Merge FFmpeg from upstream for M27

Merged from 5b802cf567a0ee7a2990e08d08f8aa0abffbb7d2

Conflicts:
	.gitignore
	libavcodec/h264_cavlc.c
	libavcodec/imgconvert.c
	libavcodec/vorbisdec.c
	libavcodec/vp3.c
	libavcodec/x86/h264_deblock.asm
	libavcodec/x86/vp8dsp.asm
	libavformat/oggparsevorbis.c
	libavutil/x86/x86inc.asm
diff --git a/.gitignore b/.gitignore
index 915922f..8cc9653 100644
--- a/.gitignore
+++ b/.gitignore
@@ -37,6 +37,8 @@
 /doc/examples/filtering_video
 /doc/examples/metadata
 /doc/examples/muxing
+/doc/examples/pc-uninstalled
+/doc/examples/resampling_audio
 /doc/examples/scaling_video
 /doc/fate.txt
 /doc/doxy/html/
@@ -65,6 +67,7 @@
 /tools/probetest
 /tools/qt-faststart
 /tools/trasher
+/tools/seek_print
 
 # Chromium stuff.
 /chromium/binaries/Chrome
@@ -73,4 +76,4 @@
 *.target.mk
 /*.targets
 /*.vcxproj*
-/*.xml
+/*.xml
\ No newline at end of file
diff --git a/CREDITS b/CREDITS
index 1d0666b..e29f0b8 100644
--- a/CREDITS
+++ b/CREDITS
@@ -1,55 +1,6 @@
-This file contains the names of some of the people who have contributed to
-FFmpeg. The names are sorted alphabetically by last name.  As this file is
-currently quite outdated and git serves as a much better tool for determining
-authorship, it remains here for historical reasons only.
+See the Git history of the project (git://source.ffmpeg.org/ffmpeg) to
+get the names of people who have contributed to FFmpeg.
 
-Dénes Balatoni
-Michel Bardiaux
-Fabrice Bellard
-Patrice Bensoussan
-Alex Beregszaszi
-BERO
-Thilo Borgmann
-Mario Brito
-Ronald Bultje
-Alex Converse
-Maarten Daniels
-Reimar Doeffinger
-Tim Ferguson
-Brian Foley
-Arpad Gereoffy
-Philip Gladstone
-Vladimir Gneushev
-Roine Gustafsson
-David Hammerton
-Wolfgang Hesseler
-Marc Hoffman
-Falk Hueffner
-Aurélien Jacobs
-Steven Johnson
-Zdenek Kabelac
-Robin Kay
-Todd Kirby
-Nick Kurshev
-Benjamin Larsson
-Loïc Le Loarer
-Daniel Maas
-Mike Melanson
-Loren Merritt
-Jeff Muizelaar
-Michael Niedermayer
-François Revol
-Peter Ross
-Måns Rullgård
-Stefano Sabatini
-Roman Shaposhnik
-Oded Shimon
-Dieter Shirley
-Konstantin Shishkov
-Juan J. Sierralta
-Ewald Snel
-Sascha Sommer
-Leon van Stuivenberg
-Roberto Togni
-Lionel Ulmer
-Reynaldo Verdejo
+To check the log, you can type the command "git log" in the FFmpeg
+source directory, or browse the online repository at
+http://source.ffmpeg.org.
diff --git a/Changelog b/Changelog
index 31981d2..6e7bac6 100644
--- a/Changelog
+++ b/Changelog
@@ -3,6 +3,30 @@
 
 version <next>:
 
+- VDPAU hardware acceleration through normal hwaccel
+- SRTP support
+- Error diffusion dither in Swscale
+- Chained Ogg support
+- Theora Midstream reconfiguration support
+- EVRC decoder
+- audio fade filter
+- filtering audio with unknown channel layout
+- allpass, bass, bandpass, bandreject, biquad, equalizer, highpass, lowpass
+  and treble audio filter
+- improved showspectrum filter, with multichannel support and sox-like colors
+- histogram filter
+- tee muxer
+- il filter ported from libmpcodecs
+- support ID3v2 tags in ASF files
+- encrypted TTA stream decoding support
+- RF64 support in WAV muxer
+- noise filter ported from libmpcodecs
+- Subtitles character encoding conversion
+- blend filter
+
+
+version 1.1:
+
 - stream disposition information printing in ffprobe
 - filter for loudness analysis following EBU R128
 - Opus encoder using libopus
@@ -14,6 +38,7 @@
 - FFM2 support
 - X-Face image encoder and decoder
 - 24-bit FLAC encoding
+- multi-channel ALAC encoding up to 7.1
 - metadata (INFO tag) support in WAV muxer
 - subtitles raw text decoder
 - support for building DLLs using MSVC
@@ -24,7 +49,7 @@
 - AVR demuxer
 - geq filter ported from libmpcodecs
 - remove ffserver daemon mode
-- AST demuxer
+- AST muxer/demuxer
 - new expansion syntax for drawtext
 - BRender PIX image decoder
 - ffprobe -show_entries option
@@ -33,6 +58,32 @@
 - BRSTM demuxer
 - animated GIF decoder and demuxer
 - PVF demuxer
+- subtitles filter
+- IRCAM muxer/demuxer
+- Paris Audio File demuxer
+- Virtual concatenation demuxer
+- VobSub demuxer
+- JSON captions for TED talks decoding support
+- SOX Resampler support in libswresample
+- aselect filter
+- SGI RLE 8-bit decoder
+- Silicon Graphics Motion Video Compressor 1 & 2 decoder
+- Silicon Graphics Movie demuxer
+- apad filter
+- Resolution & pixel format change support with multithreading for H.264
+- documentation split into per-component manuals
+- pp (postproc) filter ported from MPlayer
+- NIST Sphere demuxer
+- MPL2, VPlayer, MPlayer, AQTitle, PJS and SubViewer v1 subtitles demuxers and decoders
+- Sony Wave64 muxer
+- adobe and limelight publisher authentication in RTMP
+- data: URI scheme
+- support building on the Plan 9 operating system
+- kerndeint filter ported from MPlayer
+- histeq filter ported from VirtualDub
+- Megalux Frame demuxer
+- 012v decoder
+- Improved AVC Intra decoding support
 
 
 version 1.0:
@@ -143,6 +194,7 @@
 - vorbis parser
 - png parser
 - audio mix filter
+- ffv1: support (draft) version 1.3
 
 
 version 0.10:
diff --git a/LICENSE b/LICENSE
index a1204f4..14e3e0f 100644
--- a/LICENSE
+++ b/LICENSE
@@ -31,15 +31,24 @@
     - vf_decimate.c
     - vf_delogo.c
     - vf_geq.c
+    - vf_histeq.c
     - vf_hqdn3d.c
     - vf_hue.c
+    - vf_kerndeint.c
     - vf_mp.c
+    - vf_noise.c
+    - vf_pp.c
     - vf_smartblur.c
     - vf_super2xsai.c
     - vf_tinterlace.c
     - vf_yadif.c
     - vsrc_mptestsrc.c
 
+Should you, for whatever reason, prefer to use version 3 of the (L)GPL, then
+the configure parameter --enable-version3 will activate this licensing option
+for you. Read the file COPYING.LGPLv3 or, if you have enabled GPL parts,
+COPYING.GPLv3 to learn the exact legal terms that apply in this case.
+
 There are a handful of files under other licensing terms, namely:
 
 * The files libavcodec/jfdctfst.c, libavcodec/jfdctint_template.c and
@@ -49,11 +58,6 @@
   You must also indicate any changes including additions and deletions to
   those three files in the documentation.
 
-Should you, for whatever reason, prefer to use version 3 of the (L)GPL, then
-the configure parameter --enable-version3 will activate this licensing option
-for you. Read the file COPYING.LGPLv3 or, if you have enabled GPL parts,
-COPYING.GPLv3 to learn the exact legal terms that apply in this case.
-
 
 external libraries
 ==================
diff --git a/MAINTAINERS b/MAINTAINERS
index 724b30c..3319359 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -130,6 +130,7 @@
   bmp.c                                 Mans Rullgard, Kostya Shishkov
   cavs*                                 Stefan Gehrer
   celp_filters.*                        Vitor Sessak
+  cdxl.c                                Paul B Mahol
   cinepak.c                             Roberto Togni
   cljr                                  Alex Beregszaszi
   cllc.c                                Derek Buitenhuis
@@ -182,7 +183,7 @@
   lzo.h, lzo.c                          Reimar Doeffinger
   mdec.c                                Michael Niedermayer
   mimic.c                               Ramiro Polla
-  mjpeg.c                               Michael Niedermayer
+  mjpeg*.c                              Michael Niedermayer
   mlp*                                  Ramiro Polla
   mmvideo.c                             Peter Ross
   mpc*                                  Kostya Shishkov
@@ -193,6 +194,7 @@
   msvideo1.c                            Mike Melanson
   nellymoserdec.c                       Benjamin Larsson
   nuv.c                                 Reimar Doeffinger
+  paf.*                                 Paul B Mahol
   pcx.c                                 Ivo van Poorten
   pgssubdec.c                           Reimar Doeffinger
   ptx.c                                 Ivo van Poorten
@@ -217,6 +219,7 @@
   srt*                                  Aurelien Jacobs
   sunrast.c                             Ivo van Poorten
   svq3.c                                Michael Niedermayer
+  tak*                                  Paul B Mahol
   targa.c                               Kostya Shishkov
   tiff.c                                Kostya Shishkov
   truemotion1*                          Mike Melanson
@@ -232,6 +235,7 @@
   vc1*                                  Kostya Shishkov
   vcr1.c                                Michael Niedermayer
   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
@@ -246,8 +250,10 @@
   wmv2.c                                Michael Niedermayer
   wnv1.c                                Kostya Shishkov
   xan.c                                 Mike Melanson
+  xbm*                                  Paul B Mahol
   xl.c                                  Kostya Shishkov
   xvmc.c                                Ivan Kalvachev
+  xwd*                                  Paul B Mahol
   zerocodec.c                           Derek Buitenhuis
   zmbv*                                 Kostya Shishkov
 
@@ -301,17 +307,25 @@
 Muxers/Demuxers:
   4xm.c                                 Mike Melanson
   adtsenc.c                             Robert Swain
+  afc.c                                 Paul B Mahol
   aiff.c                                Baptiste Coudurier
   ape.c                                 Kostya Shishkov
   ass*                                  Aurelien Jacobs
+  astdec.c                              Paul B Mahol
+  astenc.c                              James Almer
   avi*                                  Michael Niedermayer
+  avr.c                                 Paul B Mahol
   bink.c                                Peter Ross
+  brstm.c                               Paul B Mahol
   caf*                                  Peter Ross
+  cdxl.c                                Paul B Mahol
   crc.c                                 Michael Niedermayer
   daud.c                                Reimar Doeffinger
+  dtshddec.c                            Paul B Mahol
   dv.c                                  Roman Shaposhnik
   dxa.c                                 Kostya Shishkov
   electronicarts.c                      Peter Ross
+  epafdec.c                             Paul B Mahol
   ffm*                                  Baptiste Coudurier
   flac*                                 Justin Ruggles
   flic.c                                Mike Melanson
@@ -323,18 +337,21 @@
   iff.c                                 Jaikrishnan Menon
   ipmovie.c                             Mike Melanson
   img2*.c                               Michael Niedermayer
+  ircam*                                Paul B Mahol
   iss.c                                 Stefan Gehrer
   jacosub*                              Clément Bœsch
   jvdec.c                               Peter Ross
   libmodplug.c                          Clément Bœsch
   libnut.c                              Oded Shimon
   lmlm4.c                               Ivo van Poorten
+  lvfdec.c                              Paul B Mahol
   lxfdec.c                              Tomas Härdin
   matroska.c                            Aurelien Jacobs
   matroskadec.c                         Aurelien Jacobs
   matroskaenc.c                         David Conrad
   metadata*                             Aurelien Jacobs
   microdvd*                             Aurelien Jacobs
+  mgsts.c                               Paul B Mahol
   mm.c                                  Peter Ross
   mov.c                                 Michael Niedermayer, Baptiste Coudurier
   movenc.c                              Michael Niedermayer, Baptiste Coudurier
@@ -346,6 +363,7 @@
   mtv.c                                 Reynaldo H. Verdejo Pinochet
   mxf*                                  Baptiste Coudurier
   mxfdec.c                              Tomas Härdin
+  nistspheredec.c                       Paul B Mahol
   nsvdec.c                              Francois Revol
   nut.c                                 Michael Niedermayer
   nuv.c                                 Reimar Doeffinger
@@ -353,8 +371,10 @@
   oggenc.c                              Baptiste Coudurier
   oggparse*.c                           David Conrad
   oma.c                                 Maxim Poliakovski
+  paf.c                                 Paul B Mahol
   psxstr.c                              Mike Melanson
   pva.c                                 Ivo van Poorten
+  pvfdec.c                              Paul B Mahol
   r3d.c                                 Baptiste Coudurier
   raw.c                                 Michael Niedermayer
   rdt.c                                 Ronald S. Bultje
@@ -370,8 +390,10 @@
   segafilm.c                            Mike Melanson
   siff.c                                Kostya Shishkov
   smacker.c                             Kostya Shishkov
+  smjpeg*                               Paul B Mahol
   srtdec.c                              Aurelien Jacobs
   swf.c                                 Baptiste Coudurier
+  takdec.c                              Paul B Mahol
   tta.c                                 Alex Beregszaszi
   txd.c                                 Ivo van Poorten
   voc.c                                 Aurelien Jacobs
@@ -380,6 +402,7 @@
   westwood.c                            Mike Melanson
   wtv.c                                 Peter Ross
   wv.c                                  Kostya Shishkov
+  wvenc.c                               Paul B Mahol
 
 Protocols:
   bluray.c                              Petri Hintukainen
@@ -388,6 +411,20 @@
   udp.c                                 Luca Abeni
 
 
+libswresample
+=============
+
+Generic parts:
+  audioconvert.c                        Michael Niedermayer
+  dither.c                              Michael Niedermayer
+  rematrix*.c                           Michael Niedermayer
+  swresample*.c                         Michael Niedermayer
+
+Resamplers:
+  resample*.c                           Michael Niedermayer
+  soxr_resample.c                       Rob Sykes
+
+
 Operating systems / CPU architectures
 =====================================
 
@@ -408,9 +445,9 @@
 Releases
 ========
 
+1.1                                     Michael Niedermayer
 1.0                                     Michael Niedermayer
 0.11                                    Michael Niedermayer
-0.10                                    Michael Niedermayer
 
 
 
@@ -441,6 +478,6 @@
 Reynaldo H. Verdejo Pinochet  6E27 CD34 170C C78E 4D4F 5F40 C18E 077F 3114 452A
 Robert Swain                  EE7A 56EA 4A81 A7B5 2001 A521 67FA 362D A2FC 3E71
 Sascha Sommer                 38A0 F88B 868E 9D3A 97D4 D6A0 E823 706F 1E07 0D3C
-Stefano Sabatini              9A43 10F8 D32C D33C 48E7 C52C 5DF2 8E4D B2EE 066B
+Stefano Sabatini              0D0B AD6B 5330 BBAD D3D6 6A0C 719C 2839 FC43 2D5F
 Stephan Hilb                  4F38 0B3A 5F39 B99B F505 E562 8D5C 5554 4E17 8863
 Tomas Härdin                  A79D 4E3D F38F 763F 91F5 8B33 A01E 8AE0 41BB 2551
diff --git a/Makefile b/Makefile
index fcb7e55..07821d1 100644
--- a/Makefile
+++ b/Makefile
@@ -70,7 +70,7 @@
 
 SUBDIR_VARS := CLEANFILES EXAMPLES FFLIBS HOSTPROGS TESTPROGS TOOLS      \
                HEADERS ARCH_HEADERS BUILT_HEADERS SKIPHEADERS            \
-               ARMV5TE-OBJS ARMV6-OBJS ARMVFP-OBJS NEON-OBJS             \
+               ARMV5TE-OBJS ARMV6-OBJS VFP-OBJS NEON-OBJS                \
                ALTIVEC-OBJS VIS-OBJS                                     \
                MMX-OBJS YASM-OBJS                                        \
                MIPSFPU-OBJS MIPSDSPR2-OBJS MIPSDSPR1-OBJS MIPS32R2-OBJS  \
@@ -153,7 +153,6 @@
 clean::
 	$(RM) $(ALLPROGS) $(ALLPROGS_G)
 	$(RM) $(CLEANSUFFIXES)
-	$(RM) $(TOOLS)
 	$(RM) $(CLEANSUFFIXES:%=tools/%)
 	$(RM) coverage.info
 	$(RM) -r coverage-html
diff --git a/README.chromium b/README.chromium
index a32781f..209626c 100644
--- a/README.chromium
+++ b/README.chromium
@@ -83,6 +83,14 @@
 -- Performing an upstream merge.
 
 The upstream merge process follows the normal Git merge process:
+  # First, modify the origin url to enable push of merge result later.
+  # e.g., change remote.origin.url from:
+  #  https://chromium.googlesource.com/chromium/third_party/ffmpeg.git
+  # to:
+  #  ssh://gerrit.chromium.org:29418/chromium/third_party/ffmpeg.git
+  # One way is to use custom_deps in .gclient.  Another might be to run
+  # git config -e within this folder and edit the URLs if already synced,
+  # though this alternative could have danger.
 
   git remote add upstream git://source.ffmpeg.org/ffmpeg.git
   git fetch upstream
diff --git a/RELEASE b/RELEASE
index 014ccf1..3d529fb 100644
--- a/RELEASE
+++ b/RELEASE
@@ -1 +1 @@
-1.0.git
\ No newline at end of file
+1.1.git
diff --git a/arch.mak b/arch.mak
index 79c9e2b..b71c8e5 100644
--- a/arch.mak
+++ b/arch.mak
@@ -1,6 +1,6 @@
 OBJS-$(HAVE_ARMV5TE) += $(ARMV5TE-OBJS) $(ARMV5TE-OBJS-yes)
 OBJS-$(HAVE_ARMV6)   += $(ARMV6-OBJS)   $(ARMV6-OBJS-yes)
-OBJS-$(HAVE_ARMVFP)  += $(ARMVFP-OBJS)  $(ARMVFP-OBJS-yes)
+OBJS-$(HAVE_VFP)     += $(VFP-OBJS)     $(VFP-OBJS-yes)
 OBJS-$(HAVE_NEON)    += $(NEON-OBJS)    $(NEON-OBJS-yes)
 
 OBJS-$(HAVE_MIPSFPU)   += $(MIPSFPU-OBJS)    $(MIPSFPU-OBJS-yes)
diff --git a/chromium/patches/README b/chromium/patches/README
index fdc18ff..4fe956b 100644
--- a/chromium/patches/README
+++ b/chromium/patches/README
@@ -4,6 +4,7 @@
 Upstream cherry-picks:
 <upstream in progress> - Win64 AVX change to not use redzone in
   libavcodec/x86/h264_deblock.asm.
+  TODO(wolenetz): Confirm upstream has the fix in M27 roll.
   TODO(wolenetz): Upstream version of this patch needs to change
   the cglobal stack to be 0x10 on WIN64, 0 on Unix64, -0x50 on 32bit.
   -0x50 means 0x50 but doesn't allocate a stack pointer, saving a
@@ -14,22 +15,17 @@
   patch in Chrome ffmpeg uses (+)0x50 for 32bit.
 <upstream in progress> - Win64 AVX alignment fix in x86inc.asm's
   WIN64_RESTORE_XMM_INTERNAL.
+  TODO(wolenetz): Confirm upstream has the fix in M27 roll.
   TODO(rbultje): Fix may already be in ffmpeg HEAD, though code is
   significantly different versus current Chromium ffmpeg. This fix
   is needed prior to m27 merge so patched directly in Chromium's ffmpeg.
   See also http://crbug.com/174160#c15
-<upstream in progress> - aligned stack fixes for MSVC++.
-<upstream in progress> - vp3 double-free fixes.
-2c16bf2de07c68513072bf3cc96401d2c6291a3e - vorbisdec: Check bark_map_size.
-
+<upstream in progress> - Fix Heap-buffer-overflow in matroska_parse_block.
+  See also http://crbug.com/167069#c16
 
 Current patches:
 
 to_upstream/
-10_realloc_mismatch.patch
-  phajdan.jr: Fixes a mismatch between posix_memalign and realloc
-  detected by debugallocation (http://crbug.com/30715). Pointer passed
-  to realloc must come from malloc, calloc or realloc, which was not the case.
 
 ugly/
 01_enable_checked_bitstream.patch
@@ -40,13 +36,14 @@
   dalecurtis: Add CONFIG_* checks to compile out code which we don't use which
   might be a security risk.  Discuss with cevans before removing.  Upstream does
   not want this patch.
+  wolenetz: In M27 merge, added call to matroska_read_close(s) in to this patch
+  in matroska_read_header() to mitigate memory leak caught by valgrind.
+  Confirmed with rbultje that this conforms to API (on error in
+  matroska_read_header(), resulting state should be same as prior to call; and
+  no double-free is expected to result from this either.)
 
 07_remove_av_gettime_symlink.patch
   dalecurtis: In order to preserve ABI compatibility after av_gettime() was
   moved inside the FFmpeg code base, they added a "symbolic link" version which
   our build chain doesn't like.  Remove it until the next major version bump.
-
-08_add_vp9_support.patch
-  tomfinegan: Add support for VP9 in WebM:
-      Tracking issue: http://crbug.com/166094
-      CL: https://codereview.chromium.org/11578025/
+  (If FF_SYMVER is no longer present, this ugly patch can be removed.)
diff --git a/chromium/patches/README.chromium b/chromium/patches/README.chromium
deleted file mode 100644
index 707683e..0000000
--- a/chromium/patches/README.chromium
+++ /dev/null
@@ -1,362 +0,0 @@
-Name: ffmpeg
-Version: 0.9.7
-
-Description:
-Contains the sources used to compile FFmpeg binaries used by Google Chrome and
-Chromium.
-
-The FFmpeg source is from ToT of the main ffmpeg branch:
-  http://git.videolan.org/?p=ffmpeg.git;a=commit;h=bb258fb995a42112d1fe14f53ec599b2cd19b707
-  Date: Tue, 12 Jul 2011 22:42:11
-  Commit: bb258fb995a42112d1fe14f53ec599b2cd19b707
-
-libvpx source
-  http://webm.googlecode.com/files/libvpx-v0.9.7-p1.zip
-  git://review.webmproject.org/libvpx.git
-  Date: Tuesday August 16 2011
-  Version: v0.9.7p1 (cayuga)
-  Commit: 20307c70ae96c45b9b00338989b952fb334e4fc9
-
-The following process is intended to run from msys
-
-Steps for extracting:
-
-AUTOMATIC:
-
-  1) On linux, mac and windows/mingw run
-
-       rm -rf sources/patched-ffmpeg
-       ./make_src_tree.sh ffmpeg.tar.gz source/patched-ffmpeg patches
-
-MANUAL: This can be useful when having to adjust patches.
-
-  1) Extract ffmpeg, which creates the directory ffmpeg:
-       cd /c/src/chrome/deps/third_party/ffmpeg
-       rm -rf ffmpeg
-       tar xf ffmpeg.tar.gz
-
-  2) Apply patches (from within the source/ directory):
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/01_static_pthread_O2.patch
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/05_respect_flac_dirac_configure.patch
-       patch -p1 --no-backup-if-mismatch < ../patches/ugly/07_get_bits_overrun.patch
-       patch -p1 --no-backup-if-mismatch < ../patches/ugly/08_enforce_theora_oob.patch
-       patch -p1 --no-backup-if-mismatch < ../patches/ugly/09_enforce_vorbis_oob_divzero.patch
-       patch -p1 --no-backup-if-mismatch < ../patches/ugly/10_aac_oob_read.patch
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/11_mkv_buffer_overflow.patch
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/12_ogg_seek_to_zero.patch
-       patch -p1 --no-backup-if-mismatch < ../patches/ugly/13_remove_avcore.patch
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/14_vp8_encode_options.patch
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/15_webp_ffmpeg.patch
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/25_ogg_index.patch
-       patch -p1 --no-backup-if-mismatch < ../patches/ugly/30_enforce_mp3_oob.patch
-       patch -p1 --no-backup-if-mismatch < ../patches/ugly/31_remove_attribute_deprecated.patch
-       patch -p1 --no-backup-if-mismatch < ../patches/ugly/32_add_rawdec_for_mac_win.patch
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/34_ogg_memcpy.patch
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/35_oggdec_duration.patch
-       patch -p1 --no-backup-if-mismatch < ../patches/from_upstream/36_theora_flush.patch
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/37_VP8_armv6_optimizations.patch
-       patch -p1 --no-backup-if-mismatch < ../patches/from_upstream/38_webm_cues_before_first_cluster.patch
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/39_VP8_fix_oob_read_writes.patch
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/40_MKV_fix_oob_write.patch
-       patch -p1 --no-backup-if-mismatch < ../patches/ugly/41_matroska_cluster_incremental.patch
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/42_vp8_fix_segmentation_maps.patch
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/43_mkv_seekahead_revalidate.patch
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/44_vorbis_oob_read.patch
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/45_mkv_fix_segmap_cache_overflow.patch
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/46_vp3_fix_double_free_invalid_read.patch
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/47_vp3_fix_infloop_and_memleak.patch
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/48_vorbis_residue_buffer.patch
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/49_vorbis_buffer_defense.patch
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/50_vp8_fix_frame_size_changes.patch
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/52_vorbis_fix_floor1_vector_int_overflow.patch
-       cd ..
-
-
-NOTE: Under Windows it is recommended to use Chromium's MinGW/MSYS environment
-or 7-Zip to extract the archives.  We've experienced issues when using WinRAR.
-
-Since FFmpeg is sandboxed inside the render process, we're only interested in
-building the absolute minimum.
-
-Refer to build_ffmpeg.sh for configuration flags for Chromium and Google Chrome.
-
-To clean up patches so there is no fuzzing
-  1) Extract ffmpeg, which creates the directory ffmpeg:
-       cd /c/src/chrome/deps/third_party/ffmpeg
-       rm -rf ffmpeg
-       tar xf ffmpeg.tar.gz
-
-  2) Apply patches:
-       rm -rf orig
-       cp -R ffmpeg orig
-       cd ffmpeg
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/01_static_pthread_O2.patch
-       cd ..
-       diff -wurp -N orig ffmpeg
-       diff -wurp -N orig ffmpeg >patches/to_upstream/01_static_pthread_O2.patch
-
-       rm -rf orig
-       cp -R ffmpeg orig
-       cd ffmpeg
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/05_respect_flac_dirac_configure.patch
-       cd ..
-       diff -wurp -N orig ffmpeg
-       diff -wurp -N orig ffmpeg >patches/to_upstream/05_respect_flac_dirac_configure.patch
-
-       rm -rf orig
-       cp -R ffmpeg orig
-       cd ffmpeg
-       patch -p1 --no-backup-if-mismatch < ../patches/ugly/07_get_bits_overrun.patch
-       cd ..
-       diff -wurp -N orig ffmpeg
-       diff -wurp -N orig ffmpeg >patches/ugly/07_get_bits_overrun.patch
-
-       rm -rf orig
-       cp -R ffmpeg orig
-       cd ffmpeg
-       patch -p1 --no-backup-if-mismatch < ../patches/ugly/08_enforce_theora_oob.patch
-       cd ..
-       diff -wurp -N orig ffmpeg
-       diff -wurp -N orig ffmpeg >patches/ugly/08_enforce_theora_oob.patch
-
-       rm -rf orig
-       cp -R ffmpeg orig
-       cd ffmpeg
-       patch -p1 --no-backup-if-mismatch < ../patches/ugly/09_enforce_vorbis_oob_divzero.patch
-       cd ..
-       diff -wurp -N orig ffmpeg
-       diff -wurp -N orig ffmpeg >patches/ugly/09_enforce_vorbis_oob_divzero.patch
-
-       rm -rf orig
-       cp -R ffmpeg orig
-       cd ffmpeg
-       patch -p1 --no-backup-if-mismatch < ../patches/ugly/10_aac_oob_read.patch
-       cd ..
-       diff -wurp -N orig ffmpeg
-       diff -wurp -N orig ffmpeg >patches/ugly/10_aac_oob_read.patch
-
-       rm -rf orig
-       cp -R ffmpeg orig
-       cd ffmpeg
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/11_mkv_buffer_overflow.patch
-       cd ..
-       diff -wurp -N orig ffmpeg
-       diff -wurp -N orig ffmpeg >patches/to_upstream/11_mkv_buffer_overflow.patch
-
-       rm -rf orig
-       cp -R ffmpeg orig
-       cd ffmpeg
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/12_ogg_seek_to_zero.patch
-       cd ..
-       diff -wurp -N orig ffmpeg
-       diff -wurp -N orig ffmpeg >patches/to_upstream/12_ogg_seek_to_zero.patch
-
-       rm -rf orig
-       cp -R ffmpeg orig
-       cd ffmpeg
-       patch -p1 --no-backup-if-mismatch < ../patches/ugly/13_remove_avcore.patch
-       cd ..
-       diff -wurp -N orig ffmpeg
-       diff -wurp -N orig ffmpeg >patches/ugly/13_remove_avcore.patch
-
-       rm -rf orig
-       cp -R ffmpeg orig
-       cd ffmpeg
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/14_vp8_encode_options.patch
-       cd ..
-       diff -wurp -N orig ffmpeg
-       diff -wurp -N orig ffmpeg >patches/to_upstream/14_vp8_encode_options.patch
-
-       rm -rf orig
-       cp -R ffmpeg orig
-       cd ffmpeg
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/15_webp_ffmpeg.patch
-       cd ..
-       diff -wurp -N orig ffmpeg
-       diff -wurp -N orig ffmpeg >patches/to_upstream/15_webp_ffmpeg.patch
-
-       rm -rf orig
-       cp -R ffmpeg orig
-       cd ffmpeg
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/25_ogg_index.patch
-       cd ..
-       diff -wurp -N orig ffmpeg
-       diff -wurp -N orig ffmpeg >patches/to_upstream/25_ogg_index.patch
-
-       rm -rf orig
-       cp -R ffmpeg orig
-       cd ffmpeg
-       patch -p1 --no-backup-if-mismatch < ../patches/ugly/30_enforce_mp3_oob.patch
-       cd ..
-       diff -wurp -N orig ffmpeg
-       diff -wurp -N orig ffmpeg >patches/ugly/30_enforce_mp3_oob.patch
-
-       rm -rf orig
-       cp -R ffmpeg orig
-       cd ffmpeg
-       patch -p1 --no-backup-if-mismatch < ../patches/ugly/31_remove_attribute_deprecated.patch
-       cd ..
-       diff -wurp -N orig ffmpeg
-       diff -wurp -N orig ffmpeg >patches/ugly/31_remove_attribute_deprecated.patch
-
-       rm -rf orig
-       cp -R ffmpeg orig
-       cd ffmpeg
-       patch -p1 --no-backup-if-mismatch < ../patches/ugly/32_add_rawdec_to_Makefile.patch
-       cd ..
-       diff -wurp -N orig ffmpeg
-       diff -wurp -N orig ffmpeg >patches/ugly/32_add_rawdec_to_Makefile.patch
-
-       rm -rf orig
-       cp -R ffmpeg orig
-       cd ffmpeg
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/34_ogg_memcpy.patch
-       cd ..
-       diff -wurp -N orig ffmpeg
-       diff -wurp -N orig ffmpeg >patches/to_upstream/34_ogg_memcpy.patch
-
-       rm -rf orig
-       cp -R ffmpeg orig
-       cd ffmpeg
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/35_oggdec_duration.patch
-       cd ..
-       diff -wurp -N orig ffmpeg
-       diff -wurp -N orig ffmpeg >patches/to_upstream/35_oggdec_duration.patch
-
-       rm -rf orig
-       cp -R ffmpeg orig
-       cd ffmpeg
-       patch -p1 --no-backup-if-mismatch < ../patches/from_upstream/36_theora_flush.patch
-       cd ..
-       diff -wurp -N orig ffmpeg
-       diff -wurp -N orig ffmpeg >patches/from_upstream/36_theora_flush.patch
-
-       rm -rf orig
-       cp -R ffmpeg orig
-       cd ffmpeg
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/37_VP8_armv6_optimizations.patch
-       cd ..
-       diff -wurp -N orig ffmpeg
-       diff -wurp -N orig ffmpeg >patches/to_upstream/37_VP8_armv6_optimizations.patch
-
-       rm -rf orig
-       cp -R ffmpeg orig
-       cd ffmpeg
-       patch -p1 --no-backup-if-mismatch < ../patches/from_upstream/38_webm_cues_before_first_cluster.patch
-       cd ..
-       diff -wurp -N orig ffmpeg
-       diff -wurp -N orig ffmpeg >patches/from_upstream/38_webm_cues_before_first_cluster.patch
-
-       rm -rf orig
-       cp -R ffmpeg orig
-       cd ffmpeg
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/39_VP8_fix_oob_read_writes.patch
-       cd ..
-       diff -wurp -N orig ffmpeg
-       diff -wurp -N orig ffmpeg >patches/to_upstream/39_VP8_fix_oob_read_writes.patch
-
-       rm -rf orig
-       cp -R ffmpeg orig
-       cd ffmpeg
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/40_MKV_fix_oob_write.patch
-       cd ..
-       diff -wurp -N orig ffmpeg
-       diff -wurp -N orig ffmpeg >patches/to_upstream/40_MKV_fix_oob_write.patch
-
-       rm -rf orig
-       cp -R ffmpeg orig
-       cd ffmpeg
-       patch -p1 --no-backup-if-mismatch < ../patches/ugly/41_matroska_cluster_incremental.patch
-       cd ..
-       diff -wurp -N orig ffmpeg
-       diff -wurp -N orig ffmpeg >patches/to_upstream/41_matroska_cluster_incremental.patch
-
-       rm -rf orig
-       cp -R ffmpeg orig
-       cd ffmpeg
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/42_vp8_fix_segmentation_maps.patch
-       cd ..
-       diff -wurp -N orig ffmpeg
-       diff -wurp -N orig ffmpeg >patches/to_upstream/42_vp8_fix_segmentation_maps.patch
-
-       rm -rf orig
-       cp -R ffmpeg orig
-       cd ffmpeg
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/43_mkv_seekahead_revalidate.patch
-       cd ..
-       diff -wurp -N orig ffmpeg
-       diff -wurp -N orig ffmpeg >patches/to_upstream/43_mkv_seekahead_revalidate.patch
-
-       rm -rf orig
-       cp -R ffmpeg orig
-       cd ffmpeg
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/44_vorbis_oob_read.patch
-       cd ..
-       diff -wurp -N orig ffmpeg
-       diff -wurp -N orig ffmpeg >patches/to_upstream/44_vorbis_oob_read.patch
-
-       rm -rf orig
-       cp -R ffmpeg orig
-       cd ffmpeg
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/45_mkv_fix_segmap_cache_overflow.patch
-       cd ..
-       diff -wurp -N orig ffmpeg
-       diff -wurp -N orig ffmpeg >patches/to_upstream/45_mkv_fix_segmap_cache_overflow.patch
-
-       rm -rf orig
-       cp -R ffmpeg orig
-       cd ffmpeg
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/46_vp3_fix_double_free_invalid_read.patch
-       cd ..
-       diff -wurp -N orig ffmpeg
-       diff -wurp -N orig ffmpeg >patches/to_upstream/46_vp3_fix_double_free_invalid_read.patch
-
-       rm -rf orig
-       cp -R ffmpeg orig
-       cd ffmpeg
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/47_vp3_fix_infloop_and_memleak.patch
-       cd ..
-       diff -wurp -N orig ffmpeg
-       diff -wurp -N orig ffmpeg >patches/to_upstream/47_vp3_fix_infloop_and_memleak.patch
-
-       rm -rf orig
-       cp -R ffmpeg orig
-       cd ffmpeg
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/48_vorbis_residue_buffer.patch
-       cd ..
-       diff -wurp -N orig ffmpeg
-       diff -wurp -N orig ffmpeg >patches/to_upstream/48_vorbis_residue_buffer.patch
-
-       rm -rf orig
-       cp -R ffmpeg orig
-       cd ffmpeg
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/49_vorbis_buffer_defense.patch
-       cd ..
-       diff -wurp -N orig ffmpeg
-       diff -wurp -N orig ffmpeg >patches/to_upstream/49_vorbis_buffer_defense.patch
-
-       rm -rf orig
-       cp -R ffmpeg orig
-       cd ffmpeg
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/50_vp8_fix_frame_size_changes.patch
-       cd ..
-       diff -wurp -N orig ffmpeg
-       diff -wurp -N orig ffmpeg >patches/to_upstream/50_vp8_fix_frame_size_changes.patch
-
-       rm -rf orig
-       cp -R ffmpeg orig
-       cd ffmpeg
-       patch -p1 --no-backup-if-mismatch < ../patches/to_upstream/52_vorbis_fix_floor1_vector_int_overflow.patch
-       cd ..
-       diff -wurp -N orig ffmpeg
-       diff -wurp -N orig ffmpeg >patches/to_upstream/52_vorbis_fix_floor1_vector_int_overflow.patch
-
-Testing
-  Updates should be tested against
-  a) http://wiki.xiph.org/TheoraTestsuite
-  b) WebKit Layout Tests
-     http://www.chromium.org/developers/testing/webkit-layout-tests
-       make -r test_shell BUILDTYPE=Debug -j16
-       make -r ImageDiff BUILDTYPE=Debug -j16
-       make -r DumpRenderTree BUILDTYPE=Debug -j16
-       ./webkit/tools/layout_tests/run_webkit_tests.sh --debug media/\*
diff --git a/chromium/patches/to_upstream/10_realloc_mismatch.patch b/chromium/patches/to_upstream/10_realloc_mismatch.patch
deleted file mode 100644
index d290dbc..0000000
--- a/chromium/patches/to_upstream/10_realloc_mismatch.patch
+++ /dev/null
@@ -1,20 +0,0 @@
-diff --git a/libavformat/oggparsevorbis.c b/libavformat/oggparsevorbis.c
-index 09f5205..3c91080 100644
---- a/libavformat/oggparsevorbis.c
-+++ b/libavformat/oggparsevorbis.c
-@@ -173,11 +173,13 @@ static unsigned int
- fixup_vorbis_headers(AVFormatContext * as, struct oggvorbis_private *priv,
-                      uint8_t **buf)
- {
--    int i,offset, len;
-+    int i,offset, len, buf_len;
-     unsigned char *ptr;
- 
-     len = priv->len[0] + priv->len[1] + priv->len[2];
--    ptr = *buf = av_mallocz(len + len/255 + 64);
-+    buf_len = len + len/255 + 64;
-+    ptr = *buf = av_realloc(NULL, buf_len);
-+    memset(*buf, '\0', buf_len);
- 
-     ptr[0] = 2;
-     offset = 1;
diff --git a/chromium/patches/ugly/02_compile_with_disabled_features.patch b/chromium/patches/ugly/02_compile_with_disabled_features.patch
index cd762b4..f81640b 100644
--- a/chromium/patches/ugly/02_compile_with_disabled_features.patch
+++ b/chromium/patches/ugly/02_compile_with_disabled_features.patch
@@ -1,5 +1,5 @@
 diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
-index d37346b..4fd4c65 100644
+index 249a023..ab675ae 100644
 --- a/libavformat/matroskadec.c
 +++ b/libavformat/matroskadec.c
 @@ -35,14 +35,18 @@
@@ -21,7 +21,16 @@
  #include "libavutil/dict.h"
  #if CONFIG_ZLIB
  #include <zlib.h>
-@@ -1682,6 +1686,7 @@ static int matroska_read_header(AVFormatContext *s)
+@@ -51,6 +55,8 @@
+ #include <bzlib.h>
+ #endif
+ 
++static int matroska_read_close(AVFormatContext *s);
++
+ typedef enum {
+     EBML_NONE,
+     EBML_UINT,
+@@ -1700,6 +1706,7 @@ static int matroska_read_header(AVFormatContext *s)
          } else if ((codec_id == AV_CODEC_ID_RA_288 || codec_id == AV_CODEC_ID_COOK ||
                      codec_id == AV_CODEC_ID_ATRAC3 || codec_id == AV_CODEC_ID_SIPR)
                      && track->codec_priv.data) {
@@ -29,17 +38,19 @@
              int flavor;
  
              ffio_init_context(&b, track->codec_priv.data,track->codec_priv.size,
-@@ -1706,6 +1711,9 @@ static int matroska_read_header(AVFormatContext *s)
+@@ -1724,6 +1731,11 @@ static int matroska_read_header(AVFormatContext *s)
                  st->codec->block_align = track->audio.sub_packet_size;
                  extradata_offset = 78;
              }
 +#else
++            /* Returning without closing would cause leaks with some files */
++            matroska_read_close(s);
 +            return AVERROR_INVALIDDATA;
 +#endif
          }
          track->codec_priv.size -= extradata_offset;
  
-@@ -2042,8 +2050,13 @@ static int matroska_parse_rm_audio(MatroskaDemuxContext *matroska,
+@@ -2066,8 +2079,13 @@ static int matroska_parse_rm_audio(MatroskaDemuxContext *matroska,
          }
  
          if (++track->audio.sub_packet_cnt >= h) {
@@ -54,7 +65,7 @@
              track->audio.sub_packet_cnt = 0;
              track->audio.pkt_cnt = h*w / a;
          }
-@@ -2242,8 +2255,12 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
+@@ -2279,8 +2297,12 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
               st->codec->codec_id == AV_CODEC_ID_ATRAC3) &&
               st->codec->block_align && track->audio.sub_packet_size) {
  
diff --git a/chromium/patches/ugly/08_add_vp9_support.patch b/chromium/patches/ugly/08_add_vp9_support.patch
deleted file mode 100644
index bb331a7..0000000
--- a/chromium/patches/ugly/08_add_vp9_support.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From c1fc9246a1121b59c64b13f7a4d6f15cfc0a26ea Mon Sep 17 00:00:00 2001
-From: Tom Finegan <tomfinegan@chromium.org>
-Date: Fri, 14 Dec 2012 14:36:24 -0800
-Subject: [PATCH] FFmpeg: Add support for VP9 in WebM.
-
-BUG=166094
-TEST=libavformat codec context for VP9 in matroska has codec_id
-AV_CODEC_ID_VP9
-
-Signed-off-by: Dale Curtis <dalecurtis@chromium.org>
----
- libavcodec/avcodec.h   | 1 +
- libavformat/matroska.c | 1 +
- 2 files changed, 2 insertions(+)
-
-diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
-index b6a4b0e..aa06348 100644
---- a/libavcodec/avcodec.h
-+++ b/libavcodec/avcodec.h
-@@ -267,6 +267,7 @@ enum AVCodecID {
-     AV_CODEC_ID_MTS2,
-     AV_CODEC_ID_CLLC,
-     AV_CODEC_ID_MSS2,
-+    AV_CODEC_ID_VP9,
-     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'),
-diff --git a/libavformat/matroska.c b/libavformat/matroska.c
-index 64d0a45..930c609 100644
---- a/libavformat/matroska.c
-+++ b/libavformat/matroska.c
-@@ -82,6 +82,7 @@ const CodecTags ff_mkv_codec_tags[]={
-     {"V_THEORA"         , AV_CODEC_ID_THEORA},
-     {"V_UNCOMPRESSED"   , AV_CODEC_ID_RAWVIDEO},
-     {"V_VP8"            , AV_CODEC_ID_VP8},
-+    {"V_VP9"            , AV_CODEC_ID_VP9},
- 
-     {""                 , AV_CODEC_ID_NONE}
- };
--- 
-1.7.11.4
-
diff --git a/cmdutils.c b/cmdutils.c
index fd8ff50..c6fde33 100644
--- a/cmdutils.c
+++ b/cmdutils.c
@@ -62,10 +62,10 @@
 static int init_report(const char *env);
 
 struct SwsContext *sws_opts;
-SwrContext *swr_opts;
-AVDictionary *format_opts, *codec_opts;
+AVDictionary *swr_opts;
+AVDictionary *format_opts, *codec_opts, *resample_opts;
 
-const int this_year = 2012;
+const int this_year = 2013;
 
 static FILE *report_file;
 
@@ -75,9 +75,6 @@
     if(CONFIG_SWSCALE)
         sws_opts = sws_getContext(16, 16, 0, 16, 16, 0, SWS_BICUBIC,
                               NULL, NULL, NULL);
-
-    if(CONFIG_SWRESAMPLE)
-        swr_opts = swr_alloc();
 }
 
 void uninit_opts(void)
@@ -87,11 +84,10 @@
     sws_opts = NULL;
 #endif
 
-    if(CONFIG_SWRESAMPLE)
-        swr_free(&swr_opts);
-
+    av_dict_free(&swr_opts);
     av_dict_free(&format_opts);
     av_dict_free(&codec_opts);
+    av_dict_free(&resample_opts);
 }
 
 void log_callback_help(void *ptr, int level, const char *fmt, va_list vl)
@@ -262,36 +258,14 @@
 }
 #endif /* HAVE_COMMANDLINETOARGVW */
 
-int parse_option(void *optctx, const char *opt, const char *arg,
-                 const OptionDef *options)
+static int write_option(void *optctx, const OptionDef *po, const char *opt,
+                        const char *arg)
 {
-    const OptionDef *po;
-    int bool_val = 1;
-    int *dstcount;
-    void *dst;
-
-    po = find_option(options, opt);
-    if (!po->name && opt[0] == 'n' && opt[1] == 'o') {
-        /* handle 'no' bool option */
-        po = find_option(options, opt + 2);
-        if ((po->name && (po->flags & OPT_BOOL)))
-            bool_val = 0;
-    }
-    if (!po->name)
-        po = find_option(options, "default");
-    if (!po->name) {
-        av_log(NULL, AV_LOG_ERROR, "Unrecognized option '%s'\n", opt);
-        return AVERROR(EINVAL);
-    }
-    if (po->flags & HAS_ARG && !arg) {
-        av_log(NULL, AV_LOG_ERROR, "Missing argument for option '%s'\n", opt);
-        return AVERROR(EINVAL);
-    }
-
     /* new-style options contain an offset into optctx, old-style address of
      * a global var*/
-    dst = po->flags & (OPT_OFFSET | OPT_SPEC) ? (uint8_t *)optctx + po->u.off
-                                              : po->u.dst_ptr;
+    void *dst = po->flags & (OPT_OFFSET | OPT_SPEC) ?
+                (uint8_t *)optctx + po->u.off : po->u.dst_ptr;
+    int *dstcount;
 
     if (po->flags & OPT_SPEC) {
         SpecifierOpt **so = dst;
@@ -308,9 +282,7 @@
         str = av_strdup(arg);
 //         av_freep(dst);
         *(char **)dst = str;
-    } else if (po->flags & OPT_BOOL) {
-        *(int *)dst = bool_val;
-    } else if (po->flags & OPT_INT) {
+    } else if (po->flags & OPT_BOOL || po->flags & OPT_INT) {
         *(int *)dst = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
     } else if (po->flags & OPT_INT64) {
         *(int64_t *)dst = parse_number_or_die(opt, arg, OPT_INT64, INT64_MIN, INT64_MAX);
@@ -330,6 +302,40 @@
     }
     if (po->flags & OPT_EXIT)
         exit(0);
+
+    return 0;
+}
+
+int parse_option(void *optctx, const char *opt, const char *arg,
+                 const OptionDef *options)
+{
+    const OptionDef *po;
+    int ret;
+
+    po = find_option(options, opt);
+    if (!po->name && opt[0] == 'n' && opt[1] == 'o') {
+        /* handle 'no' bool option */
+        po = find_option(options, opt + 2);
+        if ((po->name && (po->flags & OPT_BOOL)))
+            arg = "0";
+    } else if (po->flags & OPT_BOOL)
+        arg = "1";
+
+    if (!po->name)
+        po = find_option(options, "default");
+    if (!po->name) {
+        av_log(NULL, AV_LOG_ERROR, "Unrecognized option '%s'\n", opt);
+        return AVERROR(EINVAL);
+    }
+    if (po->flags & HAS_ARG && !arg) {
+        av_log(NULL, AV_LOG_ERROR, "Missing argument for option '%s'\n", opt);
+        return AVERROR(EINVAL);
+    }
+
+    ret = write_option(optctx, po, opt, arg);
+    if (ret < 0)
+        return ret;
+
     return !!(po->flags & HAS_ARG);
 }
 
@@ -364,6 +370,29 @@
     }
 }
 
+int parse_optgroup(void *optctx, OptionGroup *g)
+{
+    int i, ret;
+
+    av_log(NULL, AV_LOG_DEBUG, "Parsing a group of options: %s %s.\n",
+           g->group_def->name, g->arg);
+
+    for (i = 0; i < g->nb_opts; i++) {
+        Option *o = &g->opts[i];
+
+        av_log(NULL, AV_LOG_DEBUG, "Applying option %s (%s) with argument %s.\n",
+               o->key, o->opt->help, o->val);
+
+        ret = write_option(optctx, o->opt, o->key, o->val);
+        if (ret < 0)
+            return ret;
+    }
+
+    av_log(NULL, AV_LOG_DEBUG, "Successfully parsed a group of options.\n");
+
+    return 0;
+}
+
 int locate_option(int argc, char **argv, const OptionDef *options,
                   const char *optname)
 {
@@ -445,8 +474,14 @@
     char opt_stripped[128];
     const char *p;
     const AVClass *cc = avcodec_get_class(), *fc = avformat_get_class();
+#if CONFIG_AVRESAMPLE
+    const AVClass *rc = avresample_get_class();
+#endif
     const AVClass *sc, *swr_class;
 
+    if (!strcmp(opt, "debug") || !strcmp(opt, "fdebug"))
+        av_log_set_level(AV_LOG_DEBUG);
+
     if (!(p = strchr(opt, ':')))
         p = opt + strlen(opt);
     av_strlcpy(opt_stripped, opt, FFMIN(sizeof(opt_stripped), p - opt + 1));
@@ -480,23 +515,259 @@
 #endif
 #if CONFIG_SWRESAMPLE
     swr_class = swr_get_class();
-    if (!consumed && av_opt_find(&swr_class, opt, NULL, 0,
-                               AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)) {
-        int ret = av_opt_set(swr_opts, opt, arg, 0);
+    if (!consumed && (o=av_opt_find(&swr_class, opt, NULL, 0,
+                                    AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) {
+        struct SwrContext *swr = swr_alloc();
+        int ret = av_opt_set(swr, opt, arg, 0);
+        swr_free(&swr);
         if (ret < 0) {
             av_log(NULL, AV_LOG_ERROR, "Error setting option %s.\n", opt);
             return ret;
         }
+        av_dict_set(&swr_opts, opt, arg, FLAGS);
+        consumed = 1;
+    }
+#endif
+#if CONFIG_AVRESAMPLE
+    if ((o=av_opt_find(&rc, opt, NULL, 0,
+                       AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) {
+        av_dict_set(&resample_opts, opt, arg, FLAGS);
         consumed = 1;
     }
 #endif
 
     if (consumed)
         return 0;
-    av_log(NULL, AV_LOG_ERROR, "Unrecognized option '%s'\n", opt);
     return AVERROR_OPTION_NOT_FOUND;
 }
 
+/*
+ * Check whether given option is a group separator.
+ *
+ * @return index of the group definition that matched or -1 if none
+ */
+static int match_group_separator(const OptionGroupDef *groups, int nb_groups,
+                                 const char *opt)
+{
+    int i;
+
+    for (i = 0; i < nb_groups; i++) {
+        const OptionGroupDef *p = &groups[i];
+        if (p->sep && !strcmp(p->sep, opt))
+            return i;
+    }
+
+    return -1;
+}
+
+/*
+ * Finish parsing an option group.
+ *
+ * @param group_idx which group definition should this group belong to
+ * @param arg argument of the group delimiting option
+ */
+static void finish_group(OptionParseContext *octx, int group_idx,
+                         const char *arg)
+{
+    OptionGroupList *l = &octx->groups[group_idx];
+    OptionGroup *g;
+
+    GROW_ARRAY(l->groups, l->nb_groups);
+    g = &l->groups[l->nb_groups - 1];
+
+    *g             = octx->cur_group;
+    g->arg         = arg;
+    g->group_def   = l->group_def;
+#if CONFIG_SWSCALE
+    g->sws_opts    = sws_opts;
+#endif
+    g->swr_opts    = swr_opts;
+    g->codec_opts  = codec_opts;
+    g->format_opts = format_opts;
+    g->resample_opts = resample_opts;
+
+    codec_opts  = NULL;
+    format_opts = NULL;
+    resample_opts = NULL;
+#if CONFIG_SWSCALE
+    sws_opts    = NULL;
+#endif
+    swr_opts    = NULL;
+    init_opts();
+
+    memset(&octx->cur_group, 0, sizeof(octx->cur_group));
+}
+
+/*
+ * Add an option instance to currently parsed group.
+ */
+static void add_opt(OptionParseContext *octx, const OptionDef *opt,
+                    const char *key, const char *val)
+{
+    int global = !(opt->flags & (OPT_PERFILE | OPT_SPEC | OPT_OFFSET));
+    OptionGroup *g = global ? &octx->global_opts : &octx->cur_group;
+
+    GROW_ARRAY(g->opts, g->nb_opts);
+    g->opts[g->nb_opts - 1].opt = opt;
+    g->opts[g->nb_opts - 1].key = key;
+    g->opts[g->nb_opts - 1].val = val;
+}
+
+static void init_parse_context(OptionParseContext *octx,
+                               const OptionGroupDef *groups, int nb_groups)
+{
+    static const OptionGroupDef global_group = { "global" };
+    int i;
+
+    memset(octx, 0, sizeof(*octx));
+
+    octx->nb_groups = nb_groups;
+    octx->groups    = av_mallocz(sizeof(*octx->groups) * octx->nb_groups);
+    if (!octx->groups)
+        exit(1);
+
+    for (i = 0; i < octx->nb_groups; i++)
+        octx->groups[i].group_def = &groups[i];
+
+    octx->global_opts.group_def = &global_group;
+    octx->global_opts.arg       = "";
+
+    init_opts();
+}
+
+void uninit_parse_context(OptionParseContext *octx)
+{
+    int i, j;
+
+    for (i = 0; i < octx->nb_groups; i++) {
+        OptionGroupList *l = &octx->groups[i];
+
+        for (j = 0; j < l->nb_groups; j++) {
+            av_freep(&l->groups[j].opts);
+            av_dict_free(&l->groups[j].codec_opts);
+            av_dict_free(&l->groups[j].format_opts);
+            av_dict_free(&l->groups[j].resample_opts);
+#if CONFIG_SWSCALE
+            sws_freeContext(l->groups[j].sws_opts);
+#endif
+            av_dict_free(&l->groups[j].swr_opts);
+        }
+        av_freep(&l->groups);
+    }
+    av_freep(&octx->groups);
+
+    av_freep(&octx->cur_group.opts);
+    av_freep(&octx->global_opts.opts);
+
+    uninit_opts();
+}
+
+int split_commandline(OptionParseContext *octx, int argc, char *argv[],
+                      const OptionDef *options,
+                      const OptionGroupDef *groups, int nb_groups)
+{
+    int optindex = 1;
+    int dashdash = -2;
+
+    /* perform system-dependent conversions for arguments list */
+    prepare_app_arguments(&argc, &argv);
+
+    init_parse_context(octx, groups, nb_groups);
+    av_log(NULL, AV_LOG_DEBUG, "Splitting the commandline.\n");
+
+    while (optindex < argc) {
+        const char *opt = argv[optindex++], *arg;
+        const OptionDef *po;
+        int ret;
+
+        av_log(NULL, AV_LOG_DEBUG, "Reading option '%s' ...", opt);
+
+        if (opt[0] == '-' && opt[1] == '-' && !opt[2]) {
+            dashdash = optindex;
+            continue;
+        }
+        /* unnamed group separators, e.g. output filename */
+        if (opt[0] != '-' || !opt[1] || dashdash+1 == optindex) {
+            finish_group(octx, 0, opt);
+            av_log(NULL, AV_LOG_DEBUG, " matched as %s.\n", groups[0].name);
+            continue;
+        }
+        opt++;
+
+#define GET_ARG(arg)                                                           \
+do {                                                                           \
+    arg = argv[optindex++];                                                    \
+    if (!arg) {                                                                \
+        av_log(NULL, AV_LOG_ERROR, "Missing argument for option '%s'.\n", opt);\
+        return AVERROR(EINVAL);                                                \
+    }                                                                          \
+} while (0)
+
+        /* named group separators, e.g. -i */
+        if ((ret = match_group_separator(groups, nb_groups, opt)) >= 0) {
+            GET_ARG(arg);
+            finish_group(octx, ret, arg);
+            av_log(NULL, AV_LOG_DEBUG, " matched as %s with argument '%s'.\n",
+                   groups[ret].name, arg);
+            continue;
+        }
+
+        /* normal options */
+        po = find_option(options, opt);
+        if (po->name) {
+            if (po->flags & OPT_EXIT) {
+                /* optional argument, e.g. -h */
+                arg = argv[optindex++];
+            } else if (po->flags & HAS_ARG) {
+                GET_ARG(arg);
+            } else {
+                arg = "1";
+            }
+
+            add_opt(octx, po, opt, arg);
+            av_log(NULL, AV_LOG_DEBUG, " matched as option '%s' (%s) with "
+                   "argument '%s'.\n", po->name, po->help, arg);
+            continue;
+        }
+
+        /* AVOptions */
+        if (argv[optindex]) {
+            ret = opt_default(NULL, opt, argv[optindex]);
+            if (ret >= 0) {
+                av_log(NULL, AV_LOG_DEBUG, " matched as AVOption '%s' with "
+                       "argument '%s'.\n", opt, argv[optindex]);
+                optindex++;
+                continue;
+            } else if (ret != AVERROR_OPTION_NOT_FOUND) {
+                av_log(NULL, AV_LOG_ERROR, "Error parsing option '%s' "
+                       "with argument '%s'.\n", opt, argv[optindex]);
+                return ret;
+            }
+        }
+
+        /* boolean -nofoo options */
+        if (opt[0] == 'n' && opt[1] == 'o' &&
+            (po = find_option(options, opt + 2)) &&
+            po->name && po->flags & OPT_BOOL) {
+            add_opt(octx, po, opt, "0");
+            av_log(NULL, AV_LOG_DEBUG, " matched as option '%s' (%s) with "
+                   "argument 0.\n", po->name, po->help);
+            continue;
+        }
+
+        av_log(NULL, AV_LOG_ERROR, "Unrecognized option '%s'.\n", opt);
+        return AVERROR_OPTION_NOT_FOUND;
+    }
+
+    if (octx->cur_group.nb_opts || codec_opts || format_opts || resample_opts)
+        av_log(NULL, AV_LOG_WARNING, "Trailing options were found on the "
+               "commandline.\n");
+
+    av_log(NULL, AV_LOG_DEBUG, "Finished splitting the commandline.\n");
+
+    return 0;
+}
+
 int opt_loglevel(void *optctx, const char *opt, const char *arg)
 {
     const struct { const char *name; int level; } log_levels[] = {
@@ -655,12 +926,6 @@
     return 0;
 }
 
-int opt_codec_debug(void *optctx, const char *opt, const char *arg)
-{
-    av_log_set_level(AV_LOG_DEBUG);
-    return opt_default(NULL, opt, arg);
-}
-
 int opt_timelimit(void *optctx, const char *opt, const char *arg)
 {
 #if HAVE_SETRLIMIT
@@ -1195,8 +1460,6 @@
 
     while ((pix_desc = av_pix_fmt_desc_next(pix_desc))) {
         enum AVPixelFormat pix_fmt = av_pix_fmt_desc_get_id(pix_desc);
-        if(!pix_desc->name)
-            continue;
         printf("%c%c%c%c%c %-16s       %d            %2d\n",
                sws_isSupportedInput (pix_fmt)      ? 'I' : '.',
                sws_isSupportedOutput(pix_fmt)      ? 'O' : '.',
@@ -1486,10 +1749,8 @@
     if (!codec)
         codec            = s->oformat ? avcodec_find_encoder(codec_id)
                                       : avcodec_find_decoder(codec_id);
-    if (!codec)
-        return NULL;
 
-    switch (codec->type) {
+    switch (st->codec->codec_type) {
     case AVMEDIA_TYPE_VIDEO:
         prefix  = 'v';
         flags  |= AV_OPT_FLAG_VIDEO_PARAM;
@@ -1601,12 +1862,6 @@
         av_log(s, AV_LOG_ERROR, "alloc_buffer: av_image_alloc() failed\n");
         return ret;
     }
-    /* XXX this shouldn't be needed, but some tests break without this line
-     * those decoders are buggy and need to be fixed.
-     * the following tests fail:
-     * cdgraphics, ansi, aasc, fraps-v1, qtrle-1bit
-     */
-    memset(buf->base[0], 128, ret);
 
     avcodec_get_chroma_sub_sample(s->pix_fmt, &h_chroma_shift, &v_chroma_shift);
     for (i = 0; i < FF_ARRAY_ELEMS(buf->data); i++) {
@@ -1657,11 +1912,6 @@
     frame->opaque        = buf;
     frame->type          = FF_BUFFER_TYPE_USER;
     frame->extended_data = frame->data;
-    frame->pkt_pts       = s->pkt ? s->pkt->pts : AV_NOPTS_VALUE;
-    frame->width         = buf->w;
-    frame->height        = buf->h;
-    frame->format        = buf->pix_fmt;
-    frame->sample_aspect_ratio = s->sample_aspect_ratio;
 
     for (i = 0; i < FF_ARRAY_ELEMS(buf->data); i++) {
         frame->base[i]     = buf->base[i];  // XXX h264.c uses base though it shouldn't
diff --git a/cmdutils.h b/cmdutils.h
index 931b634..08c92ce 100644
--- a/cmdutils.h
+++ b/cmdutils.h
@@ -51,8 +51,8 @@
 extern AVCodecContext *avcodec_opts[AVMEDIA_TYPE_NB];
 extern AVFormatContext *avformat_opts;
 extern struct SwsContext *sws_opts;
-extern struct SwrContext *swr_opts;
-extern AVDictionary *format_opts, *codec_opts;
+extern AVDictionary *swr_opts;
+extern AVDictionary *format_opts, *codec_opts, *resample_opts;
 
 /**
  * Initialize the cmdutils option system, in particular
@@ -123,7 +123,7 @@
  * not zero timestr is interpreted as a duration, otherwise as a
  * date
  *
- * @see parse_date()
+ * @see av_parse_time()
  */
 int64_t parse_time_or_die(const char *context, const char *timestr,
                           int is_duration);
@@ -224,6 +224,96 @@
                  const OptionDef *options);
 
 /**
+ * An option extracted from the commandline.
+ * Cannot use AVDictionary because of options like -map which can be
+ * used multiple times.
+ */
+typedef struct Option {
+    const OptionDef  *opt;
+    const char       *key;
+    const char       *val;
+} Option;
+
+typedef struct OptionGroupDef {
+    /**< group name */
+    const char *name;
+    /**
+     * Option to be used as group separator. Can be NULL for groups which
+     * are terminated by a non-option argument (e.g. ffmpeg output files)
+     */
+    const char *sep;
+} OptionGroupDef;
+
+typedef struct OptionGroup {
+    const OptionGroupDef *group_def;
+    const char *arg;
+
+    Option *opts;
+    int  nb_opts;
+
+    AVDictionary *codec_opts;
+    AVDictionary *format_opts;
+    AVDictionary *resample_opts;
+    struct SwsContext *sws_opts;
+    AVDictionary *swr_opts;
+} OptionGroup;
+
+/**
+ * A list of option groups that all have the same group type
+ * (e.g. input files or output files)
+ */
+typedef struct OptionGroupList {
+    const OptionGroupDef *group_def;
+
+    OptionGroup *groups;
+    int       nb_groups;
+} OptionGroupList;
+
+typedef struct OptionParseContext {
+    OptionGroup global_opts;
+
+    OptionGroupList *groups;
+    int           nb_groups;
+
+    /* parsing state */
+    OptionGroup cur_group;
+} OptionParseContext;
+
+/**
+ * Parse an options group and write results into optctx.
+ *
+ * @param optctx an app-specific options context. NULL for global options group
+ */
+int parse_optgroup(void *optctx, OptionGroup *g);
+
+/**
+ * Split the commandline into an intermediate form convenient for further
+ * processing.
+ *
+ * The commandline is assumed to be composed of options which either belong to a
+ * group (those with OPT_SPEC, OPT_OFFSET or OPT_PERFILE) or are global
+ * (everything else).
+ *
+ * A group (defined by an OptionGroupDef struct) is a sequence of options
+ * terminated by either a group separator option (e.g. -i) or a parameter that
+ * is not an option (doesn't start with -). A group without a separator option
+ * must always be first in the supplied groups list.
+ *
+ * All options within the same group are stored in one OptionGroup struct in an
+ * OptionGroupList, all groups with the same group definition are stored in one
+ * OptionGroupList in OptionParseContext.groups. The order of group lists is the
+ * same as the order of group definitions.
+ */
+int split_commandline(OptionParseContext *octx, int argc, char *argv[],
+                      const OptionDef *options,
+                      const OptionGroupDef *groups, int nb_groups);
+
+/**
+ * Free all allocated memory in an OptionParseContext.
+ */
+void uninit_parse_context(OptionParseContext *octx);
+
+/**
  * Find the '-loglevel' option in the command line args and apply it.
  */
 void parse_loglevel(int argc, char **argv, const OptionDef *options);
@@ -427,6 +517,9 @@
  */
 void *grow_array(void *array, int elem_size, int *size, int new_size);
 
+#define GROW_ARRAY(array, nb_elems)\
+    array = grow_array(array, sizeof(*array), &nb_elems, nb_elems + 1)
+
 typedef struct FrameBuffer {
     uint8_t *base[4];
     uint8_t *data[4];
diff --git a/cmdutils_common_opts.h b/cmdutils_common_opts.h
index bfd71fe..1a84564 100644
--- a/cmdutils_common_opts.h
+++ b/cmdutils_common_opts.h
@@ -16,8 +16,6 @@
     { "sample_fmts", OPT_EXIT, {.func_arg = show_sample_fmts }, "show available audio sample formats" },
     { "loglevel"   , HAS_ARG,  {.func_arg = opt_loglevel},      "set libav* logging level", "loglevel" },
     { "v",           HAS_ARG,  {.func_arg = opt_loglevel},      "set libav* logging level", "loglevel" },
-    { "debug"      , HAS_ARG,  {.func_arg = opt_codec_debug},   "set debug flags", "flags" },
-    { "fdebug"     , HAS_ARG,  {.func_arg = opt_codec_debug},   "set debug flags", "flags" },
     { "report"     , 0,        {(void*)opt_report}, "generate a report" },
     { "max_alloc"  , HAS_ARG,  {.func_arg = opt_max_alloc},     "set maximum size of a single allocated block", "bytes" },
     { "cpuflags"   , HAS_ARG | OPT_EXPERT, {.func_arg = opt_cpuflags}, "force specific cpu flags", "flags" },
diff --git a/common.mak b/common.mak
index 0c48484..d6cb5f6 100644
--- a/common.mak
+++ b/common.mak
@@ -32,7 +32,7 @@
 CXXFLAGS   += $(CPPFLAGS) $(CFLAGS)
 YASMFLAGS  += $(IFLAGS:%=%/) -Pconfig.asm
 
-HOSTCCFLAGS = $(IFLAGS) $(HOSTCFLAGS)
+HOSTCCFLAGS = $(IFLAGS) $(HOSTCPPFLAGS) $(HOSTCFLAGS)
 LDFLAGS    := $(ALLFFLIBS:%=$(LD_PATH)lib%) $(LDFLAGS)
 
 define COMPILE
@@ -117,18 +117,24 @@
 	$(HOSTLD) $(HOSTLDFLAGS) $(HOSTLD_O) $< $(HOSTLIBS)
 
 $(OBJS):     | $(sort $(dir $(OBJS)))
+$(HOBJS):    | $(sort $(dir $(HOBJS)))
 $(HOSTOBJS): | $(sort $(dir $(HOSTOBJS)))
 $(TESTOBJS): | $(sort $(dir $(TESTOBJS)))
-$(HOBJS):    | $(sort $(dir $(HOBJS)))
 $(TOOLOBJS): | tools
 
-OBJDIRS := $(OBJDIRS) $(dir $(OBJS) $(HOSTOBJS) $(TESTOBJS) $(HOBJS))
+OBJDIRS := $(OBJDIRS) $(dir $(OBJS) $(HOBJS) $(HOSTOBJS) $(TESTOBJS))
 
 CLEANSUFFIXES     = *.d *.o *~ *.h.c *.map *.ver *.ho *.gcno *.gcda
 DISTCLEANSUFFIXES = *.pc
 LIBSUFFIXES       = *.a *.lib *.so *.so.* *.dylib *.dll *.def *.dll.a
 
+define RULES
 clean::
 	$(RM) $(OBJS) $(OBJS:.o=.d)
+	$(RM) $(HOSTPROGS)
+	$(RM) $(TOOLS)
+endef
+
+$(eval $(RULES))
 
 -include $(wildcard $(OBJS:.o=.d) $(HOSTOBJS:.o=.d) $(TESTOBJS:.o=.d) $(HOBJS:.o=.d))
diff --git a/configure b/configure
index 588104f..a9907ac 100755
--- a/configure
+++ b/configure
@@ -101,6 +101,7 @@
   --disable-runtime-cpudetect disable detecting cpu capabilities at runtime (smaller binary)
   --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
 
 Program options:
   --disable-programs       do not build command line programs
@@ -129,7 +130,6 @@
   --disable-pthreads       disable pthreads [auto]
   --disable-w32threads     disable Win32 threads [auto]
   --disable-os2threads     disable OS/2 threads [auto]
-  --enable-x11grab         enable X11 grabbing [no]
   --disable-network        disable network support [no]
   --disable-dct            disable DCT code
   --disable-dwt            disable DWT code
@@ -138,10 +138,12 @@
   --disable-mdct           disable MDCT code
   --disable-rdft           disable RDFT code
   --disable-fft            disable FFT code
+
+Hardware accelerators:
   --enable-dxva2           enable DXVA2 code
-  --enable-vaapi           enable VAAPI code [autodetect]
-  --enable-vda             enable VDA code   [autodetect]
-  --enable-vdpau           enable VDPAU code [autodetect]
+  --enable-vaapi           enable VAAPI code
+  --enable-vda             enable VDA code
+  --enable-vdpau           enable VDPAU code
 
 Individual component options:
   --disable-everything     disable all components listed below
@@ -186,6 +188,7 @@
   --enable-fontconfig      enable fontconfig
   --enable-frei0r          enable frei0r video filtering
   --enable-gnutls          enable gnutls [no]
+  --enable-iconv           enable 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]
@@ -213,6 +216,7 @@
   --enable-libpulse        enable Pulseaudio input via libpulse [no]
   --enable-librtmp         enable RTMP[E] support via librtmp [no]
   --enable-libschroedinger enable Dirac de/encoding via libschroedinger [no]
+  --enable-libsoxr         enable Include libsoxr resampling [no]
   --enable-libspeex        enable Speex de/encoding via libspeex [no]
   --enable-libstagefright-h264  enable H.264 decoding via libstagefright [no]
   --enable-libtheora       enable Theora encoding via libtheora [no]
@@ -223,13 +227,14 @@
   --enable-libvo-amrwbenc  enable AMR-WB encoding via libvo-amrwbenc [no]
   --enable-libvorbis       enable Vorbis en/decoding via libvorbis,
                            native implementation exists [no]
-  --enable-libvpx          enable VP8 de/encoding via libvpx [no]
+  --enable-libvpx          enable VP8 and VP9 de/encoding via libvpx [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-openal          enable OpenAL 1.1 capture support [no]
   --enable-openssl         enable openssl [no]
+  --enable-x11grab         enable X11 grabbing [no]
   --enable-zlib            enable zlib [autodetect]
 
 Advanced options (experts only):
@@ -251,6 +256,7 @@
   --ld=LD                  use linker LD [$ld_default]
   --host-cc=HOSTCC         use host C compiler HOSTCC
   --host-cflags=HCFLAGS    use HCFLAGS when compiling for host
+  --host-cppflags=HCPPFLAGS use HCPPFLAGS when compiling for host
   --host-ld=HOSTLD         use host linker HOSTLD
   --host-ldflags=HLDFLAGS  use HLDFLAGS when linking for host
   --host-libs=HLIBS        use libs HLIBS when linking for host
@@ -296,7 +302,7 @@
   --disable-armv5te        disable armv5te optimizations
   --disable-armv6          disable armv6 optimizations
   --disable-armv6t2        disable armv6t2 optimizations
-  --disable-armvfp         disable ARM VFP optimizations
+  --disable-vfp            disable VFP optimizations
   --disable-neon           disable NEON optimizations
   --disable-vis            disable VIS optimizations
   --disable-inline-asm     disable use of inline assembler
@@ -306,8 +312,6 @@
   --disable-mipsdspr2      disable MIPS DSP ASE R2 optimizations
   --disable-mipsfpu        disable floating point MIPS optimizations
   --disable-fast-unaligned consider unaligned accesses slow
-  --postproc-version=V     build libpostproc version V.
-                           Where V can be '$ALT_PP_VER_MAJOR.$ALT_PP_VER_MINOR.$ALT_PP_VER_MICRO' or 'current'. [$postproc_version_default]
 
 Developer options (useful when working on FFmpeg itself):
   --enable-coverage        build with test coverage instrumentation
@@ -582,12 +586,13 @@
     return 1
 }
 
-check_deps(){
+do_check_deps(){
     for cfg; do
         cfg="${cfg#!}"
         enabled ${cfg}_checking && die "Circular dependency for $cfg."
         disabled ${cfg}_checking && continue
         enable ${cfg}_checking
+        append allopts $cfg
 
         eval dep_all="\$${cfg}_deps"
         eval dep_any="\$${cfg}_deps_any"
@@ -597,7 +602,7 @@
         eval dep_ifn="\$${cfg}_if_any"
 
         pushvar cfg dep_all dep_any dep_sel dep_sgs dep_ifa dep_ifn
-        check_deps $dep_all $dep_any $dep_sel $dep_sgs $dep_ifa $dep_ifn
+        do_check_deps $dep_all $dep_any $dep_sel $dep_sgs $dep_ifa $dep_ifn
         popvar cfg dep_all dep_any dep_sel dep_sgs dep_ifa dep_ifn
 
         [ -n "$dep_ifa" ] && { enabled_all $dep_ifa && enable_weak $cfg; }
@@ -607,8 +612,6 @@
         disabled_any $dep_sel && disable $cfg
 
         if enabled $cfg; then
-            eval dep_extralibs="\$${cfg}_extralibs"
-            test -n "$dep_extralibs" && add_extralibs $dep_extralibs
             enable_deep $dep_sel
             enable_deep_weak $dep_sgs
         fi
@@ -617,6 +620,18 @@
     done
 }
 
+check_deps(){
+    unset allopts
+
+    do_check_deps "$@"
+
+    for cfg in $allopts; do
+        enabled $cfg || continue
+        eval dep_extralibs="\$${cfg}_extralibs"
+        test -n "$dep_extralibs" && add_extralibs $dep_extralibs
+    done
+}
+
 print_config(){
     pfx=$1
     files=$2
@@ -686,6 +701,10 @@
     prepend extralibs $($ldflags_filter "$@")
 }
 
+add_host_cppflags(){
+    append host_cppflags "$@"
+}
+
 add_host_cflags(){
     append host_cflags $($host_cflags_filter "$@")
 }
@@ -740,9 +759,9 @@
 
 check_as(){
     log check_as "$@"
-    cat > $TMPC
-    log_file $TMPC
-    check_cmd $as $CPPFLAGS $ASFLAGS "$@" $AS_C $(as_o $TMPO) $TMPC
+    cat > $TMPS
+    log_file $TMPS
+    check_cmd $as $CPPFLAGS $ASFLAGS "$@" $AS_C $(as_o $TMPO) $TMPS
 }
 
 check_inline_asm(){
@@ -751,11 +770,17 @@
     code="$2"
     shift 2
     disable $name
-    check_as "$@" <<EOF && enable $name
+    check_cc "$@" <<EOF && enable $name
 void foo(void){ __asm__ volatile($code); }
 EOF
 }
 
+check_insn(){
+    log check_insn "$@"
+    check_inline_asm ${1}_inline "\"$2\""
+    echo "$2" | check_as && enable ${1}_external || disable ${1}_external
+}
+
 check_yasm(){
     log check_yasm "$@"
     echo "$1" > $TMPS
@@ -772,8 +797,8 @@
     log check_ld "$@"
     type=$1
     shift 1
-    flags=$(filter_out '-l*' $@)
-    libs=$(filter '-l*' $@)
+    flags=$(filter_out '-l*|*.so' $@)
+    libs=$(filter '-l*|*.so' $@)
     check_$type $($cflags_filter $flags) || return
     flags=$($ldflags_filter $flags)
     libs=$($ldflags_filter $libs)
@@ -1047,6 +1072,13 @@
     check_cmd $host_cc $host_cflags "$@" $HOSTCC_C $(hostcc_o $TMPO) $TMPC
 }
 
+check_host_cppflags(){
+    log check_host_cppflags "$@"
+    check_host_cc "$@" <<EOF && append host_cppflags "$@"
+int x;
+EOF
+}
+
 check_host_cflags(){
     log check_host_cflags "$@"
     set -- $($host_cflags_filter "$@")
@@ -1084,53 +1116,14 @@
     protocols
 "
 
-DOCUMENT_LIST="
-    doc
-    htmlpages
-    manpages
-    podpages
-    txtpages
-"
-
-LIBRARY_LIST="
-    avcodec
-    avdevice
-    avfilter
-    avformat
-    avresample
-    avutil
-    swresample
-    swscale
-"
-
-PROGRAM_LIST="
-    ffplay
-    ffprobe
-    ffserver
-    ffmpeg
-"
-
-CONFIG_LIST="
-    $COMPONENT_LIST
-    $DOCUMENT_LIST
-    $LIBRARY_LIST
-    $PROGRAM_LIST
+EXTERNAL_LIBRARY_LIST="
     avisynth
     bzlib
     crystalhd
-    dct
-    dwt
-    dxva2
-    fast_unaligned
-    fft
     fontconfig
     frei0r
-    ftrapv
     gnutls
-    gpl
-    gray
-    hardcoded_tables
-    incompatible_fork_abi
+    iconv
     libaacplus
     libass
     libbluray
@@ -1156,6 +1149,7 @@
     libpulse
     librtmp
     libschroedinger
+    libsoxr
     libspeex
     libstagefright_h264
     libtheora
@@ -1169,6 +1163,62 @@
     libx264
     libxavs
     libxvid
+    openal
+    openssl
+    x11grab
+    zlib
+"
+
+DOCUMENT_LIST="
+    doc
+    htmlpages
+    manpages
+    podpages
+    txtpages
+"
+
+HWACCEL_LIST="
+    dxva2
+    vaapi
+    vda
+    vdpau
+"
+
+LIBRARY_LIST="
+    avcodec
+    avdevice
+    avfilter
+    avformat
+    avresample
+    avutil
+    postproc
+    swresample
+    swscale
+"
+
+PROGRAM_LIST="
+    ffplay
+    ffprobe
+    ffserver
+    ffmpeg
+"
+
+CONFIG_LIST="
+    $COMPONENT_LIST
+    $DOCUMENT_LIST
+    $EXTERNAL_LIBRARY_LIST
+    $HWACCEL_LIST
+    $LIBRARY_LIST
+    $PROGRAM_LIST
+    dct
+    dwt
+    fast_unaligned
+    fft
+    ftrapv
+    gpl
+    gray
+    hardcoded_tables
+    incompatible_fork_abi
     lsp
     lzo
     mdct
@@ -1176,10 +1226,7 @@
     memory_poisoning
     network
     nonfree
-    openal
-    openssl
     pic
-    postproc
     rdft
     runtime_cpudetect
     safe_bitstream_reader
@@ -1189,13 +1236,8 @@
     static
     swscale_alpha
     thumb
-    vaapi
-    vda
-    vdpau
     version3
     xmm_clobber_test
-    x11grab
-    zlib
 "
 
 THREADS_LIST='
@@ -1235,8 +1277,8 @@
     armv5te
     armv6
     armv6t2
-    armvfp
     neon
+    vfp
     vfpv3
 '
 
@@ -1282,6 +1324,7 @@
 MATH_FUNCS="
     atanf
     atan2f
+    cbrt
     cbrtf
     cosf
     exp2
@@ -1325,6 +1368,8 @@
     asm_types_h
     attribute_may_alias
     attribute_packed
+    cdio_paranoia_h
+    cdio_paranoia_paranoia_h
     clock_gettime
     closesocket
     cmov
@@ -1361,6 +1406,7 @@
     gettimeofday
     glob
     gnu_as
+    gsm_h
     ibm_asm
     inet_aton
     io_h
@@ -1387,6 +1433,7 @@
     mprotect
     msvcrt
     nanosleep
+    openjpeg_1_5_openjpeg_h
     PeekNamedPipe
     perl
     pod2man
@@ -1394,6 +1441,7 @@
     posix_memalign
     pthread_cancel
     rdtsc
+    rsync_contimeout
     sched_getaffinity
     sdl
     sdl_video_size
@@ -1440,10 +1488,11 @@
     xmm_clobbers
 "
 
-# options emitted with CONFIG_ prefix but not available on command line
+# options emitted with CONFIG_ prefix but not available on the command line
 CONFIG_EXTRA="
     aandcttables
     ac3dsp
+    audio_frame_queue
     error_resilience
     gcrypt
     golomb
@@ -1462,7 +1511,9 @@
     nettle
     rangecoder
     rtpdec
+    rtpenc_chain
     sinewin
+    videodsp
     vp3dsp
 "
 
@@ -1518,7 +1569,6 @@
     nm
     optflags
     pkg_config
-    postproc_version
     progs_suffix
     random_seed
     samples
@@ -1536,6 +1586,7 @@
 CMDLINE_APPEND="
     extra_cflags
     extra_cxxflags
+    host_cppflags
 "
 
 # code dependency declarations
@@ -1545,9 +1596,11 @@
 armv5te_deps="arm"
 armv6_deps="arm"
 armv6t2_deps="arm"
-armvfp_deps="arm"
 neon_deps="arm"
-vfpv3_deps="armvfp"
+vfp_deps="arm"
+vfpv3_deps="vfp"
+
+map 'eval ${v}_inline_deps=inline_asm' $ARCH_EXT_LIST_ARM
 
 mipsfpu_deps="mips"
 mips32r2_deps="mips"
@@ -1587,8 +1640,8 @@
 
 aligned_stack_if_any="ppc x86"
 fast_64bit_if_any="alpha ia64 mips64 parisc64 ppc64 sparc64 x86_64"
-fast_clz_if_any="alpha armv5te avr32 mips ppc x86"
-fast_unaligned_if_any="armv6 ppc x86"
+fast_clz_if_any="alpha avr32 mips ppc x86"
+fast_unaligned_if_any="ppc x86"
 
 inline_asm_deps="!tms470"
 need_memalign="altivec neon sse"
@@ -1603,11 +1656,12 @@
 rdft_select="fft"
 mpegaudio_select="mpegaudiodsp"
 mpegaudiodsp_select="dct"
+mpegvideo_select="videodsp"
 mpegvideoenc_select="mpegvideo"
 
-# decoders / encoders / hardware accelerators
+# decoders / encoders
 aac_decoder_select="mdct sinewin"
-aac_encoder_select="mdct sinewin"
+aac_encoder_select="audio_frame_queue mdct sinewin"
 aac_latm_decoder_select="aac_decoder aac_latm_parser"
 ac3_decoder_select="mdct ac3dsp ac3_parser"
 ac3_encoder_select="mdct ac3dsp"
@@ -1626,7 +1680,7 @@
 cscd_decoder_select="lzo"
 cscd_decoder_suggest="zlib"
 dca_decoder_select="mdct"
-dirac_decoder_select="dwt golomb"
+dirac_decoder_select="dwt golomb videodsp"
 dnxhd_encoder_select="aandcttables mpegvideoenc"
 dxa_decoder_select="zlib"
 eac3_decoder_select="ac3_decoder"
@@ -1651,18 +1705,9 @@
 h261_encoder_select="aandcttables mpegvideoenc"
 h263_decoder_select="error_resilience h263_parser mpegvideo"
 h263_encoder_select="aandcttables error_resilience mpegvideoenc"
-h263_vaapi_hwaccel_select="vaapi h263_decoder"
 h263i_decoder_select="h263_decoder"
 h263p_encoder_select="h263_encoder"
-h264_crystalhd_decoder_select="crystalhd h264_mp4toannexb_bsf h264_parser"
-h264_decoder_select="error_resilience golomb h264chroma h264dsp h264pred h264qpel mpegvideo"
-h264_dxva2_hwaccel_deps="dxva2api_h"
-h264_dxva2_hwaccel_select="dxva2 h264_decoder"
-h264_vaapi_hwaccel_select="vaapi h264_decoder"
-h264_vda_decoder_select="vda h264_parser h264_decoder"
-h264_vda_hwaccel_deps="VideoDecodeAcceleration_VDADecoder_h pthreads"
-h264_vda_hwaccel_select="vda h264_decoder"
-h264_vdpau_decoder_select="vdpau h264_decoder"
+h264_decoder_select="error_resilience golomb h264chroma h264dsp h264pred h264qpel mpegvideo videodsp"
 huffyuv_encoder_select="huffman"
 iac_decoder_select="fft mdct sinewin"
 imc_decoder_select="fft mdct sinewin"
@@ -1685,26 +1730,14 @@
 mp3on4float_decoder_select="mpegaudio"
 mpc7_decoder_select="mpegaudiodsp"
 mpc8_decoder_select="mpegaudiodsp"
-mpeg_vdpau_decoder_select="vdpau mpegvideo_decoder"
 mpeg_xvmc_decoder_deps="X11_extensions_XvMClib_h"
 mpeg_xvmc_decoder_select="mpegvideo_decoder"
-mpeg1_vdpau_decoder_select="vdpau mpeg1video_decoder"
-mpeg1_vdpau_hwaccel_select="vdpau mpeg1video_decoder"
 mpeg1video_decoder_select="error_resilience mpegvideo"
 mpeg1video_encoder_select="aandcttables error_resilience mpegvideoenc"
-mpeg2_crystalhd_decoder_select="crystalhd"
-mpeg2_dxva2_hwaccel_deps="dxva2api_h"
-mpeg2_dxva2_hwaccel_select="dxva2 mpeg2video_decoder"
-mpeg2_vdpau_hwaccel_select="vdpau mpeg2video_decoder"
-mpeg2_vaapi_hwaccel_select="vaapi mpeg2video_decoder"
 mpeg2video_decoder_select="error_resilience mpegvideo"
 mpeg2video_encoder_select="aandcttables error_resilience mpegvideoenc"
-mpeg4_crystalhd_decoder_select="crystalhd"
 mpeg4_decoder_select="h263_decoder mpeg4video_parser"
 mpeg4_encoder_select="h263_encoder"
-mpeg4_vaapi_hwaccel_select="vaapi mpeg4_decoder"
-mpeg4_vdpau_decoder_select="vdpau mpeg4_decoder"
-msmpeg4_crystalhd_decoder_select="crystalhd"
 msmpeg4v1_decoder_select="h263_decoder"
 msmpeg4v1_encoder_select="h263_encoder"
 msmpeg4v2_decoder_select="h263_decoder"
@@ -1713,13 +1746,13 @@
 msmpeg4v3_encoder_select="h263_encoder"
 mss2_decoder_select="vc1_decoder"
 nellymoser_decoder_select="mdct sinewin"
-nellymoser_encoder_select="mdct sinewin"
+nellymoser_encoder_select="audio_frame_queue mdct sinewin"
 nuv_decoder_select="lzo"
 png_decoder_select="zlib"
 png_encoder_select="zlib"
 qcelp_decoder_select="lsp"
 qdm2_decoder_select="mdct rdft mpegaudiodsp"
-ra_144_encoder_select="lpc"
+ra_144_encoder_select="audio_frame_queue lpc"
 ralf_decoder_select="golomb"
 rv10_decoder_select="h263_decoder"
 rv10_encoder_select="h263_encoder"
@@ -1745,21 +1778,16 @@
 tscc_decoder_select="zlib"
 twinvq_decoder_select="mdct lsp sinewin"
 utvideo_encoder_select="huffman"
-vc1_crystalhd_decoder_select="crystalhd"
 vc1_decoder_select="h263_decoder h264chroma h264qpel"
-vc1_dxva2_hwaccel_deps="dxva2api_h"
-vc1_dxva2_hwaccel_select="dxva2 vc1_decoder"
-vc1_vaapi_hwaccel_select="vaapi vc1_decoder"
-vc1_vdpau_decoder_select="vdpau vc1_decoder"
 vc1image_decoder_select="vc1_decoder"
 vorbis_decoder_select="mdct"
 vorbis_encoder_select="mdct"
-vp3_decoder_select="vp3dsp"
-vp5_decoder_select="vp3dsp"
-vp6_decoder_select="huffman vp3dsp"
+vp3_decoder_select="vp3dsp videodsp"
+vp5_decoder_select="vp3dsp videodsp"
+vp6_decoder_select="huffman vp3dsp videodsp"
 vp6a_decoder_select="vp6_decoder"
 vp6f_decoder_select="vp6_decoder"
-vp8_decoder_select="h264pred h264qpel"
+vp8_decoder_select="h264pred videodsp"
 wmapro_decoder_select="mdct sinewin"
 wmav1_decoder_select="mdct sinewin"
 wmav1_encoder_select="mdct sinewin"
@@ -1771,10 +1799,6 @@
 wmv2_decoder_select="h263_decoder"
 wmv2_encoder_select="h263_encoder"
 wmv3_decoder_select="vc1_decoder"
-wmv3_crystalhd_decoder_select="crystalhd"
-wmv3_dxva2_hwaccel_select="vc1_dxva2_hwaccel"
-wmv3_vaapi_hwaccel_select="vc1_vaapi_hwaccel"
-wmv3_vdpau_decoder_select="vc1_vdpau_decoder"
 wmv3image_decoder_select="wmv3_decoder"
 zerocodec_decoder_select="zlib"
 zlib_decoder_select="zlib"
@@ -1782,13 +1806,69 @@
 zmbv_decoder_select="zlib"
 zmbv_encoder_select="zlib"
 
+# hardware accelerators
 crystalhd_deps="libcrystalhd_libcrystalhd_if_h"
+dxva2_deps="dxva2api_h"
 vaapi_deps="va_va_h"
 vda_deps="VideoDecodeAcceleration_VDADecoder_h pthreads"
+vda_extralibs="-framework CoreFoundation -framework VideoDecodeAcceleration -framework QuartzCore"
 vdpau_deps="vdpau_vdpau_h vdpau_vdpau_x11_h"
 
+h263_vaapi_hwaccel_deps="vaapi"
+h263_vaapi_hwaccel_select="h263_decoder"
+h263_vdpau_hwaccel_deps="vdpau"
+h263_vdpau_hwaccel_select="h263_decoder"
+h264_crystalhd_decoder_select="crystalhd h264_mp4toannexb_bsf h264_parser"
+h264_dxva2_hwaccel_deps="dxva2"
+h264_dxva2_hwaccel_select="h264_decoder"
+h264_vaapi_hwaccel_deps="vaapi"
+h264_vaapi_hwaccel_select="h264_decoder"
+h264_vda_decoder_deps="vda"
+h264_vda_decoder_select="h264_decoder"
+h264_vda_hwaccel_deps="vda"
+h264_vda_hwaccel_select="h264_decoder"
+h264_vdpau_decoder_deps="vdpau"
+h264_vdpau_decoder_select="h264_decoder"
+h264_vdpau_hwaccel_deps="vdpau"
+h264_vdpau_hwaccel_select="h264_decoder"
+mpeg_vdpau_decoder_deps="vdpau"
+mpeg_vdpau_decoder_select="mpegvideo_decoder"
+mpeg1_vdpau_decoder_deps="vdpau"
+mpeg1_vdpau_decoder_select="mpeg1video_decoder"
+mpeg1_vdpau_hwaccel_deps="vdpau"
+mpeg1_vdpau_hwaccel_select="mpeg1video_decoder"
+mpeg2_crystalhd_decoder_select="crystalhd"
+mpeg2_dxva2_hwaccel_deps="dxva2"
+mpeg2_dxva2_hwaccel_select="mpeg2video_decoder"
+mpeg2_vaapi_hwaccel_deps="vaapi"
+mpeg2_vaapi_hwaccel_select="mpeg2video_decoder"
+mpeg2_vdpau_hwaccel_deps="vdpau"
+mpeg2_vdpau_hwaccel_select="mpeg2video_decoder"
+mpeg4_crystalhd_decoder_select="crystalhd"
+mpeg4_vaapi_hwaccel_deps="vaapi"
+mpeg4_vaapi_hwaccel_select="mpeg4_decoder"
+mpeg4_vdpau_decoder_deps="vdpau"
+mpeg4_vdpau_decoder_select="mpeg4_decoder"
+mpeg4_vdpau_hwaccel_deps="vdpau"
+mpeg4_vdpau_hwaccel_select="mpeg4_decoder"
+msmpeg4_crystalhd_decoder_select="crystalhd"
+vc1_crystalhd_decoder_select="crystalhd"
+vc1_dxva2_hwaccel_deps="dxva2"
+vc1_dxva2_hwaccel_select="vc1_decoder"
+vc1_vaapi_hwaccel_deps="vaapi"
+vc1_vaapi_hwaccel_select="vc1_decoder"
+vc1_vdpau_decoder_deps="vdpau"
+vc1_vdpau_decoder_select="vc1_decoder"
+vc1_vdpau_hwaccel_deps="vdpau"
+vc1_vdpau_hwaccel_select="vc1_decoder"
+wmv3_crystalhd_decoder_select="crystalhd"
+wmv3_dxva2_hwaccel_select="vc1_dxva2_hwaccel"
+wmv3_vaapi_hwaccel_select="vc1_vaapi_hwaccel"
+wmv3_vdpau_decoder_select="vc1_vdpau_decoder"
+wmv3_vdpau_hwaccel_select="vc1_vdpau_hwaccel"
+
 # parsers
-h264_parser_select="error_resilience golomb h264dsp h264pred mpegvideo"
+h264_parser_select="error_resilience golomb h264chroma h264dsp h264pred h264qpel mpegvideo videodsp"
 mpeg4video_parser_select="error_resilience mpegvideo"
 mpegvideo_parser_select="error_resilience mpegvideo"
 vc1_parser_select="error_resilience mpegvideo"
@@ -1797,7 +1877,9 @@
 libaacplus_encoder_deps="libaacplus"
 libcelt_decoder_deps="libcelt"
 libfaac_encoder_deps="libfaac"
+libfaac_encoder_select="audio_frame_queue"
 libfdk_aac_encoder_deps="libfdk_aac"
+libfdk_aac_encoder_select="audio_frame_queue"
 libgsm_decoder_deps="libgsm"
 libgsm_encoder_deps="libgsm"
 libgsm_ms_decoder_deps="libgsm"
@@ -1806,26 +1888,34 @@
 libilbc_encoder_deps="libilbc"
 libmodplug_demuxer_deps="libmodplug"
 libmp3lame_encoder_deps="libmp3lame"
+libmp3lame_encoder_select="audio_frame_queue"
 libopencore_amrnb_decoder_deps="libopencore_amrnb"
 libopencore_amrnb_encoder_deps="libopencore_amrnb"
+libopencore_amrnb_encoder_select="audio_frame_queue"
 libopencore_amrwb_decoder_deps="libopencore_amrwb"
 libopenjpeg_decoder_deps="libopenjpeg"
 libopenjpeg_encoder_deps="libopenjpeg"
 libopus_decoder_deps="libopus"
 libopus_encoder_deps="libopus"
+libopus_encoder_select="audio_frame_queue"
 libschroedinger_decoder_deps="libschroedinger"
 libschroedinger_encoder_deps="libschroedinger"
 libspeex_decoder_deps="libspeex"
 libspeex_encoder_deps="libspeex"
+libspeex_encoder_select="audio_frame_queue"
 libstagefright_h264_decoder_deps="libstagefright_h264"
 libtheora_encoder_deps="libtheora"
 libtwolame_encoder_deps="libtwolame"
 libvo_aacenc_encoder_deps="libvo_aacenc"
+libvo_aacenc_encoder_select="audio_frame_queue"
 libvo_amrwbenc_encoder_deps="libvo_amrwbenc"
 libvorbis_decoder_deps="libvorbis"
 libvorbis_encoder_deps="libvorbis"
-libvpx_decoder_deps="libvpx"
-libvpx_encoder_deps="libvpx"
+libvorbis_encoder_select="audio_frame_queue"
+libvpx_vp8_decoder_deps="libvpx"
+libvpx_vp8_encoder_deps="libvpx"
+libvpx_vp9_decoder_deps="libvpx"
+libvpx_vp9_encoder_deps="libvpx"
 libx264_encoder_deps="libx264"
 libx264rgb_encoder_deps="libx264"
 libxavs_encoder_deps="libxavs"
@@ -1850,6 +1940,7 @@
 matroska_audio_muxer_select="matroska_muxer"
 matroska_demuxer_suggest="bzlib lzo zlib"
 mov_demuxer_suggest="zlib"
+mov_muxer_select="rtpenc_chain"
 mp3_demuxer_select="mpegaudio_parser"
 mp4_muxer_select="mov_muxer"
 mpegts_muxer_select="adts_muxer latm_muxer mpegvideo"
@@ -1861,16 +1952,18 @@
 rtp_muxer_select="mpegvideo"
 rtpdec_select="asf_demuxer rm_demuxer rtp_protocol mpegts_demuxer mov_demuxer"
 rtsp_demuxer_select="http_protocol rtpdec"
-rtsp_muxer_select="rtp_muxer http_protocol rtp_protocol"
+rtsp_muxer_select="rtp_muxer http_protocol rtp_protocol rtpenc_chain"
 sap_demuxer_select="sdp_demuxer"
-sap_muxer_select="rtp_muxer rtp_protocol"
+sap_muxer_select="rtp_muxer rtp_protocol rtpenc_chain"
 sdp_demuxer_select="rtpdec"
 smoothstreaming_muxer_select="ismv_muxer"
 spdif_muxer_select="aac_parser"
 tak_demuxer_select="tak_parser"
 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"
 
 # indevs / outdevs
 alsa_indev_deps="alsa_asoundlib_h snd_pcm_htimestamp"
@@ -1907,10 +2000,8 @@
 ffrtmpcrypt_protocol_select="tcp_protocol"
 ffrtmphttp_protocol_deps="!librtmp_protocol"
 ffrtmphttp_protocol_select="http_protocol"
-gopher_protocol_deps="network"
-httpproxy_protocol_deps="network"
+gopher_protocol_select="network"
 httpproxy_protocol_select="tcp_protocol"
-http_protocol_deps="network"
 http_protocol_select="tcp_protocol"
 https_protocol_select="tls_protocol"
 librtmp_protocol_deps="librtmp"
@@ -1919,7 +2010,7 @@
 librtmpt_protocol_deps="librtmp"
 librtmpte_protocol_deps="librtmp"
 mmsh_protocol_select="http_protocol"
-mmst_protocol_deps="network"
+mmst_protocol_select="network"
 rtmp_protocol_deps="!librtmp_protocol"
 rtmp_protocol_select="tcp_protocol"
 rtmpe_protocol_select="ffrtmpcrypt_protocol"
@@ -1929,11 +2020,13 @@
 rtmpte_protocol_select="ffrtmpcrypt_protocol ffrtmphttp_protocol"
 rtmpts_protocol_select="ffrtmphttp_protocol https_protocol"
 rtp_protocol_select="udp_protocol"
-sctp_protocol_deps="network struct_sctp_event_subscribe"
-tcp_protocol_deps="network"
+sctp_protocol_deps="struct_sctp_event_subscribe"
+sctp_protocol_select="network"
+srtp_protocol_select="rtp_protocol"
+tcp_protocol_select="network"
 tls_protocol_deps_any="openssl gnutls"
 tls_protocol_select="tcp_protocol"
-udp_protocol_deps="network"
+udp_protocol_select="network"
 
 # filters
 aconvert_filter_deps="swresample"
@@ -1957,19 +2050,24 @@
 frei0r_src_filter_deps="frei0r dlopen"
 frei0r_src_filter_extralibs='$ldl'
 geq_filter_deps="gpl"
+histeq_filter_deps="gpl"
 hqdn3d_filter_deps="gpl"
 hue_filter_deps="gpl"
+kerndeint_filter_deps="gpl"
 movie_filter_deps="avcodec avformat"
-mp_filter_deps="gpl avcodec swscale postproc inline_asm"
+mp_filter_deps="gpl avcodec swscale inline_asm"
 mptestsrc_filter_deps="gpl"
 negate_filter_deps="lut_filter"
+noise_filter_deps="gpl"
 resample_filter_deps="avresample"
 ocv_filter_deps="libopencv"
 pan_filter_deps="swresample"
+pp_filter_deps="gpl postproc"
 removelogo_filter_deps="avcodec avformat swscale"
 scale_filter_deps="swscale"
 smartblur_filter_deps="gpl swscale"
 showspectrum_filter_deps="avcodec rdft"
+subtitles_filter_deps="avformat avcodec libass"
 super2xsai_filter_deps="gpl"
 tinterlace_filter_deps="gpl"
 yadif_filter_deps="gpl"
@@ -1983,7 +2081,7 @@
 avfilter_deps="avutil"
 avformat_deps="avutil avcodec"
 avresample_deps="avutil"
-postproc_deps="gpl"
+postproc_deps="avutil gpl"
 swscale_deps="avutil"
 
 # programs
@@ -2015,7 +2113,6 @@
 libdir_default='${prefix}/lib'
 mandir_default='${prefix}/share/man'
 shlibdir_default="$libdir_default"
-postproc_version_default="current"
 
 # toolchain
 ar_default="ar"
@@ -2024,7 +2121,7 @@
 host_cc_default="gcc"
 cp_f="cp -f"
 install="install"
-ln_s="ln -sf"
+ln_s="ln -s -f"
 nm_default="nm -g"
 objformat="elf"
 pkg_config_default=pkg-config
@@ -2042,23 +2139,15 @@
 target_os_default=$(tolower $(uname -s))
 host_os=$target_os_default
 
-# alternative libpostproc version
-ALT_PP_VER_MAJOR=51
-ALT_PP_VER_MINOR=2
-ALT_PP_VER_MICRO=101
-ALT_PP_VER=$ALT_PP_VER_MAJOR.$ALT_PP_VER_MINOR.$ALT_PP_VER_MICRO
-
 # configurable options
 enable $PROGRAM_LIST
 enable $DOCUMENT_LIST
 enable $(filter_out avresample $LIBRARY_LIST)
-enable postproc
 enable stripping
 
 enable asm
 enable debug
 enable doc
-enable network
 enable optimizations
 enable runtime_cpudetect
 enable safe_bitstream_reader
@@ -2099,7 +2188,8 @@
 HOSTCC_O='-o $@'
 HOSTLD_O='-o $@'
 
-host_cflags='-D_ISOC99_SOURCE -D_XOPEN_SOURCE=600 -O3 -g'
+host_cflags='-O3 -g'
+host_cppflags='-D_ISOC99_SOURCE -D_XOPEN_SOURCE=600'
 host_libs='-lm'
 host_cflags_filter=echo
 host_ldflags_filter=echo
@@ -2176,10 +2266,14 @@
     exit 1
 }
 
+print_3_columns() {
+    cat | tr ' ' '\n' | sort | pr -r -3 -t
+}
+
 show_list() {
     suffix=_$1
     shift
-    echo $* | sed s/$suffix//g | tr ' ' '\n' | sort | pr -3 -t
+    echo $* | sed s/$suffix//g | print_3_columns
     exit 0
 }
 
@@ -2207,13 +2301,17 @@
 for opt do
     optval="${opt#*=}"
     case "$opt" in
-        --extra-ldflags=*) add_ldflags $optval
+        --extra-ldflags=*)
+            add_ldflags $optval
         ;;
-        --extra-libs=*) add_extralibs $optval
+        --extra-libs=*)
+            add_extralibs $optval
         ;;
-        --disable-devices) disable $INDEV_LIST $OUTDEV_LIST
+        --disable-devices)
+            disable $INDEV_LIST $OUTDEV_LIST
         ;;
-        --enable-debug=*) debuglevel="$optval"
+        --enable-debug=*)
+            debuglevel="$optval"
         ;;
         --disable-programs)
             disable $PROGRAM_LIST
@@ -2221,6 +2319,10 @@
         --disable-everything)
             map 'eval unset \${$(toupper ${v%s})_LIST}' $COMPONENT_LIST
         ;;
+        --disable-all)
+            map 'eval unset \${$(toupper ${v%s})_LIST}' $COMPONENT_LIST
+            disable $LIBRARY_LIST $PROGRAM_LIST doc
+        ;;
         --enable-random|--disable-random)
             action=${opt%%-random}
             do_random ${action#--} $COMPONENT_LIST
@@ -2286,18 +2388,6 @@
         die "Must specify target arch and OS when cross-compiling"
 fi
 
-set_default postproc_version
-
-# Check if we should build alternative libpostproc version instead of current
-if   test "$postproc_version" = $ALT_PP_VER; then
-  LIBPOSTPROC_VERSION=$ALT_PP_VER
-  LIBPOSTPROC_VERSION_MAJOR=$ALT_PP_VER_MAJOR
-  LIBPOSTPROC_VERSION_MINOR=$ALT_PP_VER_MINOR
-  LIBPOSTPROC_VERSION_MICRO=$ALT_PP_VER_MICRO
-elif test "$postproc_version" != current; then
-  die "Invalid argument to --postproc-version. See --help output."
-fi
-
 ar_default="${cross_prefix}${ar_default}"
 cc_default="${cross_prefix}${cc_default}"
 cxx_default="${cross_prefix}${cxx_default}"
@@ -2431,6 +2521,7 @@
             -fno-math-errno)      ;;
             -fno-common)          ;;
             -fno-signed-zeros)    ;;
+            -fPIC)                ;;
             -lz)                  echo zlib.lib ;;
             -lavifil32)           echo vfw32.lib ;;
             -lavicap32)           echo vfw32.lib user32.lib ;;
@@ -2470,7 +2561,8 @@
                     core2)              echo -xarch=ssse3 -xchip=core2   ;;
                     corei7)           echo -xarch=sse4_2 -xchip=nehalem  ;;
                     corei7-avx)       echo -xarch=avx -xchip=sandybridge ;;
-                    amdfam10|barcelona|bdver*) echo -xarch=sse4_1        ;;
+                    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          ;;
@@ -2481,7 +2573,8 @@
             -fomit-frame-pointer) echo -xregs=frameptr    ;;
             -fPIC)                echo -KPIC -xcode=pic32 ;;
             -W*,*)                echo $flag              ;;
-            -f*-*|-W*)                                    ;;
+            -f*-*|-W*|-mimpure-text)                      ;;
+            -shared)              echo -G                 ;;
             *)                    echo $flag              ;;
         esac
     done
@@ -2544,7 +2637,7 @@
         fi
         _cflags_speed='-O3'
         _cflags_size='-Os'
-    elif $_cc --version 2>/dev/null | grep -q Intel; then
+    elif $_cc --version 2>/dev/null | grep -q ^icc; then
         _type=icc
         _ident=$($_cc --version | head -n1)
         _depflags='-MMD'
@@ -2804,10 +2897,7 @@
 enable $arch
 
 # Add processor-specific flags
-if test "$cpu" = generic; then
-    : do nothing
-
-elif enabled aarch64; then
+if enabled aarch64; then
 
     case $cpu in
         armv*)
@@ -2824,6 +2914,37 @@
 
 elif enabled arm; then
 
+    check_arm_arch() {
+        check_cpp_condition stddef.h \
+            "defined __ARM_ARCH_${1}__ || defined __TARGET_ARCH_${2:-$1}" \
+            $cpuflags
+    }
+
+    probe_arm_arch() {
+        if   check_arm_arch 4;        then echo armv4;
+        elif check_arm_arch 4T;       then echo armv4t;
+        elif check_arm_arch 5;        then echo armv5;
+        elif check_arm_arch 5E;       then echo armv5e;
+        elif check_arm_arch 5T;       then echo armv5t;
+        elif check_arm_arch 5TE;      then echo armv5te;
+        elif check_arm_arch 5TEJ;     then echo armv5te;
+        elif check_arm_arch 6;        then echo armv6;
+        elif check_arm_arch 6J;       then echo armv6j;
+        elif check_arm_arch 6K;       then echo armv6k;
+        elif check_arm_arch 6Z;       then echo armv6z;
+        elif check_arm_arch 6ZK;      then echo armv6zk;
+        elif check_arm_arch 6T2;      then echo armv6t2;
+        elif check_arm_arch 7;        then echo armv7;
+        elif check_arm_arch 7A  7_A;  then echo armv7-a;
+        elif check_arm_arch 7R  7_R;  then echo armv7-r;
+        elif check_arm_arch 7M  7_M;  then echo armv7-m;
+        elif check_arm_arch 7EM 7E_M; then echo armv7-m;
+        elif check_arm_arch 8A  8_A;  then echo armv8-a;
+        fi
+    }
+
+    [ "$cpu" = generic ] && cpu=$(probe_arm_arch)
+
     case $cpu in
         armv*)
             cpuflags="-march=$cpu"
@@ -2838,10 +2959,16 @@
                 arm11*)                                  subarch=armv6   ;;
                 arm[79]*e*|arm9[24]6*|arm96*|arm102[26]) subarch=armv5te ;;
                 armv4*|arm7*|arm9[24]*)                  subarch=armv4   ;;
+                *)                             subarch=$(probe_arm_arch) ;;
             esac
         ;;
     esac
 
+    case "$subarch" in
+        armv5t*)    enable fast_clz                ;;
+        armv[6-8]*) enable fast_clz fast_unaligned ;;
+    esac
+
 elif enabled avr32; then
 
     case $cpu in
@@ -2982,8 +3109,10 @@
 
 fi
 
-add_cflags $cpuflags
-add_asflags $cpuflags
+if [ "$cpu" != generic ]; then
+    add_cflags  $cpuflags
+    add_asflags $cpuflags
+fi
 
 # compiler sanity check
 check_exec <<EOF
@@ -3020,7 +3149,7 @@
 }
 
 case "$arch" in
-    alpha|ia64)
+    aarch64|alpha|ia64)
         spic=$shared
     ;;
     mips)
@@ -3033,6 +3162,7 @@
     ;;
     ppc)
         check_64bit ppc ppc64 'sizeof(void *) > 4'
+        spic=$shared
     ;;
     sparc)
         check_64bit sparc sparc64 'sizeof(void *) > 4'
@@ -3082,15 +3212,9 @@
         enabled gcc || check_ldflags -Wl,-zmuldefs
         ;;
     openbsd|bitrig)
-        # On OpenBSD 4.5. the compiler does not use PIC unless
-        # explicitly using -fPIC. FFmpeg builds fine without PIC,
-        # however the generated executable will not do anything
-        # (simply quits with exit-code 1, no crash, no output).
-        # Thus explicitly enable PIC here.
-        enable pic
         disable symver
         SHFLAGS='-shared'
-        SLIBNAME_WITH_MAJOR='$(SLIBNAME).$(LIBVERSION)'
+        SLIB_INSTALL_NAME='$(SLIBNAME).$(LIBMAJOR).$(LIBMINOR)'
         SLIB_INSTALL_LINKS=
         oss_indev_extralibs="-lossaudio"
         oss_outdev_extralibs="-lossaudio"
@@ -3154,7 +3278,6 @@
         objformat="win32"
         ranlib=:
         enable dos_paths
-        add_cppflags -U__STRICT_ANSI__
         ;;
     win32|win64)
         if enabled shared; then
@@ -3269,7 +3392,6 @@
         network_extralibs='-lbsd'
         exeobjs=compat/plan9/main.o
         disable ffserver
-        ln_s='ln -s -f'
         cp_f='cp'
         ;;
     none)
@@ -3281,26 +3403,29 @@
 
 # determine libc flavour
 
+# uclibc defines __GLIBC__, so it needs to be checked before glibc.
 if check_cpp_condition features.h "defined __UCLIBC__"; then
     libc_type=uclibc
     add_cppflags -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600
 elif check_cpp_condition features.h "defined __GLIBC__"; then
     libc_type=glibc
     add_cppflags -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600
+# MinGW headers can be installed on Cygwin, so check for newlib first.
+elif check_cpp_condition newlib.h "defined _NEWLIB_VERSION"; then
+    libc_type=newlib
+    add_cppflags -U__STRICT_ANSI__
 elif check_header _mingw.h; then
     libc_type=mingw
     check_cpp_condition _mingw.h \
         "defined (__MINGW64_VERSION_MAJOR) || (__MINGW32_MAJOR_VERSION > 3) || \
             (__MINGW32_MAJOR_VERSION == 3 && __MINGW32_MINOR_VERSION >= 15)" ||
         die "ERROR: MinGW runtime version must be >= 3.15."
+    add_cppflags -U__STRICT_ANSI__
     if check_cpp_condition _mingw.h "defined(__MINGW64_VERSION_MAJOR) && \
             __MINGW64_VERSION_MAJOR < 3"; then
         add_compat msvcrt/snprintf.o
         add_cflags "-include $source_path/compat/msvcrt/snprintf.h"
     fi
-elif check_cpp_condition newlib.h "defined _NEWLIB_VERSION"; then
-    libc_type=newlib
-    add_cppflags -U__STRICT_ANSI__
 elif check_func_headers stdlib.h _get_doserrno; then
     libc_type=msvcrt
     add_compat strtod.o strtod=avpriv_strtod
@@ -3423,7 +3548,10 @@
 
 elif enabled arm; then
 
-    check_cpp_condition stddef.h "defined __thumb__" && enable_weak thumb
+    check_cpp_condition stddef.h "defined __thumb__" && check_cc <<EOF && enable_weak thumb
+float func(float a, float b){ return a+b; }
+EOF
+
     enabled thumb && check_cflags -mthumb || check_cflags -marm
     nogas=die
 
@@ -3440,12 +3568,16 @@
         warn "Compiler does not indicate floating-point ABI, guessing $fpabi."
     fi
 
-    enabled armv5te && check_inline_asm armv5te '"qadd r0, r0, r0"'
-    enabled armv6   && check_inline_asm armv6   '"sadd16 r0, r0, r0"'
-    enabled armv6t2 && check_inline_asm armv6t2 '"movt r0, #0"'
-    enabled armvfp  && check_inline_asm armvfp  '"fadds s0, s0, s0"'
-    enabled neon    && check_inline_asm neon    '"vadd.i16 q0, q0, q0"'
-    enabled vfpv3   && check_inline_asm vfpv3   '"vmov.f32 s0, #1.0"'
+    enabled armv5te && check_insn armv5te 'qadd r0, r0, r0'
+    enabled armv6   && check_insn armv6   'sadd16 r0, r0, r0'
+    enabled armv6t2 && check_insn armv6t2 'movt r0, #0'
+    enabled neon    && check_insn neon    'vadd.i16 q0, q0, q0'
+    enabled vfp     && check_insn vfp     'fadds s0, s0, s0'
+    enabled vfpv3   && check_insn vfpv3   'vmov.f32 s0, #1.0'
+
+    [ $target_os = linux ] ||
+        map 'enabled_any ${v}_external ${v}_inline || disable $v' \
+            $ARCH_EXT_LIST_ARM
 
     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)'
@@ -3569,8 +3701,13 @@
 
 if enabled asm; then
     as=${gas:=$as}
-    check_inline_asm gnu_as '".macro m n\n\\n:.int 0\n.endm\nm x"' ||
+    check_as <<EOF && enable gnu_as || \
         $nogas "GNU assembler not found, install gas-preprocessor"
+.macro m n
+\n: .int 0
+.endm
+m x
+EOF
 fi
 
 check_ldflags -Wl,--as-needed
@@ -3581,7 +3718,7 @@
     ldl=-ldl
 fi
 
-if enabled network; then
+if ! disabled network; then
     check_type "sys/types.h sys/socket.h" socklen_t
     check_type netdb.h "struct addrinfo"
     check_type netinet/in.h "struct group_source_req" -D_BSD_SOURCE
@@ -3677,20 +3814,14 @@
 check_header unistd.h
 check_header vdpau/vdpau.h
 check_header vdpau/vdpau_x11.h
+check_header VideoDecodeAcceleration/VDADecoder.h
 check_header windows.h
 check_header X11/extensions/XvMClib.h
 check_header asm/types.h
 
 disabled  zlib || check_lib   zlib.h      zlibVersion -lz   || disable  zlib
 disabled bzlib || check_lib2 bzlib.h BZ2_bzlibVersion -lbz2 || disable bzlib
-
-# check for VDA header
-if ! disabled vda && ! enabled ppc; then
-    if check_header VideoDecodeAcceleration/VDADecoder.h; then
-        enable vda
-        add_extralibs -framework CoreFoundation -framework VideoDecodeAcceleration -framework QuartzCore
-    fi
-fi
+disabled iconv || check_func_headers iconv.h iconv || check_lib2 iconv.h iconv -liconv || disable iconv
 
 if ! disabled w32threads && ! enabled pthreads; then
     check_func_headers "windows.h process.h" _beginthreadex && enable w32threads
@@ -3748,7 +3879,6 @@
 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 libcdio    && require2 libcdio "cdio/cdda.h cdio/paranoia.h" cdio_cddap_open -lcdio_paranoia -lcdio_cdda -lcdio
 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."; }
@@ -3758,7 +3888,9 @@
 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     && require  libgsm gsm/gsm.h gsm_create -lgsm
+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
@@ -3766,11 +3898,14 @@
 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 && require libopenjpeg openjpeg.h opj_version -lopenjpeg
+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 librtmp    && require_pkg_config librtmp librtmp/rtmp.h RTMP_Socket
 enabled libschroedinger && require_pkg_config schroedinger-1.0 schroedinger/schro.h schro_init
+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
@@ -3785,10 +3920,12 @@
 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_decoder && { check_lib2 "vpx/vpx_decoder.h vpx/vp8dx.h" vpx_codec_dec_init_ver -lvpx ||
-                                die "ERROR: libvpx decoder must be installed and version must be >=0.9.1"; }
-    enabled libvpx_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_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"; }
+    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;  }
+    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."; }
@@ -3839,11 +3976,12 @@
 makeinfo --version > /dev/null 2>&1 && enable makeinfo  || disable makeinfo
 perl --version > /dev/null 2>&1 && enable perl || disable perl
 pod2man --help > /dev/null 2>&1 && enable pod2man || disable pod2man
+rsync --help 2> /dev/null | grep -q 'contimeout' && enable rsync_contimeout || disable rsync_contimeout
 
 check_header linux/fb.h
 check_header linux/videodev.h
 check_header linux/videodev2.h
-check_struct linux/videodev2.h "struct v4l2_frmivalenum" discrete
+check_code cc linux/videodev2.h "struct v4l2_frmsizeenum vfse; vfse.discrete.width = 0;" && enable_safe struct_v4l2_frmivalenum_discrete
 
 check_header sys/videoio.h
 
@@ -3881,6 +4019,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
+fi
 
 enabled x11grab                                           &&
 require X11 X11/Xlib.h XOpenDisplay -lX11                 &&
@@ -3894,10 +4035,9 @@
     } || disable vaapi
 fi
 
-if ! disabled vdpau && enabled vdpau_vdpau_h; then
+enabled vdpau &&
     check_cpp_condition vdpau/vdpau.h "defined VDP_DECODER_PROFILE_MPEG4_PART2_ASP" ||
-        { echolog "Please upgrade to libvdpau >= 0.2 if you would like vdpau support." && disable vdpau; }
-fi
+    disable vdpau
 
 enabled debug && add_cflags -g"$debuglevel" && add_asflags -g"$debuglevel"
 enabled coverage && add_cflags "-fprofile-arcs -ftest-coverage" && add_ldflags "-fprofile-arcs -ftest-coverage"
@@ -3988,17 +4128,16 @@
     check_cflags -w1
     # -wd: Disable following warnings
     # 144, 167, 556: -Wno-pointer-sign
+    # 188: enumerated type mixed with another type
     # 1292: attribute "foo" ignored
     # 1419: external declaration in primary source file
     # 10006: ignoring unknown option -fno-signed-zeros
     # 10148: ignoring unknown option -Wno-parentheses
     # 10156: ignoring option '-W'; no argument required
-    check_cflags -wd144,167,556,1292,1419,10006,10148,10156
+    check_cflags -wd144,167,188,556,1292,1419,10006,10148,10156
     # 11030: Warning unknown option --as-needed
     # 10156: ignoring option '-export'; no argument required
     check_ldflags -wd10156,11030
-    # Allow to compile with optimizations
-    check_ldflags -march=$cpu
     # icc 11.0 and 11.1 work with ebp_available, but don't pass the test
     enable ebp_available
     if enabled x86_32; then
@@ -4017,6 +4156,7 @@
     check_optflags -fno-tree-vectorize
     check_cflags -Werror=implicit-function-declaration
     check_cflags -Werror=missing-prototypes
+    check_cflags -Werror=return-type
     check_cflags -Werror=vla
 elif enabled llvm_gcc; then
     check_cflags -mllvm -stack-alignment=16
@@ -4025,6 +4165,7 @@
     check_cflags -Qunused-arguments
     check_cflags -Werror=implicit-function-declaration
     check_cflags -Werror=missing-prototypes
+    check_cflags -Werror=return-type
 elif enabled armcc; then
     # 2523: use of inline assembler is deprecated
     add_cflags -W${armcc_opt},--diag_suppress=2523
@@ -4129,8 +4270,9 @@
     echo "ARMv5TE enabled           ${armv5te-no}"
     echo "ARMv6 enabled             ${armv6-no}"
     echo "ARMv6T2 enabled           ${armv6t2-no}"
-    echo "ARM VFP enabled           ${armvfp-no}"
+    echo "VFP enabled               ${vfp-no}"
     echo "NEON enabled              ${neon-no}"
+    echo "THUMB enabled             ${thumb-no}"
 fi
 if enabled mips; then
     echo "MIPS FPU enabled          ${mipsfpu-no}"
@@ -4158,51 +4300,6 @@
 echo "threading support         ${thread_type-no}"
 echo "safe bitstream reader     ${safe_bitstream_reader-no}"
 echo "SDL support               ${sdl-no}"
-echo "libdxva2 enabled          ${dxva2-no}"
-echo "libva enabled             ${vaapi-no}"
-echo "libvdpau enabled          ${vdpau-no}"
-echo "AVISynth enabled          ${avisynth-no}"
-echo "frei0r enabled            ${frei0r-no}"
-echo "gnutls enabled            ${gnutls-no}"
-echo "libaacplus enabled        ${libaacplus-no}"
-echo "libass enabled            ${libass-no}"
-echo "libcaca enabled           ${libcaca-no}"
-echo "libcdio support           ${libcdio-no}"
-echo "libcelt enabled           ${libcelt-no}"
-echo "libdc1394 support         ${libdc1394-no}"
-echo "libfaac enabled           ${libfaac-no}"
-echo "libfdk-aac enabled        ${libfdk_aac-no}"
-echo "libgsm enabled            ${libgsm-no}"
-echo "libiec61883 support       ${libiec61883-no}"
-echo "libilbc enabled           ${libilbc-no}"
-echo "libmodplug enabled        ${libmodplug-no}"
-echo "libmp3lame enabled        ${libmp3lame-no}"
-echo "libnut enabled            ${libnut-no}"
-echo "libopencore-amrnb support ${libopencore_amrnb-no}"
-echo "libopencore-amrwb support ${libopencore_amrwb-no}"
-echo "libopencv support         ${libopencv-no}"
-echo "libopenjpeg enabled       ${libopenjpeg-no}"
-echo "libopus enabled           ${libopus-no}"
-echo "libpulse enabled          ${libpulse-no}"
-echo "librtmp enabled           ${librtmp-no}"
-echo "libschroedinger enabled   ${libschroedinger-no}"
-echo "libspeex enabled          ${libspeex-no}"
-echo "libstagefright-h264 enabled    ${libstagefright_h264-no}"
-echo "libtheora enabled         ${libtheora-no}"
-echo "libtwolame enabled        ${libtwolame-no}"
-echo "libutvideo enabled        ${libutvideo-no}"
-echo "libv4l2 enabled           ${libv4l2-no}"
-echo "libvo-aacenc support      ${libvo_aacenc-no}"
-echo "libvo-amrwbenc support    ${libvo_amrwbenc-no}"
-echo "libvorbis enabled         ${libvorbis-no}"
-echo "libvpx enabled            ${libvpx-no}"
-echo "libx264 enabled           ${libx264-no}"
-echo "libxavs enabled           ${libxavs-no}"
-echo "libxvid enabled           ${libxvid-no}"
-echo "openal enabled            ${openal-no}"
-echo "openssl enabled           ${openssl-no}"
-echo "zlib enabled              ${zlib-no}"
-echo "bzlib enabled             ${bzlib-no}"
 echo "texi2html enabled         ${texi2html-no}"
 echo "perl enabled              ${perl-no}"
 echo "pod2man enabled           ${pod2man-no}"
@@ -4211,10 +4308,14 @@
     echo "random seed               ${random_seed}"
 echo
 
+echo "External libraries:"
+print_enabled '' $EXTERNAL_LIBRARY_LIST | print_3_columns
+echo
+
 for type in decoder encoder hwaccel parser demuxer muxer protocol filter bsf indev outdev; do
     echo "Enabled ${type}s:"
     eval list=\$$(toupper $type)_LIST
-    print_enabled '_*' $list | sort | pr -r -3 -t
+    print_enabled '_*' $list | print_3_columns
     echo
 done
 
@@ -4291,7 +4392,7 @@
 DLLTOOL=$dlltool
 LDFLAGS=$LDFLAGS
 LDFLAGS-ffserver=$FFSERVERLDFLAGS
-SHFLAGS=$SHFLAGS
+SHFLAGS=$(echo $($ldflags_filter $SHFLAGS))
 YASMFLAGS=$YASMFLAGS
 BUILDSUF=$build_suffix
 PROGSSUF=$progs_suffix
@@ -4313,6 +4414,7 @@
 HOSTCC=$host_cc
 HOSTLD=$host_ld
 HOSTCFLAGS=$host_cflags
+HOSTCPPFLAGS=$host_cppflags
 HOSTEXESUF=$HOSTEXESUF
 HOSTLDFLAGS=$host_ldflags
 HOSTLIBS=$host_libs
@@ -4356,23 +4458,9 @@
     eval ${name}_VERSION=\$${name}_VERSION_MAJOR.\$${name}_VERSION_MINOR.\$${name}_VERSION_MICRO
     eval echo "${lcname}_VERSION=\$${name}_VERSION" >> config.mak
     eval echo "${lcname}_VERSION_MAJOR=\$${name}_VERSION_MAJOR" >> config.mak
+    eval echo "${lcname}_VERSION_MINOR=\$${name}_VERSION_MINOR" >> config.mak
 }
 
-get_version_old(){
-    name=$1
-    file=$source_path/$2
-# This condition will be removed when we stop supporting old libpostproc versions
-if ! test "$name" = LIBPOSTPROC || test "$postproc_version" = current; then
-    eval $(grep "#define ${name}_VERSION_M" "$file" | awk '{ print $2"="$3 }')
-    eval ${name}_VERSION=\$${name}_VERSION_MAJOR.\$${name}_VERSION_MINOR.\$${name}_VERSION_MICRO
-fi
-    lcname=$(tolower $name)
-    eval echo "${lcname}_VERSION=\$${name}_VERSION" >> config.mak
-    eval echo "${lcname}_VERSION_MAJOR=\$${name}_VERSION_MAJOR" >> config.mak
-}
-
-get_version_old LIBPOSTPROC libpostproc/version.h
-
 map 'get_version $v' $LIBRARY_LIST
 
 cat > $TMPH <<EOF
@@ -4423,12 +4511,6 @@
 #define AVUTIL_AVCONFIG_H
 EOF
 
-test "$postproc_version" != current && cat >> $TMPH <<EOF
-#define LIBPOSTPROC_VERSION_MAJOR $LIBPOSTPROC_VERSION_MAJOR
-#define LIBPOSTPROC_VERSION_MINOR $LIBPOSTPROC_VERSION_MINOR
-#define LIBPOSTPROC_VERSION_MICRO $LIBPOSTPROC_VERSION_MICRO
-EOF
-
 print_config AV_HAVE_ $TMPH $HAVE_LIST_PUB
 
 echo "#endif /* AVUTIL_AVCONFIG_H */" >> $TMPH
@@ -4451,7 +4533,7 @@
     requires=$5
     enabled ${name#lib} || return 0
     mkdir -p $name
-    cat <<EOF > $name/$name.pc
+    cat <<EOF > $name/$name${build_suffix}.pc
 prefix=$prefix
 exec_prefix=\${prefix}
 libdir=$libdir
@@ -4487,27 +4569,27 @@
 EOF
 }
 
-libavfilter_pc_deps="libavutil = $LIBAVUTIL_VERSION"
-enabled libavfilter_deps_avcodec    && prepend libavfilter_pc_deps "libavcodec = $LIBAVCODEC_VERSION,"
-enabled libavfilter_deps_avformat   && prepend libavfilter_pc_deps "libavformat = $LIBAVFORMAT_VERSION,"
-enabled libavfilter_deps_avresample && prepend libavfilter_pc_deps "libavresample = $LIBAVRESAMPLE_VERSION,"
-enabled libavfilter_deps_swscale    && prepend libavfilter_pc_deps "libswscale = $LIBSWSCALE_VERSION,"
-enabled libavfilter_deps_swresample && prepend libavfilter_pc_deps "libswresample = $LIBSWRESAMPLE_VERSION,"
-enabled libavfilter_deps_postproc   && prepend libavfilter_pc_deps "libpostproc = $LIBPOSTPROC_VERSION,"
+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%, }
 
-libavdevice_pc_deps="libavformat = $LIBAVFORMAT_VERSION"
-enabled lavfi_indev && prepend libavdevice_pc_deps "libavfilter = $LIBAVFILTER_VERSION,"
+libavdevice_pc_deps="libavformat${build_suffix} = $LIBAVFORMAT_VERSION"
+enabled lavfi_indev && prepend libavdevice_pc_deps "libavfilter${build_suffix} = $LIBAVFILTER_VERSION,"
 
 pkgconfig_generate libavutil "FFmpeg utility library" "$LIBAVUTIL_VERSION" "$LIBM"
-pkgconfig_generate libavcodec "FFmpeg codec library" "$LIBAVCODEC_VERSION" "$extralibs" "libavutil = $LIBAVUTIL_VERSION"
-pkgconfig_generate libavformat "FFmpeg container format library" "$LIBAVFORMAT_VERSION" "$extralibs" "libavcodec = $LIBAVCODEC_VERSION"
+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 video filtering library" "$LIBAVFILTER_VERSION" "$extralibs" "$libavfilter_pc_deps"
-pkgconfig_generate libpostproc "FFmpeg postprocessing library" "$LIBPOSTPROC_VERSION" "" "libavutil = $LIBAVUTIL_VERSION"
-pkgconfig_generate libavresample "Libav audio resampling library" "$LIBAVRESAMPLE_VERSION" "$extralibs" "libavutil = $LIBAVUTIL_VERSION"
-pkgconfig_generate libswscale "FFmpeg image rescaling library" "$LIBSWSCALE_VERSION" "$LIBM" "libavutil = $LIBAVUTIL_VERSION"
-pkgconfig_generate libswresample "FFmpeg audio resampling library" "$LIBSWRESAMPLE_VERSION" "$LIBM" "libavutil = $LIBAVUTIL_VERSION"
+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"
 
 fix_ffmpeg_remote(){
     git_remote_from=$1
diff --git a/doc/APIchanges b/doc/APIchanges
index 5707d13..8535d9f 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -15,7 +15,23 @@
 
 API changes, most recent first:
 
-2012-11-25 - xxxxxxx - lavu 52.9.100 - opt.h
+2013-02-24 - xxxxxx - lavfi 3.41.100 - buffersink.h
+  Add sample_rates field to AVABufferSinkParams.
+
+2013-01-17 - a1a707f - lavf 54.61.100
+  Add av_codec_get_tag2().
+
+2013-01-01 - 2eb2e17 - lavfi 3.34.100
+  Add avfilter_get_audio_buffer_ref_from_arrays_channels.
+
+2012-12-20 - 34de47aa - lavfi 3.29.100 - avfilter.h
+  Add AVFilterLink.channels, avfilter_link_get_channels()
+  and avfilter_ref_get_channels().
+
+2012-12-15 - 2ada584d - lavc 54.80.100 - avcodec.h
+  Add pkt_size field to AVFrame.
+
+2012-11-25 - c70ec631 - lavu 52.9.100 - opt.h
   Add the following convenience functions to opt.h:
    av_opt_get_image_size
    av_opt_get_pixel_fmt
@@ -24,19 +40,19 @@
    av_opt_set_pixel_fmt
    av_opt_set_sample_fmt
 
-2012-11-17 - xxxxxxx - lavu 52.8.100 - bprint.h
+2012-11-17 - 4cd74c81 - lavu 52.8.100 - bprint.h
   Add av_bprint_strftime().
 
-2012-11-15 - xxxxxxx - lavu 52.7.100 - opt.h
+2012-11-15 - 92648107 - lavu 52.7.100 - opt.h
   Add av_opt_get_key_value().
 
-2012-11-13 - xxxxxxx - lavfi 3.23.100 - avfilter.h
+2012-11-13 - 79456652 - lavfi 3.23.100 - avfilter.h
   Add channels field to AVFilterBufferRefAudioProps.
 
-2012-11-03 - xxxxxxx - lavu 52.3.100 - opt.h
+2012-11-03 - 481fdeee - lavu 52.3.100 - opt.h
   Add AV_OPT_TYPE_SAMPLE_FMT value to AVOptionType enum.
 
-2012-10-21 - xxxxxxx - lavc  54.68.100 - avcodec.h
+2012-10-21 - 6fb2fd8 - lavc  54.68.100 - avcodec.h
                        lavfi  3.20.100 - avfilter.h
   Add AV_PKT_DATA_STRINGS_METADATA side data type, used to transmit key/value
   strings between AVPacket and AVFrame, and add metadata field to
@@ -125,27 +141,54 @@
 2012-03-26 - a67d9cf - lavfi 2.66.100
   Add avfilter_fill_frame_from_{audio_,}buffer_ref() functions.
 
-2012-xx-xx - xxxxxxx - lavu 52.2.0 - audioconvert.h
+2013-xx-xx - xxxxxxx - 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
+  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
+  Add av_strnstr()
+
+2013-01-xx - xxxxxxx - lavu 52.5.0 - hmac.h
+  Add AVHMAC.
+
+2013-01-13 - xxxxxxx - 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
+  Add AV_PIX_FMT_VDPAU flag.
+
+2013-01-07 - 249fca3 / 074a00d - lavr 1.1.0
+  Add avresample_set_channel_mapping() for input channel reordering,
+  duplication, and silencing.
+
+2012-12-29 - 2ce43b3 / d8fd06c - lavu 52.13.100 / 52.3.0 - avstring.h
+  Add av_basename() and av_dirname().
+
+2012-11-11 - 03b0787 / 5980f5d - lavu 52.6.100 / 52.2.0 - audioconvert.h
   Rename audioconvert.h to channel_layout.h. audioconvert.h is now deprecated.
 
-2012-xx-xx - xxxxxxx - lavu 52.1.0 - intmath.h
+2012-11-05 - 7d26be6 / dfde8a3 - lavu 52.5.100 / 52.1.0 - intmath.h
   Add av_ctz() for trailing zero bit count
 
-2012-10-18 - xxxxxxx - lavu 51.45.0 - error.h
+2012-10-21 - e3a91c5 / a893655 - lavu 51.77.100 / 51.45.0 - error.h
   Add AVERROR_EXPERIMENTAL
 
-2012-10-12 - xxxxxxx - lavu 51.44.0 - pixdesc.h
+2012-10-12 - a33ed6b / d2fcb35 - lavu 51.76.100 / 51.44.0 - pixdesc.h
   Add functions for accessing pixel format descriptors.
   Accessing the av_pix_fmt_descriptors array directly is now
   deprecated.
 
-2012-10-xx - xxxxxxx - lavu 51.43.0 - aes.h, md5.h, sha.h, tree.h
+2012-10-11 - f391e40 / 9a92aea - lavu 51.75.100 / 51.43.0 - aes.h, md5.h, sha.h, tree.h
   Add functions for allocating the opaque contexts for the algorithms,
 
-2012-10-xx - xxxxxxx - lavf 54.18.0 - avio.h
+2012-10-10 - de31814 / b522000 - lavf 54.32.100 / 54.18.0 - avio.h
   Add avio_closep to complement avio_close.
 
-2012-10-xx - xxxxxxx - lavu 51.42.0 - pixfmt.h
+2012-10-08 - ae77266 / 78071a1 - lavu 51.74.100 / 51.42.0 - pixfmt.h
   Rename PixelFormat to AVPixelFormat and all PIX_FMT_* to AV_PIX_FMT_*.
   To provide backwards compatibility, PixelFormat is now #defined as
   AVPixelFormat.
@@ -153,23 +196,23 @@
   'PixelFormat' identifier. Such code should either #undef PixelFormat
   or stop using the PixelFormat name.
 
-2012-10-05 - e7ba5b1 - lavr 1.0.0 - avresample.h
+2012-10-05 - 55c49af / e7ba5b1 - lavr 1.0.0 - avresample.h
   Data planes parameters to avresample_convert() and
   avresample_read() are now uint8_t** instead of void**.
   Libavresample is now stable.
 
-2012-09-24 - a42aada - lavc 54.28.0 - avcodec.h
+2012-09-24 - 46a3595 / a42aada - lavc 54.59.100 / 54.28.0 - avcodec.h
   Add avcodec_free_frame(). This function must now
   be used for freeing an AVFrame.
 
-2012-09-12 - 8919fee - lavu 51.41.0 - audioconvert.h
+2012-09-12 - e3e09f2 / 8919fee - lavu 51.73.100 / 51.41.0 - audioconvert.h
   Added AV_CH_LOW_FREQUENCY_2 channel mask value.
 
-2012-09-04 - 686a329 - lavu 51.40.0 - opt.h
+2012-09-04 - b21b5b0 / 686a329 - lavu 51.71.100 / 51.40.0 - opt.h
   Reordered the fields in default_val in AVOption, changed which
   default_val field is used for which AVOptionType.
 
-2012-08-30 - a231832 - lavc 54.26.1 - avcodec.h
+2012-08-30 - 98298eb / a231832 - lavc 54.54.101 / 54.26.1 - avcodec.h
   Add codec descriptor properties AV_CODEC_PROP_LOSSY and
   AV_CODEC_PROP_LOSSLESS.
 
@@ -177,90 +220,90 @@
   Add codec descriptors for accessing codec properties without having
   to refer to a specific decoder or encoder.
 
-  c223d79 - Add an AVCodecDescriptor struct and functions
+  f5f3684 / c223d79 - Add an AVCodecDescriptor struct and functions
             avcodec_descriptor_get() and avcodec_descriptor_next().
-  51efed1 - Add AVCodecDescriptor.props and AV_CODEC_PROP_INTRA_ONLY.
-  91e59fe - Add avcodec_descriptor_get_by_name().
+  f5f3684 / 51efed1 - Add AVCodecDescriptor.props and AV_CODEC_PROP_INTRA_ONLY.
+  6c180b3 / 91e59fe - Add avcodec_descriptor_get_by_name().
 
-2012-08-08 - 987170c - lavu 51.38 - dict.h
+2012-08-08 - f5f3684 / 987170c - lavu 51.68.100 / 51.38.0 - dict.h
   Add av_dict_count().
 
-2012-08-07 - 104e10f - lavc 54.25 - avcodec.h
+2012-08-07 - 7a72695 / 104e10f - lavc 54.51.100 / 54.25.0 - avcodec.h
   Rename CodecID to AVCodecID and all CODEC_ID_* to AV_CODEC_ID_*.
   To provide backwards compatibility, CodecID is now #defined as AVCodecID.
   Note that this can break user code that includes avcodec.h and uses the
   'CodecID' identifier. Such code should either #undef CodecID or stop using the
   CodecID name.
 
-2012-08-03 - 239fdf1 - lavu 51.37.1 - cpu.h
+2012-08-03 - e776ee8 / 239fdf1 - lavu 51.66.101 / 51.37.1 - cpu.h
                        lsws 2.1.1   - swscale.h
   Rename AV_CPU_FLAG_MMX2  ---> AV_CPU_FLAG_MMXEXT.
   Rename SWS_CPU_CAPS_MMX2 ---> SWS_CPU_CAPS_MMXEXT.
 
-2012-07-29 - 681ed00 - lavf 54.13.0 - avformat.h
+2012-07-29 - 7c26761 / 681ed00 - lavf 54.22.100 / 54.13.0 - avformat.h
   Add AVFMT_FLAG_NOBUFFER for low latency use cases.
 
 2012-07-10 - 5fade8a - lavu 51.37.0
   Add av_malloc_array() and av_mallocz_array()
 
-2012-06-22 - d3d3a32 - lavu 51.34.0
+2012-06-22 - e847f41 / d3d3a32 - lavu 51.61.100 / 51.34.0
   Add av_usleep()
 
-2012-06-20 - ae0a301 - lavu 51.33.0
+2012-06-20 - 4da42eb / ae0a301 - lavu 51.60.100 / 51.33.0
   Move av_gettime() to libavutil, add libavutil/time.h
 
-2012-06-09 - 3971be0 - lavr 0.0.3
+2012-06-09 - 82edf67 / 3971be0 - lavr 0.0.3
   Add a parameter to avresample_build_matrix() for Dolby/DPLII downmixing.
 
-2012-06-12 - 9baeff9 - lavfi 2.23.0 - avfilter.h
+2012-06-12 - c7b9eab / 9baeff9 - lavfi 2.79.100 / 2.23.0 - avfilter.h
   Add AVFilterContext.nb_inputs/outputs. Deprecate
   AVFilterContext.input/output_count.
 
-2012-06-12 - 84b9fbe - lavfi 2.22.0 - avfilter.h
+2012-06-12 - c7b9eab / 84b9fbe - lavfi 2.79.100 / 2.22.0 - avfilter.h
   Add avfilter_pad_get_type() and avfilter_pad_get_name(). Those
   should now be used instead of accessing AVFilterPad members
   directly.
 
-2012-06-12 - b0f0dfc - lavu 51.32.0 - audioconvert.h
+2012-06-12 - 3630a07 / b0f0dfc - lavu 51.57.100 / 51.32.0 - audioconvert.h
   Add av_get_channel_layout_channel_index(), av_get_channel_name()
   and av_channel_layout_extract_channel().
 
-2012-05-25 - 154486f - lavu 51.31.0 - opt.h
+2012-05-25 - 53ce990 / 154486f - lavu 51.55.100 / 51.31.0 - opt.h
   Add av_opt_set_bin()
 
-2012-05-15 - lavfi 2.17.0
+2012-05-15 - lavfi 2.74.100 / 2.17.0
   Add support for audio filters
-  ac71230/a2cd9be - add video/audio buffer sink in a new installed
+  61930bd / ac71230, 1cbf7fb / a2cd9be - add video/audio buffer sink in a new installed
                     header buffersink.h
-  720c6b7 - add av_buffersrc_write_frame(), deprecate
+  1cbf7fb / 720c6b7 - add av_buffersrc_write_frame(), deprecate
             av_vsrc_buffer_add_frame()
-  ab16504 - add avfilter_copy_buf_props()
-  9453c9e - add extended_data to AVFilterBuffer
-  1b8c927 - add avfilter_get_audio_buffer_ref_from_arrays()
+  61930bd / ab16504 - add avfilter_copy_buf_props()
+  61930bd / 9453c9e - add extended_data to AVFilterBuffer
+  61930bd / 1b8c927 - add avfilter_get_audio_buffer_ref_from_arrays()
 
-2012-05-09 - lavu 51.30.0 - samplefmt.h
-  142e740 - add av_samples_copy()
-  6d7f617 - add av_samples_set_silence()
+2012-05-09 - lavu 51.53.100 / 51.30.0 - samplefmt.h
+  61930bd / 142e740 - add av_samples_copy()
+  61930bd / 6d7f617 - add av_samples_set_silence()
 
-2012-05-09 - a5117a2 - lavc 54.13.1
+2012-05-09 - 61930bd / a5117a2 - lavc 54.21.101 / 54.13.1
   For audio formats with fixed frame size, the last frame
   no longer needs to be padded with silence, libavcodec
   will handle this internally (effectively all encoders
   behave as if they had CODEC_CAP_SMALL_LAST_FRAME set).
 
-2012-05-07 - 828bd08 - lavc 54.13.0 - avcodec.h
+2012-05-07 - 653d117 / 828bd08 - lavc 54.20.100 / 54.13.0 - avcodec.h
   Add sample_rate and channel_layout fields to AVFrame.
 
-2012-05-01 - 4010d72 - lavr 0.0.1
+2012-05-01 - 2330eb1 / 4010d72 - lavr 0.0.1
   Change AV_MIX_COEFF_TYPE_Q6 to AV_MIX_COEFF_TYPE_Q8.
 
-2012-04-25 - 3527a73 - lavu 51.29.0 - cpu.h
+2012-04-25 - e890b68 / 3527a73 - lavu 51.48.100 / 51.29.0 - cpu.h
   Add av_parse_cpu_flags()
 
-2012-04-24 - c8af852 - lavr 0.0.0
+2012-04-24 - 3ead79e / c8af852 - lavr 0.0.0
   Add libavresample audio conversion library
 
-2012-04-20 - 0c0d1bc - lavu 51.28.0 - audio_fifo.h
+2012-04-20 - 3194ab7 / 0c0d1bc - lavu 51.47.100 / 51.28.0 - audio_fifo.h
   Add audio FIFO functions:
     av_audio_fifo_free()
     av_audio_fifo_alloc()
@@ -272,10 +315,10 @@
     av_audio_fifo_size()
     av_audio_fifo_space()
 
-2012-04-14 - lavfi 2.16.0 - avfiltergraph.h
-  d7bcc71 Add avfilter_graph_parse2().
+2012-04-14 - lavfi 2.70.100 / 2.16.0 - avfiltergraph.h
+  7432bcf / d7bcc71 Add avfilter_graph_parse2().
 
-2012-04-08 - 4d693b0 - lavu 51.27.0 - samplefmt.h
+2012-04-08 - 6bfb304 / 4d693b0 - lavu 51.46.100 / 51.27.0 - samplefmt.h
   Add av_get_packed_sample_fmt() and av_get_planar_sample_fmt()
 
 2012-03-21 - b75c67d - lavu 51.43.100
@@ -303,73 +346,73 @@
 2012-01-24 - 0c3577b - lavfi 2.60.100
   Add avfilter_graph_dump.
 
-2012-03-20 - 3c90cc2 - lavfo 54.2.0
+2012-03-20 - 0ebd836 / 3c90cc2 - lavfo 54.2.0
   Deprecate av_read_packet(), use av_read_frame() with
   AVFMT_FLAG_NOPARSE | AVFMT_FLAG_NOFILLIN in AVFormatContext.flags
 
-2012-03-05 - lavc 54.8.0
-  6699d07 Add av_get_exact_bits_per_sample()
-  9524cf7 Add av_get_audio_frame_duration()
+2012-03-05 - lavc 54.10.100 / 54.8.0
+  f095391 / 6699d07 Add av_get_exact_bits_per_sample()
+  f095391 / 9524cf7 Add av_get_audio_frame_duration()
 
-2012-03-04 - 44fe77b - lavc 54.7.0 - avcodec.h
+2012-03-04 - 2af8f2c / 44fe77b - lavc 54.8.100 / 54.7.0 - avcodec.h
   Add av_codec_is_encoder/decoder().
 
-2012-03-01 - 442c132 - lavc 54.3.0 - avcodec.h
+2012-03-01 - 1eb7f39 / 442c132 - lavc 54.5.100 / 54.3.0 - avcodec.h
   Add av_packet_shrink_side_data.
 
-2012-02-29 - dd2a4bc - lavf 54.2.0 - avformat.h
+2012-02-29 - 79ae084 / dd2a4bc - lavf 54.2.100 / 54.2.0 - avformat.h
   Add AVStream.attached_pic and AV_DISPOSITION_ATTACHED_PIC,
   used for dealing with attached pictures/cover art.
 
-2012-02-25 - c9bca80 - lavu 51.24.0 - error.h
+2012-02-25 - 305e4b3 / c9bca80 - lavu 51.41.100 / 51.24.0 - error.h
   Add AVERROR_UNKNOWN
   NOTE: this was backported to 0.8
 
-2012-02-20 - e9cda85 - lavc 54.2.0
+2012-02-20 - eadd426 / e9cda85 - lavc 54.2.100 / 54.2.0
   Add duration field to AVCodecParserContext
 
-2012-02-20 - 0b42a93 - lavu 51.23.1 - mathematics.h
+2012-02-20 - eadd426 / 0b42a93 - lavu 51.40.100 / 51.23.1 - mathematics.h
   Add av_rescale_q_rnd()
 
-2012-02-08 - 38d5533 - lavu 51.22.1 - pixdesc.h
+2012-02-08 - f2b20b7 / 38d5533 - lavu 51.38.101 / 51.22.1 - pixdesc.h
   Add PIX_FMT_PSEUDOPAL flag.
 
-2012-02-08 - 52f82a1 - lavc 54.01.0
+2012-02-08 - f2b20b7 / 52f82a1 - lavc 54.2.100 / 54.1.0
   Add avcodec_encode_video2() and deprecate avcodec_encode_video().
 
-2012-02-01 - 316fc74 - lavc 54.01.0
+2012-02-01 - 4c677df / 316fc74 - lavc 54.1.0
   Add av_fast_padded_malloc() as alternative for av_realloc() when aligned
   memory is required. The buffer will always have FF_INPUT_BUFFER_PADDING_SIZE
   zero-padded bytes at the end.
 
-2012-01-31 - dd6d3b0 - lavf 54.01.0
+2012-01-31 - a369a6b / dd6d3b0 - lavf 54.1.0
   Add avformat_get_riff_video_tags() and avformat_get_riff_audio_tags().
   NOTE: this was backported to 0.8
 
-2012-01-31 - af08d9a - lavc 54.01.0
+2012-01-31 - a369a6b / af08d9a - lavc 54.1.0
   Add avcodec_is_open() function.
   NOTE: this was backported to 0.8
 
-2012-01-30 - 8b93312 - lavu 51.22.0 - intfloat.h
+2012-01-30 - 151ecc2 / 8b93312 - lavu 51.36.100 / 51.22.0 - intfloat.h
   Add a new installed header libavutil/intfloat.h with int/float punning
   functions.
   NOTE: this was backported to 0.8
 
-2012-01-25 - lavf 53.22.0
-  f1caf01 Allow doing av_write_frame(ctx, NULL) for flushing possible
+2012-01-25 - lavf 53.31.100 / 53.22.0
+  3c5fe5b / f1caf01 Allow doing av_write_frame(ctx, NULL) for flushing possible
           buffered data within a muxer. Added AVFMT_ALLOW_FLUSH for
           muxers supporting it (av_write_frame makes sure it is called
           only for muxers with this flag).
 
-2012-01-15 - lavc 53.34.0
+2012-01-15 - lavc 53.56.105 / 53.34.0
   New audio encoding API:
-  b2c75b6 Add CODEC_CAP_VARIABLE_FRAME_SIZE capability for use by audio
+  67f5650 / b2c75b6 Add CODEC_CAP_VARIABLE_FRAME_SIZE capability for use by audio
           encoders.
-  5ee5fa0 Add avcodec_fill_audio_frame() as a convenience function.
-  b2c75b6 Add avcodec_encode_audio2() and deprecate avcodec_encode_audio().
+  67f5650 / 5ee5fa0 Add avcodec_fill_audio_frame() as a convenience function.
+  67f5650 / b2c75b6 Add avcodec_encode_audio2() and deprecate avcodec_encode_audio().
           Add AVCodec.encode2().
 
-2012-01-12 - 3167dc9 - lavfi 2.15.0
+2012-01-12 - b18e17e / 3167dc9 - lavfi 2.59.100 / 2.15.0
   Add a new installed header -- libavfilter/version.h -- with version macros.
 
 2011-12-08 - a502939 - lavfi 2.52.0
@@ -390,37 +433,37 @@
 2011-10-20 - b35e9e1 - lavu 51.22.0
   Add av_strtok() to avstring.h.
 
-2011-01-03 - b73ec05 - lavu 51.21.0
+2012-01-03 - ad1c8dd / b73ec05 - lavu 51.34.100 / 51.21.0
   Add av_popcount64
 
-2011-12-18 - 8400b12 - lavc 53.28.1
+2011-12-18 - 7c29313 / 8400b12 - lavc 53.46.1 / 53.28.1
   Deprecate AVFrame.age. The field is unused.
 
-2011-12-12 - 5266045 - lavf 53.17.0
+2011-12-12 - 8bc7fe4 / 5266045 - lavf 53.25.0 / 53.17.0
   Add avformat_close_input().
   Deprecate av_close_input_file() and av_close_input_stream().
 
-2011-12-02 - 0eea212 - lavc 53.25.0
+2011-12-02 - e4de716 / 0eea212 - lavc 53.40.0 / 53.25.0
   Add nb_samples and extended_data fields to AVFrame.
   Deprecate AVCODEC_MAX_AUDIO_FRAME_SIZE.
   Deprecate avcodec_decode_audio3() in favor of avcodec_decode_audio4().
   avcodec_decode_audio4() writes output samples to an AVFrame, which allows
   audio decoders to use get_buffer().
 
-2011-12-04 - 560f773 - lavc 53.24.0
+2011-12-04 - e4de716 / 560f773 - lavc 53.40.0 / 53.24.0
   Change AVFrame.data[4]/base[4]/linesize[4]/error[4] to [8] at next major bump.
   Change AVPicture.data[4]/linesize[4] to [8] at next major bump.
   Change AVCodecContext.error[4] to [8] at next major bump.
   Add AV_NUM_DATA_POINTERS to simplify the bump transition.
 
-2011-11-23 - bbb46f3 - lavu 51.18.0
+2011-11-23 - 8e576d5 / bbb46f3 - lavu 51.27.0 / 51.18.0
   Add av_samples_get_buffer_size(), av_samples_fill_arrays(), and
   av_samples_alloc(), to samplefmt.h.
 
-2011-11-23 - 8889cc4 - lavu 51.17.0
+2011-11-23 - 8e576d5 / 8889cc4 - lavu 51.27.0 / 51.17.0
   Add planar sample formats and av_sample_fmt_is_planar() to samplefmt.h.
 
-2011-11-19 - f3a29b7 - lavc 53.21.0
+2011-11-19 - dbb38bc / f3a29b7 - lavc 53.36.0 / 53.21.0
   Move some AVCodecContext fields to a new private struct, AVCodecInternal,
   which is accessed from a new field, AVCodecContext.internal.
   - fields moved:
@@ -428,55 +471,55 @@
       AVCodecContext.internal_buffer_count --> AVCodecInternal.buffer_count
       AVCodecContext.is_copy               --> AVCodecInternal.is_copy
 
-2011-11-16 - 6270671 - lavu 51.16.0
+2011-11-16 - 8709ba9 / 6270671 - lavu 51.26.0 / 51.16.0
   Add av_timegm()
 
-2011-11-13 - lavf 53.15.0
+2011-11-13 - lavf 53.21.0 / 53.15.0
   New interrupt callback API, allowing per-AVFormatContext/AVIOContext
   interrupt callbacks.
-  6aa0b98 Add AVIOInterruptCB struct and the interrupt_callback field to
+  5f268ca / 6aa0b98 Add AVIOInterruptCB struct and the interrupt_callback field to
           AVFormatContext.
-  1dee0ac Add avio_open2() with additional parameters. Those are
+  5f268ca / 1dee0ac Add avio_open2() with additional parameters. Those are
           an interrupt callback and an options AVDictionary.
           This will allow passing AVOptions to protocols after lavf
           54.0.
 
-2011-11-06 - ba04ecf - lavu 51.14.0
+2011-11-06 - 13b7781 / ba04ecf - lavu 51.24.0 / 51.14.0
   Add av_strcasecmp() and av_strncasecmp() to avstring.h.
 
-2011-11-06 - 07b172f - lavu 51.13.0
+2011-11-06 - 13b7781 / 07b172f - lavu 51.24.0 / 51.13.0
   Add av_toupper()/av_tolower()
 
-2011-11-05 - b6d08f4 - lavf 53.13.0
+2011-11-05 - d8cab5c / b6d08f4 - lavf 53.19.0 / 53.13.0
   Add avformat_network_init()/avformat_network_deinit()
 
-2011-10-27 - 512557b - lavc 53.15.0
+2011-10-27 - 6faf0a2 / 512557b - lavc 53.24.0 / 53.15.0
   Remove avcodec_parse_frame.
   Deprecate AVCodecContext.parse_only and CODEC_CAP_PARSE_ONLY.
 
-2011-10-19 - 569129a - lavf 53.10.0
+2011-10-19 - d049257 / 569129a - lavf 53.17.0 / 53.10.0
   Add avformat_new_stream(). Deprecate av_new_stream().
 
-2011-10-13 - b631fba - lavf 53.9.0
+2011-10-13 - 91eb1b1 / b631fba - lavf 53.16.0 / 53.9.0
   Add AVFMT_NO_BYTE_SEEK AVInputFormat flag.
 
-2011-10-12 - lavu 51.12.0
+2011-10-12 - lavu 51.21.0 / 51.12.0
   AVOptions API rewrite.
 
-  - 145f741 FF_OPT_TYPE* renamed to AV_OPT_TYPE_*
+  - f884ef0 / 145f741 FF_OPT_TYPE* renamed to AV_OPT_TYPE_*
   - new setting/getting functions with slightly different semantics:
-        dac66da av_set_string3 -> av_opt_set
+        f884ef0 / dac66da av_set_string3 -> av_opt_set
                 av_set_double  -> av_opt_set_double
                 av_set_q       -> av_opt_set_q
                 av_set_int     -> av_opt_set_int
 
-        41d9d51 av_get_string  -> av_opt_get
+        f884ef0 / 41d9d51 av_get_string  -> av_opt_get
                 av_get_double  -> av_opt_get_double
                 av_get_q       -> av_opt_get_q
                 av_get_int     -> av_opt_get_int
 
-  - 8c5dcaa trivial rename av_next_option -> av_opt_next
-  - 641c7af new functions - av_opt_child_next, av_opt_child_class_next
+  - f884ef0 / 8c5dcaa trivial rename av_next_option -> av_opt_next
+  - f884ef0 / 641c7af new functions - av_opt_child_next, av_opt_child_class_next
     and av_opt_find2()
 
 2011-09-22 - a70e787 - lavu 51.17.0
@@ -522,31 +565,31 @@
 2011-08-20 - 69e2c1a - lavu 51.13.0
   Add av_get_media_type_string().
 
-2011-09-03 - fb4ca26 - lavc 53.13.0
+2011-09-03 - 1889c67 / fb4ca26 - lavc 53.13.0
                        lavf 53.11.0
                        lsws  2.1.0
   Add {avcodec,avformat,sws}_get_class().
 
-2011-08-03 - c11fb82 - lavu 51.15.0
+2011-08-03 - 1889c67 / c11fb82 - lavu 51.15.0
   Add AV_OPT_SEARCH_FAKE_OBJ flag for av_opt_find() function.
 
 2011-08-14 - 323b930 - lavu 51.12.0
   Add av_fifo_peek2(), deprecate av_fifo_peek().
 
-2011-08-26 - lavu 51.9.0
-  - add41de..abc78a5 Do not include intfloat_readwrite.h,
+2011-08-26 - lavu 51.14.0 / 51.9.0
+  - 976a8b2 / add41de..976a8b2 / abc78a5 Do not include intfloat_readwrite.h,
     mathematics.h, rational.h, pixfmt.h, or log.h from avutil.h.
 
-2011-08-16 - 48f9e45 - lavf 53.8.0
+2011-08-16 - 27fbe31 / 48f9e45 - lavf 53.11.0 / 53.8.0
   Add avformat_query_codec().
 
-2011-08-16 - bca06e7 - lavc 53.11.0
+2011-08-16 - 27fbe31 / bca06e7 - lavc 53.11.0
   Add avcodec_get_type().
 
-2011-08-06 - 2f63440 - lavf 53.7.0
+2011-08-06 - 0cb233c / 2f63440 - lavf 53.7.0
   Add error_recognition to AVFormatContext.
 
-2011-08-02 - 9d39cbf - lavc 53.9.1
+2011-08-02 - 1d186e9 / 9d39cbf - lavc 53.9.1
   Add AV_PKT_FLAG_CORRUPT AVPacket flag.
 
 2011-07-16 - b57df29 - lavfi 2.27.0
@@ -557,11 +600,11 @@
   avfilter_set_common_packing_formats()
   avfilter_all_packing_formats()
 
-2011-07-10 - a67c061 - lavf 53.6.0
+2011-07-10 - 3602ad7 / a67c061 - lavf 53.6.0
   Add avformat_find_stream_info(), deprecate av_find_stream_info().
   NOTE: this was backported to 0.7
 
-2011-07-10 - 0b950fe - lavc 53.8.0
+2011-07-10 - 3602ad7 / 0b950fe - lavc 53.8.0
   Add avcodec_open2(), deprecate avcodec_open().
   NOTE: this was backported to 0.7
 
@@ -604,35 +647,35 @@
 2011-06-12 - 6119b23 - lavfi 2.16.0 - avfilter_graph_parse()
   Change avfilter_graph_parse() signature.
 
-2011-06-23 - 67e9ae1 - lavu 51.8.0 - attributes.h
+2011-06-23 - 686959e / 67e9ae1 - lavu 51.10.0 / 51.8.0 - attributes.h
   Add av_printf_format().
 
-2011-06-16 - 05e84c9, 25de595 - lavf 53.2.0 - avformat.h
+2011-06-16 - 2905e3f / 05e84c9, 2905e3f / 25de595 - lavf 53.4.0 / 53.2.0 - avformat.h
   Add avformat_open_input and avformat_write_header().
   Deprecate av_open_input_stream, av_open_input_file,
   AVFormatParameters and av_write_header.
 
-2011-06-16 - 7e83e1c, dc59ec5 - lavu 51.7.0 - opt.h
+2011-06-16 - 2905e3f / 7e83e1c, 2905e3f / dc59ec5 - lavu 51.9.0 / 51.7.0 - opt.h
   Add av_opt_set_dict() and av_opt_find().
   Deprecate av_find_opt().
   Add AV_DICT_APPEND flag.
 
-2011-06-10 - cb7c11c - lavu 51.6.0 - opt.h
+2011-06-10 - 45fb647 / cb7c11c - lavu 51.6.0 - opt.h
   Add av_opt_flag_is_set().
 
 2011-06-10 - c381960 - lavfi 2.15.0 - avfilter_get_audio_buffer_ref_from_arrays
   Add avfilter_get_audio_buffer_ref_from_arrays() to avfilter.h.
 
-2011-06-09 - d9f80ea - lavu 51.8.0 - AVMetadata
+2011-06-09 - f9ecb84 / d9f80ea - lavu 51.8.0 - AVMetadata
   Move AVMetadata from lavf to lavu and rename it to
   AVDictionary -- new installed header dict.h.
   All av_metadata_* functions renamed to av_dict_*.
 
-2011-06-07 - a6703fa - lavu 51.8.0 - av_get_bytes_per_sample()
+2011-06-07 - d552f61 / a6703fa - lavu 51.8.0 - av_get_bytes_per_sample()
   Add av_get_bytes_per_sample() in libavutil/samplefmt.h.
   Deprecate av_get_bits_per_sample_fmt().
 
-2011-06-05 - b39b062 - lavu 51.8.0 - opt.h
+2011-06-05 - f956924 / b39b062 - lavu 51.8.0 - opt.h
   Add av_opt_free convenience function.
 
 2011-06-06 - 95a0242 - lavfi 2.14.0 - AVFilterBufferRefAudioProps
@@ -662,7 +705,7 @@
   Add av_get_pix_fmt_name() in libavutil/pixdesc.h, and deprecate
   avcodec_get_pix_fmt_name() in libavcodec/avcodec.h in its favor.
 
-2011-05-25 - 30315a8 - lavf 53.3.0 - avformat.h
+2011-05-25 - 39e4206 / 30315a8 - lavf 53.3.0 - avformat.h
   Add fps_probe_size to AVFormatContext.
 
 2011-05-22 - 5ecdfd0 - lavf 53.2.0 - avformat.h
@@ -678,10 +721,10 @@
 2011-05-14 - 9fdf772 - lavfi 2.6.0 - avcodec.h
   Add avfilter_get_video_buffer_ref_from_frame() to libavfilter/avcodec.h.
 
-2011-05-18 - 64150ff - lavc 53.7.0 - AVCodecContext.request_sample_fmt
+2011-05-18 - 75a37b5 / 64150ff - lavc 53.7.0 - AVCodecContext.request_sample_fmt
   Add request_sample_fmt field to AVCodecContext.
 
-2011-05-10 - 188dea1 - lavc 53.6.0 - avcodec.h
+2011-05-10 - 59eb12f / 188dea1 - lavc 53.6.0 - avcodec.h
   Deprecate AVLPCType and the following fields in
   AVCodecContext: lpc_coeff_precision, prediction_order_method,
   min_partition_order, max_partition_order, lpc_type, lpc_passes.
@@ -711,81 +754,81 @@
   Add av_dynarray_add function for adding
   an element to a dynamic array.
 
-2011-04-26 - bebe72f - lavu 51.1.0 - avutil.h
+2011-04-26 - d7e5aeb / bebe72f - lavu 51.1.0 - avutil.h
   Add AVPictureType enum and av_get_picture_type_char(), deprecate
   FF_*_TYPE defines and av_get_pict_type_char() defined in
   libavcodec/avcodec.h.
 
-2011-04-26 - 10d3940 - lavfi 2.3.0 - avfilter.h
+2011-04-26 - d7e5aeb / 10d3940 - lavfi 2.3.0 - avfilter.h
   Add pict_type and key_frame fields to AVFilterBufferRefVideo.
 
-2011-04-26 - 7a11c82 - lavfi 2.2.0 - vsrc_buffer
+2011-04-26 - d7e5aeb / 7a11c82 - lavfi 2.2.0 - vsrc_buffer
   Add sample_aspect_ratio fields to vsrc_buffer arguments
 
-2011-04-21 - 94f7451 - lavc 53.1.0 - avcodec.h
+2011-04-21 - 8772156 / 94f7451 - lavc 53.1.0 - avcodec.h
   Add CODEC_CAP_SLICE_THREADS for codecs supporting sliced threading.
 
 2011-04-15 - lavc 52.120.0 - avcodec.h
   AVPacket structure got additional members for passing side information:
-    4de339e introduce side information for AVPacket
-    2d8591c make containers pass palette change in AVPacket
+    c407984 / 4de339e introduce side information for AVPacket
+    c407984 / 2d8591c make containers pass palette change in AVPacket
 
 2011-04-12 - lavf 52.107.0 - avio.h
   Avio cleanup, part II - deprecate the entire URLContext API:
-    175389c add avio_check as a replacement for url_exist
-    ff1ec0c add avio_pause and avio_seek_time as replacements
+    c55780d / 175389c add avio_check as a replacement for url_exist
+    9891004 / ff1ec0c add avio_pause and avio_seek_time as replacements
             for _av_url_read_fseek/fpause
-    cdc6a87 deprecate av_protocol_next(), avio_enum_protocols
+    d4d0932 / cdc6a87 deprecate av_protocol_next(), avio_enum_protocols
             should be used instead.
-    80c6e23 rename url_set_interrupt_cb->avio_set_interrupt_cb.
-    f87b1b3 rename open flags: URL_* -> AVIO_*
-    f8270bb add avio_enum_protocols.
-    5593f03 deprecate URLProtocol.
-    c486dad deprecate URLContext.
-    026e175 deprecate the typedef for URLInterruptCB
-    8e76a19 deprecate av_register_protocol2.
-    b840484 deprecate URL_PROTOCOL_FLAG_NESTED_SCHEME
-    1305d93 deprecate av_url_read_seek
-    fa104e1 deprecate av_url_read_pause
-    727c7aa deprecate url_get_filename().
-    5958df3 deprecate url_max_packet_size().
-    1869ea0 deprecate url_get_file_handle().
-    32a97d4 deprecate url_filesize().
-    e52a914 deprecate url_close().
-    58a48c6 deprecate url_seek().
-    925e908 deprecate url_write().
-    dce3756 deprecate url_read_complete().
-    bc371ac deprecate url_read().
-    0589da0 deprecate url_open().
-    62eaaea deprecate url_connect.
-    5652bb9 deprecate url_alloc.
-    333e894 deprecate url_open_protocol
-    e230705 deprecate url_poll and URLPollEntry
+    c88caa5 / 80c6e23 rename url_set_interrupt_cb->avio_set_interrupt_cb.
+    c88caa5 / f87b1b3 rename open flags: URL_* -> AVIO_*
+    d4d0932 / f8270bb add avio_enum_protocols.
+    d4d0932 / 5593f03 deprecate URLProtocol.
+    d4d0932 / c486dad deprecate URLContext.
+    d4d0932 / 026e175 deprecate the typedef for URLInterruptCB
+    c88caa5 / 8e76a19 deprecate av_register_protocol2.
+    11d7841 / b840484 deprecate URL_PROTOCOL_FLAG_NESTED_SCHEME
+    11d7841 / 1305d93 deprecate av_url_read_seek
+    11d7841 / fa104e1 deprecate av_url_read_pause
+    434f248 / 727c7aa deprecate url_get_filename().
+    434f248 / 5958df3 deprecate url_max_packet_size().
+    434f248 / 1869ea0 deprecate url_get_file_handle().
+    434f248 / 32a97d4 deprecate url_filesize().
+    434f248 / e52a914 deprecate url_close().
+    434f248 / 58a48c6 deprecate url_seek().
+    434f248 / 925e908 deprecate url_write().
+    434f248 / dce3756 deprecate url_read_complete().
+    434f248 / bc371ac deprecate url_read().
+    434f248 / 0589da0 deprecate url_open().
+    434f248 / 62eaaea deprecate url_connect.
+    434f248 / 5652bb9 deprecate url_alloc.
+    434f248 / 333e894 deprecate url_open_protocol
+    434f248 / e230705 deprecate url_poll and URLPollEntry
 
 2011-04-08 - lavf 52.106.0 - avformat.h
   Minor avformat.h cleanup:
-    a9bf9d8 deprecate av_guess_image2_codec
-    c3675df rename avf_sdp_create->av_sdp_create
+    d4d0932 / a9bf9d8 deprecate av_guess_image2_codec
+    d4d0932 / c3675df rename avf_sdp_create->av_sdp_create
 
 2011-04-03 - lavf 52.105.0 - avio.h
   Large-scale renaming/deprecating of AVIOContext-related functions:
-    724f6a0 deprecate url_fdopen
-    403ee83 deprecate url_open_dyn_packet_buf
-    6dc7d80 rename url_close_dyn_buf       -> avio_close_dyn_buf
-    b92c545 rename url_open_dyn_buf        -> avio_open_dyn_buf
-    8978fed introduce an AVIOContext.seekable field as a replacement for
+    2cae980 / 724f6a0 deprecate url_fdopen
+    2cae980 / 403ee83 deprecate url_open_dyn_packet_buf
+    2cae980 / 6dc7d80 rename url_close_dyn_buf       -> avio_close_dyn_buf
+    2cae980 / b92c545 rename url_open_dyn_buf        -> avio_open_dyn_buf
+    2cae980 / 8978fed introduce an AVIOContext.seekable field as a replacement for
             AVIOContext.is_streamed and url_is_streamed()
-    b64030f deprecate get_checksum()
-    4c4427a deprecate init_checksum()
-    4ec153b deprecate udp_set_remote_url/get_local_port
-    933e90a deprecate av_url_read_fseek/fpause
-    8d9769a deprecate url_fileno
-    b7f2fdd rename put_flush_packet -> avio_flush
-    35f1023 deprecate url_close_buf
-    83fddae deprecate url_open_buf
-    d9d86e0 rename url_fprintf -> avio_printf
-    59f65d9 deprecate url_setbufsize
-    3e68b3b deprecate url_ferror
+    1caa412 / b64030f deprecate get_checksum()
+    1caa412 / 4c4427a deprecate init_checksum()
+    2fd41c9 / 4ec153b deprecate udp_set_remote_url/get_local_port
+    4fa0e24 / 933e90a deprecate av_url_read_fseek/fpause
+    4fa0e24 / 8d9769a deprecate url_fileno
+    0fecf26 / b7f2fdd rename put_flush_packet -> avio_flush
+    0fecf26 / 35f1023 deprecate url_close_buf
+    0fecf26 / 83fddae deprecate url_open_buf
+    0fecf26 / d9d86e0 rename url_fprintf -> avio_printf
+    0fecf26 / 59f65d9 deprecate url_setbufsize
+    6947b0c / 3e68b3b deprecate url_ferror
     e8bb2e2 deprecate url_fget_max_packet_size
     76aa876 rename url_fsize -> avio_size
     e519753 deprecate url_fgetc
@@ -806,7 +849,7 @@
     b3db9ce deprecate get_partial_buffer
     8d9ac96 rename av_alloc_put_byte -> avio_alloc_context
 
-2011-03-25 - 34b47d7 - lavc 52.115.0 - AVCodecContext.audio_service_type
+2011-03-25 - 27ef7b1 / 34b47d7 - lavc 52.115.0 - AVCodecContext.audio_service_type
   Add audio_service_type field to AVCodecContext.
 
 2011-03-17 - e309fdc - lavu 50.40.0 - pixfmt.h
@@ -844,11 +887,11 @@
 2011-02-10 - 12c14cd - lavf 52.99.0 - AVStream.disposition
   Add AV_DISPOSITION_HEARING_IMPAIRED and AV_DISPOSITION_VISUAL_IMPAIRED.
 
-2011-02-09 - 5592734 - lavc 52.112.0 - avcodec_thread_init()
+2011-02-09 - c0b102c - lavc 52.112.0 - avcodec_thread_init()
   Deprecate avcodec_thread_init()/avcodec_thread_free() use; instead
   set thread_count before calling avcodec_open.
 
-2011-02-09 - 778b08a - lavc 52.111.0 - threading API
+2011-02-09 - 37b00b4 - lavc 52.111.0 - threading API
   Add CODEC_CAP_FRAME_THREADS with new restrictions on get_buffer()/
   release_buffer()/draw_horiz_band() callbacks for appropriate codecs.
   Add thread_type and active_thread_type fields to AVCodecContext.
diff --git a/doc/Doxyfile b/doc/Doxyfile
index 9e12ab0..7e6d0f5 100644
--- a/doc/Doxyfile
+++ b/doc/Doxyfile
@@ -288,7 +288,7 @@
 # causing a significant performance penality.
 # If the system has enough physical memory increasing the cache will improve the
 # performance by keeping more symbols in memory. Note that the value works on
-# a logarithmic scale so increasing the size by one will rougly double the
+# a logarithmic scale so increasing the size by one will roughly double the
 # memory usage. The cache size is given by this formula:
 # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
 # corresponding to a cache size of 2^16 = 65536 symbols
diff --git a/doc/Makefile b/doc/Makefile
index e85e53b..a861655 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -25,7 +25,6 @@
               doc/git-howto.html                                        \
               doc/nut.html                                              \
               doc/platform.html                                         \
-              doc/syntax.html                                           \
 
 TXTPAGES    = doc/fate.txt                                              \
 
@@ -63,7 +62,7 @@
 	$(M)texi2html -I doc -monolithic --init-file $(SRC_PATH)/doc/t2h.init --output $@ $<
 
 doc/%.pod: TAG = POD
-doc/%.pod: doc/%.texi $(GENTEXI)
+doc/%.pod: doc/%.texi $(SRC_PATH)/doc/texi2pod.pl $(GENTEXI)
 	$(Q)$(TEXIDEP)
 	$(M)perl $(SRC_PATH)/doc/texi2pod.pl -Idoc $< $@
 
@@ -93,7 +92,9 @@
 uninstall-man:
 	$(RM) $(addprefix "$(MANDIR)/man1/",$(ALLMANPAGES))
 
-clean::
+clean:: docclean
+
+docclean:
 	$(RM) $(TXTPAGES) doc/*.html doc/*.pod doc/*.1 doc/*.3 $(CLEANSUFFIXES:%=doc/%) doc/avoptions_*.texi
 	$(RM) -r doc/doxy/html
 
diff --git a/doc/RELEASE_NOTES b/doc/RELEASE_NOTES
index 135165a..f71f18a3 100644
--- a/doc/RELEASE_NOTES
+++ b/doc/RELEASE_NOTES
@@ -14,3 +14,9 @@
 FFmpeg, please try git master to check if the issue still exists. If it does,
 make your report against the development code following the usual bug reporting
 guidelines.
+
+Of big interest to our Windows users, FFmpeg now supports building with the MSVC
+compiler. Since MSVC does not support C99 features used extensively by FFmpeg,
+this has been accomplished using a converter that turns C99 code to C89. See the
+platform-specific documentation for more detailed documentation on building
+FFmpeg with MSVC.
diff --git a/doc/authors.texi b/doc/authors.texi
new file mode 100644
index 0000000..6c8c1d7
--- /dev/null
+++ b/doc/authors.texi
@@ -0,0 +1,11 @@
+@chapter Authors
+
+The FFmpeg developers.
+
+For details about the authorship, see the Git history of the project
+(git://source.ffmpeg.org/ffmpeg), e.g. by typing the command
+@command{git log} in the FFmpeg source directory, or browsing the
+online repository at @url{http://source.ffmpeg.org}.
+
+Maintainers for the specific components are listed in the file
+@file{MAINTAINERS} in the source code tree.
diff --git a/doc/avtools-common-opts.texi b/doc/avtools-common-opts.texi
index bce5220..d9d0bd0 100644
--- a/doc/avtools-common-opts.texi
+++ b/doc/avtools-common-opts.texi
@@ -152,11 +152,12 @@
 This file can be useful for bug reports.
 It also implies @code{-loglevel verbose}.
 
-Setting the environment variable @code{FFREPORT} to any value has the same
-effect. If the value is a ':'-separated key=value sequence, these options
-will affect the report; options values must be
-@ref{quoting_and_escaping, escaped} if they contain special characters or
-the options delimiter ':'. The following option is recognized:
+Setting the environment variable @code{FFREPORT} to any value has the
+same effect. If the value is a ':'-separated key=value sequence, these
+options will affect the report; options values must be escaped if they
+contain special characters or the options delimiter ':' (see the
+``Quoting and escaping'' section in the ffmpeg-utils manual). The
+following option is recognized:
 @table @option
 @item file
 set the file name to use for the report; @code{%p} is expanded to the name
@@ -208,6 +209,3 @@
 
 Note2 old undocumented way of specifying per-stream AVOptions by prepending
 v/a/s to the options name is now obsolete and will be removed soon.
-
-@include avoptions_codec.texi
-@include avoptions_format.texi
diff --git a/doc/decoders.texi b/doc/decoders.texi
index 87ad4ee..2d812a27 100644
--- a/doc/decoders.texi
+++ b/doc/decoders.texi
@@ -61,3 +61,29 @@
 documented.
 
 @c man end AUDIO DECODERS
+
+@chapter Subtitles Decoders
+@c man begin SUBTILES DECODERS
+
+@section dvdsub
+
+This codec decodes the bitmap subtitles used in DVDs; the same subtitles can
+also be found in VobSub file pairs and in some Matroska files.
+
+@subsection Options
+
+@table @option
+@item palette
+Specify the global palette used by the bitmaps. When stored in VobSub, the
+palette is normally specified in the index file; in Matroska, the palette is
+stored in the codec extra-data in the same format as in VobSub. In DVDs, the
+palette is stored in the IFO file, and therefore not available when reading
+from dumped VOB files.
+
+The format for this option is a string containing 16 24-bits hexadecimal
+numbers (without 0x prefix) separated by comas, for example @code{0d00ee,
+ee450d, 101010, eaeaea, 0ce60b, ec14ed, ebff0b, 0d617a, 7b7b7b, d1d1d1,
+7b2a0e, 0d950c, 0f007b, cf0dec, cfa80c, 7c127b}.
+@end table
+
+@c man end SUBTILES DECODERS
diff --git a/doc/default.css b/doc/default.css
new file mode 100644
index 0000000..77a3514
--- /dev/null
+++ b/doc/default.css
@@ -0,0 +1,149 @@
+a {
+    color: #2D6198;
+}
+
+a:visited {
+    color: #884488;
+}
+
+#banner {
+    background-color: white;
+    position: relative;
+    text-align: center;
+}
+
+#banner img {
+    padding-bottom: 1px;
+    padding-top: 5px;
+}
+
+#body {
+    margin-left: 1em;
+    margin-right: 1em;
+}
+
+body {
+    background-color: #313131;
+    margin: 0;
+    text-align: justify;
+}
+
+.center {
+    margin-left: auto;
+    margin-right: auto;
+    text-align: center;
+}
+
+#container {
+    background-color: white;
+    color: #202020;
+    margin-left: 1em;
+    margin-right: 1em;
+}
+
+#footer {
+    text-align: center;
+}
+
+h1, h2, h3 {
+    padding-left: 0.4em;
+    border-radius: 4px;
+    padding-bottom: 0.2em;
+    padding-top: 0.2em;
+    border: 1px solid #6A996A;
+}
+
+h1 {
+    background-color: #7BB37B;
+    color: #151515;
+    font-size: 1.2em;
+    padding-bottom: 0.3em;
+    padding-top: 0.3em;
+}
+
+h2 {
+    color: #313131;
+    font-size: 0.9em;
+    background-color: #ABE3AB;
+}
+
+h3 {
+    color: #313131;
+    font-size: 0.8em;
+    margin-bottom: -8px;
+    background-color: #BBF3BB;
+}
+
+img {
+    border: 0;
+}
+
+#navbar {
+    background-color: #738073;
+    border-bottom: 1px solid #5C665C;
+    border-top: 1px solid #5C665C;
+    margin-top: 12px;
+    padding: 0.3em;
+    position: relative;
+    text-align: center;
+}
+
+#navbar a, #navbar_secondary a {
+    color: white;
+    padding: 0.3em;
+    text-decoration: none;
+}
+
+#navbar a:hover, #navbar_secondary a:hover {
+    background-color: #313131;
+    color: white;
+    text-decoration: none;
+}
+
+#navbar_secondary {
+    background-color: #738073;
+    border-bottom: 1px solid #5C665C;
+    border-left: 1px solid #5C665C;
+    border-right: 1px solid #5C665C;
+    padding: 0.3em;
+    position: relative;
+    text-align: center;
+}
+
+p {
+    margin-left: 1em;
+    margin-right: 1em;
+}
+
+pre {
+    margin-left: 3em;
+    margin-right: 3em;
+    padding: 0.3em;
+    border: 1px solid #bbb;
+    background-color: #f7f7f7;
+}
+
+dl dt {
+    font-weight: bold;
+}
+
+#proj_desc {
+    font-size: 1.2em;
+}
+
+#repos {
+    margin-left: 1em;
+    margin-right: 1em;
+    border-collapse: collapse;
+    border: solid 1px #6A996A;
+}
+
+#repos th {
+    background-color: #7BB37B;
+    border: solid 1px #6A996A;
+}
+
+#repos td {
+    padding: 0.2em;
+    border: solid 1px #6A996A;
+}
diff --git a/doc/demuxers.texi b/doc/demuxers.texi
index aea4c54..c8eec21 100644
--- a/doc/demuxers.texi
+++ b/doc/demuxers.texi
@@ -6,18 +6,93 @@
 
 When you configure your FFmpeg build, all the supported demuxers
 are enabled by default. You can list all available ones using the
-configure option "--list-demuxers".
+configure option @code{--list-demuxers}.
 
 You can disable all the demuxers using the configure option
-"--disable-demuxers", and selectively enable a single demuxer with
-the option "--enable-demuxer=@var{DEMUXER}", or disable it
-with the option "--disable-demuxer=@var{DEMUXER}".
+@code{--disable-demuxers}, and selectively enable a single demuxer with
+the option @code{--enable-demuxer=@var{DEMUXER}}, or disable it
+with the option @code{--disable-demuxer=@var{DEMUXER}}.
 
-The option "-formats" of the ff* tools will display the list of
+The option @code{-formats} of the ff* tools will display the list of
 enabled demuxers.
 
 The description of some of the currently available demuxers follows.
 
+@section applehttp
+
+Apple HTTP Live Streaming demuxer.
+
+This demuxer presents all AVStreams from all variant streams.
+The id field is set to the bitrate variant index number. By setting
+the discard flags on AVStreams (by pressing 'a' or 'v' in ffplay),
+the caller can decide which variant streams to actually receive.
+The total bitrate of the variant that the stream belongs to is
+available in a metadata key named "variant_bitrate".
+
+@section concat
+
+Virtual concatenation script demuxer.
+
+This demuxer reads a list of files and other directives from a text file and
+demuxes them one after the other, as if all their packet had been muxed
+together.
+
+The timestamps in the files are adjusted so that the first file starts at 0
+and each next file starts where the previous one finishes. Note that it is
+done globally and may cause gaps if all streams do not have exactly the same
+length.
+
+All files must have the same streams (same codecs, same time base, etc.).
+
+@subsection Syntax
+
+The script is a text file in extended-ASCII, with one directive per line.
+Empty lines, leading spaces and lines starting with '#' are ignored. The
+following directive is recognized:
+
+@table @option
+
+@item @code{file @var{path}}
+Path to a file to read; special characters and spaces must be escaped with
+backslash or single quotes.
+
+All subsequent directives apply to that file.
+
+@item @code{ffconcat version 1.0}
+Identify the script type and version. It also sets the @option{safe} option
+to 1 if it was to its default -1.
+
+To make FFmpeg recognize the format automatically, this directive must
+appears exactly as is (no extra space or byte-order-mark) on the very first
+line of the script.
+
+@item @code{duration @var{dur}}
+Duration of the file. This information can be specified from the file;
+specifying it here may be more efficient or help if the information from the
+file is not available or accurate.
+
+@end table
+
+@subsection Options
+
+This demuxer accepts the following option:
+
+@table @option
+
+@item safe
+If set to 1, reject unsafe file paths. A file path is considered safe if it
+does not contain a protocol specification and is relative and all components
+only contain characters from the portable character set (letters, digits,
+period, underscore and hyphen) and have no period at the beginning of a
+component.
+
+If set to 0, any file name is accepted.
+
+The default is -1, it is equivalent to 1 if the format was automatically
+probed and 0 otherwise.
+
+@end table
+
 @section image2
 
 Image file demuxer.
@@ -143,16 +218,34 @@
 @end example
 @end itemize
 
-@section applehttp
+@section rawvideo
 
-Apple HTTP Live Streaming demuxer.
+Raw video demuxer.
 
-This demuxer presents all AVStreams from all variant streams.
-The id field is set to the bitrate variant index number. By setting
-the discard flags on AVStreams (by pressing 'a' or 'v' in ffplay),
-the caller can decide which variant streams to actually receive.
-The total bitrate of the variant that the stream belongs to is
-available in a metadata key named "variant_bitrate".
+This demuxer allows to read raw video data. Since there is no header
+specifying the assumed video parameters, the user must specify them
+in order to be able to decode the data correctly.
+
+This demuxer accepts the following options:
+@table @option
+
+@item framerate
+Set input video frame rate. Default value is 25.
+
+@item pixel_format
+Set the input video pixel format. Default value is @code{yuv420p}.
+
+@item video_size
+Set the input video size. This value must be specified explicitly.
+@end table
+
+For example to read a rawvideo file @file{input.raw} with
+@command{ffplay}, assuming a pixel format of @code{rgb24}, a video
+size of @code{320x240}, and a frame rate of 10 images per second, use
+the command:
+@example
+ffplay -f rawvideo -pixel_format rgb24 -video_size 320x240 -framerate 10 input.raw
+@end example
 
 @section sbg
 
@@ -184,4 +277,25 @@
 timestamps up to the sound controller's clock accuracy, but if the user
 somehow pauses the playback or seeks, all times will be shifted accordingly.
 
-@c man end INPUT DEVICES
+@section tedcaptions
+
+JSON captions used for @url{http://www.ted.com/, TED Talks}.
+
+TED does not provide links to the captions, but they can be guessed from the
+page. The file @file{tools/bookmarklets.html} from the FFmpeg source tree
+contains a bookmarklet to expose them.
+
+This demuxer accepts the following option:
+@table @option
+@item start_time
+Set the start time of the TED talk, in milliseconds. The default is 15000
+(15s). It is used to sync the captions with the downloadable videos, because
+they include a 15s intro.
+@end table
+
+Example: convert the captions to a format most players understand:
+@example
+ffmpeg -i http://www.ted.com/talks/subtitles/id/1/lang/en talk1-en.srt
+@end example
+
+@c man end DEMUXERS
diff --git a/doc/developer.texi b/doc/developer.texi
index b0e5216..fe4b40a 100644
--- a/doc/developer.texi
+++ b/doc/developer.texi
@@ -147,30 +147,42 @@
 @end itemize
 
 @subsection Naming conventions
-All names are using underscores (_), not CamelCase. For example, @samp{avfilter_get_video_buffer} is
-a valid function name and @samp{AVFilterGetVideo} is not. The exception from this are type names, like
+All names should be composed with underscores (_), not CamelCase. For example,
+@samp{avfilter_get_video_buffer} is an acceptable function name and
+@samp{AVFilterGetVideo} is not. The exception from this are type names, like
 for example structs and enums; they should always be in the CamelCase
 
-
-There are following conventions for naming variables and functions:
+There are the following conventions for naming variables and functions:
 @itemize @bullet
 @item
 For local variables no prefix is required.
 @item
-For variables and functions declared as @code{static} no prefixes are required.
+For variables and functions declared as @code{static} no prefix is required.
 @item
-For variables and functions used internally by the library, @code{ff_} prefix
-should be used.
-For example, @samp{ff_w64_demuxer}.
+For variables and functions used internally by a library an @code{ff_}
+prefix should be used, e.g. @samp{ff_w64_demuxer}.
 @item
 For variables and functions used internally across multiple libraries, use
 @code{avpriv_}. For example, @samp{avpriv_aac_parse_header}.
 @item
-For exported names, each library has its own prefixes. Just check the existing
-code and name accordingly.
+Each library has its own prefix for public symbols, in addition to the
+commonly used @code{av_} (@code{avformat_} for libavformat,
+@code{avcodec_} for libavcodec, @code{swr_} for libswresample, etc).
+Check the existing code and choose names accordingly.
+Note that some symbols without these prefixes are also exported for
+retro-compatibility reasons. These exceptions are declared in the
+@code{lib<name>/lib<name>.v} files.
 @end itemize
 
-@subsection Miscellanous conventions
+Furthermore, name space reserved for the system should not be invaded.
+Identifiers ending in @code{_t} are reserved by
+@url{http://pubs.opengroup.org/onlinepubs/007904975/functions/xsh_chap02_02.html#tag_02_02_02, POSIX}.
+Also avoid names starting with @code{__} or @code{_} followed by an uppercase
+letter as they are reserved by the C standard. Names starting with @code{_}
+are reserved at the file level and may not be used for externally visible
+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,
@@ -190,8 +202,8 @@
 set softtabstop=4
 set cindent
 set cinoptions=(0
-" allow tabs in Makefiles
-autocmd FileType make set noexpandtab shiftwidth=8 softtabstop=8
+" Allow tabs in Makefiles.
+autocmd FileType make,automake set noexpandtab shiftwidth=8 softtabstop=8
 " Trailing whitespace and tabs are forbidden, so highlight them.
 highlight ForbiddenWhitespace ctermbg=red guibg=red
 match ForbiddenWhitespace /\s\+$\|\t/
@@ -217,8 +229,13 @@
 
 @enumerate
 @item
-   Contributions should be licensed under the LGPL 2.1, including an
-   "or any later version" clause, or the MIT license.  GPL 2 including
+   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
@@ -229,6 +246,13 @@
    (#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
@@ -334,8 +358,6 @@
 
 We think our rules are not too hard. If you have comments, contact us.
 
-Note, these rules are mostly borrowed from the MPlayer project.
-
 @anchor{Submitting patches}
 @section Submitting patches
 
@@ -358,11 +380,6 @@
 Run the @ref{Regression tests} before submitting a patch in order to verify
 it does not cause unexpected problems.
 
-Patches should be posted as base64 encoded attachments (or any other
-encoding which ensures that the patch will not be trashed during
-transmission) to the ffmpeg-devel mailing list, see
-@url{http://lists.ffmpeg.org/mailman/listinfo/ffmpeg-devel}
-
 It also helps quite a bit if you tell us what the patch does (for example
 'replaces lrint by lrintf'), and why (for example '*BSD isn't C99 compliant
 and has no lrint()')
@@ -370,6 +387,13 @@
 Also please if you send several patches, send each patch as a separate mail,
 do not attach several unrelated patches to the same mail.
 
+Patches should be posted to the
+@uref{http://lists.ffmpeg.org/mailman/listinfo/ffmpeg-devel, ffmpeg-devel}
+mailing list. Use @code{git send-email} when possible since it will properly
+send patches without requiring extra care. If you cannot, then send patches
+as base64-encoded attachments, so your patch is not trashed during
+transmission.
+
 Your patch will be reviewed on the mailing list. You will likely be asked
 to make some changes and are expected to send in an improved version that
 incorporates the requests from the review. This process may go through
@@ -398,7 +422,7 @@
     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},
+    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?
@@ -451,8 +475,10 @@
     other security issues?
 @item
     Did you test your decoder or demuxer against damaged data? If no, see
-    tools/trasher and the noise bitstream filter. Your decoder or demuxer
-    should not crash or end in a (near) infinite loop when fed damaged data.
+    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?
 @item
@@ -496,6 +522,9 @@
     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.
 @end enumerate
 
 @section Patch review process
diff --git a/doc/encoders.texi b/doc/encoders.texi
index da44c17..07343eb 100644
--- a/doc/encoders.texi
+++ b/doc/encoders.texi
@@ -450,7 +450,8 @@
 Set the global quality in lambda units, only works if the
 @code{qscale} flag in @option{flags} is enabled. The value is clipped
 in the [0 - 10*@code{FF_QP2LAMBDA}] range, and then multiplied for 6.3
-to get a value in the native libtheora range [0-63].
+to get a value in the native libtheora range [0-63]. A higher value
+corresponds to a higher quality.
 
 For example, to set maximum constant quality encoding with
 @command{ffmpeg}:
@@ -580,49 +581,183 @@
 
 @section libx264
 
-H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 format supported through
-libx264.
+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
 @code{--enable-libx264}.
 
-@subsection Options
+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).
 
+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.
+
+@subsection Option Mapping
+
+The following options are supported by the x264 wrapper, the x264-equivalent
+options follow the FFmpeg ones.
+
+@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
+
+@subsection Private Options
 @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 preset @var{preset_name}
-Set the encoding preset.
+Possible values:
+@table @samp
+@item none
 
-@item tune @var{tune_name}
-Tune the encoding params.
+@item variance
+Variance AQ (complexity mask).
+@item autovariance
+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.
 
-@item fastfirstpass @var{bool}
-Use fast settings when encoding first pass, default value is 1.
+Possible values:
+@table @samp
+@item none
 
-@item profile @var{profile_name}
-Set profile restrictions.
+@item simple
 
-@item level @var{level}
-Specify level (as defined by Annex A).
-Deprecated in favor of @var{x264opts}.
+@item smart
 
-@item passlogfile @var{filename}
-Specify filename for 2 pass stats.
-Deprecated in favor of @var{x264opts} (see @var{stats} libx264 option).
+@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.
 
-@item wpredp @var{wpred_type}
-Specify Weighted prediction for P-frames.
-Deprecated in favor of @var{x264opts} (see @var{weightp} libx264 option).
+Possible values:
+@table @samp
+@item none
+
+@item strict
+Strictly hierarchical pyramid.
+@item 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:
+@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
+
+@end table
 
 @item x264opts @var{options}
-Allow to set any x264 option, see x264 --fullhelp for a list.
+Allow to set any x264 option, see @code{x264 --fullhelp} for a list.
 
 @var{options} 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.
-@end table
 
 For example to specify libx264 encoding options with @command{ffmpeg}:
 @example
@@ -632,4 +767,14 @@
 For more information about libx264 and the supported options see:
 @url{http://www.videolan.org/developers/x264.html}
 
+@item -x264-params @var{string}
+Override the x264 configuration using a :-separated list of key=value parameters.
+@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
+@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).
+
 @c man end VIDEO ENCODERS
diff --git a/doc/eval.texi b/doc/eval.texi
index 1ea89d6..3b7964c 100644
--- a/doc/eval.texi
+++ b/doc/eval.texi
@@ -20,57 +20,93 @@
 
 The following functions are available:
 @table @option
-@item sinh(x)
-Compute hyperbolic sine of @var{x}.
-
-@item cosh(x)
-Compute hyperbolic cosine of @var{x}.
-
-@item tanh(x)
-Compute hyperbolic tangent of @var{x}.
-
-@item sin(x)
-Compute sine of @var{x}.
-
-@item cos(x)
-Compute cosine of @var{x}.
-
-@item tan(x)
-Compute tangent of @var{x}.
-
-@item atan(x)
-Compute arctangent of @var{x}.
-
-@item asin(x)
-Compute arcsine of @var{x}.
+@item abs(x)
+Compute absolute value of @var{x}.
 
 @item acos(x)
 Compute arccosine of @var{x}.
 
+@item asin(x)
+Compute arcsine of @var{x}.
+
+@item atan(x)
+Compute arctangent of @var{x}.
+
+@item ceil(expr)
+Round the value of expression @var{expr} upwards to the nearest
+integer. For example, "ceil(1.5)" is "2.0".
+
+@item cos(x)
+Compute cosine of @var{x}.
+
+@item cosh(x)
+Compute hyperbolic cosine of @var{x}.
+
+@item eq(x, y)
+Return 1 if @var{x} and @var{y} are equivalent, 0 otherwise.
+
 @item exp(x)
 Compute exponential of @var{x} (with base @code{e}, the Euler's number).
 
-@item log(x)
-Compute natural logarithm of @var{x}.
-
-@item abs(x)
-Compute absolute value of @var{x}.
-
-@item squish(x)
-Compute expression @code{1/(1 + exp(4*x))}.
+@item floor(expr)
+Round the value of expression @var{expr} downwards to the nearest
+integer. For example, "floor(-1.5)" is "-2.0".
 
 @item gauss(x)
 Compute Gauss function of @var{x}, corresponding to
 @code{exp(-x*x/2) / sqrt(2*PI)}.
 
+@item gcd(x, y)
+Return the greatest common divisor of @var{x} and @var{y}. If both @var{x} and
+@var{y} are 0 or either or both are less than zero then behavior is undefined.
+
+@item gt(x, y)
+Return 1 if @var{x} is greater than @var{y}, 0 otherwise.
+
+@item gte(x, y)
+Return 1 if @var{x} is greater than or equal to @var{y}, 0 otherwise.
+
+@item hypot(x, y)
+This function is similar to the C function with the same name; it returns
+"sqrt(@var{x}*@var{x} + @var{y}*@var{y})", the length of the hypotenuse of a
+right triangle with sides of length @var{x} and @var{y}, or the distance of the
+point (@var{x}, @var{y}) from the origin.
+
+@item if(x, y)
+Evaluate @var{x}, and if the result is non-zero return the result of
+the evaluation of @var{y}, return 0 otherwise.
+
+@item if(x, y, z)
+Evaluate @var{x}, and if the result is non-zero return the evaluation
+result of @var{y}, otherwise the evaluation result of @var{z}.
+
+@item ifnot(x, y)
+Evaluate @var{x}, and if the result is zero return the result of the
+evaluation of @var{y}, return 0 otherwise.
+
+@item ifnot(x, y, z)
+Evaluate @var{x}, and if the result is zero return the evaluation
+result of @var{y}, otherwise the evaluation result of @var{z}.
+
 @item isinf(x)
 Return 1.0 if @var{x} is +/-INFINITY, 0.0 otherwise.
 
 @item isnan(x)
 Return 1.0 if @var{x} is NAN, 0.0 otherwise.
 
-@item mod(x, y)
-Compute the remainder of division of @var{x} by @var{y}.
+@item ld(var)
+Allow to load the value of the internal variable with number
+@var{var}, which was previously stored with st(@var{var}, @var{expr}).
+The function returns the loaded value.
+
+@item log(x)
+Compute natural logarithm of @var{x}.
+
+@item lt(x, y)
+Return 1 if @var{x} is lesser than @var{y}, 0 otherwise.
+
+@item lte(x, y)
+Return 1 if @var{x} is lesser than or equal to @var{y}, 0 otherwise.
 
 @item max(x, y)
 Return the maximum between @var{x} and @var{y}.
@@ -78,53 +114,8 @@
 @item min(x, y)
 Return the maximum between @var{x} and @var{y}.
 
-@item eq(x, y)
-Return 1 if @var{x} and @var{y} are equivalent, 0 otherwise.
-
-@item gte(x, y)
-Return 1 if @var{x} is greater than or equal to @var{y}, 0 otherwise.
-
-@item gt(x, y)
-Return 1 if @var{x} is greater than @var{y}, 0 otherwise.
-
-@item lte(x, y)
-Return 1 if @var{x} is lesser than or equal to @var{y}, 0 otherwise.
-
-@item lt(x, y)
-Return 1 if @var{x} is lesser than @var{y}, 0 otherwise.
-
-@item st(var, expr)
-Allow to store the value of the expression @var{expr} in an internal
-variable. @var{var} specifies the number of the variable where to
-store the value, and it is a value ranging from 0 to 9. The function
-returns the value stored in the internal variable.
-Note, Variables are currently not shared between expressions.
-
-@item ld(var)
-Allow to load the value of the internal variable with number
-@var{var}, which was previously stored with st(@var{var}, @var{expr}).
-The function returns the loaded value.
-
-@item while(cond, expr)
-Evaluate expression @var{expr} while the expression @var{cond} is
-non-zero, and returns the value of the last @var{expr} evaluation, or
-NAN if @var{cond} was always false.
-
-@item ceil(expr)
-Round the value of expression @var{expr} upwards to the nearest
-integer. For example, "ceil(1.5)" is "2.0".
-
-@item floor(expr)
-Round the value of expression @var{expr} downwards to the nearest
-integer. For example, "floor(-1.5)" is "-2.0".
-
-@item trunc(expr)
-Round the value of expression @var{expr} towards zero to the nearest
-integer. For example, "trunc(-1.5)" is "-1.0".
-
-@item sqrt(expr)
-Compute the square root of @var{expr}. This is equivalent to
-"(@var{expr})^.5".
+@item mod(x, y)
+Compute the remainder of division of @var{x} by @var{y}.
 
 @item not(expr)
 Return 1.0 if @var{expr} is zero, 0.0 otherwise.
@@ -133,39 +124,83 @@
 Compute the power of @var{x} elevated @var{y}, it is equivalent to
 "(@var{x})^(@var{y})".
 
+@item print(t)
+@item print(t, l)
+Print the value of expression @var{t} with loglevel @var{l}. If
+@var{l} is not specified then a default log level is used.
+Returns the value of the expression printed.
+
+Prints t with loglevel l
+
 @item random(x)
 Return a pseudo random value between 0.0 and 1.0. @var{x} is the index of the
 internal variable which will be used to save the seed/state.
 
-@item hypot(x, y)
-This function is similar to the C function with the same name; it returns
-"sqrt(@var{x}*@var{x} + @var{y}*@var{y})", the length of the hypotenuse of a
-right triangle with sides of length @var{x} and @var{y}, or the distance of the
-point (@var{x}, @var{y}) from the origin.
-
-@item gcd(x, y)
-Return the greatest common divisor of @var{x} and @var{y}. If both @var{x} and
-@var{y} are 0 or either or both are less than zero then behavior is undefined.
-
-@item if(x, y)
-Evaluate @var{x}, and if the result is non-zero return the result of
-the evaluation of @var{y}, return 0 otherwise.
-
-@item ifnot(x, y)
-Evaluate @var{x}, and if the result is zero return the result of the
-evaluation of @var{y}, return 0 otherwise.
-
-@item taylor(expr, x) taylor(expr, x, id)
-Evaluate a taylor series at x.
-expr represents the LD(id)-th derivates of f(x) at 0. If id is not specified
-then 0 is assumed.
-note, when you have the derivatives at y instead of 0
-taylor(expr, x-y) can be used
-When the series does not converge the results are undefined.
-
 @item root(expr, max)
-Finds x where f(x)=0 in the interval 0..max.
-f() must be continuous or the result is undefined.
+Find an input value for which the function represented by @var{expr}
+with argument @var{ld(0)} is 0 in the interval 0..@var{max}.
+
+The expression in @var{expr} must denote a continuous function or the
+result is undefined.
+
+@var{ld(0)} is used to represent the function input value, which means
+that the given expression will be evaluated multiple times with
+various input values that the expression can access through
+@code{ld(0)}. When the expression evaluates to 0 then the
+corresponding input value will be returned.
+
+@item sin(x)
+Compute sine of @var{x}.
+
+@item sinh(x)
+Compute hyperbolic sine of @var{x}.
+
+@item sqrt(expr)
+Compute the square root of @var{expr}. This is equivalent to
+"(@var{expr})^.5".
+
+@item squish(x)
+Compute expression @code{1/(1 + exp(4*x))}.
+
+@item st(var, expr)
+Allow to store the value of the expression @var{expr} in an internal
+variable. @var{var} specifies the number of the variable where to
+store the value, and it is a value ranging from 0 to 9. The function
+returns the value stored in the internal variable.
+Note, Variables are currently not shared between expressions.
+
+@item tan(x)
+Compute tangent of @var{x}.
+
+@item tanh(x)
+Compute hyperbolic tangent of @var{x}.
+
+@item taylor(expr, x)
+@item taylor(expr, x, id)
+Evaluate a Taylor series at @var{x}, given an expression representing
+the @code{ld(id)}-th derivative of a function at 0.
+
+When the series does not converge the result is undefined.
+
+@var{ld(id)} is used to represent the derivative order in @var{expr},
+which means that the given expression will be evaluated multiple times
+with various input values that the expression can access through
+@code{ld(id)}. If @var{id} is not specified then 0 is assumed.
+
+Note, when you have the derivatives at y instead of 0,
+@code{taylor(expr, x-y)} can be used.
+
+@item time(0)
+Return the current (wallclock) time in seconds.
+
+@item trunc(expr)
+Round the value of expression @var{expr} towards zero to the nearest
+integer. For example, "trunc(-1.5)" is "-1.0".
+
+@item while(cond, expr)
+Evaluate expression @var{expr} while the expression @var{cond} is
+non-zero, and returns the value of the last @var{expr} evaluation, or
+NAN if @var{cond} was always false.
 @end table
 
 The following constants are available:
@@ -185,68 +220,69 @@
 
 @code{+} works like OR
 
-and the construct:
+For example the construct:
 @example
-if A then B else C
+if (A AND B) then C
 @end example
-is equivalent to
+is equivalent to:
 @example
-if(A,B) + ifnot(A,C)
+if(A*B, C)
 @end example
 
 In your C code, you can extend the list of unary and binary functions,
 and define recognized constants, so that they are available for your
 expressions.
 
-The evaluator also recognizes the International System number
-postfixes. If 'i' is appended after the postfix, powers of 2 are used
-instead of powers of 10. The 'B' postfix multiplies the value for 8,
-and can be appended after another postfix or used alone. This allows
-using for example 'KB', 'MiB', 'G' and 'B' as postfix.
+The evaluator also recognizes the International System unit prefixes.
+If 'i' is appended after the prefix, binary prefixes are used, which
+are based on powers of 1024 instead of powers of 1000.
+The 'B' postfix multiplies the value by 8, and can be appended after a
+unit prefix or used alone. This allows using for example 'KB', 'MiB',
+'G' and 'B' as number postfix.
 
-Follows the list of available International System postfixes, with
+The list of available International System prefixes follows, with
 indication of the corresponding powers of 10 and of 2.
 @table @option
 @item y
--24 / -80
+10^-24 / 2^-80
 @item z
--21 / -70
+10^-21 / 2^-70
 @item a
--18 / -60
+10^-18 / 2^-60
 @item f
--15 / -50
+10^-15 / 2^-50
 @item p
--12 / -40
+10^-12 / 2^-40
 @item n
--9 / -30
+10^-9 / 2^-30
 @item u
--6 / -20
+10^-6 / 2^-20
 @item m
--3 / -10
+10^-3 / 2^-10
 @item c
--2
+10^-2
 @item d
--1
+10^-1
 @item h
-2
+10^2
 @item k
-3 / 10
+10^3 / 2^10
 @item K
-3 / 10
+10^3 / 2^10
 @item M
-6 / 20
+10^6 / 2^20
 @item G
-9 / 30
+10^9 / 2^30
 @item T
-12 / 40
+10^12 / 2^40
 @item P
-15 / 40
+10^15 / 2^40
 @item E
-18 / 50
+10^18 / 2^50
 @item Z
-21 / 60
+10^21 / 2^60
 @item Y
-24 / 70
+10^24 / 2^70
 @end table
 
 @c man end
diff --git a/doc/examples/Makefile b/doc/examples/Makefile
index 36c949a..c849daa 100644
--- a/doc/examples/Makefile
+++ b/doc/examples/Makefile
@@ -17,6 +17,7 @@
                 filtering_audio                    \
                 metadata                           \
                 muxing                             \
+                resampling_audio                   \
                 scaling_video                      \
 
 OBJS=$(addsuffix .o,$(EXAMPLES))
diff --git a/doc/examples/demuxing.c b/doc/examples/demuxing.c
index 3c9d4a1..6780e07 100644
--- a/doc/examples/demuxing.c
+++ b/doc/examples/demuxing.c
@@ -292,8 +292,10 @@
         printf("Demuxing audio from file '%s' into '%s'\n", src_filename, audio_dst_filename);
 
     /* read frames from the file */
-    while (av_read_frame(fmt_ctx, &pkt) >= 0)
+    while (av_read_frame(fmt_ctx, &pkt) >= 0) {
         decode_packet(&got_frame, 0);
+        av_free_packet(&pkt);
+    }
 
     /* flush cached frames */
     pkt.data = NULL;
@@ -314,7 +316,7 @@
     if (audio_stream) {
         const char *fmt;
 
-        if ((ret = get_format_from_sample_fmt(&fmt, audio_dec_ctx->sample_fmt) < 0))
+        if ((ret = get_format_from_sample_fmt(&fmt, audio_dec_ctx->sample_fmt)) < 0)
             goto end;
         printf("Play the output audio file with the command:\n"
                "ffplay -f %s -ac %d -ar %d %s\n",
diff --git a/doc/examples/filtering_audio.c b/doc/examples/filtering_audio.c
index b28e02b..6f70a8d 100644
--- a/doc/examples/filtering_audio.c
+++ b/doc/examples/filtering_audio.c
@@ -169,9 +169,13 @@
 {
     int ret;
     AVPacket packet;
-    AVFrame frame;
+    AVFrame *frame = avcodec_alloc_frame();
     int got_frame;
 
+    if (!frame) {
+        perror("Could not allocate frame");
+        exit(1);
+    }
     if (argc != 2) {
         fprintf(stderr, "Usage: %s file | %s\n", argv[0], player);
         exit(1);
@@ -193,9 +197,9 @@
             break;
 
         if (packet.stream_index == audio_stream_index) {
-            avcodec_get_frame_defaults(&frame);
+            avcodec_get_frame_defaults(frame);
             got_frame = 0;
-            ret = avcodec_decode_audio4(dec_ctx, &frame, &got_frame, &packet);
+            ret = avcodec_decode_audio4(dec_ctx, frame, &got_frame, &packet);
             if (ret < 0) {
                 av_log(NULL, AV_LOG_ERROR, "Error decoding audio\n");
                 continue;
@@ -203,7 +207,7 @@
 
             if (got_frame) {
                 /* push the audio data from decoded frame into the filtergraph */
-                if (av_buffersrc_add_frame(buffersrc_ctx, &frame, 0) < 0) {
+                if (av_buffersrc_add_frame(buffersrc_ctx, frame, 0) < 0) {
                     av_log(NULL, AV_LOG_ERROR, "Error while feeding the audio filtergraph\n");
                     break;
                 }
@@ -229,6 +233,7 @@
     if (dec_ctx)
         avcodec_close(dec_ctx);
     avformat_close_input(&fmt_ctx);
+    av_freep(&frame);
 
     if (ret < 0 && ret != AVERROR_EOF) {
         char buf[1024];
diff --git a/doc/examples/filtering_video.c b/doc/examples/filtering_video.c
index 90babb6..660e526 100644
--- a/doc/examples/filtering_video.c
+++ b/doc/examples/filtering_video.c
@@ -173,9 +173,13 @@
 {
     int ret;
     AVPacket packet;
-    AVFrame frame;
+    AVFrame *frame = avcodec_alloc_frame();
     int got_frame;
 
+    if (!frame) {
+        perror("Could not allocate frame");
+        exit(1);
+    }
     if (argc != 2) {
         fprintf(stderr, "Usage: %s file\n", argv[0]);
         exit(1);
@@ -197,19 +201,19 @@
             break;
 
         if (packet.stream_index == video_stream_index) {
-            avcodec_get_frame_defaults(&frame);
+            avcodec_get_frame_defaults(frame);
             got_frame = 0;
-            ret = avcodec_decode_video2(dec_ctx, &frame, &got_frame, &packet);
+            ret = avcodec_decode_video2(dec_ctx, frame, &got_frame, &packet);
             if (ret < 0) {
                 av_log(NULL, AV_LOG_ERROR, "Error decoding video\n");
                 break;
             }
 
             if (got_frame) {
-                frame.pts = av_frame_get_best_effort_timestamp(&frame);
+                frame->pts = av_frame_get_best_effort_timestamp(frame);
 
                 /* push the decoded frame into the filtergraph */
-                if (av_buffersrc_add_frame(buffersrc_ctx, &frame, 0) < 0) {
+                if (av_buffersrc_add_frame(buffersrc_ctx, frame, 0) < 0) {
                     av_log(NULL, AV_LOG_ERROR, "Error while feeding the filtergraph\n");
                     break;
                 }
@@ -236,6 +240,7 @@
     if (dec_ctx)
         avcodec_close(dec_ctx);
     avformat_close_input(&fmt_ctx);
+    av_freep(&frame);
 
     if (ret < 0 && ret != AVERROR_EOF) {
         char buf[1024];
diff --git a/doc/examples/muxing.c b/doc/examples/muxing.c
index f8b2f7c..8469b27 100644
--- a/doc/examples/muxing.c
+++ b/doc/examples/muxing.c
@@ -63,7 +63,8 @@
     /* find the encoder */
     *codec = avcodec_find_encoder(codec_id);
     if (!(*codec)) {
-        fprintf(stderr, "Could not find codec\n");
+        fprintf(stderr, "Could not find encoder for '%s'\n",
+                avcodec_get_name(codec_id));
         exit(1);
     }
 
@@ -133,12 +134,14 @@
 static void open_audio(AVFormatContext *oc, AVCodec *codec, AVStream *st)
 {
     AVCodecContext *c;
+    int ret;
 
     c = st->codec;
 
     /* open it */
-    if (avcodec_open2(c, codec, NULL) < 0) {
-        fprintf(stderr, "Could not open audio codec\n");
+    ret = avcodec_open2(c, codec, NULL);
+    if (ret < 0) {
+        fprintf(stderr, "Could not open audio codec: %s\n", av_err2str(ret));
         exit(1);
     }
 
@@ -198,7 +201,7 @@
 
     ret = avcodec_encode_audio2(c, &pkt, frame, &got_packet);
     if (ret < 0) {
-        fprintf(stderr, "Error encoding audio frame\n");
+        fprintf(stderr, "Error encoding audio frame: %s\n", av_err2str(ret));
         exit(1);
     }
 
@@ -208,8 +211,10 @@
     pkt.stream_index = st->index;
 
     /* Write the compressed frame to the media file. */
-    if (av_interleaved_write_frame(oc, &pkt) != 0) {
-        fprintf(stderr, "Error while writing audio frame\n");
+    ret = av_interleaved_write_frame(oc, &pkt);
+    if (ret != 0) {
+        fprintf(stderr, "Error while writing audio frame: %s\n",
+                av_err2str(ret));
         exit(1);
     }
     avcodec_free_frame(&frame);
@@ -235,8 +240,9 @@
     AVCodecContext *c = st->codec;
 
     /* open the codec */
-    if (avcodec_open2(c, codec, NULL) < 0) {
-        fprintf(stderr, "Could not open video codec\n");
+    ret = avcodec_open2(c, codec, NULL);
+    if (ret < 0) {
+        fprintf(stderr, "Could not open video codec: %s\n", av_err2str(ret));
         exit(1);
     }
 
@@ -250,7 +256,7 @@
     /* Allocate the encoded raw picture. */
     ret = avpicture_alloc(&dst_picture, c->pix_fmt, c->width, c->height);
     if (ret < 0) {
-        fprintf(stderr, "Could not allocate picture\n");
+        fprintf(stderr, "Could not allocate picture: %s\n", av_err2str(ret));
         exit(1);
     }
 
@@ -260,7 +266,8 @@
     if (c->pix_fmt != AV_PIX_FMT_YUV420P) {
         ret = avpicture_alloc(&src_picture, AV_PIX_FMT_YUV420P, c->width, c->height);
         if (ret < 0) {
-            fprintf(stderr, "Could not allocate temporary picture\n");
+            fprintf(stderr, "Could not allocate temporary picture: %s\n",
+                    av_err2str(ret));
             exit(1);
         }
     }
@@ -346,7 +353,7 @@
 
         ret = avcodec_encode_video2(c, &pkt, frame, &got_output);
         if (ret < 0) {
-            fprintf(stderr, "Error encoding video frame\n");
+            fprintf(stderr, "Error encoding video frame: %s\n", av_err2str(ret));
             exit(1);
         }
 
@@ -364,7 +371,7 @@
         }
     }
     if (ret != 0) {
-        fprintf(stderr, "Error while writing video frame\n");
+        fprintf(stderr, "Error while writing video frame: %s\n", av_err2str(ret));
         exit(1);
     }
     frame_count++;
@@ -389,7 +396,7 @@
     AVStream *audio_st, *video_st;
     AVCodec *audio_codec, *video_codec;
     double audio_pts, video_pts;
-    int i;
+    int ret, i;
 
     /* Initialize libavcodec, and register all codecs and formats. */
     av_register_all();
@@ -441,15 +448,19 @@
 
     /* open the output file, if needed */
     if (!(fmt->flags & AVFMT_NOFILE)) {
-        if (avio_open(&oc->pb, filename, AVIO_FLAG_WRITE) < 0) {
-            fprintf(stderr, "Could not open '%s'\n", filename);
+        ret = avio_open(&oc->pb, filename, AVIO_FLAG_WRITE);
+        if (ret < 0) {
+            fprintf(stderr, "Could not open '%s': %s\n", filename,
+                    av_err2str(ret));
             return 1;
         }
     }
 
     /* Write the stream header, if any. */
-    if (avformat_write_header(oc, NULL) < 0) {
-        fprintf(stderr, "Error occurred when opening output file\n");
+    ret = avformat_write_header(oc, NULL);
+    if (ret < 0) {
+        fprintf(stderr, "Error occurred when opening output file: %s\n",
+                av_err2str(ret));
         return 1;
     }
 
diff --git a/doc/examples/resampling_audio.c b/doc/examples/resampling_audio.c
new file mode 100644
index 0000000..dd128e8
--- /dev/null
+++ b/doc/examples/resampling_audio.c
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2012 Stefano Sabatini
+ *
+ * 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.
+ */
+
+/**
+ * @example doc/examples/resampling_audio.c
+ * libswresample API use example.
+ */
+
+#include <libavutil/opt.h>
+#include <libavutil/channel_layout.h>
+#include <libavutil/samplefmt.h>
+#include <libswresample/swresample.h>
+
+static int get_format_from_sample_fmt(const char **fmt,
+                                      enum AVSampleFormat sample_fmt)
+{
+    int i;
+    struct sample_fmt_entry {
+        enum AVSampleFormat sample_fmt; const char *fmt_be, *fmt_le;
+    } sample_fmt_entries[] = {
+        { AV_SAMPLE_FMT_U8,  "u8",    "u8"    },
+        { AV_SAMPLE_FMT_S16, "s16be", "s16le" },
+        { AV_SAMPLE_FMT_S32, "s32be", "s32le" },
+        { AV_SAMPLE_FMT_FLT, "f32be", "f32le" },
+        { AV_SAMPLE_FMT_DBL, "f64be", "f64le" },
+    };
+    *fmt = NULL;
+
+    for (i = 0; i < FF_ARRAY_ELEMS(sample_fmt_entries); i++) {
+        struct sample_fmt_entry *entry = &sample_fmt_entries[i];
+        if (sample_fmt == entry->sample_fmt) {
+            *fmt = AV_NE(entry->fmt_be, entry->fmt_le);
+            return 0;
+        }
+    }
+
+    fprintf(stderr,
+            "Sample format %s not supported as output format\n",
+            av_get_sample_fmt_name(sample_fmt));
+    return AVERROR(EINVAL);
+}
+
+/**
+ * Fill dst buffer with nb_samples, generated starting from t.
+ */
+void fill_samples(double *dst, int nb_samples, int nb_channels, int sample_rate, double *t)
+{
+    int i, j;
+    double tincr = 1.0 / sample_rate, *dstp = dst;
+    const double c = 2 * M_PI * 440.0;
+
+    /* generate sin tone with 440Hz frequency and duplicated channels */
+    for (i = 0; i < nb_samples; i++) {
+        *dstp = sin(c * *t);
+        for (j = 1; j < nb_channels; j++)
+            dstp[j] = dstp[0];
+        dstp += nb_channels;
+        *t += tincr;
+    }
+}
+
+int alloc_samples_array_and_data(uint8_t ***data, int *linesize, int nb_channels,
+                                    int nb_samples, enum AVSampleFormat sample_fmt, int align)
+{
+    int nb_planes = av_sample_fmt_is_planar(sample_fmt) ? nb_channels : 1;
+
+    *data = av_malloc(sizeof(*data) * nb_planes);
+    if (!*data)
+        return AVERROR(ENOMEM);
+    return av_samples_alloc(*data, linesize, nb_channels,
+                            nb_samples, sample_fmt, align);
+}
+
+int main(int argc, char **argv)
+{
+    int64_t src_ch_layout = AV_CH_LAYOUT_STEREO, dst_ch_layout = AV_CH_LAYOUT_SURROUND;
+    int src_rate = 48000, dst_rate = 44100;
+    uint8_t **src_data = NULL, **dst_data = NULL;
+    int src_nb_channels = 0, dst_nb_channels = 0;
+    int src_linesize, dst_linesize;
+    int src_nb_samples = 1024, dst_nb_samples, max_dst_nb_samples;
+    enum AVSampleFormat src_sample_fmt = AV_SAMPLE_FMT_DBL, dst_sample_fmt = AV_SAMPLE_FMT_S16;
+    const char *dst_filename = NULL;
+    FILE *dst_file;
+    int dst_bufsize;
+    const char *fmt;
+    struct SwrContext *swr_ctx;
+    double t;
+    int ret;
+
+    if (argc != 2) {
+        fprintf(stderr, "Usage: %s output_file\n"
+                "API example program to show how to resample an audio stream with libswresample.\n"
+                "This program generates a series of audio frames, resamples them to a specified "
+                "output format and rate and saves them to an output file named output_file.\n",
+            argv[0]);
+        exit(1);
+    }
+    dst_filename = argv[1];
+
+    dst_file = fopen(dst_filename, "wb");
+    if (!dst_file) {
+        fprintf(stderr, "Could not open destination file %s\n", dst_filename);
+        exit(1);
+    }
+
+    /* create resampler context */
+    swr_ctx = swr_alloc();
+    if (!swr_ctx) {
+        fprintf(stderr, "Could not allocate resampler context\n");
+        ret = AVERROR(ENOMEM);
+        goto end;
+    }
+
+    /* set options */
+    av_opt_set_int(swr_ctx, "in_channel_layout",    src_ch_layout, 0);
+    av_opt_set_int(swr_ctx, "in_sample_rate",       src_rate, 0);
+    av_opt_set_sample_fmt(swr_ctx, "in_sample_fmt", src_sample_fmt, 0);
+
+    av_opt_set_int(swr_ctx, "out_channel_layout",    dst_ch_layout, 0);
+    av_opt_set_int(swr_ctx, "out_sample_rate",       dst_rate, 0);
+    av_opt_set_sample_fmt(swr_ctx, "out_sample_fmt", dst_sample_fmt, 0);
+
+    /* initialize the resampling context */
+    if ((ret = swr_init(swr_ctx)) < 0) {
+        fprintf(stderr, "Failed to initialize the resampling context\n");
+        goto end;
+    }
+
+    /* allocate source and destination samples buffers */
+
+    src_nb_channels = av_get_channel_layout_nb_channels(src_ch_layout);
+    ret = alloc_samples_array_and_data(&src_data, &src_linesize, src_nb_channels,
+                                       src_nb_samples, src_sample_fmt, 0);
+    if (ret < 0) {
+        fprintf(stderr, "Could not allocate source samples\n");
+        goto end;
+    }
+
+    /* 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 = dst_nb_samples =
+        av_rescale_rnd(src_nb_samples, dst_rate, src_rate, AV_ROUND_UP);
+
+    /* buffer is going to be directly written to a rawaudio file, no alignment */
+    dst_nb_channels = av_get_channel_layout_nb_channels(dst_ch_layout);
+    ret = alloc_samples_array_and_data(&dst_data, &dst_linesize, dst_nb_channels,
+                                       dst_nb_samples, dst_sample_fmt, 0);
+    if (ret < 0) {
+        fprintf(stderr, "Could not allocate destination samples\n");
+        goto end;
+    }
+
+    t = 0;
+    do {
+        /* generate synthetic audio */
+        fill_samples((double *)src_data[0], src_nb_samples, src_nb_channels, src_rate, &t);
+
+        /* compute destination number of samples */
+        dst_nb_samples = av_rescale_rnd(swr_get_delay(swr_ctx, src_rate) +
+                                        src_nb_samples, dst_rate, src_rate, AV_ROUND_UP);
+        if (dst_nb_samples > max_dst_nb_samples) {
+            av_free(dst_data[0]);
+            ret = av_samples_alloc(dst_data, &dst_linesize, dst_nb_channels,
+                                   dst_nb_samples, dst_sample_fmt, 1);
+            if (ret < 0)
+                break;
+            max_dst_nb_samples = dst_nb_samples;
+        }
+
+        /* convert to destination format */
+        ret = swr_convert(swr_ctx, dst_data, dst_nb_samples, (const uint8_t **)src_data, src_nb_samples);
+        if (ret < 0) {
+            fprintf(stderr, "Error while converting\n");
+            goto end;
+        }
+        dst_bufsize = av_samples_get_buffer_size(&dst_linesize, dst_nb_channels,
+                                                 ret, dst_sample_fmt, 1);
+        printf("t:%f in:%d out:%d\n", t, src_nb_samples, ret);
+        fwrite(dst_data[0], 1, dst_bufsize, dst_file);
+    } while (t < 10);
+
+    if ((ret = get_format_from_sample_fmt(&fmt, dst_sample_fmt)) < 0)
+        goto end;
+    fprintf(stderr, "Resampling succeeded. Play the output file with the command:\n"
+            "ffplay -f %s -channel_layout %"PRId64" -channels %d -ar %d %s\n",
+            fmt, dst_ch_layout, dst_nb_channels, dst_rate, dst_filename);
+
+end:
+    if (dst_file)
+        fclose(dst_file);
+
+    if (src_data)
+        av_freep(&src_data[0]);
+    av_freep(&src_data);
+
+    if (dst_data)
+        av_freep(&dst_data[0]);
+    av_freep(&dst_data);
+
+    swr_free(&swr_ctx);
+    return ret < 0;
+}
diff --git a/doc/examples/scaling_video.c b/doc/examples/scaling_video.c
index 320f4a0..be2c510 100644
--- a/doc/examples/scaling_video.c
+++ b/doc/examples/scaling_video.c
@@ -107,7 +107,7 @@
         goto end;
     }
 
-    /* buffer is going to be written to rawvideo file, no alignmnet */
+    /* buffer is going to be written to rawvideo file, no alignment */
     if ((ret = av_image_alloc(dst_data, dst_linesize,
                               dst_w, dst_h, dst_pix_fmt, 1)) < 0) {
         fprintf(stderr, "Could not allocate destination image\n");
diff --git a/doc/faq.texi b/doc/faq.texi
index a7b34b1..ebf21f5 100644
--- a/doc/faq.texi
+++ b/doc/faq.texi
@@ -110,7 +110,16 @@
 
 Notice that @samp{%d} is replaced by the image number.
 
-@file{img%03d.jpg} means the sequence @file{img001.jpg}, @file{img002.jpg}, etc...
+@file{img%03d.jpg} means the sequence @file{img001.jpg}, @file{img002.jpg}, etc.
+
+Use the @option{-start_number} option to declare a starting number for
+the sequence. This is useful if your sequence does not start with
+@file{img001.jpg} but is still in a numerical order. The following
+example will start with @file{img100.jpg}:
+
+@example
+  ffmpeg -f image2 -start_number 100 -i img%d.jpg /tmp/a.mpg
+@end example
 
 If you have large number of pictures to rename, you can use the
 following command to ease the burden. The command, using the bourne
@@ -133,6 +142,12 @@
 
 The same logic is used for any image format that ffmpeg reads.
 
+You can also use @command{cat} to pipe images to ffmpeg:
+
+@example
+  cat *.jpg | ffmpeg -f image2pipe -c:v mjpeg -i - output.mpg
+@end example
+
 @section How do I encode movie to single pictures?
 
 Use:
@@ -245,18 +260,18 @@
 For audio, to put all channels together in a single stream (example: two
 mono streams into one stereo stream): this is sometimes called to
 @emph{merge} them, and can be done using the
-@url{http://ffmpeg.org/ffmpeg.html#amerge, @code{amerge}} filter.
+@url{http://ffmpeg.org/ffmpeg-filters.html#amerge, @code{amerge}} filter.
 
 @item
 For audio, to play one on top of the other: this is called to @emph{mix}
 them, and can be done by first merging them into a single stream and then
-using the @url{http://ffmpeg.org/ffmpeg.html#pan, @code{pan}} filter to mix
+using the @url{http://ffmpeg.org/ffmpeg-filters.html#pan, @code{pan}} filter to mix
 the channels at will.
 
 @item
 For video, to display both together, side by side or one on top of a part of
 the other; it can be done using the
-@url{http://ffmpeg.org/ffmpeg.html#overlay, @code{overlay}} video filter.
+@url{http://ffmpeg.org/ffmpeg-filters.html#overlay, @code{overlay}} video filter.
 
 @end itemize
 
@@ -265,15 +280,26 @@
 
 There are several solutions, depending on the exact circumstances.
 
-@subsection Concatenating using filters
+@subsection Concatenating using the concat @emph{filter}
 
-FFmpeg has a @url{http://ffmpeg.org/ffmpeg.html#concat-1, @code{concat}}
-filter designed specifically for that, with examples in the documentation.
+FFmpeg has a @url{http://ffmpeg.org/ffmpeg-filters.html#concat,
+@code{concat}} filter designed specifically for that, with examples in the
+documentation. This operation is recommended if you need to re-encode.
 
-@subsection Concatenating at the file level
+@subsection Concatenating using the concat @emph{demuxer}
+
+FFmpeg has a @url{http://www.ffmpeg.org/ffmpeg-formats.html#concat,
+@code{concat}} demuxer which you can use when you want to avoid a re-encode and
+your format doesn't support file level concatenation.
+
+@subsection Concatenating using the concat @emph{protocol} (file level)
+
+FFmpeg has a @url{http://ffmpeg.org/ffmpeg-protocols.html#concat,
+@code{concat}} protocol designed specifically for that, with examples in the
+documentation.
 
 A few multimedia containers (MPEG-1, MPEG-2 PS, DV) allow to concatenate
-video by merely concatenating the files them.
+video by merely concatenating the files containing them.
 
 Hence you may concatenate your multimedia files by first transcoding them to
 these privileged formats, then using the humble @code{cat} command (or the
diff --git a/doc/ffmpeg-bitstream-filters.texi b/doc/ffmpeg-bitstream-filters.texi
index b1fdac2..e33e005 100644
--- a/doc/ffmpeg-bitstream-filters.texi
+++ b/doc/ffmpeg-bitstream-filters.texi
@@ -22,18 +22,23 @@
 
 @include bitstream_filters.texi
 
+@chapter See Also
+
+@ifhtml
+@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe}, @url{ffserver.html,ffserver},
+@url{libavcodec.html,libavcodec}
+@end ifhtml
+
+@ifnothtml
+ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1), libavcodec(3)
+@end ifnothtml
+
+@include authors.texi
+
 @ignore
 
 @setfilename ffmpeg-bitstream-filters
-@settitle FFmpeg bistream filters
-
-@c man begin SEEALSO
-ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1), libavcodec(3)
-@c man end
-
-@c man begin AUTHORS
-See Git history (git://source.ffmpeg.org/ffmpeg)
-@c man end
+@settitle FFmpeg bitstream filters
 
 @end ignore
 
diff --git a/doc/ffmpeg-codecs.texi b/doc/ffmpeg-codecs.texi
index ba31a21..db20aec 100644
--- a/doc/ffmpeg-codecs.texi
+++ b/doc/ffmpeg-codecs.texi
@@ -823,7 +823,7 @@
 @end table
 
 @item me_threshold @var{integer} (@emph{encoding,video})
-Set motion estimaton threshold.
+Set motion estimation threshold.
 
 @item mb_threshold @var{integer} (@emph{encoding,video})
 Set macroblock threshold.
@@ -1098,6 +1098,9 @@
 @code{none}.
 
 @item pkt_timebase @var{rational number}
+
+@item sub_charenc @var{encoding} (@emph{decoding,subtitles})
+Set the input subtitles character encoding.
 @end table
 
 @c man end CODEC OPTIONS
@@ -1105,19 +1108,24 @@
 @include decoders.texi
 @include encoders.texi
 
+@chapter See Also
+
+@ifhtml
+@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe}, @url{ffserver.html,ffserver},
+@url{libavcodec.html,libavcodec}
+@end ifhtml
+
+@ifnothtml
+ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1), libavcodec(3)
+@end ifnothtml
+
+@include authors.texi
+
 @ignore
 
 @setfilename ffmpeg-codecs
 @settitle FFmpeg codecs
 
-@c man begin SEEALSO
-ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1), libavcodec(3)
-@c man end
-
-@c man begin AUTHORS
-See Git history (git://source.ffmpeg.org/ffmpeg)
-@c man end
-
 @end ignore
 
 @bye
diff --git a/doc/ffmpeg-devices.texi b/doc/ffmpeg-devices.texi
index 542dae8..9e004d5 100644
--- a/doc/ffmpeg-devices.texi
+++ b/doc/ffmpeg-devices.texi
@@ -23,8 +23,8 @@
 The libavdevice library provides the same interface as
 libavformat. Namely, an input device is considered like a demuxer, and
 an output device like a muxer, and the interface and generic device
-options are the same provided by libavformat (see the @ref{FFmpeg
-formats} manual page).
+options are the same provided by libavformat (see the ffmpeg-formats
+manual).
 
 In addition each input or output device may support so-called private
 options, which are specific for that component.
@@ -39,19 +39,24 @@
 @include indevs.texi
 @include outdevs.texi
 
+@chapter See Also
+
+@ifhtml
+@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe}, @url{ffserver.html,ffserver},
+@url{libavdevice.html,libavdevice}
+@end ifhtml
+
+@ifnothtml
+ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1), libavdevice(3)
+@end ifnothtml
+
+@include authors.texi
+
 @ignore
 
 @setfilename ffmpeg-devices
 @settitle FFmpeg devices
 
-@c man begin SEEALSO
-ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1), libavformat(3), libavdevice(3)
-@c man end
-
-@c man begin AUTHORS
-See Git history (git://source.ffmpeg.org/ffmpeg)
-@c man end
-
 @end ignore
 
 @bye
diff --git a/doc/ffmpeg-filters.texi b/doc/ffmpeg-filters.texi
index f272bb4..bb920ce 100644
--- a/doc/ffmpeg-filters.texi
+++ b/doc/ffmpeg-filters.texi
@@ -19,19 +19,24 @@
 
 @include filters.texi
 
+@chapter See Also
+
+@ifhtml
+@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe}, @url{ffserver.html,ffserver},
+@url{libavfilter.html,libavfilter}
+@end ifhtml
+
+@ifnothtml
+ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1), libavfilter(3)
+@end ifnothtml
+
+@include authors.texi
+
 @ignore
 
 @setfilename ffmpeg-filters
 @settitle FFmpeg filters
 
-@c man begin SEEALSO
-ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1), libavfilter(3)
-@c man end
-
-@c man begin AUTHORS
-See Git history (git://source.ffmpeg.org/ffmpeg)
-@c man end
-
 @end ignore
 
 @bye
diff --git a/doc/ffmpeg-formats.texi b/doc/ffmpeg-formats.texi
index d7f0192..30cf415 100644
--- a/doc/ffmpeg-formats.texi
+++ b/doc/ffmpeg-formats.texi
@@ -41,7 +41,10 @@
 @end table
 
 @item probesize @var{integer} (@emph{input})
-Set probing size.
+Set probing size in bytes, i.e. the size of the data to analyze to get
+stream information. A higher value will allow to detect more
+information in case it is dispersed into the stream, but will increase
+latency. Must be an integer not lesser than 32. It is 5000000 by default.
 
 @item packetsize @var{integer} (@emph{output})
 Set packet size.
@@ -74,7 +77,9 @@
 @end table
 
 @item analyzeduration @var{integer} (@emph{input})
-Specify how many microseconds are analyzed to estimate duration.
+Specify how many microseconds are analyzed to probe the input. A
+higher value will allow to detect more accurate information, but will
+increase latency. It defaults to 5,000,000 microseconds = 5 seconds.
 
 @item cryptokey @var{hexadecimal string} (@emph{input})
 Set decryption key.
@@ -135,27 +140,34 @@
 Use wallclock as timestamps.
 
 @item avoid_negative_ts @var{integer} (@emph{output})
-Avoid negative timestamps.
+Shift timestamps to make them positive. 1 enables, 0 disables, default
+of -1 enables when required by target format.
 @end table
 
 @c man end FORMAT OPTIONS
 
 @include demuxers.texi
 @include muxers.texi
+@include metadata.texi
+
+@chapter See Also
+
+@ifhtml
+@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe}, @url{ffserver.html,ffserver},
+@url{libavformat.html,libavformat}
+@end ifhtml
+
+@ifnothtml
+ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1), libavformat(3)
+@end ifnothtml
+
+@include authors.texi
 
 @ignore
 
 @setfilename ffmpeg-formats
 @settitle FFmpeg formats
 
-@c man begin SEEALSO
-ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1), libavformat(3)
-@c man end
-
-@c man begin AUTHORS
-See Git history (git://source.ffmpeg.org/ffmpeg)
-@c man end
-
 @end ignore
 
 @bye
diff --git a/doc/ffmpeg-protocols.texi b/doc/ffmpeg-protocols.texi
index 0bb89a0..d992e75 100644
--- a/doc/ffmpeg-protocols.texi
+++ b/doc/ffmpeg-protocols.texi
@@ -19,19 +19,24 @@
 
 @include protocols.texi
 
+@chapter See Also
+
+@ifhtml
+@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe}, @url{ffserver.html,ffserver},
+@url{libavformat.html,libavformat}
+@end ifhtml
+
+@ifnothtml
+ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1), libavformat(3)
+@end ifnothtml
+
+@include authors.texi
+
 @ignore
 
 @setfilename ffmpeg-protocols
 @settitle FFmpeg protocols
 
-@c man begin SEEALSO
-ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1), libavformat(3)
-@c man end
-
-@c man begin AUTHORS
-See Git history (git://source.ffmpeg.org/ffmpeg)
-@c man end
-
 @end ignore
 
 @bye
diff --git a/doc/ffmpeg-resampler.texi b/doc/ffmpeg-resampler.texi
index 3558772..525907a 100644
--- a/doc/ffmpeg-resampler.texi
+++ b/doc/ffmpeg-resampler.texi
@@ -25,7 +25,8 @@
 The audio resampler supports the following named options.
 
 Options may be set by specifying -@var{option} @var{value} in the
-FFmpeg tools, or by setting the value explicitly in the
+FFmpeg tools, @var{option}=@var{value} for the aresample filter,
+by setting the value explicitly in the
 @code{SwrContext} options or using the @file{libavutil/opt.h} API for
 programmatic use.
 
@@ -42,7 +43,7 @@
 @option{out_channel_layout} is set.
 
 @item uch, used_channel_count
-Set the number of used channels. Default value is 0. This option is
+Set the number of used input channels. Default value is 0. This option is
 only used for special remapping.
 
 @item isr, in_sample_rate
@@ -59,6 +60,7 @@
 
 @item tsf, internal_sample_fmt
 Set the internal sample format. Default value is @code{none}.
+This will automatically be chosen when it is not explicitly set.
 
 @item icl, in_channel_layout
 Set the input channel layout.
@@ -67,15 +69,17 @@
 Set the output channel layout.
 
 @item clev, center_mix_level
-Set center mix level. It is a value expressed in deciBel, and must be
-inclusively included between -32 and +32.
+Set the center mix level. It is a value expressed in deciBel, and must be
+in the interval [-32,32].
 
 @item slev, surround_mix_level
-Set surround mix level. It is a value expressed in deciBel, and must
-be inclusively included between -32 and +32.
+Set the surround mix level. It is a value expressed in deciBel, and must
+be in the interval [-32,32].
 
-@item lfe_mix_evel
-Set LFE mix level.
+@item lfe_mix_level
+Set LFE mix into non LFE level. It is used when there is a LFE input but no
+LFE output. It is a value expressed in deciBel, and must
+be in the interval [-32,32].
 
 @item rmvol, rematrix_volume
 Set rematrix volume. Default value is 1.0.
@@ -86,7 +90,8 @@
 It supports the following individual flags:
 @table @option
 @item res
-force resampling
+force resampling, this flag forces resampling to be used even when the
+input and output sample rates match.
 @end table
 
 @item dither_scale
@@ -103,41 +108,102 @@
 select triangular dither
 @item triangular_hp
 select triangular dither with high pass
+@item lipshitz
+select lipshitz noise shaping dither
+@item shibata
+select shibata noise shaping dither
+@item low_shibata
+select low shibata noise shaping dither
+@item high_shibata
+select high shibata noise shaping dither
+@item f_weighted
+select f-weighted noise shaping dither
+@item modified_e_weighted
+select modified-e-weighted noise shaping dither
+@item improved_e_weighted
+select improved-e-weighted noise shaping dither
+
+@end table
+
+@item resampler
+Set resampling engine. Default value is swr.
+
+Supported values:
+@table @samp
+@item swr
+select the native SW Resampler; filter options precision and cheby are not
+applicable in this case.
+@item soxr
+select the SoX Resampler (where available); compensation, and filter options
+filter_size, phase_shift, filter_type & kaiser_beta, are not applicable in this
+case.
 @end table
 
 @item filter_size
-Set resampling filter size, default value is 16.
+For swr only, set resampling filter size, default value is 32.
 
 @item phase_shift
-Set resampling phase shift, default value is 10, must be included
-between 0 and 30.
+For swr only, set resampling phase shift, default value is 10, and must be in
+the interval [0,30].
 
 @item linear_interp
 Use Linear Interpolation if set to 1, default value is 0.
 
 @item cutoff
-Set cutoff frequency ratio. Must be a float value between 0 and 1,
-default value is 0.8.
+Set cutoff frequency (swr: 6dB point; soxr: 0dB point) ratio; must be a float
+value between 0 and 1.  Default value is 0.97 with swr, and 0.91 with soxr
+(which, with a sample-rate of 44100, preserves the entire audio band to 20kHz).
+
+@item precision
+For soxr only, the precision in bits to which the resampled signal will be
+calculated.  The default value of 20 (which, with suitable dithering, is
+appropriate for a destination bit-depth of 16) gives SoX's 'High Quality'; a
+value of 28 gives SoX's 'Very High Quality'.
+
+@item cheby
+For soxr only, selects passband rolloff none (Chebyshev) & higher-precision
+approximation for 'irrational' ratios. Default value is 0.
+
+@item async
+For swr only, simple 1 parameter audio sync to timestamps using stretching,
+squeezing, filling and trimming. Setting this to 1 will enable filling and
+trimming, larger values represent the maximum amount in samples that the data
+may be stretched or squeezed for each second.
+Default value is 0, thus no compensation is applied to make the samples match
+the audio timestamps.
+
+@item first_pts
+For swr only, assume the first pts should be this value. The time unit 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 min_comp
-Set minimum difference between timestamps and audio data (in seconds)
-below which no timestamp compensation of either kind is applied.
-Default value is @code{FLT_MAX}.
+For swr only, set the minimum difference between timestamps and audio data (in
+seconds) to trigger stretching/squeezing/filling or trimming of the
+data to make it match the timestamps. The default is that
+stretching/squeezing/filling and trimming is disabled
+(@option{min_comp} = @code{FLT_MAX}).
 
 @item min_hard_comp
-Set minimum difference between timestamps and audio data (in seconds)
-to trigger padding/trimming the data. Must be a non-negative double,
-default value is 0.1.
+For swr only, set the minimum difference between timestamps and audio data (in
+seconds) to trigger adding/dropping samples to make it match the
+timestamps.  This option effectively is a threshold to select between
+hard (trim/fill) and soft (squeeze/stretch) compensation. Note that
+all compensation is by default disabled through @option{min_comp}.
+The default is 0.1.
 
 @item comp_duration
-Set duration (in seconds) over which data is stretched/squeezed to
-make it match the timestamps. Must be a non-negative double float
-value, default value is 1.0.
+For swr only, set duration (in seconds) over which data is stretched/squeezed
+to make it match the timestamps. Must be a non-negative double float value,
+default value is 1.0.
 
 @item max_soft_comp
-Set maximum factor by which data is stretched/squeezed to make it
-match the timestamps. Must be a non-negative double float value,
-default value is 0.
+For swr only, set maximum factor by which data is stretched/squeezed to make it
+match the timestamps. Must be a non-negative double float value, default value
+is 0.
 
 @item matrix_encoding
 Select matrixed stereo encoding.
@@ -155,7 +221,7 @@
 Default value is @code{none}.
 
 @item filter_type
-Select resampling filter type. This only affects resampling
+For swr only, select resampling filter type. This only affects resampling
 operations.
 
 It accepts the following values:
@@ -169,24 +235,31 @@
 @end table
 
 @item kaiser_beta
-Set Kaiser Window Beta value. Must be an integer included between 2
-and 16, default value is 9.
+For swr only, set Kaiser Window Beta value. Must be an integer in the
+interval [2,16], default value is 9.
 
 @end table
 
 @c man end RESAMPLER OPTIONS
 
+@chapter See Also
+
+@ifhtml
+@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe}, @url{ffserver.html,ffserver},
+@url{libswresample.html,libswresample}
+@end ifhtml
+
+@ifnothtml
+ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1), libswresample(3)
+@end ifnothtml
+
+@include authors.texi
+
 @ignore
 
 @setfilename ffmpeg-resampler
 @settitle FFmpeg Resampler
 
-@c man begin SEEALSO
-ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1), libswresample(3)
-@c man end
-
-@c man begin AUTHORS
-See Git history (git://source.ffmpeg.org/ffmpeg)
-@c man end
-
 @end ignore
+
+@bye
diff --git a/doc/ffmpeg-scaler.texi b/doc/ffmpeg-scaler.texi
index 2d1bc95..1110c69 100644
--- a/doc/ffmpeg-scaler.texi
+++ b/doc/ffmpeg-scaler.texi
@@ -118,19 +118,24 @@
 
 @c man end SCALER OPTIONS
 
+@chapter See Also
+
+@ifhtml
+@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe}, @url{ffserver.html,ffserver},
+@url{libswscale.html,libswscale}
+@end ifhtml
+
+@ifnothtml
+ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1), libswscale(3)
+@end ifnothtml
+
+@include authors.texi
+
 @ignore
 
 @setfilename ffmpeg-scaler
 @settitle FFmpeg video scaling and pixel format converter
 
-@c man begin SEEALSO
-ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1), libswscale(3)
-@c man end
-
-@c man begin AUTHORS
-See Git history (git://source.ffmpeg.org/ffmpeg)
-@c man end
-
 @end ignore
 
 @bye
diff --git a/doc/ffmpeg-utils.texi b/doc/ffmpeg-utils.texi
index 5d51fc8..c5822a8 100644
--- a/doc/ffmpeg-utils.texi
+++ b/doc/ffmpeg-utils.texi
@@ -20,19 +20,24 @@
 @include syntax.texi
 @include eval.texi
 
+@chapter See Also
+
+@ifhtml
+@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe}, @url{ffserver.html,ffserver},
+@url{libavutil.html,libavutil}
+@end ifhtml
+
+@ifnothtml
+ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1), libavutil(3)
+@end ifnothtml
+
+@include authors.texi
+
 @ignore
 
 @setfilename ffmpeg-utils
 @settitle FFmpeg utilities
 
-@c man begin SEEALSO
-ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1), libavutil(3)
-@c man end
-
-@c man begin AUTHORS
-See Git history (git://source.ffmpeg.org/ffmpeg)
-@c man end
-
 @end ignore
 
 @bye
diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi
index d39ad22..7563107 100644
--- a/doc/ffmpeg.texi
+++ b/doc/ffmpeg.texi
@@ -11,13 +11,7 @@
 
 @chapter Synopsis
 
-The generic syntax is:
-
-@example
-@c man begin SYNOPSIS
-ffmpeg [global options] [[infile options][@option{-i} @var{infile}]]... @{[outfile options] @var{outfile}@}...
-@c man end
-@end example
+ffmpeg [@var{global_options}] @{[@var{input_file_options}] -i @file{input_file}@} ... @{[@var{output_file_options}] @file{output_file}@} ...
 
 @chapter Description
 @c man begin DESCRIPTION
@@ -262,6 +256,14 @@
 Stop writing the output after its duration reaches @var{duration}.
 @var{duration} may be a number in seconds, or in @code{hh:mm:ss[.xxx]} form.
 
+-to and -t are mutually exclusive and -t has priority.
+
+@item -to @var{position} (@emph{output})
+Stop writing the output at @var{position}.
+@var{position} may be a number in seconds, or in @code{hh:mm:ss[.xxx]} form.
+
+-to and -t are mutually exclusive and -t has priority.
+
 @item -fs @var{limit_size} (@emph{output})
 Set the file size limit, expressed in bytes.
 
@@ -340,13 +342,21 @@
 Use fixed quality scale (VBR). The meaning of @var{q} is
 codec-dependent.
 
+@anchor{filter_option}
 @item -filter[:@var{stream_specifier}] @var{filter_graph} (@emph{output,per-stream})
-@var{filter_graph} is a description of the filter graph to apply to
-the stream. Use @code{-filters} to show all the available filters
-(including also sources and sinks).
+Create the filter graph specified by @var{filter_graph} and use it to
+filter the stream.
 
-See also the @option{-filter_complex} option if you want to create filter graphs
-with multiple inputs and/or outputs.
+@var{filter_graph} is a description of the filter graph to apply to
+the stream, and must have a single input and a single output of the
+same type of the stream. In the filter graph, the input is associated
+to the label @code{in}, and the output to the label @code{out}. See
+the ffmpeg-filters manual for more information about the filtergraph
+syntax.
+
+See the @ref{filter_complex_option,,-filter_complex option} if you
+want to create filter graphs with multiple inputs and/or outputs.
+
 @item -pre[:@var{stream_specifier}] @var{preset_name} (@emph{output,per-stream})
 Specify the preset for matching stream(s).
 
@@ -401,11 +411,11 @@
 
 E.g. to extract the first attachment to a file named 'out.ttf':
 @example
-ffmpeg -dump_attachment:t:0 out.ttf INPUT
+ffmpeg -dump_attachment:t:0 out.ttf -i INPUT
 @end example
 To extract all attachments to files determined by the @code{filename} tag:
 @example
-ffmpeg -dump_attachment:t "" INPUT
+ffmpeg -dump_attachment:t "" -i INPUT
 @end example
 
 Technical note -- attachments are implemented as codec extradata, so this
@@ -426,8 +436,7 @@
 generate timestamps assuming constant frame rate @var{fps}.
 
 As an output option, duplicate or drop input frames to achieve constant output
-frame rate @var{fps} (note that this actually causes the @code{fps} filter to be
-inserted to the end of the corresponding filtergraph).
+frame rate @var{fps}.
 
 @item -s[:@var{stream_specifier}] @var{size} (@emph{input/output,per-stream})
 Set frame size.
@@ -450,21 +459,6 @@
 numerator and denominator of the aspect ratio. For example "4:3",
 "16:9", "1.3333", and "1.7777" are valid argument values.
 
-@item -croptop @var{size}
-@item -cropbottom @var{size}
-@item -cropleft @var{size}
-@item -cropright @var{size}
-All the crop options have been removed. Use -vf
-crop=width:height:x:y instead.
-
-@item -padtop @var{size}
-@item -padbottom @var{size}
-@item -padleft @var{size}
-@item -padright @var{size}
-@item -padcolor @var{hex_color}
-All the pad options have been removed. Use -vf
-pad=width:height:x:y:color instead.
-
 @item -vn (@emph{output})
 Disable video recording.
 
@@ -494,11 +488,10 @@
 Set the ISO 639 language code (3 letters) of the current video stream.
 
 @item -vf @var{filter_graph} (@emph{output})
-@var{filter_graph} is a description of the filter graph to apply to
-the input video.
-Use the option "-filters" to show all the available filters (including
-also sources and sinks).  This is an alias for @code{-filter:v}.
+Create the filter graph specified by @var{filter_graph} and use it to
+filter the stream.
 
+This is an alias for @code{-filter:v}, see the @ref{filter_option,,-filter option}.
 @end table
 
 @section Advanced Video Options
@@ -552,12 +545,58 @@
 Show QP histogram
 @item -vbsf @var{bitstream_filter}
 Deprecated see -bsf
+
 @item -force_key_frames[:@var{stream_specifier}] @var{time}[,@var{time}...] (@emph{output,per-stream})
+@item -force_key_frames[:@var{stream_specifier}] expr:@var{expr} (@emph{output,per-stream})
 Force key frames at the specified timestamps, more precisely at the first
 frames after each specified time.
+
+If the argument is prefixed with @code{expr:}, the string @var{expr}
+is interpreted like an expression and is evaluated for each frame. A
+key frame is forced in case the evaluation is non-zero.
+
+If one of the times is "@code{chapters}[@var{delta}]", it is expanded into
+the time of the beginning of all chapters in the file, shifted by
+@var{delta}, expressed as a time in seconds.
 This option can be useful to ensure that a seek point is present at a
 chapter mark or any other designated place in the output file.
-The timestamps must be specified in ascending order.
+
+For example, to insert a key frame at 5 minutes, plus key frames 0.1 second
+before the beginning of every chapter:
+@example
+-force_key_frames 0:05:00,chapters-0.1
+@end example
+
+The expression in @var{expr} can contain the following constants:
+@table @option
+@item n
+the number of current processed frame, starting from 0
+@item n_forced
+the number of forced frames
+@item prev_forced_n
+the number of the previous forced frame, it is @code{NAN} when no
+keyframe was forced yet
+@item prev_forced_t
+the time of the previous forced frame, it is @code{NAN} when no
+keyframe was forced yet
+@item t
+the time of the current processed frame
+@end table
+
+For example to force a key frame every 5 seconds, you can specify:
+@example
+-force_key_frames expr:gte(t,n_forced*5)
+@end example
+
+To force a key frame 5 seconds after the time of the last forced one,
+starting from second 13:
+@example
+-force_key_frames expr:if(isnan(prev_forced_t),gte(t,13),gte(t,prev_forced_t+5))
+@end example
+
+Note that forcing too many keyframes is very harmful for the lookahead
+algorithms of certain encoders: using fixed-GOP options or similar
+would be more efficient.
 
 @item -copyinkf[:@var{stream_specifier}] (@emph{output,per-stream})
 When doing stream copy, copy also non-key frames found at the
@@ -588,11 +627,12 @@
 @item -sample_fmt[:@var{stream_specifier}] @var{sample_fmt} (@emph{output,per-stream})
 Set the audio sample format. Use @code{-sample_fmts} to get a list
 of supported sample formats.
+
 @item -af @var{filter_graph} (@emph{output})
-@var{filter_graph} is a description of the filter graph to apply to
-the input audio.
-Use the option "-filters" to show all the available filters (including
-also sources and sinks).  This is an alias for @code{-filter:a}.
+Create the filter graph specified by @var{filter_graph} and use it to
+filter the stream.
+
+This is an alias for @code{-filter:a}, see the @ref{filter_option,,-filter option}.
 @end table
 
 @section Advanced Audio options:
@@ -602,6 +642,12 @@
 Force audio tag/fourcc. This is an alias for @code{-tag:a}.
 @item -absf @var{bitstream_filter}
 Deprecated, see -bsf
+@item -guess_layout_max @var{channels} (@emph{input,per-stream})
+If some input channel layout is not known, try to guess only if it
+corresponds to at most the specified number of channels. For example, 2
+tells to @command{ffmpeg} to recognize 1 channel as mono and 2 channels as
+stereo but not 6 channels as 5.1. The default is to always try to guess. Use
+0 to disable all guessing.
 @end table
 
 @section Subtitle options:
@@ -859,9 +905,17 @@
 the parameter is the maximum samples per second by which the audio is changed.
 -async 1 is a special case where only the start of the audio stream is corrected
 without any later correction.
-This option has been deprecated. Use the @code{asyncts} audio filter instead.
+This option has been deprecated. Use the @code{aresample} audio filter instead.
+
 @item -copyts
-Copy timestamps from input to output.
+Do not process input timestamps, but keep their values without trying
+to sanitize them. In particular, do not remove the initial start time
+offset value.
+
+Note that, depending on the @option{vsync} option or on specific muxer
+processing, the output timestamps may mismatch with the input
+timestamps even when this option is selected.
+
 @item -copytb @var{mode}
 Specify how to set the encoder timebase when stream copying.  @var{mode} is an
 integer numeric value, and can assume one of the following values:
@@ -907,7 +961,7 @@
 @end example
 
 @item -bsf[:@var{stream_specifier}] @var{bitstream_filters} (@emph{output,per-stream})
-Set bitstream filters for matching streams. @var{bistream_filters} is
+Set bitstream filters for matching streams. @var{bitstream_filters} is
 a comma-separated list of bitstream filters. Use the @code{-bsfs} option
 to get the list of bitstream filters.
 @example
@@ -927,11 +981,13 @@
 ffmpeg -i input.mpg -timecode 01:02:03.04 -r 30000/1001 -s ntsc output.mpg
 @end example
 
+@anchor{filter_complex_option}
 @item -filter_complex @var{filtergraph} (@emph{global})
 Define a complex filter graph, i.e. one with arbitrary number of inputs and/or
 outputs. For simple graphs -- those with one input and one output of the same
 type -- see the @option{-filter} options. @var{filtergraph} is a description of
-the filter graph, as described in @ref{Filtergraph syntax}.
+the filter graph, as described in the ``Filtergraph syntax'' section of the
+ffmpeg-filters manual.
 
 Input link labels must refer to input streams using the
 @code{[file_index:stream_specifier]} syntax (i.e. the same as @option{-map}
@@ -970,13 +1026,13 @@
 
 To generate 5 seconds of pure red video using lavfi @code{color} source:
 @example
-ffmpeg -filter_complex 'color=red' -t 5 out.mkv
+ffmpeg -filter_complex 'color=c=red' -t 5 out.mkv
 @end example
 @end table
 
 As a special exception, you can use a bitmap subtitle stream as input: it
 will be converted into a video with the same size as the largest video in
-the file, or 720×576 if no video is present. Note that this is an
+the file, or 720x576 if no video is present. Note that this is an
 experimental and temporary solution. It will be removed once libavfilter has
 proper support for subtitles.
 
@@ -1252,7 +1308,7 @@
 You can put many streams of the same type in the output:
 
 @example
-ffmpeg -i test1.avi -i test2.avi -map 0.3 -map 0.2 -map 0.1 -map 0.0 -c copy test12.nut
+ffmpeg -i test1.avi -i test2.avi -map 0:3 -map 0:2 -map 0:1 -map 0:0 -c copy test12.nut
 @end example
 
 The resulting output file @file{test12.avi} will contain first four streams from
@@ -1274,32 +1330,35 @@
 @end itemize
 @c man end EXAMPLES
 
-@include syntax.texi
-@include eval.texi
-@include decoders.texi
-@include encoders.texi
-@include demuxers.texi
-@include muxers.texi
-@include indevs.texi
-@include outdevs.texi
-@include protocols.texi
-@include bitstream_filters.texi
-@include filters.texi
-@include metadata.texi
+@chapter See Also
+
+@ifhtml
+@url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe}, @url{ffserver.html,ffserver},
+@url{ffmpeg-utils.html,ffmpeg-utils},
+@url{ffmpeg-scaler.html,ffmpeg-scaler},
+@url{ffmpeg-resampler.html,ffmpeg-resampler},
+@url{ffmpeg-codecs.html,ffmpeg-codecs},
+@url{ffmpeg-bitstream-filters.html,ffmpeg-bitstream-filters},
+@url{ffmpeg-formats.html,ffmpeg-formats},
+@url{ffmpeg-devices.html,ffmpeg-devices},
+@url{ffmpeg-protocols.html,ffmpeg-protocols},
+@url{ffmpeg-filters.html,ffmpeg-filters}
+@end ifhtml
+
+@ifnothtml
+ffplay(1), ffprobe(1), ffserver(1),
+ffmpeg-utils(1), ffmpeg-scaler(1), ffmpeg-resampler(1),
+ffmpeg-codecs(1), ffmpeg-bitstream-filters(1), ffmpeg-formats(1),
+ffmpeg-devices(1), ffmpeg-protocols(1), ffmpeg-filters(1)
+@end ifnothtml
+
+@include authors.texi
 
 @ignore
 
 @setfilename ffmpeg
 @settitle ffmpeg video converter
 
-@c man begin SEEALSO
-ffplay(1), ffprobe(1), ffserver(1) and the FFmpeg HTML documentation
-@c man end
-
-@c man begin AUTHORS
-See git history
-@c man end
-
 @end ignore
 
 @bye
diff --git a/doc/ffplay.texi b/doc/ffplay.texi
index e2bded7..8d6abee 100644
--- a/doc/ffplay.texi
+++ b/doc/ffplay.texi
@@ -11,11 +11,7 @@
 
 @chapter Synopsis
 
-@example
-@c man begin SYNOPSIS
-ffplay [options] [@file{input_file}]
-@c man end
-@end example
+ffplay [@var{options}] [@file{input_file}]
 
 @chapter Description
 @c man begin DESCRIPTION
@@ -78,10 +74,15 @@
 pressing the key @key{w}.
 
 @item -vf @var{filter_graph}
+Create the filter graph specified by @var{filter_graph} and use it to
+filter the video stream.
+
 @var{filter_graph} is a description of the filter graph to apply to
-the input video.
-Use the option "-filters" to show all the available filters (including
-also sources and sinks).
+the stream, and must have a single video input and a single video
+output. In the filter graph, the input is associated to the label
+@code{in}, and the output to the label @code{out}. See the
+ffmpeg-filters manual for more information about the filtergraph
+syntax.
 
 @item -i @var{input_file}
 Read @var{input_file}.
@@ -134,8 +135,20 @@
 Exit if any key is pressed.
 @item -exitonmousedown
 Exit if any mouse button is pressed.
-@item -codec:@var{stream_type}
-Force a specific decoder implementation
+
+@item -codec:@var{media_specifier} @var{codec_name}
+Force a specific decoder implementation for the stream identified by
+@var{media_specifier}, which can assume the values @code{a} (audio),
+@code{v} (video), and @code{s} subtitle.
+
+@item -acodec @var{codec_name}
+Force a specific audio decoder.
+
+@item -vcodec @var{codec_name}
+Force a specific video decoder.
+
+@item -scodec @var{codec_name}
+Force a specific subtitle decoder.
 @end table
 
 @section While playing
@@ -178,29 +191,35 @@
 
 @c man end
 
-@include syntax.texi
-@include eval.texi
-@include decoders.texi
-@include demuxers.texi
-@include muxers.texi
-@include indevs.texi
-@include outdevs.texi
-@include protocols.texi
-@include filters.texi
+@chapter See Also
+
+@ifhtml
+@url{ffmpeg.html,ffmpeg}, @url{ffprobe.html,ffprobe}, @url{ffserver.html,ffserver},
+@url{ffmpeg-utils.html,ffmpeg-utils},
+@url{ffmpeg-scaler.html,ffmpeg-scaler},
+@url{ffmpeg-resampler.html,ffmpeg-resampler},
+@url{ffmpeg-codecs.html,ffmpeg-codecs},
+@url{ffmpeg-bitstream-filters.html,ffmpeg-bitstream-filters},
+@url{ffmpeg-formats.html,ffmpeg-formats},
+@url{ffmpeg-devices.html,ffmpeg-devices},
+@url{ffmpeg-protocols.html,ffmpeg-protocols},
+@url{ffmpeg-filters.html,ffmpeg-filters}
+@end ifhtml
+
+@ifnothtml
+ffmpeg(1), ffprobe(1), ffserver(1),
+ffmpeg-utils(1), ffmpeg-scaler(1), ffmpeg-resampler(1),
+ffmpeg-codecs(1), ffmpeg-bitstream-filters(1), ffmpeg-formats(1),
+ffmpeg-devices(1), ffmpeg-protocols(1), ffmpeg-filters(1)
+@end ifnothtml
+
+@include authors.texi
 
 @ignore
 
 @setfilename ffplay
 @settitle FFplay media player
 
-@c man begin SEEALSO
-ffmpeg(1), ffprobe(1), ffserver(1) and the FFmpeg HTML documentation
-@c man end
-
-@c man begin AUTHORS
-The FFmpeg developers
-@c man end
-
 @end ignore
 
 @bye
diff --git a/doc/ffprobe.texi b/doc/ffprobe.texi
index 08aef13..6e30b2f 100644
--- a/doc/ffprobe.texi
+++ b/doc/ffprobe.texi
@@ -11,13 +11,7 @@
 
 @chapter Synopsis
 
-The generic syntax is:
-
-@example
-@c man begin SYNOPSIS
-ffprobe [options] [@file{input_file}]
-@c man end
-@end example
+ffprobe [@var{options}] [@file{input_file}]
 
 @chapter Description
 @c man begin DESCRIPTION
@@ -493,25 +487,35 @@
 @end itemize
 @c man end TIMECODE
 
-@include syntax.texi
-@include decoders.texi
-@include demuxers.texi
-@include protocols.texi
-@include indevs.texi
+@chapter See Also
+
+@ifhtml
+@url{ffplay.html,ffmpeg}, @url{ffprobe.html,ffprobe}, @url{ffserver.html,ffserver},
+@url{ffmpeg-utils.html,ffmpeg-utils},
+@url{ffmpeg-scaler.html,ffmpeg-scaler},
+@url{ffmpeg-resampler.html,ffmpeg-resampler},
+@url{ffmpeg-codecs.html,ffmpeg-codecs},
+@url{ffmpeg-bitstream-filters.html,ffmpeg-bitstream-filters},
+@url{ffmpeg-formats.html,ffmpeg-formats},
+@url{ffmpeg-devices.html,ffmpeg-devices},
+@url{ffmpeg-protocols.html,ffmpeg-protocols},
+@url{ffmpeg-filters.html,ffmpeg-filters}
+@end ifhtml
+
+@ifnothtml
+ffmpeg(1), ffplay(1), ffserver(1),
+ffmpeg-utils(1), ffmpeg-scaler(1), ffmpeg-resampler(1),
+ffmpeg-codecs(1), ffmpeg-bitstream-filters(1), ffmpeg-formats(1),
+ffmpeg-devices(1), ffmpeg-protocols(1), ffmpeg-filters(1)
+@end ifnothtml
+
+@include authors.texi
 
 @ignore
 
 @setfilename ffprobe
 @settitle ffprobe media prober
 
-@c man begin SEEALSO
-ffmpeg(1), ffplay(1), ffserver(1) and the FFmpeg HTML documentation
-@c man end
-
-@c man begin AUTHORS
-The FFmpeg developers
-@c man end
-
 @end ignore
 
 @bye
diff --git a/doc/ffprobe.xsd b/doc/ffprobe.xsd
index d9c9392..d9c6655 100644
--- a/doc/ffprobe.xsd
+++ b/doc/ffprobe.xsd
@@ -59,6 +59,7 @@
       <xsd:attribute name="pkt_duration"  type="xsd:long" />
       <xsd:attribute name="pkt_duration_time" type="xsd:float"/>
       <xsd:attribute name="pkt_pos"       type="xsd:long" />
+      <xsd:attribute name="pkt_size"      type="xsd:int" />
 
       <!-- audio attributes -->
       <xsd:attribute name="sample_fmt"             type="xsd:string"/>
diff --git a/doc/ffserver.texi b/doc/ffserver.texi
index dbfffd2..f1b7599 100644
--- a/doc/ffserver.texi
+++ b/doc/ffserver.texi
@@ -9,47 +9,35 @@
 
 @contents
 
-@chapter Synopsys
+@chapter Synopsis
 
-The generic syntax is:
-
-@example
-@c man begin SYNOPSIS
-ffserver [options]
-@c man end
-@end example
+ffserver [@var{options}]
 
 @chapter Description
 @c man begin DESCRIPTION
 
-ffserver is a streaming server for both audio and video. It supports
+@command{ffserver} is a streaming server for both audio and video. It
+supports several live feeds, streaming from files and time shifting on
+live feeds (you can seek to positions in the past on each live feed,
+provided you specify a big enough feed storage in
+@file{ffserver.conf}).
 
-several live feeds, streaming from files and time shifting on live feeds
-(you can seek to positions in the past on each live feed, provided you
-specify a big enough feed storage in ffserver.conf).
+@command{ffserver} receives prerecorded files or FFM streams from some
+@command{ffmpeg} instance as input, then streams them over
+RTP/RTSP/HTTP.
 
-This documentation covers only the streaming aspects of ffserver /
-ffmpeg. All questions about parameters for ffmpeg, codec questions,
-etc. are not covered here. Read @file{ffmpeg.html} for more
-information.
+An @command{ffserver} instance will listen on some port as specified
+in the configuration file. You can launch one or more instances of
+@command{ffmpeg} and send one or more FFM streams to the port where
+ffserver is expecting to receive them. Alternately, you can make
+@command{ffserver} launch such @command{ffmpeg} instances at startup.
 
-@section How does it work?
-
-ffserver receives prerecorded files or FFM streams from some ffmpeg
-instance as input, then streams them over RTP/RTSP/HTTP.
-
-An ffserver instance will listen on some port as specified in the
-configuration file. You can launch one or more instances of ffmpeg and
-send one or more FFM streams to the port where ffserver is expecting
-to receive them. Alternately, you can make ffserver launch such ffmpeg
-instances at startup.
-
-Input streams are called feeds, and each one is specified by a <Feed>
-section in the configuration file.
+Input streams are called feeds, and each one is specified by a
+@code{<Feed>} section in the configuration file.
 
 For each feed you can have different output streams in various
-formats, each one specified by a <Stream> section in the configuration
-file.
+formats, each one specified by a @code{<Stream>} section in the
+configuration file.
 
 @section Status stream
 
@@ -85,14 +73,6 @@
 It can stream prerecorded video from .ffm files, though it is somewhat tricky
 to make it work correctly.
 
-@section What do I need?
-
-I use Linux on a 900 MHz Duron with a cheapo Bt848 based TV capture card. I'm
-using stock Linux 2.4.17 with the stock drivers. [Actually that isn't true,
-I needed some special drivers for my motherboard-based sound card.]
-
-I understand that FreeBSD systems work just fine as well.
-
 @section How do I make it work?
 
 First, build the kit. It *really* helps to have installed LAME first. Then when
@@ -235,13 +215,13 @@
 
 @section What is FFM, FFM2
 
-FFM and FFM2 are formats used by ffserver. They allow storing a wide varity of
+FFM and FFM2 are formats used by ffserver. They allow storing a wide variety of
 video and audio streams and encoding options, and can store a moving time segment
 of an infinite movie or a whole movie.
 
 FFM is version specific, and there is limited compatibility of FFM files
 generated by one version of ffmpeg/ffserver and another version of
-ffmpeg/ffserver. It may work but its not guaranteed to work.
+ffmpeg/ffserver. It may work but it is not guaranteed to work.
 
 FFM2 is extensible while maintaining compatibility and should work between
 differing versions of tools. FFM2 is the default.
@@ -266,21 +246,36 @@
 @end table
 @c man end
 
+@chapter See Also
+
+@ifhtml
+The @file{doc/ffserver.conf} example,
+@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe},
+@url{ffmpeg-utils.html,ffmpeg-utils},
+@url{ffmpeg-scaler.html,ffmpeg-scaler},
+@url{ffmpeg-resampler.html,ffmpeg-resampler},
+@url{ffmpeg-codecs.html,ffmpeg-codecs},
+@url{ffmpeg-bitstream-filters.html,ffmpeg-bitstream-filters},
+@url{ffmpeg-formats.html,ffmpeg-formats},
+@url{ffmpeg-devices.html,ffmpeg-devices},
+@url{ffmpeg-protocols.html,ffmpeg-protocols},
+@url{ffmpeg-filters.html,ffmpeg-filters}
+@end ifhtml
+
+@ifnothtml
+The @file{doc/ffserver.conf} example, ffmpeg(1), ffplay(1), ffprobe(1),
+ffmpeg-utils(1), ffmpeg-scaler(1), ffmpeg-resampler(1),
+ffmpeg-codecs(1), ffmpeg-bitstream-filters(1), ffmpeg-formats(1),
+ffmpeg-devices(1), ffmpeg-protocols(1), ffmpeg-filters(1)
+@end ifnothtml
+
+@include authors.texi
+
 @ignore
 
 @setfilename ffserver
 @settitle ffserver video server
 
-@c man begin SEEALSO
-
-ffmpeg(1), ffplay(1), ffprobe(1), the @file{ffserver.conf}
-example and the FFmpeg HTML documentation
-@c man end
-
-@c man begin AUTHORS
-The FFmpeg developers
-@c man end
-
 @end ignore
 
 @bye
diff --git a/doc/filter_design.txt b/doc/filter_design.txt
index 362fce4..772ca9d 100644
--- a/doc/filter_design.txt
+++ b/doc/filter_design.txt
@@ -15,13 +15,13 @@
   the list of supported formats.
 
   For video links, that means pixel format. For audio links, that means
-  channel layout, and sample format (the sample packing is implied by the
-  sample format).
+  channel layout, sample format (the sample packing is implied by the sample
+  format) and sample rate.
 
   The lists are not just lists, they are references to shared objects. When
   the negotiation mechanism computes the intersection of the formats
-  supported at each ends of a link, all references to both lists are
-  replaced with a reference to the intersection. And when a single format is
+  supported at each end of a link, all references to both lists are replaced
+  with a reference to the intersection. And when a single format is
   eventually chosen for a link amongst the remaining list, again, all
   references to the list are updated.
 
@@ -68,15 +68,15 @@
 
     Here are the (fairly obvious) rules for reference ownership:
 
-    * A reference received by the start_frame or filter_frame method
-      belong to the corresponding filter.
+    * A reference received by the filter_frame method (or its start_frame
+      deprecated version) belongs to the corresponding filter.
 
       Special exception: for video references: the reference may be used
       internally for automatic copying and must not be destroyed before
       end_frame; it can be given away to ff_start_frame.
 
-    * A reference passed to ff_start_frame or ff_filter_frame is given
-      away and must no longer be used.
+    * A reference passed to ff_filter_frame (or the deprecated
+      ff_start_frame) is given away and must no longer be used.
 
     * A reference created with avfilter_ref_buffer belongs to the code that
       created it.
@@ -90,27 +90,11 @@
   Link reference fields
   ---------------------
 
-    The AVFilterLink structure has a few AVFilterBufferRef fields. Here are
-    the rules to handle them:
-
-    * cur_buf is set before the start_frame and filter_frame methods to
-      the same reference given as argument to the methods and belongs to the
-      destination filter of the link. If it has not been cleared after
-      end_frame or filter_frame, libavfilter will automatically destroy
-      the reference; therefore, any filter that needs to keep the reference
-      for longer must set cur_buf to NULL.
-
-    * out_buf belongs to the source filter of the link and can be used to
-      store a reference to the buffer that has been sent to the destination.
-      If it is not NULL after end_frame or filter_frame, libavfilter will
-      automatically destroy the reference.
-
-      If a video input pad does not have a start_frame method, the default
-      method will request a buffer on the first output of the filter, store
-      the reference in out_buf and push a second reference to the output.
-
-    * src_buf, cur_buf_copy and partial_buf are used by libavfilter
-      internally and must not be accessed by filters.
+    The AVFilterLink structure has a few AVFilterBufferRef fields. The
+    cur_buf and out_buf were used with the deprecated
+    start_frame/draw_slice/end_frame API and should no longer be used.
+    src_buf, cur_buf_copy and partial_buf are used by libavfilter internally
+    and must not be accessed by filters.
 
   Reference permissions
   ---------------------
@@ -119,8 +103,10 @@
     the code that owns the reference is allowed to do to the buffer data.
     Different references for the same buffer can have different permissions.
 
-    For video filters, the permissions only apply to the parts of the buffer
-    that have already been covered by the draw_slice method.
+    For video filters that implement the deprecated
+    start_frame/draw_slice/end_frame API, the permissions only apply to the
+    parts of the buffer that have already been covered by the draw_slice
+    method.
 
     The value is a binary OR of the following constants:
 
@@ -179,9 +165,9 @@
       with the WRITE permission.
 
     * Filters that intend to keep a reference after the filtering process
-      is finished (after end_frame or filter_frame returns) must have the
-      PRESERVE permission on it and remove the WRITE permission if they
-      create a new reference to give it away.
+      is finished (after filter_frame returns) must have the PRESERVE
+      permission on it and remove the WRITE permission if they create a new
+      reference to give it away.
 
     * Filters that intend to modify a reference they have kept after the end
       of the filtering process need the REUSE2 permission and must remove
@@ -198,11 +184,11 @@
   Simple filters that output one frame for each input frame should not have
   to worry about it.
 
-  start_frame / filter_frame
-  ----------------------------
+  filter_frame
+  ------------
 
-    These methods are called when a frame is pushed to the filter's input.
-    They can be called at any time except in a reentrant way.
+    This method is called when a frame is pushed to the filter's input. It
+    can be called at any time except in a reentrant way.
 
     If the input frame is enough to produce output, then the filter should
     push the output frames on the output link immediately.
@@ -213,7 +199,7 @@
     filter; these buffered frames must be flushed immediately if a new input
     produces new output.
 
-    (Example: framerate-doubling filter: start_frame must (1) flush the
+    (Example: framerate-doubling filter: filter_frame must (1) flush the
     second copy of the previous frame, if it is still there, (2) push the
     first copy of the incoming frame, (3) keep the second copy for later.)
 
@@ -233,8 +219,8 @@
 
     This method is called when a frame is wanted on an output.
 
-    For an input, it should directly call start_frame or filter_frame on
-    the corresponding output.
+    For an input, it should directly call filter_frame on the corresponding
+    output.
 
     For a filter, if there are queued frames already ready, one of these
     frames should be pushed. If not, the filter should request a frame on
@@ -255,7 +241,7 @@
         }
         while (!frame_pushed) {
             input = input_where_a_frame_is_most_needed();
-            ret = avfilter_request_frame(input);
+            ret = ff_request_frame(input);
             if (ret == AVERROR_EOF) {
                 process_eof_on_input();
             } else if (ret < 0) {
@@ -266,4 +252,14 @@
 
     Note that, except for filters that can have queued frames, request_frame
     does not push frames: it requests them to its input, and as a reaction,
-    the start_frame / filter_frame method will be called and do the work.
+    the filter_frame method will be called and do the work.
+
+Legacy API
+==========
+
+  Until libavfilter 3.23, the filter_frame method was split:
+
+  - for video filters, it was made of start_frame, draw_slice (that could be
+    called several times on distinct parts of the frame) and end_frame;
+
+  - for audio filters, it was called filter_samples.
diff --git a/doc/filters.texi b/doc/filters.texi
index e25f548..bcbe21a 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -3,23 +3,16 @@
 
 Filtering in FFmpeg is enabled through the libavfilter library.
 
-Libavfilter is the filtering API of FFmpeg. It is the substitute of
-the now deprecated 'vhooks' and started as a Google Summer of Code
-project.
-
-Audio filtering integration into the main FFmpeg repository is a work in
-progress, so audio API and ABI should not be considered stable yet.
-
 In libavfilter, it is possible for filters to have multiple inputs and
 multiple outputs.
 To illustrate the sorts of things that are possible, we can
 use a complex filter graph. For example, the following one:
 
 @example
-input --> split --> fifo -----------------------> overlay --> output
-            |                                        ^
-            |                                        |
-            +------> fifo --> crop --> vflip --------+
+input --> split ---------------------> overlay --> output
+            |                             ^
+            |                             |
+            +-----> crop --> vflip -------+
 @end example
 
 splits the stream in two streams, sends one stream through the crop filter
@@ -27,7 +20,7 @@
 overlaying it on top. You can use the following command to achieve this:
 
 @example
-ffmpeg -i input -vf "[in] split [T1], fifo, [T2] overlay=0:H/2 [out]; [T1] fifo, crop=iw:ih/2:0:ih/2, vflip [T2]" output
+ffmpeg -i input -vf "[in] split [T1], [T2] overlay=0:H/2 [out]; [T1] crop=iw:ih/2:0:ih/2, vflip [T2]" output
 @end example
 
 The result will be that in output the top half of the video is mirrored
@@ -35,8 +28,8 @@
 
 Filters are loaded using the @var{-vf} or @var{-af} option passed to
 @command{ffmpeg} or to @command{ffplay}. Filters in the same linear
-chain are separated by commas. In our example, @var{split, fifo,
-overlay} are in one linear chain, and @var{fifo, crop, vflip} are in
+chain are separated by commas. In our example, @var{split,
+overlay} are in one linear chain, and @var{crop, vflip} are in
 another. The points where the linear chains join are labeled by names
 enclosed in square brackets. In our example, that is @var{[T1]} and
 @var{[T2]}. The special labels @var{[in]} and @var{[out]} are the points
@@ -186,7 +179,7 @@
 @var{LINKLABEL}        ::= "[" @var{NAME} "]"
 @var{LINKLABELS}       ::= @var{LINKLABEL} [@var{LINKLABELS}]
 @var{FILTER_ARGUMENTS} ::= sequence of chars (eventually quoted)
-@var{FILTER}           ::= [@var{LINKNAMES}] @var{NAME} ["=" @var{ARGUMENTS}] [@var{LINKNAMES}]
+@var{FILTER}           ::= [@var{LINKLABELS}] @var{NAME} ["=" @var{FILTER_ARGUMENTS}] [@var{LINKLABELS}]
 @var{FILTERCHAIN}      ::= @var{FILTER} [,@var{FILTERCHAIN}]
 @var{FILTERGRAPH}      ::= [sws_flags=@var{flags};] @var{FILTERCHAIN} [;@var{FILTERGRAPH}]
 @end example
@@ -240,8 +233,8 @@
 drawtext=text=\'Caesar: tu quoque\, Brute\, fili mi\'
 @end example
 
-See the @ref{quoting_and_escaping, Quoting and escaping} section for
-more information about the escaping and quoting rules adopted by
+See the ``Quoting and escaping'' section in the ffmpeg-utils manual
+for more information about the escaping and quoting rules adopted by
 FFmpeg.
 
 @c man end FILTERGRAPH DESCRIPTION
@@ -289,9 +282,388 @@
 @end example
 @end itemize
 
+@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 parameters as a list of @var{key}=@var{value}
+pairs, separated by ":".
+
+A description of the accepted parameters follows.
+
+@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 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 parameters as a list of @var{key}=@var{value}
+pairs, separated by ":".
+
+A description of the accepted parameters follows.
+
+@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 parameters as a list of @var{key}=@var{value}
+pairs, separated by ":".
+
+A description of the accepted parameters follows.
+
+@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 parameters as a list of @var{key}=@var{value}
+pairs, separated by ":".
+
+A description of the accepted parameters follows.
+
+@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 parameters as a list of @var{key}=@var{value}
+pairs, separated by ":".
+
+A description of the accepted parameters follows.
+
+@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 parameters as a list of @var{key}=@var{value}
+pairs, separated by ":".
+
+A description of the accepted parameters follows.
+
+@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 parameters as a list of @var{key}=@var{value}
+pairs, separated by ":".
+
+A description of the accepted parameters follows.
+
+@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 parameters as a list of @var{key}=@var{value}
+pairs, separated by ":".
+
+A description of the accepted parameters follows.
+
+@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 afade
+
+Apply fade-in/out effect to input audio.
+
+The filter accepts parameters as a list of @var{key}=@var{value}
+pairs, separated by ":".
+
+A description of the accepted parameters follows.
+
+@table @option
+@item type, t
+Specify the effect type, can be either @code{in} for fade-in, or
+@code{out} for a fade-out effect. Default is @code{in}.
+
+@item start_sample, ss
+Specify the number of the start sample for starting to apply the fade
+effect. Default is 0.
+
+@item nb_samples, ns
+Specify the number of samples for which the fade effect has to last. At
+the end of the fade-in effect the output audio will have the same
+volume as the input audio, at the end of the fade-out transition
+the output audio will be silence. Default is 44100.
+
+@item start_time, st
+Specify time in seconds for starting to apply the fade
+effect. Default is 0.
+If set this option is used instead of @var{start_sample} one.
+
+@item duration, d
+Specify the number of seconds for which the fade effect has to last. At
+the end of the fade-in effect the output audio will have the same
+volume as the input audio, at the end of the fade-out transition
+the output audio will be silence. Default is 0.
+If set this option is used instead of @var{nb_samples} one.
+
+@item curve
+Set curve for fade transition.
+
+It accepts the following values:
+@table @option
+@item tri
+select triangular, linear slope (default)
+@item qsin
+select quarter of sine wave
+@item hsin
+select half of sine wave
+@item esin
+select exponential sine wave
+@item log
+select logarithmic
+@item par
+select inverted parabola
+@item qua
+select quadratic
+@item cub
+select cubic
+@item squ
+select square root
+@item cbr
+select cubic root
+@end table
+@end table
+
+@subsection Examples
+@itemize
+@item
+Fade in first 15 seconds of audio:
+@example
+afade=t=in:ss=0:d=15
+@end example
+
+@item
+Fade out last 25 seconds of a 900 seconds audio:
+@example
+afade=t=out:ss=875:d=25
+@end example
+@end itemize
+
 @section aformat
 
-Convert the input audio to one of the specified formats. The framework will
+Set output format constraints for the input audio. The framework will
 negotiate the most appropriate format to minimize conversions.
 
 The filter accepts the following named parameters:
@@ -312,7 +684,7 @@
 
 For example to force the output to either unsigned 8-bit or signed 16-bit stereo:
 @example
-aformat=sample_fmts\=u8\,s16:channel_layouts\=stereo
+aformat='sample_fmts=u8,s16:channel_layouts=stereo'
 @end example
 
 @section amerge
@@ -409,19 +781,39 @@
 
 Pass the audio source unchanged to the output.
 
+@section apad
+
+Pad the end of a audio stream with silence, this can be used together with
+-shortest to extend audio streams to the same length as the video stream.
+
+@anchor{aresample}
 @section aresample
 
-Resample the input audio to the specified sample rate.
+Resample the input audio to the specified parameters, using the
+libswresample library. If none are specified then the filter will
+automatically convert between its input and output.
 
-The filter accepts exactly one parameter, the output sample rate. If not
-specified then the filter will automatically convert between its input
-and output sample rates.
+This filter is also able to stretch/squeeze the audio data to make it match
+the timestamps or to inject silence / cut out audio to make it match the
+timestamps, do a combination of both or do neither.
+
+The filter accepts the syntax
+[@var{sample_rate}:]@var{resampler_options}, where @var{sample_rate}
+expresses a sample rate and @var{resampler_options} is a list of
+@var{key}=@var{value} pairs, separated by ":". See the
+ffmpeg-resampler manual for the complete list of supported options.
 
 For example, to resample the input audio to 44100Hz:
 @example
 aresample=44100
 @end example
 
+To stretch/squeeze samples to the given timestamps, with a maximum of 1000
+samples per second compensation:
+@example
+aresample=async=1000
+@end example
+
 @section asetnsamples
 
 Set the number of samples per each output audio frame.
@@ -701,100 +1093,12 @@
 ffmpeg -f lavfi -i amovie=silence.mp3,silencedetect=noise=0.0001 -f null -
 @end example
 
-@section volume
-
-Adjust the input audio volume.
-
-The filter accepts exactly one parameter @var{vol}, which expresses
-how the audio volume will be increased or decreased.
-
-Output values are clipped to the maximum value.
-
-If @var{vol} is expressed as a decimal number, the output audio
-volume is given by the relation:
-@example
-@var{output_volume} = @var{vol} * @var{input_volume}
-@end example
-
-If @var{vol} is expressed as a decimal number followed by the string
-"dB", the value represents the requested change in decibels of the
-input audio power, and the output audio volume is given by the
-relation:
-@example
-@var{output_volume} = 10^(@var{vol}/20) * @var{input_volume}
-@end example
-
-Otherwise @var{vol} is considered an expression and its evaluated
-value is used for computing the output audio volume according to the
-first relation.
-
-Default value for @var{vol} is 1.0.
-
-@subsection Examples
-
-@itemize
-@item
-Half the input audio volume:
-@example
-volume=0.5
-@end example
-
-The above example is equivalent to:
-@example
-volume=1/2
-@end example
-
-@item
-Decrease input audio power by 12 decibels:
-@example
-volume=-12dB
-@end example
-@end itemize
-
-@section volumedetect
-
-Detect the volume of the input video.
-
-The filter has no parameters. The input is not modified. Statistics about
-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
-registered volume values (from the maximum value to a cumulated 1/1000 of
-the samples).
-
-All volumes are in decibels relative to the maximum PCM value.
-
-Here is an excerpt of the output:
-@example
-[Parsed_volumedetect_0 @ 0xa23120] mean_volume: -27 dB
-[Parsed_volumedetect_0 @ 0xa23120] max_volume: -4 dB
-[Parsed_volumedetect_0 @ 0xa23120] histogram_4db: 6
-[Parsed_volumedetect_0 @ 0xa23120] histogram_5db: 62
-[Parsed_volumedetect_0 @ 0xa23120] histogram_6db: 286
-[Parsed_volumedetect_0 @ 0xa23120] histogram_7db: 1042
-[Parsed_volumedetect_0 @ 0xa23120] histogram_8db: 2551
-[Parsed_volumedetect_0 @ 0xa23120] histogram_9db: 4609
-[Parsed_volumedetect_0 @ 0xa23120] histogram_10db: 8409
-@end example
-
-It means that:
-@itemize
-@item
-The mean square energy is approximately -27 dB, or 10^-2.7.
-@item
-The largest sample is at -4 dB, or more precisely between -4 dB and -5 dB.
-@item
-There are 6 samples at -4 dB, 62 at -5 dB, 286 at -6 dB, etc.
-@end itemize
-
-In other words, raising the volume by +4 dB does not cause any clipping,
-raising it by +5 dB causes clipping for 6 samples, etc.
-
 @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
 
@@ -812,11 +1116,12 @@
 Default value 500.
 
 @item first_pts
-Assume the first pts should be this value.
+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.
+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
 
@@ -919,6 +1224,111 @@
 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.
+
+The filter accepts the following named parameters. If the key of the
+first options is omitted, the arguments are interpreted according to
+the following syntax:
+@example
+volume=@var{volume}:@var{precision}
+@end example
+
+@table @option
+
+@item volume
+Expresses how the audio volume will be increased or decreased.
+
+Output values are clipped to the maximum value.
+
+The output audio volume is given by the relation:
+@example
+@var{output_volume} = @var{volume} * @var{input_volume}
+@end example
+
+Default value for @var{volume} is 1.0.
+
+@item precision
+Set the mathematical precision.
+
+This determines which input sample formats will be allowed, which affects the
+precision of the volume scaling.
+
+@table @option
+@item fixed
+8-bit fixed-point; limits input sample format to U8, S16, and S32.
+@item float
+32-bit floating-point; limits input sample format to FLT. (default)
+@item double
+64-bit floating-point; limits input sample format to DBL.
+@end table
+@end table
+
+@subsection Examples
+
+@itemize
+@item
+Halve the input audio volume:
+@example
+volume=volume=0.5
+volume=volume=1/2
+volume=volume=-6.0206dB
+@end example
+
+In all the above example the named key for @option{volume} can be
+omitted, for example like in:
+@example
+volume=0.5
+@end example
+
+@item
+Increase input audio power by 6 decibels using fixed-point precision:
+@example
+volume=volume=6dB:precision=fixed
+@end example
+@end itemize
+
+@section volumedetect
+
+Detect the volume of the input video.
+
+The filter has no parameters. The input is not modified. Statistics about
+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
+registered volume values (from the maximum value to a cumulated 1/1000 of
+the samples).
+
+All volumes are in decibels relative to the maximum PCM value.
+
+Here is an excerpt of the output:
+@example
+[Parsed_volumedetect_0 @ 0xa23120] mean_volume: -27 dB
+[Parsed_volumedetect_0 @ 0xa23120] max_volume: -4 dB
+[Parsed_volumedetect_0 @ 0xa23120] histogram_4db: 6
+[Parsed_volumedetect_0 @ 0xa23120] histogram_5db: 62
+[Parsed_volumedetect_0 @ 0xa23120] histogram_6db: 286
+[Parsed_volumedetect_0 @ 0xa23120] histogram_7db: 1042
+[Parsed_volumedetect_0 @ 0xa23120] histogram_8db: 2551
+[Parsed_volumedetect_0 @ 0xa23120] histogram_9db: 4609
+[Parsed_volumedetect_0 @ 0xa23120] histogram_10db: 8409
+@end example
+
+It means that:
+@itemize
+@item
+The mean square energy is approximately -27 dB, or 10^-2.7.
+@item
+The largest sample is at -4 dB, or more precisely between -4 dB and -5 dB.
+@item
+There are 6 samples at -4 dB, 62 at -5 dB, 286 at -6 dB, etc.
+@end itemize
+
+In other words, raising the volume by +4 dB does not cause any clipping,
+raising it by +5 dB causes clipping for 6 samples, etc.
+
 @c man end AUDIO FILTERS
 
 @chapter Audio Sources
@@ -952,6 +1362,11 @@
 @file{libavutil/channel_layout.c} or its corresponding integer representation
 from the AV_CH_LAYOUT_* macros in @file{libavutil/channel_layout.h}
 
+@item channels
+The number of channels of the incoming audio buffers.
+If both @var{channels} and @var{channel_layout} are specified, then they
+must be consistent.
+
 @end table
 
 For example:
@@ -1274,38 +1689,9 @@
 
 @section ass
 
-Draw ASS (Advanced Substation Alpha) subtitles on top of input video
-using the libass library.
-
-To enable compilation of this filter you need to configure FFmpeg with
-@code{--enable-libass}.
-
-This filter accepts the following named options, expressed as a
-sequence of @var{key}=@var{value} pairs, separated by ":".
-
-@table @option
-@item filename, f
-Set the filename of the ASS file to read. It must be specified.
-
-@item original_size
-Specify the size of the original video, the video for which the ASS file
-was composed. Due to a misdesign in ASS aspect ratio arithmetic, this is
-necessary to correctly scale the fonts if the aspect ratio has been changed.
-@end table
-
-If the first key is not specified, it is assumed that the first value
-specifies the @option{filename}.
-
-For example, to render the file @file{sub.ass} on top of the input
-video, use the command:
-@example
-ass=sub.ass
-@end example
-
-which is equivalent to:
-@example
-ass=filename=sub.ass
-@end example
+Same as the @ref{subtitles} filter, except that it doesn't require libavcodec
+and libavformat to work. On the other hand, it is limited to ASS (Advanced
+Substation Alpha) subtitles files.
 
 @section bbox
 
@@ -1392,21 +1778,144 @@
 @var{threshold} is the threshold below which a pixel value is
 considered black, and defaults to 32.
 
+@section blend
+
+Blend two video frames into each other.
+
+It takes two input streams and outputs one stream, the first input is the
+"top" layer and second input is "bottom" layer.
+Output terminates when shortest input terminates.
+
+This filter accepts a list of options in the form of @var{key}=@var{value}
+pairs separated by ":". A description of the accepted options follows.
+
+@table @option
+@item c0_mode
+@item c1_mode
+@item c2_mode
+@item c3_mode
+@item all_mode
+Set blend mode for specific pixel component or all pixel components in case
+of @var{all_mode}. Default value is @code{normal}.
+
+Available values for component modes are:
+@table @samp
+@item addition
+@item and
+@item average
+@item burn
+@item darken
+@item difference
+@item divide
+@item dodge
+@item exclusion
+@item hardlight
+@item lighten
+@item multiply
+@item negation
+@item normal
+@item or
+@item overlay
+@item phoenix
+@item pinlight
+@item reflect
+@item screen
+@item softlight
+@item subtract
+@item vividlight
+@item xor
+@end table
+
+@item c0_opacity
+@item c1_opacity
+@item c2_opacity
+@item c3_opacity
+@item all_opacity
+Set blend opacity for specific pixel component or all pixel components in case
+of @var{all_expr}. Only used in combination with pixel component blend modes.
+
+@item c0_expr
+@item c1_expr
+@item c2_expr
+@item c3_expr
+@item all_expr
+Set blend expression for specific pixel component or all pixel components in case
+of @var{all_expr}. Note that related mode options will be ignored if those are set.
+
+The expressions can use the following variables:
+
+@table @option
+@item X
+@item Y
+the coordinates of the current sample
+
+@item W
+@item H
+the width and height of currently filtered plane
+
+@item SW
+@item SH
+Width and height scale depending on the currently filtered plane. It is the
+ratio between the corresponding luma plane number of pixels and the current
+plane ones. E.g. for YUV4:2:0 the values are @code{1,1} for the luma plane, and
+@code{0.5,0.5} for chroma planes.
+
+@item T
+Time of the current frame, expressed in seconds.
+
+@item TOP, A
+Value of pixel component at current location for first video frame (top layer).
+
+@item BOTTOM, B
+Value of pixel component at current location for second video frame (bottom layer).
+@end table
+@end table
+
+Some examples follow.
+
+@itemize
+
+@item
+Apply transition from bottom layer to top layer in first 10 seconds:
+@example
+blend=all_expr='A*(if(gte(T,10),1,T/10))+B*(1-(if(gte(T,10),1,T/10)))'
+@end example
+
+@item
+Apply 1x1 checkerboard effect:
+@example
+blend=all_expr='if(eq(mod(X,2),mod(Y,2)),A,B)'
+@end example
+@end itemize
+
 @section boxblur
 
 Apply boxblur algorithm to the input video.
 
-This filter accepts the parameters:
-@var{luma_radius}:@var{luma_power}:@var{chroma_radius}:@var{chroma_power}:@var{alpha_radius}:@var{alpha_power}
+The filter accepts parameters as a list of @var{key}=@var{value}
+pairs, separated by ":". If the key of the first options is omitted,
+the arguments are interpreted according to the syntax
+@option{luma_radius}:@option{luma_power}:@option{chroma_radius}:@option{chroma_power}:@option{alpha_radius}:@option{alpha_power}.
 
-Chroma and alpha parameters are optional, if not specified they default
-to the corresponding values set for @var{luma_radius} and
-@var{luma_power}.
+A description of the accepted options follows.
 
-@var{luma_radius}, @var{chroma_radius}, and @var{alpha_radius} represent
-the radius in pixels of the box used for blurring the corresponding
-input plane. They are expressions, and can contain the following
-constants:
+@table @option
+@item luma_radius, lr
+@item chroma_radius, cr
+@item alpha_radius, ar
+Set an expression for the box radius in pixels used for blurring the
+corresponding input plane.
+
+The radius value must be a non-negative number, and must not be
+greater than the value of the expression @code{min(w,h)/2} for the
+luma and alpha planes, and of @code{min(cw,ch)/2} for the chroma
+planes.
+
+Default value for @option{luma_radius} is "2". If not specified,
+@option{chroma_radius} and @option{alpha_radius} default to the
+corresponding value set for @option{luma_radius}.
+
+The expressions can contain the following constants:
 @table @option
 @item w, h
 the input width and height in pixels
@@ -1419,18 +1928,22 @@
 pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1.
 @end table
 
-The radius must be a non-negative number, and must not be greater than
-the value of the expression @code{min(w,h)/2} for the luma and alpha planes,
-and of @code{min(cw,ch)/2} for the chroma planes.
+@item luma_power, lp
+@item chroma_power, cp
+@item alpha_power, ap
+Specify how many times the boxblur filter is applied to the
+corresponding plane.
 
-@var{luma_power}, @var{chroma_power}, and @var{alpha_power} represent
-how many times the boxblur filter is applied to the corresponding
-plane.
+Default value for @option{luma_power} is 2. If not specified,
+@option{chroma_power} and @option{alpha_power} default to the
+corresponding value set for @option{luma_power}.
 
-Some examples follow:
+A value of 0 will disable the effect.
+@end table
+
+Some examples follow.
 
 @itemize
-
 @item
 Apply a boxblur filter with luma, chroma, and alpha radius
 set to 2:
@@ -1439,17 +1952,16 @@
 @end example
 
 @item
-Set luma radius to 2, alpha and chroma radius to 0
+Set luma radius to 2, alpha and chroma radius to 0:
 @example
-boxblur=2:1:0:0:0:0
+boxblur=2:1:cr=0:ar=0
 @end example
 
 @item
-Set luma and chroma radius to a fraction of the video dimension
+Set luma and chroma radius to a fraction of the video dimension:
 @example
 boxblur=min(h\,w)/10:1:min(cw\,ch)/10:1
 @end example
-
 @end itemize
 
 @section colormatrix
@@ -1471,11 +1983,40 @@
 
 @section crop
 
-Crop the input video to @var{out_w}:@var{out_h}:@var{x}:@var{y}:@var{keep_aspect}
+Crop the input video.
 
-The @var{keep_aspect} parameter is optional, if specified and set to a
-non-zero value will force the output display aspect ratio to be the
-same of the input, by changing the output sample aspect ratio.
+This filter accepts a list of @var{key}=@var{value} pairs as argument,
+separated by ':'. If the key of the first options is omitted, the
+arguments are interpreted according to the syntax
+@var{out_w}:@var{out_h}:@var{x}:@var{y}:@var{keep_aspect}.
+
+A description of the accepted options follows:
+@table @option
+@item w, out_w
+Set the crop area width. It defaults to @code{iw}.
+This expression is evaluated only once during the filter
+configuration.
+
+@item h, out_h
+Set the crop area width. It defaults to @code{ih}.
+This expression is evaluated only once during the filter
+configuration.
+
+@item x
+Set the expression for the x top-left coordinate of the cropped area.
+It defaults to @code{(in_w-out_w)/2}.
+This expression is evaluated per-frame.
+
+@item y
+Set the expression for the y top-left coordinate of the cropped area.
+It defaults to @code{(in_h-out_h)/2}.
+This expression is evaluated per-frame.
+
+@item keep_aspect
+If set to 1 will force the output display aspect ratio
+to be the same of the input, by changing the output sample aspect
+ratio. It defaults to 0.
+@end table
 
 The @var{out_w}, @var{out_h}, @var{x}, @var{y} parameters are
 expressions containing the following constants:
@@ -1521,13 +2062,6 @@
 
 @end table
 
-The @var{out_w} and @var{out_h} parameters specify the expressions for
-the width and height of the output (cropped) video. They are
-evaluated just at the configuration of the filter.
-
-The default value of @var{out_w} is "in_w", and the default value of
-@var{out_h} is "in_h".
-
 The expression for @var{out_w} may depend on the value of @var{out_h},
 and the expression for @var{out_h} may depend on @var{out_w}, but they
 cannot depend on @var{x} and @var{y}, as @var{x} and @var{y} are
@@ -1538,49 +2072,86 @@
 are evaluated for each frame. If the evaluated value is not valid, it
 is approximated to the nearest valid value.
 
-The default value of @var{x} is "(in_w-out_w)/2", and the default
-value for @var{y} is "(in_h-out_h)/2", which set the cropped area at
-the center of the input image.
-
 The expression for @var{x} may depend on @var{y}, and the expression
 for @var{y} may depend on @var{x}.
 
-Follow some examples:
+@subsection Examples
+@itemize
+@item
+Crop area with size 100x100 at position (12,34).
 @example
-# crop the central input area with size 100x100
-crop=100:100
-
-# crop the central input area with size 2/3 of the input video
-"crop=2/3*in_w:2/3*in_h"
-
-# crop the input video central square
-crop=in_h
-
-# delimit the rectangle with the top-left corner placed at position
-# 100:100 and the right-bottom corner corresponding to the right-bottom
-# corner of the input image.
-crop=in_w-100:in_h-100:100:100
-
-# crop 10 pixels from the left and right borders, and 20 pixels from
-# the top and bottom borders
-"crop=in_w-2*10:in_h-2*20"
-
-# keep only the bottom right quarter of the input image
-"crop=in_w/2:in_h/2:in_w/2:in_h/2"
-
-# crop height for getting Greek harmony
-"crop=in_w:1/PHI*in_w"
-
-# trembling effect
-"crop=in_w/2:in_h/2:(in_w-out_w)/2+((in_w-out_w)/2)*sin(n/10):(in_h-out_h)/2 +((in_h-out_h)/2)*sin(n/7)"
-
-# erratic camera effect depending on timestamp
-"crop=in_w/2:in_h/2:(in_w-out_w)/2+((in_w-out_w)/2)*sin(t*10):(in_h-out_h)/2 +((in_h-out_h)/2)*sin(t*13)"
-
-# set x depending on the value of y
-"crop=in_w/2:in_h/2:y:10+10*sin(n/10)"
+crop=100:100:12:34
 @end example
 
+Using named options, the example above becomes:
+@example
+crop=w=100:h=100:x=12:y=34
+@end example
+
+@item
+Crop the central input area with size 100x100:
+@example
+crop=100:100
+@end example
+
+@item
+Crop the central input area with size 2/3 of the input video:
+@example
+crop=2/3*in_w:2/3*in_h
+@end example
+
+@item
+Crop the input video central square:
+@example
+crop=in_h
+@end example
+
+@item
+Delimit the rectangle with the top-left corner placed at position
+100:100 and the right-bottom corner corresponding to the right-bottom
+corner of the input image:
+@example
+crop=in_w-100:in_h-100:100:100
+@end example
+
+@item
+Crop 10 pixels from the left and right borders, and 20 pixels from
+the top and bottom borders
+@example
+crop=in_w-2*10:in_h-2*20
+@end example
+
+@item
+Keep only the bottom right quarter of the input image:
+@example
+crop=in_w/2:in_h/2:in_w/2:in_h/2
+@end example
+
+@item
+Crop height for getting Greek harmony:
+@example
+crop=in_w:1/PHI*in_w
+@end example
+
+@item
+Appply trembling effect:
+@example
+crop=in_w/2:in_h/2:(in_w-out_w)/2+((in_w-out_w)/2)*sin(n/10):(in_h-out_h)/2 +((in_h-out_h)/2)*sin(n/7)
+@end example
+
+@item
+Apply erratic camera effect depending on timestamp:
+@example
+crop=in_w/2:in_h/2:(in_w-out_w)/2+((in_w-out_w)/2)*sin(t*10):(in_h-out_h)/2 +((in_h-out_h)/2)*sin(t*13)"
+@end example
+
+@item
+Set x depending on the value of y:
+@example
+crop=in_w/2:in_h/2:y:10+10*sin(n/10)
+@end example
+@end itemize
+
 @section cropdetect
 
 Auto-detect crop size.
@@ -1618,17 +2189,21 @@
 
 @section decimate
 
-This filter drops frames that do not differ greatly from the previous
-frame in order to reduce framerate.  The main use of this filter is
-for very-low-bitrate encoding (e.g. streaming over dialup modem), but
-it could in theory be used for fixing movies that were
-inverse-telecined incorrectly.
+Drop frames that do not differ greatly from the previous frame in
+order to reduce framerate.
 
-It accepts the following parameters:
-@var{max}:@var{hi}:@var{lo}:@var{frac}.
+The main use of this filter is for very-low-bitrate encoding
+(e.g. streaming over dialup modem), but it could in theory be used for
+fixing movies that were inverse-telecined incorrectly.
+
+The filter accepts parameters as a list of @var{key}=@var{value}
+pairs, separated by ":". If the key of the first options is omitted,
+the arguments are interpreted according to the syntax:
+@option{max}:@option{hi}:@option{lo}:@option{frac}.
+
+A description of the accepted options follows.
 
 @table @option
-
 @item max
 Set the maximum number of consecutive frames which can be dropped (if
 positive), or the minimum interval between dropped frames (if
@@ -1637,20 +2212,22 @@
 
 Default value is 0.
 
-@item hi, lo, frac
+@item hi
+@item lo
+@item frac
 Set the dropping threshold values.
 
-Values for @var{hi} and @var{lo} are for 8x8 pixel blocks and
+Values for @option{hi} and @option{lo} are for 8x8 pixel blocks and
 represent actual pixel value differences, so a threshold of 64
 corresponds to 1 unit of difference for each pixel, or the same spread
 out differently over the block.
 
 A frame is a candidate for dropping if no 8x8 blocks differ by more
-than a threshold of @var{hi}, and if no more than @var{frac} blocks (1
-meaning the whole image) differ by more than a threshold of @var{lo}.
+than a threshold of @option{hi}, and if no more than @option{frac} blocks (1
+meaning the whole image) differ by more than a threshold of @option{lo}.
 
-Default value for @var{hi} is 64*12, default value for @var{lo} is
-64*5, and default value for @var{frac} is 0.33.
+Default value for @option{hi} is 64*12, default value for @option{lo} is
+64*5, and default value for @option{frac} is 0.33.
 @end table
 
 @section delogo
@@ -1779,10 +2356,12 @@
 
 Draw a colored box on the input image.
 
-The filter accepts parameters as a list of @var{key}=@var{value} pairs,
-separated by ":".
+The filter accepts parameters as a list of @var{key}=@var{value}
+pairs, separated by ":". If the key of the first options is omitted,
+the arguments are interpreted according to the syntax
+@option{x}:@option{y}:@option{width}:@option{height}:@option{color}:@option{thickness}.
 
-The description of the accepted parameters follows.
+A description of the accepted options follows.
 
 @table @option
 @item x, y
@@ -1803,12 +2382,6 @@
 Set the thickness of the box edge. Default value is @code{4}.
 @end table
 
-If the key of the first options is omitted, the arguments are
-interpreted according to the following syntax:
-@example
-drawbox=@var{x}:@var{y}:@var{width}:@var{height}:@var{color}:@var{thickness}
-@end example
-
 Some examples follow:
 @itemize
 @item
@@ -1876,8 +2449,8 @@
 
 @item expansion
 Select how the @var{text} is expanded. Can be either @code{none},
-@code{strftime} (default for compatibity reasons but deprecated) or
-@code{normal}. See the @ref{drawtext_expansion, Text expansion} section
+@code{strftime} (deprecated) or
+@code{normal} (default). See the @ref{drawtext_expansion, Text expansion} section
 below for details.
 
 @item fix_bounds
@@ -1964,6 +2537,10 @@
 
 If both @var{text} and @var{textfile} are specified, an error is thrown.
 
+@item reload
+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
 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
@@ -2047,14 +2624,14 @@
 @anchor{drawtext_expansion}
 @subsection Text expansion
 
-If @option{expansion} is set to @code{strftime} (which is the default for
-now), the filter recognizes strftime() sequences in the provided text and
+If @option{expansion} is set to @code{strftime},
+the filter recognizes strftime() sequences in the provided text and
 expands them accordingly. Check the documentation of strftime(). This
 feature is deprecated.
 
 If @option{expansion} is set to @code{none}, the text is printed verbatim.
 
-If @option{expansion} is set to @code{normal} (which will be the default),
+If @option{expansion} is set to @code{normal} (which is the default),
 the following expansion mechanism is used.
 
 The backslash character '\', followed by any character, always expands to
@@ -2171,7 +2748,7 @@
 @item
 Print the date of a real-time encoding (see strftime(3)):
 @example
-drawtext='fontfile=FreeSans.ttf:expansion=normal:text=%@{localtime:%a %b %d %Y@}'
+drawtext='fontfile=FreeSans.ttf:text=%@{localtime:%a %b %d %Y@}'
 @end example
 
 @end itemize
@@ -2213,56 +2790,70 @@
 
 Apply fade-in/out effect to input video.
 
-It accepts the parameters:
-@var{type}:@var{start_frame}:@var{nb_frames}[:@var{options}]
+The filter accepts parameters as a list of @var{key}=@var{value}
+pairs, separated by ":". If the key of the first options is omitted,
+the arguments are interpreted according to the syntax
+@var{type}:@var{start_frame}:@var{nb_frames}.
 
-@var{type} specifies if the effect type, can be either "in" for
-fade-in, or "out" for a fade-out effect.
-
-@var{start_frame} specifies the number of the start frame for starting
-to apply the fade effect.
-
-@var{nb_frames} specifies the number of frames for which the fade
-effect has to last. At the end of the fade-in effect the output video
-will have the same intensity as the input video, at the end of the
-fade-out transition the output video will be completely black.
-
-@var{options} is an optional sequence of @var{key}=@var{value} pairs,
-separated by ":". The description of the accepted options follows.
+A description of the accepted parameters follows.
 
 @table @option
-
 @item type, t
-See @var{type}.
+Specify if the effect type, can be either @code{in} for fade-in, or
+@code{out} for a fade-out effect. Default is @code{in}.
 
 @item start_frame, s
-See @var{start_frame}.
+Specify the number of the start frame for starting to apply the fade
+effect. Default is 0.
 
 @item nb_frames, n
-See @var{nb_frames}.
+Specify the number of frames for which the fade effect has to last. At
+the end of the fade-in effect the output video will have the same
+intensity as the input video, at the end of the fade-out transition
+the output video will be completely black. Default is 25.
 
 @item alpha
 If set to 1, fade only alpha channel, if one exists on the input.
 Default value is 0.
 @end table
 
-A few usage examples follow, usable too as test scenarios.
+@subsection Examples
+@itemize
+@item
+Fade in first 30 frames of video:
 @example
-# fade in first 30 frames of video
 fade=in:0:30
+@end example
 
-# fade out last 45 frames of a 200-frame video
+The command above is equivalent to:
+@example
+fade=t=in:s=0:n=30
+@end example
+
+@item
+Fade out last 45 frames of a 200-frame video:
+@example
 fade=out:155:45
+@end example
 
-# fade in first 25 frames and fade out last 25 frames of a 1000-frame video
+@item
+Fade in first 25 frames and fade out last 25 frames of a 1000-frame video:
+@example
 fade=in:0:25, fade=out:975:25
+@end example
 
-# make first 5 frames black, then fade in from frame 5-24
+@item
+Make first 5 frames black, then fade in from frame 5-24:
+@example
 fade=in:5:20
+@end example
 
-# fade in alpha over first 25 frames of video
+@item
+Fade in alpha over first 25 frames of video:
+@example
 fade=in:0:25:alpha=1
 @end example
+@end itemize
 
 @section field
 
@@ -2358,13 +2949,33 @@
 @table @option
 
 @item fps
-Desired output framerate.
+Desired output framerate. The default is @code{25}.
 
 @item round
-Rounding method. The default is @code{near}.
+Rounding method.
+
+Possible values are:
+@table @option
+@item zero
+zero round towards 0
+@item inf
+round away from 0
+@item down
+round towards -infinity
+@item up
+round towards +infinity
+@item near
+round to nearest
+@end table
+The default is @code{near}.
 
 @end table
 
+Alternatively, the options can be specified as a flat string:
+@var{fps}[:@var{round}].
+
+See also the @ref{setpts} filter.
+
 @section framestep
 
 Select one frame every N.
@@ -2436,7 +3047,7 @@
 
 @section geq
 
-The filter takes one, two or three equations as parameter, separated by ':'.
+The filter takes one, two, three or four equations as parameter, separated by ':'.
 The first equation is mandatory and applies to the luma plane. The two
 following are respectively for chroma blue and chroma red planes.
 
@@ -2449,11 +3060,14 @@
 the chrominance blue expression
 @item cr_expr
 the chrominance red expression
+@item alpha_expr
+the alpha expression
 @end table
 
 If one of the chrominance expression is not defined, it falls back on the other
-one. If none of them are specified, they will evaluate the luminance
-expression.
+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.
 
 The expressions can use the following variables and functions:
 
@@ -2486,11 +3100,15 @@
 
 @item cb(x, y)
 Return the value of the pixel at location (@var{x},@var{y}) of the
-blue-difference chroma plane.
+blue-difference chroma plane. Returns 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.
+red-difference chroma plane. Returns 0 if there is no such plane.
+
+@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.
 @end table
 
 For functions, if @var{x} and @var{y} are outside the area, the value will be
@@ -2530,28 +3148,46 @@
 lossy compression, because compression tends to lose the dither and
 bring back the bands.
 
-The filter takes two optional parameters, separated by ':':
-@var{strength}:@var{radius}
+The filter accepts a list of options in the form of @var{key}=@var{value} pairs
+separated by ":". A description of the accepted options follows.
 
-@var{strength} is the maximum amount by which the filter will change
+@table @option
+
+@item strength
+The maximum amount by which the filter will change
 any one pixel. Also the threshold for detecting nearly flat
-regions. Acceptable values range from .51 to 255, default value is
-1.2, out-of-range values will be clipped to the valid range.
+regions. Acceptable values range from @code{0.51} to @code{64}, default value
+is @code{1.2}.
 
-@var{radius} is the neighborhood to fit the gradient to. A larger
+@item radius
+The neighborhood to fit the gradient to. A larger
 radius makes for smoother gradients, but also prevents the filter from
 modifying the pixels near detailed regions. Acceptable values are
-8-32, default value is 16, out-of-range values will be clipped to the
-valid range.
+@code{8-32}, default value is @code{16}.
 
+@end table
+
+Alternatively, the options can be specified as a flat string:
+@var{strength}[:@var{radius}]
+
+@subsection Examples
+
+@itemize
+@item
+Apply the filter with a @code{3.5} strength and radius of @code{8}:
 @example
-# default parameters
-gradfun=1.2:16
-
-# omitting radius
-gradfun=1.2
+gradfun=3.5:8
 @end example
 
+@item
+Specify radius, omitting the strength (which will fall-back to the default
+value):
+@example
+gradfun=radius=8
+@end example
+
+@end itemize
+
 @section hflip
 
 Flip the input video horizontally.
@@ -2561,6 +3197,159 @@
 ffmpeg -i in.avi -vf "hflip" out.avi
 @end example
 
+@section histeq
+This filter applies a global color histogram equalization on a
+per-frame basis.
+
+It can be used to correct video that has a compressed range of pixel
+intensities.  The filter redistributes the pixel intensities to
+equalize their distribution across the intensity range. It may be
+viewed as an "automatically adjusting contrast filter". This filter is
+useful only for correcting degraded or poorly captured source
+video.
+
+The filter accepts parameters as a list of @var{key}=@var{value}
+pairs, separated by ":". If the key of the first options is omitted,
+the arguments are interpreted according to syntax
+@var{strength}:@var{intensity}:@var{antibanding}.
+
+This filter accepts the following named options:
+
+@table @option
+@item strength
+Determine the amount of equalization to be applied.  As the strength
+is reduced, the distribution of pixel intensities more-and-more
+approaches that of the input frame. The value must be a float number
+in the range [0,1] and defaults to 0.200.
+
+@item intensity
+Set the maximum intensity that can generated and scale the output
+values appropriately.  The strength should be set as desired and then
+the intensity can be limited if needed to avoid washing-out. The value
+must be a float number in the range [0,1] and defaults to 0.210.
+
+@item antibanding
+Set the antibanding level. If enabled the filter will randomly vary
+the luminance of output pixels by a small amount to avoid banding of
+the histogram. Possible values are @code{none}, @code{weak} or
+@code{strong}. It defaults to @code{none}.
+@end table
+
+@section histogram
+
+Compute and draw a color distribution histogram for the input video.
+
+The computed histogram is a representation of distribution of color components
+in an image.
+
+The filter accepts the following named parameters:
+
+@table @option
+@item mode
+Set histogram mode.
+
+It accepts the following values:
+@table @samp
+@item levels
+standard histogram that display color components distribution in an image.
+Displays color graph for each color component. Shows distribution
+of the Y, U, V, A or G, B, R components, depending on input format,
+in current frame. Bellow each graph is color component scale meter.
+
+@item color
+chroma values in vectorscope, if brighter more such chroma values are
+distributed in an image.
+Displays chroma values (U/V color placement) in two dimensional graph
+(which is called a vectorscope). It can be used to read of the hue and
+saturation of the current frame. At a same time it is a histogram.
+The whiter a pixel in the vectorscope, the more pixels of the input frame
+correspond to that pixel (that is the more pixels have this chroma value).
+The V component is displayed on the horizontal (X) axis, with the leftmost
+side being V = 0 and the rightmost side being V = 255.
+The U component is displayed on the vertical (Y) axis, with the top
+representing U = 0 and the bottom representing U = 255.
+
+The position of a white pixel in the graph corresponds to the chroma value
+of a pixel of the input clip. So the graph can be used to read of the
+hue (color flavor) and the saturation (the dominance of the hue in the color).
+As the hue of a color changes, it moves around the square. At the center of
+the square, the saturation is zero, which means that the corresponding pixel
+has no color. If you increase the amount of a specific color, while leaving
+the other colors unchanged, the saturation increases, and you move towards
+the edge of the square.
+
+@item color2
+chroma values in vectorscope, similar as @code{color} but actual chroma values
+are displayed.
+
+@item waveform
+per row/column color component graph. In row mode graph in the left side represents
+color component value 0 and right side represents value = 255. In column mode top
+side represents color component value = 0 and bottom side represents value = 255.
+@end table
+Default value is @code{levels}.
+
+@item level_height
+Set height of level in @code{levels}. Default value is @code{200}.
+Allowed range is [50, 2048].
+
+@item scale_height
+Set height of color scale in @code{levels}. Default value is @code{12}.
+Allowed range is [0, 40].
+
+@item step
+Set step for @code{waveform} mode. Smaller values are useful to find out how much
+of same luminance values across input rows/columns are distributed.
+Default value is @code{10}. Allowed range is [1, 255].
+
+@item waveform_mode
+Set mode for @code{waveform}. Can be either @code{row}, or @code{column}.
+Default is @code{row}.
+
+@item display_mode
+Set display mode for @code{waveform} and @code{levels}.
+It accepts the following values:
+@table @samp
+@item parade
+Display separate graph for the color components side by side in
+@code{row} waveform mode or one below other in @code{column} waveform mode
+for @code{waveform} histogram mode. For @code{levels} histogram mode
+per color component graphs are placed one bellow other.
+
+This display mode in @code{waveform} histogram mode makes it easy to spot
+color casts in the highlights and shadows of an image, by comparing the
+contours of the top and the bottom of each waveform.
+Since whites, grays, and blacks are characterized by
+exactly equal amounts of red, green, and blue, neutral areas of the
+picture should display three waveforms of roughly equal width/height.
+If not, the correction is easy to make by making adjustments to level the
+three waveforms.
+
+@item overlay
+Presents information that's identical to that in the @code{parade}, except
+that the graphs representing color components are superimposed directly
+over one another.
+
+This display mode in @code{waveform} histogram mode can make it easier to spot
+the relative differences or similarities in overlapping areas of the color
+components that are supposed to be identical, such as neutral whites, grays,
+or blacks.
+@end table
+Default is @code{parade}.
+@end table
+
+@subsection Examples
+
+@itemize
+
+@item
+Calculate and draw histogram:
+@example
+ffplay -i input -vf histogram
+@end example
+
+@end itemize
+
 @section hqdn3d
 
 High precision/quality 3d denoise filter. This filter aims to reduce
@@ -2704,8 +3493,105 @@
 
 @section idet
 
-Interlaceing detect filter. This filter tries to detect if the input is
-interlaced or progressive. Top or bottom field first.
+Detect video interlacing type.
+
+This filter tries to detect if the input is interlaced or progressive,
+top or bottom field first.
+
+@section il
+
+Deinterleave or interleave fields.
+
+This filter allows to process interlaced images fields without
+deinterlacing them. Deinterleaving splits the input frame into 2
+fields (so called half pictures). Odd lines are moved to the top
+half of the output image, even lines to the bottom half.
+You can process (filter) them independently and then re-interleave them.
+
+It accepts a list of options in the form of @var{key}=@var{value} pairs
+separated by ":". A description of the accepted options follows.
+
+@table @option
+@item luma_mode, l
+@item chroma_mode, s
+@item alpha_mode, a
+Available values for @var{luma_mode}, @var{chroma_mode} and
+@var{alpha_mode} are:
+
+@table @samp
+@item none
+Do nothing.
+
+@item deinterleave, d
+Deinterleave fields, placing one above the other.
+
+@item interleave, i
+Interleave fields. Reverse the effect of deinterleaving.
+@end table
+Default value is @code{none}.
+
+@item luma_swap, ls
+@item chroma_swap, cs
+@item alpha_swap, as
+Swap luma/chroma/alpha fields. Exchange even & odd lines. Default value is @code{0}.
+@end table
+
+@section kerndeint
+
+Deinterlace input video by applying Donald Graft's adaptive kernel
+deinterling. Work on interlaced parts of a video to produce
+progressive frames.
+
+This filter accepts parameters as a list of @var{key}=@var{value}
+pairs, separated by ":". If the key of the first options is omitted,
+the arguments are interpreted according to the following syntax:
+@var{thresh}:@var{map}:@var{order}:@var{sharp}:@var{twoway}.
+
+The description of the accepted parameters follows.
+
+@table @option
+@item thresh
+Set the threshold which affects the filter's tolerance when
+determining if a pixel line must be processed. It must be an integer
+in the range [0,255] and defaults to 10. A value of 0 will result in
+applying the process on every pixels.
+
+@item map
+Paint pixels exceeding the threshold value to white if set to 1.
+Default is 0.
+
+@item order
+Set the fields order. Swap fields if set to 1, leave fields alone if
+0. Default is 0.
+
+@item sharp
+Enable additional sharpening if set to 1. Default is 0.
+
+@item twoway
+Enable twoway sharpening if set to 1. Default is 0.
+@end table
+
+@subsection Examples
+
+@itemize
+@item
+Apply default values:
+@example
+kerndeint=thresh=10:map=0:order=0:sharp=0:twoway=0
+@end example
+
+@item
+Enable additional sharpening:
+@example
+kerndeint=sharp=1
+@end example
+
+@item
+Paint processed pixels in white:
+@example
+kerndeint=map=1
+@end example
+@end itemize
 
 @section lut, lutrgb, lutyuv
 
@@ -2722,10 +3608,14 @@
 The @var{lut} filter requires either YUV or RGB pixel formats in
 input, and accepts the options:
 @table @option
-@item @var{c0} (first  pixel component)
-@item @var{c1} (second pixel component)
-@item @var{c2} (third  pixel component)
-@item @var{c3} (fourth pixel component, corresponds to the alpha component)
+@item c0
+set first pixel component expression
+@item c1
+set second pixel component expression
+@item c2
+set third pixel component expression
+@item c3
+set fourth pixel component expression, corresponds to the alpha component
 @end table
 
 The exact component associated to each option depends on the format in
@@ -2734,19 +3624,27 @@
 The @var{lutrgb} filter requires RGB pixel formats in input, and
 accepts the options:
 @table @option
-@item @var{r} (red component)
-@item @var{g} (green component)
-@item @var{b} (blue component)
-@item @var{a} (alpha component)
+@item r
+set red component expression
+@item g
+set green component expression
+@item b
+set blue component expression
+@item a
+alpha component expression
 @end table
 
 The @var{lutyuv} filter requires YUV pixel formats in input, and
 accepts the options:
 @table @option
-@item @var{y} (Y/luminance component)
-@item @var{u} (U/Cb component)
-@item @var{v} (V/Cr component)
-@item @var{a} (alpha component)
+@item y
+set Y/luminance component expression
+@item u
+set U/Cb component expression
+@item v
+set V/Cr component expression
+@item a
+set alpha component expression
 @end table
 
 The expressions can contain the following constants and functions:
@@ -2786,34 +3684,58 @@
 
 All expressions default to "val".
 
-Some examples follow:
+@subsection Examples
+
+@itemize
+@item
+Negate input video:
 @example
-# negate input video
 lutrgb="r=maxval+minval-val:g=maxval+minval-val:b=maxval+minval-val"
 lutyuv="y=maxval+minval-val:u=maxval+minval-val:v=maxval+minval-val"
+@end example
 
-# the above is the same as
+The above is the same as:
+@example
 lutrgb="r=negval:g=negval:b=negval"
 lutyuv="y=negval:u=negval:v=negval"
+@end example
 
-# negate luminance
+@item
+Negate luminance:
+@example
 lutyuv=y=negval
+@end example
 
-# remove chroma components, turns the video into a graytone image
+@item
+Remove chroma components, turns the video into a graytone image:
+@example
 lutyuv="u=128:v=128"
+@end example
 
-# apply a luma burning effect
+@item
+Apply a luma burning effect:
+@example
 lutyuv="y=2*val"
+@end example
 
-# remove green and blue components
+@item
+Remove green and blue components:
+@example
 lutrgb="g=0:b=0"
+@end example
 
-# set a constant alpha channel value on input
+@item
+Set a constant alpha channel value on input:
+@example
 format=rgba,lutrgb=a="maxval-minval/2"
+@end example
 
-# correct luminance gamma by a 0.5 factor
+@item
+Correct luminance gamma by a 0.5 factor:
+@example
 lutyuv=y=gammaval(0.5)
 @end example
+@end itemize
 
 @section mp
 
@@ -2836,23 +3758,18 @@
 
 The list of the currently supported filters follows:
 @table @var
-@item denoise3d
 @item detc
 @item dint
 @item divtc
 @item down3dright
-@item dsize
 @item eq2
 @item eq
 @item fil
 @item fspp
 @item harddup
-@item il
 @item ilpack
 @item ivtc
-@item kerndeint
 @item mcdeint
-@item noise
 @item ow
 @item perspective
 @item phase
@@ -2861,11 +3778,9 @@
 @item qp
 @item sab
 @item softpulldown
-@item softskip
 @item spp
 @item telecine
 @item tinterlace
-@item unsharp
 @item uspp
 @end table
 
@@ -2880,12 +3795,6 @@
 @example
 mp=eq2=1.0:2:0.5
 @end example
-
-@item
-Add temporal noise to input video:
-@example
-mp=noise=20t
-@end example
 @end itemize
 
 See also mplayer(1), @url{http://www.mplayerhq.hu/}.
@@ -2915,6 +3824,57 @@
 noformat=yuv420p:yuv444p:yuv410p
 @end example
 
+@section noise
+
+Add noise on video input frame.
+
+This filter accepts a list of options in the form of @var{key}=@var{value}
+pairs separated by ":". A description of the accepted options follows.
+
+@table @option
+@item all_seed
+@item c0_seed
+@item c1_seed
+@item c2_seed
+@item c3_seed
+Set noise seed for specific pixel component or all pixel components in case
+of @var{all_seed}. Default value is @code{123457}.
+
+@item all_strength, as
+@item c0_strength, c0s
+@item c1_strength, c1s
+@item c2_strength, c2s
+@item c3_strength, c3s
+Set noise strength for specific pixel component or all pixel components in case
+@var{all_strength}. Default value is @code{0}. Allowed range is [0, 100].
+
+@item all_flags, af
+@item c0_flags, c0f
+@item c1_flags, c1f
+@item c2_flags, c2f
+@item c3_flags, c3f
+Set pixel component flags or set flags for all components if @var{all_flags}.
+Available values for component flags are:
+@table @samp
+@item a
+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
+uniform noise (gaussian otherwise)
+@end table
+@end table
+
+Some examples follow:
+@example
+Add temporal and uniform noise to input video:
+noise=alls=20:allf=t+u
+@end example
+
 @section null
 
 Pass the video source unchanged to the output.
@@ -3024,13 +3984,20 @@
 It takes two inputs and one output, the first input is the "main"
 video on which the second input is overlayed.
 
-It accepts the parameters: @var{x}:@var{y}[:@var{options}].
+This filter accepts a list of @var{key}=@var{value} pairs as argument,
+separated by ":". If the key of the first options is omitted, the
+arguments are interpreted according to the syntax @var{x}:@var{y}.
 
-@var{x} is the x coordinate of the overlayed video on the main video,
-@var{y} is the y coordinate. @var{x} and @var{y} are expressions containing
-the following parameters:
+A description of the accepted options follows.
 
 @table @option
+@item x, y
+Set the expression for the x and y coordinates of the overlayed video
+on the main video. Default value is 0.
+
+The @var{x} and @var{y} expressions can contain the following
+parameters:
+@table @option
 @item main_w, main_h
 main input width and height
 
@@ -3044,15 +4011,31 @@
 same as @var{overlay_w} and @var{overlay_h}
 @end table
 
-@var{options} is an optional list of @var{key}=@var{value} pairs,
-separated by ":".
+@item format
+Set the format for the output video.
 
-The description of the accepted options follows.
+It accepts the following values:
+@table @samp
+@item yuv420
+force YUV420 output
 
-@table @option
+@item yuv444
+force YUV444 output
+
 @item rgb
+force RGB output
+@end table
+
+Default value is @samp{yuv420}.
+
+@item rgb @emph{(deprecated)}
 If set to 1, force the filter to accept inputs in the RGB
-color space. Default value is 0.
+color space. Default value is 0. This option is deprecated, use
+@option{format} instead.
+
+@item shortest
+If set to 1, force the output to terminate when the shortest input
+terminates. Default value is 0.
 @end table
 
 Be aware that frames are taken from each input video in timestamp
@@ -3061,45 +4044,128 @@
 have them begin in the same zero timestamp, as it does the example for
 the @var{movie} filter.
 
-Follow some examples:
+You can chain together more overlays but you should test the
+efficiency of such approach.
+
+@subsection Examples
+
+@itemize
+@item
+Draw the overlay at 10 pixels from the bottom right corner of the main
+video:
 @example
-# draw the overlay at 10 pixels from the bottom right
-# corner of the main video.
 overlay=main_w-overlay_w-10:main_h-overlay_h-10
+@end example
 
-# insert a transparent PNG logo in the bottom left corner of the input
+Using named options the example above becomes:
+@example
+overlay=x=main_w-overlay_w-10:y=main_h-overlay_h-10
+@end example
+
+@item
+Insert a transparent PNG logo in the bottom left corner of the input,
+using the @command{ffmpeg} tool with the @code{-filter_complex} option:
+@example
 ffmpeg -i input -i logo -filter_complex 'overlay=10:main_h-overlay_h-10' output
+@end example
 
-# insert 2 different transparent PNG logos (second logo on bottom
-# right corner):
-ffmpeg -i input -i logo1 -i logo2 -filter_complex
-'overlay=10:H-h-10,overlay=W-w-10:H-h-10' output
+@item
+Insert 2 different transparent PNG logos (second logo on bottom
+right corner) using the @command{ffmpeg} tool:
+@example
+ffmpeg -i input -i logo1 -i logo2 -filter_complex 'overlay=10:H-h-10,overlay=W-w-10:H-h-10' output
+@end example
 
-# add a transparent color layer on top of the main video,
-# WxH specifies the size of the main input to the overlay filter
+@item
+Add a transparent color layer on top of the main video, WxH specifies
+the size of the main input to the overlay filter:
+@example
 color=red@@.3:WxH [over]; [in][over] overlay [out]
+@end example
 
-# play an original video and a filtered version (here with the deshake filter)
-# side by side
+@item
+Play an original video and a filtered version (here with the deshake
+filter) side by side using the @command{ffplay} tool:
+@example
 ffplay input.avi -vf 'split[a][b]; [a]pad=iw*2:ih[src]; [b]deshake[filt]; [src][filt]overlay=w'
+@end example
 
-# the previous example is the same as:
+The above command is the same as:
+@example
 ffplay input.avi -vf 'split[b], pad=iw*2[src], [b]deshake, [src]overlay=w'
 @end example
 
-You can chain together more overlays but the efficiency of such
-approach is yet to be tested.
+@item
+Compose output by putting two input videos side to side:
+@example
+ffmpeg -i left.avi -i right.avi -filter_complex "
+nullsrc=size=200x100 [background];
+[0:v] setpts=PTS-STARTPTS, scale=100x100 [left];
+[1:v] setpts=PTS-STARTPTS, scale=100x100 [right];
+[background][left]       overlay=shortest=1       [background+left];
+[background+left][right] overlay=shortest=1:x=100 [left+right]
+"
+@end example
+
+@item
+Chain several overlays in cascade:
+@example
+nullsrc=s=200x200 [bg];
+testsrc=s=100x100, split=4 [in0][in1][in2][in3];
+[in0] lutrgb=r=0, [bg]   overlay=0:0     [mid0];
+[in1] lutrgb=g=0, [mid0] overlay=100:0   [mid1];
+[in2] lutrgb=b=0, [mid1] overlay=0:100   [mid2];
+[in3] null,       [mid2] overlay=100:100 [out0]
+@end example
+
+@end itemize
 
 @section pad
 
-Add paddings to the input image, and places the original input at the
+Add paddings to the input image, and place the original input at the
 given coordinates @var{x}, @var{y}.
 
-It accepts the following parameters:
+The filter accepts parameters as a list of @var{key}=@var{value} pairs,
+separated by ":".
+
+If the key of the first options is omitted, the arguments are
+interpreted according to the syntax
 @var{width}:@var{height}:@var{x}:@var{y}:@var{color}.
 
-The parameters @var{width}, @var{height}, @var{x}, and @var{y} are
-expressions containing the following constants:
+A description of the accepted options follows.
+
+@table @option
+@item width, w
+@item height, h
+Specify an expression for the size of the output image with the
+paddings added. If the value for @var{width} or @var{height} is 0, the
+corresponding input size is used for the output.
+
+The @var{width} expression can reference the value set by the
+@var{height} expression, and vice versa.
+
+The default value of @var{width} and @var{height} is 0.
+
+@item x
+@item y
+Specify an expression for the offsets where to place the input image
+in the padded area with respect to the top/left border of the output
+image.
+
+The @var{x} expression can reference the value set by the @var{y}
+expression, and vice versa.
+
+The default value of @var{x} and @var{y} is 0.
+
+@item color
+Specify the color of the padded 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
+
+The value for the @var{width}, @var{height}, @var{x}, and @var{y}
+options are expressions containing the following constants:
 
 @table @option
 @item in_w, in_h
@@ -3133,39 +4199,6 @@
 pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1.
 @end table
 
-Follows the description of the accepted parameters.
-
-@table @option
-@item width, height
-
-Specify the size of the output image with the paddings added. If the
-value for @var{width} or @var{height} is 0, the corresponding input size
-is used for the output.
-
-The @var{width} expression can reference the value set by the
-@var{height} expression, and vice versa.
-
-The default value of @var{width} and @var{height} is 0.
-
-@item x, y
-
-Specify the offsets where to place the input image in the padded area
-with respect to the top/left border of the output image.
-
-The @var{x} expression can reference the value set by the @var{y}
-expression, and vice versa.
-
-The default value of @var{x} and @var{y} is 0.
-
-@item color
-
-Specify the color of the padded 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
 
 @itemize
@@ -3177,6 +4210,11 @@
 pad=640:480:0:40:violet
 @end example
 
+The example above is equivalent to the following command:
+@example
+pad=width=640:height=480:x=0:y=40:color=violet
+@end example
+
 @item
 Pad the input to get an output with dimensions increased by 3/2,
 and put the input video at the center of the padded area:
@@ -3232,6 +4270,174 @@
 
 can be used to test the monowhite pixel format descriptor definition.
 
+@section pp
+
+Enable the specified chain of postprocessing subfilters using libpostproc. This
+library should be automatically selected with a GPL build (@code{--enable-gpl}).
+Subfilters must be separated by '/' and can be disabled by prepending a '-'.
+Each subfilter and some options have a short and a long name that can be used
+interchangeably, i.e. dr/dering are the same.
+
+All subfilters share common options to determine their scope:
+
+@table @option
+@item a/autoq
+Honor the quality commands for this subfilter.
+
+@item c/chrom
+Do chrominance filtering, too (default).
+
+@item y/nochrom
+Do luminance filtering only (no chrominance).
+
+@item n/noluma
+Do chrominance filtering only (no luminance).
+@end table
+
+These options can be appended after the subfilter name, separated by a ':'.
+
+Available subfilters are:
+
+@table @option
+@item hb/hdeblock[:difference[:flatness]]
+Horizontal deblocking filter
+@table @option
+@item difference
+Difference factor where higher values mean more deblocking (default: @code{32}).
+@item flatness
+Flatness threshold where lower values mean more deblocking (default: @code{39}).
+@end table
+
+@item vb/vdeblock[:difference[:flatness]]
+Vertical deblocking filter
+@table @option
+@item difference
+Difference factor where higher values mean more deblocking (default: @code{32}).
+@item flatness
+Flatness threshold where lower values mean more deblocking (default: @code{39}).
+@end table
+
+@item ha/hadeblock[:difference[:flatness]]
+Accurate horizontal deblocking filter
+@table @option
+@item difference
+Difference factor where higher values mean more deblocking (default: @code{32}).
+@item flatness
+Flatness threshold where lower values mean more deblocking (default: @code{39}).
+@end table
+
+@item va/vadeblock[:difference[:flatness]]
+Accurate vertical deblocking filter
+@table @option
+@item difference
+Difference factor where higher values mean more deblocking (default: @code{32}).
+@item flatness
+Flatness threshold where lower values mean more deblocking (default: @code{39}).
+@end table
+@end table
+
+The horizontal and vertical deblocking filters share the difference and
+flatness values so you cannot set different horizontal and vertical
+thresholds.
+
+@table @option
+@item h1/x1hdeblock
+Experimental horizontal deblocking filter
+
+@item v1/x1vdeblock
+Experimental vertical deblocking filter
+
+@item dr/dering
+Deringing filter
+
+@item tn/tmpnoise[:threshold1[:threshold2[:threshold3]]], temporal noise reducer
+@table @option
+@item threshold1
+larger -> stronger filtering
+@item threshold2
+larger -> stronger filtering
+@item threshold3
+larger -> stronger filtering
+@end table
+
+@item al/autolevels[:f/fullyrange], automatic brightness / contrast correction
+@table @option
+@item f/fullyrange
+Stretch luminance to @code{0-255}.
+@end table
+
+@item lb/linblenddeint
+Linear blend deinterlacing filter that deinterlaces the given block by
+filtering all lines with a @code{(1 2 1)} filter.
+
+@item li/linipoldeint
+Linear interpolating deinterlacing filter that deinterlaces the given block by
+linearly interpolating every second line.
+
+@item ci/cubicipoldeint
+Cubic interpolating deinterlacing filter deinterlaces the given block by
+cubically interpolating every second line.
+
+@item md/mediandeint
+Median deinterlacing filter that deinterlaces the given block by applying a
+median filter to every second line.
+
+@item fd/ffmpegdeint
+FFmpeg deinterlacing filter that deinterlaces the given block by filtering every
+second line with a @code{(-1 4 2 4 -1)} filter.
+
+@item l5/lowpass5
+Vertically applied FIR lowpass deinterlacing filter that deinterlaces the given
+block by filtering all lines with a @code{(-1 2 6 2 -1)} filter.
+
+@item fq/forceQuant[:quantizer]
+Overrides the quantizer table from the input with the constant quantizer you
+specify.
+@table @option
+@item quantizer
+Quantizer to use
+@end table
+
+@item de/default
+Default pp filter combination (@code{hb:a,vb:a,dr:a})
+
+@item fa/fast
+Fast pp filter combination (@code{h1:a,v1:a,dr:a})
+
+@item ac
+High quality pp filter combination (@code{ha:a:128:7,va:a,dr:a})
+@end table
+
+@subsection Examples
+
+@itemize
+@item
+Apply horizontal and vertical deblocking, deringing and automatic
+brightness/contrast:
+@example
+pp=hb/vb/dr/al
+@end example
+
+@item
+Apply default filters without brightness/contrast correction:
+@example
+pp=de/-al
+@end example
+
+@item
+Apply default filters and temporal denoiser:
+@example
+pp=default/tmpnoise:1:2:3
+@end example
+
+@item
+Apply deblocking on luminance only, and switch vertical deblocking on or off
+automatically depending on available CPU time:
+@example
+pp=hb:y/vb:a
+@end example
+@end itemize
+
 @section removelogo
 
 Suppress a TV station logo, using an image file to determine which
@@ -3437,128 +4643,6 @@
 @end example
 @end itemize
 
-@section select
-Select frames to pass in output.
-
-It accepts in input an expression, which is evaluated for each input
-frame. If the expression is evaluated to a non-zero value, the frame
-is selected and passed to the output, otherwise it is discarded.
-
-The expression can contain the following constants:
-
-@table @option
-@item n
-the sequential number of the filtered frame, starting from 0
-
-@item selected_n
-the sequential number of the selected frame, starting from 0
-
-@item prev_selected_n
-the sequential number of the last selected frame, NAN if undefined
-
-@item TB
-timebase of the input timestamps
-
-@item pts
-the PTS (Presentation TimeStamp) of the filtered video frame,
-expressed in @var{TB} units, NAN if undefined
-
-@item t
-the PTS (Presentation TimeStamp) of the filtered video frame,
-expressed in seconds, NAN if undefined
-
-@item prev_pts
-the PTS of the previously filtered video frame, NAN if undefined
-
-@item prev_selected_pts
-the PTS of the last previously filtered video frame, NAN if undefined
-
-@item prev_selected_t
-the PTS of the last previously selected video frame, NAN if undefined
-
-@item start_pts
-the PTS of the first video frame in the video, NAN if undefined
-
-@item start_t
-the time of the first video frame in the video, NAN if undefined
-
-@item pict_type
-the type of the filtered frame, can assume one of the following
-values:
-@table @option
-@item I
-@item P
-@item B
-@item S
-@item SI
-@item SP
-@item BI
-@end table
-
-@item interlace_type
-the frame interlace type, can assume one of the following values:
-@table @option
-@item PROGRESSIVE
-the frame is progressive (not interlaced)
-@item TOPFIRST
-the frame is top-field-first
-@item BOTTOMFIRST
-the frame is bottom-field-first
-@end table
-
-@item key
-1 if the filtered frame is a key-frame, 0 otherwise
-
-@item pos
-the position in the file of the filtered frame, -1 if the information
-is not available (e.g. for synthetic video)
-
-@item scene
-value between 0 and 1 to indicate a new scene; a low value reflects a low
-probability for the current frame to introduce a new scene, while a higher
-value means the current frame is more likely to be one (see the example below)
-
-@end table
-
-The default value of the select expression is "1".
-
-Some examples follow:
-
-@example
-# select all frames in input
-select
-
-# the above is the same as:
-select=1
-
-# skip all frames:
-select=0
-
-# select only I-frames
-select='eq(pict_type\,I)'
-
-# select one frame every 100
-select='not(mod(n\,100))'
-
-# select only frames contained in the 10-20 time interval
-select='gte(t\,10)*lte(t\,20)'
-
-# select only I frames contained in the 10-20 time interval
-select='gte(t\,10)*lte(t\,20)*eq(pict_type\,I)'
-
-# select frames with a minimum distance of 10 seconds
-select='isnan(prev_selected_t)+gte(t-prev_selected_t\,10)'
-@end example
-
-Complete example to create a mosaic of the first scenes:
-
-@example
-ffmpeg -i video.avi -vf select='gt(scene\,0.4)',scale=160:120,tile -frames:v 1 preview.png
-@end example
-
-Comparing @var{scene} against a value between 0.3 and 0.5 is generally a sane
-choice.
-
 @section setdar, setsar
 
 The @code{setdar} filter sets the Display Aspect Ratio for the filter
@@ -3642,7 +4726,10 @@
 corresponding property, which affects how the frame is treated by
 following filters (e.g. @code{fieldorder} or @code{yadif}).
 
-It accepts a string parameter, which can assume the following values:
+This filter accepts a single option @option{mode}, which can be
+specified either by setting @code{mode=VALUE} or setting the value
+alone. Available values are:
+
 @table @samp
 @item auto
 Keep the same field property.
@@ -3745,6 +4832,47 @@
 image, a value included in [0,30] will filter flat areas and a value
 included in [-30,0] will filter edges.
 
+@anchor{subtitles}
+@section subtitles
+
+Draw subtitles on top of input video using the libass library.
+
+To enable compilation of this filter you need to configure FFmpeg with
+@code{--enable-libass}. This filter also requires a build with libavcodec and
+libavformat to convert the passed subtitles file to ASS (Advanced Substation
+Alpha) subtitles format.
+
+This filter accepts the following named options, expressed as a
+sequence of @var{key}=@var{value} pairs, separated by ":".
+
+@table @option
+@item filename, f
+Set the filename of the subtitle file to read. It must be specified.
+
+@item original_size
+Specify the size of the original video, the video for which the ASS file
+was composed. Due to a misdesign in ASS aspect ratio arithmetic, this is
+necessary to correctly scale the fonts if the aspect ratio has been changed.
+
+@item charenc
+Set subtitles input character encoding. @code{subtitles} filter only. Only
+useful if not UTF-8.
+@end table
+
+If the first key is not specified, it is assumed that the first value
+specifies the @option{filename}.
+
+For example, to render the file @file{sub.srt} on top of the input
+video, use the command:
+@example
+subtitles=sub.srt
+@end example
+
+which is equivalent to:
+@example
+subtitles=filename=sub.srt
+@end example
+
 @section split
 
 Split input video into several identical outputs.
@@ -3830,7 +4958,7 @@
 
 @var{layout}[:@var{nb_frames}[:@var{margin}[:@var{padding}]]]
 
-For example, produce 8×8 PNG tiles of all keyframes (@option{-skip_frame
+For example, produce 8x8 PNG tiles of all keyframes (@option{-skip_frame
 nokey}) in a movie:
 @example
 ffmpeg -skip_frame nokey -i file.avi -vf 'scale=128:72,tile=8x8' -an -vsync 0 keyframes%03d.png
@@ -3853,8 +4981,21 @@
 Frames are counted starting from 1, so the first input frame is
 considered odd.
 
-This filter accepts a single parameter specifying the mode. Available
-modes are:
+This filter accepts options in the form of @var{key}=@var{value} pairs
+separated by ":".
+Alternatively, the @var{mode} option can be specified as a value alone,
+optionally followed by a ":" and further ":" separated @var{key}=@var{value}
+pairs.
+
+A description of the accepted options follows.
+
+@table @option
+
+@item mode
+Specify the mode of the interlacing. This option can also be specified
+as a value alone. See below for a list of values for this option.
+
+Available values are:
 
 @table @samp
 @item merge, 0
@@ -3894,11 +5035,33 @@
 
 Default mode is @code{merge}.
 
+@item flags
+Specify flags influencing the filter process.
+
+Available value for @var{flags} is:
+
+@table @option
+@item low_pass_filter, vlfp
+Enable vertical low-pass filtering in the filter.
+Vertical low-pass filtering is required when creating an interlaced
+destination from a progressive source which contains high-frequency
+vertical detail. Filtering will reduce interlace 'twitter' and Moire
+patterning.
+
+Vertical low-pass filtering can only be enabled for @option{mode}
+@var{interleave_top} and @var{interleave_bottom}.
+
+@end table
+@end table
+
 @section transpose
 
 Transpose rows with columns in the input video and optionally flip it.
 
-This filter accepts the following named parameters:
+The filter accepts parameters as a list of @var{key}=@var{value}
+pairs, separated by ':'. If the key of the first options is omitted,
+the arguments are interpreted according to the syntax
+@var{dir}:@var{passthrough}.
 
 @table @option
 @item dir
@@ -3957,56 +5120,68 @@
 Default value is @code{none}.
 @end table
 
+For example to rotate by 90 degrees clockwise and preserve portrait
+layout:
+@example
+transpose=dir=1:passthrough=portrait
+@end example
+
+The command above can also be specified as:
+@example
+transpose=1:portrait
+@end example
+
 @section unsharp
 
 Sharpen or blur the input video.
 
-It accepts the following parameters:
+This filter accepts parameters as a list of @var{key}=@var{value} pairs,
+separated by ":".
+
+If the key of the first options is omitted, the arguments are
+interpreted according to the syntax:
 @var{luma_msize_x}:@var{luma_msize_y}:@var{luma_amount}:@var{chroma_msize_x}:@var{chroma_msize_y}:@var{chroma_amount}
 
-Negative values for the amount will blur the input video, while positive
-values will sharpen. All parameters are optional and default to the
-equivalent of the string '5:5:1.0:5:5:0.0'.
+A description of the accepted options follows.
 
 @table @option
+@item luma_msize_x, lx
+@item chroma_msize_x, cx
+Set the luma/chroma matrix horizontal size. It must be an odd integer
+between 3 and 63, default value is 5.
 
-@item luma_msize_x
-Set the luma matrix horizontal size. It can be an integer between 3
-and 13, default value is 5.
+@item luma_msize_y, ly
+@item chroma_msize_y, cy
+Set the luma/chroma matrix vertical size. It must be an odd integer
+between 3 and 63, default value is 5.
 
-@item luma_msize_y
-Set the luma matrix vertical size. It can be an integer between 3
-and 13, default value is 5.
+@item luma_amount, la
+@item chroma_amount, ca
+Set the luma/chroma effect strength. It can be a float number,
+reasonable values lay between -1.5 and 1.5.
 
-@item luma_amount
-Set the luma effect strength. It can be a float number between -2.0
-and 5.0, default value is 1.0.
+Negative values will blur the input video, while positive values will
+sharpen it, a value of zero will disable the effect.
 
-@item chroma_msize_x
-Set the chroma matrix horizontal size. It can be an integer between 3
-and 13, default value is 5.
-
-@item chroma_msize_y
-Set the chroma matrix vertical size. It can be an integer between 3
-and 13, default value is 5.
-
-@item chroma_amount
-Set the chroma effect strength. It can be a float number between -2.0
-and 5.0, default value is 0.0.
-
+Default value is 1.0 for @option{luma_amount}, 0.0 for
+@option{chroma_amount}.
 @end table
 
+Some examples follow:
+@itemize
+@item
+Apply strong luma sharpen effect:
 @example
-# Strong luma sharpen effect parameters
 unsharp=7:7:2.5
-
-# Strong blur of both luma and chroma parameters
-unsharp=7:7:-2:7:7:-2
-
-# Use the default values with @command{ffmpeg}
-ffmpeg -i in.avi -vf "unsharp" out.mp4
 @end example
 
+@item
+Apply strong blur of both luma and chroma parameters:
+@example
+unsharp=7:7:-2:7:7:-2
+@end example
+@end itemize
+
 @section vflip
 
 Flip the input video vertically.
@@ -4020,51 +5195,61 @@
 Deinterlace the input video ("yadif" means "yet another deinterlacing
 filter").
 
-It accepts the optional parameters: @var{mode}:@var{parity}:@var{auto}.
+The filter accepts parameters as a list of @var{key}=@var{value}
+pairs, separated by ":". If the key of the first options is omitted,
+the arguments are interpreted according to syntax
+@var{mode}:@var{parity}:@var{deint}.
 
-@var{mode} specifies the interlacing mode to adopt, accepts one of the
-following values:
+The description of the accepted parameters follows.
 
 @table @option
-@item 0
+@item mode
+Specify the interlacing mode to adopt. Accept one of the following
+values:
+
+@table @option
+@item 0, send_frame
 output 1 frame for each frame
-@item 1
+@item 1, send_field
 output 1 frame for each field
-@item 2
-like 0 but skips spatial interlacing check
-@item 3
-like 1 but skips spatial interlacing check
+@item 2, send_frame_nospatial
+like @code{send_frame} but skip spatial interlacing check
+@item 3, send_field_nospatial
+like @code{send_field} but skip spatial interlacing check
 @end table
 
-Default value is 0.
+Default value is @code{send_frame}.
 
-@var{parity} specifies the picture field parity assumed for the input
-interlaced video, accepts one of the following values:
+@item parity
+Specify the picture field parity assumed for the input interlaced
+video. Accept one of the following values:
 
 @table @option
-@item 0
+@item 0, tff
 assume top field first
-@item 1
+@item 1, bff
 assume bottom field first
-@item -1
+@item -1, auto
 enable automatic detection
 @end table
 
-Default value is -1.
+Default value is @code{auto}.
 If interlacing is unknown or decoder does not export this information,
 top field first will be assumed.
 
-@var{auto} specifies if deinterlacer should trust the interlaced flag
-and only deinterlace frames marked as interlaced
+@item deint
+Specify which frames to deinterlace. Accept one of the following
+values:
 
 @table @option
-@item 0
+@item 0, all
 deinterlace all frames
-@item 1
+@item 1, interlaced
 only deinterlace frames marked as interlaced
 @end table
 
-Default value is 0.
+Default value is @code{all}.
+@end table
 
 @c man end VIDEO FILTERS
 
@@ -4646,6 +5831,171 @@
 
 Below is a description of the currently available multimedia filters.
 
+@section aselect, select
+Select frames to pass in output.
+
+These filters accept a single option @option{expr} or @option{e}
+specifying the select expression, which can be specified either by
+specyfing @code{expr=VALUE} or specifying the expression
+alone.
+
+The select expression is evaluated for each input frame. If the
+evaluation result is a non-zero value, the frame is selected and
+passed to the output, otherwise it is discarded.
+
+The expression can contain the following constants:
+
+@table @option
+@item n
+the sequential number of the filtered frame, starting from 0
+
+@item selected_n
+the sequential number of the selected frame, starting from 0
+
+@item prev_selected_n
+the sequential number of the last selected frame, NAN if undefined
+
+@item TB
+timebase of the input timestamps
+
+@item pts
+the PTS (Presentation TimeStamp) of the filtered video frame,
+expressed in @var{TB} units, NAN if undefined
+
+@item t
+the PTS (Presentation TimeStamp) of the filtered video frame,
+expressed in seconds, NAN if undefined
+
+@item prev_pts
+the PTS of the previously filtered video frame, NAN if undefined
+
+@item prev_selected_pts
+the PTS of the last previously filtered video frame, NAN if undefined
+
+@item prev_selected_t
+the PTS of the last previously selected video frame, NAN if undefined
+
+@item start_pts
+the PTS of the first video frame in the video, NAN if undefined
+
+@item start_t
+the time of the first video frame in the video, NAN if undefined
+
+@item pict_type @emph{(video only)}
+the type of the filtered frame, can assume one of the following
+values:
+@table @option
+@item I
+@item P
+@item B
+@item S
+@item SI
+@item SP
+@item BI
+@end table
+
+@item interlace_type @emph{(video only)}
+the frame interlace type, can assume one of the following values:
+@table @option
+@item PROGRESSIVE
+the frame is progressive (not interlaced)
+@item TOPFIRST
+the frame is top-field-first
+@item BOTTOMFIRST
+the frame is bottom-field-first
+@end table
+
+@item consumed_sample_n @emph{(audio only)}
+the number of selected samples before the current frame
+
+@item samples_n @emph{(audio only)}
+the number of samples in the current frame
+
+@item sample_rate @emph{(audio only)}
+the input sample rate
+
+@item key
+1 if the filtered frame is a key-frame, 0 otherwise
+
+@item pos
+the position in the file of the filtered frame, -1 if the information
+is not available (e.g. for synthetic video)
+
+@item scene @emph{(video only)}
+value between 0 and 1 to indicate a new scene; a low value reflects a low
+probability for the current frame to introduce a new scene, while a higher
+value means the current frame is more likely to be one (see the example below)
+
+@end table
+
+The default value of the select expression is "1".
+
+@subsection Examples
+
+@itemize
+@item
+Select all frames in input:
+@example
+select
+@end example
+
+The example above is the same as:
+@example
+select=1
+@end example
+
+@item
+Skip all frames:
+@example
+select=0
+@end example
+
+@item
+Select only I-frames:
+@example
+select='eq(pict_type\,I)'
+@end example
+
+@item
+Select one frame every 100:
+@example
+select='not(mod(n\,100))'
+@end example
+
+@item
+Select only frames contained in the 10-20 time interval:
+@example
+select='gte(t\,10)*lte(t\,20)'
+@end example
+
+@item
+Select only I frames contained in the 10-20 time interval:
+@example
+select='gte(t\,10)*lte(t\,20)*eq(pict_type\,I)'
+@end example
+
+@item
+Select frames with a minimum distance of 10 seconds:
+@example
+select='isnan(prev_selected_t)+gte(t-prev_selected_t\,10)'
+@end example
+
+@item
+Use aselect to select only audio frames with samples number > 100:
+@example
+aselect='gt(samples_n\,100)'
+@end example
+
+@item
+Create a mosaic of the first scenes:
+@example
+ffmpeg -i video.avi -vf select='gt(scene\,0.4)',scale=160:120,tile -frames:v 1 preview.png
+@end example
+
+Comparing @var{scene} against a value between 0.3 and 0.5 is generally a sane
+choice.
+@end itemize
+
 @section asendcmd, sendcmd
 
 Send commands to filters in the filtergraph.
@@ -4777,6 +6127,7 @@
 @end example
 @end itemize
 
+@anchor{setpts}
 @section asetpts, setpts
 
 Change the PTS (presentation timestamp) of the input frames.
@@ -4836,6 +6187,13 @@
 
 @item PREV_OUTT
 previous output time in seconds
+
+@item RTCTIME
+wallclock (RTC) time in microseconds. This is deprecated, use time(0)
+instead.
+
+@item RTCSTART
+wallclock (RTC) time at the start of the movie in microseconds
 @end table
 
 @subsection Examples
@@ -4876,6 +6234,12 @@
 @example
 setpts=PTS+10/TB
 @end example
+
+@item
+Generate timestamps from a "live source" and rebase onto the current timebase:
+@example
+setpts='(RTCTIME - RTCSTART) / (TB * 1000000)'
+@end example
 @end itemize
 
 @section ebur128
@@ -5002,7 +6366,7 @@
 The filter has @var{v}+@var{a} outputs: first @var{v} video outputs, then
 @var{a} audio outputs.
 
-There are @var{n}×(@var{v}+@var{a}) inputs: first the inputs for the first
+There are @var{n}x(@var{v}+@var{a}) inputs: first the inputs for the first
 segment, in the same order as the outputs, then the inputs for the second
 segment, etc.
 
@@ -5057,10 +6421,60 @@
 The filter accepts the following named parameters:
 @table @option
 @item size, s
-Specify the video size for the output. Default value is @code{640x480}.
+Specify the video size for the output. Default value is @code{640x512}.
+
 @item slide
 Specify if the spectrum should slide along the window. Default value is
 @code{0}.
+
+@item mode
+Specify display mode.
+
+It accepts the following values:
+@table @samp
+@item combined
+all channels are displayed in the same row
+@item separate
+all channels are displayed in separate rows
+@end table
+
+Default value is @samp{combined}.
+
+@item color
+Specify display color mode.
+
+It accepts the following values:
+@table @samp
+@item channel
+each channel is displayed in a separate color
+@item intensity
+each channel is is displayed using the same color scheme
+@end table
+
+Default value is @samp{channel}.
+
+@item scale
+Specify scale used for calculating intensity color values.
+
+It accepts the following values:
+@table @samp
+@item lin
+linear
+@item sqrt
+square root, default
+@item cbrt
+cubic root
+@item log
+logarithmic
+@end table
+
+Default value is @samp{sqrt}.
+
+@item saturation
+Set saturation modifier for displayed colors. Negative values provide
+alternative color scheme. @code{0} is no saturation at all.
+Saturation must be in [-10.0, 10.0] range.
+Default value is @code{1}.
 @end table
 
 The usage is very similar to the showwaves filter; see the examples in that
@@ -5072,6 +6486,19 @@
 
 The filter accepts the following named parameters:
 @table @option
+@item mode
+Set display mode.
+
+Available values are:
+@table @samp
+@item point
+Draw a point for each sample.
+
+@item line
+Draw a vertical line for each sample.
+@end table
+
+Default value is @code{point}.
 
 @item n
 Set the number of samples which are printed on the same column. A
@@ -5113,10 +6540,10 @@
 
 @section amovie
 
-This is the same as @ref{src_movie} source, except it selects an audio
+This is the same as @ref{movie} source, except it selects an audio
 stream by default.
 
-@anchor{src_movie}
+@anchor{movie}
 @section movie
 
 Read audio and/or video stream(s) from a movie container.
@@ -5143,12 +6570,12 @@
 postfix. Default value is "0".
 
 @item streams, s
-Specifies the streams to read. Several streams can be specified, separated
-by "+". The source will then have as many outputs, in the same order. The
-syntax is explained in the @ref{Stream specifiers} chapter. Two special
-names, "dv" and "da" specify respectively the default (best suited) video
-and audio stream. Default is "dv", or "da" if the filter is called as
-"amovie".
+Specifies the streams to read. Several streams can be specified,
+separated by "+". The source will then have as many outputs, in the
+same order. The syntax is explained in the ``Stream specifiers''
+section in the ffmpeg manual. Two special names, "dv" and "da" specify
+respectively the default (best suited) video and audio stream. Default
+is "dv", or "da" if the filter is called as "amovie".
 
 @item stream_index, si
 Specifies the index of the video stream to read. If the value is -1,
diff --git a/doc/general.texi b/doc/general.texi
index 5698106..39b9360 100644
--- a/doc/general.texi
+++ b/doc/general.texi
@@ -150,7 +150,7 @@
 @item AFC                       @tab   @tab X
     @tab Audio format used on the Nintendo Gamecube.
 @item ASF                       @tab X @tab X
-@item AST                       @tab   @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
@@ -201,6 +201,7 @@
 @item Electronic Arts cdata  @tab    @tab X
 @item Electronic Arts Multimedia  @tab    @tab X
     @tab Used in various EA games; files have extensions like WVE and UV2.
+@item Ensoniq Paris Audio File  @tab   @tab X
 @item FFM (FFserver live feed)  @tab X @tab X
 @item Flash (SWF)               @tab X @tab X
 @item Flash 9 (AVM2)            @tab X @tab X
@@ -235,6 +236,7 @@
     @tab A format generated by IndigoVision 8000 video server.
 @item IVF (On2)                 @tab X @tab X
     @tab A format used by libvpx
+@item IRCAM                     @tab X @tab X
 @item LATM                      @tab X @tab X
 @item LMLM4                     @tab   @tab X
     @tab Used by Linux Media Labs MPEG-4 PCI boards
@@ -251,6 +253,8 @@
     @tab Used in Sim City 3000; file extension .xa.
 @item MD Studio                 @tab   @tab X
 @item Metal Gear Solid: The Twin Snakes @tab @tab X
+@item Megalux Frame             @tab   @tab X
+    @tab Used by Megalux Ultimate Paint
 @item Mobotix .mxg              @tab   @tab X
 @item Monkey's Audio            @tab   @tab X
 @item Motion Pixels MVI         @tab   @tab X
@@ -278,6 +282,7 @@
     @tab SMPTE 386M, D-10/IMX Mapping.
 @item NC camera feed            @tab   @tab X
     @tab NC (AVIP NC4600) camera streams
+@item NIST SPeech HEader REsources @tab   @tab X
 @item NTT TwinVQ (VQF)          @tab   @tab X
     @tab Nippon Telegraph and Telephone Corporation TwinVQ.
 @item Nullsoft Streaming Video  @tab   @tab X
@@ -357,6 +362,7 @@
 @item SDP                       @tab   @tab X
 @item Sega FILM/CPK             @tab   @tab X
     @tab Used in many Sega Saturn console games.
+@item Silicon Graphics Movie    @tab   @tab X
 @item Sierra SOL                @tab   @tab X
     @tab .sol files used in Sierra Online games.
 @item Sierra VMD                @tab   @tab X
@@ -370,7 +376,7 @@
 @item Sony OpenMG (OMA)         @tab X @tab X
     @tab Audio format used in Sony Sonic Stage and Sony Vegas.
 @item Sony PlayStation STR      @tab   @tab X
-@item Sony Wave64 (W64)         @tab   @tab X
+@item Sony Wave64 (W64)         @tab X @tab X
 @item SoX native format         @tab X @tab X
 @item SUN AU format             @tab X @tab X
 @item Text files                @tab   @tab X
@@ -662,8 +668,11 @@
     @tab Texture dictionaries used by the Renderware Engine.
 @item RL2 video              @tab     @tab  X
     @tab used in some games by Entertainment Software Partners
+@item SGI RLE 8-bit          @tab     @tab  X
 @item Sierra VMD video       @tab     @tab  X
     @tab Used in Sierra VMD files.
+@item Silicon Graphics Motion Video Compressor 1 (MVC1)  @tab     @tab  X
+@item Silicon Graphics Motion Video Compressor 2 (MVC2)  @tab     @tab  X
 @item Smacker video          @tab     @tab  X
     @tab Video encoding used in Smacker.
 @item SMPTE VC-1             @tab     @tab  X
@@ -805,6 +814,7 @@
 @item DSP Group TrueSpeech   @tab     @tab  X
 @item DV audio               @tab     @tab  X
 @item Enhanced AC-3          @tab  X  @tab  X
+@item EVRC (Enhanced Variable Rate Codec) @tab     @tab  X
 @item FLAC (Free Lossless Audio Codec)  @tab  X  @tab  IX
 @item G.723.1                @tab X @tab X
 @item G.729                  @tab     @tab  X
@@ -912,17 +922,25 @@
 
 @multitable @columnfractions .4 .1 .1 .1 .1
 @item Name @tab Muxing @tab Demuxing @tab Encoding @tab Decoding
-@item SSA/ASS          @tab X @tab X @tab X @tab X
+@item 3GPP Timed Text  @tab   @tab   @tab X @tab X
+@item AQTitle          @tab   @tab X @tab   @tab X
 @item DVB              @tab X @tab X @tab X @tab X
 @item DVD              @tab X @tab X @tab X @tab X
 @item JACOsub          @tab X @tab X @tab   @tab X
 @item MicroDVD         @tab X @tab X @tab   @tab X
+@item MPL2             @tab   @tab X @tab   @tab X
+@item MPsub (MPlayer)  @tab   @tab X @tab   @tab X
 @item PGS              @tab   @tab   @tab   @tab X
+@item PJS (Phoenix)    @tab   @tab X @tab   @tab X
 @item RealText         @tab   @tab X @tab   @tab X
 @item SAMI             @tab   @tab X @tab   @tab X
+@item SSA/ASS          @tab X @tab X @tab X @tab X
 @item SubRip (SRT)     @tab X @tab X @tab X @tab X
+@item SubViewer v1     @tab   @tab X @tab   @tab X
 @item SubViewer        @tab   @tab X @tab   @tab X
-@item 3GPP Timed Text  @tab   @tab   @tab X @tab X
+@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 XSUB             @tab   @tab   @tab X @tab X
 @end multitable
diff --git a/doc/indevs.texi b/doc/indevs.texi
index 6ccd12c..cc5d666 100644
--- a/doc/indevs.texi
+++ b/doc/indevs.texi
@@ -341,14 +341,14 @@
 @item
 Create a color video stream and play it back with @command{ffplay}:
 @example
-ffplay -f lavfi -graph "color=pink [out0]" dummy
+ffplay -f lavfi -graph "color=c=pink [out0]" dummy
 @end example
 
 @item
 As the previous example, but use filename for specifying the graph
 description, and omit the "out0" label:
 @example
-ffplay -f lavfi color=pink
+ffplay -f lavfi color=c=pink
 @end example
 
 @item
@@ -583,10 +583,16 @@
 ffmpeg -f sndio -i /dev/audio0 /tmp/oss.wav
 @end example
 
-@section video4linux2
+@section video4linux2, v4l2
 
 Video4Linux2 input video device.
 
+"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.
+
 The name of the device to grab is a file device node, usually Linux
 systems tend to automatically create such nodes when the device
 (e.g. an USB webcam) is plugged into the system, and has a name of the
@@ -596,8 +602,8 @@
 Video4Linux2 devices usually support a limited set of
 @var{width}x@var{height} sizes and framerates. You can check which are
 supported using @command{-list_formats all} for Video4Linux2 devices.
-
-Some usage examples of the video4linux2 devices with ffmpeg and ffplay:
+Some devices, like TV cards, support one or more standards. It is possible
+to list all the supported standards using @command{-list_standards all}.
 
 The time base for the timestamps is 1 microsecond. Depending on the kernel
 version and configuration, the timestamps may be derived from the real time
@@ -606,19 +612,93 @@
 @option{-timestamps abs} or @option{-ts abs} option can be used to force
 conversion into the real time clock.
 
-Note that if FFmpeg is build with v4l-utils support ("--enable-libv4l2"
-option), it will always be used.
+Some usage examples of the video4linux2 device with @command{ffmpeg}
+and @command{ffplay}:
+@itemize
+@item
+Grab and show the input of a video4linux2 device:
 @example
-# Grab and show the input of a video4linux2 device.
 ffplay -f video4linux2 -framerate 30 -video_size hd720 /dev/video0
-
-# Grab and record the input of a video4linux2 device, leave the
-framerate and size as previously set.
-ffmpeg -f video4linux2 -input_format mjpeg -i /dev/video0 out.mpeg
 @end example
 
-"v4l" and "v4l2" can be used as aliases for the respective "video4linux" and
-"video4linux2".
+@item
+Grab and record the input of a video4linux2 device, leave the
+framerate and size as previously set:
+@example
+ffmpeg -f video4linux2 -input_format mjpeg -i /dev/video0 out.mpeg
+@end example
+@end itemize
+
+For more information about Video4Linux, check @url{http://linuxtv.org/}.
+
+@subsection Options
+
+@table @option
+@item standard
+Set the standard. Must be the name of a supported standard. To get a
+list of the supported standards, use the @option{list_standards}
+option.
+
+@item channel
+Set the input channel number. Default to 0.
+
+@item video_size
+Set the video frame size. The argument must be a string in the form
+@var{WIDTH}x@var{HEIGHT} or a valid size abbreviation.
+
+@item pixel_format
+Select the pixel format (only valid for raw video input).
+
+@item input_format
+Set the preferred pixel format (for raw video) or a codec name.
+This option allows to select the input format, when several are
+available.
+
+@item framerate
+Set the preferred video framerate.
+
+@item list_formats
+List available formats (supported pixel formats, codecs, and frame
+sizes) and exit.
+
+Available values are:
+@table @samp
+@item all
+Show all available (compressed and non-compressed) formats.
+
+@item raw
+Show only raw video (non-compressed) formats.
+
+@item compressed
+Show only compressed formats.
+@end table
+
+@item list_standards
+List supported standards and exit.
+
+Available values are:
+@table @samp
+@item all
+Show all supported standards.
+@end table
+
+@item timestamps, ts
+Set type of timestamps for grabbed frames.
+
+Available values are:
+@table @samp
+@item default
+Use timestamps from the kernel.
+
+@item abs
+Use absolute timestamps (wall clock).
+
+@item mono2abs
+Force conversion from monotonic to absolute timestamps.
+@end table
+
+Default value is @code{default}.
+@end table
 
 @section vfwcap
 
diff --git a/doc/libavcodec.texi b/doc/libavcodec.texi
index 1fd1cf8..618f9f6 100644
--- a/doc/libavcodec.texi
+++ b/doc/libavcodec.texi
@@ -20,20 +20,29 @@
 stream I/O to DSP optimizations, and makes it suitable for
 implementing robust and fast codecs as well as for experimentation.
 
+@c man end DESCRIPTION
+
+@chapter See Also
+
+@ifhtml
+@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe}, @url{ffserver.html,ffserver},
+@url{ffmpeg-codecs.html,ffmpeg-codecs}, @url{ffmpeg-bitstream-filters.html,bitstream-filters},
+@url{libavutil.html,libavutil}
+@end ifhtml
+
+@ifnothtml
+ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1),
+ffmpeg-codecs(1), ffmpeg-bitstream-filters(1),
+libavutil(3)
+@end ifnothtml
+
+@include authors.texi
+
 @ignore
 
 @setfilename libavcodec
 @settitle media streams decoding and encoding library
 
-@c man begin SEEALSO
-ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1), ffmpeg-codecs(1),
-ffmpeg-bistream-filters(1), libavutil(3)
-@c man end
-
-@c man begin AUTHORS
-See Git history (git://source.ffmpeg.org/ffmpeg)
-@c man end
-
 @end ignore
 
 @bye
diff --git a/doc/libavdevice.texi b/doc/libavdevice.texi
index d6e17ae..d5f790b 100644
--- a/doc/libavdevice.texi
+++ b/doc/libavdevice.texi
@@ -19,20 +19,27 @@
 
 @c man end DESCRIPTION
 
+@chapter See Also
+
+@ifhtml
+@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe}, @url{ffserver.html,ffserver},
+@url{ffmpeg-devices.html,ffmpeg-devices},
+@url{libavutil.html,libavutil}, @url{libavcodec.html,libavcodec}, @url{libavformat.html,libavformat}
+@end ifhtml
+
+@ifnothtml
+ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1),
+ffmpeg-devices(1),
+libavutil(3), libavcodec(3), libavformat(3)
+@end ifnothtml
+
+@include authors.texi
+
 @ignore
 
 @setfilename libavdevice
 @settitle multimedia device handling library
 
-@c man begin SEEALSO
-ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1), libavutil(3),
-libavcodec(3), libavformat(3), ffmpeg-devices(1)
-@c man end
-
-@c man begin AUTHORS
-See Git history (git://source.ffmpeg.org/ffmpeg)
-@c man end
-
 @end ignore
 
 @bye
diff --git a/doc/libavfilter.texi b/doc/libavfilter.texi
index 5d0e82a..4f82944 100644
--- a/doc/libavfilter.texi
+++ b/doc/libavfilter.texi
@@ -17,19 +17,28 @@
 
 @c man end DESCRIPTION
 
+@chapter See Also
+
+@ifhtml
+@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe}, @url{ffserver.html,ffserver},
+@url{ffmpeg-filters.html,ffmpeg-filters},
+@url{libavutil.html,libavutil}, @url{libswscale.html,libswscale}, @url{libswresample.html,libswresample},
+@url{libavcodec.html,libavcodec}, @url{libavformat.html,libavformat}, @url{libavdevice.html,libavdevice}
+@end ifhtml
+
+@ifnothtml
+ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1),
+ffmpeg-filters(1),
+libavutil(3), libswscale(3), libswresample(3), libavcodec(3), libavformat(3), libavdevice(3)
+@end ifnothtml
+
+@include authors.texi
+
 @ignore
 
 @setfilename libavfilter
 @settitle multimedia filtering library
 
-@c man begin SEEALSO
-ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1), ffmpeg-filters(1)
-@c man end
-
-@c man begin AUTHORS
-See Git history (git://source.ffmpeg.org/ffmpeg)
-@c man end
-
 @end ignore
 
 @bye
diff --git a/doc/libavformat.texi b/doc/libavformat.texi
index 1e85f65..85e49cb 100644
--- a/doc/libavformat.texi
+++ b/doc/libavformat.texi
@@ -22,19 +22,27 @@
 
 @c man end DESCRIPTION
 
+@chapter See Also
+
+@ifhtml
+@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe}, @url{ffserver.html,ffserver},
+@url{ffmpeg-formats.html,ffmpeg-formats}, @url{ffmpeg-protocols.html,ffmpeg-protocols},
+@url{libavutil.html,libavutil}, @url{libavcodec.html,libavcodec}
+@end ifhtml
+
+@ifnothtml
+ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1),
+ffmpeg-formats(1), ffmpeg-protocols(1),
+libavutil(3), libavcodec(3)
+@end ifnothtml
+
+@include authors.texi
+
 @ignore
 
 @setfilename libavformat
 @settitle multimedia muxing and demuxing library
 
-@c man begin SEEALSO
-ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1), libavutil(3), libavcodec(3), ffmpeg-formats(1), ffmpeg-protocols(1)
-@c man end
-
-@c man begin AUTHORS
-See Git history (git://source.ffmpeg.org/ffmpeg)
-@c man end
-
 @end ignore
 
 @bye
diff --git a/doc/libavutil.texi b/doc/libavutil.texi
index c12d7ff..50b0d0e 100644
--- a/doc/libavutil.texi
+++ b/doc/libavutil.texi
@@ -20,19 +20,25 @@
 
 @c man end DESCRIPTION
 
+@chapter See Also
+
+@ifhtml
+@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe}, @url{ffserver.html,ffserver},
+@url{ffmpeg-utils.html,ffmpeg-utils}
+@end ifhtml
+
+@ifnothtml
+ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1),
+ffmpeg-utils(1)
+@end ifnothtml
+
+@include authors.texi
+
 @ignore
 
 @setfilename libavutil
 @settitle multimedia-biased utility library
 
-@c man begin SEEALSO
-ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1), ffmpeg-utils(1)
-@c man end
-
-@c man begin AUTHORS
-See Git history (git://source.ffmpeg.org/ffmpeg)
-@c man end
-
 @end ignore
 
 @bye
diff --git a/doc/libswresample.texi b/doc/libswresample.texi
index e1c0e2f..1a5b01f 100644
--- a/doc/libswresample.texi
+++ b/doc/libswresample.texi
@@ -44,19 +44,27 @@
 
 @c man end DESCRIPTION
 
+@chapter See Also
+
+@ifhtml
+@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe}, @url{ffserver.html,ffserver},
+@url{ffmpeg-resampler.html,ffmpeg-resampler},
+@url{libavutil.html,libavutil}
+@end ifhtml
+
+@ifnothtml
+ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1),
+ffmpeg-resampler(1),
+libavutil(3)
+@end ifnothtml
+
+@include authors.texi
+
 @ignore
 
 @setfilename libswresample
 @settitle audio resampling library
 
-@c man begin SEEALSO
-ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1), ffmpeg-resampler(1), libavutil(3)
-@c man end
-
-@c man begin AUTHORS
-See Git history (git://source.ffmpeg.org/ffmpeg)
-@c man end
-
 @end ignore
 
 @bye
diff --git a/doc/libswscale.texi b/doc/libswscale.texi
index a8c08e6..818e988 100644
--- a/doc/libswscale.texi
+++ b/doc/libswscale.texi
@@ -37,19 +37,27 @@
 
 @c man end DESCRIPTION
 
+@chapter See Also
+
+@ifhtml
+@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe}, @url{ffserver.html,ffserver},
+@url{ffmpeg-scaler.html,ffmpeg-scaler},
+@url{libavutil.html,libavutil}
+@end ifhtml
+
+@ifnothtml
+ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1),
+ffmpeg-scaler(1),
+libavutil(3)
+@end ifnothtml
+
+@include authors.texi
+
 @ignore
 
 @setfilename libswscale
 @settitle video scaling and pixel format conversion library
 
-@c man begin SEEALSO
-ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1), ffmpeg-scaler(1), libavutil(3)
-@c man end
-
-@c man begin AUTHORS
-See Git history (git://source.ffmpeg.org/ffmpeg)
-@c man end
-
 @end ignore
 
 @bye
diff --git a/doc/muxers.texi b/doc/muxers.texi
index 1c8f93b..6aae871 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -145,9 +145,14 @@
 @end example
 
 @table @option
-@item -hls_time segment length in seconds
-@item -hls_list_size maximum number of playlist entries
-@item -hls_wrap number after which index wraps
+@item -hls_time @var{seconds}
+Set the segment length in seconds.
+@item -hls_list_size @var{size}
+Set the maximum number of playlist entries.
+@item -hls_wrap @var{wrap}
+Set the number after which index wraps.
+@item -start_number @var{number}
+Start the sequence from @var{number}.
 @end table
 
 @anchor{ico}
@@ -235,6 +240,16 @@
 ffmpeg -i in.avi -f image2 -frames:v 1 img.jpeg
 @end example
 
+@table @option
+@item start_number @var{number}
+Start the sequence from @var{number}. Default value is 1. Must be a
+positive number.
+
+@item updatefirst 1|0
+If set to 1, update the first written image file again and
+again. Default value is 0.
+@end table
+
 The image muxer supports the .Y.U.V image file format. This format is
 special in that that each image frame consists of three files, for
 each of the YUV420P components. To read or write this image file format,
@@ -336,6 +351,8 @@
 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
 as fragmented output, thus it is not enabled by default.
+@item -movflags rtphint
+Add RTP hinting tracks to the output file.
 @end table
 
 Smooth Streaming content can be pushed in real time to a publishing
@@ -483,7 +500,9 @@
 and is recommended for outputting e.g. to MPEG transport stream segments.
 @code{ssegment} is a shorter alias for @code{stream_segment}.
 
-Every segment starts with a video keyframe, if a video stream is present.
+Every segment starts with a keyframe of the selected reference stream,
+which is set through the @option{reference_stream} option.
+
 Note that if you want accurate splitting for a video file, you need to
 make the input key frames correspond to the exact splitting times
 expected by the segmenter, or the segment muxer will start the new
@@ -499,12 +518,21 @@
 The segment muxer supports the following options:
 
 @table @option
+@item reference_stream @var{specifier}
+Set the reference stream, as specified by the string @var{specifier}.
+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''.
+
 @item segment_format @var{format}
 Override the inner container format, by default it is guessed by the filename
 extension.
+
 @item segment_list @var{name}
 Generate also a listfile named @var{name}. If not specified no
 listfile is generated.
+
 @item segment_list_flags @var{flags}
 Set flags affecting the segment list generation.
 
@@ -515,17 +543,15 @@
 
 @item live
 Allow live-friendly file generation.
-
-This currently only affects M3U8 lists. In particular, write a fake
-EXT-X-TARGETDURATION duration field at the top of the file, based on
-the specified @var{segment_time}.
 @end table
 
 Default value is @code{cache}.
 
 @item segment_list_size @var{size}
-Overwrite the listfile once it reaches @var{size} entries. If 0
-the listfile is never overwritten. Default value is 0.
+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}
 Specify the format for the segment list file.
 
@@ -554,18 +580,26 @@
 @code{ext} is deprecated in favor or @code{csv}.
 
 @item m3u8
-Generate an extended M3U8 file, version 4, compliant with
-@url{http://tools.ietf.org/id/draft-pantos-http-live-streaming-08.txt}.
+Generate an extended M3U8 file, version 3, compliant with
+@url{http://tools.ietf.org/id/draft-pantos-http-live-streaming}.
 
 A list file with the suffix @code{".m3u8"} will auto-select this format.
 @end table
 
 If not specified the type is guessed from the list file name suffix.
+
 @item segment_time @var{time}
-Set segment duration to @var{time}. Default value is "2".
+Set segment duration to @var{time}, the value must be a duration
+specification. Default value is "2". See also the
+@option{segment_times} option.
+
+Note that splitting may not be accurate, unless you force the
+reference stream key-frames at the given time. See the introductory
+notice and the examples below.
+
 @item segment_time_delta @var{delta}
 Specify the accuracy time when selecting the start time for a
-segment. Default value is "0".
+segment, expressed as a duration specification. Default value is "0".
 
 When delta is specified a key-frame will start a new segment if its
 PTS satisfies the relation:
@@ -587,12 +621,31 @@
 
 @item segment_times @var{times}
 Specify a list of split points. @var{times} contains a list of comma
-separated duration specifications, in increasing order.
+separated duration specifications, in increasing order. See also
+the @option{segment_time} option.
+
+@item segment_frames @var{frames}
+Specify a list of split video frame numbers. @var{frames} contains a
+list of comma separated integer numbers, in increasing order.
+
+This option specifies to start a new segment whenever a reference
+stream key frame is found and the sequential number (starting from 0)
+of the frame is greater or equal to the next value in the list.
+
 @item segment_wrap @var{limit}
 Wrap around segment index once it reaches @var{limit}.
+
+@item segment_start_number @var{number}
+Set the sequence number of the first segment. Defaults to @code{0}.
+
+@item reset_timestamps @var{1|0}
+Reset timestamps at the begin of each segment, so that each segment
+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.
 @end table
 
-Some examples follow.
+@subsection Examples
 
 @itemize
 @item
@@ -616,13 +669,20 @@
 with the segment option @var{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 -vcodec mpeg4 -acodec pcm_s16le -map 0 \
+ffmpeg -i in.mkv -force_key_frames 1,2,3,5,8,13,21 -codec:v mpeg4 -codec:a pcm_s16le -map 0 \
 -f segment -segment_list out.csv -segment_times 1,2,3,5,8,13,21 -segment_time_delta 0.05 out%03d.nut
 @end example
 In order to force key frames on the input file, transcoding is
 required.
 
 @item
+Segment the input file by splitting the input file according to the
+frame numbers sequence specified with the @var{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
+
+@item
 To convert the @file{in.mkv} to TS segments using the @code{libx264}
 and @code{libfaac} encoders:
 @example
@@ -667,10 +727,61 @@
 ffmpeg -i INPUT -id3v2_version 3 -write_id3v1 1 out.mp3
 @end example
 
-Attach a picture to an mp3:
+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 -metadata:s:v title="Album cover"
--metadata:s:v comment="Cover (Front)" out.mp3
+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
+other kind of muxer. It can be used, for example, to both stream a video to
+the network and save it to disk at the same time.
+
+It is different from specifying several outputs to the @command{ffmpeg}
+command-line tool because the audio and video data will be encoded only once
+with the tee muxer; encoding can be a very expensive process. It is not
+useful when using the libavformat API directly because it is then possible
+to feed the same packets to several muxers directly.
+
+The slave outputs are specified in the file name given to the muxer,
+separated by '|'. If any of the slave name contains the '|' separator,
+leading or trailing spaces or any special character, it must be
+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
+@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.
+
+Example: encode something and both archive it in a WebM file and stream it
+as MPEG-TS over UDP:
+
+@example
+ffmpeg -i ... -c:v libx264 -c:a mp2 -f tee
+  "archive-20121107.mkv|[f=mpegts]udp://10.0.1.255:1234/"
+@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.
+
 @c man end MUXERS
diff --git a/doc/optimization.txt b/doc/optimization.txt
index e3fd324..5a66d6b 100644
--- a/doc/optimization.txt
+++ b/doc/optimization.txt
@@ -148,7 +148,7 @@
 Some instructions on some architectures have strict alignment restrictions,
 for example most SSE/SSE2 instructions on x86.
 The minimum guaranteed alignment is written in the .h files, for example:
-    void (*put_pixels_clamped)(const DCTELEM *block/*align 16*/, UINT8 *pixels/*align 8*/, int line_size);
+    void (*put_pixels_clamped)(const int16_t *block/*align 16*/, UINT8 *pixels/*align 8*/, int line_size);
 
 
 General Tips:
diff --git a/doc/platform.texi b/doc/platform.texi
index dcdfff2..bb8e6ca 100644
--- a/doc/platform.texi
+++ b/doc/platform.texi
@@ -114,7 +114,7 @@
 You will need the following prerequisites:
 
 @itemize
-@item @uref{https://github.com/libav/c99-to-c89/, C99-to-C89 Converter & Wrapper}
+@item @uref{http://download.videolan.org/pub/contrib/c99-to-c89/, C99-to-C89 Converter & Wrapper}
 @item @uref{http://code.google.com/p/msinttypes/, msinttypes}
 @item @uref{http://www.mingw.org/, MSYS}
 @item @uref{http://yasm.tortall.net/, YASM}
diff --git a/doc/protocols.texi b/doc/protocols.texi
index e790459..9940b67 100644
--- a/doc/protocols.texi
+++ b/doc/protocols.texi
@@ -75,6 +75,15 @@
 Note that you may need to escape the character "|" which is special for
 many shells.
 
+@section data
+
+Data in-line in the URI. See @url{http://en.wikipedia.org/wiki/Data_URI_scheme}.
+
+For example, to convert a GIF file given inline with @command{ffmpeg}:
+@example
+ffmpeg -i "data:image/gif;base64,R0lGODdhCAAIAMIEAAAAAAAA//8AAP//AP///////////////ywAAAAACAAIAAADF0gEDLojDgdGiJdJqUX02iB4E8Q9jUMkADs=" smiley.png
+@end example
+
 @section file
 
 File access protocol.
@@ -119,6 +128,63 @@
 
 HTTP (Hyper Text Transfer Protocol).
 
+This protocol accepts the following options.
+
+@table @option
+@item seekable
+Control seekability of connection. If set to 1 the resource is
+supposed to be seekable, if set to 0 it is assumed not to be seekable,
+if set to -1 it will try to autodetect if it is seekable. Default
+value is -1.
+
+@item chunked_post
+If set to 1 use chunked transfer-encoding for posts, default is 1.
+
+@item headers
+Set custom HTTP headers, can override built in default headers. The
+value must be a string encoding the headers.
+
+@item content_type
+Force a content type.
+
+@item user-agent
+Override User-Agent header. If not specified the protocol will use a
+string describing the libavformat build.
+
+@item multiple_requests
+Use persistent connections if set to 1. By default it is 0.
+
+@item post_data
+Set custom HTTP post data.
+
+@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 mime_type
+Set MIME type.
+
+@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
+delimited by a newline character.
+@end table
+
+@subsection HTTP Cookies
+
+Some HTTP requests will be denied unless cookie values are passed in with the
+request. The @option{cookies} option allows these cookies to be specified. At
+the very least, each cookie must specify a value along with a path and domain.
+HTTP requests that match both the domain and path will automatically include the
+cookie value in the HTTP Cookie header field. Multiple cookies can be delimited
+by a newline.
+
+The required syntax to play a stream specifying a cookie is:
+@example
+ffplay -cookies "nlqptid=nltid=tsn; path=/; domain=somedomain.com;" http://somedomain.com/somestream.m3u8
+@end example
+
 @section mmst
 
 MMS (Microsoft Media Server) protocol over TCP.
diff --git a/doc/rate_distortion.txt b/doc/rate_distortion.txt
index a7d2c87..e9711c2 100644
--- a/doc/rate_distortion.txt
+++ b/doc/rate_distortion.txt
@@ -23,7 +23,7 @@
 
 rate is the filesize
 distortion is the quality
-lambda is a fixed value choosen as a tradeoff between quality and filesize
+lambda is a fixed value chosen as a tradeoff between quality and filesize
 Is this equivalent to finding the best quality for a given max
 filesize? The answer is yes. For each filesize limit there is some lambda
 factor for which minimizing above will get you the best quality (using your
diff --git a/doc/swresample.txt b/doc/swresample.txt
index 7904147..2d192a3 100644
--- a/doc/swresample.txt
+++ b/doc/swresample.txt
@@ -32,9 +32,9 @@
                         Output
 
 Planar/Packed conversion is done when needed during sample format conversion.
-Every step can be skipped without memcpy when its not needed.
+Every step can be skipped without memcpy when it is not needed.
 Either Resampling and Rematrixing can be performed first depending on which
-way its faster.
+way it is faster.
 The Buffers are needed for resampling due to resamplng being a process that
 requires future and past data, it thus also introduces inevitably a delay when
 used.
diff --git a/doc/syntax.texi b/doc/syntax.texi
index a3aabce..af22d6c 100644
--- a/doc/syntax.texi
+++ b/doc/syntax.texi
@@ -98,7 +98,7 @@
 
 The accepted syntax is:
 @example
-[-]HH:MM:SS[.m...]
+[-][HH:]MM:SS[.m...]
 [-]S+[.m...]
 @end example
 
@@ -112,6 +112,22 @@
 
 The following abbreviations are recognized:
 @table @samp
+@item ntsc
+720x480
+@item pal
+720x576
+@item qntsc
+352x240
+@item qpal
+352x288
+@item sntsc
+640x480
+@item spal
+768x576
+@item film
+352x240
+@item ntsc-film
+352x240
 @item sqcif
 128x96
 @item qcif
@@ -170,6 +186,18 @@
 1280x720
 @item hd1080
 1920x1080
+@item 2k
+2048x1080
+@item 2kflat
+1998x1080
+@item 2kscope
+2048x858
+@item 4k
+4096x2160
+@item 4kflat
+3996x2160
+@item 4kscope
+4096x1716
 @end table
 
 @anchor{video rate syntax}
@@ -187,17 +215,17 @@
 @item pal
 25/1
 @item qntsc
-30000/1
+30000/1001
 @item qpal
 25/1
 @item sntsc
-30000/1
+30000/1001
 @item spal
 25/1
 @item film
 24/1
 @item ntsc-film
-24000/1
+24000/1001
 @end table
 
 @anchor{ratio syntax}
diff --git a/doc/t2h.init b/doc/t2h.init
index ec7d2a0..2aab488 100644
--- a/doc/t2h.init
+++ b/doc/t2h.init
@@ -9,131 +9,14 @@
 ';
 
 $CSS_LINES = $ENV{"FFMPEG_CSS"} || <<EOT;
-<style type="text/css">
-<!--
-.container {
-  margin-right: auto;
-  margin-left: auto;
-  width: 1070px;
-}
-body {
-  font-size: 14px;
-  line-height: 20px;
-  color: #333333;
-  background-color: #ffffff;
-}
-a {
-  color: #0088cc;
-  text-decoration: none;
-}
-a:hover {
-  color: #005580;
-  text-decoration: underline;
-}
-p {
-  margin: 0 0 10px;
-}
-h2,
-h3,
-h4 {
-  margin: 10px 0;
-  font-family: inherit;
-  font-weight: bold;
-  line-height: 1;
-  border-color: #D6E9C6;
-  color: #468847;
-  border-style: solid;
-  border-width: 0 0 1px;
-  padding-left: 0.5em;
-}
-
-h1 a,
-h2 a,
-h3 a,
-h4 a {
-  color: inherit;
-}
-h1 {
-  font-size: 30px;
-  line-height: 40px;
-}
-h2 {
-  font-size: 20px;
-  line-height: 40px;
-}
-h3 {
-  font-size: 18px;
-  line-height: 40px;
-}
-code,
-pre {
-  padding: 0 3px 2px;
-  font-family: monospace;
-  font-size: 12px;
-  color: #333333;
-  border-radius: 3px;
-}
-pre {
-  display: block;
-  padding: 9.5px;
-  margin: 0 0 10px;
-  font-size: 13px;
-  line-height: 20px;
-  word-break: break-all;
-  word-wrap: break-word;
-  white-space: pre;
-  white-space: pre-wrap;
-  background-color: #f5f5f5;
-  border: 1px solid #ccc;
-  border-radius: 4px;
-}
-
-code {
-  padding: 2px 4px;
-  color: #d14;
-  background-color: #f7f7f9;
-  border: 1px solid #e1e1e8;
-}
-pre code {
-  padding: 0;
-  color: inherit;
-  background-color: transparent;
-  border: 0;
-}
-.alert {
-  padding: 8px 35px 8px 14px;
-  margin-bottom: 20px;
-  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
-  background-color: #fcf8e3;
-  border: 1px solid #fbeed5;
-  border-radius: 4px;
-  color: #c09853;
-}
-
-.alert-danger,
-.alert-error {
-  background-color: #f2dede;
-  border-color: #eed3d7;
-  color: #b94a48;
-}
-.alert-info {
-  background-color: #d9edf7;
-  border-color: #bce8f1;
-  color: #3a87ad;
-}
-
-ul.toc {
-  list-style-type: none;
-}
--->
-</style>
+<link rel="stylesheet" type="text/css" href="default.css" />
 EOT
 
 my $TEMPLATE_HEADER = $ENV{"FFMPEG_HEADER"} || <<EOT;
 <link rel="icon" href="favicon.png" type="image/png" />
 </head>
 <body>
-<div class="container">
+<div id="container">
 EOT
 
 $PRE_BODY_CLOSE = '</div></div>';
@@ -185,7 +68,7 @@
 sub FFmpeg_print_page_head($$)
 {
     my $fh = shift;
-    my $longtitle = "$Texi2HTML::THISDOC{'title_no_texi'}";
+    my $longtitle = "$Texi2HTML::THISDOC{'fulltitle_no_texi'}";
     $longtitle .= ": $Texi2HTML::NO_TEXI{'This'}" if exists $Texi2HTML::NO_TEXI{'This'};
     my $description = $DOCUMENT_DESCRIPTION;
     $description = $longtitle if (!defined($description));
diff --git a/doc/texi2pod.pl b/doc/texi2pod.pl
index d20fac6..5c3aba6 100755
--- a/doc/texi2pod.pl
+++ b/doc/texi2pod.pl
@@ -27,9 +27,9 @@
 
 $output = 0;
 $skipping = 0;
-%sects = ();
-@sects_sequence = ();
-$section = "";
+%chapters = ();
+@chapters_sequence = ();
+$chapter = "";
 @icstack = ();
 @endwstack = ();
 @skstack = ();
@@ -116,18 +116,24 @@
         die "cannot open $1: $!\n";
     };
 
-    # Look for blocks surrounded by @c man begin SECTION ... @c man end.
-    # This really oughta be @ifman ... @end ifman and the like, but such
-    # would require rev'ing all other Texinfo translators.
-    /^\@c\s+man\s+begin\s+([A-Za-z ]+)/ and $sect = $1, push (@sects_sequence, $sect), $output = 1, next;
-    /^\@c\s+man\s+end/ and do {
-        $sects{$sect} = "" unless exists $sects{$sect};
-        $sects{$sect} .= postprocess($section);
-        $section = "";
-        $output = 0;
+    /^\@chapter\s+([A-Za-z ]+)/ and do {
+        # close old chapter
+        $chapters{$chapter_name} .= postprocess($chapter) if ($chapter_name);
+
+        # start new chapter
+        $chapter_name = $1, push (@chapters_sequence, $chapter_name);
+        $chapters{$chapter_name} = "" unless exists $chapters{$chapter_name};
+        $chapter = "";
+        $output = 1;
         next;
     };
 
+    /^\@bye/ and do {
+        # close old chapter
+        $chapters{$chapter_name} .= postprocess($chapter) if ($chapter_name);
+        last INF;
+    };
+
     # handle variables
     /^\@set\s+([a-zA-Z0-9_-]+)\s*(.*)$/ and do {
         $defs{$1} = $2;
@@ -150,20 +156,20 @@
         # Ignore @end foo, where foo is not an operation which may
         # cause us to skip, if we are presently skipping.
         my $ended = $1;
-        next if $skipping && $ended !~ /^(?:ifset|ifclear|ignore|menu|iftex)$/;
+        next if $skipping && $ended !~ /^(?:ifset|ifclear|ignore|menu|iftex|ifhtml|ifnothtml)$/;
 
         die "\@end $ended without \@$ended at line $.\n" unless defined $endw;
         die "\@$endw ended by \@end $ended at line $.\n" unless $ended eq $endw;
 
         $endw = pop @endwstack;
 
-        if ($ended =~ /^(?:ifset|ifclear|ignore|menu|iftex)$/) {
+        if ($ended =~ /^(?:ifset|ifclear|ignore|menu|iftex|ifhtml|ifnothtml)$/) {
             $skipping = pop @skstack;
             next;
         } elsif ($ended =~ /^(?:example|smallexample|display)$/) {
             $shift = "";
             $_ = "";        # need a paragraph break
-        } elsif ($ended =~ /^(?:itemize|enumerate|[fv]?table)$/) {
+        } elsif ($ended =~ /^(?:itemize|enumerate|(?:multi|[fv])?table)$/) {
             $_ = "\n=back\n";
             $ic = pop @icstack;
         } else {
@@ -190,11 +196,11 @@
         next;
     };
 
-    /^\@(ignore|menu|iftex)\b/ and do {
+    /^\@(ignore|menu|iftex|ifhtml|ifnothtml)\b/ and do {
         push @endwstack, $endw;
         push @skstack, $skipping;
         $endw = $1;
-        $skipping = 1;
+        $skipping = $endw !~ /ifnothtml/;
         next;
     };
 
@@ -263,7 +269,7 @@
         $endw = "enumerate";
     };
 
-    /^\@([fv]?table)\s+(\@[a-z]+)/ and do {
+    /^\@((?:multi|[fv])?table)\s+(\@[a-z]+)/ and do {
         push @endwstack, $endw;
         push @icstack, $ic;
         $endw = $1;
@@ -272,6 +278,7 @@
         $ic =~ s/\@(?:code|kbd)/C/;
         $ic =~ s/\@(?:dfn|var|emph|cite|i)/I/;
         $ic =~ s/\@(?:file)/F/;
+        $ic =~ s/\@(?:columnfractions)//;
         $_ = "\n=over 4\n";
     };
 
@@ -282,6 +289,21 @@
         $_ = "";        # need a paragraph break
     };
 
+    /^\@item\s+(.*\S)\s*$/ and $endw eq "multitable" and do {
+        my $columns = $1;
+        $columns =~ s/\@tab/ : /;
+
+        $_ = "\n=item B&LT;". $columns ."&GT;\n";
+    };
+
+    /^\@tab\s+(.*\S)\s*$/ and $endw eq "multitable" and do {
+        my $columns = $1;
+        $columns =~ s/\@tab/ : /;
+
+        $_ = " : ". $columns;
+        $chapter =~ s/\n+\s+$//;
+    };
+
     /^\@itemx?\s*(.+)?$/ and do {
         if (defined $1) {
             # Entity escapes prevent munging by the <> processing below.
@@ -293,7 +315,7 @@
         }
     };
 
-    $section .= $shift.$_."\n";
+    $chapter .= $shift.$_."\n";
 }
 # End of current file.
 close($inf);
@@ -302,16 +324,15 @@
 
 die "No filename or title\n" unless defined $fn && defined $tl;
 
-$sects{NAME} = "$fn \- $tl\n";
-$sects{FOOTNOTES} .= "=back\n" if exists $sects{FOOTNOTES};
+$chapters{NAME} = "$fn \- $tl\n";
+$chapters{FOOTNOTES} .= "=back\n" if exists $chapters{FOOTNOTES};
 
-unshift @sects_sequence, "NAME";
-for $sect (@sects_sequence) {
-    if(exists $sects{$sect}) {
-        $head = $sect;
-        $head =~ s/SEEALSO/SEE ALSO/;
+unshift @chapters_sequence, "NAME";
+for $chapter (@chapters_sequence) {
+    if (exists $chapters{$chapter}) {
+        $head = uc($chapter);
         print "=head1 $head\n\n";
-        print scalar unmunge ($sects{$sect});
+        print scalar unmunge ($chapters{$chapter});
         print "\n";
     }
 }
@@ -356,6 +377,7 @@
     s/\(?\@xref\{(?:[^\}]*)\}(?:[^.<]|(?:<[^<>]*>))*\.\)?//g;
     s/\s+\(\@pxref\{(?:[^\}]*)\}\)//g;
     s/;\s+\@pxref\{(?:[^\}]*)\}//g;
+    s/\@ref\{(?:[^,]*,)(?:[^,]*,)([^,\}]*).*\}/$1/g;
     s/\@ref\{([^\}]*)\}/$1/g;
     s/\@noindent\s*//g;
     s/\@refill//g;
@@ -365,7 +387,7 @@
     # @uref can take one, two, or three arguments, with different
     # semantics each time.  @url and @email are just like @uref with
     # one argument, for our purposes.
-    s/\@(?:uref|url|email)\{([^\},]*)\}/&lt;B<$1>&gt;/g;
+    s/\@(?:uref|url|email)\{([^\},]*),?[^\}]*\}/&lt;B<$1>&gt;/g;
     s/\@uref\{([^\},]*),([^\},]*)\}/$2 (C<$1>)/g;
     s/\@uref\{([^\},]*),([^\},]*),([^\},]*)\}/$3/g;
 
@@ -409,13 +431,13 @@
 
 sub add_footnote
 {
-    unless (exists $sects{FOOTNOTES}) {
-        $sects{FOOTNOTES} = "\n=over 4\n\n";
+    unless (exists $chapters{FOOTNOTES}) {
+        $chapters{FOOTNOTES} = "\n=over 4\n\n";
     }
 
-    $sects{FOOTNOTES} .= "=item $fnno.\n\n"; $fnno++;
-    $sects{FOOTNOTES} .= $_[0];
-    $sects{FOOTNOTES} .= "\n\n";
+    $chapters{FOOTNOTES} .= "=item $fnno.\n\n"; $fnno++;
+    $chapters{FOOTNOTES} .= $_[0];
+    $chapters{FOOTNOTES} .= "\n\n";
 }
 
 # stolen from Symbol.pm
diff --git a/doc/viterbi.txt b/doc/viterbi.txt
index 5362a0b..9782546 100644
--- a/doc/viterbi.txt
+++ b/doc/viterbi.txt
@@ -85,8 +85,8 @@
      /        \
     O-----2--4--O
 
-Finding the new best pathes and scores for each point of our new column is
-trivial given we know the previous column best pathes and scores:
+Finding the new best paths and scores for each point of our new column is
+trivial given we know the previous column best paths and scores:
 
     O-----0-----8
      \
diff --git a/ffmpeg.c b/ffmpeg.c
index 55b5f86..448a9e2 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -109,6 +109,15 @@
 
 static FILE *vstats_file;
 
+const char *const forced_keyframes_const_names[] = {
+    "n",
+    "n_forced",
+    "prev_forced_n",
+    "prev_forced_t",
+    "t",
+    NULL
+};
+
 static void do_video_stats(OutputStream *ost, int frame_size);
 static int64_t getutime(void);
 
@@ -209,17 +218,29 @@
     AVFilterBufferRef *ref = ist->sub2video.ref;
     int8_t *dst;
     int     dst_linesize;
-    int i;
-    int64_t pts = av_rescale_q(sub->pts, AV_TIME_BASE_Q, ist->st->time_base);
+    int num_rects, i;
+    int64_t pts, end_pts;
 
     if (!ref)
         return;
+    if (sub) {
+        pts       = av_rescale_q(sub->pts + sub->start_display_time * 1000,
+                                 AV_TIME_BASE_Q, ist->st->time_base);
+        end_pts   = av_rescale_q(sub->pts + sub->end_display_time   * 1000,
+                                 AV_TIME_BASE_Q, ist->st->time_base);
+        num_rects = sub->num_rects;
+    } else {
+        pts       = ist->sub2video.end_pts;
+        end_pts   = INT64_MAX;
+        num_rects = 0;
+    }
     dst          = ref->data    [0];
     dst_linesize = ref->linesize[0];
     memset(dst, 0, h * dst_linesize);
-    for (i = 0; i < sub->num_rects; i++)
+    for (i = 0; i < num_rects; i++)
         sub2video_copy_rect(dst, dst_linesize, w, h, sub->rects[i]);
     sub2video_push_ref(ist, pts);
+    ist->sub2video.end_pts = end_pts;
 }
 
 static void sub2video_heartbeat(InputStream *ist, int64_t pts)
@@ -242,6 +263,8 @@
         /* do not send the heartbeat frame if the subtitle is already ahead */
         if (pts2 <= ist2->sub2video.last_pts)
             continue;
+        if (pts2 >= ist2->sub2video.end_pts)
+            sub2video_update(ist2, NULL);
         for (j = 0, nb_reqs = 0; j < ist2->nb_filters; j++)
             nb_reqs += av_buffersrc_get_nb_failed_requests(ist2->filters[j]->filter);
         if (nb_reqs)
@@ -355,8 +378,10 @@
     }
     if (is_pipe) {
         /* When running under a GUI, you will end here. */
-        if (!PeekNamedPipe(input_handle, NULL, 0, NULL, &nchars, NULL))
+        if (!PeekNamedPipe(input_handle, NULL, 0, NULL, &nchars, NULL)) {
+            // input pipe may have been closed by the program that ran ffmpeg
             return -1;
+        }
         //Read it
         if(nchars != 0) {
             read(0, &ch, 1);
@@ -421,6 +446,7 @@
         avcodec_free_frame(&output_streams[i]->filtered_frame);
 
         av_freep(&output_streams[i]->forced_keyframes);
+        av_expr_free(output_streams[i]->forced_keyframes_pexpr);
         av_freep(&output_streams[i]->avfilter);
         av_freep(&output_streams[i]->logfile_prefix);
         av_freep(&output_streams[i]);
@@ -433,6 +459,7 @@
         avcodec_free_frame(&input_streams[i]->decoded_frame);
         av_dict_free(&input_streams[i]->opts);
         free_buffer_pool(&input_streams[i]->buffer_pool);
+        avsubtitle_free(&input_streams[i]->prev_sub.subtitle);
         avfilter_unref_bufferp(&input_streams[i]->sub2video.ref);
         av_freep(&input_streams[i]->filters);
         av_freep(&input_streams[i]);
@@ -455,7 +482,6 @@
     if (received_sigterm) {
         av_log(NULL, AV_LOG_INFO, "Received signal %d: terminating.\n",
                (int) received_sigterm);
-        exit (255);
     }
 }
 
@@ -583,9 +609,8 @@
 
     ost->finished = 1;
     if (of->shortest) {
-        int i;
-        for (i = 0; i < of->ctx->nb_streams; i++)
-            output_streams[of->ost_index + i]->finished = 1;
+        int64_t end = av_rescale_q(ost->sync_opts - ost->first_pts, ost->st->codec->time_base, AV_TIME_BASE_Q);
+        of->recording_time = FFMIN(of->recording_time, end);
     }
 }
 
@@ -789,7 +814,7 @@
 
     format_video_sync = video_sync_method;
     if (format_video_sync == VSYNC_AUTO)
-        format_video_sync = (s->oformat->flags & AVFMT_VARIABLE_FPS) ? ((s->oformat->flags & AVFMT_NOTIMESTAMPS) ? VSYNC_PASSTHROUGH : VSYNC_VFR) : 1;
+        format_video_sync = (s->oformat->flags & AVFMT_VARIABLE_FPS) ? ((s->oformat->flags & AVFMT_NOTIMESTAMPS) ? VSYNC_PASSTHROUGH : VSYNC_VFR) : VSYNC_CFR;
 
     switch (format_video_sync) {
     case VSYNC_CFR:
@@ -858,8 +883,9 @@
         video_size += pkt.size;
         write_frame(s, &pkt, ost);
     } else {
-        int got_packet;
+        int got_packet, forced_keyframe = 0;
         AVFrame big_picture;
+        double pts_time;
 
         big_picture = *in_picture;
         /* better than nothing: use input picture interlaced
@@ -883,11 +909,41 @@
         big_picture.quality = ost->st->codec->global_quality;
         if (!enc->me_threshold)
             big_picture.pict_type = 0;
+
+        pts_time = big_picture.pts != AV_NOPTS_VALUE ?
+            big_picture.pts * av_q2d(enc->time_base) : NAN;
         if (ost->forced_kf_index < ost->forced_kf_count &&
             big_picture.pts >= ost->forced_kf_pts[ost->forced_kf_index]) {
-            big_picture.pict_type = AV_PICTURE_TYPE_I;
             ost->forced_kf_index++;
+            forced_keyframe = 1;
+        } else if (ost->forced_keyframes_pexpr) {
+            double res;
+            ost->forced_keyframes_expr_const_values[FKF_T] = pts_time;
+            res = av_expr_eval(ost->forced_keyframes_pexpr,
+                               ost->forced_keyframes_expr_const_values, NULL);
+            av_dlog(NULL, "force_key_frame: n:%f n_forced:%f prev_forced_n:%f t:%f prev_forced_t:%f -> res:%f\n",
+                    ost->forced_keyframes_expr_const_values[FKF_N],
+                    ost->forced_keyframes_expr_const_values[FKF_N_FORCED],
+                    ost->forced_keyframes_expr_const_values[FKF_PREV_FORCED_N],
+                    ost->forced_keyframes_expr_const_values[FKF_T],
+                    ost->forced_keyframes_expr_const_values[FKF_PREV_FORCED_T],
+                    res);
+            if (res) {
+                forced_keyframe = 1;
+                ost->forced_keyframes_expr_const_values[FKF_PREV_FORCED_N] =
+                    ost->forced_keyframes_expr_const_values[FKF_N];
+                ost->forced_keyframes_expr_const_values[FKF_PREV_FORCED_T] =
+                    ost->forced_keyframes_expr_const_values[FKF_T];
+                ost->forced_keyframes_expr_const_values[FKF_N_FORCED] += 1;
+            }
+
+            ost->forced_keyframes_expr_const_values[FKF_N] += 1;
         }
+        if (forced_keyframe) {
+            big_picture.pict_type = AV_PICTURE_TYPE_I;
+            av_log(NULL, AV_LOG_DEBUG, "Forced keyframe at time %f\n", pts_time);
+        }
+
         update_benchmark(NULL);
         ret = avcodec_encode_video2(enc, &pkt, &big_picture, &got_packet);
         update_benchmark("encode_video %d.%d", ost->file_index, ost->index);
@@ -958,14 +1014,14 @@
 
     enc = ost->st->codec;
     if (enc->codec_type == AVMEDIA_TYPE_VIDEO) {
-        frame_number = ost->frame_number;
+        frame_number = ost->st->nb_frames;
         fprintf(vstats_file, "frame= %5d q= %2.1f ", frame_number, enc->coded_frame->quality / (float)FF_QP2LAMBDA);
         if (enc->flags&CODEC_FLAG_PSNR)
             fprintf(vstats_file, "PSNR= %6.2f ", psnr(enc->coded_frame->error[0] / (enc->width * enc->height * 255.0 * 255.0)));
 
         fprintf(vstats_file,"f_size= %6d ", frame_size);
         /* compute pts value */
-        ti1 = ost->sync_opts * av_q2d(enc->time_base);
+        ti1 = ost->st->pts.val * av_q2d(enc->time_base);
         if (ti1 < 0.01)
             ti1 = 0.01;
 
@@ -1047,6 +1103,12 @@
             case AVMEDIA_TYPE_AUDIO:
                 avfilter_copy_buf_props(filtered_frame, picref);
                 filtered_frame->pts = frame_pts;
+                if (!(ost->st->codec->codec->capabilities & CODEC_CAP_PARAM_CHANGE) &&
+                    ost->st->codec->channels != av_frame_get_channels(filtered_frame)) {
+                    av_log(NULL, AV_LOG_ERROR,
+                           "Audio filter graph output is not normalized and encoder does not support parameter changes\n");
+                    break;
+                }
                 do_audio_out(of->ctx, ost, filtered_frame);
                 break;
             default:
@@ -1095,13 +1157,6 @@
     total_size = avio_size(oc->pb);
     if (total_size <= 0) // FIXME improve avio_size() so it works with non seekable output too
         total_size = avio_tell(oc->pb);
-    if (total_size < 0) {
-        char errbuf[128];
-        av_strerror(total_size, errbuf, sizeof(errbuf));
-        av_log(NULL, AV_LOG_VERBOSE, "Bitrate not available, "
-               "avio_tell() failed: %s\n", errbuf);
-        total_size = 0;
-    }
 
     buf[0] = '\0';
     vid = 0;
@@ -1160,7 +1215,7 @@
                     p = psnr(error / scale);
                     snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%c:%2.2f ", type[j], p);
                     av_bprintf(&buf_script, "stream_%d_%d_psnr_%c=%2.2f\n",
-                               ost->file_index, ost->index, type[i] | 32, p);
+                               ost->file_index, ost->index, type[j] | 32, p);
                 }
                 p = psnr(error_sum / scale_sum);
                 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "*:%2.2f ", psnr(error_sum / scale_sum));
@@ -1182,16 +1237,21 @@
     hours = mins / 60;
     mins %= 60;
 
-    bitrate = pts ? total_size * 8 / (pts / 1000.0) : 0;
+    bitrate = pts && total_size >= 0 ? total_size * 8 / (pts / 1000.0) : -1;
 
-    snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
-             "size=%8.0fkB time=", total_size / 1024.0);
+    if (total_size < 0) snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
+                                 "size=N/A time=");
+    else                snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
+                                 "size=%8.0fkB time=", total_size / 1024.0);
     snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
              "%02d:%02d:%02d.%02d ", hours, mins, secs,
              (100 * us) / AV_TIME_BASE);
-    snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
-             "bitrate=%6.1fkbits/s", bitrate);
-    av_bprintf(&buf_script, "total_size=%"PRId64"\n", total_size);
+    if (bitrate < 0) snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
+                              "bitrate=N/A");
+    else             snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
+                              "bitrate=%6.1fkbits/s", bitrate);
+    if (total_size < 0) av_bprintf(&buf_script, "total_size=N/A\n");
+    else                av_bprintf(&buf_script, "total_size=%"PRId64"\n", total_size);
     av_bprintf(&buf_script, "out_time_ms=%"PRId64"\n", pts);
     av_bprintf(&buf_script, "out_time=%02d:%02d:%02d.%06d\n",
                hours, mins, secs, us);
@@ -1304,6 +1364,9 @@
                 if (pkt.duration > 0)
                     pkt.duration = av_rescale_q(pkt.duration, enc->time_base, ost->st->time_base);
                 write_frame(os, &pkt, ost);
+                if (ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && vstats_filename) {
+                    do_video_stats(ost, pkt.size);
+                }
             }
 
             if (stop_encoding)
@@ -1427,6 +1490,8 @@
     if (!dec->channel_layout) {
         char layout_name[256];
 
+        if (dec->channels > ist->guess_layout_max)
+            return 0;
         dec->channel_layout = av_get_default_channel_layout(dec->channels);
         if (!dec->channel_layout)
             return 0;
@@ -1854,7 +1919,7 @@
 
 static void print_sdp(void)
 {
-    char sdp[2048];
+    char sdp[16384];
     int i;
     AVFormatContext **avc = av_malloc(sizeof(*avc) * nb_output_files);
 
@@ -1915,19 +1980,25 @@
     return NULL;
 }
 
+static int compare_int64(const void *a, const void *b)
+{
+    int64_t va = *(int64_t *)a, vb = *(int64_t *)b;
+    return va < vb ? -1 : va > vb ? +1 : 0;
+}
+
 static void parse_forced_key_frames(char *kf, OutputStream *ost,
                                     AVCodecContext *avctx)
 {
     char *p;
-    int n = 1, i;
-    int64_t t;
+    int n = 1, i, size, index = 0;
+    int64_t t, *pts;
 
     for (p = kf; *p; p++)
         if (*p == ',')
             n++;
-    ost->forced_kf_count = n;
-    ost->forced_kf_pts   = av_malloc(sizeof(*ost->forced_kf_pts) * n);
-    if (!ost->forced_kf_pts) {
+    size = n;
+    pts = av_malloc(sizeof(*pts) * size);
+    if (!pts) {
         av_log(NULL, AV_LOG_FATAL, "Could not allocate forced key frames array.\n");
         exit(1);
     }
@@ -1939,11 +2010,43 @@
         if (next)
             *next++ = 0;
 
-        t = parse_time_or_die("force_key_frames", p, 1);
-        ost->forced_kf_pts[i] = av_rescale_q(t, AV_TIME_BASE_Q, avctx->time_base);
+        if (!memcmp(p, "chapters", 8)) {
+
+            AVFormatContext *avf = output_files[ost->file_index]->ctx;
+            int j;
+
+            if (avf->nb_chapters > INT_MAX - size ||
+                !(pts = av_realloc_f(pts, size += avf->nb_chapters - 1,
+                                     sizeof(*pts)))) {
+                av_log(NULL, AV_LOG_FATAL,
+                       "Could not allocate forced key frames array.\n");
+                exit(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);
+
+            for (j = 0; j < avf->nb_chapters; j++) {
+                AVChapter *c = avf->chapters[j];
+                av_assert1(index < size);
+                pts[index++] = av_rescale_q(c->start, c->time_base,
+                                            avctx->time_base) + t;
+            }
+
+        } else {
+
+            t = parse_time_or_die("force_key_frames", p, 1);
+            av_assert1(index < size);
+            pts[index++] = av_rescale_q(t, AV_TIME_BASE_Q, avctx->time_base);
+
+        }
 
         p = next;
     }
+
+    av_assert0(index == size);
+    qsort(pts, size, sizeof(*pts), compare_int64);
+    ost->forced_kf_count = size;
+    ost->forced_kf_pts   = pts;
 }
 
 static void report_new_stream(int input_index, AVPacket *pkt)
@@ -2030,9 +2133,10 @@
             codec->codec_type = icodec->codec_type;
 
             if (!codec->codec_tag) {
+                unsigned int codec_tag;
                 if (!oc->oformat->codec_tag ||
                      av_codec_get_id (oc->oformat->codec_tag, icodec->codec_tag) == codec->codec_id ||
-                     av_codec_get_tag(oc->oformat->codec_tag, icodec->codec_id) <= 0)
+                     !av_codec_get_tag2(oc->oformat->codec_tag, icodec->codec_id, &codec_tag))
                     codec->codec_tag = icodec->codec_tag;
             }
 
@@ -2084,6 +2188,12 @@
                     codec->time_base.num *= icodec->ticks_per_frame;
                 }
             }
+            if (   codec->codec_tag == AV_RL32("tmcd")
+                && icodec->time_base.num < icodec->time_base.den
+                && icodec->time_base.num > 0
+                && 121LL*icodec->time_base.num > icodec->time_base.den) {
+                codec->time_base = icodec->time_base;
+            }
 
             if(ost->frame_rate.num)
                 codec->time_base = av_inv_q(ost->frame_rate);
@@ -2103,7 +2213,7 @@
                 codec->frame_size         = icodec->frame_size;
                 codec->audio_service_type = icodec->audio_service_type;
                 codec->block_align        = icodec->block_align;
-                if((codec->block_align == 1 || codec->block_align == 1152) && codec->codec_id == AV_CODEC_ID_MP3)
+                if((codec->block_align == 1 || codec->block_align == 1152 || codec->block_align == 576) && codec->codec_id == AV_CODEC_ID_MP3)
                     codec->block_align= 0;
                 if(codec->codec_id == AV_CODEC_ID_AC3)
                     codec->block_align= 0;
@@ -2177,7 +2287,7 @@
                 codec->sample_fmt     = ost->filter->filter->inputs[0]->format;
                 codec->sample_rate    = ost->filter->filter->inputs[0]->sample_rate;
                 codec->channel_layout = ost->filter->filter->inputs[0]->channel_layout;
-                codec->channels       = av_get_channel_layout_nb_channels(codec->channel_layout);
+                codec->channels       = avfilter_link_get_channels(ost->filter->filter->inputs[0]);
                 codec->time_base      = (AVRational){ 1, codec->sample_rate };
                 break;
             case AVMEDIA_TYPE_VIDEO:
@@ -2209,9 +2319,23 @@
                     codec->bits_per_raw_sample = frame_bits_per_raw_sample;
                 }
 
-                if (ost->forced_keyframes)
-                    parse_forced_key_frames(ost->forced_keyframes, ost,
-                                            ost->st->codec);
+                if (ost->forced_keyframes) {
+                    if (!strncmp(ost->forced_keyframes, "expr:", 5)) {
+                        ret = av_expr_parse(&ost->forced_keyframes_pexpr, ost->forced_keyframes+5,
+                                            forced_keyframes_const_names, NULL, NULL, NULL, NULL, 0, NULL);
+                        if (ret < 0) {
+                            av_log(NULL, AV_LOG_ERROR,
+                                   "Invalid force_key_frames expression '%s'\n", ost->forced_keyframes+5);
+                            return ret;
+                        }
+                        ost->forced_keyframes_expr_const_values[FKF_N] = 0;
+                        ost->forced_keyframes_expr_const_values[FKF_N_FORCED] = 0;
+                        ost->forced_keyframes_expr_const_values[FKF_PREV_FORCED_N] = NAN;
+                        ost->forced_keyframes_expr_const_values[FKF_PREV_FORCED_T] = NAN;
+                    } else {
+                        parse_forced_key_frames(ost->forced_keyframes, ost, ost->st->codec);
+                    }
+                }
                 break;
             case AVMEDIA_TYPE_SUBTITLE:
                 codec->time_base = (AVRational){1, 1000};
@@ -2300,6 +2424,8 @@
 
             if (ost->st->codec->me_threshold)
                 input_streams[ost->source_index]->st->codec->debug |= FF_DEBUG_MV;
+        } else {
+            av_opt_set_dict(ost->st->codec, &ost->opts);
         }
     }
 
@@ -3089,6 +3215,8 @@
                 av_freep(&ost->st->codec->subtitle_header);
                 av_free(ost->forced_kf_pts);
                 av_dict_free(&ost->opts);
+                av_dict_free(&ost->swr_opts);
+                av_dict_free(&ost->resample_opts);
             }
         }
     }
@@ -3136,22 +3264,13 @@
 {
 }
 
-static void parse_cpuflags(int argc, char **argv, const OptionDef *options)
-{
-    int idx = locate_option(argc, argv, options, "cpuflags");
-    if (idx && argv[idx + 1])
-        opt_cpuflags(NULL, "cpuflags", argv[idx + 1]);
-}
-
 int main(int argc, char **argv)
 {
-    OptionsContext o = { 0 };
+    int ret;
     int64_t ti;
 
     atexit(exit_program);
 
-    reset_options(&o, 0);
-
     setvbuf(stderr,NULL,_IONBF,0); /* win32 runtime needs this */
 
     av_log_set_flags(AV_LOG_SKIP_REPEATED);
@@ -3176,10 +3295,10 @@
 
     term_init();
 
-    parse_cpuflags(argc, argv, options);
-
-    /* parse options */
-    parse_options(&o, argc, argv, options, opt_output_file);
+    /* parse options and open all input/output files */
+    ret = ffmpeg_parse_options(argc, argv);
+    if (ret < 0)
+        exit(1);
 
     if (nb_output_files <= 0 && nb_input_files == 0) {
         show_usage();
@@ -3207,6 +3326,6 @@
         printf("bench: utime=%0.3fs maxrss=%ikB\n", ti / 1000000.0, maxrss);
     }
 
-    exit(0);
+    exit(received_nb_signals ? 255 : 0);
     return 0;
 }
diff --git a/ffmpeg.h b/ffmpeg.h
index d260222..d7046fd 100644
--- a/ffmpeg.h
+++ b/ffmpeg.h
@@ -41,6 +41,7 @@
 
 #include "libavutil/avutil.h"
 #include "libavutil/dict.h"
+#include "libavutil/eval.h"
 #include "libavutil/fifo.h"
 #include "libavutil/pixfmt.h"
 #include "libavutil/rational.h"
@@ -71,6 +72,8 @@
 } AudioChannelMap;
 
 typedef struct OptionsContext {
+    OptionGroup *g;
+
     /* input/output options */
     int64_t start_time;
     const char *format;
@@ -111,6 +114,7 @@
     int chapters_input_file;
 
     int64_t recording_time;
+    int64_t stop_time;
     uint64_t limit_filesize;
     float mux_preload;
     float mux_max_delay;
@@ -169,6 +173,8 @@
     int        nb_pass;
     SpecifierOpt *passlogfiles;
     int        nb_passlogfiles;
+    SpecifierOpt *guess_layout_max;
+    int        nb_guess_layout_max;
 } OptionsContext;
 
 typedef struct InputFilter {
@@ -193,6 +199,7 @@
     const char    *graph_desc;
 
     AVFilterGraph *graph;
+    int reconfiguration;
 
     InputFilter   **inputs;
     int          nb_inputs;
@@ -227,6 +234,7 @@
     AVDictionary *opts;
     AVRational framerate;               /* framerate forced with -r */
     int top_field_first;
+    int guess_layout_max;
 
     int resample_height;
     int resample_width;
@@ -246,6 +254,7 @@
 
     struct sub2video {
         int64_t last_pts;
+        int64_t end_pts;
         AVFilterBufferRef *ref;
         int w, h;
     } sub2video;
@@ -283,6 +292,17 @@
 #endif
 } InputFile;
 
+enum forced_keyframes_const {
+    FKF_N,
+    FKF_N_FORCED,
+    FKF_PREV_FORCED_N,
+    FKF_PREV_FORCED_T,
+    FKF_T,
+    FKF_NB
+};
+
+extern const char *const forced_keyframes_const_names[];
+
 typedef struct OutputStream {
     int file_index;          /* file index */
     int index;               /* stream index in the output file */
@@ -314,6 +334,8 @@
     int forced_kf_count;
     int forced_kf_index;
     char *forced_keyframes;
+    AVExpr *forced_keyframes_pexpr;
+    double forced_keyframes_expr_const_values[FKF_NB];
 
     /* audio only */
     int audio_channels_map[SWR_CH_MAX];  /* list of the channels id to pick from the source stream */
@@ -326,10 +348,9 @@
     char *avfilter;
 
     int64_t sws_flags;
-    int64_t swr_filter_type;
-    int64_t swr_dither_method;
-    double swr_dither_scale;
     AVDictionary *opts;
+    AVDictionary *swr_opts;
+    AVDictionary *resample_opts;
     int finished;        /* no more packets should be written for this stream */
     int unavailable;                     /* true if the steram is unavailable (possibly temporarily) */
     int stream_copy;
@@ -412,4 +433,6 @@
 int ist_in_filtergraph(FilterGraph *fg, InputStream *ist);
 FilterGraph *init_simple_filtergraph(InputStream *ist, OutputStream *ost);
 
+int ffmpeg_parse_options(int argc, char **argv);
+
 #endif /* FFMPEG_H */
diff --git a/ffmpeg_filter.c b/ffmpeg_filter.c
index 5e37128..1919f78 100644
--- a/ffmpeg_filter.c
+++ b/ffmpeg_filter.c
@@ -24,6 +24,8 @@
 #include "libavfilter/avfiltergraph.h"
 #include "libavfilter/buffersink.h"
 
+#include "libavresample/avresample.h"
+
 #include "libavutil/avassert.h"
 #include "libavutil/avstring.h"
 #include "libavutil/bprint.h"
@@ -179,8 +181,7 @@
         exit(1);
     fg->index = nb_filtergraphs;
 
-    fg->outputs = grow_array(fg->outputs, sizeof(*fg->outputs), &fg->nb_outputs,
-                             fg->nb_outputs + 1);
+    GROW_ARRAY(fg->outputs, fg->nb_outputs);
     if (!(fg->outputs[0] = av_mallocz(sizeof(*fg->outputs[0]))))
         exit(1);
     fg->outputs[0]->ost   = ost;
@@ -188,19 +189,16 @@
 
     ost->filter = fg->outputs[0];
 
-    fg->inputs = grow_array(fg->inputs, sizeof(*fg->inputs), &fg->nb_inputs,
-                            fg->nb_inputs + 1);
+    GROW_ARRAY(fg->inputs, fg->nb_inputs);
     if (!(fg->inputs[0] = av_mallocz(sizeof(*fg->inputs[0]))))
         exit(1);
     fg->inputs[0]->ist   = ist;
     fg->inputs[0]->graph = fg;
 
-    ist->filters = grow_array(ist->filters, sizeof(*ist->filters),
-                              &ist->nb_filters, ist->nb_filters + 1);
+    GROW_ARRAY(ist->filters, ist->nb_filters);
     ist->filters[ist->nb_filters - 1] = fg->inputs[0];
 
-    filtergraphs = grow_array(filtergraphs, sizeof(*filtergraphs),
-                              &nb_filtergraphs, nb_filtergraphs + 1);
+    GROW_ARRAY(filtergraphs, nb_filtergraphs);
     filtergraphs[nb_filtergraphs - 1] = fg;
 
     return fg;
@@ -269,15 +267,13 @@
     ist->decoding_needed++;
     ist->st->discard = AVDISCARD_NONE;
 
-    fg->inputs = grow_array(fg->inputs, sizeof(*fg->inputs),
-                            &fg->nb_inputs, fg->nb_inputs + 1);
+    GROW_ARRAY(fg->inputs, fg->nb_inputs);
     if (!(fg->inputs[fg->nb_inputs - 1] = av_mallocz(sizeof(*fg->inputs[0]))))
         exit(1);
     fg->inputs[fg->nb_inputs - 1]->ist   = ist;
     fg->inputs[fg->nb_inputs - 1]->graph = fg;
 
-    ist->filters = grow_array(ist->filters, sizeof(*ist->filters),
-                              &ist->nb_filters, ist->nb_filters + 1);
+    GROW_ARRAY(ist->filters, ist->nb_filters);
     ist->filters[ist->nb_filters - 1] = fg->inputs[fg->nb_inputs - 1];
 }
 
@@ -373,12 +369,16 @@
     char *sample_fmts, *sample_rates, *channel_layouts;
     char name[255];
     int ret;
+    AVABufferSinkParams *params = av_abuffersink_params_alloc();
 
-
+    if (!params)
+        return AVERROR(ENOMEM);
+    params->all_channel_counts = 1;
     snprintf(name, sizeof(name), "output stream %d:%d", ost->file_index, ost->index);
     ret = avfilter_graph_create_filter(&ofilter->filter,
                                        avfilter_get_by_name("ffabuffersink"),
-                                       name, NULL, NULL, fg->graph);
+                                       name, NULL, params, fg->graph);
+    av_freep(&params);
     if (ret < 0)
         return ret;
 
@@ -523,12 +523,12 @@
         }
         av_log(avf, AV_LOG_INFO, "sub2video: using %dx%d canvas\n", w, h);
     }
-    ist->sub2video.w = ist->st->codec->width  = w;
-    ist->sub2video.h = ist->st->codec->height = h;
+    ist->sub2video.w = ist->st->codec->width  = ist->resample_width  = w;
+    ist->sub2video.h = ist->st->codec->height = ist->resample_height = h;
 
     /* rectangles are AV_PIX_FMT_PAL8, but we have no guarantee that the
        palettes for all rectangles are identical or compatible */
-    ist->st->codec->pix_fmt = AV_PIX_FMT_RGB32;
+    ist->resample_pix_fmt = ist->st->codec->pix_fmt = AV_PIX_FMT_RGB32;
 
     ret = av_image_alloc(image, linesize, w, h, AV_PIX_FMT_RGB32, 32);
     if (ret < 0)
@@ -562,8 +562,10 @@
 
     if (!ist->framerate.num && ist->st->codec->ticks_per_frame>1) {
         AVRational codec_fr = av_inv_q(ist->st->codec->time_base);
+        AVRational   avg_fr = ist->st->avg_frame_rate;
         codec_fr.den *= ist->st->codec->ticks_per_frame;
-        if(codec_fr.num>0 && codec_fr.den>0 && av_q2d(codec_fr) < av_q2d(fr)*0.7)
+        if (   codec_fr.num>0 && codec_fr.den>0 && av_q2d(codec_fr) < av_q2d(fr)*0.7
+            && fabs(1.0 - av_q2d(av_div_q(avg_fr, fr)))>0.1)
             fr = codec_fr;
     }
 
@@ -581,8 +583,8 @@
     av_bprint_init(&args, 0, 1);
     av_bprintf(&args,
              "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:"
-             "pixel_aspect=%d/%d:sws_param=flags=%d", ist->st->codec->width,
-             ist->st->codec->height, ist->st->codec->pix_fmt,
+             "pixel_aspect=%d/%d:sws_param=flags=%d", ist->resample_width,
+             ist->resample_height, ist->resample_pix_fmt,
              tb.num, tb.den, sar.num, sar.den,
              SWS_BILINEAR + ((ist->st->codec->flags&CODEC_FLAG_BITEXACT) ? SWS_BITEXACT:0));
     if (fr.num && fr.den)
@@ -624,20 +626,25 @@
     AVFilter *filter = avfilter_get_by_name("abuffer");
     InputStream *ist = ifilter->ist;
     int pad_idx = in->pad_idx;
-    char args[255], name[255];
+    AVBPrint args;
+    char name[255];
     int ret;
 
-    snprintf(args, sizeof(args), "time_base=%d/%d:sample_rate=%d:sample_fmt=%s"
-             ":channel_layout=0x%"PRIx64,
+    av_bprint_init(&args, 0, AV_BPRINT_SIZE_AUTOMATIC);
+    av_bprintf(&args, "time_base=%d/%d:sample_rate=%d:sample_fmt=%s",
              1, ist->st->codec->sample_rate,
              ist->st->codec->sample_rate,
-             av_get_sample_fmt_name(ist->st->codec->sample_fmt),
-             ist->st->codec->channel_layout);
+             av_get_sample_fmt_name(ist->st->codec->sample_fmt));
+    if (ist->st->codec->channel_layout)
+        av_bprintf(&args, ":channel_layout=0x%"PRIx64,
+                   ist->st->codec->channel_layout);
+    else
+        av_bprintf(&args, ":channels=%d", ist->st->codec->channels);
     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, args, NULL,
+                                            name, args.str, NULL,
                                             fg->graph)) < 0)
         return ret;
 
@@ -665,9 +672,11 @@
     if (audio_sync_method > 0) {
         char args[256] = {0};
 
-        av_strlcatf(args, sizeof(args), "min_comp=0.001:min_hard_comp=%f", audio_drift_threshold);
-        if (audio_sync_method > 1)
-            av_strlcatf(args, sizeof(args), ":max_soft_comp=%f", audio_sync_method/(double)ist->st->codec->sample_rate);
+        av_strlcatf(args, sizeof(args), "async=%d", audio_sync_method);
+        if (audio_drift_threshold != 0.1)
+            av_strlcatf(args, sizeof(args), ":min_hard_comp=%f", audio_drift_threshold);
+        if (!fg->reconfiguration)
+            av_strlcatf(args, sizeof(args), ":first_pts=0");
         AUTO_INSERT_FILTER_INPUT("-async", "aresample", args);
     }
 
@@ -687,6 +696,9 @@
     if (audio_volume != 256) {
         char args[256];
 
+        av_log(NULL, AV_LOG_WARNING, "-vol has been deprecated. Use the volume "
+               "audio filter instead.\n");
+
         snprintf(args, sizeof(args), "%f", audio_volume / 256.);
         AUTO_INSERT_FILTER_INPUT("-vol", "volume", args);
     }
@@ -722,20 +734,29 @@
 
     if (simple) {
         OutputStream *ost = fg->outputs[0]->ost;
-        char args[255];
+        char args[512];
+        AVDictionaryEntry *e = NULL;
+
         snprintf(args, sizeof(args), "flags=0x%X", (unsigned)ost->sws_flags);
         fg->graph->scale_sws_opts = av_strdup(args);
 
         args[0] = 0;
-        if (ost->swr_filter_type != SWR_FILTER_TYPE_KAISER)
-            av_strlcatf(args, sizeof(args), "filter_type=%d:", (int)ost->swr_filter_type);
-        if (ost->swr_dither_method)
-            av_strlcatf(args, sizeof(args), "dither_method=%d:", (int)ost->swr_dither_method);
-        if (ost->swr_dither_scale != 1.0)
-            av_strlcatf(args, sizeof(args), "dither_scale=%f:", ost->swr_dither_scale);
+        while ((e = av_dict_get(ost->swr_opts, "", e,
+                                AV_DICT_IGNORE_SUFFIX))) {
+            av_strlcatf(args, sizeof(args), "%s=%s:", e->key, e->value);
+        }
         if (strlen(args))
             args[strlen(args)-1] = 0;
         av_opt_set(fg->graph, "aresample_swr_opts", args, 0);
+
+        args[0] = '\0';
+        while ((e = av_dict_get(fg->outputs[0]->ost->resample_opts, "", e,
+                                AV_DICT_IGNORE_SUFFIX))) {
+            av_strlcatf(args, sizeof(args), "%s=%s:", e->key, e->value);
+        }
+        if (strlen(args))
+            args[strlen(args) - 1] = '\0';
+        fg->graph->resample_lavr_opts = av_strdup(args);
     }
 
     if ((ret = avfilter_graph_parse2(fg->graph, graph_desc, &inputs, &outputs)) < 0)
@@ -767,8 +788,7 @@
     } else {
         /* wait until output mappings are processed */
         for (cur = outputs; cur;) {
-            fg->outputs = grow_array(fg->outputs, sizeof(*fg->outputs),
-                                     &fg->nb_outputs, fg->nb_outputs + 1);
+            GROW_ARRAY(fg->outputs, fg->nb_outputs);
             if (!(fg->outputs[fg->nb_outputs - 1] = av_mallocz(sizeof(*fg->outputs[0]))))
                 exit(1);
             fg->outputs[fg->nb_outputs - 1]->graph   = fg;
@@ -778,6 +798,7 @@
         }
     }
 
+    fg->reconfiguration = 1;
     return 0;
 }
 
diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c
index c846a10..22d6e41 100644
--- a/ffmpeg_opt.c
+++ b/ffmpeg_opt.c
@@ -95,10 +95,11 @@
 static int do_psnr            = 0;
 static int input_sync;
 
-void reset_options(OptionsContext *o, int is_input)
+static int64_t recording_time = INT64_MAX;
+
+static void uninit_options(OptionsContext *o, int is_input)
 {
     const OptionDef *po = options;
-    OptionsContext bak= *o;
     int i;
 
     /* all OPT_SPEC and OPT_STRING can be freed in generic way */
@@ -125,36 +126,29 @@
     av_freep(&o->stream_maps);
     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)
+{
     memset(o, 0, sizeof(*o));
 
-    if (is_input) {
-        o->recording_time = bak.recording_time;
-        if (o->recording_time != INT64_MAX)
-            av_log(NULL, AV_LOG_WARNING,
-                   "-t is not an input option, keeping it for the next output;"
-                   " consider fixing your command line.\n");
+    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->recording_time = INT64_MAX;
+    o->stop_time = INT64_MAX;
     o->mux_max_delay  = 0.7;
     o->limit_filesize = UINT64_MAX;
     o->chapters_input_file = INT_MAX;
-
-    uninit_opts();
-    init_opts();
-}
-
-
-static int opt_frame_crop(void *optctx, const char *opt, const char *arg)
-{
-    av_log(NULL, AV_LOG_FATAL, "Option '%s' has been removed, use the crop filter instead\n", opt);
-    return AVERROR(EINVAL);
-}
-
-static int opt_pad(void *optctx, const char *opt, const char *arg)
-{
-    av_log(NULL, AV_LOG_FATAL, "Option '%s' has been removed, use the pad filter instead\n", opt);
-    return -1;
 }
 
 static int opt_sameq(void *optctx, const char *opt, const char *arg)
@@ -244,8 +238,7 @@
     if (map[0] == '[') {
         /* this mapping refers to lavfi output */
         const char *c = map + 1;
-        o->stream_maps = grow_array(o->stream_maps, sizeof(*o->stream_maps),
-                                    &o->nb_stream_maps, o->nb_stream_maps + 1);
+        GROW_ARRAY(o->stream_maps, o->nb_stream_maps);
         m = &o->stream_maps[o->nb_stream_maps - 1];
         m->linklabel = av_get_token(&c, "]");
         if (!m->linklabel) {
@@ -273,8 +266,7 @@
                 if (check_stream_specifier(input_files[file_idx]->ctx, input_files[file_idx]->ctx->streams[i],
                             *p == ':' ? p + 1 : p) <= 0)
                     continue;
-                o->stream_maps = grow_array(o->stream_maps, sizeof(*o->stream_maps),
-                                            &o->nb_stream_maps, o->nb_stream_maps + 1);
+                GROW_ARRAY(o->stream_maps, o->nb_stream_maps);
                 m = &o->stream_maps[o->nb_stream_maps - 1];
 
                 m->file_index   = file_idx;
@@ -302,8 +294,7 @@
 static int opt_attach(void *optctx, const char *opt, const char *arg)
 {
     OptionsContext *o = optctx;
-    o->attachments = grow_array(o->attachments, sizeof(*o->attachments),
-                                &o->nb_attachments, o->nb_attachments + 1);
+    GROW_ARRAY(o->attachments, o->nb_attachments);
     o->attachments[o->nb_attachments - 1] = arg;
     return 0;
 }
@@ -315,9 +306,7 @@
     AVStream *st;
     AudioChannelMap *m;
 
-    o->audio_channel_maps =
-        grow_array(o->audio_channel_maps, sizeof(*o->audio_channel_maps),
-                   &o->nb_audio_channel_maps, o->nb_audio_channel_maps + 1);
+    GROW_ARRAY(o->audio_channel_maps, o->nb_audio_channel_maps);
     m = &o->audio_channel_maps[o->nb_audio_channel_maps - 1];
 
     /* muted channel syntax */
@@ -565,14 +554,13 @@
         if (!ist)
             exit(1);
 
-        input_streams = grow_array(input_streams, sizeof(*input_streams), &nb_input_streams, nb_input_streams + 1);
+        GROW_ARRAY(input_streams, nb_input_streams);
         input_streams[nb_input_streams - 1] = ist;
 
         ist->st = st;
         ist->file_index = nb_input_files;
         ist->discard = 1;
         st->discard  = AVDISCARD_ALL;
-        ist->opts = filter_codec_opts(codec_opts, ist->st->codec->codec_id, ic, st, choose_decoder(o, ic, st));
 
         ist->ts_scale = 1.0;
         MATCH_PER_STREAM_OPT(ts_scale, dbl, ist->ts_scale, ic, st);
@@ -586,6 +574,7 @@
         }
 
         ist->dec = choose_decoder(o, ic, st);
+        ist->opts = filter_codec_opts(o->g->codec_opts, ist->st->codec->codec_id, ic, st, ist->dec);
 
         ist->reinit_filters = -1;
         MATCH_PER_STREAM_OPT(reinit_filters, i, ist->reinit_filters, ic, st);
@@ -617,6 +606,8 @@
 
             break;
         case AVMEDIA_TYPE_AUDIO:
+            ist->guess_layout_max = INT_MAX;
+            MATCH_PER_STREAM_OPT(guess_layout_max, i, ist->guess_layout_max, ic, st);
             guess_input_channel_layout(ist);
 
             ist->resample_sample_fmt     = dec->sample_fmt;
@@ -697,9 +688,8 @@
     avio_close(out);
 }
 
-static int opt_input_file(void *optctx, const char *opt, const char *filename)
+static int open_input_file(OptionsContext *o, const char *filename)
 {
-    OptionsContext *o = optctx;
     AVFormatContext *ic;
     AVInputFormat *file_iformat = NULL;
     int err, i, ret;
@@ -732,7 +722,7 @@
     }
     if (o->nb_audio_sample_rate) {
         snprintf(buf, sizeof(buf), "%d", o->audio_sample_rate[o->nb_audio_sample_rate - 1].u.i);
-        av_dict_set(&format_opts, "sample_rate", buf, 0);
+        av_dict_set(&o->g->format_opts, "sample_rate", buf, 0);
     }
     if (o->nb_audio_channels) {
         /* because we set audio_channels based on both the "ac" and
@@ -743,7 +733,7 @@
                         AV_OPT_SEARCH_FAKE_OBJ)) {
             snprintf(buf, sizeof(buf), "%d",
                      o->audio_channels[o->nb_audio_channels - 1].u.i);
-            av_dict_set(&format_opts, "channels", buf, 0);
+            av_dict_set(&o->g->format_opts, "channels", buf, 0);
         }
     }
     if (o->nb_frame_rates) {
@@ -752,15 +742,15 @@
         if (file_iformat && file_iformat->priv_class &&
             av_opt_find(&file_iformat->priv_class, "framerate", NULL, 0,
                         AV_OPT_SEARCH_FAKE_OBJ)) {
-            av_dict_set(&format_opts, "framerate",
+            av_dict_set(&o->g->format_opts, "framerate",
                         o->frame_rates[o->nb_frame_rates - 1].u.str, 0);
         }
     }
     if (o->nb_frame_sizes) {
-        av_dict_set(&format_opts, "video_size", o->frame_sizes[o->nb_frame_sizes - 1].u.str, 0);
+        av_dict_set(&o->g->format_opts, "video_size", o->frame_sizes[o->nb_frame_sizes - 1].u.str, 0);
     }
     if (o->nb_frame_pix_fmts)
-        av_dict_set(&format_opts, "pixel_format", o->frame_pix_fmts[o->nb_frame_pix_fmts - 1].u.str, 0);
+        av_dict_set(&o->g->format_opts, "pixel_format", o->frame_pix_fmts[o->nb_frame_pix_fmts - 1].u.str, 0);
 
     MATCH_PER_TYPE_OPT(codec_names, str,    video_codec_name, ic, "v");
     MATCH_PER_TYPE_OPT(codec_names, str,    audio_codec_name, ic, "a");
@@ -776,19 +766,19 @@
     ic->interrupt_callback = int_cb;
 
     /* open the input file with generic avformat function */
-    err = avformat_open_input(&ic, filename, file_iformat, &format_opts);
+    err = avformat_open_input(&ic, filename, file_iformat, &o->g->format_opts);
     if (err < 0) {
         print_error(filename, err);
         exit(1);
     }
-    assert_avoptions(format_opts);
+    assert_avoptions(o->g->format_opts);
 
     /* apply forced codec ids */
     for (i = 0; i < ic->nb_streams; i++)
         choose_decoder(o, ic, ic->streams[i]);
 
     /* Set AVCodecContext options for avformat_find_stream_info */
-    opts = setup_find_stream_info_opts(ic, codec_opts);
+    opts = setup_find_stream_info_opts(ic, o->g->codec_opts);
     orig_nb_streams = ic->nb_streams;
 
     /* If not enough info to get the stream parameters, we decode the
@@ -820,7 +810,7 @@
     /* dump the file content */
     av_dump_format(ic, nb_input_files, filename, 0);
 
-    input_files = grow_array(input_files, sizeof(*input_files), &nb_input_files, nb_input_files + 1);
+    GROW_ARRAY(input_files, nb_input_files);
     if (!(input_files[nb_input_files - 1] = av_mallocz(sizeof(*input_files[0]))))
         exit(1);
 
@@ -845,7 +835,6 @@
         av_dict_free(&opts[i]);
     av_freep(&opts);
 
-    reset_options(o, 1);
     return 0;
 }
 
@@ -928,8 +917,7 @@
     if (oc->nb_streams - 1 < o->nb_streamid_map)
         st->id = o->streamid_map[oc->nb_streams - 1];
 
-    output_streams = grow_array(output_streams, sizeof(*output_streams), &nb_output_streams,
-                                nb_output_streams + 1);
+    GROW_ARRAY(output_streams, nb_output_streams);
     if (!(ost = av_mallocz(sizeof(*ost))))
         exit(1);
     output_streams[nb_output_streams - 1] = ost;
@@ -943,7 +931,7 @@
         AVIOContext *s = NULL;
         char *buf = NULL, *arg = NULL, *preset = NULL;
 
-        ost->opts  = filter_codec_opts(codec_opts, ost->enc->id, oc, st, ost->enc);
+        ost->opts  = filter_codec_opts(o->g->codec_opts, ost->enc->id, oc, st, ost->enc);
 
         MATCH_PER_STREAM_OPT(presets, str, preset, oc, st);
         if (preset && (!(ret = get_preset_file_2(preset, ost->enc->name, &s)))) {
@@ -969,6 +957,8 @@
                    preset, ost->file_index, ost->index);
             exit(1);
         }
+    } else {
+        ost->opts = filter_codec_opts(o->g->codec_opts, AV_CODEC_ID_NONE, oc, st, NULL);
     }
 
     avcodec_get_context_defaults3(st->codec, ost->enc);
@@ -1014,10 +1004,13 @@
     if (oc->oformat->flags & AVFMT_GLOBALHEADER)
         st->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
 
-    av_opt_get_int(sws_opts, "sws_flags", 0, &ost->sws_flags);
-    av_opt_get_int   (swr_opts, "filter_type"  , 0, &ost->swr_filter_type);
-    av_opt_get_int   (swr_opts, "dither_method", 0, &ost->swr_dither_method);
-    av_opt_get_double(swr_opts, "dither_scale" , 0, &ost->swr_dither_scale);
+    av_opt_get_int(o->g->sws_opts, "sws_flags", 0, &ost->sws_flags);
+
+    av_dict_copy(&ost->swr_opts, o->g->swr_opts, 0);
+    if (ost->enc && av_get_exact_bits_per_sample(ost->enc->id) == 24)
+        av_dict_set(&ost->swr_opts, "output_sample_bits", "24", 0);
+
+    av_dict_copy(&ost->resample_opts, o->g->resample_opts, 0);
 
     ost->source_index = source_index;
     if (source_index >= 0) {
@@ -1147,8 +1140,6 @@
             if (p) p++;
         }
         video_enc->rc_override_count = i;
-        if (!video_enc->rc_initial_buffer_occupancy)
-            video_enc->rc_initial_buffer_occupancy = video_enc->rc_buffer_size * 3 / 4;
         video_enc->intra_dc_precision = intra_dc_precision - 8;
 
         if (do_psnr)
@@ -1159,9 +1150,11 @@
         if (do_pass) {
             if (do_pass & 1) {
                 video_enc->flags |= CODEC_FLAG_PASS1;
+                av_dict_set(&ost->opts, "flags", "+pass1", AV_DICT_APPEND);
             }
             if (do_pass & 2) {
                 video_enc->flags |= CODEC_FLAG_PASS2;
+                av_dict_set(&ost->opts, "flags", "+pass2", AV_DICT_APPEND);
             }
         }
 
@@ -1440,9 +1433,8 @@
     return 0;
 }
 
-void opt_output_file(void *optctx, const char *filename)
+static int open_output_file(OptionsContext *o, const char *filename)
 {
-    OptionsContext *o = optctx;
     AVFormatContext *oc;
     int i, j, err;
     AVOutputFormat *file_oformat;
@@ -1590,7 +1582,7 @@
 loop_end:
                 if (!ofilter) {
                     av_log(NULL, AV_LOG_FATAL, "Output with label '%s' does not exist "
-                           "in any defined filter graph.\n", map->linklabel);
+                           "in any defined filter graph, or was already used elsewhere.\n", map->linklabel);
                     exit(1);
                 }
                 init_output_filter(ofilter, o, oc);
@@ -1620,18 +1612,6 @@
         }
     }
 
-
-    for (i = nb_output_streams - oc->nb_streams; i < nb_output_streams; i++) { //for all streams of this output file
-        AVDictionaryEntry *e;
-        ost = output_streams[i];
-
-        if (   ost->stream_copy
-            && (e = av_dict_get(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);
-    }
-
     /* handle attached files */
     for (i = 0; i < o->nb_attachments; i++) {
         AVIOContext *pb;
@@ -1659,6 +1639,7 @@
         ost = new_attachment_stream(o, oc, -1);
         ost->stream_copy               = 0;
         ost->attachment_filename       = o->attachments[i];
+        ost->finished                  = 1;
         ost->st->codec->extradata      = attachment;
         ost->st->codec->extradata_size = len;
 
@@ -1667,7 +1648,32 @@
         avio_close(pb);
     }
 
-    output_files = grow_array(output_files, sizeof(*output_files), &nb_output_files, nb_output_files + 1);
+    for (i = nb_output_streams - oc->nb_streams; i < nb_output_streams; i++) { //for all streams of this output file
+        AVDictionaryEntry *e;
+        ost = output_streams[i];
+
+        if ((ost->stream_copy || ost->attachment_filename)
+            && (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);
+    }
+
+    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);
     if (!(output_files[nb_output_files - 1] = av_mallocz(sizeof(*output_files[0]))))
         exit(1);
 
@@ -1679,7 +1685,7 @@
     output_files[nb_output_files - 1]->start_time     = o->start_time;
     output_files[nb_output_files - 1]->limit_filesize = o->limit_filesize;
     output_files[nb_output_files - 1]->shortest       = o->shortest;
-    av_dict_copy(&output_files[nb_output_files - 1]->opts, format_opts, 0);
+    av_dict_copy(&output_files[nb_output_files - 1]->opts, o->g->format_opts, 0);
 
     /* check filename in case of an image number is expected */
     if (oc->oformat->flags & AVFMT_NEEDNUMBER) {
@@ -1804,7 +1810,7 @@
         }
     }
 
-    reset_options(o, 0);
+    return 0;
 }
 
 static int opt_target(void *optctx, const char *opt, const char *arg)
@@ -1859,22 +1865,23 @@
         opt_video_codec(o, "c:v", "mpeg1video");
         opt_audio_codec(o, "c:a", "mp2");
         parse_option(o, "f", "vcd", options);
+        av_dict_set(&o->g->codec_opts, "b:v", arg, 0);
 
         parse_option(o, "s", norm == PAL ? "352x288" : "352x240", options);
         parse_option(o, "r", frame_rates[norm], options);
-        opt_default(NULL, "g", norm == PAL ? "15" : "18");
+        av_dict_set(&o->g->codec_opts, "g", norm == PAL ? "15" : "18", 0);
 
-        opt_default(NULL, "b:v", "1150000");
-        opt_default(NULL, "maxrate", "1150000");
-        opt_default(NULL, "minrate", "1150000");
-        opt_default(NULL, "bufsize", "327680"); // 40*1024*8;
+        av_dict_set(&o->g->codec_opts, "b:v", "1150000", 0);
+        av_dict_set(&o->g->codec_opts, "maxrate", "1150000", 0);
+        av_dict_set(&o->g->codec_opts, "minrate", "1150000", 0);
+        av_dict_set(&o->g->codec_opts, "bufsize", "327680", 0); // 40*1024*8;
 
-        opt_default(NULL, "b:a", "224000");
+        av_dict_set(&o->g->codec_opts, "b:a", "224000", 0);
         parse_option(o, "ar", "44100", options);
         parse_option(o, "ac", "2", options);
 
-        opt_default(NULL, "packetsize", "2324");
-        opt_default(NULL, "muxrate", "1411200"); // 2352 * 75 * 8;
+        av_dict_set(&o->g->format_opts, "packetsize", "2324", 0);
+        av_dict_set(&o->g->format_opts, "muxrate", "1411200", 0); // 2352 * 75 * 8;
 
         /* We have to offset the PTS, so that it is consistent with the SCR.
            SCR starts at 36000, but the first two packs contain only padding
@@ -1891,18 +1898,18 @@
         parse_option(o, "s", norm == PAL ? "480x576" : "480x480", options);
         parse_option(o, "r", frame_rates[norm], options);
         parse_option(o, "pix_fmt", "yuv420p", options);
-        opt_default(NULL, "g", norm == PAL ? "15" : "18");
+        av_dict_set(&o->g->codec_opts, "g", norm == PAL ? "15" : "18", 0);
 
-        opt_default(NULL, "b:v", "2040000");
-        opt_default(NULL, "maxrate", "2516000");
-        opt_default(NULL, "minrate", "0"); // 1145000;
-        opt_default(NULL, "bufsize", "1835008"); // 224*1024*8;
-        opt_default(NULL, "scan_offset", "1");
+        av_dict_set(&o->g->codec_opts, "b:v", "2040000", 0);
+        av_dict_set(&o->g->codec_opts, "maxrate", "2516000", 0);
+        av_dict_set(&o->g->codec_opts, "minrate", "0", 0); // 1145000;
+        av_dict_set(&o->g->codec_opts, "bufsize", "1835008", 0); // 224*1024*8;
+        av_dict_set(&o->g->codec_opts, "scan_offset", "1", 0);
 
-        opt_default(NULL, "b:a", "224000");
+        av_dict_set(&o->g->codec_opts, "b:a", "224000", 0);
         parse_option(o, "ar", "44100", options);
 
-        opt_default(NULL, "packetsize", "2324");
+        av_dict_set(&o->g->format_opts, "packetsize", "2324", 0);
 
     } else if (!strcmp(arg, "dvd")) {
 
@@ -1913,17 +1920,17 @@
         parse_option(o, "s", norm == PAL ? "720x576" : "720x480", options);
         parse_option(o, "r", frame_rates[norm], options);
         parse_option(o, "pix_fmt", "yuv420p", options);
-        opt_default(NULL, "g", norm == PAL ? "15" : "18");
+        av_dict_set(&o->g->codec_opts, "g", norm == PAL ? "15" : "18", 0);
 
-        opt_default(NULL, "b:v", "6000000");
-        opt_default(NULL, "maxrate", "9000000");
-        opt_default(NULL, "minrate", "0"); // 1500000;
-        opt_default(NULL, "bufsize", "1835008"); // 224*1024*8;
+        av_dict_set(&o->g->codec_opts, "b:v", "6000000", 0);
+        av_dict_set(&o->g->codec_opts, "maxrate", "9000000", 0);
+        av_dict_set(&o->g->codec_opts, "minrate", "0", 0); // 1500000;
+        av_dict_set(&o->g->codec_opts, "bufsize", "1835008", 0); // 224*1024*8;
 
-        opt_default(NULL, "packetsize", "2048");  // from www.mpucoder.com: DVD sectors contain 2048 bytes of data, this is also the size of one pack.
-        opt_default(NULL, "muxrate", "10080000"); // from mplex project: data_rate = 1260000. mux_rate = data_rate * 8
+        av_dict_set(&o->g->format_opts, "packetsize", "2048", 0);  // from www.mpucoder.com: DVD sectors contain 2048 bytes of data, this is also the size of one pack.
+        av_dict_set(&o->g->format_opts, "muxrate", "10080000", 0); // from mplex project: data_rate = 1260000. mux_rate = data_rate * 8
 
-        opt_default(NULL, "b:a", "448000");
+        av_dict_set(&o->g->codec_opts, "b:a", "448000", 0);
         parse_option(o, "ar", "48000", options);
 
     } else if (!strncmp(arg, "dv", 2)) {
@@ -1981,6 +1988,26 @@
     return parse_option(o, "frames:d", arg, options);
 }
 
+static int opt_default_new(OptionsContext *o, const char *opt, const char *arg)
+{
+    int ret;
+    AVDictionary *cbak = codec_opts;
+    AVDictionary *fbak = format_opts;
+    codec_opts = NULL;
+    format_opts = NULL;
+
+    ret = opt_default(NULL, opt, arg);
+
+    av_dict_copy(&o->g->codec_opts , codec_opts, 0);
+    av_dict_copy(&o->g->format_opts, format_opts, 0);
+    av_dict_free(&codec_opts);
+    av_dict_free(&format_opts);
+    codec_opts = cbak;
+    format_opts = fbak;
+
+    return ret;
+}
+
 static int opt_preset(void *optctx, const char *opt, const char *arg)
 {
     OptionsContext *o = optctx;
@@ -1998,7 +2025,7 @@
         }else
             av_log(NULL, AV_LOG_FATAL, "File for preset '%s' not found\n", arg);
         exit(1);
-}
+    }
 
     while (fgets(line, sizeof(line), f)) {
         char *key = tmp_line, *value, *endptr;
@@ -2017,7 +2044,7 @@
         else if (!strcmp(key, "vcodec")) opt_video_codec   (o, key, value);
         else if (!strcmp(key, "scodec")) opt_subtitle_codec(o, key, value);
         else if (!strcmp(key, "dcodec")) opt_data_codec    (o, key, value);
-        else if (opt_default(NULL, key, value) < 0) {
+        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);
@@ -2043,9 +2070,11 @@
     OptionsContext *o = optctx;
     if(!strcmp(opt, "b")){
         av_log(NULL, AV_LOG_WARNING, "Please use -b:a or -b:v, -b is ambiguous\n");
-        return parse_option(o, "b:v", arg, options);
+        av_dict_set(&o->g->codec_opts, "b:v", arg, 0);
+        return 0;
     }
-    return opt_default(optctx, opt, arg);
+    av_dict_set(&o->g->codec_opts, opt, arg, 0);
+    return 0;
 }
 
 static int opt_qscale(void *optctx, const char *opt, const char *arg)
@@ -2068,10 +2097,11 @@
     OptionsContext *o = optctx;
     if(!strcmp(opt, "profile")){
         av_log(NULL, AV_LOG_WARNING, "Please use -profile:a or -profile:v, -profile is ambiguous\n");
-        return parse_option(o, "profile:v", arg, options);
+        av_dict_set(&o->g->codec_opts, "profile:v", arg, 0);
+        return 0;
     }
-    return opt_default(optctx, opt, arg);
-
+    av_dict_set(&o->g->codec_opts, opt, arg, 0);
+    return 0;
 }
 
 static int opt_video_filters(void *optctx, const char *opt, const char *arg)
@@ -2111,9 +2141,9 @@
     char *tcr = av_asprintf("timecode=%s", arg);
     int ret = parse_option(o, "metadata:g", tcr, options);
     if (ret >= 0)
-        ret = opt_default(optctx, "gop_timecode", arg);
+        ret = av_dict_set(&o->g->codec_opts, "gop_timecode", arg, 0);
     av_free(tcr);
-    return ret;
+    return 0;
 }
 
 static int opt_channel_layout(void *optctx, const char *opt, const char *arg)
@@ -2131,7 +2161,7 @@
         return AVERROR(EINVAL);
     }
     snprintf(layout_str, sizeof(layout_str), "%"PRIu64, layout);
-    ret = opt_default(NULL, opt, layout_str);
+    ret = opt_default_new(o, opt, layout_str);
     if (ret < 0)
         return ret;
 
@@ -2160,8 +2190,7 @@
 
 static int opt_filter_complex(void *optctx, const char *opt, const char *arg)
 {
-    filtergraphs = grow_array(filtergraphs, sizeof(*filtergraphs),
-                              &nb_filtergraphs, nb_filtergraphs + 1);
+    GROW_ARRAY(filtergraphs, nb_filtergraphs);
     if (!(filtergraphs[nb_filtergraphs - 1] = av_mallocz(sizeof(*filtergraphs[0]))))
         return AVERROR(ENOMEM);
     filtergraphs[nb_filtergraphs - 1]->index       = nb_filtergraphs - 1;
@@ -2242,6 +2271,94 @@
     av_log(NULL, AV_LOG_INFO, "\n");
 }
 
+enum OptGroup {
+    GROUP_OUTFILE,
+    GROUP_INFILE,
+};
+
+static const OptionGroupDef groups[] = {
+    [GROUP_OUTFILE] = { "output file",  NULL },
+    [GROUP_INFILE]  = { "input file",   "i"  },
+};
+
+static int open_files(OptionGroupList *l, const char *inout,
+                      int (*open_file)(OptionsContext*, const char*))
+{
+    int i, ret;
+
+    for (i = 0; i < l->nb_groups; i++) {
+        OptionGroup *g = &l->groups[i];
+        OptionsContext o;
+
+        init_options(&o, !strcmp(inout, "input"));
+        o.g = g;
+
+        ret = parse_optgroup(&o, g);
+        if (ret < 0) {
+            av_log(NULL, AV_LOG_ERROR, "Error parsing options for %s file "
+                   "%s.\n", inout, g->arg);
+            return ret;
+        }
+
+        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"));
+        if (ret < 0) {
+            av_log(NULL, AV_LOG_ERROR, "Error opening %s file %s.\n",
+                   inout, g->arg);
+            return ret;
+        }
+        av_log(NULL, AV_LOG_DEBUG, "Successfully opened the file.\n");
+    }
+
+    return 0;
+}
+
+int ffmpeg_parse_options(int argc, char **argv)
+{
+    OptionParseContext octx;
+    uint8_t error[128];
+    int ret;
+
+    memset(&octx, 0, sizeof(octx));
+
+    /* split the commandline into an internal representation */
+    ret = split_commandline(&octx, argc, argv, options, groups,
+                            FF_ARRAY_ELEMS(groups));
+    if (ret < 0) {
+        av_log(NULL, AV_LOG_FATAL, "Error splitting the argument list: ");
+        goto fail;
+    }
+
+    /* apply global options */
+    ret = parse_optgroup(NULL, &octx.global_opts);
+    if (ret < 0) {
+        av_log(NULL, AV_LOG_FATAL, "Error parsing global options: ");
+        goto fail;
+    }
+
+    /* open input files */
+    ret = open_files(&octx.groups[GROUP_INFILE], "input", open_input_file);
+    if (ret < 0) {
+        av_log(NULL, AV_LOG_FATAL, "Error opening input files: ");
+        goto fail;
+    }
+
+    /* open output files */
+    ret = open_files(&octx.groups[GROUP_OUTFILE], "output", open_output_file);
+    if (ret < 0) {
+        av_log(NULL, AV_LOG_FATAL, "Error opening output files: ");
+        goto fail;
+    }
+
+fail:
+    uninit_parse_context(&octx);
+    if (ret < 0) {
+        av_strerror(ret, error, sizeof(error));
+        av_log(NULL, AV_LOG_FATAL, "%s\n", error);
+    }
+    return ret;
+}
 
 static int opt_progress(void *optctx, const char *opt, const char *arg)
 {
@@ -2266,8 +2383,6 @@
 #include "cmdutils_common_opts.h"
     { "f",              HAS_ARG | OPT_STRING | OPT_OFFSET,           { .off       = OFFSET(format) },
         "force format", "fmt" },
-    { "i",              HAS_ARG | OPT_PERFILE,                       { .func_arg = opt_input_file },
-        "input file name", "filename" },
     { "y",              OPT_BOOL,                                    {              &file_overwrite },
         "overwrite output files" },
     { "n",              OPT_BOOL,                                    {              &no_file_overwrite },
@@ -2291,6 +2406,8 @@
     { "t",              HAS_ARG | OPT_TIME | OPT_OFFSET,             { .off = OFFSET(recording_time) },
         "record or transcode \"duration\" seconds of audio/video",
         "duration" },
+    { "to",             HAS_ARG | OPT_TIME | OPT_OFFSET,             { .off = OFFSET(stop_time) },
+        "record or transcode stop time", "time_stop" },
     { "fs",             HAS_ARG | OPT_INT64 | OPT_OFFSET,            { .off = OFFSET(limit_filesize) },
         "set the limit file size in bytes", "limit_size" },
     { "ss",             HAS_ARG | OPT_TIME | OPT_OFFSET,             { .off = OFFSET(start_time) },
@@ -2357,7 +2474,7 @@
     { "profile",        HAS_ARG | OPT_EXPERT | OPT_PERFILE,          { .func_arg = opt_profile },
         "set profile", "profile" },
     { "filter",         HAS_ARG | OPT_STRING | OPT_SPEC,             { .off = OFFSET(filters) },
-        "set stream filterchain", "filter_list" },
+        "set stream filtergraph", "filter_graph" },
     { "reinit_filter",  HAS_ARG | OPT_INT | OPT_SPEC,                { .off = OFFSET(reinit_filters) },
         "reinit filtergraph on input parameter changes", "" },
     { "filter_complex", HAS_ARG | OPT_EXPERT,                        { .func_arg = opt_filter_complex },
@@ -2384,24 +2501,6 @@
         "set pixel format", "format" },
     { "bits_per_raw_sample", OPT_VIDEO | OPT_INT | HAS_ARG,                      { &frame_bits_per_raw_sample },
         "set the number of bits per raw sample", "number" },
-    { "croptop",      OPT_VIDEO | HAS_ARG,                                       { .func_arg = opt_frame_crop },
-        "Removed, use the crop filter instead", "size" },
-    { "cropbottom",   OPT_VIDEO | HAS_ARG,                                       { .func_arg = opt_frame_crop },
-        "Removed, use the crop filter instead", "size" },
-    { "cropleft",     OPT_VIDEO | HAS_ARG,                                       { .func_arg = opt_frame_crop },
-        "Removed, use the crop filter instead", "size" },
-    { "cropright",    OPT_VIDEO | HAS_ARG,                                       { .func_arg = opt_frame_crop },
-        "Removed, use the crop filter instead", "size" },
-    { "padtop",       OPT_VIDEO | HAS_ARG,                                       { .func_arg = opt_pad },
-        "Removed, use the pad filter instead", "size" },
-    { "padbottom",    OPT_VIDEO | HAS_ARG,                                       { .func_arg = opt_pad },
-        "Removed, use the pad filter instead", "size" },
-    { "padleft",      OPT_VIDEO | HAS_ARG,                                       { .func_arg = opt_pad },
-        "Removed, use the pad filter instead", "size" },
-    { "padright",     OPT_VIDEO | HAS_ARG,                                       { .func_arg = opt_pad },
-        "Removed, use the pad filter instead", "size" },
-    { "padcolor",     OPT_VIDEO | HAS_ARG,                                       { .func_arg = opt_pad },
-        "Removed, use the pad filter instead", "color" },
     { "intra",        OPT_VIDEO | OPT_BOOL | OPT_EXPERT,                         { &intra_only },
         "deprecated use -g 1" },
     { "vn",           OPT_VIDEO | OPT_BOOL  | OPT_OFFSET,                        { .off = OFFSET(video_disable) },
@@ -2431,7 +2530,7 @@
     { "vstats_file",  OPT_VIDEO | HAS_ARG | OPT_EXPERT ,                         { opt_vstats_file },
         "dump video coding statistics to file", "file" },
     { "vf",           OPT_VIDEO | HAS_ARG  | OPT_PERFILE,                        { .func_arg = opt_video_filters },
-        "video filters", "filter list" },
+        "set video filters", "filter_graph" },
     { "intra_matrix", OPT_VIDEO | HAS_ARG | OPT_EXPERT  | OPT_STRING | OPT_SPEC, { .off = OFFSET(intra_matrices) },
         "specify intra matrix coeffs", "matrix" },
     { "inter_matrix", OPT_VIDEO | HAS_ARG | OPT_EXPERT  | OPT_STRING | OPT_SPEC, { .off = OFFSET(inter_matrices) },
@@ -2476,7 +2575,9 @@
     { "channel_layout", OPT_AUDIO | HAS_ARG  | OPT_EXPERT | OPT_PERFILE,           { .func_arg = opt_channel_layout },
         "set channel layout", "layout" },
     { "af",             OPT_AUDIO | HAS_ARG  | OPT_PERFILE,                        { .func_arg = opt_audio_filters },
-        "audio filters", "filter list" },
+        "set audio filters", "filter_graph" },
+    { "guess_layout_max", OPT_AUDIO | HAS_ARG | OPT_INT | OPT_SPEC | OPT_EXPERT,   { .off = OFFSET(guess_layout_max) },
+      "set the maximum number of channels to try to guess the channel layout" },
 
     /* subtitle options */
     { "sn",     OPT_SUBTITLE | OPT_BOOL | OPT_OFFSET, { .off = OFFSET(subtitle_disable) },
@@ -2522,7 +2623,5 @@
     { "dn", OPT_BOOL | OPT_VIDEO | OPT_OFFSET, { .off = OFFSET(data_disable) },
         "disable data" },
 
-    { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default },
-        "generic catch all option", "" },
     { NULL, },
 };
diff --git a/ffplay.c b/ffplay.c
index d6b17c2..01ee15e 100644
--- a/ffplay.c
+++ b/ffplay.c
@@ -86,10 +86,15 @@
 /* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
 #define AUDIO_DIFF_AVG_NB   20
 
+/* polls for possible required screen refresh at least this often, should be less than 1/fps */
+#define REFRESH_RATE 0.01
+
 /* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
 /* TODO: We assume that a decoded and resampled frame fits into this buffer */
 #define SAMPLE_ARRAY_SIZE (8 * 65536)
 
+#define CURSOR_HIDE_DELAY 1000000
+
 static int64_t sws_flags = SWS_BICUBIC;
 
 typedef struct MyAVPacketList {
@@ -114,7 +119,6 @@
 typedef struct VideoPicture {
     double pts;             // presentation timestamp for this picture
     int64_t pos;            // byte position in file
-    int skip;
     SDL_Overlay *bmp;
     int width, height; /* source height & width */
     AVRational sample_aspect_ratio;
@@ -135,7 +139,7 @@
 typedef struct AudioParams {
     int freq;
     int channels;
-    int channel_layout;
+    int64_t channel_layout;
     enum AVSampleFormat fmt;
 } AudioParams;
 
@@ -148,14 +152,13 @@
 typedef struct VideoState {
     SDL_Thread *read_tid;
     SDL_Thread *video_tid;
-    SDL_Thread *refresh_tid;
     AVInputFormat *iformat;
     int no_background;
     int abort_request;
     int force_refresh;
     int paused;
     int last_paused;
-    int que_attachments_req;
+    int queue_attachments_req;
     int seek_req;
     int seek_flags;
     int64_t seek_pos;
@@ -173,6 +176,7 @@
     double external_clock_speed;             ///< speed of the external clock
 
     double audio_clock;
+    int audio_clock_serial;
     double audio_diff_cum; /* used for AV difference average computation */
     double audio_diff_avg_coef;
     double audio_diff_threshold;
@@ -180,11 +184,11 @@
     AVStream *audio_st;
     PacketQueue audioq;
     int audio_hw_buf_size;
-    DECLARE_ALIGNED(16,uint8_t,audio_buf2)[AVCODEC_MAX_AUDIO_FRAME_SIZE * 4];
     uint8_t silence_buf[SDL_AUDIO_BUFFER_SIZE];
     uint8_t *audio_buf;
     uint8_t *audio_buf1;
     unsigned int audio_buf_size; /* in bytes */
+    unsigned int audio_buf1_size;
     int audio_buf_index; /* in bytes */
     int audio_write_buf_size;
     AVPacket audio_pkt_temp;
@@ -209,6 +213,7 @@
     int rdft_bits;
     FFTSample *rdft_data;
     int xpos;
+    double last_vis_time;
 
     SDL_Thread *subtitle_tid;
     int subtitle_stream;
@@ -227,14 +232,14 @@
     double frame_last_returned_time;
     double frame_last_filter_delay;
     int64_t frame_last_dropped_pos;
-    double video_clock;             // pts of last decoded frame / predicted pts of next decoded frame
     int video_stream;
     AVStream *video_st;
     PacketQueue videoq;
-    double video_current_pts;       // current displayed pts (different from video_clock if frame fifos are used)
+    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;
@@ -255,7 +260,6 @@
     FrameBuffer *buffer_pool;
 #endif
 
-    int refresh;
     int last_video_stream, last_audio_stream, last_subtitle_stream;
 
     SDL_cond *continue_read_thread;
@@ -267,10 +271,13 @@
 static const char *window_title;
 static int fs_screen_width;
 static int fs_screen_height;
+static int default_width  = 640;
+static int default_height = 480;
 static int screen_width  = 0;
 static int screen_height = 0;
 static int audio_disable;
 static int video_disable;
+static int subtitle_disable;
 static int wanted_stream[AVMEDIA_TYPE_NB] = {
     [AVMEDIA_TYPE_AUDIO]    = -1,
     [AVMEDIA_TYPE_VIDEO]    = -1,
@@ -302,7 +309,9 @@
 static const char *audio_codec_name;
 static const char *subtitle_codec_name;
 static const char *video_codec_name;
-static int rdftspeed = 20;
+double rdftspeed = 0.02;
+static int64_t cursor_last_shown;
+static int cursor_hidden = 0;
 #if CONFIG_AVFILTER
 static char *vfilters = NULL;
 #endif
@@ -314,7 +323,6 @@
 static AVPacket flush_pkt;
 
 #define FF_ALLOC_EVENT   (SDL_USEREVENT)
-#define FF_REFRESH_EVENT (SDL_USEREVENT + 1)
 #define FF_QUIT_EVENT    (SDL_USEREVENT + 2)
 
 static SDL_Surface *screen;
@@ -824,7 +832,7 @@
 {
     int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
     int ch, channels, h, h2, bgcolor, fgcolor;
-    int16_t time_diff;
+    int64_t time_diff;
     int rdft_bits, nb_freq;
 
     for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
@@ -967,7 +975,6 @@
     /* XXX: use a special url_shutdown call to abort parse cleanly */
     is->abort_request = 1;
     SDL_WaitThread(is->read_tid, NULL);
-    SDL_WaitThread(is->refresh_tid, NULL);
     packet_queue_destroy(&is->videoq);
     packet_queue_destroy(&is->audioq);
     packet_queue_destroy(&is->subtitleq);
@@ -989,8 +996,7 @@
     SDL_DestroyCond(is->subpq_cond);
     SDL_DestroyCond(is->continue_read_thread);
 #if !CONFIG_AVFILTER
-    if (is->img_convert_ctx)
-        sws_freeContext(is->img_convert_ctx);
+    sws_freeContext(is->img_convert_ctx);
 #endif
     av_free(is);
 }
@@ -1019,29 +1025,30 @@
     exit(123);
 }
 
-static int video_open(VideoState *is, int force_set_video_mode)
+static int video_open(VideoState *is, int force_set_video_mode, VideoPicture *vp)
 {
     int flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
     int w,h;
-    VideoPicture *vp = &is->pictq[is->pictq_rindex];
     SDL_Rect rect;
 
     if (is_full_screen) flags |= SDL_FULLSCREEN;
     else                flags |= SDL_RESIZABLE;
 
+    if (vp && vp->width) {
+        calculate_display_rect(&rect, 0, 0, INT_MAX, vp->height, vp);
+        default_width  = rect.w;
+        default_height = rect.h;
+    }
+
     if (is_full_screen && fs_screen_width) {
         w = fs_screen_width;
         h = fs_screen_height;
     } else if (!is_full_screen && screen_width) {
         w = screen_width;
         h = screen_height;
-    } else if (vp->width) {
-        calculate_display_rect(&rect, 0, 0, INT_MAX, vp->height, vp);
-        w = rect.w;
-        h = rect.h;
     } else {
-        w = 640;
-        h = 480;
+        w = default_width;
+        h = default_height;
     }
     if (screen && is->width == screen->w && screen->w == w
        && is->height== screen->h && screen->h == h && !force_set_video_mode)
@@ -1065,33 +1072,18 @@
 static void video_display(VideoState *is)
 {
     if (!screen)
-        video_open(is, 0);
+        video_open(is, 0, NULL);
     if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
         video_audio_display(is);
     else if (is->video_st)
         video_image_display(is);
 }
 
-static int refresh_thread(void *opaque)
-{
-    VideoState *is= opaque;
-    while (!is->abort_request) {
-        SDL_Event event;
-        event.type = FF_REFRESH_EVENT;
-        event.user.data1 = opaque;
-        if (!is->refresh && (!is->paused || is->force_refresh)) {
-            is->refresh = 1;
-            SDL_PushEvent(&event);
-        }
-        //FIXME ideally we should wait the correct time but SDLs event passing is so slow it would be silly
-        av_usleep(is->audio_st && is->show_mode != SHOW_MODE_VIDEO ? rdftspeed*1000 : 5000);
-    }
-    return 0;
-}
-
 /* get the current audio clock value */
 static double get_audio_clock(VideoState *is)
 {
+    if (is->audio_clock_serial != is->audioq.serial)
+        return NAN;
     if (is->paused) {
         return is->audio_current_pts;
     } else {
@@ -1102,6 +1094,8 @@
 /* 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 {
@@ -1163,7 +1157,8 @@
 }
 
 static void check_external_clock_sync(VideoState *is, double pts) {
-    if (fabs(get_external_clock(is) - pts) > AV_NOSYNC_THRESHOLD) {
+    double ext_clock = get_external_clock(is);
+    if (isnan(ext_clock) || fabs(ext_clock - pts) > AV_NOSYNC_THRESHOLD) {
         update_external_clock_pts(is, pts);
     }
 }
@@ -1197,6 +1192,7 @@
         if (seek_by_bytes)
             is->seek_flags |= AVSEEK_FLAG_BYTE;
         is->seek_req = 1;
+        SDL_CondSignal(is->continue_read_thread);
     }
 }
 
@@ -1214,6 +1210,20 @@
     is->paused = !is->paused;
 }
 
+static void toggle_pause(VideoState *is)
+{
+    stream_toggle_pause(is);
+    is->step = 0;
+}
+
+static void step_to_next_frame(VideoState *is)
+{
+    /* if the stream is paused unpause it, then step */
+    if (is->paused)
+        stream_toggle_pause(is);
+    is->step = 1;
+}
+
 static double compute_target_delay(double delay, VideoState *is)
 {
     double sync_threshold, diff;
@@ -1228,7 +1238,7 @@
            delay to compute the threshold. I still don't know
            if it is the best guess */
         sync_threshold = FFMAX(AV_SYNC_THRESHOLD, delay);
-        if (fabs(diff) < AV_NOSYNC_THRESHOLD) {
+        if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
             if (diff <= -sync_threshold)
                 delay = 0;
             else if (diff >= sync_threshold)
@@ -1253,20 +1263,23 @@
     SDL_UnlockMutex(is->pictq_mutex);
 }
 
-static void pictq_prev_picture(VideoState *is) {
+static int pictq_prev_picture(VideoState *is) {
     VideoPicture *prevvp;
+    int ret = 0;
     /* update queue size and signal for the previous picture */
     prevvp = &is->pictq[(is->pictq_rindex + VIDEO_PICTURE_QUEUE_SIZE - 1) % VIDEO_PICTURE_QUEUE_SIZE];
-    if (prevvp->allocated && !prevvp->skip) {
+    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_rindex == -1)
                 is->pictq_rindex = VIDEO_PICTURE_QUEUE_SIZE - 1;
             is->pictq_size++;
+            ret = 1;
         }
         SDL_CondSignal(is->pictq_cond);
         SDL_UnlockMutex(is->pictq_mutex);
     }
+    return ret;
 }
 
 static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
@@ -1276,12 +1289,13 @@
     is->video_current_pts_drift = is->video_current_pts - time;
     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 */
-static void video_refresh(void *opaque)
+static void video_refresh(void *opaque, double *remaining_time)
 {
     VideoState *is = opaque;
     VideoPicture *vp;
@@ -1292,9 +1306,19 @@
     if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
         check_external_clock_speed(is);
 
+    if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
+        time = av_gettime() / 1000000.0;
+        if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
+            video_display(is);
+            is->last_vis_time = time;
+        }
+        *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
+    }
+
     if (is->video_st) {
+        int redisplay = 0;
         if (is->force_refresh)
-            pictq_prev_picture(is);
+            redisplay = pictq_prev_picture(is);
 retry:
         if (is->pictq_size == 0) {
             SDL_LockMutex(is->pictq_mutex);
@@ -1303,14 +1327,15 @@
                 is->frame_last_dropped_pts = AV_NOPTS_VALUE;
             }
             SDL_UnlockMutex(is->pictq_mutex);
-            // nothing to do, no picture to display in the que
+            // nothing to do, no picture to display in the queue
         } else {
             double last_duration, duration, delay;
             /* dequeue the picture */
             vp = &is->pictq[is->pictq_rindex];
 
-            if (vp->skip) {
+            if (vp->serial != is->videoq.serial) {
                 pictq_next_picture(is);
+                redisplay = 0;
                 goto retry;
             }
 
@@ -1326,8 +1351,10 @@
             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) {
+                *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));
@@ -1339,9 +1366,11 @@
             if (is->pictq_size > 1) {
                 VideoPicture *nextvp = &is->pictq[(is->pictq_rindex + 1) % VIDEO_PICTURE_QUEUE_SIZE];
                 duration = nextvp->pts - vp->pts;
-                if((framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
-                    is->frame_drops_late++;
+                if(!is->step && (redisplay || framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
+                    if (!redisplay)
+                        is->frame_drops_late++;
                     pictq_next_picture(is);
+                    redisplay = 0;
                     goto retry;
                 }
             }
@@ -1392,20 +1421,14 @@
 
 display:
             /* display picture */
-            if (!display_disable)
+            if (!display_disable && is->show_mode == SHOW_MODE_VIDEO)
                 video_display(is);
 
             pictq_next_picture(is);
+
+            if (is->step && !is->paused)
+                stream_toggle_pause(is);
         }
-    } else if (is->audio_st) {
-        /* draw the next audio frame */
-
-        /* if only audio stream, then display the audio bars (better
-           than nothing, just to test the implementation */
-
-        /* display picture */
-        if (!display_disable)
-            video_display(is);
     }
     is->force_refresh = 0;
     if (show_status) {
@@ -1458,7 +1481,7 @@
     avfilter_unref_bufferp(&vp->picref);
 #endif
 
-    video_open(is, 0);
+    video_open(is, 0, vp);
 
     vp->bmp = SDL_CreateYUVOverlay(vp->width, vp->height,
                                    SDL_YV12_OVERLAY,
@@ -1478,29 +1501,31 @@
     SDL_UnlockMutex(is->pictq_mutex);
 }
 
-static int queue_picture(VideoState *is, AVFrame *src_frame, double pts1, int64_t pos, int serial)
+static void duplicate_right_border_pixels(SDL_Overlay *bmp) {
+    int i, width, height;
+    Uint8 *p, *maxp;
+    for (i = 0; i < 3; i++) {
+        width  = bmp->w;
+        height = bmp->h;
+        if (i > 0) {
+            width  >>= 1;
+            height >>= 1;
+        }
+        if (bmp->pitches[i] > width) {
+            maxp = bmp->pixels[i] + bmp->pitches[i] * height - 1;
+            for (p = bmp->pixels[i] + width - 1; p < maxp; p += bmp->pitches[i])
+                *(p+1) = *p;
+        }
+    }
+}
+
+static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, int64_t pos, int serial)
 {
     VideoPicture *vp;
-    double frame_delay, pts = pts1;
-
-    /* compute the exact PTS for the picture if it is omitted in the stream
-     * pts1 is the dts of the pkt / pts of the frame */
-    if (pts != 0) {
-        /* update video clock with pts, if present */
-        is->video_clock = pts;
-    } else {
-        pts = is->video_clock;
-    }
-    /* update video clock for next frame */
-    frame_delay = av_q2d(is->video_st->codec->time_base);
-    /* for MPEG2, the frame can be repeated, so we update the
-       clock accordingly */
-    frame_delay += src_frame->repeat_pict * (frame_delay * 0.5);
-    is->video_clock += frame_delay;
 
 #if defined(DEBUG_SYNC) && 0
-    printf("frame_type=%c clock=%0.3f pts=%0.3f\n",
-           av_get_picture_type_char(src_frame->pict_type), pts, pts1);
+    printf("frame_type=%c pts=%0.3f\n",
+           av_get_picture_type_char(src_frame->pict_type), pts);
 #endif
 
     /* wait until we have space to put a new picture */
@@ -1593,12 +1618,13 @@
         sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
                   0, vp->height, pict.data, pict.linesize);
 #endif
+        /* workaround SDL PITCH_WORKAROUND */
+        duplicate_right_border_pixels(vp->bmp);
         /* update the bitmap content */
         SDL_UnlockYUVOverlay(vp->bmp);
 
         vp->pts = pts;
         vp->pos = pos;
-        vp->skip = 0;
         vp->serial = serial;
 
         /* now we can update the picture count */
@@ -1613,7 +1639,7 @@
 
 static int get_video_frame(VideoState *is, AVFrame *frame, int64_t *pts, AVPacket *pkt, int *serial)
 {
-    int got_picture, i;
+    int got_picture;
 
     if (packet_queue_get(&is->videoq, pkt, 1, serial) < 0)
         return -1;
@@ -1622,10 +1648,7 @@
         avcodec_flush_buffers(is->video_st->codec);
 
         SDL_LockMutex(is->pictq_mutex);
-        // Make sure there are no long delay timers (ideally we should just flush the que but thats harder)
-        for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++) {
-            is->pictq[i].skip = 1;
-        }
+        // Make sure there are no long delay timers (ideally we should just flush the queue but that's harder)
         while (is->pictq_size && !is->videoq.abort_request) {
             SDL_CondWait(is->pictq_cond, is->pictq_mutex);
         }
@@ -1663,7 +1686,7 @@
                 double clockdiff = get_video_clock(is) - get_master_clock(is);
                 double dpts = av_q2d(is->video_st->time_base) * *pts;
                 double ptsdiff = dpts - is->frame_last_pts;
-                if (fabs(clockdiff) < AV_NOSYNC_THRESHOLD &&
+                if (!isnan(clockdiff) && fabs(clockdiff) < AV_NOSYNC_THRESHOLD &&
                      ptsdiff > 0 && ptsdiff < AV_NOSYNC_THRESHOLD &&
                      clockdiff + ptsdiff - is->frame_last_filter_delay < 0) {
                     is->frame_last_dropped_pos = pkt->pos;
@@ -1719,7 +1742,7 @@
     return ret;
 }
 
-static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters)
+static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
 {
     static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE };
     char sws_flags_str[128];
@@ -1732,12 +1755,13 @@
     if (!buffersink_params)
         return AVERROR(ENOMEM);
 
+    av_opt_get_int(sws_opts, "sws_flags", 0, &sws_flags);
     snprintf(sws_flags_str, sizeof(sws_flags_str), "flags=%"PRId64, sws_flags);
     graph->scale_sws_opts = av_strdup(sws_flags_str);
 
     snprintf(buffersrc_args, sizeof(buffersrc_args),
              "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
-             codec->width, codec->height, codec->pix_fmt,
+             frame->width, frame->height, frame->format,
              is->video_st->time_base.num, is->video_st->time_base.den,
              codec->sample_aspect_ratio.num, FFMAX(codec->sample_aspect_ratio.den, 1));
 
@@ -1793,6 +1817,7 @@
     int last_w = 0;
     int last_h = 0;
     enum AVPixelFormat last_format = -2;
+    int last_serial = -1;
 
     if (codec->codec->capabilities & CODEC_CAP_DR1) {
         is->use_dr1 = 1;
@@ -1821,14 +1846,19 @@
             continue;
 
 #if CONFIG_AVFILTER
-        if (   last_w != is->video_st->codec->width
-            || last_h != is->video_st->codec->height
-            || last_format != is->video_st->codec->pix_fmt) {
-            av_log(NULL, AV_LOG_INFO, "Frame changed from size:%dx%d to size:%dx%d\n",
-                   last_w, last_h, is->video_st->codec->width, is->video_st->codec->height);
+        if (   last_w != frame->width
+            || last_h != frame->height
+            || last_format != frame->format
+            || last_serial != serial) {
+            av_log(NULL, AV_LOG_DEBUG,
+                   "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
+                   last_w, last_h,
+                   (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
+                   frame->width, frame->height,
+                   (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), serial);
             avfilter_graph_free(&graph);
             graph = avfilter_graph_alloc();
-            if ((ret = configure_video_filters(graph, is, vfilters)) < 0) {
+            if ((ret = configure_video_filters(graph, is, vfilters, frame)) < 0) {
                 SDL_Event event;
                 event.type = FF_QUIT_EVENT;
                 event.user.data1 = is;
@@ -1838,9 +1868,10 @@
             }
             filt_in  = is->in_video_filter;
             filt_out = is->out_video_filter;
-            last_w = is->video_st->codec->width;
-            last_h = is->video_st->codec->height;
-            last_format = is->video_st->codec->pix_fmt;
+            last_w = frame->width;
+            last_h = frame->height;
+            last_format = frame->format;
+            last_serial = serial;
         }
 
         frame->pts = pts_int;
@@ -1903,9 +1934,6 @@
 
         if (ret < 0)
             goto the_end;
-
-        if (is->step)
-            stream_toggle_pause(is);
     }
  the_end:
     avcodec_flush_buffers(is->video_st->codec);
@@ -2019,7 +2047,7 @@
 
         diff = get_audio_clock(is) - get_master_clock(is);
 
-        if (fabs(diff) < AV_NOSYNC_THRESHOLD) {
+        if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
             is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
             if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
                 /* not enough measures to have a correct estimate */
@@ -2034,9 +2062,9 @@
                     max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
                     wanted_nb_samples = FFMIN(FFMAX(wanted_nb_samples, min_nb_samples), max_nb_samples);
                 }
-                av_dlog(NULL, "diff=%f adiff=%f sample_diff=%d apts=%0.3f vpts=%0.3f %f\n",
+                av_dlog(NULL, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
                         diff, avg_diff, wanted_nb_samples - nb_samples,
-                        is->audio_clock, is->video_clock, is->audio_diff_threshold);
+                        is->audio_clock, is->audio_diff_threshold);
             }
         } else {
             /* too big difference : may be initial PTS errors, so
@@ -2049,8 +2077,14 @@
     return wanted_nb_samples;
 }
 
-/* decode one audio frame and returns its uncompressed size */
-static int audio_decode_frame(VideoState *is, double *pts_ptr)
+/**
+ * Decode one audio frame and return its uncompressed size.
+ *
+ * The processed audio frame is decoded, converted if required, and
+ * stored in is->audio_buf, with size in bytes given by the return
+ * value.
+ */
+static int audio_decode_frame(VideoState *is)
 {
     AVPacket *pkt_temp = &is->audio_pkt_temp;
     AVPacket *pkt = &is->audio_pkt;
@@ -2058,7 +2092,7 @@
     int len1, len2, data_size, resampled_data_size;
     int64_t dec_channel_layout;
     int got_frame;
-    double pts;
+    av_unused double audio_clock0;
     int new_packet = 0;
     int flush_complete = 0;
     int wanted_nb_samples;
@@ -2072,6 +2106,9 @@
             } else
                 avcodec_get_frame_defaults(is->frame);
 
+            if (is->audioq.serial != is->audio_pkt_temp_serial)
+                break;
+
             if (is->paused)
                 return -1;
 
@@ -2114,8 +2151,8 @@
                                                  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",
-                        is->frame->sample_rate,   av_get_sample_fmt_name(is->frame->format), (int)is->frame->channels,
-                        is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
+                            is->frame->sample_rate, av_get_sample_fmt_name(is->frame->format), is->frame->channels,
+                            is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
                     break;
                 }
                 is->audio_src.channel_layout = dec_channel_layout;
@@ -2126,8 +2163,9 @@
 
             if (is->swr_ctx) {
                 const uint8_t **in = (const uint8_t **)is->frame->extended_data;
-                uint8_t *out[] = {is->audio_buf2};
-                int out_count = sizeof(is->audio_buf2) / is->audio_tgt.channels / av_get_bytes_per_sample(is->audio_tgt.fmt);
+                uint8_t **out = &is->audio_buf1;
+                int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / is->frame->sample_rate + 256;
+                int out_size  = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
                 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) {
@@ -2135,6 +2173,9 @@
                         break;
                     }
                 }
+                av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
+                if (!is->audio_buf1)
+                    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");
@@ -2144,24 +2185,22 @@
                     fprintf(stderr, "warning: audio buffer is probably too small\n");
                     swr_init(is->swr_ctx);
                 }
-                is->audio_buf = is->audio_buf2;
+                is->audio_buf = is->audio_buf1;
                 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
             } else {
                 is->audio_buf = is->frame->data[0];
                 resampled_data_size = data_size;
             }
 
-            /* if no pts, then compute it */
-            pts = is->audio_clock;
-            *pts_ptr = pts;
+            audio_clock0 = is->audio_clock;
             is->audio_clock += (double)data_size /
                 (is->frame->channels * is->frame->sample_rate * av_get_bytes_per_sample(is->frame->format));
 #ifdef DEBUG
             {
                 static double last_clock;
-                printf("audio: delay=%0.3f clock=%0.3f pts=%0.3f\n",
+                printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
                        is->audio_clock - last_clock,
-                       is->audio_clock, pts);
+                       is->audio_clock, audio_clock0);
                 last_clock = is->audio_clock;
             }
 #endif
@@ -2173,7 +2212,7 @@
             av_free_packet(pkt);
         memset(pkt_temp, 0, sizeof(*pkt_temp));
 
-        if (is->paused || is->audioq.abort_request) {
+        if (is->audioq.abort_request) {
             return -1;
         }
 
@@ -2194,6 +2233,7 @@
         /* if update the audio clock with the pts */
         if (pkt->pts != AV_NOPTS_VALUE) {
             is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts;
+            is->audio_clock_serial = is->audio_pkt_temp_serial;
         }
     }
 }
@@ -2205,13 +2245,12 @@
     int audio_size, len1;
     int bytes_per_sec;
     int frame_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, 1, is->audio_tgt.fmt, 1);
-    double pts;
 
     audio_callback_time = av_gettime();
 
     while (len > 0) {
         if (is->audio_buf_index >= is->audio_buf_size) {
-           audio_size = audio_decode_frame(is, &pts);
+           audio_size = audio_decode_frame(is);
            if (audio_size < 0) {
                 /* if error, just output silence */
                is->audio_buf      = is->silence_buf;
@@ -2236,7 +2275,7 @@
     /* 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_pkt_temp_serial)
+    if (is->audioq.serial == is->audio_clock_serial)
         check_external_clock_sync(is, is->audio_current_pts);
 }
 
@@ -2300,6 +2339,7 @@
     AVFormatContext *ic = is->ic;
     AVCodecContext *avctx;
     AVCodec *codec;
+    const char *forced_codec_name = NULL;
     AVDictionary *opts;
     AVDictionaryEntry *t = NULL;
 
@@ -2310,13 +2350,19 @@
     codec = avcodec_find_decoder(avctx->codec_id);
 
     switch(avctx->codec_type){
-        case AVMEDIA_TYPE_AUDIO   : is->last_audio_stream    = stream_index; if(audio_codec_name   ) codec= avcodec_find_decoder_by_name(   audio_codec_name); break;
-        case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; if(subtitle_codec_name) codec= avcodec_find_decoder_by_name(subtitle_codec_name); break;
-        case AVMEDIA_TYPE_VIDEO   : is->last_video_stream    = stream_index; if(video_codec_name   ) codec= avcodec_find_decoder_by_name(   video_codec_name); break;
+        case AVMEDIA_TYPE_AUDIO   : is->last_audio_stream    = stream_index; forced_codec_name =    audio_codec_name; break;
+        case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
+        case AVMEDIA_TYPE_VIDEO   : is->last_video_stream    = stream_index; forced_codec_name =    video_codec_name; break;
     }
-    if (!codec)
+    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);
         return -1;
+    }
 
+    avctx->codec_id = codec->id;
     avctx->workaround_bugs   = workaround_bugs;
     avctx->lowres            = lowres;
     if(avctx->lowres > codec->max_lowres){
@@ -2413,6 +2459,7 @@
         av_free_packet(&is->audio_pkt);
         swr_free(&is->swr_ctx);
         av_freep(&is->audio_buf1);
+        is->audio_buf1_size = 0;
         is->audio_buf = NULL;
         avcodec_free_frame(&is->frame);
 
@@ -2589,7 +2636,7 @@
                                 wanted_stream[AVMEDIA_TYPE_AUDIO],
                                 st_index[AVMEDIA_TYPE_VIDEO],
                                 NULL, 0);
-    if (!video_disable)
+    if (!video_disable && !subtitle_disable)
         st_index[AVMEDIA_TYPE_SUBTITLE] =
             av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
                                 wanted_stream[AVMEDIA_TYPE_SUBTITLE],
@@ -2612,7 +2659,6 @@
     if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
         ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
     }
-    is->refresh_tid = SDL_CreateThread(refresh_thread, is);
     if (is->show_mode == SHOW_MODE_NONE)
         is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
 
@@ -2673,18 +2719,19 @@
                     packet_queue_put(&is->videoq, &flush_pkt);
                 }
                 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
-                   //FIXME: use a cleaner way to signal obsolete external clock...
-                   update_external_clock_pts(is, (double)AV_NOPTS_VALUE);
+                   update_external_clock_pts(is, NAN);
                 } else {
                    update_external_clock_pts(is, seek_target / (double)AV_TIME_BASE);
                 }
             }
             is->seek_req = 0;
             eof = 0;
+            if (is->paused)
+                step_to_next_frame(is);
         }
-        if (is->que_attachments_req) {
+        if (is->queue_attachments_req) {
             avformat_queue_attached_pictures(ic);
-            is->que_attachments_req = 0;
+            is->queue_attachments_req = 0;
         }
 
         /* if the queue are full, no need to read more */
@@ -2808,10 +2855,12 @@
 
     is->continue_read_thread = SDL_CreateCond();
 
-    update_external_clock_pts(is, 0.0);
+    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;
+    is->audio_clock_serial = -1;
+    is->video_clock_serial = -1;
     is->av_sync_type = av_sync_type;
     is->read_tid     = SDL_CreateThread(read_thread, is);
     if (!is->read_tid) {
@@ -2875,7 +2924,7 @@
     stream_component_close(is, old_index);
     stream_component_open(is, stream_index);
     if (codec_type == AVMEDIA_TYPE_VIDEO)
-        is->que_attachments_req = 1;
+        is->queue_attachments_req = 1;
 }
 
 
@@ -2888,30 +2937,40 @@
         is->pictq[i].reallocate = 1;
 #endif
     is_full_screen = !is_full_screen;
-    video_open(is, 1);
-}
-
-static void toggle_pause(VideoState *is)
-{
-    stream_toggle_pause(is);
-    is->step = 0;
-}
-
-static void step_to_next_frame(VideoState *is)
-{
-    /* if the stream is paused unpause it, then step */
-    if (is->paused)
-        stream_toggle_pause(is);
-    is->step = 1;
+    video_open(is, 1, NULL);
 }
 
 static void toggle_audio_display(VideoState *is)
 {
     int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
-    is->show_mode = (is->show_mode + 1) % SHOW_MODE_NB;
-    fill_rectangle(screen,
-                is->xleft, is->ytop, is->width, is->height,
-                bgcolor, 1);
+    int next = is->show_mode;
+    do {
+        next = (next + 1) % SHOW_MODE_NB;
+    } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
+    if (is->show_mode != next) {
+        fill_rectangle(screen,
+                    is->xleft, is->ytop, is->width, is->height,
+                    bgcolor, 1);
+        is->force_refresh = 1;
+        is->show_mode = next;
+    }
+}
+
+static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
+    double remaining_time = 0.0;
+    SDL_PumpEvents();
+    while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)) {
+        if (!cursor_hidden && av_gettime() - cursor_last_shown > CURSOR_HIDE_DELAY) {
+            SDL_ShowCursor(0);
+            cursor_hidden = 1;
+        }
+        if (remaining_time > 0.0)
+            av_usleep((int64_t)(remaining_time * 1000000.0));
+        remaining_time = REFRESH_RATE;
+        if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
+            video_refresh(is, &remaining_time);
+        SDL_PumpEvents();
+    }
 }
 
 /* handle an event sent by the GUI */
@@ -2922,7 +2981,7 @@
 
     for (;;) {
         double x;
-        SDL_WaitEvent(&event);
+        refresh_loop_wait_event(cur_stream, &event);
         switch (event.type) {
         case SDL_KEYDOWN:
             if (exit_on_keydown) {
@@ -2956,7 +3015,6 @@
                 break;
             case SDLK_w:
                 toggle_audio_display(cur_stream);
-                cur_stream->force_refresh = 1;
                 break;
             case SDLK_PAGEUP:
                 incr = 600.0;
@@ -2991,6 +3049,8 @@
                         stream_seek(cur_stream, pos, incr, 1);
                     } else {
                         pos = get_master_clock(cur_stream);
+                        if (isnan(pos))
+                            pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
                         pos += incr;
                         if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
                             pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
@@ -3010,6 +3070,11 @@
                 break;
             }
         case SDL_MOUSEMOTION:
+            if (cursor_hidden) {
+                SDL_ShowCursor(1);
+                cursor_hidden = 0;
+            }
+            cursor_last_shown = av_gettime();
             if (event.type == SDL_MOUSEBUTTONDOWN) {
                 x = event.button.x;
             } else {
@@ -3055,10 +3120,6 @@
         case FF_ALLOC_EVENT:
             alloc_picture(event.user.data1);
             break;
-        case FF_REFRESH_EVENT:
-            video_refresh(event.user.data1);
-            cur_stream->refresh = 0;
-            break;
         default:
             break;
         }
@@ -3147,14 +3208,24 @@
     input_filename = filename;
 }
 
-static int opt_codec(void *o, const char *opt, const char *arg)
+static int opt_codec(void *optctx, const char *opt, const char *arg)
 {
-    switch(opt[strlen(opt)-1]){
-    case 'a' :    audio_codec_name = arg; break;
-    case 's' : subtitle_codec_name = arg; break;
-    case 'v' :    video_codec_name = arg; break;
-    }
-    return 0;
+   const char *spec = strchr(opt, ':');
+   if (!spec) {
+       fprintf(stderr, "No media specifier was specified in '%s' in option '%s'\n",
+               arg, opt);
+       return AVERROR(EINVAL);
+   }
+   spec++;
+   switch (spec[0]) {
+   case 'a' :    audio_codec_name = arg; break;
+   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);
+       return AVERROR(EINVAL);
+   }
+   return 0;
 }
 
 static int dummy;
@@ -3167,6 +3238,7 @@
     { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
     { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
     { "vn", OPT_BOOL, { &video_disable }, "disable video" },
+    { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
     { "ast", OPT_INT | HAS_ARG | OPT_EXPERT, { &wanted_stream[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_number" },
     { "vst", OPT_INT | HAS_ARG | OPT_EXPERT, { &wanted_stream[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_number" },
     { "sst", OPT_INT | HAS_ARG | OPT_EXPERT, { &wanted_stream[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_number" },
@@ -3196,13 +3268,16 @@
     { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
     { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
 #if CONFIG_AVFILTER
-    { "vf", OPT_STRING | HAS_ARG, { &vfilters }, "video filters", "filter list" },
+    { "vf", OPT_STRING | HAS_ARG, { &vfilters }, "set video filters", "filter_graph" },
 #endif
     { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
     { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
     { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
     { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
-    { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder" },
+    { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
+    { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, {    &audio_codec_name }, "force audio decoder",    "decoder_name" },
+    { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
+    { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, {    &video_codec_name }, "force video decoder",    "decoder_name" },
     { NULL, },
 };
 
diff --git a/ffprobe.c b/ffprobe.c
index 84dfa19..f70c24c 100644
--- a/ffprobe.c
+++ b/ffprobe.c
@@ -642,15 +642,15 @@
     int needs_quoting = !!src[strcspn(src, meta_chars)];
 
     if (needs_quoting)
-        av_bprint_chars(dst, '\"', 1);
+        av_bprint_chars(dst, '"', 1);
 
     for (; *src; src++) {
         if (*src == '"')
-            av_bprint_chars(dst, '\"', 1);
+            av_bprint_chars(dst, '"', 1);
         av_bprint_chars(dst, *src, 1);
     }
     if (needs_quoting)
-        av_bprint_chars(dst, '\"', 1);
+        av_bprint_chars(dst, '"', 1);
     return dst->str;
 }
 
@@ -1254,7 +1254,7 @@
         case '&' : av_bprintf(dst, "%s", "&amp;");  break;
         case '<' : av_bprintf(dst, "%s", "&lt;");   break;
         case '>' : av_bprintf(dst, "%s", "&gt;");   break;
-        case '\"': av_bprintf(dst, "%s", "&quot;"); break;
+        case '"' : av_bprintf(dst, "%s", "&quot;"); break;
         case '\'': av_bprintf(dst, "%s", "&apos;"); break;
         default: av_bprint_chars(dst, *p, 1);
         }
@@ -1476,6 +1476,8 @@
     print_duration_time("pkt_duration_time", frame->pkt_duration, &stream->time_base);
     if (frame->pkt_pos != -1) print_fmt    ("pkt_pos", "%"PRId64, frame->pkt_pos);
     else                      print_str_opt("pkt_pos", "N/A");
+    if (frame->pkt_size != -1) print_fmt    ("pkt_size", "%d", av_frame_get_pkt_size(frame));
+    else                       print_str_opt("pkt_size", "N/A");
 
     switch (stream->codec->codec_type) {
         AVRational sar;
diff --git a/ffserver.c b/ffserver.c
index 3af481d..f2cf67f 100644
--- a/ffserver.c
+++ b/ffserver.c
@@ -2961,12 +2961,14 @@
 {
     AVFormatContext *avc;
     AVStream *avs = NULL;
+    AVOutputFormat *rtp_format = av_guess_format("rtp", NULL, NULL);
     int i;
 
     avc =  avformat_alloc_context();
-    if (avc == NULL) {
+    if (avc == NULL || !rtp_format) {
         return -1;
     }
+    avc->oformat = rtp_format;
     av_dict_set(&avc->metadata, "title",
                stream->title[0] ? stream->title : "No Title", 0);
     avc->nb_streams = stream->nb_streams;
@@ -3516,7 +3518,7 @@
         fst->codec = avcodec_alloc_context3(NULL);
         memcpy(fst->codec, codec, sizeof(AVCodecContext));
         if (codec->extradata_size) {
-            fst->codec->extradata = av_malloc(codec->extradata_size);
+            fst->codec->extradata = av_mallocz(codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
             memcpy(fst->codec->extradata, codec->extradata,
                 codec->extradata_size);
         }
@@ -3625,7 +3627,7 @@
                     p[2] == 0x01 && p[3] == 0xb6) {
                     size = p - pkt.data;
                     //                    av_hex_dump_log(infile, AV_LOG_DEBUG, pkt.data, size);
-                    st->codec->extradata = av_malloc(size);
+                    st->codec->extradata = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE);
                     st->codec->extradata_size = size;
                     memcpy(st->codec->extradata, pkt.data, size);
                     break;
diff --git a/libavcodec/012v.c b/libavcodec/012v.c
new file mode 100644
index 0000000..6f4533b
--- /dev/null
+++ b/libavcodec/012v.c
@@ -0,0 +1,172 @@
+/*
+ * 012v decoder
+ *
+ * Copyright (C) 2012 Carl Eugen Hoyos
+ *
+ * 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 "libavutil/intreadwrite.h"
+
+static av_cold int zero12v_decode_init(AVCodecContext *avctx)
+{
+    avctx->pix_fmt             = PIX_FMT_YUV422P16;
+    avctx->bits_per_raw_sample = 10;
+
+    avctx->coded_frame = avcodec_alloc_frame();
+    if (!avctx->coded_frame)
+        return AVERROR(ENOMEM);
+
+    if (avctx->codec_tag == MKTAG('a', '1', '2', 'v'))
+        av_log_ask_for_sample(avctx, "Samples with actual transparency needed\n");
+
+    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+    avctx->coded_frame->key_frame = 1;
+    return 0;
+}
+
+static int zero12v_decode_frame(AVCodecContext *avctx, void *data,
+                                int *got_frame, AVPacket *avpkt)
+{
+    int line = 0, ret;
+    const int width = avctx->width;
+    AVFrame *pic = avctx->coded_frame;
+    uint16_t *y, *u, *v;
+    const uint8_t *line_end, *src = avpkt->data;
+    int stride = avctx->width * 8 / 3;
+
+    if (pic->data[0])
+        avctx->release_buffer(avctx, pic);
+
+    if (width == 1) {
+        av_log(avctx, AV_LOG_ERROR, "Width 1 not supported.\n");
+        return AVERROR_INVALIDDATA;
+    }
+    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);
+        return AVERROR_INVALIDDATA;
+    }
+
+    pic->reference = 0;
+    if ((ret = ff_get_buffer(avctx, pic)) < 0)
+        return ret;
+
+    y = (uint16_t *)pic->data[0];
+    u = (uint16_t *)pic->data[1];
+    v = (uint16_t *)pic->data[2];
+    line_end = avpkt->data + stride;
+
+    while (line++ < avctx->height) {
+        while (1) {
+            uint32_t t = AV_RL32(src);
+            src += 4;
+            *u++ = t <<  6 & 0xFFC0;
+            *y++ = t >>  4 & 0xFFC0;
+            *v++ = t >> 14 & 0xFFC0;
+
+            if (src >= line_end - 1) {
+                *y = 0x80;
+                src++;
+                line_end += stride;
+                y = (uint16_t *)(pic->data[0] + line * pic->linesize[0]);
+                u = (uint16_t *)(pic->data[1] + line * pic->linesize[1]);
+                v = (uint16_t *)(pic->data[2] + line * pic->linesize[2]);
+                break;
+            }
+
+            t = AV_RL32(src);
+            src += 4;
+            *y++ = t <<  6 & 0xFFC0;
+            *u++ = t >>  4 & 0xFFC0;
+            *y++ = t >> 14 & 0xFFC0;
+            if (src >= line_end - 2) {
+                if (!(width & 1)) {
+                    *y = 0x80;
+                    src += 2;
+                }
+                line_end += stride;
+                y = (uint16_t *)(pic->data[0] + line * pic->linesize[0]);
+                u = (uint16_t *)(pic->data[1] + line * pic->linesize[1]);
+                v = (uint16_t *)(pic->data[2] + line * pic->linesize[2]);
+                break;
+            }
+
+            t = AV_RL32(src);
+            src += 4;
+            *v++ = t <<  6 & 0xFFC0;
+            *y++ = t >>  4 & 0xFFC0;
+            *u++ = t >> 14 & 0xFFC0;
+
+            if (src >= line_end - 1) {
+                *y = 0x80;
+                src++;
+                line_end += stride;
+                y = (uint16_t *)(pic->data[0] + line * pic->linesize[0]);
+                u = (uint16_t *)(pic->data[1] + line * pic->linesize[1]);
+                v = (uint16_t *)(pic->data[2] + line * pic->linesize[2]);
+                break;
+            }
+
+            t = AV_RL32(src);
+            src += 4;
+            *y++ = t <<  6 & 0xFFC0;
+            *v++ = t >>  4 & 0xFFC0;
+            *y++ = t >> 14 & 0xFFC0;
+
+            if (src >= line_end - 2) {
+                if (width & 1) {
+                    *y = 0x80;
+                    src += 2;
+                }
+                line_end += stride;
+                y = (uint16_t *)(pic->data[0] + line * pic->linesize[0]);
+                u = (uint16_t *)(pic->data[1] + line * pic->linesize[1]);
+                v = (uint16_t *)(pic->data[2] + line * pic->linesize[2]);
+                break;
+            }
+        }
+    }
+
+    *got_frame = 1;
+    *(AVFrame*)data= *avctx->coded_frame;
+
+    return avpkt->size;
+}
+
+static av_cold int zero12v_decode_close(AVCodecContext *avctx)
+{
+    AVFrame *pic = avctx->coded_frame;
+    if (pic->data[0])
+        avctx->release_buffer(avctx, pic);
+    av_freep(&avctx->coded_frame);
+
+    return 0;
+}
+
+AVCodec ff_zero12v_decoder = {
+    .name           = "012v",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_012V,
+    .init           = zero12v_decode_init,
+    .close          = zero12v_decode_close,
+    .decode         = zero12v_decode_frame,
+    .capabilities   = CODEC_CAP_DR1,
+    .long_name      = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"),
+};
diff --git a/libavcodec/4xm.c b/libavcodec/4xm.c
index 85795f9..e3d8486 100644
--- a/libavcodec/4xm.c
+++ b/libavcodec/4xm.c
@@ -29,6 +29,7 @@
 #include "bytestream.h"
 #include "dsputil.h"
 #include "get_bits.h"
+#include "internal.h"
 
 #include "libavutil/avassert.h"
 
@@ -129,7 +130,7 @@
 typedef struct FourXContext {
     AVCodecContext *avctx;
     DSPContext dsp;
-    AVFrame current_picture, last_picture;
+    AVFrame *current_picture, *last_picture;
     GetBitContext pre_gb;          ///< ac/dc prefix
     GetBitContext gb;
     GetByteContext g;
@@ -137,7 +138,7 @@
     int mv[256];
     VLC pre_vlc;
     int last_dc;
-    DECLARE_ALIGNED(16, DCTELEM, block)[6][64];
+    DECLARE_ALIGNED(16, int16_t, block)[6][64];
     void *bitstream_buffer;
     unsigned int bitstream_buffer_size;
     int version;
@@ -152,7 +153,7 @@
 
 #define MULTIPLY(var, const) (((var) * (const)) >> 16)
 
-static void idct(DCTELEM block[64])
+static void idct(int16_t block[64])
 {
     int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
     int tmp10, tmp11, tmp12, tmp13;
@@ -260,9 +261,9 @@
 
     for (i = 0; i < 256; i++) {
         if (f->version > 1)
-            f->mv[i] = mv[i][0] + mv[i][1] * f->current_picture.linesize[0] / 2;
+            f->mv[i] = mv[i][0] + mv[i][1] * f->current_picture->linesize[0] / 2;
         else
-            f->mv[i] = (i & 15) - 8 + ((i >> 4) - 8) * f->current_picture.linesize[0] / 2;
+            f->mv[i] = (i & 15) - 8 + ((i >> 4) - 8) * f->current_picture->linesize[0] / 2;
     }
 }
 
@@ -339,17 +340,17 @@
     int code        = get_vlc2(&f->gb,
                                block_type_vlc[1 - (f->version > 1)][index].table,
                                BLOCK_TYPE_VLC_BITS, 1);
-    uint16_t *start = (uint16_t *)f->last_picture.data[0];
+    uint16_t *start = (uint16_t *)f->last_picture->data[0];
     uint16_t *end   = start + stride * (f->avctx->height - h + 1) - (1 << log2w);
 
     av_assert2(code >= 0 && code <= 6);
 
     if (code == 0) {
-        if (f->g.buffer_end - f->g.buffer < 1) {
+        if (bytestream2_get_bytes_left(&f->g) < 1) {
             av_log(f->avctx, AV_LOG_ERROR, "bytestream overread\n");
             return;
         }
-        src += f->mv[bytestream2_get_byte(&f->g)];
+        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;
@@ -368,37 +369,37 @@
     } else if (code == 3 && f->version < 2) {
         mcdc(dst, src, log2w, h, stride, 1, 0);
     } else if (code == 4) {
-        if (f->g.buffer_end - f->g.buffer < 1) {
+        if (bytestream2_get_bytes_left(&f->g) < 1) {
             av_log(f->avctx, AV_LOG_ERROR, "bytestream overread\n");
             return;
         }
-        src += f->mv[bytestream2_get_byte(&f->g)];
+        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 (f->g2.buffer_end - f->g2.buffer < 1){
+        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_le16(&f->g2));
+        mcdc(dst, src, log2w, h, stride, 1, bytestream2_get_le16u(&f->g2));
     } else if (code == 5) {
-        if (f->g2.buffer_end - f->g2.buffer < 1) {
+        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_le16(&f->g2));
+        mcdc(dst, src, log2w, h, stride, 0, bytestream2_get_le16u(&f->g2));
     } else if (code == 6) {
-        if (f->g2.buffer_end - f->g2.buffer < 2) {
+        if (bytestream2_get_bytes_left(&f->g2) < 4) {
             av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n");
             return;
         }
         if (log2w) {
-            dst[0]      = bytestream2_get_le16(&f->g2);
-            dst[1]      = bytestream2_get_le16(&f->g2);
+            dst[0]      = bytestream2_get_le16u(&f->g2);
+            dst[1]      = bytestream2_get_le16u(&f->g2);
         } else {
-            dst[0]      = bytestream2_get_le16(&f->g2);
-            dst[stride] = bytestream2_get_le16(&f->g2);
+            dst[0]      = bytestream2_get_le16u(&f->g2);
+            dst[stride] = bytestream2_get_le16u(&f->g2);
         }
     }
 }
@@ -408,9 +409,9 @@
     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 *)f->current_picture.data[0];
-    const int stride =             f->current_picture.linesize[0] >> 1;
+    uint16_t *src    = (uint16_t *)f->last_picture->data[0];
+    uint16_t *dst    = (uint16_t *)f->current_picture->data[0];
+    const int stride =             f->current_picture->linesize[0] >> 1;
     unsigned int bitstream_size, bytestream_size, wordstream_size, extra,
                  bytestream_offset, wordstream_offset;
 
@@ -434,7 +435,7 @@
         extra > length - bytestream_size - bitstream_size - wordstream_size) {
         av_log(f->avctx, AV_LOG_ERROR, "lengths %d %d %d %d\n", bitstream_size, bytestream_size, wordstream_size,
         bitstream_size+ bytestream_size+ wordstream_size - length);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     av_fast_malloc(&f->bitstream_buffer, &f->bitstream_buffer_size,
@@ -470,7 +471,7 @@
  * decode block and dequantize.
  * Note this is almost identical to MJPEG.
  */
-static int decode_i_block(FourXContext *f, DCTELEM *block)
+static int decode_i_block(FourXContext *f, int16_t *block)
 {
     int code, i, j, level, val;
 
@@ -520,10 +521,10 @@
 
 static inline void idct_put(FourXContext *f, int x, int y)
 {
-    DCTELEM (*block)[64] = f->block;
-    int stride           = f->current_picture.linesize[0] >> 1;
+    int16_t (*block)[64] = f->block;
+    int stride           = f->current_picture->linesize[0] >> 1;
     int i;
-    uint16_t *dst = ((uint16_t*)f->current_picture.data[0]) + y * stride + x;
+    uint16_t *dst = ((uint16_t*)f->current_picture->data[0]) + y * stride + x;
 
     for (i = 0; i < 4; i++) {
         block[i][0] += 0x80 * 8 * 8;
@@ -541,7 +542,7 @@
      * cr = (-1b - 4g + 5r) / 14 */
     for (y = 0; y < 8; y++) {
         for (x = 0; x < 8; x++) {
-            DCTELEM *temp = block[(x >> 2) + 2 * (y >> 2)] +
+            int16_t *temp = block[(x >> 2) + 2 * (y >> 2)] +
                             2 * (x & 3) + 2 * 8 * (y & 3); // FIXME optimize
             int cb = block[4][x + 8 * y];
             int cr = block[5][x + 8 * y];
@@ -566,13 +567,14 @@
 
 static int decode_i_mb(FourXContext *f)
 {
+    int ret;
     int i;
 
     f->dsp.clear_blocks(f->block[0]);
 
     for (i = 0; i < 6; i++)
-        if (decode_i_block(f, f->block[i]) < 0)
-            return -1;
+        if ((ret = decode_i_block(f, f->block[i])) < 0)
+            return ret;
 
     return 0;
 }
@@ -597,8 +599,10 @@
     for (;;) {
         int i;
 
-        if (start <= end && ptr_end - ptr < end - start + 1 + 1)
+        if (ptr_end - ptr < FFMAX(end - start + 1, 0) + 1) {
+            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++;
@@ -612,6 +616,11 @@
     while ((ptr - buf) & 3)
         ptr++; // 4byte align
 
+    if (ptr > ptr_end) {
+        av_log(f->avctx, AV_LOG_ERROR, "ptr overflow in read_huffman_tables\n");
+        return NULL;
+    }
+
     for (j = 257; j < 512; j++) {
         int min_freq[2] = { 256 * 256, 256 * 256 };
         int smallest[2] = { 0, 0 };
@@ -679,8 +688,8 @@
     const int width  = f->avctx->width;
     const int height = f->avctx->height;
     const int mbs    = (FFALIGN(width, 16) >> 4) * (FFALIGN(height, 16) >> 4);
-    uint16_t *dst    = (uint16_t*)f->current_picture.data[0];
-    const int stride =            f->current_picture.linesize[0]>>1;
+    uint16_t *dst    = (uint16_t*)f->current_picture->data[0];
+    const int stride =            f->current_picture->linesize[0]>>1;
     const uint8_t *buf_end = buf + length;
     GetByteContext g3;
 
@@ -724,7 +733,7 @@
 
 static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length)
 {
-    int x, y;
+    int x, y, ret;
     const int width  = f->avctx->width;
     const int height = f->avctx->height;
     const unsigned int bitstream_size = AV_RL32(buf);
@@ -744,12 +753,16 @@
         || prestream_size > (1 << 26)) {
         av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d %d\n",
                prestream_size, bitstream_size, length);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     prestream = read_huffman_tables(f, prestream, buf + length - prestream);
-    if (!prestream)
-        return -1;
+    if (!prestream) {
+        av_log(f->avctx, AV_LOG_ERROR, "Error reading Huffman tables.\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    av_assert0(prestream <= buf + length);
 
     init_get_bits(&f->gb, buf + 4, 8 * bitstream_size);
 
@@ -769,8 +782,8 @@
 
     for (y = 0; y < height; y += 16) {
         for (x = 0; x < width; x += 16) {
-            if (decode_i_mb(f) < 0)
-                return -1;
+            if ((ret = decode_i_mb(f)) < 0)
+                return ret;
 
             idct_put(f, x, y);
         }
@@ -783,14 +796,14 @@
 }
 
 static int decode_frame(AVCodecContext *avctx, void *data,
-                        int *data_size, AVPacket *avpkt)
+                        int *got_frame, AVPacket *avpkt)
 {
     const uint8_t *buf    = avpkt->data;
     int buf_size          = avpkt->size;
     FourXContext *const f = avctx->priv_data;
     AVFrame *picture      = data;
-    AVFrame *p, temp;
-    int i, frame_4cc, frame_size;
+    AVFrame *p;
+    int i, frame_4cc, frame_size, ret;
 
     if (buf_size < 12)
         return AVERROR_INVALIDDATA;
@@ -841,8 +854,8 @@
                                      cfrm->size + data_size + FF_INPUT_BUFFER_PADDING_SIZE);
         // explicit check needed as memcpy below might not catch a NULL
         if (!cfrm->data) {
-            av_log(f->avctx, AV_LOG_ERROR, "realloc falure\n");
-            return -1;
+            av_log(f->avctx, AV_LOG_ERROR, "realloc failure\n");
+            return AVERROR(ENOMEM);
         }
 
         memcpy(cfrm->data + cfrm->size, buf + 20, data_size);
@@ -865,47 +878,47 @@
         frame_size = buf_size - 12;
     }
 
-    temp               = f->current_picture;
-    f->current_picture = f->last_picture;
-    f->last_picture    = temp;
+    FFSWAP(AVFrame*, f->current_picture, f->last_picture);
 
-    p                  = &f->current_picture;
+    p                  = f->current_picture;
     avctx->coded_frame = p;
 
     // alternatively we would have to use our own buffer management
     avctx->flags |= CODEC_FLAG_EMU_EDGE;
 
     p->reference= 3;
-    if (avctx->reget_buffer(avctx, p) < 0) {
+    if ((ret = avctx->reget_buffer(avctx, p)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     if (frame_4cc == AV_RL32("ifr2")) {
         p->pict_type= AV_PICTURE_TYPE_I;
-        if (decode_i2_frame(f, buf - 4, frame_size + 4) < 0) {
+        if ((ret = decode_i2_frame(f, buf - 4, frame_size + 4)) < 0) {
             av_log(f->avctx, AV_LOG_ERROR, "decode i2 frame failed\n");
-            return -1;
+            return ret;
         }
     } else if (frame_4cc == AV_RL32("ifrm")) {
         p->pict_type= AV_PICTURE_TYPE_I;
-        if (decode_i_frame(f, buf, frame_size) < 0) {
+        if ((ret = decode_i_frame(f, buf, frame_size)) < 0) {
             av_log(f->avctx, AV_LOG_ERROR, "decode i frame failed\n");
-            return -1;
+            return ret;
         }
     } else if (frame_4cc == AV_RL32("pfrm") || frame_4cc == AV_RL32("pfr2")) {
-        if (!f->last_picture.data[0]) {
-            f->last_picture.reference = 3;
-            if (avctx->get_buffer(avctx, &f->last_picture) < 0) {
+        if (!f->last_picture->data[0]) {
+            f->last_picture->reference = 3;
+            if ((ret = ff_get_buffer(avctx, f->last_picture)) < 0) {
                 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-                return -1;
+                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);
         }
 
         p->pict_type = AV_PICTURE_TYPE_P;
-        if (decode_p_frame(f, buf, frame_size) < 0) {
+        if ((ret = decode_p_frame(f, buf, frame_size)) < 0) {
             av_log(f->avctx, AV_LOG_ERROR, "decode p frame failed\n");
-            return -1;
+            return ret;
         }
     } else if (frame_4cc == AV_RL32("snd_")) {
         av_log(avctx, AV_LOG_ERROR, "ignoring snd_ chunk length:%d\n",
@@ -918,23 +931,13 @@
     p->key_frame = p->pict_type == AV_PICTURE_TYPE_I;
 
     *picture   = *p;
-    *data_size = sizeof(AVPicture);
+    *got_frame = 1;
 
     emms_c();
 
     return buf_size;
 }
 
-
-static av_cold void common_init(AVCodecContext *avctx)
-{
-    FourXContext * const f = avctx->priv_data;
-
-    ff_dsputil_init(&f->dsp, avctx);
-
-    f->avctx = avctx;
-}
-
 static av_cold int decode_init(AVCodecContext *avctx)
 {
     FourXContext * const f = avctx->priv_data;
@@ -948,10 +951,9 @@
         return AVERROR_INVALIDDATA;
     }
 
-    avcodec_get_frame_defaults(&f->current_picture);
-    avcodec_get_frame_defaults(&f->last_picture);
     f->version = AV_RL32(avctx->extradata) >> 16;
-    common_init(avctx);
+    ff_dsputil_init(&f->dsp, avctx);
+    f->avctx = avctx;
     init_vlcs(f);
 
     if (f->version > 2)
@@ -959,6 +961,14 @@
     else
         avctx->pix_fmt = AV_PIX_FMT_BGR555;
 
+    f->current_picture = avcodec_alloc_frame();
+    f->last_picture    = avcodec_alloc_frame();
+    if (!f->current_picture || !f->last_picture) {
+        avcodec_free_frame(&f->current_picture);
+        avcodec_free_frame(&f->last_picture);
+        return AVERROR(ENOMEM);
+    }
+
     return 0;
 }
 
@@ -975,10 +985,12 @@
         f->cfrm[i].allocated_size = 0;
     }
     ff_free_vlc(&f->pre_vlc);
-    if (f->current_picture.data[0])
-        avctx->release_buffer(avctx, &f->current_picture);
-    if (f->last_picture.data[0])
-        avctx->release_buffer(avctx, &f->last_picture);
+    if (f->current_picture->data[0])
+        avctx->release_buffer(avctx, f->current_picture);
+    if (f->last_picture->data[0])
+        avctx->release_buffer(avctx, f->last_picture);
+    avcodec_free_frame(&f->current_picture);
+    avcodec_free_frame(&f->last_picture);
 
     return 0;
 }
diff --git a/libavcodec/8bps.c b/libavcodec/8bps.c
index f895ed3..158e29f 100644
--- a/libavcodec/8bps.c
+++ b/libavcodec/8bps.c
@@ -38,14 +38,12 @@
 #include "libavutil/internal.h"
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
+#include "internal.h"
 
 
 static const enum AVPixelFormat pixfmt_rgb24[] = {
     AV_PIX_FMT_BGR24, AV_PIX_FMT_RGB32, AV_PIX_FMT_NONE };
 
-/*
- * Decoder context
- */
 typedef struct EightBpsContext {
     AVCodecContext *avctx;
     AVFrame pic;
@@ -56,14 +54,8 @@
     uint32_t pal[256];
 } EightBpsContext;
 
-
-/*
- *
- * Decode a frame
- *
- */
 static int decode_frame(AVCodecContext *avctx, void *data,
-                        int *data_size, AVPacket *avpkt)
+                        int *got_frame, AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
@@ -76,15 +68,16 @@
     unsigned char count;
     unsigned int planes     = c->planes;
     unsigned char *planemap = c->planemap;
+    int ret;
 
     if (c->pic.data[0])
         avctx->release_buffer(avctx, &c->pic);
 
     c->pic.reference    = 0;
     c->pic.buffer_hints = FF_BUFFER_HINTS_VALID;
-    if (avctx->get_buffer(avctx, &c->pic) < 0){
+    if ((ret = ff_get_buffer(avctx, &c->pic)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     /* Set data pointer after line lengths */
@@ -104,14 +97,14 @@
             /* Decode a row of this plane */
             while (dlen > 0) {
                 if (dp + 1 >= buf + buf_size)
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 if ((count = *dp++) <= 127) {
                     count++;
                     dlen -= count + 1;
                     if (pixptr + count * planes > pixptr_end)
                         break;
                     if (dp + count > buf + buf_size)
-                        return -1;
+                        return AVERROR_INVALIDDATA;
                     while (count--) {
                         *pixptr = *dp++;
                         pixptr += planes;
@@ -143,19 +136,13 @@
         memcpy (c->pic.data[1], c->pal, AVPALETTE_SIZE);
     }
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*)data = c->pic;
 
     /* always report that the buffer was completely consumed */
     return buf_size;
 }
 
-
-/*
- *
- * Init 8BPS decoder
- *
- */
 static av_cold int decode_init(AVCodecContext *avctx)
 {
     EightBpsContext * const c = avctx->priv_data;
@@ -195,20 +182,12 @@
     default:
         av_log(avctx, AV_LOG_ERROR, "Error: Unsupported color depth: %u.\n",
                avctx->bits_per_coded_sample);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     return 0;
 }
 
-
-
-
-/*
- *
- * Uninit 8BPS decoder
- *
- */
 static av_cold int decode_end(AVCodecContext *avctx)
 {
     EightBpsContext * const c = avctx->priv_data;
@@ -219,8 +198,6 @@
     return 0;
 }
 
-
-
 AVCodec ff_eightbps_decoder = {
     .name           = "8bps",
     .type           = AVMEDIA_TYPE_VIDEO,
diff --git a/libavcodec/8svx.c b/libavcodec/8svx.c
index 618ae87..d33f73e 100644
--- a/libavcodec/8svx.c
+++ b/libavcodec/8svx.c
@@ -39,11 +39,11 @@
 
 #include "libavutil/avassert.h"
 #include "avcodec.h"
+#include "internal.h"
 #include "libavutil/common.h"
 
 /** decoder context */
 typedef struct EightSvxContext {
-    AVFrame frame;
     uint8_t fib_acc[2];
     const int8_t *table;
 
@@ -87,6 +87,7 @@
                                  int *got_frame_ptr, AVPacket *avpkt)
 {
     EightSvxContext *esc = avctx->priv_data;
+    AVFrame *frame       = data;
     int buf_size;
     int ch, ret;
     int hdr_size = 2;
@@ -134,21 +135,20 @@
     }
 
     /* get output buffer */
-    esc->frame.nb_samples = buf_size * 2;
-    if ((ret = avctx->get_buffer(avctx, &esc->frame)) < 0) {
+    frame->nb_samples = buf_size * 2;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
 
     for (ch = 0; ch < avctx->channels; ch++) {
-        delta_decode(esc->frame.data[ch], &esc->data[ch][esc->data_idx],
+        delta_decode(frame->data[ch], &esc->data[ch][esc->data_idx],
                      buf_size, &esc->fib_acc[ch], esc->table);
     }
 
     esc->data_idx += buf_size;
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = esc->frame;
+    *got_frame_ptr = 1;
 
     return ((avctx->frame_number == 0)*hdr_size + buf_size)*avctx->channels;
 }
@@ -171,9 +171,6 @@
     }
     avctx->sample_fmt = AV_SAMPLE_FMT_U8P;
 
-    avcodec_get_frame_defaults(&esc->frame);
-    avctx->coded_frame = &esc->frame;
-
     return 0;
 }
 
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 1d4cb59..52282e3 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -39,9 +39,9 @@
 # parts needed for many different codecs
 OBJS-$(CONFIG_AANDCTTABLES)            += aandcttab.o
 OBJS-$(CONFIG_AC3DSP)                  += ac3dsp.o
+OBJS-$(CONFIG_AUDIO_FRAME_QUEUE)       += audio_frame_queue.o
 OBJS-$(CONFIG_CRYSTALHD)               += crystalhd.o
 OBJS-$(CONFIG_DCT)                     += dct.o dct32_fixed.o dct32_float.o
-OBJS-$(CONFIG_DWT)                     += dwt.o snow.o
 OBJS-$(CONFIG_DXVA2)                   += dxva2.o
 OBJS-$(CONFIG_ENCODERS)                += faandct.o jfdctfst.o jfdctint.o
 OBJS-$(CONFIG_ERROR_RESILIENCE)        += error_resilience.o
@@ -49,8 +49,10 @@
 OBJS-$(CONFIG_FFT)                     += avfft.o fft_fixed.o fft_float.o \
                                           $(FFT-OBJS-yes)
 OBJS-$(CONFIG_GOLOMB)                  += golomb.o
+OBJS-$(CONFIG_H264CHROMA)              += h264chroma.o
 OBJS-$(CONFIG_H264DSP)                 += h264dsp.o h264idct.o
 OBJS-$(CONFIG_H264PRED)                += h264pred.o
+OBJS-$(CONFIG_H264QPEL)                += h264qpel.o
 OBJS-$(CONFIG_HUFFMAN)                 += huffman.o
 OBJS-$(CONFIG_LIBXVID)                 += libxvid_rc.o
 OBJS-$(CONFIG_LPC)                     += lpc.o
@@ -71,9 +73,11 @@
 OBJS-$(CONFIG_SINEWIN)                 += sinewin.o
 OBJS-$(CONFIG_VAAPI)                   += vaapi.o
 OBJS-$(CONFIG_VDPAU)                   += vdpau.o
+OBJS-$(CONFIG_VIDEODSP)                += videodsp.o
 OBJS-$(CONFIG_VP3DSP)                  += vp3dsp.o
 
 # decoders/encoders/hardware accelerators
+OBJS-$(CONFIG_ZERO12V_DECODER)         += 012v.o
 OBJS-$(CONFIG_A64MULTI_ENCODER)        += a64multienc.o elbg.o
 OBJS-$(CONFIG_A64MULTI5_ENCODER)       += a64multienc.o elbg.o
 OBJS-$(CONFIG_AAC_DECODER)             += aacdec.o aactab.o aacsbr.o aacps.o \
@@ -82,15 +86,14 @@
 OBJS-$(CONFIG_AAC_ENCODER)             += aacenc.o aaccoder.o    \
                                           aacpsy.o aactab.o      \
                                           psymodel.o iirfilter.o \
-                                          mpeg4audio.o kbdwin.o  \
-                                          audio_frame_queue.o
+                                          mpeg4audio.o kbdwin.o
 OBJS-$(CONFIG_AASC_DECODER)            += aasc.o msrledec.o
 OBJS-$(CONFIG_AC3_DECODER)             += ac3dec.o ac3dec_data.o ac3.o kbdwin.o
 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_ALAC_DECODER)            += alac.o
-OBJS-$(CONFIG_ALAC_ENCODER)            += alacenc.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
 OBJS-$(CONFIG_AMRNB_DECODER)           += amrnbdec.o celp_filters.o   \
                                           celp_math.o acelp_filters.o \
@@ -118,7 +121,7 @@
 OBJS-$(CONFIG_ATRAC3_DECODER)          += atrac3.o atrac.o
 OBJS-$(CONFIG_AURA_DECODER)            += cyuv.o
 OBJS-$(CONFIG_AURA2_DECODER)           += aura.o
-OBJS-$(CONFIG_AVRP_DECODER)            += avrndec.o
+OBJS-$(CONFIG_AVRN_DECODER)            += avrndec.o mjpegdec.o mjpeg.o
 OBJS-$(CONFIG_AVRP_DECODER)            += r210dec.o
 OBJS-$(CONFIG_AVRP_ENCODER)            += r210enc.o
 OBJS-$(CONFIG_AVS_DECODER)             += avs.o
@@ -154,9 +157,9 @@
 OBJS-$(CONFIG_CYUV_DECODER)            += cyuv.o
 OBJS-$(CONFIG_DCA_DECODER)             += dcadec.o dca.o dcadsp.o      \
                                           dca_parser.o synth_filter.o
-OBJS-$(CONFIG_DCA_ENCODER)             += dcaenc.o
+OBJS-$(CONFIG_DCA_ENCODER)             += dcaenc.o dca.o
 OBJS-$(CONFIG_DIRAC_DECODER)           += diracdec.o dirac.o diracdsp.o \
-                                          dirac_arith.o mpeg12data.o dwt.o
+                                          dirac_arith.o mpeg12data.o dirac_dwt.o
 OBJS-$(CONFIG_DFA_DECODER)             += dfa.o
 OBJS-$(CONFIG_DNXHD_DECODER)           += dnxhddec.o dnxhddata.o
 OBJS-$(CONFIG_DNXHD_ENCODER)           += dnxhdenc.o dnxhddata.o
@@ -186,11 +189,12 @@
 OBJS-$(CONFIG_EIGHTSVX_FIB_DECODER)    += 8svx.o
 OBJS-$(CONFIG_ESCAPE124_DECODER)       += escape124.o
 OBJS-$(CONFIG_ESCAPE130_DECODER)       += escape130.o
+OBJS-$(CONFIG_EVRC_DECODER)            += evrcdec.o acelp_vectors.o lsp.o
 OBJS-$(CONFIG_EXR_DECODER)             += exr.o
 OBJS-$(CONFIG_FFV1_DECODER)            += ffv1dec.o ffv1.o
 OBJS-$(CONFIG_FFV1_ENCODER)            += ffv1enc.o ffv1.o
-OBJS-$(CONFIG_FFVHUFF_DECODER)         += huffyuv.o
-OBJS-$(CONFIG_FFVHUFF_ENCODER)         += huffyuv.o
+OBJS-$(CONFIG_FFVHUFF_DECODER)         += huffyuv.o huffyuvdec.o
+OBJS-$(CONFIG_FFVHUFF_ENCODER)         += huffyuv.o huffyuvenc.o
 OBJS-$(CONFIG_FFWAVESYNTH_DECODER)     += ffwavesynth.o
 OBJS-$(CONFIG_FLAC_DECODER)            += flacdec.o flacdata.o flac.o flacdsp.o
 OBJS-$(CONFIG_FLAC_ENCODER)            += flacenc.o flacdata.o flac.o flacdsp.o vorbis_data.o
@@ -203,7 +207,7 @@
 OBJS-$(CONFIG_FRAPS_DECODER)           += fraps.o
 OBJS-$(CONFIG_FRWU_DECODER)            += frwu.o
 OBJS-$(CONFIG_G723_1_DECODER)          += g723_1.o acelp_vectors.o \
-                                          celp_filters.o
+                                          celp_filters.o celp_math.o
 OBJS-$(CONFIG_G723_1_ENCODER)          += g723_1.o acelp_vectors.o celp_math.o
 OBJS-$(CONFIG_G729_DECODER)            += g729dec.o lsp.o celp_math.o acelp_filters.o acelp_pitch_delay.o acelp_vectors.o g729postfilter.o
 OBJS-$(CONFIG_GIF_DECODER)             += gifdec.o lzw.o
@@ -216,6 +220,7 @@
                                           mpeg4video.o mpeg4videodec.o flvdec.o\
                                           intelh263dec.o
 OBJS-$(CONFIG_H263_VAAPI_HWACCEL)      += vaapi_mpeg4.o
+OBJS-$(CONFIG_H263_VDPAU_HWACCEL)      += vdpau_mpeg4.o
 OBJS-$(CONFIG_H263_ENCODER)            += mpeg4videoenc.o mpeg4video.o  \
                                           h263.o ituh263enc.o flvenc.o
 OBJS-$(CONFIG_H264_DECODER)            += h264.o                               \
@@ -226,8 +231,9 @@
 OBJS-$(CONFIG_H264_VAAPI_HWACCEL)      += vaapi_h264.o
 OBJS-$(CONFIG_H264_VDA_HWACCEL)        += vda_h264.o
 OBJS-$(CONFIG_H264_VDA_DECODER)        += vda_h264_dec.o
-OBJS-$(CONFIG_HUFFYUV_DECODER)         += huffyuv.o
-OBJS-$(CONFIG_HUFFYUV_ENCODER)         += huffyuv.o
+OBJS-$(CONFIG_H264_VDPAU_HWACCEL)      += vdpau_h264.o
+OBJS-$(CONFIG_HUFFYUV_DECODER)         += huffyuv.o huffyuvdec.o
+OBJS-$(CONFIG_HUFFYUV_ENCODER)         += huffyuv.o huffyuvenc.o
 OBJS-$(CONFIG_IAC_DECODER)             += imc.o
 OBJS-$(CONFIG_IDCIN_DECODER)           += idcinvideo.o
 OBJS-$(CONFIG_IDF_DECODER)             += bintext.o cga_data.o
@@ -282,15 +288,19 @@
 OBJS-$(CONFIG_MPEGVIDEO_DECODER)       += mpeg12.o mpeg12data.o \
                                           mpegvideo.o error_resilience.o
 OBJS-$(CONFIG_MPEG_XVMC_DECODER)       += mpegvideo_xvmc.o
+OBJS-$(CONFIG_MPEG1_VDPAU_HWACCEL)     += vdpau_mpeg12.o
 OBJS-$(CONFIG_MPEG1VIDEO_DECODER)      += mpeg12.o mpeg12data.o
 OBJS-$(CONFIG_MPEG1VIDEO_ENCODER)      += mpeg12enc.o mpeg12.o          \
                                           timecode.o
 OBJS-$(CONFIG_MPEG2_DXVA2_HWACCEL)     += dxva2_mpeg2.o
 OBJS-$(CONFIG_MPEG2_VAAPI_HWACCEL)     += vaapi_mpeg2.o
+OBJS-$(CONFIG_MPEG2_VDPAU_HWACCEL)     += vdpau_mpeg12.o
 OBJS-$(CONFIG_MPEG2VIDEO_DECODER)      += mpeg12.o mpeg12data.o
 OBJS-$(CONFIG_MPEG2VIDEO_ENCODER)      += mpeg12enc.o mpeg12.o          \
                                           timecode.o
 OBJS-$(CONFIG_MPEG4_VAAPI_HWACCEL)     += vaapi_mpeg4.o
+OBJS-$(CONFIG_MPEG4_VDPAU_HWACCEL)     += vdpau_mpeg4.o
+OBJS-$(CONFIG_MPL2_DECODER)            += mpl2dec.o ass.o
 OBJS-$(CONFIG_MSMPEG4V1_DECODER)       += msmpeg4.o msmpeg4data.o
 OBJS-$(CONFIG_MSMPEG4V2_DECODER)       += msmpeg4.o msmpeg4data.o h263dec.o \
                                           h263.o ituh263dec.o mpeg4videodec.o
@@ -310,10 +320,11 @@
 OBJS-$(CONFIG_MSVIDEO1_ENCODER)        += msvideo1enc.o elbg.o
 OBJS-$(CONFIG_MSZH_DECODER)            += lcldec.o
 OBJS-$(CONFIG_MTS2_DECODER)            += mss4.o mss34dsp.o
+OBJS-$(CONFIG_MVC1_DECODER)            += mvcdec.o
+OBJS-$(CONFIG_MVC2_DECODER)            += mvcdec.o
 OBJS-$(CONFIG_MXPEG_DECODER)           += mxpegdec.o mjpegdec.o mjpeg.o
 OBJS-$(CONFIG_NELLYMOSER_DECODER)      += nellymoserdec.o nellymoser.o
-OBJS-$(CONFIG_NELLYMOSER_ENCODER)      += nellymoserenc.o nellymoser.o \
-                                          audio_frame_queue.o
+OBJS-$(CONFIG_NELLYMOSER_ENCODER)      += nellymoserenc.o nellymoser.o
 OBJS-$(CONFIG_NUV_DECODER)             += nuv.o rtjpeg.o
 OBJS-$(CONFIG_PAF_VIDEO_DECODER)       += paf.o
 OBJS-$(CONFIG_PAF_AUDIO_DECODER)       += paf.o
@@ -329,6 +340,7 @@
 OBJS-$(CONFIG_PGMYUV_ENCODER)          += pnmenc.o pnm.o
 OBJS-$(CONFIG_PGSSUB_DECODER)          += pgssubdec.o
 OBJS-$(CONFIG_PICTOR_DECODER)          += pictordec.o cga_data.o
+OBJS-$(CONFIG_PJS_DECODER)             += textdec.o ass.o
 OBJS-$(CONFIG_PNG_DECODER)             += png.o pngdec.o pngdsp.o
 OBJS-$(CONFIG_PNG_ENCODER)             += png.o pngenc.o
 OBJS-$(CONFIG_PPM_DECODER)             += pnmdec.o pnm.o
@@ -352,8 +364,7 @@
 OBJS-$(CONFIG_R210_DECODER)            += r210dec.o
 OBJS-$(CONFIG_R210_ENCODER)            += r210enc.o
 OBJS-$(CONFIG_RA_144_DECODER)          += ra144dec.o ra144.o celp_filters.o
-OBJS-$(CONFIG_RA_144_ENCODER)          += ra144enc.o ra144.o celp_filters.o \
-                                          audio_frame_queue.o
+OBJS-$(CONFIG_RA_144_ENCODER)          += ra144enc.o ra144.o celp_filters.o
 OBJS-$(CONFIG_RA_288_DECODER)          += ra288.o celp_filters.o
 OBJS-$(CONFIG_RALF_DECODER)            += ralf.o
 OBJS-$(CONFIG_RAWVIDEO_DECODER)        += rawdec.o
@@ -376,6 +387,7 @@
 OBJS-$(CONFIG_SANM_DECODER)            += sanm.o
 OBJS-$(CONFIG_SGI_DECODER)             += sgidec.o
 OBJS-$(CONFIG_SGI_ENCODER)             += sgienc.o rle.o
+OBJS-$(CONFIG_SGIRLE_DECODER)          += sgirledec.o
 OBJS-$(CONFIG_SHORTEN_DECODER)         += shorten.o
 OBJS-$(CONFIG_SIPR_DECODER)            += sipr.o acelp_pitch_delay.o \
                                           celp_math.o acelp_vectors.o \
@@ -384,8 +396,8 @@
 OBJS-$(CONFIG_SMACKAUD_DECODER)        += smacker.o
 OBJS-$(CONFIG_SMACKER_DECODER)         += smacker.o
 OBJS-$(CONFIG_SMC_DECODER)             += smc.o
-OBJS-$(CONFIG_SNOW_DECODER)            += snowdec.o snow.o
-OBJS-$(CONFIG_SNOW_ENCODER)            += snowenc.o snow.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
 OBJS-$(CONFIG_SOL_DPCM_DECODER)        += dpcm.o
 OBJS-$(CONFIG_SONIC_DECODER)           += sonic.o
@@ -396,6 +408,7 @@
 OBJS-$(CONFIG_SRT_ENCODER)             += srtenc.o ass_split.o
 OBJS-$(CONFIG_SUBRIP_DECODER)          += srtdec.o ass.o
 OBJS-$(CONFIG_SUBRIP_ENCODER)          += srtenc.o ass_split.o
+OBJS-$(CONFIG_SUBVIEWER1_DECODER)      += textdec.o ass.o
 OBJS-$(CONFIG_SUBVIEWER_DECODER)       += subviewerdec.o ass.o
 OBJS-$(CONFIG_SUNRAST_DECODER)         += sunrast.o
 OBJS-$(CONFIG_SUNRAST_ENCODER)         += sunrastenc.o
@@ -445,12 +458,12 @@
                                           intrax8.o intrax8dsp.o
 OBJS-$(CONFIG_VC1_DXVA2_HWACCEL)       += dxva2_vc1.o
 OBJS-$(CONFIG_VC1_VAAPI_HWACCEL)       += vaapi_vc1.o
+OBJS-$(CONFIG_VC1_VDPAU_HWACCEL)       += vdpau_vc1.o
 OBJS-$(CONFIG_VCR1_DECODER)            += vcr1.o
-OBJS-$(CONFIG_VCR1_ENCODER)            += vcr1.o
 OBJS-$(CONFIG_VMDAUDIO_DECODER)        += vmdav.o
 OBJS-$(CONFIG_VMDVIDEO_DECODER)        += vmdav.o
 OBJS-$(CONFIG_VMNC_DECODER)            += vmnc.o
-OBJS-$(CONFIG_VORBIS_DECODER)          += vorbisdec.o vorbis.o \
+OBJS-$(CONFIG_VORBIS_DECODER)          += vorbisdec.o vorbisdsp.o vorbis.o \
                                           vorbis_data.o xiph.o
 OBJS-$(CONFIG_VORBIS_ENCODER)          += vorbisenc.o vorbis.o \
                                           vorbis_data.o
@@ -460,6 +473,7 @@
 OBJS-$(CONFIG_VP6_DECODER)             += vp6.o vp56.o vp56data.o vp56dsp.o \
                                           vp6dsp.o vp56rac.o
 OBJS-$(CONFIG_VP8_DECODER)             += vp8.o vp8dsp.o vp56rac.o
+OBJS-$(CONFIG_VPLAYER_DECODER)         += textdec.o ass.o
 OBJS-$(CONFIG_VQA_DECODER)             += vqavideo.o
 OBJS-$(CONFIG_WAVPACK_DECODER)         += wavpack.o
 OBJS-$(CONFIG_WEBVTT_DECODER)          += webvttdec.o
@@ -473,10 +487,10 @@
                                           celp_filters.o \
                                           acelp_vectors.o acelp_filters.o
 OBJS-$(CONFIG_WMV1_DECODER)            += msmpeg4.o msmpeg4data.o
-OBJS-$(CONFIG_WMV2_DECODER)            += wmv2dec.o wmv2.o        \
+OBJS-$(CONFIG_WMV2_DECODER)            += wmv2dec.o wmv2.o wmv2dsp.o \
                                           msmpeg4.o msmpeg4data.o \
                                           intrax8.o intrax8dsp.o
-OBJS-$(CONFIG_WMV2_ENCODER)            += wmv2enc.o wmv2.o \
+OBJS-$(CONFIG_WMV2_ENCODER)            += wmv2enc.o wmv2.o wmv2dsp.o \
                                           msmpeg4.o msmpeg4enc.o msmpeg4data.o \
                                           mpeg4videodec.o ituh263dec.o h263dec.o
 OBJS-$(CONFIG_WNV1_DECODER)            += wnv1.o
@@ -631,7 +645,7 @@
 OBJS-$(CONFIG_MOV_MUXER)               += mpeg4audio.o mpegaudiodata.o
 OBJS-$(CONFIG_MPEGTS_MUXER)            += mpeg4audio.o
 OBJS-$(CONFIG_MPEGTS_DEMUXER)          += mpeg4audio.o mpegaudiodata.o
-OBJS-$(CONFIG_MXF_MUXER)               += timecode.o
+OBJS-$(CONFIG_MXF_MUXER)               += timecode.o dnxhddata.o
 OBJS-$(CONFIG_NUT_MUXER)               += mpegaudiodata.o
 OBJS-$(CONFIG_OGG_DEMUXER)             += xiph.o flac.o flacdata.o     \
                                           mpeg12data.o vorbis_parser.o \
@@ -642,6 +656,7 @@
 OBJS-$(CONFIG_RTPDEC)                  += mjpeg.o
 OBJS-$(CONFIG_SPDIF_DEMUXER)           += aacadtsdec.o mpeg4audio.o
 OBJS-$(CONFIG_SPDIF_MUXER)             += dca.o
+OBJS-$(CONFIG_TAK_DEMUXER)             += tak.o
 OBJS-$(CONFIG_WEBM_MUXER)              += mpeg4audio.o mpegaudiodata.o  \
                                           xiph.o flac.o flacdata.o \
                                           vorbis_data.o
@@ -650,46 +665,44 @@
 # external codec libraries
 OBJS-$(CONFIG_LIBAACPLUS_ENCODER)         += libaacplus.o
 OBJS-$(CONFIG_LIBCELT_DECODER)            += libcelt_dec.o
-OBJS-$(CONFIG_LIBFAAC_ENCODER)            += libfaac.o audio_frame_queue.o
-OBJS-$(CONFIG_LIBFDK_AAC_ENCODER)         += libfdk-aacenc.o audio_frame_queue.o
+OBJS-$(CONFIG_LIBFAAC_ENCODER)            += libfaac.o
+OBJS-$(CONFIG_LIBFDK_AAC_ENCODER)         += libfdk-aacenc.o
 OBJS-$(CONFIG_LIBGSM_DECODER)             += libgsm.o
 OBJS-$(CONFIG_LIBGSM_ENCODER)             += libgsm.o
 OBJS-$(CONFIG_LIBGSM_MS_DECODER)          += libgsm.o
 OBJS-$(CONFIG_LIBGSM_MS_ENCODER)          += libgsm.o
 OBJS-$(CONFIG_LIBILBC_DECODER)            += libilbc.o
 OBJS-$(CONFIG_LIBILBC_ENCODER)            += libilbc.o
-OBJS-$(CONFIG_LIBMP3LAME_ENCODER)         += libmp3lame.o mpegaudiodecheader.o \
-                                             audio_frame_queue.o
-OBJS-$(CONFIG_LIBOPENCORE_AMRNB_DECODER)  += libopencore-amr.o \
-                                             audio_frame_queue.o
-OBJS-$(CONFIG_LIBOPENCORE_AMRNB_ENCODER)  += libopencore-amr.o \
-                                             audio_frame_queue.o
+OBJS-$(CONFIG_LIBMP3LAME_ENCODER)         += libmp3lame.o mpegaudiodecheader.o
+OBJS-$(CONFIG_LIBOPENCORE_AMRNB_DECODER)  += libopencore-amr.o
+OBJS-$(CONFIG_LIBOPENCORE_AMRNB_ENCODER)  += libopencore-amr.o
 OBJS-$(CONFIG_LIBOPENCORE_AMRWB_DECODER)  += libopencore-amr.o
 OBJS-$(CONFIG_LIBOPENJPEG_DECODER)        += libopenjpegdec.o
 OBJS-$(CONFIG_LIBOPENJPEG_ENCODER)        += libopenjpegenc.o
 OBJS-$(CONFIG_LIBOPUS_DECODER)            += libopusdec.o libopus.o     \
                                              vorbis_data.o
 OBJS-$(CONFIG_LIBOPUS_ENCODER)            += libopusenc.o libopus.o     \
-                                             vorbis_data.o audio_frame_queue.o
+                                             vorbis_data.o
 OBJS-$(CONFIG_LIBSCHROEDINGER_DECODER)    += libschroedingerdec.o \
                                              libschroedinger.o
 OBJS-$(CONFIG_LIBSCHROEDINGER_ENCODER)    += libschroedingerenc.o \
                                              libschroedinger.o
 OBJS-$(CONFIG_LIBSPEEX_DECODER)           += libspeexdec.o
-OBJS-$(CONFIG_LIBSPEEX_ENCODER)           += libspeexenc.o audio_frame_queue.o
+OBJS-$(CONFIG_LIBSPEEX_ENCODER)           += libspeexenc.o
 OBJS-$(CONFIG_LIBSTAGEFRIGHT_H264_DECODER)+= libstagefright.o
 OBJS-$(CONFIG_LIBTHEORA_ENCODER)          += libtheoraenc.o
 OBJS-$(CONFIG_LIBTWOLAME_ENCODER)         += libtwolame.o
 OBJS-$(CONFIG_LIBUTVIDEO_DECODER)         += libutvideodec.o
 OBJS-$(CONFIG_LIBUTVIDEO_ENCODER)         += libutvideoenc.o
-OBJS-$(CONFIG_LIBVO_AACENC_ENCODER)       += libvo-aacenc.o mpeg4audio.o \
-                                             audio_frame_queue.o
+OBJS-$(CONFIG_LIBVO_AACENC_ENCODER)       += libvo-aacenc.o mpeg4audio.o
 OBJS-$(CONFIG_LIBVO_AMRWBENC_ENCODER)     += libvo-amrwbenc.o
 OBJS-$(CONFIG_LIBVORBIS_DECODER)          += libvorbisdec.o
-OBJS-$(CONFIG_LIBVORBIS_ENCODER)          += libvorbisenc.o audio_frame_queue.o \
+OBJS-$(CONFIG_LIBVORBIS_ENCODER)          += libvorbisenc.o \
                                              vorbis_data.o vorbis_parser.o xiph.o
-OBJS-$(CONFIG_LIBVPX_DECODER)             += libvpxdec.o
-OBJS-$(CONFIG_LIBVPX_ENCODER)             += libvpxenc.o
+OBJS-$(CONFIG_LIBVPX_VP8_DECODER)         += libvpxdec.o
+OBJS-$(CONFIG_LIBVPX_VP8_ENCODER)         += libvpxenc.o
+OBJS-$(CONFIG_LIBVPX_VP9_DECODER)         += libvpxdec.o
+OBJS-$(CONFIG_LIBVPX_VP9_ENCODER)         += libvpxenc.o
 OBJS-$(CONFIG_LIBX264_ENCODER)            += libx264.o
 OBJS-$(CONFIG_LIBXAVS_ENCODER)            += libxavs.o
 OBJS-$(CONFIG_LIBXVID_ENCODER)            += libxvid.o
diff --git a/libavcodec/aac.h b/libavcodec/aac.h
index 9ceccf8..d586e27 100644
--- a/libavcodec/aac.h
+++ b/libavcodec/aac.h
@@ -32,7 +32,6 @@
 
 #include "libavutil/float_dsp.h"
 #include "avcodec.h"
-#include "dsputil.h"
 #include "fft.h"
 #include "mpeg4audio.h"
 #include "sbr.h"
@@ -260,9 +259,10 @@
 /**
  * main AAC context
  */
-typedef struct AACContext {
+struct AACContext {
+    AVClass        *class;
     AVCodecContext *avctx;
-    AVFrame frame;
+    AVFrame *frame;
 
     int is_saved;                 ///< Set if elements have stored overlap from previous frame.
     DynamicRangeControl che_drc;
@@ -291,7 +291,6 @@
     FFTContext mdct;
     FFTContext mdct_small;
     FFTContext mdct_ltp;
-    DSPContext dsp;
     FmtConvertContext fmt_conv;
     AVFloatDSPContext fdsp;
     int random_state;
@@ -309,14 +308,26 @@
      * @name Japanese DTV specific extension
      * @{
      */
-    int enable_jp_dmono; ///< enable japanese DTV specific 'dual mono'
-    int dmono_mode;      ///< select the channel to decode in dual mono.
+    int force_dmono_mode;///< 0->not dmono, 1->use first channel, 2->use second channel
+    int dmono_mode;      ///< 0->not dmono, 1->use first channel, 2->use second channel
     /** @} */
 
     DECLARE_ALIGNED(32, float, temp)[128];
 
     OutputConfiguration oc[2];
     int warned_num_aac_frames;
-} AACContext;
+
+    /* aacdec functions pointers */
+    void (*imdct_and_windowing)(AACContext *ac, SingleChannelElement *sce);
+    void (*apply_ltp)(AACContext *ac, SingleChannelElement *sce);
+    void (*apply_tns)(float coef[1024], TemporalNoiseShaping *tns,
+                      IndividualChannelStream *ics, int decode);
+    void (*windowing_and_mdct_ltp)(AACContext *ac, float *out,
+                                   float *in, IndividualChannelStream *ics);
+    void (*update_ltp)(AACContext *ac, SingleChannelElement *sce);
+
+};
+
+void ff_aacdec_init_mips(AACContext *c);
 
 #endif /* AVCODEC_AAC_H */
diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c
index 719426c..7a871c4 100644
--- a/libavcodec/aacdec.c
+++ b/libavcodec/aacdec.c
@@ -80,10 +80,10 @@
  */
 
 #include "libavutil/float_dsp.h"
+#include "libavutil/opt.h"
 #include "avcodec.h"
 #include "internal.h"
 #include "get_bits.h"
-#include "dsputil.h"
 #include "fft.h"
 #include "fmtconvert.h"
 #include "lpc.h"
@@ -107,11 +107,17 @@
 
 #if ARCH_ARM
 #   include "arm/aac.h"
+#elif ARCH_MIPS
+#   include "mips/aacdec_mips.h"
 #endif
 
 static VLC vlc_scalefactors;
 static VLC vlc_spectral[11];
 
+static int output_configure(AACContext *ac,
+                            uint8_t layout_map[MAX_ELEM_ID*4][3], int tags,
+                            enum OCStatus oc_type, int get_new_frame);
+
 #define overread_err "Input buffer exhausted before END element found\n"
 
 static int count_channels(uint8_t (*layout)[3], int tags)
@@ -184,8 +190,8 @@
     }
 
     /* get output buffer */
-    ac->frame.nb_samples = 2048;
-    if ((ret = avctx->get_buffer(avctx, &ac->frame)) < 0) {
+    ac->frame->nb_samples = 2048;
+    if ((ret = ff_get_buffer(avctx, ac->frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -193,7 +199,7 @@
     /* map output channel pointers to AVFrame data */
     for (ch = 0; ch < avctx->channels; ch++) {
         if (ac->output_element[ch])
-            ac->output_element[ch]->ret = (float *)ac->frame.extended_data[ch];
+            ac->output_element[ch]->ret = (float *)ac->frame->extended_data[ch];
     }
 
     return 0;
@@ -405,6 +411,8 @@
         ac->oc[1] = ac->oc[0];
         ac->avctx->channels = ac->oc[1].channels;
         ac->avctx->channel_layout = ac->oc[1].channel_layout;
+        output_configure(ac, ac->oc[1].layout_map, ac->oc[1].layout_map_tags,
+                         ac->oc[1].status, 0);
     }
 }
 
@@ -773,13 +781,15 @@
 {
     GetBitContext gb;
     int i;
+    int 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, "\n");
 
-    init_get_bits(&gb, data, bit_size);
+    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;
@@ -869,6 +879,8 @@
         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);
+
 static av_cold int aac_decode_init(AVCodecContext *avctx)
 {
     AACContext *ac = avctx->priv_data;
@@ -876,6 +888,8 @@
     ac->avctx = avctx;
     ac->oc[1].m4ac.sample_rate = avctx->sample_rate;
 
+    aacdec_init(ac);
+
     avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
 
     if (avctx->extradata_size > 0) {
@@ -913,6 +927,11 @@
         }
     }
 
+    if (avctx->channels > MAX_CHANNELS) {
+        av_log(avctx, AV_LOG_ERROR, "Too many channels\n");
+        return AVERROR_INVALIDDATA;
+    }
+
     AAC_INIT_VLC_STATIC( 0, 304);
     AAC_INIT_VLC_STATIC( 1, 270);
     AAC_INIT_VLC_STATIC( 2, 550);
@@ -927,7 +946,6 @@
 
     ff_aac_sbr_init();
 
-    ff_dsputil_init(&ac->dsp, avctx);
     ff_fmt_convert_init(&ac->fmt_conv, avctx);
     avpriv_float_dsp_init(&ac->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
 
@@ -951,9 +969,6 @@
 
     cbrt_tableinit();
 
-    avcodec_get_frame_defaults(&ac->frame);
-    avctx->coded_frame = &ac->frame;
-
     return 0;
 }
 
@@ -1393,7 +1408,7 @@
                         cfo[k] = ac->random_state;
                     }
 
-                    band_energy = ac->dsp.scalarproduct_float(cfo, cfo, off_len);
+                    band_energy = ac->fdsp.scalarproduct_float(cfo, cfo, off_len);
                     scale = sf[idx] / sqrtf(band_energy);
                     ac->fdsp.vector_fmul_scalar(cfo, cfo, scale, off_len);
                 }
@@ -1728,9 +1743,9 @@
             if (cpe->ms_mask[idx] &&
                     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->dsp.butterflies_float(ch0 + group * 128 + offsets[i],
-                                              ch1 + group * 128 + offsets[i],
-                                              offsets[i+1] - offsets[i]);
+                    ac->fdsp.butterflies_float(ch0 + group * 128 + offsets[i],
+                                               ch1 + group * 128 + offsets[i],
+                                               offsets[i+1] - offsets[i]);
                 }
             }
         }
@@ -2130,9 +2145,9 @@
         ac->fdsp.vector_fmul(in + 448, in + 448, swindow_prev, 128);
     }
     if (ics->window_sequence[0] != LONG_START_SEQUENCE) {
-        ac->dsp.vector_fmul_reverse(in + 1024, in + 1024, lwindow, 1024);
+        ac->fdsp.vector_fmul_reverse(in + 1024, in + 1024, lwindow, 1024);
     } else {
-        ac->dsp.vector_fmul_reverse(in + 1024 + 448, in + 1024 + 448, swindow, 128);
+        ac->fdsp.vector_fmul_reverse(in + 1024 + 448, in + 1024 + 448, swindow, 128);
         memset(in + 1024 + 576, 0, 448 * sizeof(float));
     }
     ac->mdct_ltp.mdct_calc(&ac->mdct_ltp, out, in);
@@ -2158,10 +2173,10 @@
             predTime[i] = sce->ltp_state[i + 2048 - ltp->lag] * ltp->coef;
         memset(&predTime[i], 0, (2048 - i) * sizeof(float));
 
-        windowing_and_mdct_ltp(ac, predFreq, predTime, &sce->ics);
+        ac->windowing_and_mdct_ltp(ac, predFreq, predTime, &sce->ics);
 
         if (sce->tns.present)
-            apply_tns(predFreq, &sce->tns, &sce->ics, 0);
+            ac->apply_tns(predFreq, &sce->tns, &sce->ics, 0);
 
         for (sfb = 0; sfb < FFMIN(sce->ics.max_sfb, MAX_LTP_LONG_SFB); sfb++)
             if (ltp->used[sfb])
@@ -2185,17 +2200,17 @@
     if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
         memcpy(saved_ltp,       saved, 512 * sizeof(float));
         memset(saved_ltp + 576, 0,     448 * sizeof(float));
-        ac->dsp.vector_fmul_reverse(saved_ltp + 448, ac->buf_mdct + 960,     &swindow[64],      64);
+        ac->fdsp.vector_fmul_reverse(saved_ltp + 448, ac->buf_mdct + 960,     &swindow[64],      64);
         for (i = 0; i < 64; i++)
             saved_ltp[i + 512] = ac->buf_mdct[1023 - i] * swindow[63 - i];
     } else if (ics->window_sequence[0] == LONG_START_SEQUENCE) {
         memcpy(saved_ltp,       ac->buf_mdct + 512, 448 * sizeof(float));
         memset(saved_ltp + 576, 0,                  448 * sizeof(float));
-        ac->dsp.vector_fmul_reverse(saved_ltp + 448, ac->buf_mdct + 960,     &swindow[64],      64);
+        ac->fdsp.vector_fmul_reverse(saved_ltp + 448, ac->buf_mdct + 960,     &swindow[64],      64);
         for (i = 0; i < 64; i++)
             saved_ltp[i + 512] = ac->buf_mdct[1023 - i] * swindow[63 - i];
     } else { // LONG_STOP or ONLY_LONG
-        ac->dsp.vector_fmul_reverse(saved_ltp,       ac->buf_mdct + 512,     &lwindow[512],     512);
+        ac->fdsp.vector_fmul_reverse(saved_ltp,       ac->buf_mdct + 512,     &lwindow[512],     512);
         for (i = 0; i < 512; i++)
             saved_ltp[i + 512] = ac->buf_mdct[1023 - i] * lwindow[511 - i];
     }
@@ -2236,35 +2251,35 @@
      */
     if ((ics->window_sequence[1] == ONLY_LONG_SEQUENCE || ics->window_sequence[1] == LONG_STOP_SEQUENCE) &&
             (ics->window_sequence[0] == ONLY_LONG_SEQUENCE || ics->window_sequence[0] == LONG_START_SEQUENCE)) {
-        ac->dsp.vector_fmul_window(    out,               saved,            buf,         lwindow_prev, 512);
+        ac->fdsp.vector_fmul_window(    out,               saved,            buf,         lwindow_prev, 512);
     } else {
-        memcpy(                        out,               saved,            448 * sizeof(float));
+        memcpy(                         out,               saved,            448 * sizeof(float));
 
         if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
-            ac->dsp.vector_fmul_window(out + 448 + 0*128, saved + 448,      buf + 0*128, swindow_prev, 64);
-            ac->dsp.vector_fmul_window(out + 448 + 1*128, buf + 0*128 + 64, buf + 1*128, swindow,      64);
-            ac->dsp.vector_fmul_window(out + 448 + 2*128, buf + 1*128 + 64, buf + 2*128, swindow,      64);
-            ac->dsp.vector_fmul_window(out + 448 + 3*128, buf + 2*128 + 64, buf + 3*128, swindow,      64);
-            ac->dsp.vector_fmul_window(temp,              buf + 3*128 + 64, buf + 4*128, swindow,      64);
-            memcpy(                    out + 448 + 4*128, temp, 64 * sizeof(float));
+            ac->fdsp.vector_fmul_window(out + 448 + 0*128, saved + 448,      buf + 0*128, swindow_prev, 64);
+            ac->fdsp.vector_fmul_window(out + 448 + 1*128, buf + 0*128 + 64, buf + 1*128, swindow,      64);
+            ac->fdsp.vector_fmul_window(out + 448 + 2*128, buf + 1*128 + 64, buf + 2*128, swindow,      64);
+            ac->fdsp.vector_fmul_window(out + 448 + 3*128, buf + 2*128 + 64, buf + 3*128, swindow,      64);
+            ac->fdsp.vector_fmul_window(temp,              buf + 3*128 + 64, buf + 4*128, swindow,      64);
+            memcpy(                     out + 448 + 4*128, temp, 64 * sizeof(float));
         } else {
-            ac->dsp.vector_fmul_window(out + 448,         saved + 448,      buf,         swindow_prev, 64);
-            memcpy(                    out + 576,         buf + 64,         448 * sizeof(float));
+            ac->fdsp.vector_fmul_window(out + 448,         saved + 448,      buf,         swindow_prev, 64);
+            memcpy(                     out + 576,         buf + 64,         448 * sizeof(float));
         }
     }
 
     // buffer update
     if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
-        memcpy(                    saved,       temp + 64,         64 * sizeof(float));
-        ac->dsp.vector_fmul_window(saved + 64,  buf + 4*128 + 64, buf + 5*128, swindow, 64);
-        ac->dsp.vector_fmul_window(saved + 192, buf + 5*128 + 64, buf + 6*128, swindow, 64);
-        ac->dsp.vector_fmul_window(saved + 320, buf + 6*128 + 64, buf + 7*128, swindow, 64);
-        memcpy(                    saved + 448, buf + 7*128 + 64,  64 * sizeof(float));
+        memcpy(                     saved,       temp + 64,         64 * sizeof(float));
+        ac->fdsp.vector_fmul_window(saved + 64,  buf + 4*128 + 64, buf + 5*128, swindow, 64);
+        ac->fdsp.vector_fmul_window(saved + 192, buf + 5*128 + 64, buf + 6*128, swindow, 64);
+        ac->fdsp.vector_fmul_window(saved + 320, buf + 6*128 + 64, buf + 7*128, swindow, 64);
+        memcpy(                     saved + 448, buf + 7*128 + 64,  64 * sizeof(float));
     } else if (ics->window_sequence[0] == LONG_START_SEQUENCE) {
-        memcpy(                    saved,       buf + 512,        448 * sizeof(float));
-        memcpy(                    saved + 448, buf + 7*128 + 64,  64 * sizeof(float));
+        memcpy(                     saved,       buf + 512,        448 * sizeof(float));
+        memcpy(                     saved + 448, buf + 7*128 + 64,  64 * sizeof(float));
     } else { // LONG_STOP or ONLY_LONG
-        memcpy(                    saved,       buf + 512,        512 * sizeof(float));
+        memcpy(                     saved,       buf + 512,        512 * sizeof(float));
     }
 }
 
@@ -2373,25 +2388,25 @@
                 if (ac->oc[1].m4ac.object_type == AOT_AAC_LTP) {
                     if (che->ch[0].ics.predictor_present) {
                         if (che->ch[0].ics.ltp.present)
-                            apply_ltp(ac, &che->ch[0]);
+                            ac->apply_ltp(ac, &che->ch[0]);
                         if (che->ch[1].ics.ltp.present && type == TYPE_CPE)
-                            apply_ltp(ac, &che->ch[1]);
+                            ac->apply_ltp(ac, &che->ch[1]);
                     }
                 }
                 if (che->ch[0].tns.present)
-                    apply_tns(che->ch[0].coeffs, &che->ch[0].tns, &che->ch[0].ics, 1);
+                    ac->apply_tns(che->ch[0].coeffs, &che->ch[0].tns, &che->ch[0].ics, 1);
                 if (che->ch[1].tns.present)
-                    apply_tns(che->ch[1].coeffs, &che->ch[1].tns, &che->ch[1].ics, 1);
+                    ac->apply_tns(che->ch[1].coeffs, &che->ch[1].tns, &che->ch[1].ics, 1);
                 if (type <= TYPE_CPE)
                     apply_channel_coupling(ac, che, type, i, BETWEEN_TNS_AND_IMDCT, apply_dependent_coupling);
                 if (type != TYPE_CCE || che->coup.coupling_point == AFTER_IMDCT) {
-                    imdct_and_windowing(ac, &che->ch[0]);
+                    ac->imdct_and_windowing(ac, &che->ch[0]);
                     if (ac->oc[1].m4ac.object_type == AOT_AAC_LTP)
-                        update_ltp(ac, &che->ch[0]);
+                        ac->update_ltp(ac, &che->ch[0]);
                     if (type == TYPE_CPE) {
-                        imdct_and_windowing(ac, &che->ch[1]);
+                        ac->imdct_and_windowing(ac, &che->ch[1]);
                         if (ac->oc[1].m4ac.object_type == AOT_AAC_LTP)
-                            update_ltp(ac, &che->ch[1]);
+                            ac->update_ltp(ac, &che->ch[1]);
                     }
                     if (ac->oc[1].m4ac.sbr > 0) {
                         ff_sbr_apply(ac, &che->sbr, type, che->ch[0].ret, che->ch[1].ret);
@@ -2435,18 +2450,16 @@
              * WITHOUT specifying PCE.
              *  thus, set dual mono as default.
              */
-#if 0
-            if (ac->enable_jp_dmono && ac->oc[0].status == OC_NONE) {
+            if (ac->dmono_mode && ac->oc[0].status == OC_NONE) {
                 layout_map_tags = 2;
                 layout_map[0][0] = layout_map[1][0] = TYPE_SCE;
                 layout_map[0][2] = layout_map[1][2] = AAC_CHANNEL_FRONT;
                 layout_map[0][1] = 0;
                 layout_map[1][1] = 1;
                 if (output_configure(ac, layout_map, layout_map_tags,
-                                     OC_TRIAL_FRAME))
+                                     OC_TRIAL_FRAME, 0))
                     return -7;
             }
-#endif
         }
         ac->oc[1].m4ac.sample_rate     = hdr_info.sample_rate;
         ac->oc[1].m4ac.sampling_index  = hdr_info.sampling_index;
@@ -2472,7 +2485,8 @@
     int err, elem_id;
     int samples = 0, multiplier, audio_found = 0, pce_found = 0;
     int is_dmono, sce_count = 0;
-    float *tmp = NULL;
+
+    ac->frame = data;
 
     if (show_bits(gb, 12) == 0xfff) {
         if (parse_adts_frame_header(ac, gb) < 0) {
@@ -2545,7 +2559,6 @@
             if (pce_found) {
                 av_log(avctx, AV_LOG_ERROR,
                        "Not evaluating a further program_config_element as this construct is dubious at best.\n");
-                pop_output_configuration(ac);
             } else {
                 err = output_configure(ac, layout_map, tags, OC_TRIAL_PCE, 1);
                 if (!err)
@@ -2590,34 +2603,21 @@
 
     multiplier = (ac->oc[1].m4ac.sbr == 1) ? ac->oc[1].m4ac.ext_sample_rate > ac->oc[1].m4ac.sample_rate : 0;
     samples <<= multiplier;
-#if 0
     /* for dual-mono audio (SCE + SCE) */
-    is_dmono = ac->enable_jp_dmono && sce_count == 2 &&
+    is_dmono = ac->dmono_mode && sce_count == 2 &&
                ac->oc[1].channel_layout == (AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT);
 
-    if (is_dmono) {
-        if (ac->dmono_mode == 0) {
-            tmp = ac->output_data[1];
-            ac->output_data[1] = ac->output_data[0];
-        } else if (ac->dmono_mode == 1) {
-            tmp = ac->output_data[0];
-            ac->output_data[0] = ac->output_data[1];
-        }
-    }
-#endif
-    if (samples) {
-        ac->frame.nb_samples = samples;
-        *(AVFrame *)data = ac->frame;
-    }
+    if (samples)
+        ac->frame->nb_samples = samples;
     *got_frame_ptr = !!samples;
-#if 0
+
     if (is_dmono) {
-        if (ac->dmono_mode == 0)
-            ac->output_data[1] = tmp;
-        else if (ac->dmono_mode == 1)
-            ac->output_data[0] = tmp;
+        if (ac->dmono_mode == 1)
+            ((AVFrame *)data)->data[1] =((AVFrame *)data)->data[0];
+        else if (ac->dmono_mode == 2)
+            ((AVFrame *)data)->data[0] =((AVFrame *)data)->data[1];
     }
-#endif
+
     if (ac->oc[1].status && audio_found) {
         avctx->sample_rate = ac->oc[1].m4ac.sample_rate << multiplier;
         avctx->frame_size = samples;
@@ -2626,7 +2626,7 @@
 
     if (multiplier) {
         int side_size;
-        uint32_t *side = av_packet_get_side_data(avpkt, AV_PKT_DATA_SKIP_SAMPLES, &side_size);
+        const uint8_t *side = av_packet_get_side_data(avpkt, AV_PKT_DATA_SKIP_SAMPLES, &side_size);
         if (side && side_size>=4)
             AV_WL32(side, 2*AV_RL32(side));
     }
@@ -2672,10 +2672,14 @@
         }
     }
 
-    ac->enable_jp_dmono = !!jp_dualmono;
     ac->dmono_mode = 0;
     if (jp_dualmono && jp_dualmono_size > 0)
-        ac->dmono_mode = *jp_dualmono;
+        ac->dmono_mode =  1 + *jp_dualmono;
+    if (ac->force_dmono_mode >= 0)
+        ac->dmono_mode = ac->force_dmono_mode;
+
+    if (INT_MAX / 8 <= buf_size)
+        return AVERROR_INVALIDDATA;
 
     init_get_bits(&gb, buf, buf_size * 8);
 
@@ -2766,7 +2770,7 @@
         if(latmctx->initialized) {
             av_log(avctx, AV_LOG_INFO, "audio config changed\n");
         } else {
-            av_log(avctx, AV_LOG_INFO, "initializing latmctx\n");
+            av_log(avctx, AV_LOG_DEBUG, "initializing latmctx\n");
         }
         latmctx->initialized = 0;
 
@@ -2927,7 +2931,8 @@
     int                 muxlength, err;
     GetBitContext       gb;
 
-    init_get_bits(&gb, avpkt->data, avpkt->size * 8);
+    if ((err = init_get_bits8(&gb, avpkt->data, avpkt->size)) < 0)
+        return err;
 
     // check for LOAS sync word
     if (get_bits(&gb, 11) != LOAS_SYNC_WORD)
@@ -2981,6 +2986,40 @@
     return ret;
 }
 
+static void aacdec_init(AACContext *c)
+{
+    c->imdct_and_windowing                      = imdct_and_windowing;
+    c->apply_ltp                                = apply_ltp;
+    c->apply_tns                                = apply_tns;
+    c->windowing_and_mdct_ltp                   = windowing_and_mdct_ltp;
+    c->update_ltp                               = update_ltp;
+
+    if(ARCH_MIPS)
+        ff_aacdec_init_mips(c);
+}
+/**
+ * AVOptions for Japanese DTV specific extensions (ADTS only)
+ */
+#define AACDEC_FLAGS AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM
+static const AVOption options[] = {
+    {"dual_mono_mode", "Select the channel to decode for dual mono",
+     offsetof(AACContext, force_dmono_mode), AV_OPT_TYPE_INT, {.i64=-1}, -1, 2,
+     AACDEC_FLAGS, "dual_mono_mode"},
+
+    {"auto", "autoselection",            0, AV_OPT_TYPE_CONST, {.i64=-1}, INT_MIN, INT_MAX, AACDEC_FLAGS, "dual_mono_mode"},
+    {"main", "Select Main/Left channel", 0, AV_OPT_TYPE_CONST, {.i64= 1}, INT_MIN, INT_MAX, AACDEC_FLAGS, "dual_mono_mode"},
+    {"sub" , "Select Sub/Right channel", 0, AV_OPT_TYPE_CONST, {.i64= 2}, INT_MIN, INT_MAX, AACDEC_FLAGS, "dual_mono_mode"},
+    {"both", "Select both channels",     0, AV_OPT_TYPE_CONST, {.i64= 0}, INT_MIN, INT_MAX, AACDEC_FLAGS, "dual_mono_mode"},
+
+    {NULL},
+};
+
+static const AVClass aac_decoder_class = {
+    .class_name = "AAC decoder",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
 
 AVCodec ff_aac_decoder = {
     .name            = "aac",
@@ -2997,6 +3036,7 @@
     .capabilities    = CODEC_CAP_CHANNEL_CONF | CODEC_CAP_DR1,
     .channel_layouts = aac_channel_layout,
     .flush = flush,
+    .priv_class      = &aac_decoder_class,
 };
 
 /*
diff --git a/libavcodec/aacenc.c b/libavcodec/aacenc.c
index 2c40ec9..5711d01 100644
--- a/libavcodec/aacenc.c
+++ b/libavcodec/aacenc.c
@@ -34,7 +34,6 @@
 #include "libavutil/opt.h"
 #include "avcodec.h"
 #include "put_bits.h"
-#include "dsputil.h"
 #include "internal.h"
 #include "mpeg4audio.h"
 #include "kbdwin.h"
@@ -183,7 +182,7 @@
 }
 
 #define WINDOW_FUNC(type) \
-static void apply_ ##type ##_window(DSPContext *dsp, AVFloatDSPContext *fdsp, \
+static void apply_ ##type ##_window(AVFloatDSPContext *fdsp, \
                                     SingleChannelElement *sce, \
                                     const float *audio)
 
@@ -193,8 +192,8 @@
     const float *pwindow = sce->ics.use_kb_window[1] ? ff_aac_kbd_long_1024 : ff_sine_1024;
     float *out = sce->ret_buf;
 
-    fdsp->vector_fmul       (out,        audio,        lwindow, 1024);
-    dsp->vector_fmul_reverse(out + 1024, audio + 1024, pwindow, 1024);
+    fdsp->vector_fmul        (out,        audio,        lwindow, 1024);
+    fdsp->vector_fmul_reverse(out + 1024, audio + 1024, pwindow, 1024);
 }
 
 WINDOW_FUNC(long_start)
@@ -205,7 +204,7 @@
 
     fdsp->vector_fmul(out, audio, lwindow, 1024);
     memcpy(out + 1024, audio + 1024, sizeof(out[0]) * 448);
-    dsp->vector_fmul_reverse(out + 1024 + 448, audio + 1024 + 448, swindow, 128);
+    fdsp->vector_fmul_reverse(out + 1024 + 448, audio + 1024 + 448, swindow, 128);
     memset(out + 1024 + 576, 0, sizeof(out[0]) * 448);
 }
 
@@ -218,7 +217,7 @@
     memset(out, 0, sizeof(out[0]) * 448);
     fdsp->vector_fmul(out + 448, audio + 448, swindow, 128);
     memcpy(out + 576, audio + 576, sizeof(out[0]) * 448);
-    dsp->vector_fmul_reverse(out + 1024, audio + 1024, lwindow, 1024);
+    fdsp->vector_fmul_reverse(out + 1024, audio + 1024, lwindow, 1024);
 }
 
 WINDOW_FUNC(eight_short)
@@ -230,15 +229,15 @@
     int w;
 
     for (w = 0; w < 8; w++) {
-        fdsp->vector_fmul       (out, in, w ? pwindow : swindow, 128);
+        fdsp->vector_fmul        (out, in, w ? pwindow : swindow, 128);
         out += 128;
         in  += 128;
-        dsp->vector_fmul_reverse(out, in, swindow, 128);
+        fdsp->vector_fmul_reverse(out, in, swindow, 128);
         out += 128;
     }
 }
 
-static void (*const apply_window[4])(DSPContext *dsp, AVFloatDSPContext *fdsp,
+static void (*const apply_window[4])(AVFloatDSPContext *fdsp,
                                      SingleChannelElement *sce,
                                      const float *audio) = {
     [ONLY_LONG_SEQUENCE]   = apply_only_long_window,
@@ -253,7 +252,7 @@
     int i;
     float *output = sce->ret_buf;
 
-    apply_window[sce->ics.window_sequence[0]](&s->dsp, &s->fdsp, sce, audio);
+    apply_window[sce->ics.window_sequence[0]](&s->fdsp, sce, audio);
 
     if (sce->ics.window_sequence[0] != EIGHT_SHORT_SEQUENCE)
         s->mdct1024.mdct_calc(&s->mdct1024, sce->coeffs, output);
@@ -517,7 +516,7 @@
 
     /* add current frame to queue */
     if (frame) {
-        if ((ret = ff_af_queue_add(&s->afq, frame) < 0))
+        if ((ret = ff_af_queue_add(&s->afq, frame)) < 0)
             return ret;
     }
 
@@ -692,7 +691,6 @@
 {
     int ret = 0;
 
-    ff_dsputil_init(&s->dsp, avctx);
     avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
 
     // window init
diff --git a/libavcodec/aacenc.h b/libavcodec/aacenc.h
index fbc3da8..386c72f 100644
--- a/libavcodec/aacenc.h
+++ b/libavcodec/aacenc.h
@@ -25,7 +25,6 @@
 #include "libavutil/float_dsp.h"
 #include "avcodec.h"
 #include "put_bits.h"
-#include "dsputil.h"
 
 #include "aac.h"
 #include "audio_frame_queue.h"
@@ -61,7 +60,6 @@
     PutBitContext pb;
     FFTContext mdct1024;                         ///< long (1024 samples) frame transform context
     FFTContext mdct128;                          ///< short (128 samples) frame transform context
-    DSPContext  dsp;
     AVFloatDSPContext fdsp;
     float *planar_samples[6];                    ///< saved preprocessed input
 
diff --git a/libavcodec/aacps.c b/libavcodec/aacps.c
index 25ed1d0..b82001e 100644
--- a/libavcodec/aacps.c
+++ b/libavcodec/aacps.c
@@ -21,13 +21,13 @@
 
 #include <stdint.h>
 #include "libavutil/common.h"
+#include "libavutil/internal.h"
 #include "libavutil/mathematics.h"
 #include "avcodec.h"
 #include "get_bits.h"
 #include "aacps.h"
 #include "aacps_tablegen.h"
 #include "aacpsdata.c"
-#include "dsputil.h"
 
 #define PS_BASELINE 0  ///< Operate in Baseline PS mode
                        ///< Baseline implies 10 or 20 stereo bands,
diff --git a/libavcodec/aacpsdsp.c b/libavcodec/aacpsdsp.c
index e90c50b..9526d3a 100644
--- a/libavcodec/aacpsdsp.c
+++ b/libavcodec/aacpsdsp.c
@@ -211,4 +211,6 @@
 
     if (ARCH_ARM)
         ff_psdsp_init_arm(s);
+    if (ARCH_MIPS)
+        ff_psdsp_init_mips(s);
 }
diff --git a/libavcodec/aacpsdsp.h b/libavcodec/aacpsdsp.h
index 93737d2..df01e0b 100644
--- a/libavcodec/aacpsdsp.h
+++ b/libavcodec/aacpsdsp.h
@@ -49,5 +49,6 @@
 
 void ff_psdsp_init(PSDSPContext *s);
 void ff_psdsp_init_arm(PSDSPContext *s);
+void ff_psdsp_init_mips(PSDSPContext *s);
 
 #endif /* LIBAVCODEC_AACPSDSP_H */
diff --git a/libavcodec/aacpsy.c b/libavcodec/aacpsy.c
index fa562b3..d77b3de 100644
--- a/libavcodec/aacpsy.c
+++ b/libavcodec/aacpsy.c
@@ -597,7 +597,7 @@
     for (w = 0; w < wi->num_windows*16; w += 16) {
         AacPsyBand *bands = &pch->band[w];
 
-        //5.4.2.3 "Spreading" & 5.4.3 "Spreaded Energy Calculation"
+        /* 5.4.2.3 "Spreading" & 5.4.3 "Spread Energy Calculation" */
         spread_en[0] = bands[0].energy;
         for (g = 1; g < num_bands; g++) {
             bands[g].thr   = FFMAX(bands[g].thr,    bands[g-1].thr * coeffs[g].spread_hi[0]);
@@ -617,7 +617,7 @@
                 band->thr = FFMAX(PSY_3GPP_RPEMIN*band->thr, FFMIN(band->thr,
                                   PSY_3GPP_RPELEV*pch->prev_band[w+g].thr_quiet));
 
-            /* 5.6.1.3.1 "Prepatory steps of the perceptual entropy calculation" */
+            /* 5.6.1.3.1 "Preparatory steps of the perceptual entropy calculation" */
             pe += calc_pe_3gpp(band);
             a  += band->pe_const;
             active_lines += band->active_lines;
diff --git a/libavcodec/aacsbr.c b/libavcodec/aacsbr.c
index e46b4a4..1820f80 100644
--- a/libavcodec/aacsbr.c
+++ b/libavcodec/aacsbr.c
@@ -33,6 +33,7 @@
 #include "fft.h"
 #include "aacps.h"
 #include "sbrdsp.h"
+#include "libavutil/internal.h"
 #include "libavutil/libm.h"
 #include "libavutil/avassert.h"
 
@@ -43,6 +44,10 @@
 #define ENVELOPE_ADJUSTMENT_OFFSET 2
 #define NOISE_FLOOR_OFFSET 6.0f
 
+#if ARCH_MIPS
+#include "mips/aacsbr_mips.h"
+#endif /* ARCH_MIPS */
+
 /**
  * SBR VLC tables
  */
@@ -76,7 +81,6 @@
 static VLC vlc_sbr[10];
 static const int8_t vlc_sbr_lav[10] =
     { 60, 60, 24, 24, 31, 31, 12, 12, 31, 12 };
-static const DECLARE_ALIGNED(16, float, zero64)[64];
 
 #define SBR_INIT_VLC_STATIC(num, size) \
     INIT_VLC_STATIC(&vlc_sbr[num], 9, sbr_tmp[num].table_size / sbr_tmp[num].elem_size,     \
@@ -87,6 +91,8 @@
 #define SBR_VLC_ROW(name) \
     { name ## _codes, name ## _bits, sizeof(name ## _codes), sizeof(name ## _codes[0]) }
 
+static void aacsbr_func_ptr_init(AACSBRContext *c);
+
 av_cold void ff_aac_sbr_init(void)
 {
     int n;
@@ -155,6 +161,7 @@
     ff_mdct_init(&sbr->mdct_ana, 7, 1, -2.0 * 32768.0);
     ff_ps_ctx_init(&sbr->ps);
     ff_sbrdsp_init(&sbr->dsp);
+    aacsbr_func_ptr_init(&sbr->c);
 }
 
 av_cold void ff_aac_sbr_ctx_close(SpectralBandReplication *sbr)
@@ -392,6 +399,8 @@
         max_qmf_subbands = 35;
     } else if (sbr->sample_rate >= 48000)
         max_qmf_subbands = 32;
+    else
+        av_assert0(0);
 
     if (sbr->k[2] - sbr->k[0] > max_qmf_subbands) {
         av_log(ac->avctx, AV_LOG_ERROR,
@@ -1157,7 +1166,8 @@
  * @param   x       pointer to the beginning of the first sample window
  * @param   W       array of complex-valued samples split into subbands
  */
-static void sbr_qmf_analysis(DSPContext *dsp, FFTContext *mdct,
+#ifndef sbr_qmf_analysis
+static void sbr_qmf_analysis(AVFloatDSPContext *dsp, FFTContext *mdct,
                              SBRDSPContext *sbrdsp, const float *in, float *x,
                              float z[320], float W[2][32][32][2], int buf_idx)
 {
@@ -1174,13 +1184,15 @@
         x += 32;
     }
 }
+#endif
 
 /**
  * Synthesis QMF Bank (14496-3 sp04 p206) and Downsampled Synthesis QMF Bank
  * (14496-3 sp04 p206)
  */
-static void sbr_qmf_synthesis(DSPContext *dsp, FFTContext *mdct,
-                              SBRDSPContext *sbrdsp,
+#ifndef sbr_qmf_synthesis
+static void sbr_qmf_synthesis(FFTContext *mdct,
+                              SBRDSPContext *sbrdsp, AVFloatDSPContext *dsp,
                               float *out, float X[2][38][64],
                               float mdct_buf[2][64],
                               float *v0, int *v_off, const unsigned int div)
@@ -1211,7 +1223,7 @@
             mdct->imdct_half(mdct, mdct_buf[1], X[1][i]);
             sbrdsp->qmf_deint_bfly(v, mdct_buf[1], mdct_buf[0]);
         }
-        dsp->vector_fmul_add(out, v                , sbr_qmf_window               , zero64, 64 >> div);
+        dsp->vector_fmul    (out, v                , sbr_qmf_window                       , 64 >> div);
         dsp->vector_fmul_add(out, v + ( 192 >> div), sbr_qmf_window + ( 64 >> div), out   , 64 >> div);
         dsp->vector_fmul_add(out, v + ( 256 >> div), sbr_qmf_window + (128 >> div), out   , 64 >> div);
         dsp->vector_fmul_add(out, v + ( 448 >> div), sbr_qmf_window + (192 >> div), out   , 64 >> div);
@@ -1224,6 +1236,7 @@
         out += 64 >> div;
     }
 }
+#endif
 
 /** High Frequency Generation (14496-3 sp04 p214+) and Inverse Filtering
  * (14496-3 sp04 p214)
@@ -1669,13 +1682,13 @@
     }
     for (ch = 0; ch < nch; ch++) {
         /* decode channel */
-        sbr_qmf_analysis(&ac->dsp, &sbr->mdct_ana, &sbr->dsp, ch ? R : L, sbr->data[ch].analysis_filterbank_samples,
+        sbr_qmf_analysis(&ac->fdsp, &sbr->mdct_ana, &sbr->dsp, ch ? R : L, sbr->data[ch].analysis_filterbank_samples,
                          (float*)sbr->qmf_filter_scratch,
                          sbr->data[ch].W, sbr->data[ch].Ypos);
-        sbr_lf_gen(ac, sbr, sbr->X_low, sbr->data[ch].W, sbr->data[ch].Ypos);
+        sbr->c.sbr_lf_gen(ac, sbr, sbr->X_low, sbr->data[ch].W, sbr->data[ch].Ypos);
         sbr->data[ch].Ypos ^= 1;
         if (sbr->start) {
-            sbr_hf_inverse_filter(&sbr->dsp, sbr->alpha0, sbr->alpha1, sbr->X_low, sbr->k[0]);
+            sbr->c.sbr_hf_inverse_filter(&sbr->dsp, sbr->alpha0, sbr->alpha1, sbr->X_low, sbr->k[0]);
             sbr_chirp(sbr, &sbr->data[ch]);
             sbr_hf_gen(ac, sbr, sbr->X_high, sbr->X_low, sbr->alpha0, sbr->alpha1,
                        sbr->data[ch].bw_array, sbr->data[ch].t_env,
@@ -1686,14 +1699,14 @@
             if (!err) {
                 sbr_env_estimate(sbr->e_curr, sbr->X_high, sbr, &sbr->data[ch]);
                 sbr_gain_calc(ac, sbr, &sbr->data[ch], sbr->data[ch].e_a);
-                sbr_hf_assemble(sbr->data[ch].Y[sbr->data[ch].Ypos],
+                sbr->c.sbr_hf_assemble(sbr->data[ch].Y[sbr->data[ch].Ypos],
                                 sbr->X_high, sbr, &sbr->data[ch],
                                 sbr->data[ch].e_a);
             }
         }
 
         /* synthesis */
-        sbr_x_gen(sbr, sbr->X[ch],
+        sbr->c.sbr_x_gen(sbr, sbr->X[ch],
                   sbr->data[ch].Y[1-sbr->data[ch].Ypos],
                   sbr->data[ch].Y[  sbr->data[ch].Ypos],
                   sbr->X_low, ch);
@@ -1708,13 +1721,26 @@
         nch = 2;
     }
 
-    sbr_qmf_synthesis(&ac->dsp, &sbr->mdct, &sbr->dsp, L, sbr->X[0], sbr->qmf_filter_scratch,
+    sbr_qmf_synthesis(&sbr->mdct, &sbr->dsp, &ac->fdsp,
+                      L, sbr->X[0], sbr->qmf_filter_scratch,
                       sbr->data[0].synthesis_filterbank_samples,
                       &sbr->data[0].synthesis_filterbank_samples_offset,
                       downsampled);
     if (nch == 2)
-        sbr_qmf_synthesis(&ac->dsp, &sbr->mdct, &sbr->dsp, R, sbr->X[1], sbr->qmf_filter_scratch,
+        sbr_qmf_synthesis(&sbr->mdct, &sbr->dsp, &ac->fdsp,
+                          R, sbr->X[1], sbr->qmf_filter_scratch,
                           sbr->data[1].synthesis_filterbank_samples,
                           &sbr->data[1].synthesis_filterbank_samples_offset,
                           downsampled);
 }
+
+static void aacsbr_func_ptr_init(AACSBRContext *c)
+{
+    c->sbr_lf_gen            = sbr_lf_gen;
+    c->sbr_hf_assemble       = sbr_hf_assemble;
+    c->sbr_x_gen             = sbr_x_gen;
+    c->sbr_hf_inverse_filter = sbr_hf_inverse_filter;
+
+    if(ARCH_MIPS)
+        ff_aacsbr_func_ptr_init_mips(c);
+}
diff --git a/libavcodec/aacsbr.h b/libavcodec/aacsbr.h
index d028498..f5e33ab 100644
--- a/libavcodec/aacsbr.h
+++ b/libavcodec/aacsbr.h
@@ -34,11 +34,11 @@
 #include "sbr.h"
 
 /** Initialize SBR. */
-av_cold void ff_aac_sbr_init(void);
+void ff_aac_sbr_init(void);
 /** Initialize one SBR context. */
-av_cold void ff_aac_sbr_ctx_init(AACContext *ac, SpectralBandReplication *sbr);
+void ff_aac_sbr_ctx_init(AACContext *ac, SpectralBandReplication *sbr);
 /** Close one SBR context. */
-av_cold void ff_aac_sbr_ctx_close(SpectralBandReplication *sbr);
+void ff_aac_sbr_ctx_close(SpectralBandReplication *sbr);
 /** Decode one SBR element. */
 int ff_decode_sbr_extension(AACContext *ac, SpectralBandReplication *sbr,
                             GetBitContext *gb, int crc, int cnt, int id_aac);
@@ -46,4 +46,6 @@
 void ff_sbr_apply(AACContext *ac, SpectralBandReplication *sbr, int id_aac,
                   float* L, float *R);
 
+void ff_aacsbr_func_ptr_init_mips(AACSBRContext *c);
+
 #endif /* AVCODEC_AACSBR_H */
diff --git a/libavcodec/aasc.c b/libavcodec/aasc.c
index 6c9fd4e..308edd0 100644
--- a/libavcodec/aasc.c
+++ b/libavcodec/aasc.c
@@ -29,7 +29,6 @@
 #include <string.h>
 
 #include "avcodec.h"
-#include "dsputil.h"
 #include "msrledec.h"
 
 typedef struct AascContext {
@@ -60,7 +59,7 @@
         }
         break;
     case 16:
-        avctx->pix_fmt = AV_PIX_FMT_RGB555;
+        avctx->pix_fmt = AV_PIX_FMT_RGB555LE;
         break;
     case 24:
         avctx->pix_fmt = AV_PIX_FMT_BGR24;
@@ -75,13 +74,13 @@
 }
 
 static int aasc_decode_frame(AVCodecContext *avctx,
-                              void *data, int *data_size,
+                              void *data, int *got_frame,
                               AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
-    AascContext *s = avctx->priv_data;
-    int compr, i, stride, psize;
+    int buf_size       = avpkt->size;
+    AascContext *s     = avctx->priv_data;
+    int compr, i, stride, psize, ret;
 
     if (buf_size < 4) {
         av_log(avctx, AV_LOG_ERROR, "frame too short\n");
@@ -90,13 +89,13 @@
 
     s->frame.reference = 3;
     s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if (avctx->reget_buffer(avctx, &s->frame)) {
+    if ((ret = avctx->reget_buffer(avctx, &s->frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
-    compr = AV_RL32(buf);
-    buf += 4;
+    compr     = AV_RL32(buf);
+    buf      += 4;
     buf_size -= 4;
     psize = avctx->bits_per_coded_sample / 8;
     switch (avctx->codec_tag) {
@@ -105,11 +104,11 @@
         ff_msrle_decode(avctx, (AVPicture*)&s->frame, 8, &s->gb);
         break;
     case MKTAG('A', 'A', 'S', 'C'):
-    switch(compr){
+    switch (compr) {
     case 0:
         stride = (avctx->width * psize + psize) & ~psize;
-        for(i = avctx->height - 1; i >= 0; i--){
-            if(avctx->width * psize > buf_size){
+        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;
             }
@@ -124,7 +123,7 @@
         break;
     default:
         av_log(avctx, AV_LOG_ERROR, "Unknown compression type %d\n", compr);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
         break;
     default:
@@ -135,7 +134,7 @@
     if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
         memcpy(s->frame.data[1], s->palette, s->palette_size);
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*)data = s->frame;
 
     /* report that the buffer was completely consumed */
diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c
index 7fb380c..5dde004 100644
--- a/libavcodec/ac3dec.c
+++ b/libavcodec/ac3dec.c
@@ -160,6 +160,8 @@
 static av_cold int ac3_decode_init(AVCodecContext *avctx)
 {
     AC3DecodeContext *s = avctx->priv_data;
+    int i;
+
     s->avctx = avctx;
 
     ff_ac3_common_init();
@@ -168,18 +170,12 @@
     ff_mdct_init(&s->imdct_512, 9, 1, 1.0);
     ff_kbd_window_init(s->window, 5.0, 256);
     ff_dsputil_init(&s->dsp, avctx);
+    avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
     ff_ac3dsp_init(&s->ac3dsp, avctx->flags & CODEC_FLAG_BITEXACT);
     ff_fmt_convert_init(&s->fmt_conv, avctx);
     av_lfg_init(&s->dith_state, 0);
 
-    /* set scale value for float to int16 conversion */
-    if (avctx->request_sample_fmt == AV_SAMPLE_FMT_FLT) {
-        s->mul_bias = 1.0f;
-        avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
-    } else {
-        s->mul_bias = 32767.0f;
-        avctx->sample_fmt = AV_SAMPLE_FMT_S16;
-    }
+    avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
 
     /* allow downmixing to stereo or mono */
     if (avctx->channels > 0 && avctx->request_channels > 0 &&
@@ -189,8 +185,10 @@
     }
     s->downmixed = 1;
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
+    for (i = 0; i < AC3_MAX_CHANNELS; i++) {
+        s->xcfptr[i] = s->transform_coeffs[i];
+        s->dlyptr[i] = s->delay[i];
+    }
 
     return 0;
 }
@@ -441,8 +439,9 @@
         int mantissa;
         switch (bap) {
         case 0:
+            /* random noise with approximate range of -0.707 to 0.707 */
             if (dither)
-                mantissa = (av_lfg_get(&s->dith_state) & 0x7FFFFF) - 0x400000;
+                mantissa = (((av_lfg_get(&s->dith_state)>>8)*181)>>8) - 5931008;
             else
                 mantissa = 0;
             break;
@@ -546,7 +545,7 @@
     for (ch = 1; ch <= s->channels; ch++) {
         /* transform coefficients for full-bandwidth channel */
         decode_transform_coeffs_ch(s, blk, ch, &m);
-        /* tranform coefficients for coupling channel come right after the
+        /* transform coefficients for coupling channel come right after the
            coefficients for the first coupled channel*/
         if (s->channel_in_cpl[ch])  {
             if (!got_cplchan) {
@@ -606,15 +605,15 @@
             for (i = 0; i < 128; i++)
                 x[i] = s->transform_coeffs[ch][2 * i];
             s->imdct_256.imdct_half(&s->imdct_256, s->tmp_output, x);
-            s->dsp.vector_fmul_window(s->output[ch - 1], s->delay[ch - 1],
-                                      s->tmp_output, s->window, 128);
+            s->fdsp.vector_fmul_window(s->outptr[ch - 1], s->delay[ch - 1],
+                                       s->tmp_output, s->window, 128);
             for (i = 0; i < 128; i++)
                 x[i] = s->transform_coeffs[ch][2 * i + 1];
             s->imdct_256.imdct_half(&s->imdct_256, s->delay[ch - 1], x);
         } else {
             s->imdct_512.imdct_half(&s->imdct_512, s->tmp_output, s->transform_coeffs[ch]);
-            s->dsp.vector_fmul_window(s->output[ch - 1], s->delay[ch - 1],
-                                      s->tmp_output, s->window, 128);
+            s->fdsp.vector_fmul_window(s->outptr[ch - 1], s->delay[ch - 1],
+                                       s->tmp_output, s->window, 128);
             memcpy(s->delay[ch - 1], s->tmp_output + 128, 128 * sizeof(float));
         }
     }
@@ -1206,7 +1205,7 @@
 
     /* apply scaling to coefficients (headroom, dynrng) */
     for (ch = 1; ch <= s->channels; ch++) {
-        float gain = s->mul_bias / 4194304.0f;
+        float gain = 1.0 / 4194304.0f;
         if (s->channel_mode == AC3_CHMODE_DUALMONO) {
             gain *= s->dynamic_range[2 - ch];
         } else {
@@ -1238,18 +1237,18 @@
         do_imdct(s, s->channels);
 
         if (downmix_output) {
-            s->ac3dsp.downmix(s->output, s->downmix_coeffs,
+            s->ac3dsp.downmix(s->outptr, s->downmix_coeffs,
                               s->out_channels, s->fbw_channels, 256);
         }
     } else {
         if (downmix_output) {
-            s->ac3dsp.downmix(s->transform_coeffs + 1, s->downmix_coeffs,
+            s->ac3dsp.downmix(s->xcfptr + 1, s->downmix_coeffs,
                               s->out_channels, s->fbw_channels, 256);
         }
 
         if (downmix_output && !s->downmixed) {
             s->downmixed = 1;
-            s->ac3dsp.downmix(s->delay, s->downmix_coeffs, s->out_channels,
+            s->ac3dsp.downmix(s->dlyptr, s->downmix_coeffs, s->out_channels,
                               s->fbw_channels, 128);
         }
 
@@ -1265,11 +1264,10 @@
 static int ac3_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;
     AC3DecodeContext *s = avctx->priv_data;
-    float   *out_samples_flt;
-    int16_t *out_samples_s16;
     int blk, ch, err, ret;
     const uint8_t *channel_map;
     const float *output[AC3_MAX_CHANNELS];
@@ -1338,8 +1336,10 @@
     if (!err) {
         avctx->sample_rate = s->sample_rate;
         avctx->bit_rate    = s->bit_rate;
+    }
 
-        /* channel config */
+    /* channel config */
+    if (!err || (s->channels && s->out_channels != s->channels)) {
         s->out_channels = s->channels;
         s->output_mode  = s->channel_mode;
         if (s->lfe_on)
@@ -1362,54 +1362,57 @@
                 s->fbw_channels == s->out_channels)) {
             set_downmix_coeffs(s);
         }
-    } else if (!s->out_channels) {
-        s->out_channels = avctx->channels;
-        if (s->out_channels < s->channels)
-            s->output_mode  = s->out_channels == 1 ? AC3_CHMODE_MONO : AC3_CHMODE_STEREO;
-    }
-    if (avctx->channels != s->out_channels) {
-        av_log(avctx, AV_LOG_ERROR, "channel number mismatching on damaged frame\n");
+    } else if (!s->channels) {
+        av_log(avctx, AV_LOG_ERROR, "unable to determine channel mode\n");
         return AVERROR_INVALIDDATA;
     }
+    avctx->channels = s->out_channels;
+
     /* set audio service type based on bitstream mode for AC-3 */
     avctx->audio_service_type = s->bitstream_mode;
     if (s->bitstream_mode == 0x7 && s->channels > 1)
         avctx->audio_service_type = AV_AUDIO_SERVICE_TYPE_KARAOKE;
 
     /* get output buffer */
-    avctx->channels = s->out_channels;
-    s->frame.nb_samples = s->num_blocks * 256;
-    if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = s->num_blocks * 256;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    out_samples_flt = (float   *)s->frame.data[0];
-    out_samples_s16 = (int16_t *)s->frame.data[0];
 
     /* decode the audio blocks */
     channel_map = ff_ac3_dec_channel_map[s->output_mode & ~AC3_OUTPUT_LFEON][s->lfe_on];
-    for (ch = 0; ch < s->out_channels; ch++)
-        output[ch] = s->output[channel_map[ch]];
+    for (ch = 0; ch < AC3_MAX_CHANNELS; ch++) {
+        output[ch] = s->output[ch];
+        s->outptr[ch] = s->output[ch];
+    }
+    for (ch = 0; ch < s->channels; ch++) {
+        if (ch < s->out_channels)
+            s->outptr[channel_map[ch]] = (float *)frame->data[ch];
+    }
     for (blk = 0; blk < s->num_blocks; blk++) {
         if (!err && decode_audio_block(s, blk)) {
             av_log(avctx, AV_LOG_ERROR, "error decoding the audio block\n");
             err = 1;
         }
-        if (avctx->sample_fmt == AV_SAMPLE_FMT_FLT) {
-            s->fmt_conv.float_interleave(out_samples_flt, output, 256,
-                                         s->out_channels);
-            out_samples_flt += 256 * s->out_channels;
-        } else {
-            s->fmt_conv.float_to_int16_interleave(out_samples_s16, output, 256,
-                                                  s->out_channels);
-            out_samples_s16 += 256 * s->out_channels;
+        if (err)
+            for (ch = 0; ch < s->out_channels; ch++)
+                memcpy(((float*)frame->data[ch]) + AC3_BLOCK_SIZE*blk, output[ch], 1024);
+        for (ch = 0; ch < s->out_channels; ch++)
+            output[ch] = s->outptr[channel_map[ch]];
+        for (ch = 0; ch < s->out_channels; ch++) {
+            if (!ch || channel_map[ch])
+                s->outptr[channel_map[ch]] += AC3_BLOCK_SIZE;
         }
     }
 
-    s->frame.decode_error_flags = err ? FF_DECODE_ERROR_INVALID_BITSTREAM : 0;
+    frame->decode_error_flags = err ? FF_DECODE_ERROR_INVALID_BITSTREAM : 0;
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
+    /* keep last block for error concealment in next frame */
+    for (ch = 0; ch < s->out_channels; ch++)
+        memcpy(s->output[ch], output[ch], 1024);
+
+    *got_frame_ptr = 1;
 
     return FFMIN(buf_size, s->frame_size);
 }
@@ -1457,8 +1460,7 @@
     .decode         = ac3_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"),
-    .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLT,
-                                                      AV_SAMPLE_FMT_S16,
+    .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                       AV_SAMPLE_FMT_NONE },
     .priv_class     = &ac3_decoder_class,
 };
@@ -1481,8 +1483,7 @@
     .decode         = ac3_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("ATSC A/52B (AC-3, E-AC-3)"),
-    .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLT,
-                                                      AV_SAMPLE_FMT_S16,
+    .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                       AV_SAMPLE_FMT_NONE },
     .priv_class     = &eac3_decoder_class,
 };
diff --git a/libavcodec/ac3dec.h b/libavcodec/ac3dec.h
index c3a43bf..6c99ef6 100644
--- a/libavcodec/ac3dec.h
+++ b/libavcodec/ac3dec.h
@@ -50,6 +50,7 @@
 #ifndef AVCODEC_AC3DEC_H
 #define AVCODEC_AC3DEC_H
 
+#include "libavutil/float_dsp.h"
 #include "libavutil/lfg.h"
 #include "ac3.h"
 #include "ac3dsp.h"
@@ -68,7 +69,6 @@
 typedef struct AC3DecodeContext {
     AVClass        *class;                  ///< class for AVOptions
     AVCodecContext *avctx;                  ///< parent context
-    AVFrame frame;                          ///< AVFrame for decoded output
     GetBitContext gbc;                      ///< bitstream reader
 
 ///@name Bit stream information
@@ -199,11 +199,15 @@
 
 ///@name Optimization
     DSPContext dsp;                         ///< for optimization
+    AVFloatDSPContext fdsp;
     AC3DSPContext ac3dsp;
     FmtConvertContext fmt_conv;             ///< optimized conversion functions
-    float mul_bias;                         ///< scaling for float_to_int16 conversion
 ///@}
 
+    float *outptr[AC3_MAX_CHANNELS];
+    float *xcfptr[AC3_MAX_CHANNELS];
+    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(32, float, transform_coeffs)[AC3_MAX_CHANNELS][AC3_MAX_COEFS];   ///< transform coefficients
diff --git a/libavcodec/ac3dsp.c b/libavcodec/ac3dsp.c
index 9277411..6df3a68 100644
--- a/libavcodec/ac3dsp.c
+++ b/libavcodec/ac3dsp.c
@@ -214,7 +214,7 @@
     }
 }
 
-static void ac3_downmix_c(float (*samples)[256], float (*matrix)[2],
+static void ac3_downmix_c(float **samples, float (*matrix)[2],
                           int out_ch, int in_ch, int len)
 {
     int i, j;
diff --git a/libavcodec/ac3dsp.h b/libavcodec/ac3dsp.h
index 7269c57..bafbc89 100644
--- a/libavcodec/ac3dsp.h
+++ b/libavcodec/ac3dsp.h
@@ -132,7 +132,7 @@
     void (*sum_square_butterfly_float)(float sum[4], const float *coef0,
                                        const float *coef1, int len);
 
-    void (*downmix)(float (*samples)[256], float (*matrix)[2], int out_ch,
+    void (*downmix)(float **samples, float (*matrix)[2], int out_ch,
                     int in_ch, int len);
 } AC3DSPContext;
 
diff --git a/libavcodec/ac3enc.c b/libavcodec/ac3enc.c
index 22b6857..16f0cdc 100644
--- a/libavcodec/ac3enc.c
+++ b/libavcodec/ac3enc.c
@@ -34,10 +34,10 @@
 #include "libavutil/avstring.h"
 #include "libavutil/channel_layout.h"
 #include "libavutil/crc.h"
+#include "libavutil/internal.h"
 #include "libavutil/opt.h"
 #include "avcodec.h"
 #include "put_bits.h"
-#include "dsputil.h"
 #include "ac3dsp.h"
 #include "ac3.h"
 #include "fft.h"
@@ -659,7 +659,7 @@
      *   bit allocation parameters do not change between blocks
      *   no delta bit allocation
      *   no skipped data
-     *   no auxilliary data
+     *   no auxiliary data
      *   no E-AC-3 metadata
      */
 
diff --git a/libavcodec/ac3enc_template.c b/libavcodec/ac3enc_template.c
index 904e0bb..fb6aad9 100644
--- a/libavcodec/ac3enc_template.c
+++ b/libavcodec/ac3enc_template.c
@@ -28,6 +28,7 @@
 
 #include <stdint.h>
 
+#include "libavutil/internal.h"
 
 /* prototypes for static functions in ac3enc_fixed.c and ac3enc_float.c */
 
@@ -132,7 +133,7 @@
 #else
     int32_t (*fixed_cpl_coords)[AC3_MAX_CHANNELS][16] = cpl_coords;
 #endif
-    int blk, ch, bnd, i, j;
+    int av_uninit(blk), ch, bnd, i, j;
     CoefSumType energy[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][16] = {{{0}}};
     int cpl_start, num_cpl_coefs;
 
@@ -336,7 +337,7 @@
 {
     int nb_coefs;
     int blk, bnd;
-    AC3Block *block, *block0;
+    AC3Block *block, *block0 = NULL;
 
     if (s->channel_mode != AC3_CHMODE_STEREO)
         return;
diff --git a/libavcodec/acelp_filters.h b/libavcodec/acelp_filters.h
index 56197bc..7a3061b 100644
--- a/libavcodec/acelp_filters.h
+++ b/libavcodec/acelp_filters.h
@@ -65,7 +65,7 @@
  * the coefficients are scaled by 2^15.
  * This array only contains the right half of the filter.
  * This filter is likely identical to the one used in G.729, though this
- * could not be determined from the original comments with certainity.
+ * could not be determined from the original comments with certainty.
  */
 extern const int16_t ff_acelp_interp_filter[61];
 
diff --git a/libavcodec/acelp_pitch_delay.c b/libavcodec/acelp_pitch_delay.c
index 95bcce7..c005c4b 100644
--- a/libavcodec/acelp_pitch_delay.c
+++ b/libavcodec/acelp_pitch_delay.c
@@ -21,10 +21,10 @@
  */
 
 #include "libavutil/common.h"
+#include "libavutil/float_dsp.h"
 #include "libavutil/libm.h"
 #include "libavutil/mathematics.h"
 #include "avcodec.h"
-#include "dsputil.h"
 #include "acelp_pitch_delay.h"
 #include "celp_math.h"
 
@@ -132,7 +132,7 @@
     // Note 10^(0.05 * -10log(average x2)) = 1/sqrt((average x2)).
     float val = fixed_gain_factor *
         exp2f(M_LOG2_10 * 0.05 *
-              (ff_scalarproduct_float_c(pred_table, prediction_error, 4) +
+              (avpriv_scalarproduct_float_c(pred_table, prediction_error, 4) +
                energy_mean)) /
         sqrtf(fixed_mean_energy);
 
diff --git a/libavcodec/acelp_vectors.c b/libavcodec/acelp_vectors.c
index aadacb4..c9d6f87 100644
--- a/libavcodec/acelp_vectors.c
+++ b/libavcodec/acelp_vectors.c
@@ -23,8 +23,8 @@
 #include <inttypes.h>
 
 #include "libavutil/common.h"
+#include "libavutil/float_dsp.h"
 #include "avcodec.h"
-#include "dsputil.h"
 #include "acelp_vectors.h"
 
 const uint8_t ff_fc_2pulses_9bits_track1[16] =
@@ -203,7 +203,7 @@
                               int size, float alpha, float *gain_mem)
 {
     int i;
-    float postfilter_energ = ff_scalarproduct_float_c(in, in, size);
+    float postfilter_energ = avpriv_scalarproduct_float_c(in, in, size);
     float gain_scale_factor = 1.0;
     float mem = *gain_mem;
 
@@ -224,7 +224,7 @@
                                              float sum_of_squares, const int n)
 {
     int i;
-    float scalefactor = ff_scalarproduct_float_c(in, in, n);
+    float scalefactor = avpriv_scalarproduct_float_c(in, in, n);
     if (scalefactor)
         scalefactor = sqrt(sum_of_squares / scalefactor);
     for (i = 0; i < n; i++)
diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c
index fd308a9..02de22c 100644
--- a/libavcodec/adpcm.c
+++ b/libavcodec/adpcm.c
@@ -23,6 +23,7 @@
 #include "bytestream.h"
 #include "adpcm.h"
 #include "adpcm_data.h"
+#include "internal.h"
 
 /**
  * @file
@@ -84,7 +85,6 @@
 /* end of tables */
 
 typedef struct ADPCMDecodeContext {
-    AVFrame frame;
     ADPCMChannelStatus status[6];
     int vqa_version;                /**< VQA version. Used for ADPCM_IMA_WS */
 } ADPCMDecodeContext;
@@ -158,9 +158,6 @@
             avctx->sample_fmt = AV_SAMPLE_FMT_S16;
     }
 
-    avcodec_get_frame_defaults(&c->frame);
-    avctx->coded_frame = &c->frame;
-
     return 0;
 }
 
@@ -618,6 +615,7 @@
 static int adpcm_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;
     ADPCMDecodeContext *c = avctx->priv_data;
@@ -638,20 +636,20 @@
     }
 
     /* get output buffer */
-    c->frame.nb_samples = nb_samples;
-    if ((ret = avctx->get_buffer(avctx, &c->frame)) < 0) {
+    frame->nb_samples = nb_samples;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    samples = (short *)c->frame.data[0];
-    samples_p = (int16_t **)c->frame.extended_data;
+    samples = (short *)frame->data[0];
+    samples_p = (int16_t **)frame->extended_data;
 
     /* use coded_samples when applicable */
     /* it is always <= nb_samples, so the output buffer will be large enough */
     if (coded_samples) {
         if (coded_samples != nb_samples)
             av_log(avctx, AV_LOG_WARNING, "mismatch in coded sample count\n");
-        c->frame.nb_samples = nb_samples = coded_samples;
+        frame->nb_samples = nb_samples = coded_samples;
     }
 
     st = avctx->channels == 2 ? 1 : 0;
@@ -737,7 +735,7 @@
         }
 
         for (i = 0; i < avctx->channels; i++) {
-            samples = (int16_t *)c->frame.data[i];
+            samples = (int16_t *)frame->data[i];
             cs = &c->status[i];
             for (n = nb_samples >> 1; n > 0; n--) {
                 int v = bytestream2_get_byteu(&gb);
@@ -800,7 +798,7 @@
                 return AVERROR_INVALIDDATA;
             }
         }
-        for (n = nb_samples >> (1 - st); n > 0; n--) {
+        for (n = (nb_samples - 1) >> (1 - st); n > 0; n--) {
             int v = bytestream2_get_byteu(&gb);
             *samples++ = adpcm_ima_expand_nibble(&c->status[0 ], v >> 4  , 3);
             *samples++ = adpcm_ima_expand_nibble(&c->status[st], v & 0x0F, 3);
@@ -1134,7 +1132,7 @@
             }
         }
 
-        c->frame.nb_samples = count * 28;
+        frame->nb_samples = count * 28;
         bytestream2_seek(&gb, 0, SEEK_END);
         break;
     }
@@ -1377,8 +1375,7 @@
         return AVERROR_INVALIDDATA;
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = c->frame;
+    *got_frame_ptr = 1;
 
     return bytestream2_tell(&gb);
 }
diff --git a/libavcodec/adpcmenc.c b/libavcodec/adpcmenc.c
index 217d165..8caedf7 100644
--- a/libavcodec/adpcmenc.c
+++ b/libavcodec/adpcmenc.c
@@ -19,7 +19,6 @@
  */
 
 #include "avcodec.h"
-#include "get_bits.h"
 #include "put_bits.h"
 #include "bytestream.h"
 #include "adpcm.h"
diff --git a/libavcodec/adx.h b/libavcodec/adx.h
index 85b35d1..b28d09a 100644
--- a/libavcodec/adx.h
+++ b/libavcodec/adx.h
@@ -40,7 +40,6 @@
 } ADXChannelState;
 
 typedef struct ADXContext {
-    AVFrame frame;
     int channels;
     ADXChannelState prev[2];
     int header_parsed;
diff --git a/libavcodec/adxdec.c b/libavcodec/adxdec.c
index 901d717..aebf691 100644
--- a/libavcodec/adxdec.c
+++ b/libavcodec/adxdec.c
@@ -23,6 +23,7 @@
 #include "avcodec.h"
 #include "adx.h"
 #include "get_bits.h"
+#include "internal.h"
 
 /**
  * @file
@@ -51,9 +52,6 @@
 
     avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
 
-    avcodec_get_frame_defaults(&c->frame);
-    avctx->coded_frame = &c->frame;
-
     return 0;
 }
 
@@ -97,6 +95,7 @@
 static int adx_decode_frame(AVCodecContext *avctx, void *data,
                             int *got_frame_ptr, AVPacket *avpkt)
 {
+    AVFrame *frame      = data;
     int buf_size        = avpkt->size;
     ADXContext *c       = avctx->priv_data;
     int16_t **samples;
@@ -142,12 +141,12 @@
     }
 
     /* get output buffer */
-    c->frame.nb_samples = num_blocks * BLOCK_SAMPLES;
-    if ((ret = avctx->get_buffer(avctx, &c->frame)) < 0) {
+    frame->nb_samples = num_blocks * BLOCK_SAMPLES;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    samples = (int16_t **)c->frame.extended_data;
+    samples = (int16_t **)frame->extended_data;
     samples_offset = 0;
 
     while (num_blocks--) {
@@ -163,8 +162,7 @@
         samples_offset += BLOCK_SAMPLES;
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = c->frame;
+    *got_frame_ptr = 1;
 
     return buf - avpkt->data;
 }
diff --git a/libavcodec/adxenc.c b/libavcodec/adxenc.c
index 8514a0c..fb8e06d 100644
--- a/libavcodec/adxenc.c
+++ b/libavcodec/adxenc.c
@@ -107,6 +107,14 @@
     return HEADER_SIZE;
 }
 
+#if FF_API_OLD_ENCODE_AUDIO
+static av_cold int adx_encode_close(AVCodecContext *avctx)
+{
+    av_freep(&avctx->coded_frame);
+    return 0;
+}
+#endif
+
 static av_cold int adx_encode_init(AVCodecContext *avctx)
 {
     ADXContext *c = avctx->priv_data;
@@ -118,8 +126,8 @@
     avctx->frame_size = BLOCK_SAMPLES;
 
 #if FF_API_OLD_ENCODE_AUDIO
-    avcodec_get_frame_defaults(&c->frame);
-    avctx->coded_frame = &c->frame;
+    if (!(avctx->coded_frame = avcodec_alloc_frame()))
+        return AVERROR(ENOMEM);
 #endif
 
     /* the cutoff can be adjusted, but this seems to work pretty well */
@@ -167,6 +175,9 @@
     .id             = AV_CODEC_ID_ADPCM_ADX,
     .priv_data_size = sizeof(ADXContext),
     .init           = adx_encode_init,
+#if FF_API_OLD_ENCODE_AUDIO
+    .close          = adx_encode_close,
+#endif
     .encode2        = adx_encode_frame,
     .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16,
                                                       AV_SAMPLE_FMT_NONE },
diff --git a/libavcodec/alac.c b/libavcodec/alac.c
index 49ccaac..f8ac560 100644
--- a/libavcodec/alac.c
+++ b/libavcodec/alac.c
@@ -49,15 +49,15 @@
 #include "avcodec.h"
 #include "get_bits.h"
 #include "bytestream.h"
+#include "internal.h"
 #include "unary.h"
 #include "mathops.h"
+#include "alac_data.h"
 
 #define ALAC_EXTRADATA_SIZE 36
-#define MAX_CHANNELS 8
 
 typedef struct {
     AVCodecContext *avctx;
-    AVFrame frame;
     GetBitContext gb;
     int channels;
 
@@ -77,40 +77,6 @@
     int direct_output;
 } ALACContext;
 
-enum RawDataBlockType {
-    /* At the moment, only SCE, CPE, LFE, and END are recognized. */
-    TYPE_SCE,
-    TYPE_CPE,
-    TYPE_CCE,
-    TYPE_LFE,
-    TYPE_DSE,
-    TYPE_PCE,
-    TYPE_FIL,
-    TYPE_END
-};
-
-static const uint8_t alac_channel_layout_offsets[8][8] = {
-    { 0 },
-    { 0, 1 },
-    { 2, 0, 1 },
-    { 2, 0, 1, 3 },
-    { 2, 0, 1, 3, 4 },
-    { 2, 0, 1, 4, 5, 3 },
-    { 2, 0, 1, 4, 5, 6, 3 },
-    { 2, 6, 7, 0, 1, 4, 5, 3 }
-};
-
-static const uint16_t alac_channel_layouts[8] = {
-    AV_CH_LAYOUT_MONO,
-    AV_CH_LAYOUT_STEREO,
-    AV_CH_LAYOUT_SURROUND,
-    AV_CH_LAYOUT_4POINT0,
-    AV_CH_LAYOUT_5POINT0_BACK,
-    AV_CH_LAYOUT_5POINT1_BACK,
-    AV_CH_LAYOUT_6POINT1_BACK,
-    AV_CH_LAYOUT_7POINT1_WIDE_BACK
-};
-
 static inline unsigned int decode_scalar(GetBitContext *gb, int k, int bps)
 {
     unsigned int x = get_unary_0_9(gb);
@@ -287,7 +253,7 @@
             buffer[ch][i] = (buffer[ch][i] << extra_bits) | extra_bits_buffer[ch][i];
 }
 
-static int decode_element(AVCodecContext *avctx, void *data, int ch_index,
+static int decode_element(AVCodecContext *avctx, AVFrame *frame, int ch_index,
                           int channels)
 {
     ALACContext *alac = avctx->priv_data;
@@ -322,8 +288,8 @@
     }
     if (!alac->nb_samples) {
         /* get output buffer */
-        alac->frame.nb_samples = output_samples;
-        if ((ret = avctx->get_buffer(avctx, &alac->frame)) < 0) {
+        frame->nb_samples = output_samples;
+        if ((ret = ff_get_buffer(avctx, frame)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
             return ret;
         }
@@ -335,7 +301,7 @@
     alac->nb_samples = output_samples;
     if (alac->direct_output) {
         for (ch = 0; ch < channels; ch++)
-            alac->output_samples_buffer[ch] = (int32_t *)alac->frame.extended_data[ch_index + ch];
+            alac->output_samples_buffer[ch] = (int32_t *)frame->extended_data[ch_index + ch];
     }
 
     if (is_compressed) {
@@ -423,7 +389,7 @@
     switch(alac->sample_size) {
     case 16: {
         for (ch = 0; ch < channels; ch++) {
-            int16_t *outbuffer = (int16_t *)alac->frame.extended_data[ch_index + ch];
+            int16_t *outbuffer = (int16_t *)frame->extended_data[ch_index + ch];
             for (i = 0; i < alac->nb_samples; i++)
                 *outbuffer++ = alac->output_samples_buffer[ch][i];
         }}
@@ -438,7 +404,7 @@
     }else{
         switch(alac->sample_size) {
         case 16: {
-            int16_t *outbuffer = ((int16_t *)alac->frame.extended_data[0]) + ch_index;
+            int16_t *outbuffer = ((int16_t *)frame->extended_data[0]) + ch_index;
             for (i = 0; i < alac->nb_samples; i++) {
                 for (ch = 0; ch < channels; ch++)
                     *outbuffer++ = alac->output_samples_buffer[ch][i];
@@ -447,7 +413,7 @@
             }
             break;
         case 24: {
-            int32_t *outbuffer = ((int32_t *)alac->frame.extended_data[0]) + ch_index;
+            int32_t *outbuffer = ((int32_t *)frame->extended_data[0]) + ch_index;
             for (i = 0; i < alac->nb_samples; i++) {
                 for (ch = 0; ch < channels; ch++)
                     *outbuffer++ = alac->output_samples_buffer[ch][i] << 8;
@@ -456,7 +422,7 @@
             }
             break;
         case 32: {
-            int32_t *outbuffer = ((int32_t *)alac->frame.extended_data[0]) + ch_index;
+            int32_t *outbuffer = ((int32_t *)frame->extended_data[0]) + ch_index;
             for (i = 0; i < alac->nb_samples; i++) {
                 for (ch = 0; ch < channels; ch++)
                     *outbuffer++ = alac->output_samples_buffer[ch][i];
@@ -474,7 +440,8 @@
                              int *got_frame_ptr, AVPacket *avpkt)
 {
     ALACContext *alac = avctx->priv_data;
-    enum RawDataBlockType element;
+    AVFrame *frame    = data;
+    enum AlacRawDataBlockType element;
     int channels;
     int ch, ret, got_end;
 
@@ -496,14 +463,14 @@
 
         channels = (element == TYPE_CPE) ? 2 : 1;
         if (   ch + channels > alac->channels
-            || alac_channel_layout_offsets[alac->channels - 1][ch] + channels > alac->channels
+            || ff_alac_channel_layout_offsets[alac->channels - 1][ch] + channels > alac->channels
         ) {
             av_log(avctx, AV_LOG_ERROR, "invalid element channel count\n");
             return AVERROR_INVALIDDATA;
         }
 
-        ret = decode_element(avctx, data,
-                             alac_channel_layout_offsets[alac->channels - 1][ch],
+        ret = decode_element(avctx, frame,
+                             ff_alac_channel_layout_offsets[alac->channels - 1][ch],
                              channels);
         if (ret < 0 && get_bits_left(&alac->gb))
             return ret;
@@ -520,8 +487,7 @@
                avpkt->size * 8 - get_bits_count(&alac->gb));
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = alac->frame;
+    *got_frame_ptr = 1;
 
     return avpkt->size;
 }
@@ -606,10 +572,9 @@
     alac->avctx = avctx;
 
     /* initialize from the extradata */
-    if (alac->avctx->extradata_size != ALAC_EXTRADATA_SIZE) {
-        av_log(avctx, AV_LOG_ERROR, "expected %d extradata bytes\n",
-            ALAC_EXTRADATA_SIZE);
-        return -1;
+    if (alac->avctx->extradata_size < ALAC_EXTRADATA_SIZE) {
+        av_log(avctx, AV_LOG_ERROR, "extradata is too small\n");
+        return AVERROR_INVALIDDATA;
     }
     if (alac_set_info(alac)) {
         av_log(avctx, AV_LOG_ERROR, "set_info failed\n");
@@ -633,26 +598,23 @@
         av_log(avctx, AV_LOG_WARNING, "Invalid channel count\n");
         alac->channels = avctx->channels;
     } else {
-        if (alac->channels > MAX_CHANNELS)
+        if (alac->channels > ALAC_MAX_CHANNELS)
             alac->channels = avctx->channels;
         else
             avctx->channels = alac->channels;
     }
-    if (avctx->channels > MAX_CHANNELS || avctx->channels <= 0 ) {
+    if (avctx->channels > ALAC_MAX_CHANNELS || avctx->channels <= 0 ) {
         av_log(avctx, AV_LOG_ERROR, "Unsupported channel count: %d\n",
                avctx->channels);
         return AVERROR_PATCHWELCOME;
     }
-    avctx->channel_layout = alac_channel_layouts[alac->channels - 1];
+    avctx->channel_layout = ff_alac_channel_layouts[alac->channels - 1];
 
     if ((ret = allocate_buffers(alac)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "Error allocating buffers\n");
         return ret;
     }
 
-    avcodec_get_frame_defaults(&alac->frame);
-    avctx->coded_frame = &alac->frame;
-
     return 0;
 }
 
diff --git a/libavcodec/alac_data.c b/libavcodec/alac_data.c
new file mode 100644
index 0000000..0bcb06c
--- /dev/null
+++ b/libavcodec/alac_data.c
@@ -0,0 +1,56 @@
+/*
+ * ALAC encoder and decoder common 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 "libavutil/channel_layout.h"
+#include "alac_data.h"
+
+const uint8_t ff_alac_channel_layout_offsets[ALAC_MAX_CHANNELS][ALAC_MAX_CHANNELS] = {
+    { 0 },
+    { 0, 1 },
+    { 2, 0, 1 },
+    { 2, 0, 1, 3 },
+    { 2, 0, 1, 3, 4 },
+    { 2, 0, 1, 4, 5, 3 },
+    { 2, 0, 1, 4, 5, 6, 3 },
+    { 2, 6, 7, 0, 1, 4, 5, 3 }
+};
+
+const uint64_t ff_alac_channel_layouts[ALAC_MAX_CHANNELS + 1] = {
+    AV_CH_LAYOUT_MONO,
+    AV_CH_LAYOUT_STEREO,
+    AV_CH_LAYOUT_SURROUND,
+    AV_CH_LAYOUT_4POINT0,
+    AV_CH_LAYOUT_5POINT0_BACK,
+    AV_CH_LAYOUT_5POINT1_BACK,
+    AV_CH_LAYOUT_6POINT1_BACK,
+    AV_CH_LAYOUT_7POINT1_WIDE_BACK,
+    0
+};
+
+const enum AlacRawDataBlockType ff_alac_channel_elements[ALAC_MAX_CHANNELS][5] = {
+    { TYPE_SCE,                                         },
+    { TYPE_CPE,                                         },
+    { TYPE_SCE, TYPE_CPE,                               },
+    { TYPE_SCE, TYPE_CPE, TYPE_SCE                      },
+    { TYPE_SCE, TYPE_CPE, TYPE_CPE,                     },
+    { TYPE_SCE, TYPE_CPE, TYPE_CPE, TYPE_SCE,           },
+    { TYPE_SCE, TYPE_CPE, TYPE_CPE, TYPE_SCE, TYPE_SCE, },
+    { TYPE_SCE, TYPE_CPE, TYPE_CPE, TYPE_CPE, TYPE_SCE, },
+};
diff --git a/libavcodec/alac_data.h b/libavcodec/alac_data.h
new file mode 100644
index 0000000..650d6dc
--- /dev/null
+++ b/libavcodec/alac_data.h
@@ -0,0 +1,46 @@
+/*
+ * ALAC encoder and decoder common 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_ALAC_DATA_H
+#define AVCODEC_ALAC_DATA_H
+
+#include <stdint.h>
+
+enum AlacRawDataBlockType {
+    /* At the moment, only SCE, CPE, LFE, and END are recognized. */
+    TYPE_SCE,
+    TYPE_CPE,
+    TYPE_CCE,
+    TYPE_LFE,
+    TYPE_DSE,
+    TYPE_PCE,
+    TYPE_FIL,
+    TYPE_END
+};
+
+#define ALAC_MAX_CHANNELS 8
+
+extern const uint8_t ff_alac_channel_layout_offsets[ALAC_MAX_CHANNELS][ALAC_MAX_CHANNELS];
+
+extern const uint64_t ff_alac_channel_layouts[ALAC_MAX_CHANNELS + 1];
+
+extern const enum AlacRawDataBlockType ff_alac_channel_elements[ALAC_MAX_CHANNELS][5];
+
+#endif /* AVCODEC_ALAC_DATA_H */
diff --git a/libavcodec/alacenc.c b/libavcodec/alacenc.c
index 706810f..61bb65a 100644
--- a/libavcodec/alacenc.c
+++ b/libavcodec/alacenc.c
@@ -21,13 +21,12 @@
 
 #include "avcodec.h"
 #include "put_bits.h"
-#include "dsputil.h"
 #include "internal.h"
 #include "lpc.h"
 #include "mathops.h"
+#include "alac_data.h"
 
 #define DEFAULT_FRAME_SIZE        4096
-#define MAX_CHANNELS              8
 #define ALAC_EXTRADATA_SIZE       36
 #define ALAC_FRAME_HEADER_SIZE    55
 #define ALAC_FRAME_FOOTER_SIZE    3
@@ -66,27 +65,27 @@
     int max_coded_frame_size;
     int write_sample_size;
     int extra_bits;
-    int32_t sample_buf[MAX_CHANNELS][DEFAULT_FRAME_SIZE];
+    int32_t sample_buf[2][DEFAULT_FRAME_SIZE];
     int32_t predictor_buf[DEFAULT_FRAME_SIZE];
     int interlacing_shift;
     int interlacing_leftweight;
     PutBitContext pbctx;
     RiceContext rc;
-    AlacLPCContext lpc[MAX_CHANNELS];
+    AlacLPCContext lpc[2];
     LPCContext lpc_ctx;
     AVCodecContext *avctx;
 } AlacEncodeContext;
 
 
-static void init_sample_buffers(AlacEncodeContext *s,
-                                uint8_t * const *samples)
+static void init_sample_buffers(AlacEncodeContext *s, int channels,
+                                uint8_t const *samples[2])
 {
     int ch, i;
     int shift = av_get_bytes_per_sample(s->avctx->sample_fmt) * 8 -
                 s->avctx->bits_per_raw_sample;
 
 #define COPY_SAMPLES(type) do {                             \
-        for (ch = 0; ch < s->avctx->channels; ch++) {       \
+        for (ch = 0; ch < channels; ch++) {                 \
             int32_t       *bptr = s->sample_buf[ch];        \
             const type *sptr = (const type *)samples[ch];   \
             for (i = 0; i < s->frame_size; i++)             \
@@ -128,15 +127,18 @@
     }
 }
 
-static void write_frame_header(AlacEncodeContext *s)
+static void write_element_header(AlacEncodeContext *s,
+                                 enum AlacRawDataBlockType element,
+                                 int instance)
 {
     int encode_fs = 0;
 
     if (s->frame_size < DEFAULT_FRAME_SIZE)
         encode_fs = 1;
 
-    put_bits(&s->pbctx, 3,  s->avctx->channels-1);  // No. of channels -1
-    put_bits(&s->pbctx, 16, 0);                     // Seems to be zero
+    put_bits(&s->pbctx, 3,  element);               // element type
+    put_bits(&s->pbctx, 4,  instance);              // element instance
+    put_bits(&s->pbctx, 12, 0);                     // unused header bits
     put_bits(&s->pbctx, 1,  encode_fs);             // Sample count is in the header
     put_bits(&s->pbctx, 2,  s->extra_bits >> 3);    // Extra bytes (for 24-bit)
     put_bits(&s->pbctx, 1,  s->verbatim);           // Audio block is verbatim
@@ -355,42 +357,51 @@
     }
 }
 
-static int write_frame(AlacEncodeContext *s, AVPacket *avpkt,
-                       uint8_t * const *samples)
+static void write_element(AlacEncodeContext *s,
+                          enum AlacRawDataBlockType element, int instance,
+                          const uint8_t *samples0, const uint8_t *samples1)
 {
-    int i, j;
+    uint8_t const *samples[2] = { samples0, samples1 };
+    int i, j, channels;
     int prediction_type = 0;
     PutBitContext *pb = &s->pbctx;
 
-    init_put_bits(pb, avpkt->data, avpkt->size);
+    channels = element == TYPE_CPE ? 2 : 1;
 
     if (s->verbatim) {
-        write_frame_header(s);
+        write_element_header(s, element, instance);
         /* samples are channel-interleaved in verbatim mode */
         if (s->avctx->sample_fmt == AV_SAMPLE_FMT_S32P) {
             int shift = 32 - s->avctx->bits_per_raw_sample;
-            int32_t * const *samples_s32 = (int32_t * const *)samples;
+            int32_t const *samples_s32[2] = { (const int32_t *)samples0,
+                                              (const int32_t *)samples1 };
             for (i = 0; i < s->frame_size; i++)
-                for (j = 0; j < s->avctx->channels; j++)
+                for (j = 0; j < channels; j++)
                     put_sbits(pb, s->avctx->bits_per_raw_sample,
                               samples_s32[j][i] >> shift);
         } else {
-            int16_t * const *samples_s16 = (int16_t * const *)samples;
+            int16_t const *samples_s16[2] = { (const int16_t *)samples0,
+                                              (const int16_t *)samples1 };
             for (i = 0; i < s->frame_size; i++)
-                for (j = 0; j < s->avctx->channels; j++)
+                for (j = 0; j < channels; j++)
                     put_sbits(pb, s->avctx->bits_per_raw_sample,
                               samples_s16[j][i]);
         }
     } else {
-        init_sample_buffers(s, samples);
-        write_frame_header(s);
+        s->write_sample_size = s->avctx->bits_per_raw_sample - s->extra_bits +
+                               channels - 1;
 
-        if (s->avctx->channels == 2)
+        init_sample_buffers(s, channels, samples);
+        write_element_header(s, element, instance);
+
+        if (channels == 2)
             alac_stereo_decorrelation(s);
+        else
+            s->interlacing_shift = s->interlacing_leftweight = 0;
         put_bits(pb, 8, s->interlacing_shift);
         put_bits(pb, 8, s->interlacing_leftweight);
 
-        for (i = 0; i < s->avctx->channels; i++) {
+        for (i = 0; i < channels; i++) {
             calc_predictor_params(s, i);
 
             put_bits(pb, 4, prediction_type);
@@ -407,7 +418,7 @@
         if (s->extra_bits) {
             uint32_t mask = (1 << s->extra_bits) - 1;
             for (i = 0; i < s->frame_size; i++) {
-                for (j = 0; j < s->avctx->channels; j++) {
+                for (j = 0; j < channels; j++) {
                     put_bits(pb, s->extra_bits, s->sample_buf[j][i] & mask);
                     s->sample_buf[j][i] >>= s->extra_bits;
                 }
@@ -415,8 +426,7 @@
         }
 
         // apply lpc and entropy coding to audio samples
-
-        for (i = 0; i < s->avctx->channels; i++) {
+        for (i = 0; i < channels; i++) {
             alac_linear_predictor(s, i);
 
             // TODO: determine when this will actually help. for now it's not used.
@@ -425,12 +435,39 @@
                 for (j = s->frame_size - 1; j > 0; j--)
                     s->predictor_buf[j] -= s->predictor_buf[j - 1];
             }
-
             alac_entropy_coder(s);
         }
     }
-    put_bits(pb, 3, 7);
+}
+
+static int write_frame(AlacEncodeContext *s, AVPacket *avpkt,
+                       uint8_t * const *samples)
+{
+    PutBitContext *pb = &s->pbctx;
+    const enum AlacRawDataBlockType *ch_elements = ff_alac_channel_elements[s->avctx->channels - 1];
+    const uint8_t *ch_map = ff_alac_channel_layout_offsets[s->avctx->channels - 1];
+    int ch, element, sce, cpe;
+
+    init_put_bits(pb, avpkt->data, avpkt->size);
+
+    ch = element = sce = cpe = 0;
+    while (ch < s->avctx->channels) {
+        if (ch_elements[element] == TYPE_CPE) {
+            write_element(s, TYPE_CPE, cpe, samples[ch_map[ch]],
+                          samples[ch_map[ch + 1]]);
+            cpe++;
+            ch += 2;
+        } else {
+            write_element(s, TYPE_SCE, sce, samples[ch_map[ch]], NULL);
+            sce++;
+            ch++;
+        }
+        element++;
+    }
+
+    put_bits(pb, 3, TYPE_END);
     flush_put_bits(pb);
+
     return put_bits_count(pb) >> 3;
 }
 
@@ -458,14 +495,6 @@
 
     avctx->frame_size = s->frame_size = DEFAULT_FRAME_SIZE;
 
-    /* TODO: Correctly implement multi-channel ALAC.
-             It is similar to multi-channel AAC, in that it has a series of
-             single-channel (SCE), channel-pair (CPE), and LFE elements. */
-    if (avctx->channels > 2) {
-        av_log(avctx, AV_LOG_ERROR, "only mono or stereo input is currently supported\n");
-        return AVERROR_PATCHWELCOME;
-    }
-
     if (avctx->sample_fmt == AV_SAMPLE_FMT_S32P) {
         if (avctx->bits_per_raw_sample != 24)
             av_log(avctx, AV_LOG_WARNING, "encoding as 24 bits-per-sample\n");
@@ -595,8 +624,6 @@
         s->verbatim   = 1;
         s->extra_bits = 0;
     }
-    s->write_sample_size = avctx->bits_per_raw_sample - s->extra_bits +
-                           avctx->channels - 1;
 
     out_bytes = write_frame(s, avpkt, frame->extended_data);
 
@@ -604,7 +631,6 @@
         /* frame too large. use verbatim mode */
         s->verbatim = 1;
         s->extra_bits = 0;
-        s->write_sample_size = avctx->bits_per_raw_sample + avctx->channels - 1;
         out_bytes = write_frame(s, avpkt, frame->extended_data);
     }
 
@@ -622,6 +648,7 @@
     .encode2        = alac_encode_frame,
     .close          = alac_encode_close,
     .capabilities   = CODEC_CAP_SMALL_LAST_FRAME,
+    .channel_layouts = ff_alac_channel_layouts,
     .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S32P,
                                                      AV_SAMPLE_FMT_S16P,
                                                      AV_SAMPLE_FMT_NONE },
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index 4743bb1..584446f 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -27,24 +27,42 @@
 #include "avcodec.h"
 #include "config.h"
 
-#define REGISTER_HWACCEL(X,x) { \
-          extern AVHWAccel ff_##x##_hwaccel; \
-          if(CONFIG_##X##_HWACCEL) av_register_hwaccel(&ff_##x##_hwaccel); }
+#define REGISTER_HWACCEL(X, x)                                          \
+    {                                                                   \
+        extern AVHWAccel ff_##x##_hwaccel;                              \
+        if (CONFIG_##X##_HWACCEL)                                       \
+            av_register_hwaccel(&ff_##x##_hwaccel);                     \
+    }
 
-#define REGISTER_ENCODER(X,x) { \
-          extern AVCodec ff_##x##_encoder; \
-          if(CONFIG_##X##_ENCODER)  avcodec_register(&ff_##x##_encoder); }
-#define REGISTER_DECODER(X,x) { \
-          extern AVCodec ff_##x##_decoder; \
-          if(CONFIG_##X##_DECODER)  avcodec_register(&ff_##x##_decoder); }
-#define REGISTER_ENCDEC(X,x)  REGISTER_ENCODER(X,x); REGISTER_DECODER(X,x)
+#define REGISTER_ENCODER(X, x)                                          \
+    {                                                                   \
+        extern AVCodec ff_##x##_encoder;                                \
+        if (CONFIG_##X##_ENCODER)                                       \
+            avcodec_register(&ff_##x##_encoder);                        \
+    }
 
-#define REGISTER_PARSER(X,x) { \
-          extern AVCodecParser ff_##x##_parser; \
-          if(CONFIG_##X##_PARSER)  av_register_codec_parser(&ff_##x##_parser); }
-#define REGISTER_BSF(X,x) { \
-          extern AVBitStreamFilter ff_##x##_bsf; \
-          if(CONFIG_##X##_BSF)     av_register_bitstream_filter(&ff_##x##_bsf); }
+#define REGISTER_DECODER(X, x)                                          \
+    {                                                                   \
+        extern AVCodec ff_##x##_decoder;                                \
+        if (CONFIG_##X##_DECODER)                                       \
+            avcodec_register(&ff_##x##_decoder);                        \
+    }
+
+#define REGISTER_ENCDEC(X, x) REGISTER_ENCODER(X, x); REGISTER_DECODER(X, x)
+
+#define REGISTER_PARSER(X, x)                                           \
+    {                                                                   \
+        extern AVCodecParser ff_##x##_parser;                           \
+        if (CONFIG_##X##_PARSER)                                        \
+            av_register_codec_parser(&ff_##x##_parser);                 \
+    }
+
+#define REGISTER_BSF(X, x)                                              \
+    {                                                                   \
+        extern AVBitStreamFilter ff_##x##_bsf;                          \
+        if (CONFIG_##X##_BSF)                                           \
+            av_register_bitstream_filter(&ff_##x##_bsf);                \
+    }
 
 void avcodec_register_all(void)
 {
@@ -55,465 +73,480 @@
     initialized = 1;
 
     /* hardware accelerators */
-    REGISTER_HWACCEL (H263_VAAPI, h263_vaapi);
-    REGISTER_HWACCEL (H264_DXVA2, h264_dxva2);
-    REGISTER_HWACCEL (H264_VAAPI, h264_vaapi);
-    REGISTER_HWACCEL (H264_VDA, h264_vda);
-    REGISTER_HWACCEL (MPEG1_VDPAU, mpeg1_vdpau);
-    REGISTER_HWACCEL (MPEG2_DXVA2, mpeg2_dxva2);
-    REGISTER_HWACCEL (MPEG2_VAAPI, mpeg2_vaapi);
-    REGISTER_HWACCEL (MPEG2_VDPAU, mpeg2_vdpau);
-    REGISTER_HWACCEL (MPEG4_VAAPI, mpeg4_vaapi);
-    REGISTER_HWACCEL (VC1_DXVA2, vc1_dxva2);
-    REGISTER_HWACCEL (VC1_VAAPI, vc1_vaapi);
-    REGISTER_HWACCEL (WMV3_DXVA2, wmv3_dxva2);
-    REGISTER_HWACCEL (WMV3_VAAPI, wmv3_vaapi);
+    REGISTER_HWACCEL(H263_VAAPI,        h263_vaapi);
+    REGISTER_HWACCEL(H263_VDPAU,        h263_vdpau);
+    REGISTER_HWACCEL(H264_DXVA2,        h264_dxva2);
+    REGISTER_HWACCEL(H264_VAAPI,        h264_vaapi);
+    REGISTER_HWACCEL(H264_VDA,          h264_vda);
+    REGISTER_HWACCEL(H264_VDPAU,        h264_vdpau);
+    REGISTER_HWACCEL(MPEG1_VDPAU,       mpeg1_vdpau);
+    REGISTER_HWACCEL(MPEG2_DXVA2,       mpeg2_dxva2);
+    REGISTER_HWACCEL(MPEG2_VAAPI,       mpeg2_vaapi);
+    REGISTER_HWACCEL(MPEG2_VDPAU,       mpeg2_vdpau);
+    REGISTER_HWACCEL(MPEG4_VAAPI,       mpeg4_vaapi);
+    REGISTER_HWACCEL(MPEG4_VDPAU,       mpeg4_vdpau);
+    REGISTER_HWACCEL(VC1_DXVA2,         vc1_dxva2);
+    REGISTER_HWACCEL(VC1_VAAPI,         vc1_vaapi);
+    REGISTER_HWACCEL(VC1_VDPAU,         vc1_vdpau);
+    REGISTER_HWACCEL(WMV3_DXVA2,        wmv3_dxva2);
+    REGISTER_HWACCEL(WMV3_VAAPI,        wmv3_vaapi);
+    REGISTER_HWACCEL(WMV3_VDPAU,        wmv3_vdpau);
 
     /* video codecs */
-    REGISTER_ENCODER (A64MULTI, a64multi);
-    REGISTER_ENCODER (A64MULTI5, a64multi5);
-    REGISTER_DECODER (AASC, aasc);
-    REGISTER_ENCDEC  (AMV, amv);
-    REGISTER_DECODER (ANM, anm);
-    REGISTER_DECODER (ANSI, ansi);
-    REGISTER_ENCDEC  (ASV1, asv1);
-    REGISTER_ENCDEC  (ASV2, asv2);
-    REGISTER_DECODER (AURA, aura);
-    REGISTER_DECODER (AURA2, aura2);
-    REGISTER_ENCDEC  (AVRP, avrp);
-    REGISTER_DECODER (AVRN, avrn);
-    REGISTER_DECODER (AVS, avs);
-    REGISTER_ENCDEC  (AVUI, avui);
-    REGISTER_ENCDEC  (AYUV, ayuv);
-    REGISTER_DECODER (BETHSOFTVID, bethsoftvid);
-    REGISTER_DECODER (BFI, bfi);
-    REGISTER_DECODER (BINK, bink);
-    REGISTER_ENCDEC  (BMP, bmp);
-    REGISTER_DECODER (BMV_VIDEO, bmv_video);
-    REGISTER_DECODER (BRENDER_PIX, brender_pix);
-    REGISTER_DECODER (C93, c93);
-    REGISTER_DECODER (CAVS, cavs);
-    REGISTER_DECODER (CDGRAPHICS, cdgraphics);
-    REGISTER_DECODER (CDXL, cdxl);
-    REGISTER_DECODER (CINEPAK, cinepak);
-    REGISTER_ENCDEC  (CLJR, cljr);
-    REGISTER_DECODER (CLLC, cllc);
-    REGISTER_ENCDEC  (COMFORTNOISE, comfortnoise);
-    REGISTER_DECODER (CPIA, cpia);
-    REGISTER_DECODER (CSCD, cscd);
-    REGISTER_DECODER (CYUV, cyuv);
-    REGISTER_DECODER (DFA, dfa);
-    REGISTER_DECODER (DIRAC, dirac);
-    REGISTER_ENCDEC  (DNXHD, dnxhd);
-    REGISTER_ENCDEC  (DPX, dpx);
-    REGISTER_DECODER (DSICINVIDEO, dsicinvideo);
-    REGISTER_ENCDEC  (DVVIDEO, dvvideo);
-    REGISTER_DECODER (DXA, dxa);
-    REGISTER_DECODER (DXTORY, dxtory);
-    REGISTER_DECODER (EACMV, eacmv);
-    REGISTER_DECODER (EAMAD, eamad);
-    REGISTER_DECODER (EATGQ, eatgq);
-    REGISTER_DECODER (EATGV, eatgv);
-    REGISTER_DECODER (EATQI, eatqi);
-    REGISTER_DECODER (EIGHTBPS, eightbps);
-    REGISTER_DECODER (EIGHTSVX_EXP, eightsvx_exp);
-    REGISTER_DECODER (EIGHTSVX_FIB, eightsvx_fib);
-    REGISTER_DECODER (ESCAPE124, escape124);
-    REGISTER_DECODER (ESCAPE130, escape130);
-    REGISTER_DECODER (EXR, exr);
-    REGISTER_ENCDEC  (FFV1, ffv1);
-    REGISTER_ENCDEC  (FFVHUFF, ffvhuff);
-    REGISTER_ENCDEC  (FLASHSV, flashsv);
-    REGISTER_ENCDEC  (FLASHSV2, flashsv2);
-    REGISTER_DECODER (FLIC, flic);
-    REGISTER_ENCDEC  (FLV, flv);
-    REGISTER_DECODER (FOURXM, fourxm);
-    REGISTER_DECODER (FRAPS, fraps);
-    REGISTER_DECODER (FRWU, frwu);
-    REGISTER_ENCDEC  (GIF, gif);
-    REGISTER_ENCDEC  (H261, h261);
-    REGISTER_ENCDEC  (H263, h263);
-    REGISTER_DECODER (H263I, h263i);
-    REGISTER_ENCDEC  (H263P, h263p);
-    REGISTER_DECODER (H264, h264);
-    REGISTER_DECODER (H264_CRYSTALHD, h264_crystalhd);
-    REGISTER_DECODER (H264_VDA, h264_vda);
-    REGISTER_DECODER (H264_VDPAU, h264_vdpau);
-    REGISTER_ENCDEC  (HUFFYUV, huffyuv);
-    REGISTER_DECODER (IDCIN, idcin);
-    REGISTER_DECODER (IFF_BYTERUN1, iff_byterun1);
-    REGISTER_DECODER (IFF_ILBM, iff_ilbm);
-    REGISTER_DECODER (INDEO2, indeo2);
-    REGISTER_DECODER (INDEO3, indeo3);
-    REGISTER_DECODER (INDEO4, indeo4);
-    REGISTER_DECODER (INDEO5, indeo5);
-    REGISTER_DECODER (INTERPLAY_VIDEO, interplay_video);
-    REGISTER_ENCDEC  (JPEG2000, jpeg2000);
-    REGISTER_ENCDEC  (JPEGLS, jpegls);
-    REGISTER_DECODER (JV, jv);
-    REGISTER_DECODER (KGV1, kgv1);
-    REGISTER_DECODER (KMVC, kmvc);
-    REGISTER_DECODER (LAGARITH, lagarith);
-    REGISTER_ENCODER (LJPEG, ljpeg);
-    REGISTER_DECODER (LOCO, loco);
-    REGISTER_DECODER (MDEC, mdec);
-    REGISTER_DECODER (MIMIC, mimic);
-    REGISTER_ENCDEC  (MJPEG, mjpeg);
-    REGISTER_DECODER (MJPEGB, mjpegb);
-    REGISTER_DECODER (MMVIDEO, mmvideo);
-    REGISTER_DECODER (MOTIONPIXELS, motionpixels);
-    REGISTER_DECODER (MPEG_XVMC, mpeg_xvmc);
-    REGISTER_ENCDEC  (MPEG1VIDEO, mpeg1video);
-    REGISTER_ENCDEC  (MPEG2VIDEO, mpeg2video);
-    REGISTER_ENCDEC  (MPEG4, mpeg4);
-    REGISTER_DECODER (MPEG4_CRYSTALHD, mpeg4_crystalhd);
-    REGISTER_DECODER (MPEG4_VDPAU, mpeg4_vdpau);
-    REGISTER_DECODER (MPEGVIDEO, mpegvideo);
-    REGISTER_DECODER (MPEG_VDPAU, mpeg_vdpau);
-    REGISTER_DECODER (MPEG1_VDPAU, mpeg1_vdpau);
-    REGISTER_DECODER (MPEG2_CRYSTALHD, mpeg2_crystalhd);
-    REGISTER_DECODER (MSA1, msa1);
-    REGISTER_DECODER (MSMPEG4_CRYSTALHD, msmpeg4_crystalhd);
-    REGISTER_DECODER (MSMPEG4V1, msmpeg4v1);
-    REGISTER_ENCDEC  (MSMPEG4V2, msmpeg4v2);
-    REGISTER_ENCDEC  (MSMPEG4V3, msmpeg4v3);
-    REGISTER_DECODER (MSRLE, msrle);
-    REGISTER_DECODER (MSS1, mss1);
-    REGISTER_DECODER (MSS2, mss2);
-    REGISTER_ENCDEC  (MSVIDEO1, msvideo1);
-    REGISTER_DECODER (MSZH, mszh);
-    REGISTER_DECODER (MTS2, mts2);
-    REGISTER_DECODER (MXPEG, mxpeg);
-    REGISTER_DECODER (NUV, nuv);
-    REGISTER_DECODER (PAF_VIDEO, paf_video);
-    REGISTER_ENCDEC  (PAM, pam);
-    REGISTER_ENCDEC  (PBM, pbm);
-    REGISTER_ENCDEC  (PCX, pcx);
-    REGISTER_ENCDEC  (PGM, pgm);
-    REGISTER_ENCDEC  (PGMYUV, pgmyuv);
-    REGISTER_DECODER (PICTOR, pictor);
-    REGISTER_ENCDEC  (PNG, png);
-    REGISTER_ENCDEC  (PPM, ppm);
-    REGISTER_ENCDEC  (PRORES, prores);
-    REGISTER_ENCODER (PRORES_ANATOLIY, prores_anatoliy);
-    REGISTER_ENCODER (PRORES_KOSTYA, prores_kostya);
-    REGISTER_DECODER (PRORES_LGPL, prores_lgpl);
-    REGISTER_DECODER (PTX, ptx);
-    REGISTER_DECODER (QDRAW, qdraw);
-    REGISTER_DECODER (QPEG, qpeg);
-    REGISTER_ENCDEC  (QTRLE, qtrle);
-    REGISTER_ENCDEC  (R10K,  r10k);
-    REGISTER_ENCDEC  (R210,  r210);
-    REGISTER_ENCDEC  (RAWVIDEO, rawvideo);
-    REGISTER_DECODER (RL2, rl2);
-    REGISTER_ENCDEC  (ROQ, roq);
-    REGISTER_DECODER (RPZA, rpza);
-    REGISTER_ENCDEC  (RV10, rv10);
-    REGISTER_ENCDEC  (RV20, rv20);
-    REGISTER_DECODER (RV30, rv30);
-    REGISTER_DECODER (RV40, rv40);
-    REGISTER_DECODER (S302M, s302m);
-    REGISTER_DECODER (SANM, sanm);
-    REGISTER_ENCDEC  (SGI, sgi);
-    REGISTER_DECODER (SMACKER, smacker);
-    REGISTER_DECODER (SMC, smc);
-    REGISTER_ENCDEC  (SNOW, snow);
-    REGISTER_DECODER (SP5X, sp5x);
-    REGISTER_ENCDEC  (SUNRAST, sunrast);
-    REGISTER_ENCDEC  (SVQ1, svq1);
-    REGISTER_DECODER (SVQ3, svq3);
-    REGISTER_ENCDEC  (TARGA, targa);
-    REGISTER_DECODER (TARGA_Y216, targa_y216);
-    REGISTER_DECODER (THEORA, theora);
-    REGISTER_DECODER (THP, thp);
-    REGISTER_DECODER (TIERTEXSEQVIDEO, tiertexseqvideo);
-    REGISTER_ENCDEC  (TIFF, tiff);
-    REGISTER_DECODER (TMV, tmv);
-    REGISTER_DECODER (TRUEMOTION1, truemotion1);
-    REGISTER_DECODER (TRUEMOTION2, truemotion2);
-    REGISTER_DECODER (TSCC, tscc);
-    REGISTER_DECODER (TSCC2, tscc2);
-    REGISTER_DECODER (TXD, txd);
-    REGISTER_DECODER (ULTI, ulti);
-    REGISTER_ENCDEC  (UTVIDEO, utvideo);
-    REGISTER_ENCDEC  (V210,  v210);
-    REGISTER_DECODER (V210X, v210x);
-    REGISTER_ENCDEC  (V308, v308);
-    REGISTER_ENCDEC  (V408, v408);
-    REGISTER_ENCDEC  (V410, v410);
-    REGISTER_DECODER (VB, vb);
-    REGISTER_DECODER (VBLE, vble);
-    REGISTER_DECODER (VC1, vc1);
-    REGISTER_DECODER (VC1_CRYSTALHD, vc1_crystalhd);
-    REGISTER_DECODER (VC1_VDPAU, vc1_vdpau);
-    REGISTER_DECODER (VC1IMAGE, vc1image);
-    REGISTER_DECODER (VCR1, vcr1);
-    REGISTER_DECODER (VMDVIDEO, vmdvideo);
-    REGISTER_DECODER (VMNC, vmnc);
-    REGISTER_DECODER (VP3, vp3);
-    REGISTER_DECODER (VP5, vp5);
-    REGISTER_DECODER (VP6, vp6);
-    REGISTER_DECODER (VP6A, vp6a);
-    REGISTER_DECODER (VP6F, vp6f);
-    REGISTER_DECODER (VP8, vp8);
-    REGISTER_DECODER (VQA, vqa);
-    REGISTER_ENCDEC  (WMV1, wmv1);
-    REGISTER_ENCDEC  (WMV2, wmv2);
-    REGISTER_DECODER (WMV3, wmv3);
-    REGISTER_DECODER (WMV3_CRYSTALHD, wmv3_crystalhd);
-    REGISTER_DECODER (WMV3_VDPAU, wmv3_vdpau);
-    REGISTER_DECODER (WMV3IMAGE, wmv3image);
-    REGISTER_DECODER (WNV1, wnv1);
-    REGISTER_DECODER (XAN_WC3, xan_wc3);
-    REGISTER_DECODER (XAN_WC4, xan_wc4);
-    REGISTER_ENCDEC  (XBM, xbm);
-    REGISTER_ENCDEC  (XFACE, xface);
-    REGISTER_DECODER (XL, xl);
-    REGISTER_ENCDEC  (XWD, xwd);
-    REGISTER_ENCDEC  (Y41P, y41p);
-    REGISTER_DECODER (YOP, yop);
-    REGISTER_ENCDEC  (YUV4, yuv4);
-    REGISTER_DECODER (ZEROCODEC, zerocodec);
-    REGISTER_ENCDEC  (ZLIB, zlib);
-    REGISTER_ENCDEC  (ZMBV, zmbv);
+    REGISTER_ENCODER(A64MULTI,          a64multi);
+    REGISTER_ENCODER(A64MULTI5,         a64multi5);
+    REGISTER_DECODER(AASC,              aasc);
+    REGISTER_ENCDEC (AMV,               amv);
+    REGISTER_DECODER(ANM,               anm);
+    REGISTER_DECODER(ANSI,              ansi);
+    REGISTER_ENCDEC (ASV1,              asv1);
+    REGISTER_ENCDEC (ASV2,              asv2);
+    REGISTER_DECODER(AURA,              aura);
+    REGISTER_DECODER(AURA2,             aura2);
+    REGISTER_ENCDEC (AVRP,              avrp);
+    REGISTER_DECODER(AVRN,              avrn);
+    REGISTER_DECODER(AVS,               avs);
+    REGISTER_ENCDEC (AVUI,              avui);
+    REGISTER_ENCDEC (AYUV,              ayuv);
+    REGISTER_DECODER(BETHSOFTVID,       bethsoftvid);
+    REGISTER_DECODER(BFI,               bfi);
+    REGISTER_DECODER(BINK,              bink);
+    REGISTER_ENCDEC (BMP,               bmp);
+    REGISTER_DECODER(BMV_VIDEO,         bmv_video);
+    REGISTER_DECODER(BRENDER_PIX,       brender_pix);
+    REGISTER_DECODER(C93,               c93);
+    REGISTER_DECODER(CAVS,              cavs);
+    REGISTER_DECODER(CDGRAPHICS,        cdgraphics);
+    REGISTER_DECODER(CDXL,              cdxl);
+    REGISTER_DECODER(CINEPAK,           cinepak);
+    REGISTER_ENCDEC (CLJR,              cljr);
+    REGISTER_DECODER(CLLC,              cllc);
+    REGISTER_ENCDEC (COMFORTNOISE,      comfortnoise);
+    REGISTER_DECODER(CPIA,              cpia);
+    REGISTER_DECODER(CSCD,              cscd);
+    REGISTER_DECODER(CYUV,              cyuv);
+    REGISTER_DECODER(DFA,               dfa);
+    REGISTER_DECODER(DIRAC,             dirac);
+    REGISTER_ENCDEC (DNXHD,             dnxhd);
+    REGISTER_ENCDEC (DPX,               dpx);
+    REGISTER_DECODER(DSICINVIDEO,       dsicinvideo);
+    REGISTER_ENCDEC (DVVIDEO,           dvvideo);
+    REGISTER_DECODER(DXA,               dxa);
+    REGISTER_DECODER(DXTORY,            dxtory);
+    REGISTER_DECODER(EACMV,             eacmv);
+    REGISTER_DECODER(EAMAD,             eamad);
+    REGISTER_DECODER(EATGQ,             eatgq);
+    REGISTER_DECODER(EATGV,             eatgv);
+    REGISTER_DECODER(EATQI,             eatqi);
+    REGISTER_DECODER(EIGHTBPS,          eightbps);
+    REGISTER_DECODER(EIGHTSVX_EXP,      eightsvx_exp);
+    REGISTER_DECODER(EIGHTSVX_FIB,      eightsvx_fib);
+    REGISTER_DECODER(ESCAPE124,         escape124);
+    REGISTER_DECODER(ESCAPE130,         escape130);
+    REGISTER_DECODER(EXR,               exr);
+    REGISTER_ENCDEC (FFV1,              ffv1);
+    REGISTER_ENCDEC (FFVHUFF,           ffvhuff);
+    REGISTER_ENCDEC (FLASHSV,           flashsv);
+    REGISTER_ENCDEC (FLASHSV2,          flashsv2);
+    REGISTER_DECODER(FLIC,              flic);
+    REGISTER_ENCDEC (FLV,               flv);
+    REGISTER_DECODER(FOURXM,            fourxm);
+    REGISTER_DECODER(FRAPS,             fraps);
+    REGISTER_DECODER(FRWU,              frwu);
+    REGISTER_ENCDEC (GIF,               gif);
+    REGISTER_ENCDEC (H261,              h261);
+    REGISTER_ENCDEC (H263,              h263);
+    REGISTER_DECODER(H263I,             h263i);
+    REGISTER_ENCDEC (H263P,             h263p);
+    REGISTER_DECODER(H264,              h264);
+    REGISTER_DECODER(H264_CRYSTALHD,    h264_crystalhd);
+    REGISTER_DECODER(H264_VDA,          h264_vda);
+    REGISTER_DECODER(H264_VDPAU,        h264_vdpau);
+    REGISTER_ENCDEC (HUFFYUV,           huffyuv);
+    REGISTER_DECODER(IDCIN,             idcin);
+    REGISTER_DECODER(IFF_BYTERUN1,      iff_byterun1);
+    REGISTER_DECODER(IFF_ILBM,          iff_ilbm);
+    REGISTER_DECODER(INDEO2,            indeo2);
+    REGISTER_DECODER(INDEO3,            indeo3);
+    REGISTER_DECODER(INDEO4,            indeo4);
+    REGISTER_DECODER(INDEO5,            indeo5);
+    REGISTER_DECODER(INTERPLAY_VIDEO,   interplay_video);
+    REGISTER_ENCDEC (JPEG2000,          jpeg2000);
+    REGISTER_ENCDEC (JPEGLS,            jpegls);
+    REGISTER_DECODER(JV,                jv);
+    REGISTER_DECODER(KGV1,              kgv1);
+    REGISTER_DECODER(KMVC,              kmvc);
+    REGISTER_DECODER(LAGARITH,          lagarith);
+    REGISTER_ENCODER(LJPEG,             ljpeg);
+    REGISTER_DECODER(LOCO,              loco);
+    REGISTER_DECODER(MDEC,              mdec);
+    REGISTER_DECODER(MIMIC,             mimic);
+    REGISTER_ENCDEC (MJPEG,             mjpeg);
+    REGISTER_DECODER(MJPEGB,            mjpegb);
+    REGISTER_DECODER(MMVIDEO,           mmvideo);
+    REGISTER_DECODER(MOTIONPIXELS,      motionpixels);
+    REGISTER_DECODER(MPEG_XVMC,         mpeg_xvmc);
+    REGISTER_ENCDEC (MPEG1VIDEO,        mpeg1video);
+    REGISTER_ENCDEC (MPEG2VIDEO,        mpeg2video);
+    REGISTER_ENCDEC (MPEG4,             mpeg4);
+    REGISTER_DECODER(MPEG4_CRYSTALHD,   mpeg4_crystalhd);
+    REGISTER_DECODER(MPEG4_VDPAU,       mpeg4_vdpau);
+    REGISTER_DECODER(MPEGVIDEO,         mpegvideo);
+    REGISTER_DECODER(MPEG_VDPAU,        mpeg_vdpau);
+    REGISTER_DECODER(MPEG1_VDPAU,       mpeg1_vdpau);
+    REGISTER_DECODER(MPEG2_CRYSTALHD,   mpeg2_crystalhd);
+    REGISTER_DECODER(MSA1,              msa1);
+    REGISTER_DECODER(MSMPEG4_CRYSTALHD, msmpeg4_crystalhd);
+    REGISTER_DECODER(MSMPEG4V1,         msmpeg4v1);
+    REGISTER_ENCDEC (MSMPEG4V2,         msmpeg4v2);
+    REGISTER_ENCDEC (MSMPEG4V3,         msmpeg4v3);
+    REGISTER_DECODER(MSRLE,             msrle);
+    REGISTER_DECODER(MSS1,              mss1);
+    REGISTER_DECODER(MSS2,              mss2);
+    REGISTER_ENCDEC (MSVIDEO1,          msvideo1);
+    REGISTER_DECODER(MSZH,              mszh);
+    REGISTER_DECODER(MTS2,              mts2);
+    REGISTER_DECODER(MVC1,              mvc1);
+    REGISTER_DECODER(MVC2,              mvc2);
+    REGISTER_DECODER(MXPEG,             mxpeg);
+    REGISTER_DECODER(NUV,               nuv);
+    REGISTER_DECODER(PAF_VIDEO,         paf_video);
+    REGISTER_ENCDEC (PAM,               pam);
+    REGISTER_ENCDEC (PBM,               pbm);
+    REGISTER_ENCDEC (PCX,               pcx);
+    REGISTER_ENCDEC (PGM,               pgm);
+    REGISTER_ENCDEC (PGMYUV,            pgmyuv);
+    REGISTER_DECODER(PICTOR,            pictor);
+    REGISTER_ENCDEC (PNG,               png);
+    REGISTER_ENCDEC (PPM,               ppm);
+    REGISTER_ENCDEC (PRORES,            prores);
+    REGISTER_ENCODER(PRORES_ANATOLIY,   prores_anatoliy);
+    REGISTER_ENCODER(PRORES_KOSTYA,     prores_kostya);
+    REGISTER_DECODER(PRORES_LGPL,       prores_lgpl);
+    REGISTER_DECODER(PTX,               ptx);
+    REGISTER_DECODER(QDRAW,             qdraw);
+    REGISTER_DECODER(QPEG,              qpeg);
+    REGISTER_ENCDEC (QTRLE,             qtrle);
+    REGISTER_ENCDEC (R10K,              r10k);
+    REGISTER_ENCDEC (R210,              r210);
+    REGISTER_ENCDEC (RAWVIDEO,          rawvideo);
+    REGISTER_DECODER(RL2,               rl2);
+    REGISTER_ENCDEC (ROQ,               roq);
+    REGISTER_DECODER(RPZA,              rpza);
+    REGISTER_ENCDEC (RV10,              rv10);
+    REGISTER_ENCDEC (RV20,              rv20);
+    REGISTER_DECODER(RV30,              rv30);
+    REGISTER_DECODER(RV40,              rv40);
+    REGISTER_DECODER(S302M,             s302m);
+    REGISTER_DECODER(SANM,              sanm);
+    REGISTER_ENCDEC (SGI,               sgi);
+    REGISTER_DECODER(SGIRLE,            sgirle);
+    REGISTER_DECODER(SMACKER,           smacker);
+    REGISTER_DECODER(SMC,               smc);
+    REGISTER_ENCDEC (SNOW,              snow);
+    REGISTER_DECODER(SP5X,              sp5x);
+    REGISTER_ENCDEC (SUNRAST,           sunrast);
+    REGISTER_ENCDEC (SVQ1,              svq1);
+    REGISTER_DECODER(SVQ3,              svq3);
+    REGISTER_ENCDEC (TARGA,             targa);
+    REGISTER_DECODER(TARGA_Y216,        targa_y216);
+    REGISTER_DECODER(THEORA,            theora);
+    REGISTER_DECODER(THP,               thp);
+    REGISTER_DECODER(TIERTEXSEQVIDEO,   tiertexseqvideo);
+    REGISTER_ENCDEC (TIFF,              tiff);
+    REGISTER_DECODER(TMV,               tmv);
+    REGISTER_DECODER(TRUEMOTION1,       truemotion1);
+    REGISTER_DECODER(TRUEMOTION2,       truemotion2);
+    REGISTER_DECODER(TSCC,              tscc);
+    REGISTER_DECODER(TSCC2,             tscc2);
+    REGISTER_DECODER(TXD,               txd);
+    REGISTER_DECODER(ULTI,              ulti);
+    REGISTER_ENCDEC (UTVIDEO,           utvideo);
+    REGISTER_ENCDEC (V210,              v210);
+    REGISTER_DECODER(V210X,             v210x);
+    REGISTER_ENCDEC (V308,              v308);
+    REGISTER_ENCDEC (V408,              v408);
+    REGISTER_ENCDEC (V410,              v410);
+    REGISTER_DECODER(VB,                vb);
+    REGISTER_DECODER(VBLE,              vble);
+    REGISTER_DECODER(VC1,               vc1);
+    REGISTER_DECODER(VC1_CRYSTALHD,     vc1_crystalhd);
+    REGISTER_DECODER(VC1_VDPAU,         vc1_vdpau);
+    REGISTER_DECODER(VC1IMAGE,          vc1image);
+    REGISTER_DECODER(VCR1,              vcr1);
+    REGISTER_DECODER(VMDVIDEO,          vmdvideo);
+    REGISTER_DECODER(VMNC,              vmnc);
+    REGISTER_DECODER(VP3,               vp3);
+    REGISTER_DECODER(VP5,               vp5);
+    REGISTER_DECODER(VP6,               vp6);
+    REGISTER_DECODER(VP6A,              vp6a);
+    REGISTER_DECODER(VP6F,              vp6f);
+    REGISTER_DECODER(VP8,               vp8);
+    REGISTER_DECODER(VQA,               vqa);
+    REGISTER_ENCDEC (WMV1,              wmv1);
+    REGISTER_ENCDEC (WMV2,              wmv2);
+    REGISTER_DECODER(WMV3,              wmv3);
+    REGISTER_DECODER(WMV3_CRYSTALHD,    wmv3_crystalhd);
+    REGISTER_DECODER(WMV3_VDPAU,        wmv3_vdpau);
+    REGISTER_DECODER(WMV3IMAGE,         wmv3image);
+    REGISTER_DECODER(WNV1,              wnv1);
+    REGISTER_DECODER(XAN_WC3,           xan_wc3);
+    REGISTER_DECODER(XAN_WC4,           xan_wc4);
+    REGISTER_ENCDEC (XBM,               xbm);
+    REGISTER_ENCDEC (XFACE,             xface);
+    REGISTER_DECODER(XL,                xl);
+    REGISTER_ENCDEC (XWD,               xwd);
+    REGISTER_ENCDEC (Y41P,              y41p);
+    REGISTER_DECODER(YOP,               yop);
+    REGISTER_ENCDEC (YUV4,              yuv4);
+    REGISTER_DECODER(ZERO12V,           zero12v);
+    REGISTER_DECODER(ZEROCODEC,         zerocodec);
+    REGISTER_ENCDEC (ZLIB,              zlib);
+    REGISTER_ENCDEC (ZMBV,              zmbv);
 
     /* audio codecs */
-    REGISTER_ENCDEC  (AAC, aac);
-    REGISTER_DECODER (AAC_LATM, aac_latm);
-    REGISTER_ENCDEC  (AC3, ac3);
-    REGISTER_ENCODER (AC3_FIXED, ac3_fixed);
-    REGISTER_ENCDEC  (ALAC, alac);
-    REGISTER_DECODER (ALS, als);
-    REGISTER_DECODER (AMRNB, amrnb);
-    REGISTER_DECODER (AMRWB, amrwb);
-    REGISTER_DECODER (APE, ape);
-    REGISTER_DECODER (ATRAC1, atrac1);
-    REGISTER_DECODER (ATRAC3, atrac3);
-    REGISTER_DECODER (BINKAUDIO_DCT, binkaudio_dct);
-    REGISTER_DECODER (BINKAUDIO_RDFT, binkaudio_rdft);
-    REGISTER_DECODER (BMV_AUDIO, bmv_audio);
-    REGISTER_DECODER (COOK, cook);
-    REGISTER_ENCDEC  (DCA, dca);
-    REGISTER_DECODER (DSICINAUDIO, dsicinaudio);
-    REGISTER_ENCDEC  (EAC3, eac3);
-    REGISTER_DECODER (FFWAVESYNTH, ffwavesynth);
-    REGISTER_ENCDEC  (FLAC, flac);
-    REGISTER_ENCDEC  (G723_1, g723_1);
-    REGISTER_DECODER (G729, g729);
-    REGISTER_DECODER (GSM, gsm);
-    REGISTER_DECODER (GSM_MS, gsm_ms);
-    REGISTER_DECODER (IAC, iac);
-    REGISTER_DECODER (IMC, imc);
-    REGISTER_DECODER (MACE3, mace3);
-    REGISTER_DECODER (MACE6, mace6);
-    REGISTER_DECODER (MLP, mlp);
-    REGISTER_DECODER (MP1, mp1);
-    REGISTER_DECODER (MP1FLOAT, mp1float);
-    REGISTER_ENCDEC  (MP2, mp2);
-    REGISTER_DECODER (MP2FLOAT, mp2float);
-    REGISTER_DECODER (MP3, mp3);
-    REGISTER_DECODER (MP3FLOAT, mp3float);
-    REGISTER_DECODER (MP3ADU, mp3adu);
-    REGISTER_DECODER (MP3ADUFLOAT, mp3adufloat);
-    REGISTER_DECODER (MP3ON4, mp3on4);
-    REGISTER_DECODER (MP3ON4FLOAT, mp3on4float);
-    REGISTER_DECODER (MPC7, mpc7);
-    REGISTER_DECODER (MPC8, mpc8);
-    REGISTER_ENCDEC  (NELLYMOSER, nellymoser);
-    REGISTER_DECODER (PAF_AUDIO, paf_audio);
-    REGISTER_DECODER (QCELP, qcelp);
-    REGISTER_DECODER (QDM2, qdm2);
-    REGISTER_ENCDEC  (RA_144, ra_144);
-    REGISTER_DECODER (RA_288, ra_288);
-    REGISTER_DECODER (RALF, ralf);
-    REGISTER_DECODER (SHORTEN, shorten);
-    REGISTER_DECODER (SIPR, sipr);
-    REGISTER_DECODER (SMACKAUD, smackaud);
-    REGISTER_ENCDEC  (SONIC, sonic);
-    REGISTER_ENCODER (SONIC_LS, sonic_ls);
-    REGISTER_DECODER (TAK, tak);
-    REGISTER_DECODER (TRUEHD, truehd);
-    REGISTER_DECODER (TRUESPEECH, truespeech);
-    REGISTER_DECODER (TTA, tta);
-    REGISTER_DECODER (TWINVQ, twinvq);
-    REGISTER_DECODER (VMDAUDIO, vmdaudio);
-    REGISTER_ENCDEC  (VORBIS, vorbis);
-    REGISTER_DECODER (WAVPACK, wavpack);
-    REGISTER_DECODER (WMALOSSLESS, wmalossless);
-    REGISTER_DECODER (WMAPRO, wmapro);
-    REGISTER_ENCDEC  (WMAV1, wmav1);
-    REGISTER_ENCDEC  (WMAV2, wmav2);
-    REGISTER_DECODER (WMAVOICE, wmavoice);
-    REGISTER_DECODER (WS_SND1, ws_snd1);
+    REGISTER_ENCDEC (AAC,               aac);
+    REGISTER_DECODER(AAC_LATM,          aac_latm);
+    REGISTER_ENCDEC (AC3,               ac3);
+    REGISTER_ENCODER(AC3_FIXED,         ac3_fixed);
+    REGISTER_ENCDEC (ALAC,              alac);
+    REGISTER_DECODER(ALS,               als);
+    REGISTER_DECODER(AMRNB,             amrnb);
+    REGISTER_DECODER(AMRWB,             amrwb);
+    REGISTER_DECODER(APE,               ape);
+    REGISTER_DECODER(ATRAC1,            atrac1);
+    REGISTER_DECODER(ATRAC3,            atrac3);
+    REGISTER_DECODER(BINKAUDIO_DCT,     binkaudio_dct);
+    REGISTER_DECODER(BINKAUDIO_RDFT,    binkaudio_rdft);
+    REGISTER_DECODER(BMV_AUDIO,         bmv_audio);
+    REGISTER_DECODER(COOK,              cook);
+    REGISTER_ENCDEC (DCA,               dca);
+    REGISTER_DECODER(DSICINAUDIO,       dsicinaudio);
+    REGISTER_ENCDEC (EAC3,              eac3);
+    REGISTER_DECODER(EVRC,              evrc);
+    REGISTER_DECODER(FFWAVESYNTH,       ffwavesynth);
+    REGISTER_ENCDEC (FLAC,              flac);
+    REGISTER_ENCDEC (G723_1,            g723_1);
+    REGISTER_DECODER(G729,              g729);
+    REGISTER_DECODER(GSM,               gsm);
+    REGISTER_DECODER(GSM_MS,            gsm_ms);
+    REGISTER_DECODER(IAC,               iac);
+    REGISTER_DECODER(IMC,               imc);
+    REGISTER_DECODER(MACE3,             mace3);
+    REGISTER_DECODER(MACE6,             mace6);
+    REGISTER_DECODER(MLP,               mlp);
+    REGISTER_DECODER(MP1,               mp1);
+    REGISTER_DECODER(MP1FLOAT,          mp1float);
+    REGISTER_ENCDEC (MP2,               mp2);
+    REGISTER_DECODER(MP2FLOAT,          mp2float);
+    REGISTER_DECODER(MP3,               mp3);
+    REGISTER_DECODER(MP3FLOAT,          mp3float);
+    REGISTER_DECODER(MP3ADU,            mp3adu);
+    REGISTER_DECODER(MP3ADUFLOAT,       mp3adufloat);
+    REGISTER_DECODER(MP3ON4,            mp3on4);
+    REGISTER_DECODER(MP3ON4FLOAT,       mp3on4float);
+    REGISTER_DECODER(MPC7,              mpc7);
+    REGISTER_DECODER(MPC8,              mpc8);
+    REGISTER_ENCDEC (NELLYMOSER,        nellymoser);
+    REGISTER_DECODER(PAF_AUDIO,         paf_audio);
+    REGISTER_DECODER(QCELP,             qcelp);
+    REGISTER_DECODER(QDM2,              qdm2);
+    REGISTER_ENCDEC (RA_144,            ra_144);
+    REGISTER_DECODER(RA_288,            ra_288);
+    REGISTER_DECODER(RALF,              ralf);
+    REGISTER_DECODER(SHORTEN,           shorten);
+    REGISTER_DECODER(SIPR,              sipr);
+    REGISTER_DECODER(SMACKAUD,          smackaud);
+    REGISTER_ENCDEC (SONIC,             sonic);
+    REGISTER_ENCODER(SONIC_LS,          sonic_ls);
+    REGISTER_DECODER(TAK,               tak);
+    REGISTER_DECODER(TRUEHD,            truehd);
+    REGISTER_DECODER(TRUESPEECH,        truespeech);
+    REGISTER_DECODER(TTA,               tta);
+    REGISTER_DECODER(TWINVQ,            twinvq);
+    REGISTER_DECODER(VMDAUDIO,          vmdaudio);
+    REGISTER_ENCDEC (VORBIS,            vorbis);
+    REGISTER_DECODER(WAVPACK,           wavpack);
+    REGISTER_DECODER(WMALOSSLESS,       wmalossless);
+    REGISTER_DECODER(WMAPRO,            wmapro);
+    REGISTER_ENCDEC (WMAV1,             wmav1);
+    REGISTER_ENCDEC (WMAV2,             wmav2);
+    REGISTER_DECODER(WMAVOICE,          wmavoice);
+    REGISTER_DECODER(WS_SND1,           ws_snd1);
 
     /* PCM codecs */
-    REGISTER_ENCDEC  (PCM_ALAW, pcm_alaw);
-    REGISTER_DECODER (PCM_BLURAY, pcm_bluray);
-    REGISTER_DECODER (PCM_DVD, pcm_dvd);
-    REGISTER_ENCDEC  (PCM_F32BE, pcm_f32be);
-    REGISTER_ENCDEC  (PCM_F32LE, pcm_f32le);
-    REGISTER_ENCDEC  (PCM_F64BE, pcm_f64be);
-    REGISTER_ENCDEC  (PCM_F64LE, pcm_f64le);
-    REGISTER_DECODER (PCM_LXF, pcm_lxf);
-    REGISTER_ENCDEC  (PCM_MULAW, pcm_mulaw);
-    REGISTER_ENCDEC  (PCM_S8, pcm_s8);
-    REGISTER_ENCDEC  (PCM_S8_PLANAR, pcm_s8_planar);
-    REGISTER_ENCDEC  (PCM_S16BE, pcm_s16be);
-    REGISTER_ENCDEC  (PCM_S16BE_PLANAR, pcm_s16be_planar);
-    REGISTER_ENCDEC  (PCM_S16LE, pcm_s16le);
-    REGISTER_ENCDEC  (PCM_S16LE_PLANAR, pcm_s16le_planar);
-    REGISTER_ENCDEC  (PCM_S24BE, pcm_s24be);
-    REGISTER_ENCDEC  (PCM_S24DAUD, pcm_s24daud);
-    REGISTER_ENCDEC  (PCM_S24LE, pcm_s24le);
-    REGISTER_ENCDEC  (PCM_S24LE_PLANAR, pcm_s24le_planar);
-    REGISTER_ENCDEC  (PCM_S32BE, pcm_s32be);
-    REGISTER_ENCDEC  (PCM_S32LE, pcm_s32le);
-    REGISTER_ENCDEC  (PCM_S32LE_PLANAR, pcm_s32le_planar);
-    REGISTER_ENCDEC  (PCM_U8, pcm_u8);
-    REGISTER_ENCDEC  (PCM_U16BE, pcm_u16be);
-    REGISTER_ENCDEC  (PCM_U16LE, pcm_u16le);
-    REGISTER_ENCDEC  (PCM_U24BE, pcm_u24be);
-    REGISTER_ENCDEC  (PCM_U24LE, pcm_u24le);
-    REGISTER_ENCDEC  (PCM_U32BE, pcm_u32be);
-    REGISTER_ENCDEC  (PCM_U32LE, pcm_u32le);
-    REGISTER_DECODER (PCM_ZORK , pcm_zork);
+    REGISTER_ENCDEC (PCM_ALAW,          pcm_alaw);
+    REGISTER_DECODER(PCM_BLURAY,        pcm_bluray);
+    REGISTER_DECODER(PCM_DVD,           pcm_dvd);
+    REGISTER_ENCDEC (PCM_F32BE,         pcm_f32be);
+    REGISTER_ENCDEC (PCM_F32LE,         pcm_f32le);
+    REGISTER_ENCDEC (PCM_F64BE,         pcm_f64be);
+    REGISTER_ENCDEC (PCM_F64LE,         pcm_f64le);
+    REGISTER_DECODER(PCM_LXF,           pcm_lxf);
+    REGISTER_ENCDEC (PCM_MULAW,         pcm_mulaw);
+    REGISTER_ENCDEC (PCM_S8,            pcm_s8);
+    REGISTER_ENCDEC (PCM_S8_PLANAR,     pcm_s8_planar);
+    REGISTER_ENCDEC (PCM_S16BE,         pcm_s16be);
+    REGISTER_ENCDEC (PCM_S16BE_PLANAR,  pcm_s16be_planar);
+    REGISTER_ENCDEC (PCM_S16LE,         pcm_s16le);
+    REGISTER_ENCDEC (PCM_S16LE_PLANAR,  pcm_s16le_planar);
+    REGISTER_ENCDEC (PCM_S24BE,         pcm_s24be);
+    REGISTER_ENCDEC (PCM_S24DAUD,       pcm_s24daud);
+    REGISTER_ENCDEC (PCM_S24LE,         pcm_s24le);
+    REGISTER_ENCDEC (PCM_S24LE_PLANAR,  pcm_s24le_planar);
+    REGISTER_ENCDEC (PCM_S32BE,         pcm_s32be);
+    REGISTER_ENCDEC (PCM_S32LE,         pcm_s32le);
+    REGISTER_ENCDEC (PCM_S32LE_PLANAR,  pcm_s32le_planar);
+    REGISTER_ENCDEC (PCM_U8,            pcm_u8);
+    REGISTER_ENCDEC (PCM_U16BE,         pcm_u16be);
+    REGISTER_ENCDEC (PCM_U16LE,         pcm_u16le);
+    REGISTER_ENCDEC (PCM_U24BE,         pcm_u24be);
+    REGISTER_ENCDEC (PCM_U24LE,         pcm_u24le);
+    REGISTER_ENCDEC (PCM_U32BE,         pcm_u32be);
+    REGISTER_ENCDEC (PCM_U32LE,         pcm_u32le);
+    REGISTER_DECODER(PCM_ZORK,          pcm_zork);
 
     /* DPCM codecs */
-    REGISTER_DECODER (INTERPLAY_DPCM, interplay_dpcm);
-    REGISTER_ENCDEC  (ROQ_DPCM, roq_dpcm);
-    REGISTER_DECODER (SOL_DPCM, sol_dpcm);
-    REGISTER_DECODER (XAN_DPCM, xan_dpcm);
+    REGISTER_DECODER(INTERPLAY_DPCM,    interplay_dpcm);
+    REGISTER_ENCDEC (ROQ_DPCM,          roq_dpcm);
+    REGISTER_DECODER(SOL_DPCM,          sol_dpcm);
+    REGISTER_DECODER(XAN_DPCM,          xan_dpcm);
 
     /* ADPCM codecs */
-    REGISTER_DECODER (ADPCM_4XM, adpcm_4xm);
-    REGISTER_ENCDEC  (ADPCM_ADX, adpcm_adx);
-    REGISTER_DECODER (ADPCM_AFC, adpcm_afc);
-    REGISTER_DECODER (ADPCM_CT, adpcm_ct);
-    REGISTER_DECODER (ADPCM_EA, adpcm_ea);
-    REGISTER_DECODER (ADPCM_EA_MAXIS_XA, adpcm_ea_maxis_xa);
-    REGISTER_DECODER (ADPCM_EA_R1, adpcm_ea_r1);
-    REGISTER_DECODER (ADPCM_EA_R2, adpcm_ea_r2);
-    REGISTER_DECODER (ADPCM_EA_R3, adpcm_ea_r3);
-    REGISTER_DECODER (ADPCM_EA_XAS, adpcm_ea_xas);
-    REGISTER_ENCDEC  (ADPCM_G722, adpcm_g722);
-    REGISTER_ENCDEC  (ADPCM_G726, adpcm_g726);
-    REGISTER_DECODER (ADPCM_IMA_AMV, adpcm_ima_amv);
-    REGISTER_DECODER (ADPCM_IMA_APC, adpcm_ima_apc);
-    REGISTER_DECODER (ADPCM_IMA_DK3, adpcm_ima_dk3);
-    REGISTER_DECODER (ADPCM_IMA_DK4, adpcm_ima_dk4);
-    REGISTER_DECODER (ADPCM_IMA_EA_EACS, adpcm_ima_ea_eacs);
-    REGISTER_DECODER (ADPCM_IMA_EA_SEAD, adpcm_ima_ea_sead);
-    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_SMJPEG, adpcm_ima_smjpeg);
-    REGISTER_ENCDEC  (ADPCM_IMA_WAV, adpcm_ima_wav);
-    REGISTER_DECODER (ADPCM_IMA_WS, adpcm_ima_ws);
-    REGISTER_ENCDEC  (ADPCM_MS, adpcm_ms);
-    REGISTER_DECODER (ADPCM_SBPRO_2, adpcm_sbpro_2);
-    REGISTER_DECODER (ADPCM_SBPRO_3, adpcm_sbpro_3);
-    REGISTER_DECODER (ADPCM_SBPRO_4, adpcm_sbpro_4);
-    REGISTER_ENCDEC  (ADPCM_SWF, adpcm_swf);
-    REGISTER_DECODER (ADPCM_THP, adpcm_thp);
-    REGISTER_DECODER (ADPCM_XA, adpcm_xa);
-    REGISTER_ENCDEC  (ADPCM_YAMAHA, adpcm_yamaha);
-    REGISTER_DECODER (VIMA, vima);
+    REGISTER_DECODER(ADPCM_4XM,         adpcm_4xm);
+    REGISTER_ENCDEC (ADPCM_ADX,         adpcm_adx);
+    REGISTER_DECODER(ADPCM_AFC,         adpcm_afc);
+    REGISTER_DECODER(ADPCM_CT,          adpcm_ct);
+    REGISTER_DECODER(ADPCM_EA,          adpcm_ea);
+    REGISTER_DECODER(ADPCM_EA_MAXIS_XA, adpcm_ea_maxis_xa);
+    REGISTER_DECODER(ADPCM_EA_R1,       adpcm_ea_r1);
+    REGISTER_DECODER(ADPCM_EA_R2,       adpcm_ea_r2);
+    REGISTER_DECODER(ADPCM_EA_R3,       adpcm_ea_r3);
+    REGISTER_DECODER(ADPCM_EA_XAS,      adpcm_ea_xas);
+    REGISTER_ENCDEC (ADPCM_G722,        adpcm_g722);
+    REGISTER_ENCDEC (ADPCM_G726,        adpcm_g726);
+    REGISTER_DECODER(ADPCM_IMA_AMV,     adpcm_ima_amv);
+    REGISTER_DECODER(ADPCM_IMA_APC,     adpcm_ima_apc);
+    REGISTER_DECODER(ADPCM_IMA_DK3,     adpcm_ima_dk3);
+    REGISTER_DECODER(ADPCM_IMA_DK4,     adpcm_ima_dk4);
+    REGISTER_DECODER(ADPCM_IMA_EA_EACS, adpcm_ima_ea_eacs);
+    REGISTER_DECODER(ADPCM_IMA_EA_SEAD, adpcm_ima_ea_sead);
+    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_SMJPEG,  adpcm_ima_smjpeg);
+    REGISTER_ENCDEC (ADPCM_IMA_WAV,     adpcm_ima_wav);
+    REGISTER_DECODER(ADPCM_IMA_WS,      adpcm_ima_ws);
+    REGISTER_ENCDEC (ADPCM_MS,          adpcm_ms);
+    REGISTER_DECODER(ADPCM_SBPRO_2,     adpcm_sbpro_2);
+    REGISTER_DECODER(ADPCM_SBPRO_3,     adpcm_sbpro_3);
+    REGISTER_DECODER(ADPCM_SBPRO_4,     adpcm_sbpro_4);
+    REGISTER_ENCDEC (ADPCM_SWF,         adpcm_swf);
+    REGISTER_DECODER(ADPCM_THP,         adpcm_thp);
+    REGISTER_DECODER(ADPCM_XA,          adpcm_xa);
+    REGISTER_ENCDEC (ADPCM_YAMAHA,      adpcm_yamaha);
+    REGISTER_DECODER(VIMA,              vima);
 
     /* subtitles */
-    REGISTER_ENCDEC  (ASS, ass);
-    REGISTER_ENCDEC  (DVBSUB, dvbsub);
-    REGISTER_ENCDEC  (DVDSUB, dvdsub);
-    REGISTER_DECODER (JACOSUB, jacosub);
-    REGISTER_DECODER (MICRODVD, microdvd);
-    REGISTER_ENCDEC  (MOVTEXT, movtext);
-    REGISTER_DECODER (PGSSUB, pgssub);
-    REGISTER_DECODER (REALTEXT, realtext);
-    REGISTER_DECODER (SAMI, sami);
-    REGISTER_ENCDEC  (SRT, srt);
-    REGISTER_ENCDEC  (SUBRIP, subrip);
-    REGISTER_DECODER (SUBVIEWER, subviewer);
-    REGISTER_DECODER (TEXT, text);
-    REGISTER_DECODER (WEBVTT, webvtt);
-    REGISTER_ENCDEC  (XSUB, xsub);
+    REGISTER_ENCDEC (ASS,               ass);
+    REGISTER_ENCDEC (DVBSUB,            dvbsub);
+    REGISTER_ENCDEC (DVDSUB,            dvdsub);
+    REGISTER_DECODER(JACOSUB,           jacosub);
+    REGISTER_DECODER(MICRODVD,          microdvd);
+    REGISTER_ENCDEC (MOVTEXT,           movtext);
+    REGISTER_DECODER(MPL2,              mpl2);
+    REGISTER_DECODER(PGSSUB,            pgssub);
+    REGISTER_DECODER(PJS,               pjs);
+    REGISTER_DECODER(REALTEXT,          realtext);
+    REGISTER_DECODER(SAMI,              sami);
+    REGISTER_ENCDEC (SRT,               srt);
+    REGISTER_ENCDEC (SUBRIP,            subrip);
+    REGISTER_DECODER(SUBVIEWER,         subviewer);
+    REGISTER_DECODER(SUBVIEWER1,        subviewer1);
+    REGISTER_DECODER(TEXT,              text);
+    REGISTER_DECODER(VPLAYER,           vplayer);
+    REGISTER_DECODER(WEBVTT,            webvtt);
+    REGISTER_ENCDEC (XSUB,              xsub);
 
     /* external libraries */
-    REGISTER_DECODER (LIBCELT, libcelt);
-    REGISTER_ENCODER (LIBFAAC, libfaac);
-    REGISTER_ENCODER (LIBFDK_AAC, libfdk_aac);
-    REGISTER_ENCDEC  (LIBGSM, libgsm);
-    REGISTER_ENCDEC  (LIBGSM_MS, libgsm_ms);
-    REGISTER_ENCDEC  (LIBILBC, libilbc);
-    REGISTER_ENCODER (LIBMP3LAME, libmp3lame);
-    REGISTER_ENCDEC  (LIBOPENCORE_AMRNB, libopencore_amrnb);
-    REGISTER_DECODER (LIBOPENCORE_AMRWB, libopencore_amrwb);
-    REGISTER_ENCDEC  (LIBOPENJPEG, libopenjpeg);
-    REGISTER_ENCDEC  (LIBOPUS, libopus);
-    REGISTER_ENCDEC  (LIBSCHROEDINGER, libschroedinger);
-    REGISTER_ENCDEC  (LIBSPEEX, libspeex);
-    REGISTER_DECODER (LIBSTAGEFRIGHT_H264, libstagefright_h264);
-    REGISTER_ENCODER (LIBTHEORA, libtheora);
-    REGISTER_ENCODER (LIBTWOLAME, libtwolame);
-    REGISTER_ENCDEC  (LIBUTVIDEO, libutvideo);
-    REGISTER_ENCODER (LIBVO_AACENC, libvo_aacenc);
-    REGISTER_ENCODER (LIBVO_AMRWBENC, libvo_amrwbenc);
-    REGISTER_ENCDEC  (LIBVORBIS, libvorbis);
-    REGISTER_ENCDEC  (LIBVPX, libvpx);
-    REGISTER_ENCODER (LIBX264, libx264);
-    REGISTER_ENCODER (LIBX264RGB, libx264rgb);
-    REGISTER_ENCODER (LIBXAVS, libxavs);
-    REGISTER_ENCODER (LIBXVID, libxvid);
-    REGISTER_ENCODER (LIBAACPLUS, libaacplus);
+    REGISTER_DECODER(LIBCELT,           libcelt);
+    REGISTER_ENCODER(LIBFAAC,           libfaac);
+    REGISTER_ENCODER(LIBFDK_AAC,        libfdk_aac);
+    REGISTER_ENCDEC (LIBGSM,            libgsm);
+    REGISTER_ENCDEC (LIBGSM_MS,         libgsm_ms);
+    REGISTER_ENCDEC (LIBILBC,           libilbc);
+    REGISTER_ENCODER(LIBMP3LAME,        libmp3lame);
+    REGISTER_ENCDEC (LIBOPENCORE_AMRNB, libopencore_amrnb);
+    REGISTER_DECODER(LIBOPENCORE_AMRWB, libopencore_amrwb);
+    REGISTER_ENCDEC (LIBOPENJPEG,       libopenjpeg);
+    REGISTER_ENCDEC (LIBOPUS,           libopus);
+    REGISTER_ENCDEC (LIBSCHROEDINGER,   libschroedinger);
+    REGISTER_ENCDEC (LIBSPEEX,          libspeex);
+    REGISTER_DECODER(LIBSTAGEFRIGHT_H264, libstagefright_h264);
+    REGISTER_ENCODER(LIBTHEORA,         libtheora);
+    REGISTER_ENCODER(LIBTWOLAME,        libtwolame);
+    REGISTER_ENCDEC (LIBUTVIDEO,        libutvideo);
+    REGISTER_ENCODER(LIBVO_AACENC,      libvo_aacenc);
+    REGISTER_ENCODER(LIBVO_AMRWBENC,    libvo_amrwbenc);
+    REGISTER_ENCDEC (LIBVORBIS,         libvorbis);
+    REGISTER_ENCDEC (LIBVPX_VP8,        libvpx_vp8);
+    REGISTER_ENCDEC (LIBVPX_VP9,        libvpx_vp9);
+    REGISTER_ENCODER(LIBX264,           libx264);
+    REGISTER_ENCODER(LIBX264RGB,        libx264rgb);
+    REGISTER_ENCODER(LIBXAVS,           libxavs);
+    REGISTER_ENCODER(LIBXVID,           libxvid);
+    REGISTER_ENCODER(LIBAACPLUS,        libaacplus);
 
     /* text */
-    REGISTER_DECODER (BINTEXT, bintext);
-    REGISTER_DECODER (XBIN, xbin);
-    REGISTER_DECODER (IDF, idf);
+    REGISTER_DECODER(BINTEXT,           bintext);
+    REGISTER_DECODER(XBIN,              xbin);
+    REGISTER_DECODER(IDF,               idf);
 
     /* parsers */
-    REGISTER_PARSER  (AAC, aac);
-    REGISTER_PARSER  (AAC_LATM, aac_latm);
-    REGISTER_PARSER  (AC3, ac3);
-    REGISTER_PARSER  (ADX, adx);
-    REGISTER_PARSER  (BMP, bmp);
-    REGISTER_PARSER  (CAVSVIDEO, cavsvideo);
-    REGISTER_PARSER  (COOK, cook);
-    REGISTER_PARSER  (DCA, dca);
-    REGISTER_PARSER  (DIRAC, dirac);
-    REGISTER_PARSER  (DNXHD, dnxhd);
-    REGISTER_PARSER  (DVBSUB, dvbsub);
-    REGISTER_PARSER  (DVDSUB, dvdsub);
-    REGISTER_PARSER  (FLAC, flac);
-    REGISTER_PARSER  (GSM, gsm);
-    REGISTER_PARSER  (H261, h261);
-    REGISTER_PARSER  (H263, h263);
-    REGISTER_PARSER  (H264, h264);
-    REGISTER_PARSER  (MJPEG, mjpeg);
-    REGISTER_PARSER  (MLP, mlp);
-    REGISTER_PARSER  (MPEG4VIDEO, mpeg4video);
-    REGISTER_PARSER  (MPEGAUDIO, mpegaudio);
-    REGISTER_PARSER  (MPEGVIDEO, mpegvideo);
-    REGISTER_PARSER  (PNG, png);
-    REGISTER_PARSER  (PNM, pnm);
-    REGISTER_PARSER  (RV30, rv30);
-    REGISTER_PARSER  (RV40, rv40);
-    REGISTER_PARSER  (TAK, tak);
-    REGISTER_PARSER  (VC1, vc1);
-    REGISTER_PARSER  (VORBIS, vorbis);
-    REGISTER_PARSER  (VP3, vp3);
-    REGISTER_PARSER  (VP8, vp8);
+    REGISTER_PARSER(AAC,                aac);
+    REGISTER_PARSER(AAC_LATM,           aac_latm);
+    REGISTER_PARSER(AC3,                ac3);
+    REGISTER_PARSER(ADX,                adx);
+    REGISTER_PARSER(BMP,                bmp);
+    REGISTER_PARSER(CAVSVIDEO,          cavsvideo);
+    REGISTER_PARSER(COOK,               cook);
+    REGISTER_PARSER(DCA,                dca);
+    REGISTER_PARSER(DIRAC,              dirac);
+    REGISTER_PARSER(DNXHD,              dnxhd);
+    REGISTER_PARSER(DVBSUB,             dvbsub);
+    REGISTER_PARSER(DVDSUB,             dvdsub);
+    REGISTER_PARSER(FLAC,               flac);
+    REGISTER_PARSER(GSM,                gsm);
+    REGISTER_PARSER(H261,               h261);
+    REGISTER_PARSER(H263,               h263);
+    REGISTER_PARSER(H264,               h264);
+    REGISTER_PARSER(MJPEG,              mjpeg);
+    REGISTER_PARSER(MLP,                mlp);
+    REGISTER_PARSER(MPEG4VIDEO,         mpeg4video);
+    REGISTER_PARSER(MPEGAUDIO,          mpegaudio);
+    REGISTER_PARSER(MPEGVIDEO,          mpegvideo);
+    REGISTER_PARSER(PNG,                png);
+    REGISTER_PARSER(PNM,                pnm);
+    REGISTER_PARSER(RV30,               rv30);
+    REGISTER_PARSER(RV40,               rv40);
+    REGISTER_PARSER(TAK,                tak);
+    REGISTER_PARSER(VC1,                vc1);
+    REGISTER_PARSER(VORBIS,             vorbis);
+    REGISTER_PARSER(VP3,                vp3);
+    REGISTER_PARSER(VP8,                vp8);
 
     /* bitstream filters */
-    REGISTER_BSF     (AAC_ADTSTOASC, aac_adtstoasc);
-    REGISTER_BSF     (CHOMP, chomp);
-    REGISTER_BSF     (DUMP_EXTRADATA, dump_extradata);
-    REGISTER_BSF     (H264_MP4TOANNEXB, h264_mp4toannexb);
-    REGISTER_BSF     (IMX_DUMP_HEADER, imx_dump_header);
-    REGISTER_BSF     (MJPEG2JPEG, mjpeg2jpeg);
-    REGISTER_BSF     (MJPEGA_DUMP_HEADER, mjpega_dump_header);
-    REGISTER_BSF     (MP3_HEADER_COMPRESS, mp3_header_compress);
-    REGISTER_BSF     (MP3_HEADER_DECOMPRESS, mp3_header_decompress);
-    REGISTER_BSF     (MOV2TEXTSUB, mov2textsub);
-    REGISTER_BSF     (NOISE, noise);
-    REGISTER_BSF     (REMOVE_EXTRADATA, remove_extradata);
-    REGISTER_BSF     (TEXT2MOVSUB, text2movsub);
+    REGISTER_BSF(AAC_ADTSTOASC,         aac_adtstoasc);
+    REGISTER_BSF(CHOMP,                 chomp);
+    REGISTER_BSF(DUMP_EXTRADATA,        dump_extradata);
+    REGISTER_BSF(H264_MP4TOANNEXB,      h264_mp4toannexb);
+    REGISTER_BSF(IMX_DUMP_HEADER,       imx_dump_header);
+    REGISTER_BSF(MJPEG2JPEG,            mjpeg2jpeg);
+    REGISTER_BSF(MJPEGA_DUMP_HEADER,    mjpega_dump_header);
+    REGISTER_BSF(MP3_HEADER_COMPRESS,   mp3_header_compress);
+    REGISTER_BSF(MP3_HEADER_DECOMPRESS, mp3_header_decompress);
+    REGISTER_BSF(MOV2TEXTSUB,           mov2textsub);
+    REGISTER_BSF(NOISE,                 noise);
+    REGISTER_BSF(REMOVE_EXTRADATA,      remove_extradata);
+    REGISTER_BSF(TEXT2MOVSUB,           text2movsub);
 }
diff --git a/libavcodec/alpha/dsputil_alpha.c b/libavcodec/alpha/dsputil_alpha.c
index 38ac020..cb62665 100644
--- a/libavcodec/alpha/dsputil_alpha.c
+++ b/libavcodec/alpha/dsputil_alpha.c
@@ -19,20 +19,21 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavcodec/dsputil.h"
 #include "dsputil_alpha.h"
 #include "asm.h"
 
-void (*put_pixels_clamped_axp_p)(const DCTELEM *block, uint8_t *pixels,
+void (*put_pixels_clamped_axp_p)(const int16_t *block, uint8_t *pixels,
                                  int line_size);
-void (*add_pixels_clamped_axp_p)(const DCTELEM *block, uint8_t *pixels,
+void (*add_pixels_clamped_axp_p)(const int16_t *block, uint8_t *pixels,
                                  int line_size);
 
 #if 0
 /* These functions were the base for the optimized assembler routines,
    and remain here for documentation purposes.  */
-static void put_pixels_clamped_mvi(const DCTELEM *block, uint8_t *pixels,
-                                   int line_size)
+static void put_pixels_clamped_mvi(const int16_t *block, uint8_t *pixels,
+                                   ptrdiff_t line_size)
 {
     int i = 8;
     uint64_t clampmask = zap(-1, 0xaa); /* 0x00ff00ff00ff00ff */
@@ -55,8 +56,8 @@
     } while (--i);
 }
 
-void add_pixels_clamped_mvi(const DCTELEM *block, uint8_t *pixels,
-                            int line_size)
+void add_pixels_clamped_mvi(const int16_t *block, uint8_t *pixels,
+                            ptrdiff_t line_size)
 {
     int h = 8;
     /* Keep this function a leaf function by generating the constants
@@ -100,9 +101,9 @@
 }
 #endif
 
-static void clear_blocks_axp(DCTELEM *blocks) {
+static void clear_blocks_axp(int16_t *blocks) {
     uint64_t *p = (uint64_t *) blocks;
-    int n = sizeof(DCTELEM) * 6 * 64;
+    int n = sizeof(int16_t) * 6 * 64;
 
     do {
         p[0] = 0;
@@ -211,8 +212,8 @@
 
 #define MAKE_OP(OPNAME, SUFF, OPKIND, STORE)                                \
 static void OPNAME ## _pixels ## SUFF ## _axp                               \
-        (uint8_t *av_restrict block, const uint8_t *av_restrict pixels,           \
-         int line_size, int h)                                              \
+        (uint8_t *restrict block, const uint8_t *restrict pixels,           \
+         ptrdiff_t line_size, int h)                                        \
 {                                                                           \
     if ((size_t) pixels & 0x7) {                                            \
         OPKIND(uldq, STORE);                                                \
@@ -222,8 +223,8 @@
 }                                                                           \
                                                                             \
 static void OPNAME ## _pixels16 ## SUFF ## _axp                             \
-        (uint8_t *av_restrict block, const uint8_t *av_restrict pixels,           \
-         int line_size, int h)                                              \
+        (uint8_t *restrict block, const uint8_t *restrict pixels,           \
+         ptrdiff_t line_size, int h)                                        \
 {                                                                           \
     OPNAME ## _pixels ## SUFF ## _axp(block,     pixels,     line_size, h); \
     OPNAME ## _pixels ## SUFF ## _axp(block + 8, pixels + 8, line_size, h); \
@@ -262,13 +263,13 @@
 PIXOP(avg_no_rnd, STORE);
 
 static void put_pixels16_axp_asm(uint8_t *block, const uint8_t *pixels,
-                                 int line_size, int h)
+                                 ptrdiff_t line_size, int h)
 {
     put_pixels_axp_asm(block,     pixels,     line_size, h);
     put_pixels_axp_asm(block + 8, pixels + 8, line_size, h);
 }
 
-void ff_dsputil_init_alpha(DSPContext* c, AVCodecContext *avctx)
+av_cold void ff_dsputil_init_alpha(DSPContext *c, AVCodecContext *avctx)
 {
     const int high_bit_depth = avctx->bits_per_raw_sample > 8;
 
@@ -288,10 +289,10 @@
     c->avg_pixels_tab[0][2] = avg_pixels16_y2_axp;
     c->avg_pixels_tab[0][3] = avg_pixels16_xy2_axp;
 
-    c->avg_no_rnd_pixels_tab[0][0] = avg_no_rnd_pixels16_axp;
-    c->avg_no_rnd_pixels_tab[0][1] = avg_no_rnd_pixels16_x2_axp;
-    c->avg_no_rnd_pixels_tab[0][2] = avg_no_rnd_pixels16_y2_axp;
-    c->avg_no_rnd_pixels_tab[0][3] = avg_no_rnd_pixels16_xy2_axp;
+    c->avg_no_rnd_pixels_tab[0] = avg_no_rnd_pixels16_axp;
+    c->avg_no_rnd_pixels_tab[1] = avg_no_rnd_pixels16_x2_axp;
+    c->avg_no_rnd_pixels_tab[2] = avg_no_rnd_pixels16_y2_axp;
+    c->avg_no_rnd_pixels_tab[3] = avg_no_rnd_pixels16_xy2_axp;
 
     c->put_pixels_tab[1][0] = put_pixels_axp_asm;
     c->put_pixels_tab[1][1] = put_pixels_x2_axp;
@@ -308,11 +309,6 @@
     c->avg_pixels_tab[1][2] = avg_pixels_y2_axp;
     c->avg_pixels_tab[1][3] = avg_pixels_xy2_axp;
 
-    c->avg_no_rnd_pixels_tab[1][0] = avg_no_rnd_pixels_axp;
-    c->avg_no_rnd_pixels_tab[1][1] = avg_no_rnd_pixels_x2_axp;
-    c->avg_no_rnd_pixels_tab[1][2] = avg_no_rnd_pixels_y2_axp;
-    c->avg_no_rnd_pixels_tab[1][3] = avg_no_rnd_pixels_xy2_axp;
-
     c->clear_blocks = clear_blocks_axp;
     }
 
diff --git a/libavcodec/alpha/dsputil_alpha.h b/libavcodec/alpha/dsputil_alpha.h
index 4bc09a4..cf5ca3b 100644
--- a/libavcodec/alpha/dsputil_alpha.h
+++ b/libavcodec/alpha/dsputil_alpha.h
@@ -19,26 +19,27 @@
 #ifndef AVCODEC_ALPHA_DSPUTIL_ALPHA_H
 #define AVCODEC_ALPHA_DSPUTIL_ALPHA_H
 
-#include "libavcodec/dsputil.h"
+#include <stddef.h>
+#include <stdint.h>
 
-void ff_simple_idct_axp(DCTELEM *block);
-void ff_simple_idct_put_axp(uint8_t *dest, int line_size, DCTELEM *block);
-void ff_simple_idct_add_axp(uint8_t *dest, int line_size, DCTELEM *block);
+void ff_simple_idct_axp(int16_t *block);
+void ff_simple_idct_put_axp(uint8_t *dest, int line_size, int16_t *block);
+void ff_simple_idct_add_axp(uint8_t *dest, int line_size, int16_t *block);
 
 void put_pixels_axp_asm(uint8_t *block, const uint8_t *pixels,
-                        int line_size, int h);
-void put_pixels_clamped_mvi_asm(const DCTELEM *block, uint8_t *pixels,
+                        ptrdiff_t line_size, int h);
+void put_pixels_clamped_mvi_asm(const int16_t *block, uint8_t *pixels,
                                 int line_size);
-void add_pixels_clamped_mvi_asm(const DCTELEM *block, uint8_t *pixels,
+void add_pixels_clamped_mvi_asm(const int16_t *block, uint8_t *pixels,
                                 int line_size);
-extern void (*put_pixels_clamped_axp_p)(const DCTELEM *block, uint8_t *pixels,
+extern void (*put_pixels_clamped_axp_p)(const int16_t *block, uint8_t *pixels,
                                         int line_size);
-extern void (*add_pixels_clamped_axp_p)(const DCTELEM *block, uint8_t *pixels,
+extern void (*add_pixels_clamped_axp_p)(const int16_t *block, uint8_t *pixels,
                                         int line_size);
 
-void get_pixels_mvi(DCTELEM *av_restrict block,
-                    const uint8_t *av_restrict pixels, int line_size);
-void diff_pixels_mvi(DCTELEM *block, const uint8_t *s1, const uint8_t *s2,
+void get_pixels_mvi(int16_t *restrict block,
+                    const uint8_t *restrict pixels, int line_size);
+void diff_pixels_mvi(int16_t *block, const uint8_t *s1, const uint8_t *s2,
                      int stride);
 int pix_abs8x8_mvi(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h);
 int pix_abs16x16_mvi_asm(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h);
diff --git a/libavcodec/alpha/dsputil_alpha_asm.S b/libavcodec/alpha/dsputil_alpha_asm.S
index 32a8bc9..557ba57 100644
--- a/libavcodec/alpha/dsputil_alpha_asm.S
+++ b/libavcodec/alpha/dsputil_alpha_asm.S
@@ -135,7 +135,7 @@
         .end put_pixels_axp_asm
 
 /************************************************************************
- * void put_pixels_clamped_mvi_asm(const DCTELEM *block, uint8_t *pixels,
+ * void put_pixels_clamped_mvi_asm(const int16_t *block, uint8_t *pixels,
  *                                 int line_size)
  */
         .align 6
@@ -185,7 +185,7 @@
         .end put_pixels_clamped_mvi_asm
 
 /************************************************************************
- * void add_pixels_clamped_mvi_asm(const DCTELEM *block, uint8_t *pixels,
+ * void add_pixels_clamped_mvi_asm(const int16_t *block, uint8_t *pixels,
  *                                 int line_size)
  */
         .align 6
diff --git a/libavcodec/alpha/motion_est_alpha.c b/libavcodec/alpha/motion_est_alpha.c
index 927b25d..a7c33e4 100644
--- a/libavcodec/alpha/motion_est_alpha.c
+++ b/libavcodec/alpha/motion_est_alpha.c
@@ -19,12 +19,11 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavcodec/dsputil.h"
 #include "dsputil_alpha.h"
 #include "asm.h"
 
-void get_pixels_mvi(DCTELEM *av_restrict block,
-                    const uint8_t *av_restrict pixels, int line_size)
+void get_pixels_mvi(int16_t *restrict block,
+                    const uint8_t *restrict pixels, int line_size)
 {
     int h = 8;
 
@@ -40,7 +39,7 @@
     } while (--h);
 }
 
-void diff_pixels_mvi(DCTELEM *block, const uint8_t *s1, const uint8_t *s2,
+void diff_pixels_mvi(int16_t *block, const uint8_t *s1, const uint8_t *s2,
                      int stride) {
     int h = 8;
     uint64_t mask = 0x4040;
diff --git a/libavcodec/alpha/mpegvideo_alpha.c b/libavcodec/alpha/mpegvideo_alpha.c
index 28eca07..7ba0f2e 100644
--- a/libavcodec/alpha/mpegvideo_alpha.c
+++ b/libavcodec/alpha/mpegvideo_alpha.c
@@ -19,11 +19,11 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavcodec/dsputil.h"
+#include "libavutil/attributes.h"
 #include "libavcodec/mpegvideo.h"
 #include "asm.h"
 
-static void dct_unquantize_h263_axp(DCTELEM *block, int n_coeffs,
+static void dct_unquantize_h263_axp(int16_t *block, int n_coeffs,
                                     uint64_t qscale, uint64_t qadd)
 {
     uint64_t qmul = qscale << 1;
@@ -69,12 +69,12 @@
     }
 }
 
-static void dct_unquantize_h263_intra_axp(MpegEncContext *s, DCTELEM *block,
+static void dct_unquantize_h263_intra_axp(MpegEncContext *s, int16_t *block,
                                     int n, int qscale)
 {
     int n_coeffs;
     uint64_t qadd;
-    DCTELEM block0 = block[0];
+    int16_t block0 = block[0];
 
     if (!s->h263_aic) {
         if (n < 4)
@@ -96,14 +96,14 @@
     block[0] = block0;
 }
 
-static void dct_unquantize_h263_inter_axp(MpegEncContext *s, DCTELEM *block,
+static void dct_unquantize_h263_inter_axp(MpegEncContext *s, int16_t *block,
                                     int n, int qscale)
 {
     int n_coeffs = s->inter_scantable.raster_end[s->block_last_index[n]];
     dct_unquantize_h263_axp(block, n_coeffs, qscale, (qscale - 1) | 1);
 }
 
-void ff_MPV_common_init_axp(MpegEncContext *s)
+av_cold void ff_MPV_common_init_axp(MpegEncContext *s)
 {
     s->dct_unquantize_h263_intra = dct_unquantize_h263_intra_axp;
     s->dct_unquantize_h263_inter = dct_unquantize_h263_inter_axp;
diff --git a/libavcodec/alpha/simple_idct_alpha.c b/libavcodec/alpha/simple_idct_alpha.c
index 522efd2..3bd1b33 100644
--- a/libavcodec/alpha/simple_idct_alpha.c
+++ b/libavcodec/alpha/simple_idct_alpha.c
@@ -26,7 +26,6 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavcodec/dsputil.h"
 #include "dsputil_alpha.h"
 #include "asm.h"
 
@@ -44,7 +43,7 @@
 #define COL_SHIFT 20
 
 /* 0: all entries 0, 1: only first entry nonzero, 2: otherwise  */
-static inline int idct_row(DCTELEM *row)
+static inline int idct_row(int16_t *row)
 {
     int a0, a1, a2, a3, b0, b1, b2, b3, t;
     uint64_t l, r, t2;
@@ -152,7 +151,7 @@
     return 2;
 }
 
-static inline void idct_col(DCTELEM *col)
+static inline void idct_col(int16_t *col)
 {
     int a0, a1, a2, a3, b0, b1, b2, b3;
 
@@ -229,7 +228,7 @@
 
 /* If all rows but the first one are zero after row transformation,
    all rows will be identical after column transformation.  */
-static inline void idct_col2(DCTELEM *col)
+static inline void idct_col2(int16_t *col)
 {
     int i;
     uint64_t l, r;
@@ -251,7 +250,7 @@
     stq(l, col + 14 * 4); stq(r, col + 15 * 4);
 }
 
-void ff_simple_idct_axp(DCTELEM *block)
+void ff_simple_idct_axp(int16_t *block)
 {
 
     int i;
@@ -291,13 +290,13 @@
     }
 }
 
-void ff_simple_idct_put_axp(uint8_t *dest, int line_size, DCTELEM *block)
+void ff_simple_idct_put_axp(uint8_t *dest, int line_size, int16_t *block)
 {
     ff_simple_idct_axp(block);
     put_pixels_clamped_axp_p(block, dest, line_size);
 }
 
-void ff_simple_idct_add_axp(uint8_t *dest, int line_size, DCTELEM *block)
+void ff_simple_idct_add_axp(uint8_t *dest, int line_size, int16_t *block)
 {
     ff_simple_idct_axp(block);
     add_pixels_clamped_axp_p(block, dest, line_size);
diff --git a/libavcodec/alsdec.c b/libavcodec/alsdec.c
index 69e66d6..a6d70d4 100644
--- a/libavcodec/alsdec.c
+++ b/libavcodec/alsdec.c
@@ -36,6 +36,7 @@
 #include "bytestream.h"
 #include "bgmc.h"
 #include "dsputil.h"
+#include "internal.h"
 #include "libavutil/samplefmt.h"
 #include "libavutil/crc.h"
 
@@ -191,7 +192,6 @@
 
 typedef struct {
     AVCodecContext *avctx;
-    AVFrame frame;
     ALSSpecificConfig sconf;
     GetBitContext gb;
     DSPContext dsp;
@@ -201,6 +201,7 @@
     unsigned int cur_frame_length;  ///< length of the current frame to decode
     unsigned int frame_id;          ///< the frame ID / number of the current frame
     unsigned int js_switch;         ///< if true, joint-stereo decoding is enforced
+    unsigned int cs_switch;         ///< if true, channel rearrangement is done
     unsigned int num_blocks;        ///< number of blocks used in the current frame
     unsigned int s_max;             ///< maximum Rice parameter allowed in entropy coding
     uint8_t *bgmc_lut;              ///< pointer at lookup tables used for BGMC
@@ -287,8 +288,10 @@
     ALSSpecificConfig *sconf = &ctx->sconf;
     AVCodecContext *avctx    = ctx->avctx;
     uint32_t als_id, header_size, trailer_size;
+    int ret;
 
-    init_get_bits(&gb, avctx->extradata, avctx->extradata_size * 8);
+    if ((ret = init_get_bits8(&gb, avctx->extradata, avctx->extradata_size)) < 0)
+        return ret;
 
     config_offset = avpriv_mpeg4audio_get_config(&m4ac, avctx->extradata,
                                                  avctx->extradata_size * 8, 1);
@@ -307,7 +310,7 @@
     skip_bits_long(&gb, 32); // sample rate already known
     sconf->samples              = get_bits_long(&gb, 32);
     avctx->channels             = m4ac.channels;
-    skip_bits(&gb, 16);      // number of channels already knwon
+    skip_bits(&gb, 16);      // number of channels already known
     skip_bits(&gb, 3);       // skip file_type
     sconf->resolution           = get_bits(&gb, 3);
     sconf->floating             = get_bits1(&gb);
@@ -354,13 +357,21 @@
         if (!(sconf->chan_pos = av_malloc(avctx->channels * sizeof(*sconf->chan_pos))))
             return AVERROR(ENOMEM);
 
-        for (i = 0; i < avctx->channels; i++)
-            sconf->chan_pos[i] = get_bits(&gb, chan_pos_bits);
+        ctx->cs_switch = 1;
+
+        for (i = 0; i < avctx->channels; i++) {
+            int idx;
+
+            idx = get_bits(&gb, chan_pos_bits);
+            if (idx >= avctx->channels) {
+                av_log(avctx, AV_LOG_WARNING, "Invalid channel reordering.\n");
+                ctx->cs_switch = 0;
+                break;
+            }
+            sconf->chan_pos[idx] = i;
+        }
 
         align_get_bits(&gb);
-        // TODO: use this to actually do channel sorting
-    } else {
-        sconf->chan_sort = 0;
     }
 
 
@@ -429,7 +440,6 @@
 
     MISSING_ERR(sconf->floating,  "Floating point decoding",     AVERROR_PATCHWELCOME);
     MISSING_ERR(sconf->rlslms,    "Adaptive RLS-LMS prediction", AVERROR_PATCHWELCOME);
-    MISSING_ERR(sconf->chan_sort, "Channel sorting",             0);
 
     return error;
 }
@@ -552,12 +562,15 @@
 
 /** Read the block data for a constant block
  */
-static void read_const_block_data(ALSDecContext *ctx, ALSBlockData *bd)
+static int read_const_block_data(ALSDecContext *ctx, ALSBlockData *bd)
 {
     ALSSpecificConfig *sconf = &ctx->sconf;
     AVCodecContext *avctx    = ctx->avctx;
     GetBitContext *gb        = &ctx->gb;
 
+    if (bd->block_length <= 0)
+        return AVERROR_INVALIDDATA;
+
     *bd->raw_samples = 0;
     *bd->const_block = get_bits1(gb);    // 1 = constant value, 0 = zero block (silence)
     bd->js_blocks    = get_bits1(gb);
@@ -572,6 +585,8 @@
 
     // ensure constant block decoding by reusing this field
     *bd->const_block = 1;
+
+    return 0;
 }
 
 
@@ -670,7 +685,7 @@
             *bd->opt_order       = get_bits(gb, opt_order_length);
             if (*bd->opt_order > sconf->max_order) {
                 *bd->opt_order = sconf->max_order;
-                av_log(avctx, AV_LOG_ERROR, "Predictor order too large!\n");
+                av_log(avctx, AV_LOG_ERROR, "Predictor order too large.\n");
                 return AVERROR_INVALIDDATA;
             }
         } else {
@@ -706,7 +721,7 @@
                     int offset     = parcor_rice_table[sconf->coef_table][k][0];
                     quant_cof[k] = decode_rice(gb, rice_param) + offset;
                     if (quant_cof[k] < -64 || quant_cof[k] > 63) {
-                        av_log(avctx, AV_LOG_ERROR, "quant_cof %d is out of range\n", quant_cof[k]);
+                        av_log(avctx, AV_LOG_ERROR, "quant_cof %d is out of range.\n", quant_cof[k]);
                         return AVERROR_INVALIDDATA;
                     }
                 }
@@ -964,14 +979,16 @@
 static int read_block(ALSDecContext *ctx, ALSBlockData *bd)
 {
     GetBitContext *gb        = &ctx->gb;
+    int ret;
 
     *bd->shift_lsbs = 0;
     // read block type flag and read the samples accordingly
     if (get_bits1(gb)) {
-        if (read_var_block_data(ctx, bd))
-            return -1;
+        if ((ret = read_var_block_data(ctx, bd)) < 0)
+            return ret;
     } else {
-        read_const_block_data(ctx, bd);
+        if ((ret = read_const_block_data(ctx, bd)) < 0)
+            return ret;
     }
 
     return 0;
@@ -1169,7 +1186,7 @@
         current->master_channel = get_bits_long(gb, av_ceil_log2(channels));
 
         if (current->master_channel >= channels) {
-            av_log(ctx->avctx, AV_LOG_ERROR, "Invalid master channel!\n");
+            av_log(ctx->avctx, AV_LOG_ERROR, "Invalid master channel.\n");
             return -1;
         }
 
@@ -1194,7 +1211,7 @@
     }
 
     if (entries == channels) {
-        av_log(ctx->avctx, AV_LOG_ERROR, "Damaged channel data!\n");
+        av_log(ctx->avctx, AV_LOG_ERROR, "Damaged channel data.\n");
         return -1;
     }
 
@@ -1354,7 +1371,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");
+                av_log(ctx->avctx, AV_LOG_ERROR, "Invalid channel data.\n");
                 return -1;
             }
 
@@ -1432,6 +1449,7 @@
                         AVPacket *avpkt)
 {
     ALSDecContext *ctx       = avctx->priv_data;
+    AVFrame *frame           = data;
     ALSSpecificConfig *sconf = &ctx->sconf;
     const uint8_t *buffer    = avpkt->data;
     int buffer_size          = avpkt->size;
@@ -1461,20 +1479,26 @@
     ctx->frame_id++;
 
     /* get output buffer */
-    ctx->frame.nb_samples = ctx->cur_frame_length;
-    if ((ret = avctx->get_buffer(avctx, &ctx->frame)) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+    frame->nb_samples = ctx->cur_frame_length;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed.\n");
         return ret;
     }
 
     // transform decoded frame into output format
-    #define INTERLEAVE_OUTPUT(bps)                                 \
-    {                                                              \
-        int##bps##_t *dest = (int##bps##_t*)ctx->frame.data[0];    \
-        shift = bps - ctx->avctx->bits_per_raw_sample;             \
-        for (sample = 0; sample < ctx->cur_frame_length; sample++) \
-            for (c = 0; c < avctx->channels; c++)                  \
-                *dest++ = ctx->raw_samples[c][sample] << shift;    \
+    #define INTERLEAVE_OUTPUT(bps)                                                   \
+    {                                                                                \
+        int##bps##_t *dest = (int##bps##_t*)frame->data[0];                          \
+        shift = bps - ctx->avctx->bits_per_raw_sample;                               \
+        if (!ctx->cs_switch) {                                                       \
+            for (sample = 0; sample < ctx->cur_frame_length; sample++)               \
+                for (c = 0; c < avctx->channels; c++)                                \
+                    *dest++ = ctx->raw_samples[c][sample] << shift;                  \
+        } else {                                                                     \
+            for (sample = 0; sample < ctx->cur_frame_length; sample++)               \
+                for (c = 0; c < avctx->channels; c++)                                \
+                    *dest++ = ctx->raw_samples[sconf->chan_pos[c]][sample] << shift; \
+        }                                                                            \
     }
 
     if (ctx->avctx->bits_per_raw_sample <= 16) {
@@ -1488,7 +1512,7 @@
         int swap = HAVE_BIGENDIAN != sconf->msb_first;
 
         if (ctx->avctx->bits_per_raw_sample == 24) {
-            int32_t *src = (int32_t *)ctx->frame.data[0];
+            int32_t *src = (int32_t *)frame->data[0];
 
             for (sample = 0;
                  sample < ctx->cur_frame_length * avctx->channels;
@@ -1509,7 +1533,7 @@
 
             if (swap) {
                 if (ctx->avctx->bits_per_raw_sample <= 16) {
-                    int16_t *src  = (int16_t*) ctx->frame.data[0];
+                    int16_t *src  = (int16_t*) frame->data[0];
                     int16_t *dest = (int16_t*) ctx->crc_buffer;
                     for (sample = 0;
                          sample < ctx->cur_frame_length * avctx->channels;
@@ -1517,12 +1541,12 @@
                         *dest++ = av_bswap16(src[sample]);
                 } else {
                     ctx->dsp.bswap_buf((uint32_t*)ctx->crc_buffer,
-                                       (uint32_t *)ctx->frame.data[0],
+                                       (uint32_t *)frame->data[0],
                                        ctx->cur_frame_length * avctx->channels);
                 }
                 crc_source = ctx->crc_buffer;
             } else {
-                crc_source = ctx->frame.data[0];
+                crc_source = frame->data[0];
             }
 
             ctx->crc = av_crc(ctx->crc_table, ctx->crc, crc_source,
@@ -1534,13 +1558,11 @@
         // check CRC sums if this is the last frame
         if (ctx->cur_frame_length != sconf->frame_length &&
             ctx->crc_org != ctx->crc) {
-            av_log(avctx, AV_LOG_ERROR, "CRC error!\n");
+            av_log(avctx, AV_LOG_ERROR, "CRC error.\n");
         }
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = ctx->frame;
-
+    *got_frame_ptr = 1;
 
     bytes_read = invalid_frame ? buffer_size :
                                  (get_bits_count(&ctx->gb) + 7) >> 3;
@@ -1596,12 +1618,12 @@
     ctx->avctx = avctx;
 
     if (!avctx->extradata) {
-        av_log(avctx, AV_LOG_ERROR, "Missing required ALS extradata!\n");
+        av_log(avctx, AV_LOG_ERROR, "Missing required ALS extradata.\n");
         return -1;
     }
 
     if (read_specific_config(ctx)) {
-        av_log(avctx, AV_LOG_ERROR, "Reading ALSSpecificConfig failed!\n");
+        av_log(avctx, AV_LOG_ERROR, "Reading ALSSpecificConfig failed.\n");
         decode_end(avctx);
         return -1;
     }
@@ -1647,7 +1669,7 @@
     if (!ctx->quant_cof              || !ctx->lpc_cof        ||
         !ctx->quant_cof_buffer       || !ctx->lpc_cof_buffer ||
         !ctx->lpc_cof_reversed_buffer) {
-        av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed!\n");
+        av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n");
         return AVERROR(ENOMEM);
     }
 
@@ -1672,7 +1694,7 @@
         !ctx->opt_order || !ctx->store_prev_samples ||
         !ctx->use_ltp  || !ctx->ltp_lag ||
         !ctx->ltp_gain || !ctx->ltp_gain_buffer) {
-        av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed!\n");
+        av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n");
         decode_end(avctx);
         return AVERROR(ENOMEM);
     }
@@ -1690,7 +1712,7 @@
                                            num_buffers);
 
         if (!ctx->chan_data_buffer || !ctx->chan_data || !ctx->reverted_channels) {
-            av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed!\n");
+            av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n");
             decode_end(avctx);
             return AVERROR(ENOMEM);
         }
@@ -1711,7 +1733,7 @@
 
     // 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");
+        av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n");
         decode_end(avctx);
         return AVERROR(ENOMEM);
     }
@@ -1729,7 +1751,7 @@
                                     avctx->channels *
                                     av_get_bytes_per_sample(avctx->sample_fmt));
         if (!ctx->crc_buffer) {
-            av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed!\n");
+            av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n");
             decode_end(avctx);
             return AVERROR(ENOMEM);
         }
@@ -1737,9 +1759,6 @@
 
     ff_dsputil_init(&ctx->dsp, avctx);
 
-    avcodec_get_frame_defaults(&ctx->frame);
-    avctx->coded_frame = &ctx->frame;
-
     return 0;
 }
 
diff --git a/libavcodec/amrnbdec.c b/libavcodec/amrnbdec.c
index 0057959..6e14a60 100644
--- a/libavcodec/amrnbdec.c
+++ b/libavcodec/amrnbdec.c
@@ -44,8 +44,8 @@
 #include <math.h>
 
 #include "libavutil/channel_layout.h"
+#include "libavutil/float_dsp.h"
 #include "avcodec.h"
-#include "dsputil.h"
 #include "libavutil/common.h"
 #include "libavutil/avassert.h"
 #include "celp_math.h"
@@ -55,6 +55,7 @@
 #include "acelp_pitch_delay.h"
 #include "lsp.h"
 #include "amr.h"
+#include "internal.h"
 
 #include "amrnbdata.h"
 
@@ -97,7 +98,6 @@
 #define AMR_AGC_ALPHA      0.9
 
 typedef struct AMRContext {
-    AVFrame                         avframe; ///< AVFrame for decoded samples
     AMRNBFrame                        frame; ///< decoded AMR parameters (lsf coefficients, codebook indexes, etc)
     uint8_t             bad_frame_indicator; ///< bad frame ? 1 : 0
     enum Mode                cur_frame_mode;
@@ -184,9 +184,6 @@
     for (i = 0; i < 4; i++)
         p->prediction_error[i] = MIN_ENERGY;
 
-    avcodec_get_frame_defaults(&p->avframe);
-    avctx->coded_frame = &p->avframe;
-
     ff_acelp_filter_init(&p->acelpf_ctx);
     ff_acelp_vectors_init(&p->acelpv_ctx);
     ff_celp_filter_init(&p->celpf_ctx);
@@ -809,7 +806,7 @@
     // emphasize pitch vector contribution
     if (p->pitch_gain[4] > 0.5 && !overflow) {
         float energy = p->celpm_ctx.dot_productf(excitation, excitation,
-                                                AMR_SUBFRAME_SIZE);
+                                                    AMR_SUBFRAME_SIZE);
         float pitch_factor =
             p->pitch_gain[4] *
             (p->cur_frame_mode == MODE_12k2 ?
@@ -910,7 +907,7 @@
     float *samples          = p->samples_in + LP_FILTER_ORDER; // Start of input
 
     float speech_gain       = p->celpm_ctx.dot_productf(samples, samples,
-                                                       AMR_SUBFRAME_SIZE);
+                                                           AMR_SUBFRAME_SIZE);
 
     float pole_out[AMR_SUBFRAME_SIZE + LP_FILTER_ORDER];  // Output of pole filter
     const float *gamma_n, *gamma_d;                       // Formant filter factor table
@@ -953,6 +950,7 @@
 {
 
     AMRContext *p = avctx->priv_data;        // pointer to private data
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
     float *buf_out;                          // pointer to the output data buffer
@@ -964,12 +962,12 @@
     const float *synth_fixed_vector;         // pointer to the fixed vector that synthesis should use
 
     /* get output buffer */
-    p->avframe.nb_samples = AMR_BLOCK_SIZE;
-    if ((ret = avctx->get_buffer(avctx, &p->avframe)) < 0) {
+    frame->nb_samples = AMR_BLOCK_SIZE;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    buf_out = (float *)p->avframe.data[0];
+    buf_out = (float *)frame->data[0];
 
     p->cur_frame_mode = unpack_bitstream(p, buf, buf_size);
     if (p->cur_frame_mode == NO_DATA) {
@@ -1017,8 +1015,8 @@
         p->fixed_gain[4] =
             ff_amr_set_fixed_gain(fixed_gain_factor,
                        p->celpm_ctx.dot_productf(p->fixed_vector,
-                                                           p->fixed_vector,
-                                                           AMR_SUBFRAME_SIZE) /
+                                                               p->fixed_vector,
+                                                               AMR_SUBFRAME_SIZE) /
                                   AMR_SUBFRAME_SIZE,
                        p->prediction_error,
                        energy_mean[p->cur_frame_mode], energy_pred_fac);
@@ -1077,8 +1075,7 @@
     p->acelpv_ctx.weighted_vector_sumf(p->lsf_avg, p->lsf_avg, p->lsf_q[3],
                             0.84, 0.16, LP_FILTER_ORDER);
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = p->avframe;
+    *got_frame_ptr = 1;
 
     /* return the amount of bytes consumed if everything was OK */
     return frame_sizes_nb[p->cur_frame_mode] + 1; // +7 for rounding and +8 for TOC
diff --git a/libavcodec/amrwbdec.c b/libavcodec/amrwbdec.c
index 468ffa0..c0481325e 100644
--- a/libavcodec/amrwbdec.c
+++ b/libavcodec/amrwbdec.c
@@ -26,16 +26,17 @@
 
 #include "libavutil/channel_layout.h"
 #include "libavutil/common.h"
+#include "libavutil/float_dsp.h"
 #include "libavutil/lfg.h"
 
 #include "avcodec.h"
-#include "dsputil.h"
 #include "lsp.h"
 #include "celp_filters.h"
 #include "celp_math.h"
 #include "acelp_filters.h"
 #include "acelp_vectors.h"
 #include "acelp_pitch_delay.h"
+#include "internal.h"
 
 #define AMR_USE_16BIT_TABLES
 #include "amr.h"
@@ -44,7 +45,6 @@
 #include "mips/amrwbdec_mips.h"
 
 typedef struct {
-    AVFrame                              avframe; ///< AVFrame for decoded samples
     AMRWBFrame                             frame; ///< AMRWB parameters decoded from bitstream
     enum Mode                        fr_cur_mode; ///< mode index of current frame
     uint8_t                           fr_quality; ///< frame quality index (FQI)
@@ -120,9 +120,6 @@
     for (i = 0; i < 4; i++)
         ctx->prediction_error[i] = MIN_ENERGY;
 
-    avcodec_get_frame_defaults(&ctx->avframe);
-    avctx->coded_frame = &ctx->avframe;
-
     ff_acelp_filter_init(&ctx->acelpf_ctx);
     ff_acelp_vectors_init(&ctx->acelpv_ctx);
     ff_celp_filter_init(&ctx->celpf_ctx);
@@ -611,11 +608,11 @@
                           CELPMContext *ctx)
 {
     double p_ener = (double) ctx->dot_productf(p_vector, p_vector,
-                                             AMRWB_SFR_SIZE) *
-                                             p_gain * p_gain;
+                                                          AMRWB_SFR_SIZE) *
+                    p_gain * p_gain;
     double f_ener = (double) ctx->dot_productf(f_vector, f_vector,
-                                             AMRWB_SFR_SIZE) *
-                                             f_gain * f_gain;
+                                                          AMRWB_SFR_SIZE) *
+                    f_gain * f_gain;
 
     return (p_ener - f_ener) / (p_ener + f_ener);
 }
@@ -784,7 +781,7 @@
     if (ctx->pitch_gain[0] > 0.5 && ctx->fr_cur_mode <= MODE_8k85) {
         int i;
         float energy = ctx->celpm_ctx.dot_productf(excitation, excitation,
-                                                AMRWB_SFR_SIZE);
+                                                    AMRWB_SFR_SIZE);
 
         // XXX: Weird part in both ref code and spec. A unknown parameter
         // {beta} seems to be identical to the current pitch gain
@@ -845,8 +842,8 @@
 
         for (k = 1; k < 5; k++) {
             out[i] = ctx->dot_productf(in0 + int_part,
-                                              upsample_fir[4 - frac_part],
-                                              UPS_MEM_SIZE);
+                                                  upsample_fir[4 - frac_part],
+                                                  UPS_MEM_SIZE);
             int_part++;
             frac_part--;
             i++;
@@ -892,7 +889,8 @@
                                  const float *synth_exc, float hb_gain)
 {
     int i;
-    float energy = ctx->celpm_ctx.dot_productf(synth_exc, synth_exc, AMRWB_SFR_SIZE);
+    float energy = ctx->celpm_ctx.dot_productf(synth_exc, synth_exc,
+                                                AMRWB_SFR_SIZE);
 
     /* Generate a white-noise excitation */
     for (i = 0; i < AMRWB_SFR_SIZE_16k; i++)
@@ -1095,6 +1093,7 @@
                               int *got_frame_ptr, AVPacket *avpkt)
 {
     AMRWBContext *ctx  = avctx->priv_data;
+    AVFrame *frame     = data;
     AMRWBFrame   *cf   = &ctx->frame;
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
@@ -1112,12 +1111,12 @@
     int sub, i, ret;
 
     /* get output buffer */
-    ctx->avframe.nb_samples = 4 * AMRWB_SFR_SIZE_16k;
-    if ((ret = avctx->get_buffer(avctx, &ctx->avframe)) < 0) {
+    frame->nb_samples = 4 * AMRWB_SFR_SIZE_16k;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    buf_out = (float *)ctx->avframe.data[0];
+    buf_out = (float *)frame->data[0];
 
     header_size      = decode_mime_header(ctx, buf);
     if (ctx->fr_cur_mode > MODE_SID) {
@@ -1188,8 +1187,8 @@
         ctx->fixed_gain[0] =
             ff_amr_set_fixed_gain(fixed_gain_factor,
                                   ctx->celpm_ctx.dot_productf(ctx->fixed_vector,
-                                                           ctx->fixed_vector,
-                                                           AMRWB_SFR_SIZE) /
+                                                               ctx->fixed_vector,
+                                                               AMRWB_SFR_SIZE) /
                                   AMRWB_SFR_SIZE,
                        ctx->prediction_error,
                        ENERGY_MEAN, energy_pred_fac);
@@ -1263,8 +1262,7 @@
     memcpy(ctx->isp_sub4_past, ctx->isp[3], LP_ORDER * sizeof(ctx->isp[3][0]));
     memcpy(ctx->isf_past_final, ctx->isf_cur, LP_ORDER * sizeof(float));
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = ctx->avframe;
+    *got_frame_ptr = 1;
 
     return expected_fr_size;
 }
diff --git a/libavcodec/anm.c b/libavcodec/anm.c
index 7cac095..08f5170 100644
--- a/libavcodec/anm.c
+++ b/libavcodec/anm.c
@@ -106,7 +106,7 @@
 }
 
 static int decode_frame(AVCodecContext *avctx,
-                        void *data, int *data_size,
+                        void *data, int *got_frame,
                         AVPacket *avpkt)
 {
     AnmContext *s = avctx->priv_data;
@@ -114,7 +114,7 @@
     uint8_t *dst, *dst_end;
     int count, ret;
 
-    if ((ret = avctx->reget_buffer(avctx, &s->frame)) < 0) {
+    if ((ret = avctx->reget_buffer(avctx, &s->frame)) < 0){
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -159,7 +159,7 @@
                     break; // stop
                 if (type == 2) {
                     av_log_ask_for_sample(avctx, "unknown opcode");
-                    return AVERROR_INVALIDDATA;
+                    return AVERROR_PATCHWELCOME;
                 }
                 continue;
             }
@@ -171,7 +171,7 @@
 
     memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE);
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*)data = s->frame;
     return buf_size;
 }
diff --git a/libavcodec/ansi.c b/libavcodec/ansi.c
index d84b395..51339d2 100644
--- a/libavcodec/ansi.c
+++ b/libavcodec/ansi.c
@@ -29,6 +29,7 @@
 #include "libavutil/xga_font_data.h"
 #include "avcodec.h"
 #include "cga_data.h"
+#include "internal.h"
 
 #define ATTR_BOLD         0x01  /**< Bold/Bright-foreground (mode 1) */
 #define ATTR_FAINT        0x02  /**< Faint (mode 2) */
@@ -242,7 +243,7 @@
             if (s->frame.data[0])
                 avctx->release_buffer(avctx, &s->frame);
             avcodec_set_dimensions(avctx, width, height);
-            ret = avctx->get_buffer(avctx, &s->frame);
+            ret = ff_get_buffer(avctx, &s->frame);
             if (ret < 0) {
                 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
                 return ret;
@@ -338,7 +339,7 @@
 }
 
 static int decode_frame(AVCodecContext *avctx,
-                            void *data, int *data_size,
+                            void *data, int *got_frame,
                             AVPacket *avpkt)
 {
     AnsiContext *s = avctx->priv_data;
@@ -352,6 +353,12 @@
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
+    if (!avctx->frame_number) {
+        for (i=0; i<avctx->height; i++)
+            memset(s->frame.data[0]+ i*s->frame.linesize[0], 0, avctx->width);
+        memset(s->frame.data[1], 0, AVPALETTE_SIZE);
+    }
+
     s->frame.pict_type           = AV_PICTURE_TYPE_I;
     s->frame.palette_has_changed = 1;
     set_palette((uint32_t *)s->frame.data[1]);
@@ -427,8 +434,8 @@
                     av_log(avctx, AV_LOG_WARNING, "args overflow (%i)\n", s->nb_args);
                 if (s->nb_args < MAX_NB_ARGS && s->args[s->nb_args] >= 0)
                     s->nb_args++;
-                if (execute_code(avctx, buf[0]) < 0)
-                    return -1;
+                if ((ret = execute_code(avctx, buf[0])) < 0)
+                    return ret;
                 s->state = STATE_NORMAL;
             }
             break;
@@ -441,7 +448,7 @@
         buf++;
     }
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*)data = s->frame;
     return buf_size;
 }
diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c
index a85d355..e0af6aa 100644
--- a/libavcodec/apedec.c
+++ b/libavcodec/apedec.c
@@ -26,6 +26,7 @@
 #include "avcodec.h"
 #include "dsputil.h"
 #include "bytestream.h"
+#include "internal.h"
 
 /**
  * @file
@@ -128,7 +129,6 @@
 typedef struct APEContext {
     AVClass *class;                          ///< class for AVOptions
     AVCodecContext *avctx;
-    AVFrame frame;
     DSPContext dsp;
     int channels;
     int samples;                             ///< samples left to decode in current frame
@@ -234,9 +234,6 @@
     ff_dsputil_init(&s->dsp, avctx);
     avctx->channel_layout = (avctx->channels==2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO;
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     return 0;
 filter_alloc_fail:
     ape_decode_close(avctx);
@@ -825,6 +822,7 @@
 static int ape_decode_frame(AVCodecContext *avctx, void *data,
                             int *got_frame_ptr, AVPacket *avpkt)
 {
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     APEContext *s = avctx->priv_data;
     uint8_t *sample8;
@@ -905,8 +903,8 @@
     s->decoded[1] = s->decoded_buffer + FFALIGN(blockstodecode, 8);
 
     /* get output buffer */
-    s->frame.nb_samples = blockstodecode;
-    if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = blockstodecode;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -928,21 +926,21 @@
     switch (s->bps) {
     case 8:
         for (ch = 0; ch < s->channels; ch++) {
-            sample8 = (uint8_t *)s->frame.data[ch];
+            sample8 = (uint8_t *)frame->data[ch];
             for (i = 0; i < blockstodecode; i++)
                 *sample8++ = (s->decoded[ch][i] + 0x80) & 0xff;
         }
         break;
     case 16:
         for (ch = 0; ch < s->channels; ch++) {
-            sample16 = (int16_t *)s->frame.data[ch];
+            sample16 = (int16_t *)frame->data[ch];
             for (i = 0; i < blockstodecode; i++)
                 *sample16++ = s->decoded[ch][i];
         }
         break;
     case 24:
         for (ch = 0; ch < s->channels; ch++) {
-            sample24 = (int32_t *)s->frame.data[ch];
+            sample24 = (int32_t *)frame->data[ch];
             for (i = 0; i < blockstodecode; i++)
                 *sample24++ = s->decoded[ch][i] << 8;
         }
@@ -951,8 +949,7 @@
 
     s->samples -= blockstodecode;
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
+    *got_frame_ptr = 1;
 
     return !s->samples ? avpkt->size : 0;
 }
diff --git a/libavcodec/arm/Makefile b/libavcodec/arm/Makefile
index acfd626..1c91d62 100644
--- a/libavcodec/arm/Makefile
+++ b/libavcodec/arm/Makefile
@@ -1,3 +1,5 @@
+ARCH_HEADERS = mathops.h
+
 OBJS-$(CONFIG_AC3DSP)                  += arm/ac3dsp_init_arm.o         \
                                           arm/ac3dsp_arm.o
 
@@ -15,6 +17,7 @@
 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
@@ -23,13 +26,17 @@
                                           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_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            \
@@ -41,6 +48,9 @@
 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     \
 
@@ -48,10 +58,7 @@
                                           arm/dsputil_armv6.o           \
                                           arm/simple_idct_armv6.o       \
 
-ARMVFP-OBJS-$(HAVE_ARMV6)              += arm/fmtconvert_vfp.o
-
-ARMVFP-OBJS                            += arm/dsputil_vfp.o             \
-                                          arm/dsputil_init_vfp.o        \
+VFP-OBJS-$(HAVE_ARMV6)                 += arm/fmtconvert_vfp.o
 
 NEON-OBJS-$(CONFIG_FFT)                += arm/fft_neon.o                \
                                           arm/fft_fixed_neon.o          \
@@ -61,12 +68,14 @@
 
 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           \
-                                          arm/h264cmc_neon.o            \
 
 NEON-OBJS-$(CONFIG_H264PRED)           += arm/h264pred_neon.o           \
 
+NEON-OBJS-$(CONFIG_H264QPEL)           += arm/h264qpel_neon.o           \
+
 NEON-OBJS-$(CONFIG_AC3DSP)             += arm/ac3dsp_neon.o
 
 NEON-OBJS-$(CONFIG_AAC_DECODER)        += arm/sbrdsp_neon.o             \
@@ -79,7 +88,8 @@
 NEON-OBJS-$(CONFIG_RV30_DECODER)       += arm/rv34dsp_neon.o
 NEON-OBJS-$(CONFIG_RV40_DECODER)       += arm/rv34dsp_neon.o            \
                                           arm/rv40dsp_neon.o            \
-                                          arm/h264cmc_neon.o            \
+
+NEON-OBJS-$(CONFIG_VORBIS_DECODER)     += arm/vorbisdsp_neon.o
 
 NEON-OBJS-$(CONFIG_VP3DSP)             += arm/vp3dsp_neon.o
 
diff --git a/libavcodec/arm/aac.h b/libavcodec/arm/aac.h
index bd4d293..cafa881 100644
--- a/libavcodec/arm/aac.h
+++ b/libavcodec/arm/aac.h
@@ -23,7 +23,7 @@
 
 #include "config.h"
 
-#if HAVE_NEON && HAVE_INLINE_ASM
+#if HAVE_NEON_INLINE
 
 #define VMUL2 VMUL2
 static inline float *VMUL2(float *dst, const float *v, unsigned idx,
@@ -138,6 +138,6 @@
     return dst;
 }
 
-#endif /* HAVE_NEON && HAVE_INLINE_ASM */
+#endif /* HAVE_NEON_INLINE */
 
 #endif /* AVCODEC_ARM_AAC_H */
diff --git a/libavcodec/arm/dca.h b/libavcodec/arm/dca.h
index 05be789..2cfd18a 100644
--- a/libavcodec/arm/dca.h
+++ b/libavcodec/arm/dca.h
@@ -22,10 +22,11 @@
 #define AVCODEC_ARM_DCA_H
 
 #include <stdint.h>
-#include "config.h"
-#include "libavutil/intmath.h"
 
-#if HAVE_ARMV6 && HAVE_INLINE_ASM && AV_GCC_VERSION_AT_LEAST(4,4) && !CONFIG_THUMB
+#include "config.h"
+#include "libavcodec/mathops.h"
+
+#if HAVE_ARMV6_INLINE && AV_GCC_VERSION_AT_LEAST(4,4) && !CONFIG_THUMB
 
 #define decode_blockcodes decode_blockcodes
 static inline int decode_blockcodes(int code1, int code2, int levels,
@@ -79,7 +80,7 @@
 
 #endif
 
-#if HAVE_NEON && HAVE_INLINE_ASM && HAVE_ASM_MOD_Y
+#if HAVE_NEON_INLINE && HAVE_ASM_MOD_Y
 
 #define int8x8_fmul_int32 int8x8_fmul_int32
 static inline void int8x8_fmul_int32(float *dst, const int8_t *src, int scale)
diff --git a/libavcodec/arm/dsputil_arm.S b/libavcodec/arm/dsputil_arm.S
index d665ab3..994b440 100644
--- a/libavcodec/arm/dsputil_arm.S
+++ b/libavcodec/arm/dsputil_arm.S
@@ -22,15 +22,7 @@
 #include "config.h"
 #include "libavutil/arm/asm.S"
 
-#if HAVE_ARMV5TE
-function ff_prefetch_arm, export=1
-        subs            r2,  r2,  #1
-        pld             [r0]
-        add             r0,  r0,  r1
-        bne             ff_prefetch_arm
-        bx              lr
-endfunc
-#else
+#if !HAVE_ARMV5TE_EXTERNAL
 #define pld @
 #endif
 
diff --git a/libavcodec/arm/dsputil_init_arm.c b/libavcodec/arm/dsputil_init_arm.c
index 03df6b2..a6725f3 100644
--- a/libavcodec/arm/dsputil_init_arm.c
+++ b/libavcodec/arm/dsputil_init_arm.c
@@ -19,27 +19,27 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/arm/cpu.h"
-#include "libavcodec/dsputil.h"
 #include "dsputil_arm.h"
 
-void ff_j_rev_dct_arm(DCTELEM *data);
-void ff_simple_idct_arm(DCTELEM *data);
+void ff_j_rev_dct_arm(int16_t *data);
+void ff_simple_idct_arm(int16_t *data);
 
 /* XXX: local hack */
-static void (*ff_put_pixels_clamped)(const DCTELEM *block, uint8_t *pixels, int line_size);
-static void (*ff_add_pixels_clamped)(const DCTELEM *block, uint8_t *pixels, int line_size);
+static void (*ff_put_pixels_clamped)(const int16_t *block, uint8_t *pixels, int line_size);
+static void (*ff_add_pixels_clamped)(const int16_t *block, uint8_t *pixels, int line_size);
 
-void ff_put_pixels8_arm(uint8_t *block, const uint8_t *pixels, int line_size, int h);
-void ff_put_pixels8_x2_arm(uint8_t *block, const uint8_t *pixels, int line_size, int h);
-void ff_put_pixels8_y2_arm(uint8_t *block, const uint8_t *pixels, int line_size, int h);
-void ff_put_pixels8_xy2_arm(uint8_t *block, const uint8_t *pixels, int line_size, int h);
+void ff_put_pixels8_arm(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h);
+void ff_put_pixels8_x2_arm(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h);
+void ff_put_pixels8_y2_arm(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h);
+void ff_put_pixels8_xy2_arm(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h);
 
-void ff_put_no_rnd_pixels8_x2_arm(uint8_t *block, const uint8_t *pixels, int line_size, int h);
-void ff_put_no_rnd_pixels8_y2_arm(uint8_t *block, const uint8_t *pixels, int line_size, int h);
-void ff_put_no_rnd_pixels8_xy2_arm(uint8_t *block, const uint8_t *pixels, int line_size, int h);
+void ff_put_no_rnd_pixels8_x2_arm(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h);
+void ff_put_no_rnd_pixels8_y2_arm(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h);
+void ff_put_no_rnd_pixels8_xy2_arm(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h);
 
-void ff_put_pixels16_arm(uint8_t *block, const uint8_t *pixels, int line_size, int h);
+void ff_put_pixels16_arm(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h);
 
 CALL_2X_PIXELS(ff_put_pixels16_x2_arm,         ff_put_pixels8_x2_arm,        8)
 CALL_2X_PIXELS(ff_put_pixels16_y2_arm,         ff_put_pixels8_y2_arm,        8)
@@ -48,33 +48,33 @@
 CALL_2X_PIXELS(ff_put_no_rnd_pixels16_y2_arm,  ff_put_no_rnd_pixels8_y2_arm, 8)
 CALL_2X_PIXELS(ff_put_no_rnd_pixels16_xy2_arm, ff_put_no_rnd_pixels8_xy2_arm,8)
 
-void ff_add_pixels_clamped_arm(const DCTELEM *block, uint8_t *dest,
+void ff_add_pixels_clamped_arm(const int16_t *block, uint8_t *dest,
                                int line_size);
 
 /* XXX: those functions should be suppressed ASAP when all IDCTs are
    converted */
-static void j_rev_dct_arm_put(uint8_t *dest, int line_size, DCTELEM *block)
+static void j_rev_dct_arm_put(uint8_t *dest, int line_size, int16_t *block)
 {
     ff_j_rev_dct_arm (block);
     ff_put_pixels_clamped(block, dest, line_size);
 }
-static void j_rev_dct_arm_add(uint8_t *dest, int line_size, DCTELEM *block)
+static void j_rev_dct_arm_add(uint8_t *dest, int line_size, int16_t *block)
 {
     ff_j_rev_dct_arm (block);
     ff_add_pixels_clamped(block, dest, line_size);
 }
-static void simple_idct_arm_put(uint8_t *dest, int line_size, DCTELEM *block)
+static void simple_idct_arm_put(uint8_t *dest, int line_size, int16_t *block)
 {
     ff_simple_idct_arm (block);
     ff_put_pixels_clamped(block, dest, line_size);
 }
-static void simple_idct_arm_add(uint8_t *dest, int line_size, DCTELEM *block)
+static void simple_idct_arm_add(uint8_t *dest, int line_size, int16_t *block)
 {
     ff_simple_idct_arm (block);
     ff_add_pixels_clamped(block, dest, line_size);
 }
 
-void ff_dsputil_init_arm(DSPContext* c, AVCodecContext *avctx)
+av_cold void ff_dsputil_init_arm(DSPContext *c, AVCodecContext *avctx)
 {
     const int high_bit_depth = avctx->bits_per_raw_sample > 8;
     int cpu_flags = av_get_cpu_flags();
@@ -121,6 +121,5 @@
 
     if (have_armv5te(cpu_flags)) ff_dsputil_init_armv5te(c, avctx);
     if (have_armv6(cpu_flags))   ff_dsputil_init_armv6(c, avctx);
-    if (have_vfp(cpu_flags))     ff_dsputil_init_vfp(c, avctx);
     if (have_neon(cpu_flags))    ff_dsputil_init_neon(c, avctx);
 }
diff --git a/libavcodec/arm/dsputil_init_armv5te.c b/libavcodec/arm/dsputil_init_armv5te.c
index 9fedb7a..841fbfa 100644
--- a/libavcodec/arm/dsputil_init_armv5te.c
+++ b/libavcodec/arm/dsputil_init_armv5te.c
@@ -18,14 +18,11 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavcodec/dsputil.h"
 #include "dsputil_arm.h"
 
-void ff_simple_idct_armv5te(DCTELEM *data);
-void ff_simple_idct_put_armv5te(uint8_t *dest, int line_size, DCTELEM *data);
-void ff_simple_idct_add_armv5te(uint8_t *dest, int line_size, DCTELEM *data);
-
-void ff_prefetch_arm(void *mem, int stride, int h);
+void ff_simple_idct_armv5te(int16_t *data);
+void ff_simple_idct_put_armv5te(uint8_t *dest, int line_size, int16_t *data);
+void ff_simple_idct_add_armv5te(uint8_t *dest, int line_size, int16_t *data);
 
 av_cold void ff_dsputil_init_armv5te(DSPContext *c, AVCodecContext *avctx)
 {
@@ -37,6 +34,4 @@
         c->idct                  = ff_simple_idct_armv5te;
         c->idct_permutation_type = FF_NO_IDCT_PERM;
     }
-
-    c->prefetch = ff_prefetch_arm;
 }
diff --git a/libavcodec/arm/dsputil_init_armv6.c b/libavcodec/arm/dsputil_init_armv6.c
index 1081135..3e7aa37 100644
--- a/libavcodec/arm/dsputil_init_armv6.c
+++ b/libavcodec/arm/dsputil_init_armv6.c
@@ -21,37 +21,36 @@
 #include <stdint.h>
 
 #include "libavcodec/avcodec.h"
-#include "libavcodec/dsputil.h"
 #include "dsputil_arm.h"
 
-void ff_simple_idct_armv6(DCTELEM *data);
-void ff_simple_idct_put_armv6(uint8_t *dest, int line_size, DCTELEM *data);
-void ff_simple_idct_add_armv6(uint8_t *dest, int line_size, DCTELEM *data);
+void ff_simple_idct_armv6(int16_t *data);
+void ff_simple_idct_put_armv6(uint8_t *dest, int line_size, int16_t *data);
+void ff_simple_idct_add_armv6(uint8_t *dest, int line_size, int16_t *data);
 
-void ff_put_pixels16_armv6(uint8_t *, const uint8_t *, int, int);
-void ff_put_pixels16_x2_armv6(uint8_t *, const uint8_t *, int, int);
-void ff_put_pixels16_y2_armv6(uint8_t *, const uint8_t *, int, int);
+void ff_put_pixels16_armv6(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_put_pixels16_x2_armv6(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_put_pixels16_y2_armv6(uint8_t *, const uint8_t *, ptrdiff_t, int);
 
-void ff_put_pixels16_x2_no_rnd_armv6(uint8_t *, const uint8_t *, int, int);
-void ff_put_pixels16_y2_no_rnd_armv6(uint8_t *, const uint8_t *, int, int);
+void ff_put_pixels16_x2_no_rnd_armv6(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_put_pixels16_y2_no_rnd_armv6(uint8_t *, const uint8_t *, ptrdiff_t, int);
 
-void ff_avg_pixels16_armv6(uint8_t *, const uint8_t *, int, int);
+void ff_avg_pixels16_armv6(uint8_t *, const uint8_t *, ptrdiff_t, int);
 
-void ff_put_pixels8_armv6(uint8_t *, const uint8_t *, int, int);
-void ff_put_pixels8_x2_armv6(uint8_t *, const uint8_t *, int, int);
-void ff_put_pixels8_y2_armv6(uint8_t *, const uint8_t *, int, int);
+void ff_put_pixels8_armv6(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_put_pixels8_x2_armv6(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_put_pixels8_y2_armv6(uint8_t *, const uint8_t *, ptrdiff_t, int);
 
-void ff_put_pixels8_x2_no_rnd_armv6(uint8_t *, const uint8_t *, int, int);
-void ff_put_pixels8_y2_no_rnd_armv6(uint8_t *, const uint8_t *, int, int);
+void ff_put_pixels8_x2_no_rnd_armv6(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_put_pixels8_y2_no_rnd_armv6(uint8_t *, const uint8_t *, ptrdiff_t, int);
 
-void ff_avg_pixels8_armv6(uint8_t *, const uint8_t *, int, int);
+void ff_avg_pixels8_armv6(uint8_t *, const uint8_t *, ptrdiff_t, int);
 
-void ff_add_pixels_clamped_armv6(const DCTELEM *block,
-                                 uint8_t *av_restrict pixels,
+void ff_add_pixels_clamped_armv6(const int16_t *block,
+                                 uint8_t *restrict pixels,
                                  int line_size);
 
-void ff_get_pixels_armv6(DCTELEM *block, const uint8_t *pixels, int stride);
-void ff_diff_pixels_armv6(DCTELEM *block, const uint8_t *s1,
+void ff_get_pixels_armv6(int16_t *block, const uint8_t *pixels, int stride);
+void ff_diff_pixels_armv6(int16_t *block, const uint8_t *s1,
                           const uint8_t *s2, int stride);
 
 int ff_pix_abs16_armv6(void *s, uint8_t *blk1, uint8_t *blk2,
diff --git a/libavcodec/arm/dsputil_init_neon.c b/libavcodec/arm/dsputil_init_neon.c
index ff1178d..5555bc8 100644
--- a/libavcodec/arm/dsputil_init_neon.c
+++ b/libavcodec/arm/dsputil_init_neon.c
@@ -21,143 +21,53 @@
 
 #include <stdint.h>
 
+#include "libavutil/attributes.h"
 #include "libavcodec/avcodec.h"
-#include "libavcodec/dsputil.h"
 #include "dsputil_arm.h"
 
-void ff_simple_idct_neon(DCTELEM *data);
-void ff_simple_idct_put_neon(uint8_t *dest, int line_size, DCTELEM *data);
-void ff_simple_idct_add_neon(uint8_t *dest, int line_size, DCTELEM *data);
+void ff_simple_idct_neon(int16_t *data);
+void ff_simple_idct_put_neon(uint8_t *dest, int line_size, int16_t *data);
+void ff_simple_idct_add_neon(uint8_t *dest, int line_size, int16_t *data);
 
-void ff_clear_block_neon(DCTELEM *block);
-void ff_clear_blocks_neon(DCTELEM *blocks);
+void ff_clear_block_neon(int16_t *block);
+void ff_clear_blocks_neon(int16_t *blocks);
 
-void ff_put_pixels16_neon(uint8_t *, const uint8_t *, int, int);
-void ff_put_pixels16_x2_neon(uint8_t *, const uint8_t *, int, int);
-void ff_put_pixels16_y2_neon(uint8_t *, const uint8_t *, int, int);
-void ff_put_pixels16_xy2_neon(uint8_t *, const uint8_t *, int, int);
-void ff_put_pixels8_neon(uint8_t *, const uint8_t *, int, int);
-void ff_put_pixels8_x2_neon(uint8_t *, const uint8_t *, int, int);
-void ff_put_pixels8_y2_neon(uint8_t *, const uint8_t *, int, int);
-void ff_put_pixels8_xy2_neon(uint8_t *, const uint8_t *, int, int);
-void ff_put_pixels16_x2_no_rnd_neon(uint8_t *, const uint8_t *, int, int);
-void ff_put_pixels16_y2_no_rnd_neon(uint8_t *, const uint8_t *, int, int);
-void ff_put_pixels16_xy2_no_rnd_neon(uint8_t *, const uint8_t *, int, int);
-void ff_put_pixels8_x2_no_rnd_neon(uint8_t *, const uint8_t *, int, int);
-void ff_put_pixels8_y2_no_rnd_neon(uint8_t *, const uint8_t *, int, int);
-void ff_put_pixels8_xy2_no_rnd_neon(uint8_t *, const uint8_t *, int, int);
+void ff_put_pixels16_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_put_pixels16_x2_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_put_pixels16_y2_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_put_pixels16_xy2_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_put_pixels8_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_put_pixels8_x2_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_put_pixels8_y2_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_put_pixels8_xy2_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_put_pixels16_x2_no_rnd_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_put_pixels16_y2_no_rnd_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_put_pixels16_xy2_no_rnd_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_put_pixels8_x2_no_rnd_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_put_pixels8_y2_no_rnd_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_put_pixels8_xy2_no_rnd_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
 
-void ff_avg_pixels16_neon(uint8_t *, const uint8_t *, int, int);
-void ff_avg_pixels16_x2_neon(uint8_t *, const uint8_t *, int, int);
-void ff_avg_pixels16_y2_neon(uint8_t *, const uint8_t *, int, int);
-void ff_avg_pixels16_xy2_neon(uint8_t *, const uint8_t *, int, int);
-void ff_avg_pixels8_neon(uint8_t *, const uint8_t *, int, int);
-void ff_avg_pixels8_x2_neon(uint8_t *, const uint8_t *, int, int);
-void ff_avg_pixels8_y2_neon(uint8_t *, const uint8_t *, int, int);
-void ff_avg_pixels8_xy2_neon(uint8_t *, const uint8_t *, int, int);
-void ff_avg_pixels16_x2_no_rnd_neon(uint8_t *, const uint8_t *, int, int);
-void ff_avg_pixels16_y2_no_rnd_neon(uint8_t *, const uint8_t *, int, int);
-void ff_avg_pixels16_xy2_no_rnd_neon(uint8_t *, const uint8_t *, int, int);
-void ff_avg_pixels8_x2_no_rnd_neon(uint8_t *, const uint8_t *, int, int);
-void ff_avg_pixels8_y2_no_rnd_neon(uint8_t *, const uint8_t *, int, int);
-void ff_avg_pixels8_xy2_no_rnd_neon(uint8_t *, const uint8_t *, int, int);
+void ff_avg_pixels16_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_avg_pixels16_x2_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_avg_pixels16_y2_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_avg_pixels16_xy2_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_avg_pixels8_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_avg_pixels8_x2_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_avg_pixels8_y2_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_avg_pixels8_xy2_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_avg_pixels16_x2_no_rnd_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_avg_pixels16_y2_no_rnd_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_avg_pixels16_xy2_no_rnd_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
 
-void ff_add_pixels_clamped_neon(const DCTELEM *, uint8_t *, int);
-void ff_put_pixels_clamped_neon(const DCTELEM *, uint8_t *, int);
-void ff_put_signed_pixels_clamped_neon(const DCTELEM *, uint8_t *, int);
-
-void ff_put_h264_qpel16_mc00_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel16_mc10_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel16_mc20_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel16_mc30_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel16_mc01_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel16_mc11_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel16_mc21_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel16_mc31_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel16_mc02_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel16_mc12_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel16_mc22_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel16_mc32_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel16_mc03_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel16_mc13_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel16_mc23_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel16_mc33_neon(uint8_t *, uint8_t *, int);
-
-void ff_put_h264_qpel8_mc00_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel8_mc10_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel8_mc20_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel8_mc30_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel8_mc01_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel8_mc11_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel8_mc21_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel8_mc31_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel8_mc02_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel8_mc12_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel8_mc22_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel8_mc32_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel8_mc03_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel8_mc13_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel8_mc23_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel8_mc33_neon(uint8_t *, uint8_t *, int);
-
-void ff_avg_h264_qpel16_mc00_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel16_mc10_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel16_mc20_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel16_mc30_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel16_mc01_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel16_mc11_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel16_mc21_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel16_mc31_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel16_mc02_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel16_mc12_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel16_mc22_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel16_mc32_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel16_mc03_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel16_mc13_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel16_mc23_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel16_mc33_neon(uint8_t *, uint8_t *, int);
-
-void ff_avg_h264_qpel8_mc00_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel8_mc10_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel8_mc20_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel8_mc30_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel8_mc01_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel8_mc11_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel8_mc21_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel8_mc31_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel8_mc02_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel8_mc12_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel8_mc22_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel8_mc32_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel8_mc03_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel8_mc13_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel8_mc23_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel8_mc33_neon(uint8_t *, uint8_t *, int);
-
-void ff_put_h264_chroma_mc8_neon(uint8_t *, uint8_t *, int, int, int, int);
-void ff_put_h264_chroma_mc4_neon(uint8_t *, uint8_t *, int, int, int, int);
-void ff_put_h264_chroma_mc2_neon(uint8_t *, uint8_t *, int, int, int, int);
-
-void ff_avg_h264_chroma_mc8_neon(uint8_t *, uint8_t *, int, int, int, int);
-void ff_avg_h264_chroma_mc4_neon(uint8_t *, uint8_t *, int, int, int, int);
-void ff_avg_h264_chroma_mc2_neon(uint8_t *, uint8_t *, int, int, int, int);
-
-void ff_vector_fmul_window_neon(float *dst, const float *src0,
-                                const float *src1, const float *win, int len);
-void ff_butterflies_float_neon(float *v1, float *v2, int len);
-float ff_scalarproduct_float_neon(const float *v1, const float *v2, int len);
-void ff_vector_fmul_reverse_neon(float *dst, const float *src0,
-                                 const float *src1, int len);
-void ff_vector_fmul_add_neon(float *dst, const float *src0, const float *src1,
-                             const float *src2, int len);
+void ff_add_pixels_clamped_neon(const int16_t *, uint8_t *, int);
+void ff_put_pixels_clamped_neon(const int16_t *, uint8_t *, int);
+void ff_put_signed_pixels_clamped_neon(const int16_t *, uint8_t *, int);
 
 void ff_vector_clipf_neon(float *dst, const float *src, float min, float max,
                           int len);
 void ff_vector_clip_int32_neon(int32_t *dst, const int32_t *src, int32_t min,
                                int32_t max, unsigned int len);
 
-void ff_vorbis_inverse_coupling_neon(float *mag, float *ang, int blocksize);
-
 int32_t ff_scalarproduct_int16_neon(const int16_t *v1, const int16_t *v2, int len);
 int32_t ff_scalarproduct_and_madd_int16_neon(int16_t *v1, const int16_t *v2,
                                              const int16_t *v3, int len, int mul);
@@ -165,7 +75,7 @@
 void ff_apply_window_int16_neon(int16_t *dst, const int16_t *src,
                                 const int16_t *window, unsigned n);
 
-void ff_dsputil_init_neon(DSPContext *c, AVCodecContext *avctx)
+av_cold void ff_dsputil_init_neon(DSPContext *c, AVCodecContext *avctx)
 {
     const int high_bit_depth = avctx->bits_per_raw_sample > 8;
 
@@ -210,109 +120,19 @@
         c->avg_pixels_tab[1][2] = ff_avg_pixels8_y2_neon;
         c->avg_pixels_tab[1][3] = ff_avg_pixels8_xy2_neon;
 
-        c->avg_no_rnd_pixels_tab[0][0] = ff_avg_pixels16_neon;
-        c->avg_no_rnd_pixels_tab[0][1] = ff_avg_pixels16_x2_no_rnd_neon;
-        c->avg_no_rnd_pixels_tab[0][2] = ff_avg_pixels16_y2_no_rnd_neon;
-        c->avg_no_rnd_pixels_tab[0][3] = ff_avg_pixels16_xy2_no_rnd_neon;
-        c->avg_no_rnd_pixels_tab[1][0] = ff_avg_pixels8_neon;
-        c->avg_no_rnd_pixels_tab[1][1] = ff_avg_pixels8_x2_no_rnd_neon;
-        c->avg_no_rnd_pixels_tab[1][2] = ff_avg_pixels8_y2_no_rnd_neon;
-        c->avg_no_rnd_pixels_tab[1][3] = ff_avg_pixels8_xy2_no_rnd_neon;
+        c->avg_no_rnd_pixels_tab[0] = ff_avg_pixels16_neon;
+        c->avg_no_rnd_pixels_tab[1] = ff_avg_pixels16_x2_no_rnd_neon;
+        c->avg_no_rnd_pixels_tab[2] = ff_avg_pixels16_y2_no_rnd_neon;
+        c->avg_no_rnd_pixels_tab[3] = ff_avg_pixels16_xy2_no_rnd_neon;
     }
 
     c->add_pixels_clamped = ff_add_pixels_clamped_neon;
     c->put_pixels_clamped = ff_put_pixels_clamped_neon;
     c->put_signed_pixels_clamped = ff_put_signed_pixels_clamped_neon;
 
-    if (CONFIG_H264_DECODER && !high_bit_depth) {
-        c->put_h264_chroma_pixels_tab[0] = ff_put_h264_chroma_mc8_neon;
-        c->put_h264_chroma_pixels_tab[1] = ff_put_h264_chroma_mc4_neon;
-        c->put_h264_chroma_pixels_tab[2] = ff_put_h264_chroma_mc2_neon;
-
-        c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_neon;
-        c->avg_h264_chroma_pixels_tab[1] = ff_avg_h264_chroma_mc4_neon;
-        c->avg_h264_chroma_pixels_tab[2] = ff_avg_h264_chroma_mc2_neon;
-
-        c->put_h264_qpel_pixels_tab[0][ 0] = ff_put_h264_qpel16_mc00_neon;
-        c->put_h264_qpel_pixels_tab[0][ 1] = ff_put_h264_qpel16_mc10_neon;
-        c->put_h264_qpel_pixels_tab[0][ 2] = ff_put_h264_qpel16_mc20_neon;
-        c->put_h264_qpel_pixels_tab[0][ 3] = ff_put_h264_qpel16_mc30_neon;
-        c->put_h264_qpel_pixels_tab[0][ 4] = ff_put_h264_qpel16_mc01_neon;
-        c->put_h264_qpel_pixels_tab[0][ 5] = ff_put_h264_qpel16_mc11_neon;
-        c->put_h264_qpel_pixels_tab[0][ 6] = ff_put_h264_qpel16_mc21_neon;
-        c->put_h264_qpel_pixels_tab[0][ 7] = ff_put_h264_qpel16_mc31_neon;
-        c->put_h264_qpel_pixels_tab[0][ 8] = ff_put_h264_qpel16_mc02_neon;
-        c->put_h264_qpel_pixels_tab[0][ 9] = ff_put_h264_qpel16_mc12_neon;
-        c->put_h264_qpel_pixels_tab[0][10] = ff_put_h264_qpel16_mc22_neon;
-        c->put_h264_qpel_pixels_tab[0][11] = ff_put_h264_qpel16_mc32_neon;
-        c->put_h264_qpel_pixels_tab[0][12] = ff_put_h264_qpel16_mc03_neon;
-        c->put_h264_qpel_pixels_tab[0][13] = ff_put_h264_qpel16_mc13_neon;
-        c->put_h264_qpel_pixels_tab[0][14] = ff_put_h264_qpel16_mc23_neon;
-        c->put_h264_qpel_pixels_tab[0][15] = ff_put_h264_qpel16_mc33_neon;
-
-        c->put_h264_qpel_pixels_tab[1][ 0] = ff_put_h264_qpel8_mc00_neon;
-        c->put_h264_qpel_pixels_tab[1][ 1] = ff_put_h264_qpel8_mc10_neon;
-        c->put_h264_qpel_pixels_tab[1][ 2] = ff_put_h264_qpel8_mc20_neon;
-        c->put_h264_qpel_pixels_tab[1][ 3] = ff_put_h264_qpel8_mc30_neon;
-        c->put_h264_qpel_pixels_tab[1][ 4] = ff_put_h264_qpel8_mc01_neon;
-        c->put_h264_qpel_pixels_tab[1][ 5] = ff_put_h264_qpel8_mc11_neon;
-        c->put_h264_qpel_pixels_tab[1][ 6] = ff_put_h264_qpel8_mc21_neon;
-        c->put_h264_qpel_pixels_tab[1][ 7] = ff_put_h264_qpel8_mc31_neon;
-        c->put_h264_qpel_pixels_tab[1][ 8] = ff_put_h264_qpel8_mc02_neon;
-        c->put_h264_qpel_pixels_tab[1][ 9] = ff_put_h264_qpel8_mc12_neon;
-        c->put_h264_qpel_pixels_tab[1][10] = ff_put_h264_qpel8_mc22_neon;
-        c->put_h264_qpel_pixels_tab[1][11] = ff_put_h264_qpel8_mc32_neon;
-        c->put_h264_qpel_pixels_tab[1][12] = ff_put_h264_qpel8_mc03_neon;
-        c->put_h264_qpel_pixels_tab[1][13] = ff_put_h264_qpel8_mc13_neon;
-        c->put_h264_qpel_pixels_tab[1][14] = ff_put_h264_qpel8_mc23_neon;
-        c->put_h264_qpel_pixels_tab[1][15] = ff_put_h264_qpel8_mc33_neon;
-
-        c->avg_h264_qpel_pixels_tab[0][ 0] = ff_avg_h264_qpel16_mc00_neon;
-        c->avg_h264_qpel_pixels_tab[0][ 1] = ff_avg_h264_qpel16_mc10_neon;
-        c->avg_h264_qpel_pixels_tab[0][ 2] = ff_avg_h264_qpel16_mc20_neon;
-        c->avg_h264_qpel_pixels_tab[0][ 3] = ff_avg_h264_qpel16_mc30_neon;
-        c->avg_h264_qpel_pixels_tab[0][ 4] = ff_avg_h264_qpel16_mc01_neon;
-        c->avg_h264_qpel_pixels_tab[0][ 5] = ff_avg_h264_qpel16_mc11_neon;
-        c->avg_h264_qpel_pixels_tab[0][ 6] = ff_avg_h264_qpel16_mc21_neon;
-        c->avg_h264_qpel_pixels_tab[0][ 7] = ff_avg_h264_qpel16_mc31_neon;
-        c->avg_h264_qpel_pixels_tab[0][ 8] = ff_avg_h264_qpel16_mc02_neon;
-        c->avg_h264_qpel_pixels_tab[0][ 9] = ff_avg_h264_qpel16_mc12_neon;
-        c->avg_h264_qpel_pixels_tab[0][10] = ff_avg_h264_qpel16_mc22_neon;
-        c->avg_h264_qpel_pixels_tab[0][11] = ff_avg_h264_qpel16_mc32_neon;
-        c->avg_h264_qpel_pixels_tab[0][12] = ff_avg_h264_qpel16_mc03_neon;
-        c->avg_h264_qpel_pixels_tab[0][13] = ff_avg_h264_qpel16_mc13_neon;
-        c->avg_h264_qpel_pixels_tab[0][14] = ff_avg_h264_qpel16_mc23_neon;
-        c->avg_h264_qpel_pixels_tab[0][15] = ff_avg_h264_qpel16_mc33_neon;
-
-        c->avg_h264_qpel_pixels_tab[1][ 0] = ff_avg_h264_qpel8_mc00_neon;
-        c->avg_h264_qpel_pixels_tab[1][ 1] = ff_avg_h264_qpel8_mc10_neon;
-        c->avg_h264_qpel_pixels_tab[1][ 2] = ff_avg_h264_qpel8_mc20_neon;
-        c->avg_h264_qpel_pixels_tab[1][ 3] = ff_avg_h264_qpel8_mc30_neon;
-        c->avg_h264_qpel_pixels_tab[1][ 4] = ff_avg_h264_qpel8_mc01_neon;
-        c->avg_h264_qpel_pixels_tab[1][ 5] = ff_avg_h264_qpel8_mc11_neon;
-        c->avg_h264_qpel_pixels_tab[1][ 6] = ff_avg_h264_qpel8_mc21_neon;
-        c->avg_h264_qpel_pixels_tab[1][ 7] = ff_avg_h264_qpel8_mc31_neon;
-        c->avg_h264_qpel_pixels_tab[1][ 8] = ff_avg_h264_qpel8_mc02_neon;
-        c->avg_h264_qpel_pixels_tab[1][ 9] = ff_avg_h264_qpel8_mc12_neon;
-        c->avg_h264_qpel_pixels_tab[1][10] = ff_avg_h264_qpel8_mc22_neon;
-        c->avg_h264_qpel_pixels_tab[1][11] = ff_avg_h264_qpel8_mc32_neon;
-        c->avg_h264_qpel_pixels_tab[1][12] = ff_avg_h264_qpel8_mc03_neon;
-        c->avg_h264_qpel_pixels_tab[1][13] = ff_avg_h264_qpel8_mc13_neon;
-        c->avg_h264_qpel_pixels_tab[1][14] = ff_avg_h264_qpel8_mc23_neon;
-        c->avg_h264_qpel_pixels_tab[1][15] = ff_avg_h264_qpel8_mc33_neon;
-    }
-
-    c->vector_fmul_window         = ff_vector_fmul_window_neon;
-    c->butterflies_float          = ff_butterflies_float_neon;
-    c->scalarproduct_float        = ff_scalarproduct_float_neon;
-    c->vector_fmul_reverse        = ff_vector_fmul_reverse_neon;
-    c->vector_fmul_add            = ff_vector_fmul_add_neon;
     c->vector_clipf               = ff_vector_clipf_neon;
     c->vector_clip_int32          = ff_vector_clip_int32_neon;
 
-    if (CONFIG_VORBIS_DECODER)
-        c->vorbis_inverse_coupling = ff_vorbis_inverse_coupling_neon;
-
     c->scalarproduct_int16 = ff_scalarproduct_int16_neon;
     c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_neon;
 
diff --git a/libavcodec/arm/dsputil_neon.S b/libavcodec/arm/dsputil_neon.S
index 610a2bb..89d3643 100644
--- a/libavcodec/arm/dsputil_neon.S
+++ b/libavcodec/arm/dsputil_neon.S
@@ -19,7 +19,6 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "config.h"
 #include "libavutil/arm/asm.S"
 
 function ff_clear_block_neon, export=1
@@ -422,9 +421,9 @@
 endfunc
 
         pixfunc         avg_, pixels8,     avg=1
-        pixfunc2        avg_, pixels8_x2,  avg=1
-        pixfunc2        avg_, pixels8_y2,  avg=1
-        pixfunc2        avg_, pixels8_xy2, avg=1
+        pixfunc         avg_, pixels8_x2,  avg=1
+        pixfunc         avg_, pixels8_y2,  avg=1
+        pixfunc         avg_, pixels8_xy2, avg=1
 
 function ff_put_pixels_clamped_neon, export=1
         vld1.16         {d16-d19}, [r0,:128]!
@@ -532,192 +531,6 @@
         bx              lr
 endfunc
 
-function ff_vector_fmul_window_neon, export=1
-        push            {r4,r5,lr}
-        ldr             lr,  [sp, #12]
-        sub             r2,  r2,  #8
-        sub             r5,  lr,  #2
-        add             r2,  r2,  r5, lsl #2
-        add             r4,  r3,  r5, lsl #3
-        add             ip,  r0,  r5, lsl #3
-        mov             r5,  #-16
-        vld1.32         {d0,d1},  [r1,:128]!
-        vld1.32         {d2,d3},  [r2,:128], r5
-        vld1.32         {d4,d5},  [r3,:128]!
-        vld1.32         {d6,d7},  [r4,:128], r5
-1:      subs            lr,  lr,  #4
-        vmul.f32        d22, d0,  d4
-        vrev64.32       q3,  q3
-        vmul.f32        d23, d1,  d5
-        vrev64.32       q1,  q1
-        vmul.f32        d20, d0,  d7
-        vmul.f32        d21, d1,  d6
-        beq             2f
-        vmla.f32        d22, d3,  d7
-        vld1.32         {d0,d1},  [r1,:128]!
-        vmla.f32        d23, d2,  d6
-        vld1.32         {d18,d19},[r2,:128], r5
-        vmls.f32        d20, d3,  d4
-        vld1.32         {d24,d25},[r3,:128]!
-        vmls.f32        d21, d2,  d5
-        vld1.32         {d6,d7},  [r4,:128], r5
-        vmov            q1,  q9
-        vrev64.32       q11, q11
-        vmov            q2,  q12
-        vswp            d22, d23
-        vst1.32         {d20,d21},[r0,:128]!
-        vst1.32         {d22,d23},[ip,:128], r5
-        b               1b
-2:      vmla.f32        d22, d3,  d7
-        vmla.f32        d23, d2,  d6
-        vmls.f32        d20, d3,  d4
-        vmls.f32        d21, d2,  d5
-        vrev64.32       q11, q11
-        vswp            d22, d23
-        vst1.32         {d20,d21},[r0,:128]!
-        vst1.32         {d22,d23},[ip,:128], r5
-        pop             {r4,r5,pc}
-endfunc
-
-#if CONFIG_VORBIS_DECODER
-function ff_vorbis_inverse_coupling_neon, export=1
-        vmov.i32        q10, #1<<31
-        subs            r2,  r2,  #4
-        mov             r3,  r0
-        mov             r12, r1
-        beq             3f
-
-        vld1.32         {d24-d25},[r1,:128]!
-        vld1.32         {d22-d23},[r0,:128]!
-        vcle.s32        q8,  q12, #0
-        vand            q9,  q11, q10
-        veor            q12, q12, q9
-        vand            q2,  q12, q8
-        vbic            q3,  q12, q8
-        vadd.f32        q12, q11, q2
-        vsub.f32        q11, q11, q3
-1:      vld1.32         {d2-d3},  [r1,:128]!
-        vld1.32         {d0-d1},  [r0,:128]!
-        vcle.s32        q8,  q1,  #0
-        vand            q9,  q0,  q10
-        veor            q1,  q1,  q9
-        vst1.32         {d24-d25},[r3, :128]!
-        vst1.32         {d22-d23},[r12,:128]!
-        vand            q2,  q1,  q8
-        vbic            q3,  q1,  q8
-        vadd.f32        q1,  q0,  q2
-        vsub.f32        q0,  q0,  q3
-        subs            r2,  r2,  #8
-        ble             2f
-        vld1.32         {d24-d25},[r1,:128]!
-        vld1.32         {d22-d23},[r0,:128]!
-        vcle.s32        q8,  q12, #0
-        vand            q9,  q11, q10
-        veor            q12, q12, q9
-        vst1.32         {d2-d3},  [r3, :128]!
-        vst1.32         {d0-d1},  [r12,:128]!
-        vand            q2,  q12, q8
-        vbic            q3,  q12, q8
-        vadd.f32        q12, q11, q2
-        vsub.f32        q11, q11, q3
-        b               1b
-
-2:      vst1.32         {d2-d3},  [r3, :128]!
-        vst1.32         {d0-d1},  [r12,:128]!
-        it              lt
-        bxlt            lr
-
-3:      vld1.32         {d2-d3},  [r1,:128]
-        vld1.32         {d0-d1},  [r0,:128]
-        vcle.s32        q8,  q1,  #0
-        vand            q9,  q0,  q10
-        veor            q1,  q1,  q9
-        vand            q2,  q1,  q8
-        vbic            q3,  q1,  q8
-        vadd.f32        q1,  q0,  q2
-        vsub.f32        q0,  q0,  q3
-        vst1.32         {d2-d3},  [r0,:128]!
-        vst1.32         {d0-d1},  [r1,:128]!
-        bx              lr
-endfunc
-#endif
-
-function ff_butterflies_float_neon, export=1
-1:      vld1.32         {q0},[r0,:128]
-        vld1.32         {q1},[r1,:128]
-        vsub.f32        q2,  q0,  q1
-        vadd.f32        q1,  q0,  q1
-        vst1.32         {q2},[r1,:128]!
-        vst1.32         {q1},[r0,:128]!
-        subs            r2,  r2,  #4
-        bgt             1b
-        bx              lr
-endfunc
-
-function ff_scalarproduct_float_neon, export=1
-        vmov.f32        q2,  #0.0
-1:      vld1.32         {q0},[r0,:128]!
-        vld1.32         {q1},[r1,:128]!
-        vmla.f32        q2,  q0,  q1
-        subs            r2,  r2,  #4
-        bgt             1b
-        vadd.f32        d0,  d4,  d5
-        vpadd.f32       d0,  d0,  d0
-NOVFP   vmov.32         r0,  d0[0]
-        bx              lr
-endfunc
-
-function ff_vector_fmul_reverse_neon, export=1
-        add             r2,  r2,  r3,  lsl #2
-        sub             r2,  r2,  #32
-        mov             r12, #-32
-        vld1.32         {q0-q1},  [r1,:128]!
-        vld1.32         {q2-q3},  [r2,:128], r12
-1:      pld             [r1, #32]
-        vrev64.32       q3,  q3
-        vmul.f32        d16, d0,  d7
-        vmul.f32        d17, d1,  d6
-        pld             [r2, #-32]
-        vrev64.32       q2,  q2
-        vmul.f32        d18, d2,  d5
-        vmul.f32        d19, d3,  d4
-        subs            r3,  r3,  #8
-        beq             2f
-        vld1.32         {q0-q1},  [r1,:128]!
-        vld1.32         {q2-q3},  [r2,:128], r12
-        vst1.32         {q8-q9},  [r0,:128]!
-        b               1b
-2:      vst1.32         {q8-q9},  [r0,:128]!
-        bx              lr
-endfunc
-
-function ff_vector_fmul_add_neon, export=1
-        ldr             r12, [sp]
-        vld1.32         {q0-q1},  [r1,:128]!
-        vld1.32         {q8-q9},  [r2,:128]!
-        vld1.32         {q2-q3},  [r3,:128]!
-        vmul.f32        q10, q0,  q8
-        vmul.f32        q11, q1,  q9
-1:      vadd.f32        q12, q2,  q10
-        vadd.f32        q13, q3,  q11
-        pld             [r1, #16]
-        pld             [r2, #16]
-        pld             [r3, #16]
-        subs            r12, r12, #8
-        beq             2f
-        vld1.32         {q0},     [r1,:128]!
-        vld1.32         {q8},     [r2,:128]!
-        vmul.f32        q10, q0,  q8
-        vld1.32         {q1},     [r1,:128]!
-        vld1.32         {q9},     [r2,:128]!
-        vmul.f32        q11, q1,  q9
-        vld1.32         {q2-q3},  [r3,:128]!
-        vst1.32         {q12-q13},[r0,:128]!
-        b               1b
-2:      vst1.32         {q12-q13},[r0,:128]!
-        bx              lr
-endfunc
-
 function ff_vector_clipf_neon, export=1
 VFP     vdup.32         q1,  d0[1]
 VFP     vdup.32         q0,  d0[0]
diff --git a/libavcodec/arm/dsputil_vfp.S b/libavcodec/arm/dsputil_vfp.S
deleted file mode 100644
index 63ba766..0000000
--- a/libavcodec/arm/dsputil_vfp.S
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (c) 2008 Siarhei Siamashka <ssvb@users.sourceforge.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
- */
-
-#include "config.h"
-#include "libavutil/arm/asm.S"
-
-/*
- * VFP is a floating point coprocessor used in some ARM cores. VFP11 has 1 cycle
- * throughput for almost all the instructions (except for double precision
- * arithmetics), but rather high latency. Latency is 4 cycles for loads and 8 cycles
- * for arithmetic operations. Scheduling code to avoid pipeline stalls is very
- * important for performance. One more interesting feature is that VFP has
- * independent load/store and arithmetics pipelines, so it is possible to make
- * them work simultaneously and get more than 1 operation per cycle. Load/store
- * pipeline can process 2 single precision floating point values per cycle and
- * supports bulk loads and stores for large sets of registers. Arithmetic operations
- * can be done on vectors, which allows to keep the arithmetics pipeline busy,
- * while the processor may issue and execute other instructions. Detailed
- * optimization manuals can be found at http://www.arm.com
- */
-
-/**
- * ARM VFP optimized implementation of 'vector_fmul_reverse_c' function.
- * Assume that len is a positive number and is multiple of 8
- */
-@ void ff_vector_fmul_reverse_vfp(float *dst, const float *src0,
-@                                 const float *src1, int len)
-function ff_vector_fmul_reverse_vfp, export=1
-        vpush           {d8-d15}
-        add             r2,  r2,  r3, lsl #2
-        vldmdb          r2!, {s0-s3}
-        vldmia          r1!, {s8-s11}
-        vldmdb          r2!, {s4-s7}
-        vldmia          r1!, {s12-s15}
-        vmul.f32        s8,  s3,  s8
-        vmul.f32        s9,  s2,  s9
-        vmul.f32        s10, s1,  s10
-        vmul.f32        s11, s0,  s11
-1:
-        subs            r3,  r3,  #16
-        it              ge
-        vldmdbge        r2!, {s16-s19}
-        vmul.f32        s12, s7,  s12
-        it              ge
-        vldmiage        r1!, {s24-s27}
-        vmul.f32        s13, s6,  s13
-        it              ge
-        vldmdbge        r2!, {s20-s23}
-        vmul.f32        s14, s5,  s14
-        it              ge
-        vldmiage        r1!, {s28-s31}
-        vmul.f32        s15, s4,  s15
-        it              ge
-        vmulge.f32      s24, s19, s24
-        it              gt
-        vldmdbgt        r2!, {s0-s3}
-        it              ge
-        vmulge.f32      s25, s18, s25
-        vstmia          r0!, {s8-s13}
-        it              ge
-        vmulge.f32      s26, s17, s26
-        it              gt
-        vldmiagt        r1!, {s8-s11}
-        itt             ge
-        vmulge.f32      s27, s16, s27
-        vmulge.f32      s28, s23, s28
-        it              gt
-        vldmdbgt        r2!, {s4-s7}
-        it              ge
-        vmulge.f32      s29, s22, s29
-        vstmia          r0!, {s14-s15}
-        ittt            ge
-        vmulge.f32      s30, s21, s30
-        vmulge.f32      s31, s20, s31
-        vmulge.f32      s8,  s3,  s8
-        it              gt
-        vldmiagt        r1!, {s12-s15}
-        itttt           ge
-        vmulge.f32      s9,  s2,  s9
-        vmulge.f32      s10, s1,  s10
-        vstmiage        r0!, {s24-s27}
-        vmulge.f32      s11, s0,  s11
-        it              ge
-        vstmiage        r0!, {s28-s31}
-        bgt             1b
-
-        vpop            {d8-d15}
-        bx              lr
-endfunc
diff --git a/libavcodec/arm/fft_fixed_init_arm.c b/libavcodec/arm/fft_fixed_init_arm.c
index 7cf8a6e..ef098f4 100644
--- a/libavcodec/arm/fft_fixed_init_arm.c
+++ b/libavcodec/arm/fft_fixed_init_arm.c
@@ -33,10 +33,12 @@
 
     if (have_neon(cpu_flags)) {
         s->fft_permutation = FF_FFT_PERM_SWAP_LSBS;
+#if CONFIG_FFT
         s->fft_calc        = ff_fft_fixed_calc_neon;
+#endif
 
 #if CONFIG_MDCT
-        if (!s->inverse && s->mdct_bits >= 5) {
+        if (!s->inverse && s->nbits >= 3) {
             s->mdct_permutation = FF_MDCT_PERM_INTERLEAVE;
             s->mdct_calc        = ff_mdct_fixed_calc_neon;
             s->mdct_calcw       = ff_mdct_fixed_calcw_neon;
diff --git a/libavcodec/arm/fft_init_arm.c b/libavcodec/arm/fft_init_arm.c
index 12d28a3..8c98abc 100644
--- a/libavcodec/arm/fft_init_arm.c
+++ b/libavcodec/arm/fft_init_arm.c
@@ -43,8 +43,10 @@
     int cpu_flags = av_get_cpu_flags();
 
     if (have_neon(cpu_flags)) {
+#if CONFIG_FFT
         s->fft_permute  = ff_fft_permute_neon;
         s->fft_calc     = ff_fft_calc_neon;
+#endif
 #if CONFIG_MDCT
         s->imdct_calc   = ff_imdct_calc_neon;
         s->imdct_half   = ff_imdct_half_neon;
diff --git a/libavcodec/arm/fmtconvert_init_arm.c b/libavcodec/arm/fmtconvert_init_arm.c
index 5b3e3c1..1d99c97 100644
--- a/libavcodec/arm/fmtconvert_init_arm.c
+++ b/libavcodec/arm/fmtconvert_init_arm.c
@@ -20,6 +20,7 @@
 
 #include <stdint.h>
 
+#include "libavutil/attributes.h"
 #include "libavutil/arm/cpu.h"
 #include "libavcodec/avcodec.h"
 #include "libavcodec/fmtconvert.h"
@@ -32,7 +33,7 @@
 
 void ff_float_to_int16_vfp(int16_t *dst, const float *src, long len);
 
-void ff_fmt_convert_init_arm(FmtConvertContext *c, AVCodecContext *avctx)
+av_cold void ff_fmt_convert_init_arm(FmtConvertContext *c, AVCodecContext *avctx)
 {
     int cpu_flags = av_get_cpu_flags();
 
diff --git a/libavcodec/arm/fmtconvert_vfp.S b/libavcodec/arm/fmtconvert_vfp.S
index 4bdbe82..7b012bc 100644
--- a/libavcodec/arm/fmtconvert_vfp.S
+++ b/libavcodec/arm/fmtconvert_vfp.S
@@ -25,7 +25,7 @@
  * ARM VFP optimized float to int16 conversion.
  * Assume that len is a positive number and is multiple of 8, destination
  * buffer is at least 4 bytes aligned (8 bytes alignment is better for
- * performance), little endian byte sex
+ * performance), little-endian byte sex.
  */
 @ void ff_float_to_int16_vfp(int16_t *dst, const float *src, int len)
 function ff_float_to_int16_vfp, export=1
diff --git a/libavcodec/arm/h264chroma_init_arm.c b/libavcodec/arm/h264chroma_init_arm.c
new file mode 100644
index 0000000..13f7e0d
--- /dev/null
+++ b/libavcodec/arm/h264chroma_init_arm.c
@@ -0,0 +1,51 @@
+/*
+ * ARM NEON optimised H.264 chroma functions
+ * Copyright (c) 2008 Mans Rullgard <mans@mansr.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 <stdint.h>
+
+#include "libavutil/attributes.h"
+#include "libavutil/cpu.h"
+#include "libavutil/arm/cpu.h"
+#include "libavcodec/h264chroma.h"
+
+void ff_put_h264_chroma_mc8_neon(uint8_t *, uint8_t *, int, int, int, int);
+void ff_put_h264_chroma_mc4_neon(uint8_t *, uint8_t *, int, int, int, int);
+void ff_put_h264_chroma_mc2_neon(uint8_t *, uint8_t *, int, int, int, int);
+
+void ff_avg_h264_chroma_mc8_neon(uint8_t *, uint8_t *, int, int, int, int);
+void ff_avg_h264_chroma_mc4_neon(uint8_t *, uint8_t *, int, int, int, int);
+void ff_avg_h264_chroma_mc2_neon(uint8_t *, uint8_t *, int, int, int, int);
+
+av_cold void ff_h264chroma_init_arm(H264ChromaContext *c, int bit_depth)
+{
+    const int high_bit_depth = bit_depth > 8;
+    int cpu_flags = av_get_cpu_flags();
+
+    if (have_neon(cpu_flags) && !high_bit_depth) {
+        c->put_h264_chroma_pixels_tab[0] = ff_put_h264_chroma_mc8_neon;
+        c->put_h264_chroma_pixels_tab[1] = ff_put_h264_chroma_mc4_neon;
+        c->put_h264_chroma_pixels_tab[2] = ff_put_h264_chroma_mc2_neon;
+
+        c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_neon;
+        c->avg_h264_chroma_pixels_tab[1] = ff_avg_h264_chroma_mc4_neon;
+        c->avg_h264_chroma_pixels_tab[2] = ff_avg_h264_chroma_mc2_neon;
+    }
+}
diff --git a/libavcodec/arm/h264dsp_init_arm.c b/libavcodec/arm/h264dsp_init_arm.c
index f150a45..785b604 100644
--- a/libavcodec/arm/h264dsp_init_arm.c
+++ b/libavcodec/arm/h264dsp_init_arm.c
@@ -20,8 +20,8 @@
 
 #include <stdint.h>
 
+#include "libavutil/attributes.h"
 #include "libavutil/arm/cpu.h"
-#include "libavcodec/dsputil.h"
 #include "libavcodec/h264dsp.h"
 
 void ff_h264_v_loop_filter_luma_neon(uint8_t *pix, int stride, int alpha,
@@ -50,25 +50,26 @@
                                     int height, int log2_den, int weightd,
                                     int weights, int offset);
 
-void ff_h264_idct_add_neon(uint8_t *dst, DCTELEM *block, int stride);
-void ff_h264_idct_dc_add_neon(uint8_t *dst, DCTELEM *block, int stride);
+void ff_h264_idct_add_neon(uint8_t *dst, int16_t *block, int stride);
+void ff_h264_idct_dc_add_neon(uint8_t *dst, int16_t *block, int stride);
 void ff_h264_idct_add16_neon(uint8_t *dst, const int *block_offset,
-                             DCTELEM *block, int stride,
+                             int16_t *block, int stride,
                              const uint8_t nnzc[6*8]);
 void ff_h264_idct_add16intra_neon(uint8_t *dst, const int *block_offset,
-                                  DCTELEM *block, int stride,
+                                  int16_t *block, int stride,
                                   const uint8_t nnzc[6*8]);
 void ff_h264_idct_add8_neon(uint8_t **dest, const int *block_offset,
-                            DCTELEM *block, int stride,
+                            int16_t *block, int stride,
                             const uint8_t nnzc[6*8]);
 
-void ff_h264_idct8_add_neon(uint8_t *dst, DCTELEM *block, int stride);
-void ff_h264_idct8_dc_add_neon(uint8_t *dst, DCTELEM *block, int stride);
+void ff_h264_idct8_add_neon(uint8_t *dst, int16_t *block, int stride);
+void ff_h264_idct8_dc_add_neon(uint8_t *dst, int16_t *block, int stride);
 void ff_h264_idct8_add4_neon(uint8_t *dst, const int *block_offset,
-                             DCTELEM *block, int stride,
+                             int16_t *block, int stride,
                              const uint8_t nnzc[6*8]);
 
-static void ff_h264dsp_init_neon(H264DSPContext *c, const int bit_depth, const int chroma_format_idc)
+static av_cold void ff_h264dsp_init_neon(H264DSPContext *c, const int bit_depth,
+                                         const int chroma_format_idc)
 {
 #if HAVE_NEON
     if (bit_depth == 8) {
@@ -100,7 +101,8 @@
 #endif // HAVE_NEON
 }
 
-void ff_h264dsp_init_arm(H264DSPContext *c, const int bit_depth, const int chroma_format_idc)
+av_cold void ff_h264dsp_init_arm(H264DSPContext *c, const int bit_depth,
+                                 const int chroma_format_idc)
 {
     int cpu_flags = av_get_cpu_flags();
 
diff --git a/libavcodec/arm/h264dsp_neon.S b/libavcodec/arm/h264dsp_neon.S
index be0d2ec..274a547 100644
--- a/libavcodec/arm/h264dsp_neon.S
+++ b/libavcodec/arm/h264dsp_neon.S
@@ -271,939 +271,6 @@
         bx              lr
 endfunc
 
-        /* H.264 qpel MC */
-
-.macro  lowpass_const   r
-        movw            \r,  #5
-        movt            \r,  #20
-        vmov.32         d6[0], \r
-.endm
-
-.macro  lowpass_8       r0,  r1,  r2,  r3,  d0,  d1,  narrow=1
-  .if \narrow
-        t0 .req q0
-        t1 .req q8
-  .else
-        t0 .req \d0
-        t1 .req \d1
-  .endif
-        vext.8          d2,  \r0, \r1, #2
-        vext.8          d3,  \r0, \r1, #3
-        vaddl.u8        q1,  d2,  d3
-        vext.8          d4,  \r0, \r1, #1
-        vext.8          d5,  \r0, \r1, #4
-        vaddl.u8        q2,  d4,  d5
-        vext.8          d30, \r0, \r1, #5
-        vaddl.u8        t0,  \r0, d30
-        vext.8          d18, \r2, \r3, #2
-        vmla.i16        t0,  q1,  d6[1]
-        vext.8          d19, \r2, \r3, #3
-        vaddl.u8        q9,  d18, d19
-        vext.8          d20, \r2, \r3, #1
-        vmls.i16        t0,  q2,  d6[0]
-        vext.8          d21, \r2, \r3, #4
-        vaddl.u8        q10, d20, d21
-        vext.8          d31, \r2, \r3, #5
-        vaddl.u8        t1,  \r2, d31
-        vmla.i16        t1,  q9,  d6[1]
-        vmls.i16        t1,  q10, d6[0]
-  .if \narrow
-        vqrshrun.s16    \d0, t0,  #5
-        vqrshrun.s16    \d1, t1,  #5
-  .endif
-        .unreq  t0
-        .unreq  t1
-.endm
-
-.macro  lowpass_8_1     r0,  r1,  d0,  narrow=1
-  .if \narrow
-        t0 .req q0
-  .else
-        t0 .req \d0
-  .endif
-        vext.8          d2,  \r0, \r1, #2
-        vext.8          d3,  \r0, \r1, #3
-        vaddl.u8        q1,  d2,  d3
-        vext.8          d4,  \r0, \r1, #1
-        vext.8          d5,  \r0, \r1, #4
-        vaddl.u8        q2,  d4,  d5
-        vext.8          d30, \r0, \r1, #5
-        vaddl.u8        t0,  \r0, d30
-        vmla.i16        t0,  q1,  d6[1]
-        vmls.i16        t0,  q2,  d6[0]
-  .if \narrow
-        vqrshrun.s16    \d0, t0,  #5
-  .endif
-        .unreq  t0
-.endm
-
-.macro  lowpass_8.16    r0,  r1,  l0,  h0,  l1,  h1,  d
-        vext.16         q1,  \r0, \r1, #2
-        vext.16         q0,  \r0, \r1, #3
-        vaddl.s16       q9,  d2,  d0
-        vext.16         q2,  \r0, \r1, #1
-        vaddl.s16       q1,  d3,  d1
-        vext.16         q3,  \r0, \r1, #4
-        vaddl.s16       q10, d4,  d6
-        vext.16         \r1, \r0, \r1, #5
-        vaddl.s16       q2,  d5,  d7
-        vaddl.s16       q0,  \h0, \h1
-        vaddl.s16       q8,  \l0, \l1
-
-        vshl.i32        q3,  q9,  #4
-        vshl.i32        q9,  q9,  #2
-        vshl.i32        q15, q10, #2
-        vadd.i32        q9,  q9,  q3
-        vadd.i32        q10, q10, q15
-
-        vshl.i32        q3,  q1,  #4
-        vshl.i32        q1,  q1,  #2
-        vshl.i32        q15, q2,  #2
-        vadd.i32        q1,  q1,  q3
-        vadd.i32        q2,  q2,  q15
-
-        vadd.i32        q9,  q9,  q8
-        vsub.i32        q9,  q9,  q10
-
-        vadd.i32        q1,  q1,  q0
-        vsub.i32        q1,  q1,  q2
-
-        vrshrn.s32      d18, q9,  #10
-        vrshrn.s32      d19, q1,  #10
-
-        vqmovun.s16     \d,  q9
-.endm
-
-function put_h264_qpel16_h_lowpass_neon_packed
-        mov             r4,  lr
-        mov             r12, #16
-        mov             r3,  #8
-        bl              put_h264_qpel8_h_lowpass_neon
-        sub             r1,  r1,  r2, lsl #4
-        add             r1,  r1,  #8
-        mov             r12, #16
-        mov             lr,  r4
-        b               put_h264_qpel8_h_lowpass_neon
-endfunc
-
-.macro  h264_qpel_h_lowpass type
-function \type\()_h264_qpel16_h_lowpass_neon
-        push            {lr}
-        mov             r12, #16
-        bl              \type\()_h264_qpel8_h_lowpass_neon
-        sub             r0,  r0,  r3, lsl #4
-        sub             r1,  r1,  r2, lsl #4
-        add             r0,  r0,  #8
-        add             r1,  r1,  #8
-        mov             r12, #16
-        pop             {lr}
-endfunc
-
-function \type\()_h264_qpel8_h_lowpass_neon
-1:      vld1.8          {d0, d1},  [r1], r2
-        vld1.8          {d16,d17}, [r1], r2
-        subs            r12, r12, #2
-        lowpass_8       d0,  d1,  d16, d17, d0,  d16
-  .ifc \type,avg
-        vld1.8          {d2},     [r0,:64], r3
-        vrhadd.u8       d0,  d0,  d2
-        vld1.8          {d3},     [r0,:64]
-        vrhadd.u8       d16, d16, d3
-        sub             r0,  r0,  r3
-  .endif
-        vst1.8          {d0},     [r0,:64], r3
-        vst1.8          {d16},    [r0,:64], r3
-        bne             1b
-        bx              lr
-endfunc
-.endm
-
-        h264_qpel_h_lowpass put
-        h264_qpel_h_lowpass avg
-
-.macro  h264_qpel_h_lowpass_l2 type
-function \type\()_h264_qpel16_h_lowpass_l2_neon
-        push            {lr}
-        mov             r12, #16
-        bl              \type\()_h264_qpel8_h_lowpass_l2_neon
-        sub             r0,  r0,  r2, lsl #4
-        sub             r1,  r1,  r2, lsl #4
-        sub             r3,  r3,  r2, lsl #4
-        add             r0,  r0,  #8
-        add             r1,  r1,  #8
-        add             r3,  r3,  #8
-        mov             r12, #16
-        pop             {lr}
-endfunc
-
-function \type\()_h264_qpel8_h_lowpass_l2_neon
-1:      vld1.8          {d0, d1},  [r1], r2
-        vld1.8          {d16,d17}, [r1], r2
-        vld1.8          {d28},     [r3], r2
-        vld1.8          {d29},     [r3], r2
-        subs            r12, r12, #2
-        lowpass_8       d0,  d1,  d16, d17, d0,  d1
-        vrhadd.u8       q0,  q0,  q14
-  .ifc \type,avg
-        vld1.8          {d2},      [r0,:64], r2
-        vrhadd.u8       d0,  d0,  d2
-        vld1.8          {d3},      [r0,:64]
-        vrhadd.u8       d1,  d1,  d3
-        sub             r0,  r0,  r2
-  .endif
-        vst1.8          {d0},      [r0,:64], r2
-        vst1.8          {d1},      [r0,:64], r2
-        bne             1b
-        bx              lr
-endfunc
-.endm
-
-        h264_qpel_h_lowpass_l2 put
-        h264_qpel_h_lowpass_l2 avg
-
-function put_h264_qpel16_v_lowpass_neon_packed
-        mov             r4,  lr
-        mov             r2,  #8
-        bl              put_h264_qpel8_v_lowpass_neon
-        sub             r1,  r1,  r3, lsl #2
-        bl              put_h264_qpel8_v_lowpass_neon
-        sub             r1,  r1,  r3, lsl #4
-        sub             r1,  r1,  r3, lsl #2
-        add             r1,  r1,  #8
-        bl              put_h264_qpel8_v_lowpass_neon
-        sub             r1,  r1,  r3, lsl #2
-        mov             lr,  r4
-        b               put_h264_qpel8_v_lowpass_neon
-endfunc
-
-.macro  h264_qpel_v_lowpass type
-function \type\()_h264_qpel16_v_lowpass_neon
-        mov             r4,  lr
-        bl              \type\()_h264_qpel8_v_lowpass_neon
-        sub             r1,  r1,  r3, lsl #2
-        bl              \type\()_h264_qpel8_v_lowpass_neon
-        sub             r0,  r0,  r2, lsl #4
-        add             r0,  r0,  #8
-        sub             r1,  r1,  r3, lsl #4
-        sub             r1,  r1,  r3, lsl #2
-        add             r1,  r1,  #8
-        bl              \type\()_h264_qpel8_v_lowpass_neon
-        sub             r1,  r1,  r3, lsl #2
-        mov             lr,  r4
-endfunc
-
-function \type\()_h264_qpel8_v_lowpass_neon
-        vld1.8          {d8},  [r1], r3
-        vld1.8          {d10}, [r1], r3
-        vld1.8          {d12}, [r1], r3
-        vld1.8          {d14}, [r1], r3
-        vld1.8          {d22}, [r1], r3
-        vld1.8          {d24}, [r1], r3
-        vld1.8          {d26}, [r1], r3
-        vld1.8          {d28}, [r1], r3
-        vld1.8          {d9},  [r1], r3
-        vld1.8          {d11}, [r1], r3
-        vld1.8          {d13}, [r1], r3
-        vld1.8          {d15}, [r1], r3
-        vld1.8          {d23}, [r1]
-
-        transpose_8x8   q4,  q5,  q6,  q7,  q11, q12, q13, q14
-        lowpass_8       d8,  d9,  d10, d11, d8,  d10
-        lowpass_8       d12, d13, d14, d15, d12, d14
-        lowpass_8       d22, d23, d24, d25, d22, d24
-        lowpass_8       d26, d27, d28, d29, d26, d28
-        transpose_8x8   d8,  d10, d12, d14, d22, d24, d26, d28
-
-  .ifc \type,avg
-        vld1.8          {d9},  [r0,:64], r2
-        vrhadd.u8       d8,  d8,  d9
-        vld1.8          {d11}, [r0,:64], r2
-        vrhadd.u8       d10, d10, d11
-        vld1.8          {d13}, [r0,:64], r2
-        vrhadd.u8       d12, d12, d13
-        vld1.8          {d15}, [r0,:64], r2
-        vrhadd.u8       d14, d14, d15
-        vld1.8          {d23}, [r0,:64], r2
-        vrhadd.u8       d22, d22, d23
-        vld1.8          {d25}, [r0,:64], r2
-        vrhadd.u8       d24, d24, d25
-        vld1.8          {d27}, [r0,:64], r2
-        vrhadd.u8       d26, d26, d27
-        vld1.8          {d29}, [r0,:64], r2
-        vrhadd.u8       d28, d28, d29
-        sub             r0,  r0,  r2,  lsl #3
-  .endif
-
-        vst1.8          {d8},  [r0,:64], r2
-        vst1.8          {d10}, [r0,:64], r2
-        vst1.8          {d12}, [r0,:64], r2
-        vst1.8          {d14}, [r0,:64], r2
-        vst1.8          {d22}, [r0,:64], r2
-        vst1.8          {d24}, [r0,:64], r2
-        vst1.8          {d26}, [r0,:64], r2
-        vst1.8          {d28}, [r0,:64], r2
-
-        bx              lr
-endfunc
-.endm
-
-        h264_qpel_v_lowpass put
-        h264_qpel_v_lowpass avg
-
-.macro  h264_qpel_v_lowpass_l2 type
-function \type\()_h264_qpel16_v_lowpass_l2_neon
-        mov             r4,  lr
-        bl              \type\()_h264_qpel8_v_lowpass_l2_neon
-        sub             r1,  r1,  r3, lsl #2
-        bl              \type\()_h264_qpel8_v_lowpass_l2_neon
-        sub             r0,  r0,  r3, lsl #4
-        sub             r12, r12, r2, lsl #4
-        add             r0,  r0,  #8
-        add             r12, r12, #8
-        sub             r1,  r1,  r3, lsl #4
-        sub             r1,  r1,  r3, lsl #2
-        add             r1,  r1,  #8
-        bl              \type\()_h264_qpel8_v_lowpass_l2_neon
-        sub             r1,  r1,  r3, lsl #2
-        mov             lr,  r4
-endfunc
-
-function \type\()_h264_qpel8_v_lowpass_l2_neon
-        vld1.8          {d8},  [r1], r3
-        vld1.8          {d10}, [r1], r3
-        vld1.8          {d12}, [r1], r3
-        vld1.8          {d14}, [r1], r3
-        vld1.8          {d22}, [r1], r3
-        vld1.8          {d24}, [r1], r3
-        vld1.8          {d26}, [r1], r3
-        vld1.8          {d28}, [r1], r3
-        vld1.8          {d9},  [r1], r3
-        vld1.8          {d11}, [r1], r3
-        vld1.8          {d13}, [r1], r3
-        vld1.8          {d15}, [r1], r3
-        vld1.8          {d23}, [r1]
-
-        transpose_8x8   q4,  q5,  q6,  q7,  q11, q12, q13, q14
-        lowpass_8       d8,  d9,  d10, d11, d8,  d9
-        lowpass_8       d12, d13, d14, d15, d12, d13
-        lowpass_8       d22, d23, d24, d25, d22, d23
-        lowpass_8       d26, d27, d28, d29, d26, d27
-        transpose_8x8   d8,  d9,  d12, d13, d22, d23, d26, d27
-
-        vld1.8          {d0},  [r12], r2
-        vld1.8          {d1},  [r12], r2
-        vld1.8          {d2},  [r12], r2
-        vld1.8          {d3},  [r12], r2
-        vld1.8          {d4},  [r12], r2
-        vrhadd.u8       q0,  q0,  q4
-        vld1.8          {d5},  [r12], r2
-        vrhadd.u8       q1,  q1,  q6
-        vld1.8          {d10}, [r12], r2
-        vrhadd.u8       q2,  q2,  q11
-        vld1.8          {d11}, [r12], r2
-        vrhadd.u8       q5,  q5,  q13
-
-  .ifc \type,avg
-        vld1.8          {d16}, [r0,:64], r3
-        vrhadd.u8       d0,  d0,  d16
-        vld1.8          {d17}, [r0,:64], r3
-        vrhadd.u8       d1,  d1,  d17
-        vld1.8          {d16}, [r0,:64], r3
-        vrhadd.u8       d2,  d2,  d16
-        vld1.8          {d17}, [r0,:64], r3
-        vrhadd.u8       d3,  d3,  d17
-        vld1.8          {d16}, [r0,:64], r3
-        vrhadd.u8       d4,  d4,  d16
-        vld1.8          {d17}, [r0,:64], r3
-        vrhadd.u8       d5,  d5,  d17
-        vld1.8          {d16}, [r0,:64], r3
-        vrhadd.u8       d10, d10, d16
-        vld1.8          {d17}, [r0,:64], r3
-        vrhadd.u8       d11, d11, d17
-        sub             r0,  r0,  r3,  lsl #3
-  .endif
-
-        vst1.8          {d0},  [r0,:64], r3
-        vst1.8          {d1},  [r0,:64], r3
-        vst1.8          {d2},  [r0,:64], r3
-        vst1.8          {d3},  [r0,:64], r3
-        vst1.8          {d4},  [r0,:64], r3
-        vst1.8          {d5},  [r0,:64], r3
-        vst1.8          {d10}, [r0,:64], r3
-        vst1.8          {d11}, [r0,:64], r3
-
-        bx              lr
-endfunc
-.endm
-
-        h264_qpel_v_lowpass_l2 put
-        h264_qpel_v_lowpass_l2 avg
-
-function put_h264_qpel8_hv_lowpass_neon_top
-        lowpass_const   r12
-        mov             r12, #12
-1:      vld1.8          {d0, d1},  [r1], r3
-        vld1.8          {d16,d17}, [r1], r3
-        subs            r12, r12, #2
-        lowpass_8       d0,  d1,  d16, d17, q11, q12, narrow=0
-        vst1.8          {d22-d25}, [r4,:128]!
-        bne             1b
-
-        vld1.8          {d0, d1},  [r1]
-        lowpass_8_1     d0,  d1,  q12, narrow=0
-
-        mov             r12, #-16
-        add             r4,  r4,  r12
-        vld1.8          {d30,d31}, [r4,:128], r12
-        vld1.8          {d20,d21}, [r4,:128], r12
-        vld1.8          {d18,d19}, [r4,:128], r12
-        vld1.8          {d16,d17}, [r4,:128], r12
-        vld1.8          {d14,d15}, [r4,:128], r12
-        vld1.8          {d12,d13}, [r4,:128], r12
-        vld1.8          {d10,d11}, [r4,:128], r12
-        vld1.8          {d8, d9},  [r4,:128], r12
-        vld1.8          {d6, d7},  [r4,:128], r12
-        vld1.8          {d4, d5},  [r4,:128], r12
-        vld1.8          {d2, d3},  [r4,:128], r12
-        vld1.8          {d0, d1},  [r4,:128]
-
-        swap4           d1,  d3,  d5,  d7,  d8,  d10, d12, d14
-        transpose16_4x4 q0,  q1,  q2,  q3,  q4,  q5,  q6,  q7
-
-        swap4           d17, d19, d21, d31, d24, d26, d28, d22
-        transpose16_4x4 q8,  q9,  q10, q15, q12, q13, q14, q11
-
-        vst1.8          {d30,d31}, [r4,:128]!
-        vst1.8          {d6, d7},  [r4,:128]!
-        vst1.8          {d20,d21}, [r4,:128]!
-        vst1.8          {d4, d5},  [r4,:128]!
-        vst1.8          {d18,d19}, [r4,:128]!
-        vst1.8          {d2, d3},  [r4,:128]!
-        vst1.8          {d16,d17}, [r4,:128]!
-        vst1.8          {d0, d1},  [r4,:128]
-
-        lowpass_8.16    q4,  q12, d8,  d9,  d24, d25, d8
-        lowpass_8.16    q5,  q13, d10, d11, d26, d27, d9
-        lowpass_8.16    q6,  q14, d12, d13, d28, d29, d10
-        lowpass_8.16    q7,  q11, d14, d15, d22, d23, d11
-
-        vld1.8          {d16,d17}, [r4,:128], r12
-        vld1.8          {d30,d31}, [r4,:128], r12
-        lowpass_8.16    q8,  q15, d16, d17, d30, d31, d12
-        vld1.8          {d16,d17}, [r4,:128], r12
-        vld1.8          {d30,d31}, [r4,:128], r12
-        lowpass_8.16    q8,  q15, d16, d17, d30, d31, d13
-        vld1.8          {d16,d17}, [r4,:128], r12
-        vld1.8          {d30,d31}, [r4,:128], r12
-        lowpass_8.16    q8,  q15, d16, d17, d30, d31, d14
-        vld1.8          {d16,d17}, [r4,:128], r12
-        vld1.8          {d30,d31}, [r4,:128]
-        lowpass_8.16    q8,  q15, d16, d17, d30, d31, d15
-
-        transpose_8x8   d12, d13, d14, d15, d8,  d9,  d10, d11
-
-        bx              lr
-endfunc
-
-.macro  h264_qpel8_hv_lowpass type
-function \type\()_h264_qpel8_hv_lowpass_neon
-        mov             r10, lr
-        bl              put_h264_qpel8_hv_lowpass_neon_top
-  .ifc \type,avg
-        vld1.8          {d0},      [r0,:64], r2
-        vrhadd.u8       d12, d12, d0
-        vld1.8          {d1},      [r0,:64], r2
-        vrhadd.u8       d13, d13, d1
-        vld1.8          {d2},      [r0,:64], r2
-        vrhadd.u8       d14, d14, d2
-        vld1.8          {d3},      [r0,:64], r2
-        vrhadd.u8       d15, d15, d3
-        vld1.8          {d4},      [r0,:64], r2
-        vrhadd.u8       d8,  d8,  d4
-        vld1.8          {d5},      [r0,:64], r2
-        vrhadd.u8       d9,  d9,  d5
-        vld1.8          {d6},      [r0,:64], r2
-        vrhadd.u8       d10, d10, d6
-        vld1.8          {d7},      [r0,:64], r2
-        vrhadd.u8       d11, d11, d7
-        sub             r0,  r0,  r2,  lsl #3
-  .endif
-
-        vst1.8          {d12},     [r0,:64], r2
-        vst1.8          {d13},     [r0,:64], r2
-        vst1.8          {d14},     [r0,:64], r2
-        vst1.8          {d15},     [r0,:64], r2
-        vst1.8          {d8},      [r0,:64], r2
-        vst1.8          {d9},      [r0,:64], r2
-        vst1.8          {d10},     [r0,:64], r2
-        vst1.8          {d11},     [r0,:64], r2
-
-        mov             lr,  r10
-        bx              lr
-endfunc
-.endm
-
-        h264_qpel8_hv_lowpass put
-        h264_qpel8_hv_lowpass avg
-
-.macro  h264_qpel8_hv_lowpass_l2 type
-function \type\()_h264_qpel8_hv_lowpass_l2_neon
-        mov             r10, lr
-        bl              put_h264_qpel8_hv_lowpass_neon_top
-
-        vld1.8          {d0, d1},  [r2,:128]!
-        vld1.8          {d2, d3},  [r2,:128]!
-        vrhadd.u8       q0,  q0,  q6
-        vld1.8          {d4, d5},  [r2,:128]!
-        vrhadd.u8       q1,  q1,  q7
-        vld1.8          {d6, d7},  [r2,:128]!
-        vrhadd.u8       q2,  q2,  q4
-        vrhadd.u8       q3,  q3,  q5
-  .ifc \type,avg
-        vld1.8          {d16},     [r0,:64], r3
-        vrhadd.u8       d0,  d0,  d16
-        vld1.8          {d17},     [r0,:64], r3
-        vrhadd.u8       d1,  d1,  d17
-        vld1.8          {d18},     [r0,:64], r3
-        vrhadd.u8       d2,  d2,  d18
-        vld1.8          {d19},     [r0,:64], r3
-        vrhadd.u8       d3,  d3,  d19
-        vld1.8          {d20},     [r0,:64], r3
-        vrhadd.u8       d4,  d4,  d20
-        vld1.8          {d21},     [r0,:64], r3
-        vrhadd.u8       d5,  d5,  d21
-        vld1.8          {d22},     [r0,:64], r3
-        vrhadd.u8       d6,  d6,  d22
-        vld1.8          {d23},     [r0,:64], r3
-        vrhadd.u8       d7,  d7,  d23
-        sub             r0,  r0,  r3,  lsl #3
-  .endif
-        vst1.8          {d0},      [r0,:64], r3
-        vst1.8          {d1},      [r0,:64], r3
-        vst1.8          {d2},      [r0,:64], r3
-        vst1.8          {d3},      [r0,:64], r3
-        vst1.8          {d4},      [r0,:64], r3
-        vst1.8          {d5},      [r0,:64], r3
-        vst1.8          {d6},      [r0,:64], r3
-        vst1.8          {d7},      [r0,:64], r3
-
-        mov             lr,  r10
-        bx              lr
-endfunc
-.endm
-
-        h264_qpel8_hv_lowpass_l2 put
-        h264_qpel8_hv_lowpass_l2 avg
-
-.macro  h264_qpel16_hv  type
-function \type\()_h264_qpel16_hv_lowpass_neon
-        mov             r9,  lr
-        bl              \type\()_h264_qpel8_hv_lowpass_neon
-        sub             r1,  r1,  r3, lsl #2
-        bl              \type\()_h264_qpel8_hv_lowpass_neon
-        sub             r1,  r1,  r3, lsl #4
-        sub             r1,  r1,  r3, lsl #2
-        add             r1,  r1,  #8
-        sub             r0,  r0,  r2, lsl #4
-        add             r0,  r0,  #8
-        bl              \type\()_h264_qpel8_hv_lowpass_neon
-        sub             r1,  r1,  r3, lsl #2
-        mov             lr,  r9
-        b               \type\()_h264_qpel8_hv_lowpass_neon
-endfunc
-
-function \type\()_h264_qpel16_hv_lowpass_l2_neon
-        mov             r9,  lr
-        sub             r2,  r4,  #256
-        bl              \type\()_h264_qpel8_hv_lowpass_l2_neon
-        sub             r1,  r1,  r3, lsl #2
-        bl              \type\()_h264_qpel8_hv_lowpass_l2_neon
-        sub             r1,  r1,  r3, lsl #4
-        sub             r1,  r1,  r3, lsl #2
-        add             r1,  r1,  #8
-        sub             r0,  r0,  r3, lsl #4
-        add             r0,  r0,  #8
-        bl              \type\()_h264_qpel8_hv_lowpass_l2_neon
-        sub             r1,  r1,  r3, lsl #2
-        mov             lr,  r9
-        b               \type\()_h264_qpel8_hv_lowpass_l2_neon
-endfunc
-.endm
-
-        h264_qpel16_hv put
-        h264_qpel16_hv avg
-
-.macro  h264_qpel8      type
-function ff_\type\()_h264_qpel8_mc10_neon, export=1
-        lowpass_const   r3
-        mov             r3,  r1
-        sub             r1,  r1,  #2
-        mov             r12, #8
-        b               \type\()_h264_qpel8_h_lowpass_l2_neon
-endfunc
-
-function ff_\type\()_h264_qpel8_mc20_neon, export=1
-        lowpass_const   r3
-        sub             r1,  r1,  #2
-        mov             r3,  r2
-        mov             r12, #8
-        b               \type\()_h264_qpel8_h_lowpass_neon
-endfunc
-
-function ff_\type\()_h264_qpel8_mc30_neon, export=1
-        lowpass_const   r3
-        add             r3,  r1,  #1
-        sub             r1,  r1,  #2
-        mov             r12, #8
-        b               \type\()_h264_qpel8_h_lowpass_l2_neon
-endfunc
-
-function ff_\type\()_h264_qpel8_mc01_neon, export=1
-        push            {lr}
-        mov             r12, r1
-\type\()_h264_qpel8_mc01:
-        lowpass_const   r3
-        mov             r3,  r2
-        sub             r1,  r1,  r2, lsl #1
-        vpush           {d8-d15}
-        bl              \type\()_h264_qpel8_v_lowpass_l2_neon
-        vpop            {d8-d15}
-        pop             {pc}
-endfunc
-
-function ff_\type\()_h264_qpel8_mc11_neon, export=1
-        push            {r0, r1, r11, lr}
-\type\()_h264_qpel8_mc11:
-        lowpass_const   r3
-        mov             r11, sp
-A       bic             sp,  sp,  #15
-T       bic             r0,  r11, #15
-T       mov             sp,  r0
-        sub             sp,  sp,  #64
-        mov             r0,  sp
-        sub             r1,  r1,  #2
-        mov             r3,  #8
-        mov             r12, #8
-        vpush           {d8-d15}
-        bl              put_h264_qpel8_h_lowpass_neon
-        ldrd            r0,  r1,  [r11], #8
-        mov             r3,  r2
-        add             r12, sp,  #64
-        sub             r1,  r1,  r2, lsl #1
-        mov             r2,  #8
-        bl              \type\()_h264_qpel8_v_lowpass_l2_neon
-        vpop            {d8-d15}
-        mov             sp,  r11
-        pop             {r11, pc}
-endfunc
-
-function ff_\type\()_h264_qpel8_mc21_neon, export=1
-        push            {r0, r1, r4, r10, r11, lr}
-\type\()_h264_qpel8_mc21:
-        lowpass_const   r3
-        mov             r11, sp
-A       bic             sp,  sp,  #15
-T       bic             r0,  r11, #15
-T       mov             sp,  r0
-        sub             sp,  sp,  #(8*8+16*12)
-        sub             r1,  r1,  #2
-        mov             r3,  #8
-        mov             r0,  sp
-        mov             r12, #8
-        vpush           {d8-d15}
-        bl              put_h264_qpel8_h_lowpass_neon
-        mov             r4,  r0
-        ldrd            r0,  r1,  [r11], #8
-        sub             r1,  r1,  r2, lsl #1
-        sub             r1,  r1,  #2
-        mov             r3,  r2
-        sub             r2,  r4,  #64
-        bl              \type\()_h264_qpel8_hv_lowpass_l2_neon
-        vpop            {d8-d15}
-        mov             sp,  r11
-        pop             {r4, r10, r11, pc}
-endfunc
-
-function ff_\type\()_h264_qpel8_mc31_neon, export=1
-        add             r1,  r1,  #1
-        push            {r0, r1, r11, lr}
-        sub             r1,  r1,  #1
-        b               \type\()_h264_qpel8_mc11
-endfunc
-
-function ff_\type\()_h264_qpel8_mc02_neon, export=1
-        push            {lr}
-        lowpass_const   r3
-        sub             r1,  r1,  r2, lsl #1
-        mov             r3,  r2
-        vpush           {d8-d15}
-        bl              \type\()_h264_qpel8_v_lowpass_neon
-        vpop            {d8-d15}
-        pop             {pc}
-endfunc
-
-function ff_\type\()_h264_qpel8_mc12_neon, export=1
-        push            {r0, r1, r4, r10, r11, lr}
-\type\()_h264_qpel8_mc12:
-        lowpass_const   r3
-        mov             r11, sp
-A       bic             sp,  sp,  #15
-T       bic             r0,  r11, #15
-T       mov             sp,  r0
-        sub             sp,  sp,  #(8*8+16*12)
-        sub             r1,  r1,  r2, lsl #1
-        mov             r3,  r2
-        mov             r2,  #8
-        mov             r0,  sp
-        vpush           {d8-d15}
-        bl              put_h264_qpel8_v_lowpass_neon
-        mov             r4,  r0
-        ldrd            r0,  r1,  [r11], #8
-        sub             r1,  r1,  r3, lsl #1
-        sub             r1,  r1,  #2
-        sub             r2,  r4,  #64
-        bl              \type\()_h264_qpel8_hv_lowpass_l2_neon
-        vpop            {d8-d15}
-        mov             sp,  r11
-        pop             {r4, r10, r11, pc}
-endfunc
-
-function ff_\type\()_h264_qpel8_mc22_neon, export=1
-        push            {r4, r10, r11, lr}
-        mov             r11, sp
-A       bic             sp,  sp,  #15
-T       bic             r4,  r11, #15
-T       mov             sp,  r4
-        sub             r1,  r1,  r2, lsl #1
-        sub             r1,  r1,  #2
-        mov             r3,  r2
-        sub             sp,  sp,  #(16*12)
-        mov             r4,  sp
-        vpush           {d8-d15}
-        bl              \type\()_h264_qpel8_hv_lowpass_neon
-        vpop            {d8-d15}
-        mov             sp,  r11
-        pop             {r4, r10, r11, pc}
-endfunc
-
-function ff_\type\()_h264_qpel8_mc32_neon, export=1
-        push            {r0, r1, r4, r10, r11, lr}
-        add             r1,  r1,  #1
-        b               \type\()_h264_qpel8_mc12
-endfunc
-
-function ff_\type\()_h264_qpel8_mc03_neon, export=1
-        push            {lr}
-        add             r12, r1,  r2
-        b               \type\()_h264_qpel8_mc01
-endfunc
-
-function ff_\type\()_h264_qpel8_mc13_neon, export=1
-        push            {r0, r1, r11, lr}
-        add             r1,  r1,  r2
-        b               \type\()_h264_qpel8_mc11
-endfunc
-
-function ff_\type\()_h264_qpel8_mc23_neon, export=1
-        push            {r0, r1, r4, r10, r11, lr}
-        add             r1,  r1,  r2
-        b               \type\()_h264_qpel8_mc21
-endfunc
-
-function ff_\type\()_h264_qpel8_mc33_neon, export=1
-        add             r1,  r1,  #1
-        push            {r0, r1, r11, lr}
-        add             r1,  r1,  r2
-        sub             r1,  r1,  #1
-        b               \type\()_h264_qpel8_mc11
-endfunc
-.endm
-
-        h264_qpel8 put
-        h264_qpel8 avg
-
-.macro  h264_qpel16     type
-function ff_\type\()_h264_qpel16_mc10_neon, export=1
-        lowpass_const   r3
-        mov             r3,  r1
-        sub             r1,  r1,  #2
-        b               \type\()_h264_qpel16_h_lowpass_l2_neon
-endfunc
-
-function ff_\type\()_h264_qpel16_mc20_neon, export=1
-        lowpass_const   r3
-        sub             r1,  r1,  #2
-        mov             r3,  r2
-        b               \type\()_h264_qpel16_h_lowpass_neon
-endfunc
-
-function ff_\type\()_h264_qpel16_mc30_neon, export=1
-        lowpass_const   r3
-        add             r3,  r1,  #1
-        sub             r1,  r1,  #2
-        b               \type\()_h264_qpel16_h_lowpass_l2_neon
-endfunc
-
-function ff_\type\()_h264_qpel16_mc01_neon, export=1
-        push            {r4, lr}
-        mov             r12, r1
-\type\()_h264_qpel16_mc01:
-        lowpass_const   r3
-        mov             r3,  r2
-        sub             r1,  r1,  r2, lsl #1
-        vpush           {d8-d15}
-        bl              \type\()_h264_qpel16_v_lowpass_l2_neon
-        vpop            {d8-d15}
-        pop             {r4, pc}
-endfunc
-
-function ff_\type\()_h264_qpel16_mc11_neon, export=1
-        push            {r0, r1, r4, r11, lr}
-\type\()_h264_qpel16_mc11:
-        lowpass_const   r3
-        mov             r11, sp
-A       bic             sp,  sp,  #15
-T       bic             r0,  r11, #15
-T       mov             sp,  r0
-        sub             sp,  sp,  #256
-        mov             r0,  sp
-        sub             r1,  r1,  #2
-        mov             r3,  #16
-        vpush           {d8-d15}
-        bl              put_h264_qpel16_h_lowpass_neon
-        ldrd            r0,  r1,  [r11], #8
-        mov             r3,  r2
-        add             r12, sp,  #64
-        sub             r1,  r1,  r2, lsl #1
-        mov             r2,  #16
-        bl              \type\()_h264_qpel16_v_lowpass_l2_neon
-        vpop            {d8-d15}
-        mov             sp,  r11
-        pop             {r4, r11, pc}
-endfunc
-
-function ff_\type\()_h264_qpel16_mc21_neon, export=1
-        push            {r0, r1, r4-r5, r9-r11, lr}
-\type\()_h264_qpel16_mc21:
-        lowpass_const   r3
-        mov             r11, sp
-A       bic             sp,  sp,  #15
-T       bic             r0,  r11, #15
-T       mov             sp,  r0
-        sub             sp,  sp,  #(16*16+16*12)
-        sub             r1,  r1,  #2
-        mov             r0,  sp
-        vpush           {d8-d15}
-        bl              put_h264_qpel16_h_lowpass_neon_packed
-        mov             r4,  r0
-        ldrd            r0,  r1,  [r11], #8
-        sub             r1,  r1,  r2, lsl #1
-        sub             r1,  r1,  #2
-        mov             r3,  r2
-        bl              \type\()_h264_qpel16_hv_lowpass_l2_neon
-        vpop            {d8-d15}
-        mov             sp,  r11
-        pop             {r4-r5, r9-r11, pc}
-endfunc
-
-function ff_\type\()_h264_qpel16_mc31_neon, export=1
-        add             r1,  r1,  #1
-        push            {r0, r1, r4, r11, lr}
-        sub             r1,  r1,  #1
-        b               \type\()_h264_qpel16_mc11
-endfunc
-
-function ff_\type\()_h264_qpel16_mc02_neon, export=1
-        push            {r4, lr}
-        lowpass_const   r3
-        sub             r1,  r1,  r2, lsl #1
-        mov             r3,  r2
-        vpush           {d8-d15}
-        bl              \type\()_h264_qpel16_v_lowpass_neon
-        vpop            {d8-d15}
-        pop             {r4, pc}
-endfunc
-
-function ff_\type\()_h264_qpel16_mc12_neon, export=1
-        push            {r0, r1, r4-r5, r9-r11, lr}
-\type\()_h264_qpel16_mc12:
-        lowpass_const   r3
-        mov             r11, sp
-A       bic             sp,  sp,  #15
-T       bic             r0,  r11, #15
-T       mov             sp,  r0
-        sub             sp,  sp,  #(16*16+16*12)
-        sub             r1,  r1,  r2, lsl #1
-        mov             r0,  sp
-        mov             r3,  r2
-        vpush           {d8-d15}
-        bl              put_h264_qpel16_v_lowpass_neon_packed
-        mov             r4,  r0
-        ldrd            r0,  r1,  [r11], #8
-        sub             r1,  r1,  r3, lsl #1
-        sub             r1,  r1,  #2
-        mov             r2,  r3
-        bl              \type\()_h264_qpel16_hv_lowpass_l2_neon
-        vpop            {d8-d15}
-        mov             sp,  r11
-        pop             {r4-r5, r9-r11, pc}
-endfunc
-
-function ff_\type\()_h264_qpel16_mc22_neon, export=1
-        push            {r4, r9-r11, lr}
-        lowpass_const   r3
-        mov             r11, sp
-A       bic             sp,  sp,  #15
-T       bic             r4,  r11, #15
-T       mov             sp,  r4
-        sub             r1,  r1,  r2, lsl #1
-        sub             r1,  r1,  #2
-        mov             r3,  r2
-        sub             sp,  sp,  #(16*12)
-        mov             r4,  sp
-        vpush           {d8-d15}
-        bl              \type\()_h264_qpel16_hv_lowpass_neon
-        vpop            {d8-d15}
-        mov             sp,  r11
-        pop             {r4, r9-r11, pc}
-endfunc
-
-function ff_\type\()_h264_qpel16_mc32_neon, export=1
-        push            {r0, r1, r4-r5, r9-r11, lr}
-        add             r1,  r1,  #1
-        b               \type\()_h264_qpel16_mc12
-endfunc
-
-function ff_\type\()_h264_qpel16_mc03_neon, export=1
-        push            {r4, lr}
-        add             r12, r1,  r2
-        b               \type\()_h264_qpel16_mc01
-endfunc
-
-function ff_\type\()_h264_qpel16_mc13_neon, export=1
-        push            {r0, r1, r4, r11, lr}
-        add             r1,  r1,  r2
-        b               \type\()_h264_qpel16_mc11
-endfunc
-
-function ff_\type\()_h264_qpel16_mc23_neon, export=1
-        push            {r0, r1, r4-r5, r9-r11, lr}
-        add             r1,  r1,  r2
-        b               \type\()_h264_qpel16_mc21
-endfunc
-
-function ff_\type\()_h264_qpel16_mc33_neon, export=1
-        add             r1,  r1,  #1
-        push            {r0, r1, r4, r11, lr}
-        add             r1,  r1,  r2
-        sub             r1,  r1,  #1
-        b               \type\()_h264_qpel16_mc11
-endfunc
-.endm
-
-        h264_qpel16 put
-        h264_qpel16 avg
-
 @ Biweighted prediction
 
 .macro  biweight_16     macs, macd
diff --git a/libavcodec/arm/h264idct_neon.S b/libavcodec/arm/h264idct_neon.S
index 1b349ce..fa5b90c 100644
--- a/libavcodec/arm/h264idct_neon.S
+++ b/libavcodec/arm/h264idct_neon.S
@@ -22,9 +22,12 @@
 
 function ff_h264_idct_add_neon, export=1
         vld1.64         {d0-d3},  [r1,:128]
+        vmov.i16        q15, #0
 
         vswp            d1,  d2
+        vst1.16         {q15},    [r1,:128]!
         vadd.i16        d4,  d0,  d1
+        vst1.16         {q15},    [r1,:128]!
         vshr.s16        q8,  q1,  #1
         vsub.i16        d5,  d0,  d1
         vadd.i16        d6,  d2,  d17
@@ -65,11 +68,14 @@
         vst1.32         {d0[1]},  [r0,:32], r2
         vst1.32         {d1[0]},  [r0,:32], r2
 
+        sub             r1,  r1,  #32
         bx              lr
 endfunc
 
 function ff_h264_idct_dc_add_neon, export=1
+        mov             r3,       #0
         vld1.16         {d2[],d3[]}, [r1,:16]
+        strh            r3,       [r1]
         vrshr.s16       q1,  q1,  #6
         vld1.32         {d0[0]},  [r0,:32], r2
         vld1.32         {d0[1]},  [r0,:32], r2
@@ -148,7 +154,7 @@
         add             r5,  r1,  #16*4
         add             r1,  r2,  #16*32
         mov             r2,  r3
-        mov             r3,  r1
+        mov             r10, r1
         ldr             r6,  [sp, #32]
         movrel          r7,  scan8+16
         mov             r12, #0
@@ -156,7 +162,7 @@
         ldr             r0,  [r5, r12, lsl #2]
         ldrb            r8,  [r6, r8]
         add             r0,  r0,  r4
-        add             r1,  r3,  r12, lsl #5
+        add             r1,  r10, r12, lsl #5
         cmp             r8,  #0
         ldrsh           r8,  [r1]
         iteet           ne
@@ -180,7 +186,9 @@
         qb      .req    q14
         vshr.s16        q2,  q10, #1
         vadd.i16        q0,  q8,  q12
-        vld1.16         {q14-q15},[r1,:128]!
+        vld1.16         {q14-q15},[r1,:128]
+        vst1.16         {q7},     [r1,:128]!
+        vst1.16         {q7},     [r1,:128]!
         vsub.i16        q1,  q8,  q12
         vshr.s16        q3,  q14, #1
         vsub.i16        q2,  q2,  q14
@@ -259,9 +267,16 @@
 .endm
 
 function ff_h264_idct8_add_neon, export=1
-        vld1.16         {q8-q9},  [r1,:128]!
-        vld1.16         {q10-q11},[r1,:128]!
-        vld1.16         {q12-q13},[r1,:128]!
+        vmov.i16        q7,       #0
+        vld1.16         {q8-q9},  [r1,:128]
+        vst1.16         {q7},     [r1,:128]!
+        vst1.16         {q7},     [r1,:128]!
+        vld1.16         {q10-q11},[r1,:128]
+        vst1.16         {q7},     [r1,:128]!
+        vst1.16         {q7},     [r1,:128]!
+        vld1.16         {q12-q13},[r1,:128]
+        vst1.16         {q7},     [r1,:128]!
+        vst1.16         {q7},     [r1,:128]!
 
         idct8x8_cols    0
         idct8x8_cols    1
@@ -313,7 +328,9 @@
 endfunc
 
 function ff_h264_idct8_dc_add_neon, export=1
+        mov             r3,       #0
         vld1.16         {d30[],d31[]},[r1,:16]
+        strh            r3,       [r1]
         vld1.32         {d0},     [r0,:64], r2
         vrshr.s16       q15, q15, #6
         vld1.32         {d1},     [r0,:64], r2
diff --git a/libavcodec/arm/h264pred_init_arm.c b/libavcodec/arm/h264pred_init_arm.c
index 31714d7..5ec39ce 100644
--- a/libavcodec/arm/h264pred_init_arm.c
+++ b/libavcodec/arm/h264pred_init_arm.c
@@ -20,7 +20,9 @@
 
 #include <stdint.h>
 
+#include "libavutil/attributes.h"
 #include "libavutil/arm/cpu.h"
+#include "libavcodec/avcodec.h"
 #include "libavcodec/h264pred.h"
 
 void ff_pred16x16_vert_neon(uint8_t *src, ptrdiff_t stride);
@@ -43,7 +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 void ff_h264_pred_init_neon(H264PredContext *h, int codec_id, const int bit_depth, const int chroma_format_idc)
+static av_cold void ff_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;
@@ -78,7 +82,8 @@
 #endif // HAVE_NEON
 }
 
-void ff_h264_pred_init_arm(H264PredContext *h, int codec_id, int bit_depth, const int chroma_format_idc)
+av_cold void ff_h264_pred_init_arm(H264PredContext *h, int codec_id,
+                                   int bit_depth, const int chroma_format_idc)
 {
     int cpu_flags = av_get_cpu_flags();
 
diff --git a/libavcodec/arm/h264qpel_init_arm.c b/libavcodec/arm/h264qpel_init_arm.c
new file mode 100644
index 0000000..fd014fd
--- /dev/null
+++ b/libavcodec/arm/h264qpel_init_arm.c
@@ -0,0 +1,171 @@
+/*
+ * ARM NEON optimised DSP functions
+ * Copyright (c) 2008 Mans Rullgard <mans@mansr.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 <stdint.h>
+
+#include "config.h"
+#include "libavutil/attributes.h"
+#include "libavutil/arm/cpu.h"
+#include "libavcodec/h264qpel.h"
+
+void ff_put_h264_qpel16_mc00_neon(uint8_t *, uint8_t *, int);
+void ff_put_h264_qpel16_mc10_neon(uint8_t *, uint8_t *, int);
+void ff_put_h264_qpel16_mc20_neon(uint8_t *, uint8_t *, int);
+void ff_put_h264_qpel16_mc30_neon(uint8_t *, uint8_t *, int);
+void ff_put_h264_qpel16_mc01_neon(uint8_t *, uint8_t *, int);
+void ff_put_h264_qpel16_mc11_neon(uint8_t *, uint8_t *, int);
+void ff_put_h264_qpel16_mc21_neon(uint8_t *, uint8_t *, int);
+void ff_put_h264_qpel16_mc31_neon(uint8_t *, uint8_t *, int);
+void ff_put_h264_qpel16_mc02_neon(uint8_t *, uint8_t *, int);
+void ff_put_h264_qpel16_mc12_neon(uint8_t *, uint8_t *, int);
+void ff_put_h264_qpel16_mc22_neon(uint8_t *, uint8_t *, int);
+void ff_put_h264_qpel16_mc32_neon(uint8_t *, uint8_t *, int);
+void ff_put_h264_qpel16_mc03_neon(uint8_t *, uint8_t *, int);
+void ff_put_h264_qpel16_mc13_neon(uint8_t *, uint8_t *, int);
+void ff_put_h264_qpel16_mc23_neon(uint8_t *, uint8_t *, int);
+void ff_put_h264_qpel16_mc33_neon(uint8_t *, uint8_t *, int);
+
+void ff_put_h264_qpel8_mc00_neon(uint8_t *, uint8_t *, int);
+void ff_put_h264_qpel8_mc10_neon(uint8_t *, uint8_t *, int);
+void ff_put_h264_qpel8_mc20_neon(uint8_t *, uint8_t *, int);
+void ff_put_h264_qpel8_mc30_neon(uint8_t *, uint8_t *, int);
+void ff_put_h264_qpel8_mc01_neon(uint8_t *, uint8_t *, int);
+void ff_put_h264_qpel8_mc11_neon(uint8_t *, uint8_t *, int);
+void ff_put_h264_qpel8_mc21_neon(uint8_t *, uint8_t *, int);
+void ff_put_h264_qpel8_mc31_neon(uint8_t *, uint8_t *, int);
+void ff_put_h264_qpel8_mc02_neon(uint8_t *, uint8_t *, int);
+void ff_put_h264_qpel8_mc12_neon(uint8_t *, uint8_t *, int);
+void ff_put_h264_qpel8_mc22_neon(uint8_t *, uint8_t *, int);
+void ff_put_h264_qpel8_mc32_neon(uint8_t *, uint8_t *, int);
+void ff_put_h264_qpel8_mc03_neon(uint8_t *, uint8_t *, int);
+void ff_put_h264_qpel8_mc13_neon(uint8_t *, uint8_t *, int);
+void ff_put_h264_qpel8_mc23_neon(uint8_t *, uint8_t *, int);
+void ff_put_h264_qpel8_mc33_neon(uint8_t *, uint8_t *, int);
+
+void ff_avg_h264_qpel16_mc00_neon(uint8_t *, uint8_t *, int);
+void ff_avg_h264_qpel16_mc10_neon(uint8_t *, uint8_t *, int);
+void ff_avg_h264_qpel16_mc20_neon(uint8_t *, uint8_t *, int);
+void ff_avg_h264_qpel16_mc30_neon(uint8_t *, uint8_t *, int);
+void ff_avg_h264_qpel16_mc01_neon(uint8_t *, uint8_t *, int);
+void ff_avg_h264_qpel16_mc11_neon(uint8_t *, uint8_t *, int);
+void ff_avg_h264_qpel16_mc21_neon(uint8_t *, uint8_t *, int);
+void ff_avg_h264_qpel16_mc31_neon(uint8_t *, uint8_t *, int);
+void ff_avg_h264_qpel16_mc02_neon(uint8_t *, uint8_t *, int);
+void ff_avg_h264_qpel16_mc12_neon(uint8_t *, uint8_t *, int);
+void ff_avg_h264_qpel16_mc22_neon(uint8_t *, uint8_t *, int);
+void ff_avg_h264_qpel16_mc32_neon(uint8_t *, uint8_t *, int);
+void ff_avg_h264_qpel16_mc03_neon(uint8_t *, uint8_t *, int);
+void ff_avg_h264_qpel16_mc13_neon(uint8_t *, uint8_t *, int);
+void ff_avg_h264_qpel16_mc23_neon(uint8_t *, uint8_t *, int);
+void ff_avg_h264_qpel16_mc33_neon(uint8_t *, uint8_t *, int);
+
+void ff_avg_h264_qpel8_mc00_neon(uint8_t *, uint8_t *, int);
+void ff_avg_h264_qpel8_mc10_neon(uint8_t *, uint8_t *, int);
+void ff_avg_h264_qpel8_mc20_neon(uint8_t *, uint8_t *, int);
+void ff_avg_h264_qpel8_mc30_neon(uint8_t *, uint8_t *, int);
+void ff_avg_h264_qpel8_mc01_neon(uint8_t *, uint8_t *, int);
+void ff_avg_h264_qpel8_mc11_neon(uint8_t *, uint8_t *, int);
+void ff_avg_h264_qpel8_mc21_neon(uint8_t *, uint8_t *, int);
+void ff_avg_h264_qpel8_mc31_neon(uint8_t *, uint8_t *, int);
+void ff_avg_h264_qpel8_mc02_neon(uint8_t *, uint8_t *, int);
+void ff_avg_h264_qpel8_mc12_neon(uint8_t *, uint8_t *, int);
+void ff_avg_h264_qpel8_mc22_neon(uint8_t *, uint8_t *, int);
+void ff_avg_h264_qpel8_mc32_neon(uint8_t *, uint8_t *, int);
+void ff_avg_h264_qpel8_mc03_neon(uint8_t *, uint8_t *, int);
+void ff_avg_h264_qpel8_mc13_neon(uint8_t *, uint8_t *, int);
+void ff_avg_h264_qpel8_mc23_neon(uint8_t *, uint8_t *, int);
+void ff_avg_h264_qpel8_mc33_neon(uint8_t *, uint8_t *, int);
+
+av_cold void ff_h264qpel_init_arm(H264QpelContext *c, int bit_depth)
+{
+    const int high_bit_depth = bit_depth > 8;
+    int cpu_flags = av_get_cpu_flags();
+
+    if (have_neon(cpu_flags) && !high_bit_depth) {
+        c->put_h264_qpel_pixels_tab[0][ 0] = ff_put_h264_qpel16_mc00_neon;
+        c->put_h264_qpel_pixels_tab[0][ 1] = ff_put_h264_qpel16_mc10_neon;
+        c->put_h264_qpel_pixels_tab[0][ 2] = ff_put_h264_qpel16_mc20_neon;
+        c->put_h264_qpel_pixels_tab[0][ 3] = ff_put_h264_qpel16_mc30_neon;
+        c->put_h264_qpel_pixels_tab[0][ 4] = ff_put_h264_qpel16_mc01_neon;
+        c->put_h264_qpel_pixels_tab[0][ 5] = ff_put_h264_qpel16_mc11_neon;
+        c->put_h264_qpel_pixels_tab[0][ 6] = ff_put_h264_qpel16_mc21_neon;
+        c->put_h264_qpel_pixels_tab[0][ 7] = ff_put_h264_qpel16_mc31_neon;
+        c->put_h264_qpel_pixels_tab[0][ 8] = ff_put_h264_qpel16_mc02_neon;
+        c->put_h264_qpel_pixels_tab[0][ 9] = ff_put_h264_qpel16_mc12_neon;
+        c->put_h264_qpel_pixels_tab[0][10] = ff_put_h264_qpel16_mc22_neon;
+        c->put_h264_qpel_pixels_tab[0][11] = ff_put_h264_qpel16_mc32_neon;
+        c->put_h264_qpel_pixels_tab[0][12] = ff_put_h264_qpel16_mc03_neon;
+        c->put_h264_qpel_pixels_tab[0][13] = ff_put_h264_qpel16_mc13_neon;
+        c->put_h264_qpel_pixels_tab[0][14] = ff_put_h264_qpel16_mc23_neon;
+        c->put_h264_qpel_pixels_tab[0][15] = ff_put_h264_qpel16_mc33_neon;
+
+        c->put_h264_qpel_pixels_tab[1][ 0] = ff_put_h264_qpel8_mc00_neon;
+        c->put_h264_qpel_pixels_tab[1][ 1] = ff_put_h264_qpel8_mc10_neon;
+        c->put_h264_qpel_pixels_tab[1][ 2] = ff_put_h264_qpel8_mc20_neon;
+        c->put_h264_qpel_pixels_tab[1][ 3] = ff_put_h264_qpel8_mc30_neon;
+        c->put_h264_qpel_pixels_tab[1][ 4] = ff_put_h264_qpel8_mc01_neon;
+        c->put_h264_qpel_pixels_tab[1][ 5] = ff_put_h264_qpel8_mc11_neon;
+        c->put_h264_qpel_pixels_tab[1][ 6] = ff_put_h264_qpel8_mc21_neon;
+        c->put_h264_qpel_pixels_tab[1][ 7] = ff_put_h264_qpel8_mc31_neon;
+        c->put_h264_qpel_pixels_tab[1][ 8] = ff_put_h264_qpel8_mc02_neon;
+        c->put_h264_qpel_pixels_tab[1][ 9] = ff_put_h264_qpel8_mc12_neon;
+        c->put_h264_qpel_pixels_tab[1][10] = ff_put_h264_qpel8_mc22_neon;
+        c->put_h264_qpel_pixels_tab[1][11] = ff_put_h264_qpel8_mc32_neon;
+        c->put_h264_qpel_pixels_tab[1][12] = ff_put_h264_qpel8_mc03_neon;
+        c->put_h264_qpel_pixels_tab[1][13] = ff_put_h264_qpel8_mc13_neon;
+        c->put_h264_qpel_pixels_tab[1][14] = ff_put_h264_qpel8_mc23_neon;
+        c->put_h264_qpel_pixels_tab[1][15] = ff_put_h264_qpel8_mc33_neon;
+
+        c->avg_h264_qpel_pixels_tab[0][ 0] = ff_avg_h264_qpel16_mc00_neon;
+        c->avg_h264_qpel_pixels_tab[0][ 1] = ff_avg_h264_qpel16_mc10_neon;
+        c->avg_h264_qpel_pixels_tab[0][ 2] = ff_avg_h264_qpel16_mc20_neon;
+        c->avg_h264_qpel_pixels_tab[0][ 3] = ff_avg_h264_qpel16_mc30_neon;
+        c->avg_h264_qpel_pixels_tab[0][ 4] = ff_avg_h264_qpel16_mc01_neon;
+        c->avg_h264_qpel_pixels_tab[0][ 5] = ff_avg_h264_qpel16_mc11_neon;
+        c->avg_h264_qpel_pixels_tab[0][ 6] = ff_avg_h264_qpel16_mc21_neon;
+        c->avg_h264_qpel_pixels_tab[0][ 7] = ff_avg_h264_qpel16_mc31_neon;
+        c->avg_h264_qpel_pixels_tab[0][ 8] = ff_avg_h264_qpel16_mc02_neon;
+        c->avg_h264_qpel_pixels_tab[0][ 9] = ff_avg_h264_qpel16_mc12_neon;
+        c->avg_h264_qpel_pixels_tab[0][10] = ff_avg_h264_qpel16_mc22_neon;
+        c->avg_h264_qpel_pixels_tab[0][11] = ff_avg_h264_qpel16_mc32_neon;
+        c->avg_h264_qpel_pixels_tab[0][12] = ff_avg_h264_qpel16_mc03_neon;
+        c->avg_h264_qpel_pixels_tab[0][13] = ff_avg_h264_qpel16_mc13_neon;
+        c->avg_h264_qpel_pixels_tab[0][14] = ff_avg_h264_qpel16_mc23_neon;
+        c->avg_h264_qpel_pixels_tab[0][15] = ff_avg_h264_qpel16_mc33_neon;
+
+        c->avg_h264_qpel_pixels_tab[1][ 0] = ff_avg_h264_qpel8_mc00_neon;
+        c->avg_h264_qpel_pixels_tab[1][ 1] = ff_avg_h264_qpel8_mc10_neon;
+        c->avg_h264_qpel_pixels_tab[1][ 2] = ff_avg_h264_qpel8_mc20_neon;
+        c->avg_h264_qpel_pixels_tab[1][ 3] = ff_avg_h264_qpel8_mc30_neon;
+        c->avg_h264_qpel_pixels_tab[1][ 4] = ff_avg_h264_qpel8_mc01_neon;
+        c->avg_h264_qpel_pixels_tab[1][ 5] = ff_avg_h264_qpel8_mc11_neon;
+        c->avg_h264_qpel_pixels_tab[1][ 6] = ff_avg_h264_qpel8_mc21_neon;
+        c->avg_h264_qpel_pixels_tab[1][ 7] = ff_avg_h264_qpel8_mc31_neon;
+        c->avg_h264_qpel_pixels_tab[1][ 8] = ff_avg_h264_qpel8_mc02_neon;
+        c->avg_h264_qpel_pixels_tab[1][ 9] = ff_avg_h264_qpel8_mc12_neon;
+        c->avg_h264_qpel_pixels_tab[1][10] = ff_avg_h264_qpel8_mc22_neon;
+        c->avg_h264_qpel_pixels_tab[1][11] = ff_avg_h264_qpel8_mc32_neon;
+        c->avg_h264_qpel_pixels_tab[1][12] = ff_avg_h264_qpel8_mc03_neon;
+        c->avg_h264_qpel_pixels_tab[1][13] = ff_avg_h264_qpel8_mc13_neon;
+        c->avg_h264_qpel_pixels_tab[1][14] = ff_avg_h264_qpel8_mc23_neon;
+        c->avg_h264_qpel_pixels_tab[1][15] = ff_avg_h264_qpel8_mc33_neon;
+    }
+}
diff --git a/libavcodec/arm/h264qpel_neon.S b/libavcodec/arm/h264qpel_neon.S
new file mode 100644
index 0000000..21336c6
--- /dev/null
+++ b/libavcodec/arm/h264qpel_neon.S
@@ -0,0 +1,955 @@
+/*
+ * Copyright (c) 2008 Mans Rullgard <mans@mansr.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/arm/asm.S"
+#include "neon.S"
+
+        /* H.264 qpel MC */
+
+.macro  lowpass_const   r
+        movw            \r,  #5
+        movt            \r,  #20
+        vmov.32         d6[0], \r
+.endm
+
+.macro  lowpass_8       r0,  r1,  r2,  r3,  d0,  d1,  narrow=1
+  .if \narrow
+        t0 .req q0
+        t1 .req q8
+  .else
+        t0 .req \d0
+        t1 .req \d1
+  .endif
+        vext.8          d2,  \r0, \r1, #2
+        vext.8          d3,  \r0, \r1, #3
+        vaddl.u8        q1,  d2,  d3
+        vext.8          d4,  \r0, \r1, #1
+        vext.8          d5,  \r0, \r1, #4
+        vaddl.u8        q2,  d4,  d5
+        vext.8          d30, \r0, \r1, #5
+        vaddl.u8        t0,  \r0, d30
+        vext.8          d18, \r2, \r3, #2
+        vmla.i16        t0,  q1,  d6[1]
+        vext.8          d19, \r2, \r3, #3
+        vaddl.u8        q9,  d18, d19
+        vext.8          d20, \r2, \r3, #1
+        vmls.i16        t0,  q2,  d6[0]
+        vext.8          d21, \r2, \r3, #4
+        vaddl.u8        q10, d20, d21
+        vext.8          d31, \r2, \r3, #5
+        vaddl.u8        t1,  \r2, d31
+        vmla.i16        t1,  q9,  d6[1]
+        vmls.i16        t1,  q10, d6[0]
+  .if \narrow
+        vqrshrun.s16    \d0, t0,  #5
+        vqrshrun.s16    \d1, t1,  #5
+  .endif
+        .unreq  t0
+        .unreq  t1
+.endm
+
+.macro  lowpass_8_1     r0,  r1,  d0,  narrow=1
+  .if \narrow
+        t0 .req q0
+  .else
+        t0 .req \d0
+  .endif
+        vext.8          d2,  \r0, \r1, #2
+        vext.8          d3,  \r0, \r1, #3
+        vaddl.u8        q1,  d2,  d3
+        vext.8          d4,  \r0, \r1, #1
+        vext.8          d5,  \r0, \r1, #4
+        vaddl.u8        q2,  d4,  d5
+        vext.8          d30, \r0, \r1, #5
+        vaddl.u8        t0,  \r0, d30
+        vmla.i16        t0,  q1,  d6[1]
+        vmls.i16        t0,  q2,  d6[0]
+  .if \narrow
+        vqrshrun.s16    \d0, t0,  #5
+  .endif
+        .unreq  t0
+.endm
+
+.macro  lowpass_8.16    r0,  r1,  l0,  h0,  l1,  h1,  d
+        vext.16         q1,  \r0, \r1, #2
+        vext.16         q0,  \r0, \r1, #3
+        vaddl.s16       q9,  d2,  d0
+        vext.16         q2,  \r0, \r1, #1
+        vaddl.s16       q1,  d3,  d1
+        vext.16         q3,  \r0, \r1, #4
+        vaddl.s16       q10, d4,  d6
+        vext.16         \r1, \r0, \r1, #5
+        vaddl.s16       q2,  d5,  d7
+        vaddl.s16       q0,  \h0, \h1
+        vaddl.s16       q8,  \l0, \l1
+
+        vshl.i32        q3,  q9,  #4
+        vshl.i32        q9,  q9,  #2
+        vshl.i32        q15, q10, #2
+        vadd.i32        q9,  q9,  q3
+        vadd.i32        q10, q10, q15
+
+        vshl.i32        q3,  q1,  #4
+        vshl.i32        q1,  q1,  #2
+        vshl.i32        q15, q2,  #2
+        vadd.i32        q1,  q1,  q3
+        vadd.i32        q2,  q2,  q15
+
+        vadd.i32        q9,  q9,  q8
+        vsub.i32        q9,  q9,  q10
+
+        vadd.i32        q1,  q1,  q0
+        vsub.i32        q1,  q1,  q2
+
+        vrshrn.s32      d18, q9,  #10
+        vrshrn.s32      d19, q1,  #10
+
+        vqmovun.s16     \d,  q9
+.endm
+
+function put_h264_qpel16_h_lowpass_neon_packed
+        mov             r4,  lr
+        mov             r12, #16
+        mov             r3,  #8
+        bl              put_h264_qpel8_h_lowpass_neon
+        sub             r1,  r1,  r2, lsl #4
+        add             r1,  r1,  #8
+        mov             r12, #16
+        mov             lr,  r4
+        b               put_h264_qpel8_h_lowpass_neon
+endfunc
+
+.macro  h264_qpel_h_lowpass type
+function \type\()_h264_qpel16_h_lowpass_neon
+        push            {lr}
+        mov             r12, #16
+        bl              \type\()_h264_qpel8_h_lowpass_neon
+        sub             r0,  r0,  r3, lsl #4
+        sub             r1,  r1,  r2, lsl #4
+        add             r0,  r0,  #8
+        add             r1,  r1,  #8
+        mov             r12, #16
+        pop             {lr}
+endfunc
+
+function \type\()_h264_qpel8_h_lowpass_neon
+1:      vld1.8          {d0, d1},  [r1], r2
+        vld1.8          {d16,d17}, [r1], r2
+        subs            r12, r12, #2
+        lowpass_8       d0,  d1,  d16, d17, d0,  d16
+  .ifc \type,avg
+        vld1.8          {d2},     [r0,:64], r3
+        vrhadd.u8       d0,  d0,  d2
+        vld1.8          {d3},     [r0,:64]
+        vrhadd.u8       d16, d16, d3
+        sub             r0,  r0,  r3
+  .endif
+        vst1.8          {d0},     [r0,:64], r3
+        vst1.8          {d16},    [r0,:64], r3
+        bne             1b
+        bx              lr
+endfunc
+.endm
+
+        h264_qpel_h_lowpass put
+        h264_qpel_h_lowpass avg
+
+.macro  h264_qpel_h_lowpass_l2 type
+function \type\()_h264_qpel16_h_lowpass_l2_neon
+        push            {lr}
+        mov             r12, #16
+        bl              \type\()_h264_qpel8_h_lowpass_l2_neon
+        sub             r0,  r0,  r2, lsl #4
+        sub             r1,  r1,  r2, lsl #4
+        sub             r3,  r3,  r2, lsl #4
+        add             r0,  r0,  #8
+        add             r1,  r1,  #8
+        add             r3,  r3,  #8
+        mov             r12, #16
+        pop             {lr}
+endfunc
+
+function \type\()_h264_qpel8_h_lowpass_l2_neon
+1:      vld1.8          {d0, d1},  [r1], r2
+        vld1.8          {d16,d17}, [r1], r2
+        vld1.8          {d28},     [r3], r2
+        vld1.8          {d29},     [r3], r2
+        subs            r12, r12, #2
+        lowpass_8       d0,  d1,  d16, d17, d0,  d1
+        vrhadd.u8       q0,  q0,  q14
+  .ifc \type,avg
+        vld1.8          {d2},      [r0,:64], r2
+        vrhadd.u8       d0,  d0,  d2
+        vld1.8          {d3},      [r0,:64]
+        vrhadd.u8       d1,  d1,  d3
+        sub             r0,  r0,  r2
+  .endif
+        vst1.8          {d0},      [r0,:64], r2
+        vst1.8          {d1},      [r0,:64], r2
+        bne             1b
+        bx              lr
+endfunc
+.endm
+
+        h264_qpel_h_lowpass_l2 put
+        h264_qpel_h_lowpass_l2 avg
+
+function put_h264_qpel16_v_lowpass_neon_packed
+        mov             r4,  lr
+        mov             r2,  #8
+        bl              put_h264_qpel8_v_lowpass_neon
+        sub             r1,  r1,  r3, lsl #2
+        bl              put_h264_qpel8_v_lowpass_neon
+        sub             r1,  r1,  r3, lsl #4
+        sub             r1,  r1,  r3, lsl #2
+        add             r1,  r1,  #8
+        bl              put_h264_qpel8_v_lowpass_neon
+        sub             r1,  r1,  r3, lsl #2
+        mov             lr,  r4
+        b               put_h264_qpel8_v_lowpass_neon
+endfunc
+
+.macro  h264_qpel_v_lowpass type
+function \type\()_h264_qpel16_v_lowpass_neon
+        mov             r4,  lr
+        bl              \type\()_h264_qpel8_v_lowpass_neon
+        sub             r1,  r1,  r3, lsl #2
+        bl              \type\()_h264_qpel8_v_lowpass_neon
+        sub             r0,  r0,  r2, lsl #4
+        add             r0,  r0,  #8
+        sub             r1,  r1,  r3, lsl #4
+        sub             r1,  r1,  r3, lsl #2
+        add             r1,  r1,  #8
+        bl              \type\()_h264_qpel8_v_lowpass_neon
+        sub             r1,  r1,  r3, lsl #2
+        mov             lr,  r4
+endfunc
+
+function \type\()_h264_qpel8_v_lowpass_neon
+        vld1.8          {d8},  [r1], r3
+        vld1.8          {d10}, [r1], r3
+        vld1.8          {d12}, [r1], r3
+        vld1.8          {d14}, [r1], r3
+        vld1.8          {d22}, [r1], r3
+        vld1.8          {d24}, [r1], r3
+        vld1.8          {d26}, [r1], r3
+        vld1.8          {d28}, [r1], r3
+        vld1.8          {d9},  [r1], r3
+        vld1.8          {d11}, [r1], r3
+        vld1.8          {d13}, [r1], r3
+        vld1.8          {d15}, [r1], r3
+        vld1.8          {d23}, [r1]
+
+        transpose_8x8   q4,  q5,  q6,  q7,  q11, q12, q13, q14
+        lowpass_8       d8,  d9,  d10, d11, d8,  d10
+        lowpass_8       d12, d13, d14, d15, d12, d14
+        lowpass_8       d22, d23, d24, d25, d22, d24
+        lowpass_8       d26, d27, d28, d29, d26, d28
+        transpose_8x8   d8,  d10, d12, d14, d22, d24, d26, d28
+
+  .ifc \type,avg
+        vld1.8          {d9},  [r0,:64], r2
+        vrhadd.u8       d8,  d8,  d9
+        vld1.8          {d11}, [r0,:64], r2
+        vrhadd.u8       d10, d10, d11
+        vld1.8          {d13}, [r0,:64], r2
+        vrhadd.u8       d12, d12, d13
+        vld1.8          {d15}, [r0,:64], r2
+        vrhadd.u8       d14, d14, d15
+        vld1.8          {d23}, [r0,:64], r2
+        vrhadd.u8       d22, d22, d23
+        vld1.8          {d25}, [r0,:64], r2
+        vrhadd.u8       d24, d24, d25
+        vld1.8          {d27}, [r0,:64], r2
+        vrhadd.u8       d26, d26, d27
+        vld1.8          {d29}, [r0,:64], r2
+        vrhadd.u8       d28, d28, d29
+        sub             r0,  r0,  r2,  lsl #3
+  .endif
+
+        vst1.8          {d8},  [r0,:64], r2
+        vst1.8          {d10}, [r0,:64], r2
+        vst1.8          {d12}, [r0,:64], r2
+        vst1.8          {d14}, [r0,:64], r2
+        vst1.8          {d22}, [r0,:64], r2
+        vst1.8          {d24}, [r0,:64], r2
+        vst1.8          {d26}, [r0,:64], r2
+        vst1.8          {d28}, [r0,:64], r2
+
+        bx              lr
+endfunc
+.endm
+
+        h264_qpel_v_lowpass put
+        h264_qpel_v_lowpass avg
+
+.macro  h264_qpel_v_lowpass_l2 type
+function \type\()_h264_qpel16_v_lowpass_l2_neon
+        mov             r4,  lr
+        bl              \type\()_h264_qpel8_v_lowpass_l2_neon
+        sub             r1,  r1,  r3, lsl #2
+        bl              \type\()_h264_qpel8_v_lowpass_l2_neon
+        sub             r0,  r0,  r3, lsl #4
+        sub             r12, r12, r2, lsl #4
+        add             r0,  r0,  #8
+        add             r12, r12, #8
+        sub             r1,  r1,  r3, lsl #4
+        sub             r1,  r1,  r3, lsl #2
+        add             r1,  r1,  #8
+        bl              \type\()_h264_qpel8_v_lowpass_l2_neon
+        sub             r1,  r1,  r3, lsl #2
+        mov             lr,  r4
+endfunc
+
+function \type\()_h264_qpel8_v_lowpass_l2_neon
+        vld1.8          {d8},  [r1], r3
+        vld1.8          {d10}, [r1], r3
+        vld1.8          {d12}, [r1], r3
+        vld1.8          {d14}, [r1], r3
+        vld1.8          {d22}, [r1], r3
+        vld1.8          {d24}, [r1], r3
+        vld1.8          {d26}, [r1], r3
+        vld1.8          {d28}, [r1], r3
+        vld1.8          {d9},  [r1], r3
+        vld1.8          {d11}, [r1], r3
+        vld1.8          {d13}, [r1], r3
+        vld1.8          {d15}, [r1], r3
+        vld1.8          {d23}, [r1]
+
+        transpose_8x8   q4,  q5,  q6,  q7,  q11, q12, q13, q14
+        lowpass_8       d8,  d9,  d10, d11, d8,  d9
+        lowpass_8       d12, d13, d14, d15, d12, d13
+        lowpass_8       d22, d23, d24, d25, d22, d23
+        lowpass_8       d26, d27, d28, d29, d26, d27
+        transpose_8x8   d8,  d9,  d12, d13, d22, d23, d26, d27
+
+        vld1.8          {d0},  [r12], r2
+        vld1.8          {d1},  [r12], r2
+        vld1.8          {d2},  [r12], r2
+        vld1.8          {d3},  [r12], r2
+        vld1.8          {d4},  [r12], r2
+        vrhadd.u8       q0,  q0,  q4
+        vld1.8          {d5},  [r12], r2
+        vrhadd.u8       q1,  q1,  q6
+        vld1.8          {d10}, [r12], r2
+        vrhadd.u8       q2,  q2,  q11
+        vld1.8          {d11}, [r12], r2
+        vrhadd.u8       q5,  q5,  q13
+
+  .ifc \type,avg
+        vld1.8          {d16}, [r0,:64], r3
+        vrhadd.u8       d0,  d0,  d16
+        vld1.8          {d17}, [r0,:64], r3
+        vrhadd.u8       d1,  d1,  d17
+        vld1.8          {d16}, [r0,:64], r3
+        vrhadd.u8       d2,  d2,  d16
+        vld1.8          {d17}, [r0,:64], r3
+        vrhadd.u8       d3,  d3,  d17
+        vld1.8          {d16}, [r0,:64], r3
+        vrhadd.u8       d4,  d4,  d16
+        vld1.8          {d17}, [r0,:64], r3
+        vrhadd.u8       d5,  d5,  d17
+        vld1.8          {d16}, [r0,:64], r3
+        vrhadd.u8       d10, d10, d16
+        vld1.8          {d17}, [r0,:64], r3
+        vrhadd.u8       d11, d11, d17
+        sub             r0,  r0,  r3,  lsl #3
+  .endif
+
+        vst1.8          {d0},  [r0,:64], r3
+        vst1.8          {d1},  [r0,:64], r3
+        vst1.8          {d2},  [r0,:64], r3
+        vst1.8          {d3},  [r0,:64], r3
+        vst1.8          {d4},  [r0,:64], r3
+        vst1.8          {d5},  [r0,:64], r3
+        vst1.8          {d10}, [r0,:64], r3
+        vst1.8          {d11}, [r0,:64], r3
+
+        bx              lr
+endfunc
+.endm
+
+        h264_qpel_v_lowpass_l2 put
+        h264_qpel_v_lowpass_l2 avg
+
+function put_h264_qpel8_hv_lowpass_neon_top
+        lowpass_const   r12
+        mov             r12, #12
+1:      vld1.8          {d0, d1},  [r1], r3
+        vld1.8          {d16,d17}, [r1], r3
+        subs            r12, r12, #2
+        lowpass_8       d0,  d1,  d16, d17, q11, q12, narrow=0
+        vst1.8          {d22-d25}, [r4,:128]!
+        bne             1b
+
+        vld1.8          {d0, d1},  [r1]
+        lowpass_8_1     d0,  d1,  q12, narrow=0
+
+        mov             r12, #-16
+        add             r4,  r4,  r12
+        vld1.8          {d30,d31}, [r4,:128], r12
+        vld1.8          {d20,d21}, [r4,:128], r12
+        vld1.8          {d18,d19}, [r4,:128], r12
+        vld1.8          {d16,d17}, [r4,:128], r12
+        vld1.8          {d14,d15}, [r4,:128], r12
+        vld1.8          {d12,d13}, [r4,:128], r12
+        vld1.8          {d10,d11}, [r4,:128], r12
+        vld1.8          {d8, d9},  [r4,:128], r12
+        vld1.8          {d6, d7},  [r4,:128], r12
+        vld1.8          {d4, d5},  [r4,:128], r12
+        vld1.8          {d2, d3},  [r4,:128], r12
+        vld1.8          {d0, d1},  [r4,:128]
+
+        swap4           d1,  d3,  d5,  d7,  d8,  d10, d12, d14
+        transpose16_4x4 q0,  q1,  q2,  q3,  q4,  q5,  q6,  q7
+
+        swap4           d17, d19, d21, d31, d24, d26, d28, d22
+        transpose16_4x4 q8,  q9,  q10, q15, q12, q13, q14, q11
+
+        vst1.8          {d30,d31}, [r4,:128]!
+        vst1.8          {d6, d7},  [r4,:128]!
+        vst1.8          {d20,d21}, [r4,:128]!
+        vst1.8          {d4, d5},  [r4,:128]!
+        vst1.8          {d18,d19}, [r4,:128]!
+        vst1.8          {d2, d3},  [r4,:128]!
+        vst1.8          {d16,d17}, [r4,:128]!
+        vst1.8          {d0, d1},  [r4,:128]
+
+        lowpass_8.16    q4,  q12, d8,  d9,  d24, d25, d8
+        lowpass_8.16    q5,  q13, d10, d11, d26, d27, d9
+        lowpass_8.16    q6,  q14, d12, d13, d28, d29, d10
+        lowpass_8.16    q7,  q11, d14, d15, d22, d23, d11
+
+        vld1.8          {d16,d17}, [r4,:128], r12
+        vld1.8          {d30,d31}, [r4,:128], r12
+        lowpass_8.16    q8,  q15, d16, d17, d30, d31, d12
+        vld1.8          {d16,d17}, [r4,:128], r12
+        vld1.8          {d30,d31}, [r4,:128], r12
+        lowpass_8.16    q8,  q15, d16, d17, d30, d31, d13
+        vld1.8          {d16,d17}, [r4,:128], r12
+        vld1.8          {d30,d31}, [r4,:128], r12
+        lowpass_8.16    q8,  q15, d16, d17, d30, d31, d14
+        vld1.8          {d16,d17}, [r4,:128], r12
+        vld1.8          {d30,d31}, [r4,:128]
+        lowpass_8.16    q8,  q15, d16, d17, d30, d31, d15
+
+        transpose_8x8   d12, d13, d14, d15, d8,  d9,  d10, d11
+
+        bx              lr
+endfunc
+
+.macro  h264_qpel8_hv_lowpass type
+function \type\()_h264_qpel8_hv_lowpass_neon
+        mov             r10, lr
+        bl              put_h264_qpel8_hv_lowpass_neon_top
+  .ifc \type,avg
+        vld1.8          {d0},      [r0,:64], r2
+        vrhadd.u8       d12, d12, d0
+        vld1.8          {d1},      [r0,:64], r2
+        vrhadd.u8       d13, d13, d1
+        vld1.8          {d2},      [r0,:64], r2
+        vrhadd.u8       d14, d14, d2
+        vld1.8          {d3},      [r0,:64], r2
+        vrhadd.u8       d15, d15, d3
+        vld1.8          {d4},      [r0,:64], r2
+        vrhadd.u8       d8,  d8,  d4
+        vld1.8          {d5},      [r0,:64], r2
+        vrhadd.u8       d9,  d9,  d5
+        vld1.8          {d6},      [r0,:64], r2
+        vrhadd.u8       d10, d10, d6
+        vld1.8          {d7},      [r0,:64], r2
+        vrhadd.u8       d11, d11, d7
+        sub             r0,  r0,  r2,  lsl #3
+  .endif
+
+        vst1.8          {d12},     [r0,:64], r2
+        vst1.8          {d13},     [r0,:64], r2
+        vst1.8          {d14},     [r0,:64], r2
+        vst1.8          {d15},     [r0,:64], r2
+        vst1.8          {d8},      [r0,:64], r2
+        vst1.8          {d9},      [r0,:64], r2
+        vst1.8          {d10},     [r0,:64], r2
+        vst1.8          {d11},     [r0,:64], r2
+
+        mov             lr,  r10
+        bx              lr
+endfunc
+.endm
+
+        h264_qpel8_hv_lowpass put
+        h264_qpel8_hv_lowpass avg
+
+.macro  h264_qpel8_hv_lowpass_l2 type
+function \type\()_h264_qpel8_hv_lowpass_l2_neon
+        mov             r10, lr
+        bl              put_h264_qpel8_hv_lowpass_neon_top
+
+        vld1.8          {d0, d1},  [r2,:128]!
+        vld1.8          {d2, d3},  [r2,:128]!
+        vrhadd.u8       q0,  q0,  q6
+        vld1.8          {d4, d5},  [r2,:128]!
+        vrhadd.u8       q1,  q1,  q7
+        vld1.8          {d6, d7},  [r2,:128]!
+        vrhadd.u8       q2,  q2,  q4
+        vrhadd.u8       q3,  q3,  q5
+  .ifc \type,avg
+        vld1.8          {d16},     [r0,:64], r3
+        vrhadd.u8       d0,  d0,  d16
+        vld1.8          {d17},     [r0,:64], r3
+        vrhadd.u8       d1,  d1,  d17
+        vld1.8          {d18},     [r0,:64], r3
+        vrhadd.u8       d2,  d2,  d18
+        vld1.8          {d19},     [r0,:64], r3
+        vrhadd.u8       d3,  d3,  d19
+        vld1.8          {d20},     [r0,:64], r3
+        vrhadd.u8       d4,  d4,  d20
+        vld1.8          {d21},     [r0,:64], r3
+        vrhadd.u8       d5,  d5,  d21
+        vld1.8          {d22},     [r0,:64], r3
+        vrhadd.u8       d6,  d6,  d22
+        vld1.8          {d23},     [r0,:64], r3
+        vrhadd.u8       d7,  d7,  d23
+        sub             r0,  r0,  r3,  lsl #3
+  .endif
+        vst1.8          {d0},      [r0,:64], r3
+        vst1.8          {d1},      [r0,:64], r3
+        vst1.8          {d2},      [r0,:64], r3
+        vst1.8          {d3},      [r0,:64], r3
+        vst1.8          {d4},      [r0,:64], r3
+        vst1.8          {d5},      [r0,:64], r3
+        vst1.8          {d6},      [r0,:64], r3
+        vst1.8          {d7},      [r0,:64], r3
+
+        mov             lr,  r10
+        bx              lr
+endfunc
+.endm
+
+        h264_qpel8_hv_lowpass_l2 put
+        h264_qpel8_hv_lowpass_l2 avg
+
+.macro  h264_qpel16_hv  type
+function \type\()_h264_qpel16_hv_lowpass_neon
+        mov             r9,  lr
+        bl              \type\()_h264_qpel8_hv_lowpass_neon
+        sub             r1,  r1,  r3, lsl #2
+        bl              \type\()_h264_qpel8_hv_lowpass_neon
+        sub             r1,  r1,  r3, lsl #4
+        sub             r1,  r1,  r3, lsl #2
+        add             r1,  r1,  #8
+        sub             r0,  r0,  r2, lsl #4
+        add             r0,  r0,  #8
+        bl              \type\()_h264_qpel8_hv_lowpass_neon
+        sub             r1,  r1,  r3, lsl #2
+        mov             lr,  r9
+        b               \type\()_h264_qpel8_hv_lowpass_neon
+endfunc
+
+function \type\()_h264_qpel16_hv_lowpass_l2_neon
+        mov             r9,  lr
+        sub             r2,  r4,  #256
+        bl              \type\()_h264_qpel8_hv_lowpass_l2_neon
+        sub             r1,  r1,  r3, lsl #2
+        bl              \type\()_h264_qpel8_hv_lowpass_l2_neon
+        sub             r1,  r1,  r3, lsl #4
+        sub             r1,  r1,  r3, lsl #2
+        add             r1,  r1,  #8
+        sub             r0,  r0,  r3, lsl #4
+        add             r0,  r0,  #8
+        bl              \type\()_h264_qpel8_hv_lowpass_l2_neon
+        sub             r1,  r1,  r3, lsl #2
+        mov             lr,  r9
+        b               \type\()_h264_qpel8_hv_lowpass_l2_neon
+endfunc
+.endm
+
+        h264_qpel16_hv put
+        h264_qpel16_hv avg
+
+.macro  h264_qpel8      type
+function ff_\type\()_h264_qpel8_mc10_neon, export=1
+        lowpass_const   r3
+        mov             r3,  r1
+        sub             r1,  r1,  #2
+        mov             r12, #8
+        b               \type\()_h264_qpel8_h_lowpass_l2_neon
+endfunc
+
+function ff_\type\()_h264_qpel8_mc20_neon, export=1
+        lowpass_const   r3
+        sub             r1,  r1,  #2
+        mov             r3,  r2
+        mov             r12, #8
+        b               \type\()_h264_qpel8_h_lowpass_neon
+endfunc
+
+function ff_\type\()_h264_qpel8_mc30_neon, export=1
+        lowpass_const   r3
+        add             r3,  r1,  #1
+        sub             r1,  r1,  #2
+        mov             r12, #8
+        b               \type\()_h264_qpel8_h_lowpass_l2_neon
+endfunc
+
+function ff_\type\()_h264_qpel8_mc01_neon, export=1
+        push            {lr}
+        mov             r12, r1
+\type\()_h264_qpel8_mc01:
+        lowpass_const   r3
+        mov             r3,  r2
+        sub             r1,  r1,  r2, lsl #1
+        vpush           {d8-d15}
+        bl              \type\()_h264_qpel8_v_lowpass_l2_neon
+        vpop            {d8-d15}
+        pop             {pc}
+endfunc
+
+function ff_\type\()_h264_qpel8_mc11_neon, export=1
+        push            {r0, r1, r11, lr}
+\type\()_h264_qpel8_mc11:
+        lowpass_const   r3
+        mov             r11, sp
+A       bic             sp,  sp,  #15
+T       bic             r0,  r11, #15
+T       mov             sp,  r0
+        sub             sp,  sp,  #64
+        mov             r0,  sp
+        sub             r1,  r1,  #2
+        mov             r3,  #8
+        mov             r12, #8
+        vpush           {d8-d15}
+        bl              put_h264_qpel8_h_lowpass_neon
+        ldrd            r0,  r1,  [r11], #8
+        mov             r3,  r2
+        add             r12, sp,  #64
+        sub             r1,  r1,  r2, lsl #1
+        mov             r2,  #8
+        bl              \type\()_h264_qpel8_v_lowpass_l2_neon
+        vpop            {d8-d15}
+        mov             sp,  r11
+        pop             {r11, pc}
+endfunc
+
+function ff_\type\()_h264_qpel8_mc21_neon, export=1
+        push            {r0, r1, r4, r10, r11, lr}
+\type\()_h264_qpel8_mc21:
+        lowpass_const   r3
+        mov             r11, sp
+A       bic             sp,  sp,  #15
+T       bic             r0,  r11, #15
+T       mov             sp,  r0
+        sub             sp,  sp,  #(8*8+16*12)
+        sub             r1,  r1,  #2
+        mov             r3,  #8
+        mov             r0,  sp
+        mov             r12, #8
+        vpush           {d8-d15}
+        bl              put_h264_qpel8_h_lowpass_neon
+        mov             r4,  r0
+        ldrd            r0,  r1,  [r11], #8
+        sub             r1,  r1,  r2, lsl #1
+        sub             r1,  r1,  #2
+        mov             r3,  r2
+        sub             r2,  r4,  #64
+        bl              \type\()_h264_qpel8_hv_lowpass_l2_neon
+        vpop            {d8-d15}
+        mov             sp,  r11
+        pop             {r4, r10, r11, pc}
+endfunc
+
+function ff_\type\()_h264_qpel8_mc31_neon, export=1
+        add             r1,  r1,  #1
+        push            {r0, r1, r11, lr}
+        sub             r1,  r1,  #1
+        b               \type\()_h264_qpel8_mc11
+endfunc
+
+function ff_\type\()_h264_qpel8_mc02_neon, export=1
+        push            {lr}
+        lowpass_const   r3
+        sub             r1,  r1,  r2, lsl #1
+        mov             r3,  r2
+        vpush           {d8-d15}
+        bl              \type\()_h264_qpel8_v_lowpass_neon
+        vpop            {d8-d15}
+        pop             {pc}
+endfunc
+
+function ff_\type\()_h264_qpel8_mc12_neon, export=1
+        push            {r0, r1, r4, r10, r11, lr}
+\type\()_h264_qpel8_mc12:
+        lowpass_const   r3
+        mov             r11, sp
+A       bic             sp,  sp,  #15
+T       bic             r0,  r11, #15
+T       mov             sp,  r0
+        sub             sp,  sp,  #(8*8+16*12)
+        sub             r1,  r1,  r2, lsl #1
+        mov             r3,  r2
+        mov             r2,  #8
+        mov             r0,  sp
+        vpush           {d8-d15}
+        bl              put_h264_qpel8_v_lowpass_neon
+        mov             r4,  r0
+        ldrd            r0,  r1,  [r11], #8
+        sub             r1,  r1,  r3, lsl #1
+        sub             r1,  r1,  #2
+        sub             r2,  r4,  #64
+        bl              \type\()_h264_qpel8_hv_lowpass_l2_neon
+        vpop            {d8-d15}
+        mov             sp,  r11
+        pop             {r4, r10, r11, pc}
+endfunc
+
+function ff_\type\()_h264_qpel8_mc22_neon, export=1
+        push            {r4, r10, r11, lr}
+        mov             r11, sp
+A       bic             sp,  sp,  #15
+T       bic             r4,  r11, #15
+T       mov             sp,  r4
+        sub             r1,  r1,  r2, lsl #1
+        sub             r1,  r1,  #2
+        mov             r3,  r2
+        sub             sp,  sp,  #(16*12)
+        mov             r4,  sp
+        vpush           {d8-d15}
+        bl              \type\()_h264_qpel8_hv_lowpass_neon
+        vpop            {d8-d15}
+        mov             sp,  r11
+        pop             {r4, r10, r11, pc}
+endfunc
+
+function ff_\type\()_h264_qpel8_mc32_neon, export=1
+        push            {r0, r1, r4, r10, r11, lr}
+        add             r1,  r1,  #1
+        b               \type\()_h264_qpel8_mc12
+endfunc
+
+function ff_\type\()_h264_qpel8_mc03_neon, export=1
+        push            {lr}
+        add             r12, r1,  r2
+        b               \type\()_h264_qpel8_mc01
+endfunc
+
+function ff_\type\()_h264_qpel8_mc13_neon, export=1
+        push            {r0, r1, r11, lr}
+        add             r1,  r1,  r2
+        b               \type\()_h264_qpel8_mc11
+endfunc
+
+function ff_\type\()_h264_qpel8_mc23_neon, export=1
+        push            {r0, r1, r4, r10, r11, lr}
+        add             r1,  r1,  r2
+        b               \type\()_h264_qpel8_mc21
+endfunc
+
+function ff_\type\()_h264_qpel8_mc33_neon, export=1
+        add             r1,  r1,  #1
+        push            {r0, r1, r11, lr}
+        add             r1,  r1,  r2
+        sub             r1,  r1,  #1
+        b               \type\()_h264_qpel8_mc11
+endfunc
+.endm
+
+        h264_qpel8 put
+        h264_qpel8 avg
+
+.macro  h264_qpel16     type
+function ff_\type\()_h264_qpel16_mc10_neon, export=1
+        lowpass_const   r3
+        mov             r3,  r1
+        sub             r1,  r1,  #2
+        b               \type\()_h264_qpel16_h_lowpass_l2_neon
+endfunc
+
+function ff_\type\()_h264_qpel16_mc20_neon, export=1
+        lowpass_const   r3
+        sub             r1,  r1,  #2
+        mov             r3,  r2
+        b               \type\()_h264_qpel16_h_lowpass_neon
+endfunc
+
+function ff_\type\()_h264_qpel16_mc30_neon, export=1
+        lowpass_const   r3
+        add             r3,  r1,  #1
+        sub             r1,  r1,  #2
+        b               \type\()_h264_qpel16_h_lowpass_l2_neon
+endfunc
+
+function ff_\type\()_h264_qpel16_mc01_neon, export=1
+        push            {r4, lr}
+        mov             r12, r1
+\type\()_h264_qpel16_mc01:
+        lowpass_const   r3
+        mov             r3,  r2
+        sub             r1,  r1,  r2, lsl #1
+        vpush           {d8-d15}
+        bl              \type\()_h264_qpel16_v_lowpass_l2_neon
+        vpop            {d8-d15}
+        pop             {r4, pc}
+endfunc
+
+function ff_\type\()_h264_qpel16_mc11_neon, export=1
+        push            {r0, r1, r4, r11, lr}
+\type\()_h264_qpel16_mc11:
+        lowpass_const   r3
+        mov             r11, sp
+A       bic             sp,  sp,  #15
+T       bic             r0,  r11, #15
+T       mov             sp,  r0
+        sub             sp,  sp,  #256
+        mov             r0,  sp
+        sub             r1,  r1,  #2
+        mov             r3,  #16
+        vpush           {d8-d15}
+        bl              put_h264_qpel16_h_lowpass_neon
+        ldrd            r0,  r1,  [r11], #8
+        mov             r3,  r2
+        add             r12, sp,  #64
+        sub             r1,  r1,  r2, lsl #1
+        mov             r2,  #16
+        bl              \type\()_h264_qpel16_v_lowpass_l2_neon
+        vpop            {d8-d15}
+        mov             sp,  r11
+        pop             {r4, r11, pc}
+endfunc
+
+function ff_\type\()_h264_qpel16_mc21_neon, export=1
+        push            {r0, r1, r4-r5, r9-r11, lr}
+\type\()_h264_qpel16_mc21:
+        lowpass_const   r3
+        mov             r11, sp
+A       bic             sp,  sp,  #15
+T       bic             r0,  r11, #15
+T       mov             sp,  r0
+        sub             sp,  sp,  #(16*16+16*12)
+        sub             r1,  r1,  #2
+        mov             r0,  sp
+        vpush           {d8-d15}
+        bl              put_h264_qpel16_h_lowpass_neon_packed
+        mov             r4,  r0
+        ldrd            r0,  r1,  [r11], #8
+        sub             r1,  r1,  r2, lsl #1
+        sub             r1,  r1,  #2
+        mov             r3,  r2
+        bl              \type\()_h264_qpel16_hv_lowpass_l2_neon
+        vpop            {d8-d15}
+        mov             sp,  r11
+        pop             {r4-r5, r9-r11, pc}
+endfunc
+
+function ff_\type\()_h264_qpel16_mc31_neon, export=1
+        add             r1,  r1,  #1
+        push            {r0, r1, r4, r11, lr}
+        sub             r1,  r1,  #1
+        b               \type\()_h264_qpel16_mc11
+endfunc
+
+function ff_\type\()_h264_qpel16_mc02_neon, export=1
+        push            {r4, lr}
+        lowpass_const   r3
+        sub             r1,  r1,  r2, lsl #1
+        mov             r3,  r2
+        vpush           {d8-d15}
+        bl              \type\()_h264_qpel16_v_lowpass_neon
+        vpop            {d8-d15}
+        pop             {r4, pc}
+endfunc
+
+function ff_\type\()_h264_qpel16_mc12_neon, export=1
+        push            {r0, r1, r4-r5, r9-r11, lr}
+\type\()_h264_qpel16_mc12:
+        lowpass_const   r3
+        mov             r11, sp
+A       bic             sp,  sp,  #15
+T       bic             r0,  r11, #15
+T       mov             sp,  r0
+        sub             sp,  sp,  #(16*16+16*12)
+        sub             r1,  r1,  r2, lsl #1
+        mov             r0,  sp
+        mov             r3,  r2
+        vpush           {d8-d15}
+        bl              put_h264_qpel16_v_lowpass_neon_packed
+        mov             r4,  r0
+        ldrd            r0,  r1,  [r11], #8
+        sub             r1,  r1,  r3, lsl #1
+        sub             r1,  r1,  #2
+        mov             r2,  r3
+        bl              \type\()_h264_qpel16_hv_lowpass_l2_neon
+        vpop            {d8-d15}
+        mov             sp,  r11
+        pop             {r4-r5, r9-r11, pc}
+endfunc
+
+function ff_\type\()_h264_qpel16_mc22_neon, export=1
+        push            {r4, r9-r11, lr}
+        lowpass_const   r3
+        mov             r11, sp
+A       bic             sp,  sp,  #15
+T       bic             r4,  r11, #15
+T       mov             sp,  r4
+        sub             r1,  r1,  r2, lsl #1
+        sub             r1,  r1,  #2
+        mov             r3,  r2
+        sub             sp,  sp,  #(16*12)
+        mov             r4,  sp
+        vpush           {d8-d15}
+        bl              \type\()_h264_qpel16_hv_lowpass_neon
+        vpop            {d8-d15}
+        mov             sp,  r11
+        pop             {r4, r9-r11, pc}
+endfunc
+
+function ff_\type\()_h264_qpel16_mc32_neon, export=1
+        push            {r0, r1, r4-r5, r9-r11, lr}
+        add             r1,  r1,  #1
+        b               \type\()_h264_qpel16_mc12
+endfunc
+
+function ff_\type\()_h264_qpel16_mc03_neon, export=1
+        push            {r4, lr}
+        add             r12, r1,  r2
+        b               \type\()_h264_qpel16_mc01
+endfunc
+
+function ff_\type\()_h264_qpel16_mc13_neon, export=1
+        push            {r0, r1, r4, r11, lr}
+        add             r1,  r1,  r2
+        b               \type\()_h264_qpel16_mc11
+endfunc
+
+function ff_\type\()_h264_qpel16_mc23_neon, export=1
+        push            {r0, r1, r4-r5, r9-r11, lr}
+        add             r1,  r1,  r2
+        b               \type\()_h264_qpel16_mc21
+endfunc
+
+function ff_\type\()_h264_qpel16_mc33_neon, export=1
+        add             r1,  r1,  #1
+        push            {r0, r1, r4, r11, lr}
+        add             r1,  r1,  r2
+        sub             r1,  r1,  #1
+        b               \type\()_h264_qpel16_mc11
+endfunc
+.endm
+
+        h264_qpel16 put
+        h264_qpel16 avg
diff --git a/libavcodec/arm/jrevdct_arm.S b/libavcodec/arm/jrevdct_arm.S
index 331ad85..f951e2a 100644
--- a/libavcodec/arm/jrevdct_arm.S
+++ b/libavcodec/arm/jrevdct_arm.S
@@ -66,7 +66,7 @@
         ldrsh r2, [lr, # 2]             @ r2 = 'd2'
 
         @ Optimization for row that have all items except the first set to 0
-        @ (this works as the DCTELEMS are always 4-byte aligned)
+        @ (this works as the int16_t are always 4-byte aligned)
         ldr r5, [lr, # 0]
         ldr r6, [lr, # 4]
         ldr r3, [lr, # 8]
diff --git a/libavcodec/arm/mathops.h b/libavcodec/arm/mathops.h
index 9313d6b..dc57c55 100644
--- a/libavcodec/arm/mathops.h
+++ b/libavcodec/arm/mathops.h
@@ -28,7 +28,7 @@
 
 #if HAVE_INLINE_ASM
 
-#if HAVE_ARMV6
+#if HAVE_ARMV6_INLINE
 #define MULH MULH
 static inline av_const int MULH(int a, int b)
 {
@@ -50,7 +50,7 @@
     return r;
 }
 
-#else /* HAVE_ARMV6 */
+#else /* HAVE_ARMV6_INLINE */
 
 #define FASTDIV FASTDIV
 static av_always_inline av_const int FASTDIV(int a, int b)
@@ -64,7 +64,7 @@
 
 #define MLS64(d, a, b) MAC64(d, -(a), b)
 
-#if HAVE_ARMV5TE
+#if HAVE_ARMV5TE_INLINE
 
 /* signed 16x16 -> 32 multiply add accumulate */
 #   define MAC16(rt, ra, rb)                                            \
diff --git a/libavcodec/arm/mpegaudiodsp_init_arm.c b/libavcodec/arm/mpegaudiodsp_init_arm.c
index a9804e9..e73aee6 100644
--- a/libavcodec/arm/mpegaudiodsp_init_arm.c
+++ b/libavcodec/arm/mpegaudiodsp_init_arm.c
@@ -20,6 +20,7 @@
 
 #include <stdint.h>
 
+#include "libavutil/attributes.h"
 #include "libavutil/arm/cpu.h"
 #include "libavcodec/mpegaudiodsp.h"
 #include "config.h"
@@ -27,7 +28,7 @@
 void ff_mpadsp_apply_window_fixed_armv6(int32_t *synth_buf, int32_t *window,
                                         int *dither, int16_t *out, int incr);
 
-void ff_mpadsp_init_arm(MPADSPContext *s)
+av_cold void ff_mpadsp_init_arm(MPADSPContext *s)
 {
     int cpu_flags = av_get_cpu_flags();
 
diff --git a/libavcodec/arm/mpegvideo_arm.c b/libavcodec/arm/mpegvideo_arm.c
index 28838bb..6566798 100644
--- a/libavcodec/arm/mpegvideo_arm.c
+++ b/libavcodec/arm/mpegvideo_arm.c
@@ -20,7 +20,6 @@
 
 #include "libavutil/arm/cpu.h"
 #include "libavcodec/avcodec.h"
-#include "libavcodec/dsputil.h"
 #include "libavcodec/mpegvideo.h"
 #include "mpegvideo_arm.h"
 #include "asm-offsets.h"
@@ -34,12 +33,12 @@
 CHK_OFFS(MpegEncContext, h263_aic,         H263_AIC);
 #endif
 
-void ff_dct_unquantize_h263_inter_neon(MpegEncContext *s, DCTELEM *block,
+void ff_dct_unquantize_h263_inter_neon(MpegEncContext *s, int16_t *block,
                                        int n, int qscale);
-void ff_dct_unquantize_h263_intra_neon(MpegEncContext *s, DCTELEM *block,
+void ff_dct_unquantize_h263_intra_neon(MpegEncContext *s, int16_t *block,
                                        int n, int qscale);
 
-void ff_MPV_common_init_arm(MpegEncContext *s)
+av_cold void ff_MPV_common_init_arm(MpegEncContext *s)
 {
     int cpu_flags = av_get_cpu_flags();
 
diff --git a/libavcodec/arm/mpegvideo_armv5te.c b/libavcodec/arm/mpegvideo_armv5te.c
index 842620b..a572290 100644
--- a/libavcodec/arm/mpegvideo_armv5te.c
+++ b/libavcodec/arm/mpegvideo_armv5te.c
@@ -19,13 +19,13 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/avassert.h"
 #include "libavcodec/avcodec.h"
-#include "libavcodec/dsputil.h"
 #include "libavcodec/mpegvideo.h"
 #include "mpegvideo_arm.h"
 
-void ff_dct_unquantize_h263_armv5te(DCTELEM *block, int qmul, int qadd, int count);
+void ff_dct_unquantize_h263_armv5te(int16_t *block, int qmul, int qadd, int count);
 
 #ifdef ENABLE_ARM_TESTS
 /**
@@ -33,7 +33,7 @@
  * have optimized implementations for each architecture. Is also used as a reference
  * implementation in regression tests
  */
-static inline void dct_unquantize_h263_helper_c(DCTELEM *block, int qmul, int qadd, int count)
+static inline void dct_unquantize_h263_helper_c(int16_t *block, int qmul, int qadd, int count)
 {
     int i, level;
     for (i = 0; i < count; i++) {
@@ -51,7 +51,7 @@
 #endif
 
 static void dct_unquantize_h263_intra_armv5te(MpegEncContext *s,
-                                  DCTELEM *block, int n, int qscale)
+                                  int16_t *block, int n, int qscale)
 {
     int level, qmul, qadd;
     int nCoeffs;
@@ -80,7 +80,7 @@
 }
 
 static void dct_unquantize_h263_inter_armv5te(MpegEncContext *s,
-                                  DCTELEM *block, int n, int qscale)
+                                  int16_t *block, int n, int qscale)
 {
     int qmul, qadd;
     int nCoeffs;
@@ -95,7 +95,7 @@
     ff_dct_unquantize_h263_armv5te(block, qmul, qadd, nCoeffs + 1);
 }
 
-void ff_MPV_common_init_armv5te(MpegEncContext *s)
+av_cold void ff_MPV_common_init_armv5te(MpegEncContext *s)
 {
     s->dct_unquantize_h263_intra = dct_unquantize_h263_intra_armv5te;
     s->dct_unquantize_h263_inter = dct_unquantize_h263_inter_armv5te;
diff --git a/libavcodec/arm/rv34dsp_init_arm.c b/libavcodec/arm/rv34dsp_init_arm.c
index 60ab82e..8bfe90b 100644
--- a/libavcodec/arm/rv34dsp_init_arm.c
+++ b/libavcodec/arm/rv34dsp_init_arm.c
@@ -20,18 +20,19 @@
 
 #include <stdint.h>
 
+#include "libavutil/attributes.h"
 #include "libavcodec/avcodec.h"
 #include "libavcodec/rv34dsp.h"
 #include "libavutil/arm/cpu.h"
 
-void ff_rv34_inv_transform_noround_neon(DCTELEM *block);
+void ff_rv34_inv_transform_noround_neon(int16_t *block);
 
-void ff_rv34_inv_transform_noround_dc_neon(DCTELEM *block);
+void ff_rv34_inv_transform_noround_dc_neon(int16_t *block);
 
-void ff_rv34_idct_add_neon(uint8_t *dst, ptrdiff_t stride, DCTELEM *block);
+void ff_rv34_idct_add_neon(uint8_t *dst, ptrdiff_t stride, int16_t *block);
 void ff_rv34_idct_dc_add_neon(uint8_t *dst, ptrdiff_t stride, int dc);
 
-void ff_rv34dsp_init_arm(RV34DSPContext *c, DSPContext* dsp)
+av_cold void ff_rv34dsp_init_arm(RV34DSPContext *c)
 {
     int cpu_flags = av_get_cpu_flags();
 
diff --git a/libavcodec/arm/rv34dsp_neon.S b/libavcodec/arm/rv34dsp_neon.S
index 522e387..a29123f 100644
--- a/libavcodec/arm/rv34dsp_neon.S
+++ b/libavcodec/arm/rv34dsp_neon.S
@@ -67,7 +67,7 @@
         vsub.s32        q15, q14, q9    @ z0 - z3
 .endm
 
-/* void rv34_idct_add_c(uint8_t *dst, int stride, DCTELEM *block) */
+/* void rv34_idct_add_c(uint8_t *dst, int stride, int16_t *block) */
 function ff_rv34_idct_add_neon, export=1
         mov             r3,  r0
         rv34_inv_transform   r2
@@ -97,7 +97,7 @@
         bx              lr
 endfunc
 
-/* void rv34_inv_transform_noround_neon(DCTELEM *block); */
+/* void rv34_inv_transform_noround_neon(int16_t *block); */
 function ff_rv34_inv_transform_noround_neon, export=1
         rv34_inv_transform   r0
         vshl.s32        q11, q2,  #1
@@ -142,7 +142,7 @@
         bx              lr
 endfunc
 
-/* void rv34_inv_transform_dc_noround_c(DCTELEM *block) */
+/* void rv34_inv_transform_dc_noround_c(int16_t *block) */
 function ff_rv34_inv_transform_noround_dc_neon, export=1
         vld1.16         {d28[]}, [r0,:16]       @ block[0]
         vmov.i16        d4,  #251
diff --git a/libavcodec/arm/rv40dsp_init_arm.c b/libavcodec/arm/rv40dsp_init_arm.c
index 1f9364a..59ef10b 100644
--- a/libavcodec/arm/rv40dsp_init_arm.c
+++ b/libavcodec/arm/rv40dsp_init_arm.c
@@ -20,6 +20,7 @@
 
 #include <stdint.h>
 
+#include "libavutil/attributes.h"
 #include "libavcodec/avcodec.h"
 #include "libavcodec/rv34dsp.h"
 #include "libavutil/arm/cpu.h"
@@ -69,7 +70,7 @@
                                      int filter_q1, int alpha, int beta,
                                      int lim_p0q0, int lim_q1, int lim_p1);
 
-static void ff_rv40dsp_init_neon(RV34DSPContext *c)
+static av_cold void ff_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;
@@ -138,7 +139,7 @@
     c->rv40_weak_loop_filter[1]     = ff_rv40_v_weak_loop_filter_neon;
 }
 
-void ff_rv40dsp_init_arm(RV34DSPContext *c, DSPContext* dsp)
+av_cold void ff_rv40dsp_init_arm(RV34DSPContext *c)
 {
     int cpu_flags = av_get_cpu_flags();
 
diff --git a/libavcodec/arm/simple_idct_armv6.S b/libavcodec/arm/simple_idct_armv6.S
index 0c19d26..79cf5d4 100644
--- a/libavcodec/arm/simple_idct_armv6.S
+++ b/libavcodec/arm/simple_idct_armv6.S
@@ -375,7 +375,7 @@
         sub    r0, r0, #(16*7)
         .endm
 
-/* void ff_simple_idct_armv6(DCTELEM *data); */
+/* void ff_simple_idct_armv6(int16_t *data); */
 function ff_simple_idct_armv6, export=1
         push   {r4-r11, lr}
         sub    sp, sp, #128
@@ -390,7 +390,7 @@
         pop    {r4-r11, pc}
 endfunc
 
-/* ff_simple_idct_add_armv6(uint8_t *dest, int line_size, DCTELEM *data); */
+/* ff_simple_idct_add_armv6(uint8_t *dest, int line_size, int16_t *data); */
 function ff_simple_idct_add_armv6, export=1
         push   {r0, r1, r4-r11, lr}
         sub    sp, sp, #128
@@ -407,7 +407,7 @@
         pop    {r4-r11, pc}
 endfunc
 
-/* ff_simple_idct_put_armv6(uint8_t *dest, int line_size, DCTELEM *data); */
+/* ff_simple_idct_put_armv6(uint8_t *dest, int line_size, int16_t *data); */
 function ff_simple_idct_put_armv6, export=1
         push   {r0, r1, r4-r11, lr}
         sub    sp, sp, #128
diff --git a/libavcodec/arm/simple_idct_neon.S b/libavcodec/arm/simple_idct_neon.S
index a8fc137..c3e573c 100644
--- a/libavcodec/arm/simple_idct_neon.S
+++ b/libavcodec/arm/simple_idct_neon.S
@@ -261,7 +261,7 @@
         pop             {r4-r7, pc}
         .endm
 
-/* void ff_simple_idct_put_neon(uint8_t *dst, int line_size, DCTELEM *data); */
+/* void ff_simple_idct_put_neon(uint8_t *dst, int line_size, int16_t *data); */
 function ff_simple_idct_put_neon, export=1
         idct_start      r2
 
@@ -316,7 +316,7 @@
         bx              lr
 endfunc
 
-/* void ff_simple_idct_add_neon(uint8_t *dst, int line_size, DCTELEM *data); */
+/* void ff_simple_idct_add_neon(uint8_t *dst, int line_size, int16_t *data); */
 function ff_simple_idct_add_neon, export=1
         idct_start      r2
 
@@ -355,7 +355,7 @@
         bx              lr
 endfunc
 
-/* void ff_simple_idct_neon(DCTELEM *data); */
+/* void ff_simple_idct_neon(int16_t *data); */
 function ff_simple_idct_neon, export=1
         idct_start      r0
 
diff --git a/libavcodec/arm/dsputil_init_vfp.c b/libavcodec/arm/videodsp_arm.h
similarity index 67%
rename from libavcodec/arm/dsputil_init_vfp.c
rename to libavcodec/arm/videodsp_arm.h
index 5713c71..112cbb8 100644
--- a/libavcodec/arm/dsputil_init_vfp.c
+++ b/libavcodec/arm/videodsp_arm.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008 Siarhei Siamashka <ssvb@users.sourceforge.net>
+ * Copyright (c) 2009 Mans Rullgard <mans@mansr.com>
  *
  * This file is part of FFmpeg.
  *
@@ -18,13 +18,12 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavcodec/dsputil.h"
-#include "dsputil_arm.h"
+#ifndef AVCODEC_ARM_VIDEODSP_ARM_H
+#define AVCODEC_ARM_VIDEODSP_ARM_H
 
-void ff_vector_fmul_reverse_vfp(float *dst, const float *src0,
-                                const float *src1, int len);
+#include "libavcodec/avcodec.h"
+#include "libavcodec/videodsp.h"
 
-void ff_dsputil_init_vfp(DSPContext* c, AVCodecContext *avctx)
-{
-    c->vector_fmul_reverse = ff_vector_fmul_reverse_vfp;
-}
+void ff_videodsp_init_armv5te(VideoDSPContext* ctx, int bpc);
+
+#endif /* AVCODEC_ARM_VIDEODSP_ARM_H */
diff --git a/libavcodec/arm/videodsp_armv5te.S b/libavcodec/arm/videodsp_armv5te.S
new file mode 100644
index 0000000..48a6c3b
--- /dev/null
+++ b/libavcodec/arm/videodsp_armv5te.S
@@ -0,0 +1,31 @@
+@
+@ ARMv5te optimized DSP utils
+@ Copyright (c) 2004 AGAWA Koji <i (AT) atty (DOT) jp>
+@
+@ 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/arm/asm.S"
+
+function ff_prefetch_arm, export=1
+        subs            r2,  r2,  #1
+        pld             [r0]
+        add             r0,  r0,  r1
+        bne             ff_prefetch_arm
+        bx              lr
+endfunc
diff --git a/libavcodec/arm/dsputil_init_vfp.c b/libavcodec/arm/videodsp_init_arm.c
similarity index 67%
copy from libavcodec/arm/dsputil_init_vfp.c
copy to libavcodec/arm/videodsp_init_arm.c
index 5713c71..a89abb2 100644
--- a/libavcodec/arm/dsputil_init_vfp.c
+++ b/libavcodec/arm/videodsp_init_arm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008 Siarhei Siamashka <ssvb@users.sourceforge.net>
+ * Copyright (C) 2012 Ronald S. Bultje
  *
  * This file is part of FFmpeg.
  *
@@ -18,13 +18,13 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavcodec/dsputil.h"
-#include "dsputil_arm.h"
+#include "libavutil/attributes.h"
+#include "libavutil/arm/cpu.h"
+#include "libavcodec/videodsp.h"
+#include "videodsp_arm.h"
 
-void ff_vector_fmul_reverse_vfp(float *dst, const float *src0,
-                                const float *src1, int len);
-
-void ff_dsputil_init_vfp(DSPContext* c, AVCodecContext *avctx)
+av_cold void ff_videodsp_init_arm(VideoDSPContext *ctx, int bpc)
 {
-    c->vector_fmul_reverse = ff_vector_fmul_reverse_vfp;
+    int cpu_flags = av_get_cpu_flags();
+    if (have_armv5te(cpu_flags)) ff_videodsp_init_armv5te(ctx, bpc);
 }
diff --git a/libavcodec/arm/dsputil_init_vfp.c b/libavcodec/arm/videodsp_init_armv5te.c
similarity index 67%
copy from libavcodec/arm/dsputil_init_vfp.c
copy to libavcodec/arm/videodsp_init_armv5te.c
index 5713c71..1ea1f34 100644
--- a/libavcodec/arm/dsputil_init_vfp.c
+++ b/libavcodec/arm/videodsp_init_armv5te.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008 Siarhei Siamashka <ssvb@users.sourceforge.net>
+ * Copyright (C) 2012 Ronald S. Bultje
  *
  * This file is part of FFmpeg.
  *
@@ -18,13 +18,16 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavcodec/dsputil.h"
-#include "dsputil_arm.h"
+#include "libavutil/attributes.h"
+#include "libavutil/arm/cpu.h"
+#include "libavcodec/videodsp.h"
+#include "videodsp_arm.h"
 
-void ff_vector_fmul_reverse_vfp(float *dst, const float *src0,
-                                const float *src1, int len);
+void ff_prefetch_arm(uint8_t *mem, ptrdiff_t stride, int h);
 
-void ff_dsputil_init_vfp(DSPContext* c, AVCodecContext *avctx)
+av_cold void ff_videodsp_init_armv5te(VideoDSPContext *ctx, int bpc)
 {
-    c->vector_fmul_reverse = ff_vector_fmul_reverse_vfp;
+#if HAVE_ARMV5TE_EXTERNAL
+    ctx->prefetch = ff_prefetch_arm;
+#endif
 }
diff --git a/libavcodec/arm/vorbisdsp_init_arm.c b/libavcodec/arm/vorbisdsp_init_arm.c
new file mode 100644
index 0000000..f4b3d80
--- /dev/null
+++ b/libavcodec/arm/vorbisdsp_init_arm.c
@@ -0,0 +1,37 @@
+/*
+ * ARM NEON optimised DSP functions
+ * Copyright (c) 2008 Mans Rullgard <mans@mansr.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/attributes.h"
+#include "libavutil/cpu.h"
+#include "libavutil/arm/cpu.h"
+#include "libavcodec/vorbisdsp.h"
+
+void ff_vorbis_inverse_coupling_neon(float *mag, float *ang,
+                                     intptr_t blocksize);
+
+av_cold void ff_vorbisdsp_init_arm(VorbisDSPContext *c)
+{
+    int cpu_flags = av_get_cpu_flags();
+
+    if (have_neon(cpu_flags)) {
+        c->vorbis_inverse_coupling = ff_vorbis_inverse_coupling_neon;
+    }
+}
diff --git a/libavcodec/arm/vorbisdsp_neon.S b/libavcodec/arm/vorbisdsp_neon.S
new file mode 100644
index 0000000..79ce54f
--- /dev/null
+++ b/libavcodec/arm/vorbisdsp_neon.S
@@ -0,0 +1,83 @@
+/*
+ * ARM NEON optimised DSP functions
+ * Copyright (c) 2008 Mans Rullgard <mans@mansr.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/arm/asm.S"
+
+function ff_vorbis_inverse_coupling_neon, export=1
+        vmov.i32        q10, #1<<31
+        subs            r2,  r2,  #4
+        mov             r3,  r0
+        mov             r12, r1
+        beq             3f
+
+        vld1.32         {d24-d25},[r1,:128]!
+        vld1.32         {d22-d23},[r0,:128]!
+        vcle.s32        q8,  q12, #0
+        vand            q9,  q11, q10
+        veor            q12, q12, q9
+        vand            q2,  q12, q8
+        vbic            q3,  q12, q8
+        vadd.f32        q12, q11, q2
+        vsub.f32        q11, q11, q3
+1:      vld1.32         {d2-d3},  [r1,:128]!
+        vld1.32         {d0-d1},  [r0,:128]!
+        vcle.s32        q8,  q1,  #0
+        vand            q9,  q0,  q10
+        veor            q1,  q1,  q9
+        vst1.32         {d24-d25},[r3, :128]!
+        vst1.32         {d22-d23},[r12,:128]!
+        vand            q2,  q1,  q8
+        vbic            q3,  q1,  q8
+        vadd.f32        q1,  q0,  q2
+        vsub.f32        q0,  q0,  q3
+        subs            r2,  r2,  #8
+        ble             2f
+        vld1.32         {d24-d25},[r1,:128]!
+        vld1.32         {d22-d23},[r0,:128]!
+        vcle.s32        q8,  q12, #0
+        vand            q9,  q11, q10
+        veor            q12, q12, q9
+        vst1.32         {d2-d3},  [r3, :128]!
+        vst1.32         {d0-d1},  [r12,:128]!
+        vand            q2,  q12, q8
+        vbic            q3,  q12, q8
+        vadd.f32        q12, q11, q2
+        vsub.f32        q11, q11, q3
+        b               1b
+
+2:      vst1.32         {d2-d3},  [r3, :128]!
+        vst1.32         {d0-d1},  [r12,:128]!
+        it              lt
+        bxlt            lr
+
+3:      vld1.32         {d2-d3},  [r1,:128]
+        vld1.32         {d0-d1},  [r0,:128]
+        vcle.s32        q8,  q1,  #0
+        vand            q9,  q0,  q10
+        veor            q1,  q1,  q9
+        vand            q2,  q1,  q8
+        vbic            q3,  q1,  q8
+        vadd.f32        q1,  q0,  q2
+        vsub.f32        q0,  q0,  q3
+        vst1.32         {d2-d3},  [r0,:128]!
+        vst1.32         {d0-d1},  [r1,:128]!
+        bx              lr
+endfunc
diff --git a/libavcodec/arm/vp3dsp_init_arm.c b/libavcodec/arm/vp3dsp_init_arm.c
index 90fc34b..5ffc8fd 100644
--- a/libavcodec/arm/vp3dsp_init_arm.c
+++ b/libavcodec/arm/vp3dsp_init_arm.c
@@ -21,11 +21,12 @@
 #include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
 #include "libavutil/arm/cpu.h"
+#include "libavcodec/dsputil.h"
 #include "libavcodec/vp3dsp.h"
 
-void ff_vp3_idct_put_neon(uint8_t *dest, int line_size, DCTELEM *data);
-void ff_vp3_idct_add_neon(uint8_t *dest, int line_size, DCTELEM *data);
-void ff_vp3_idct_dc_add_neon(uint8_t *dest, int line_size, const DCTELEM *data);
+void ff_vp3_idct_put_neon(uint8_t *dest, int line_size, int16_t *data);
+void ff_vp3_idct_add_neon(uint8_t *dest, int line_size, int16_t *data);
+void ff_vp3_idct_dc_add_neon(uint8_t *dest, int line_size, const int16_t *data);
 
 void ff_vp3_v_loop_filter_neon(uint8_t *, int, int *);
 void ff_vp3_h_loop_filter_neon(uint8_t *, int, int *);
diff --git a/libavcodec/arm/vp3dsp_neon.S b/libavcodec/arm/vp3dsp_neon.S
index 0c88562..f133905 100644
--- a/libavcodec/arm/vp3dsp_neon.S
+++ b/libavcodec/arm/vp3dsp_neon.S
@@ -108,14 +108,20 @@
 
 function vp3_idct_start_neon
     vpush           {d8-d15}
+    vmov.i16        q4,  #0
+    vmov.i16        q5,  #0
     movrel          r3,  vp3_idct_constants
     vld1.64         {d0-d1},   [r3,:128]
-    vld1.64         {d16-d19}, [r2,:128]!
-    vld1.64         {d20-d23}, [r2,:128]!
-    vld1.64         {d24-d27}, [r2,:128]!
+    vld1.64         {d16-d19}, [r2,:128]
+    vst1.64         {q4-q5},   [r2,:128]!
+    vld1.64         {d20-d23}, [r2,:128]
+    vst1.64         {q4-q5},   [r2,:128]!
+    vld1.64         {d24-d27}, [r2,:128]
+    vst1.64         {q4-q5},   [r2,:128]!
     vadd.s16        q1,  q8,  q12
     vsub.s16        q8,  q8,  q12
-    vld1.64         {d28-d31}, [r2,:128]!
+    vld1.64         {d28-d31}, [r2,:128]
+    vst1.64         {q4-q5},   [r2,:128]!
 
 vp3_idct_core_neon:
     vmull.s16       q2,  d18, xC1S7     // (ip[1] * C1) << 16
@@ -345,10 +351,12 @@
 endfunc
 
 function ff_vp3_idct_dc_add_neon, export=1
-    ldrsh           r2,  [r2]
+    ldrsh           r12, [r2]
     mov             r3,  r0
-    add             r2,  r2,  #15
-    vdup.16         q15, r2
+    add             r12, r12,  #15
+    vdup.16         q15, r12
+    mov             r12, 0
+    strh            r12, [r2]
     vshr.s16        q15, q15, #5
 
     vld1.8          {d0}, [r0,:64], r1
diff --git a/libavcodec/arm/vp56_arith.h b/libavcodec/arm/vp56_arith.h
index 29a2228..feb1247 100644
--- a/libavcodec/arm/vp56_arith.h
+++ b/libavcodec/arm/vp56_arith.h
@@ -37,7 +37,7 @@
 #   define U(x)
 #endif
 
-#if HAVE_ARMV6 && HAVE_INLINE_ASM
+#if HAVE_ARMV6_INLINE
 
 #define vp56_rac_get_prob vp56_rac_get_prob_armv6
 static inline int vp56_rac_get_prob_armv6(VP56RangeCoder *c, int pr)
diff --git a/libavcodec/arm/vp56dsp_init_arm.c b/libavcodec/arm/vp56dsp_init_arm.c
index 1304653..f53cbae 100644
--- a/libavcodec/arm/vp56dsp_init_arm.c
+++ b/libavcodec/arm/vp56dsp_init_arm.c
@@ -20,6 +20,7 @@
 
 #include <stdint.h>
 
+#include "libavutil/attributes.h"
 #include "libavutil/arm/cpu.h"
 #include "libavcodec/avcodec.h"
 #include "libavcodec/vp56dsp.h"
@@ -27,7 +28,7 @@
 void ff_vp6_edge_filter_hor_neon(uint8_t *yuv, int stride, int t);
 void ff_vp6_edge_filter_ver_neon(uint8_t *yuv, int stride, int t);
 
-void ff_vp56dsp_init_arm(VP56DSPContext *s, enum AVCodecID codec)
+av_cold void ff_vp56dsp_init_arm(VP56DSPContext *s, enum AVCodecID codec)
 {
     int cpu_flags = av_get_cpu_flags();
 
diff --git a/libavcodec/arm/vp8.h b/libavcodec/arm/vp8.h
index 5a7b142..ddaa120 100644
--- a/libavcodec/arm/vp8.h
+++ b/libavcodec/arm/vp8.h
@@ -19,11 +19,15 @@
 #ifndef AVCODEC_ARM_VP8_H
 #define AVCODEC_ARM_VP8_H
 
-#include "config.h"
+#include <stdint.h>
 
-#if HAVE_ARMV6
+#include "config.h"
+#include "libavcodec/vp56.h"
+#include "libavcodec/vp8.h"
+
+#if HAVE_ARMV6_EXTERNAL
 #define decode_block_coeffs_internal ff_decode_block_coeffs_armv6
-int ff_decode_block_coeffs_armv6(VP56RangeCoder *rc, DCTELEM block[16],
+int ff_decode_block_coeffs_armv6(VP56RangeCoder *rc, int16_t block[16],
                                  uint8_t probs[8][3][NUM_DCT_TOKENS-1],
                                  int i, uint8_t *token_prob, int16_t qmul[2]);
 #endif
diff --git a/libavcodec/arm/vp8dsp_armv6.S b/libavcodec/arm/vp8dsp_armv6.S
index 40be926..5207758 100644
--- a/libavcodec/arm/vp8dsp_armv6.S
+++ b/libavcodec/arm/vp8dsp_armv6.S
@@ -56,7 +56,7 @@
 
 @ idct
 
-@ void vp8_luma_dc_wht(DCTELEM block[4][4][16], DCTELEM dc[16])
+@ void vp8_luma_dc_wht(int16_t block[4][4][16], int16_t dc[16])
 function ff_vp8_luma_dc_wht_armv6, export=1
         push            {r4-r10, lr}
 
@@ -118,20 +118,20 @@
         usub16          r4,  r4,  r6            @ block[0,1][3]
         usub16          r5,  r5,  r12           @ block[2,3][3]
 
-#if HAVE_ARMV6T2
+#if HAVE_ARMV6T2_EXTERNAL
         sbfx            r6,  r8,  #3,  #13
         sbfx            r12, r7,  #3,  #13
         sbfx            r1,  r9,  #3,  #13
         sbfx            r10, r4,  #3,  #13
 #else
-        sxth            r8,  r8
-        sxth            r7,  r7
-        sxth            r9,  r9
-        sxth            r4,  r4
-        asr             r8,  #3                 @ block[0][0]
-        asr             r7,  #3                 @ block[0][1]
-        asr             r9,  #3                 @ block[0][2]
-        asr             r4,  #3                 @ block[0][3]
+        sxth            r6,  r8
+        sxth            r12, r7
+        sxth            r1,  r9
+        sxth            r10, r4
+        asr             r6,  #3                 @ block[0][0]
+        asr             r12, #3                 @ block[0][1]
+        asr             r1,  #3                 @ block[0][2]
+        asr             r10, #3                 @ block[0][3]
 #endif
 
         strh            r6,  [r0], #32
@@ -151,7 +151,7 @@
         strh            r4,  [r0], #32
         asr             r10, r5,  #19           @ block[3][3]
 
-#if HAVE_ARMV6T2
+#if HAVE_ARMV6T2_EXTERNAL
         sbfx            r2,  r2,  #3,  #13
         sbfx            lr,  lr,  #3,  #13
         sbfx            r3,  r3,  #3,  #13
@@ -179,7 +179,7 @@
         pop             {r4-r10, pc}
 endfunc
 
-@ void vp8_luma_dc_wht_dc(DCTELEM block[4][4][16], DCTELEM dc[16])
+@ void vp8_luma_dc_wht_dc(int16_t block[4][4][16], int16_t dc[16])
 function ff_vp8_luma_dc_wht_dc_armv6, export=1
         ldrsh           r2,  [r1]
         mov             r3,  #0
@@ -192,7 +192,7 @@
         bx              lr
 endfunc
 
-@ void vp8_idct_add(uint8_t *dst, DCTELEM block[16], int stride)
+@ void vp8_idct_add(uint8_t *dst, int16_t block[16], int stride)
 function ff_vp8_idct_add_armv6, export=1
         push            {r4-r12, lr}
         sub             sp,  sp,  #32
@@ -284,7 +284,7 @@
         sxth            r12, r12
         ldr             r9,  [r0, r2]
         sxth            r1,  r1
-#if HAVE_ARMV6T2
+#if HAVE_ARMV6T2_EXTERNAL
         sbfx            r7,  r7,  #3,  #13
         sbfx            r10, r10, #3,  #13
 #else
@@ -314,7 +314,7 @@
         pop             {r4-r12, pc}
 endfunc
 
-@ void vp8_idct_dc_add(uint8_t *dst, DCTELEM block[16], int stride)
+@ void vp8_idct_dc_add(uint8_t *dst, int16_t block[16], int stride)
 function ff_vp8_idct_dc_add_armv6, export=1
         push            {r4-r6, lr}
         add             r6,  r0,  r2,  lsl #1
@@ -355,7 +355,7 @@
         pop             {r4-r6, pc}
 endfunc
 
-@ void vp8_idct_dc_add4uv(uint8_t *dst, DCTELEM block[4][16], int stride)
+@ void vp8_idct_dc_add4uv(uint8_t *dst, int16_t block[4][16], int stride)
 function ff_vp8_idct_dc_add4uv_armv6, export=1
         push            {r4, lr}
 
@@ -371,7 +371,7 @@
         pop             {r4, pc}
 endfunc
 
-@ void vp8_idct_dc_add4y(uint8_t *dst, DCTELEM block[4][16], int stride)
+@ void vp8_idct_dc_add4y(uint8_t *dst, int16_t block[4][16], int stride)
 function ff_vp8_idct_dc_add4y_armv6, export=1
         push            {r4, lr}
 
diff --git a/libavcodec/arm/vp8dsp_init_arm.c b/libavcodec/arm/vp8dsp_init_arm.c
index 5c84ed3..d360ae3 100644
--- a/libavcodec/arm/vp8dsp_init_arm.c
+++ b/libavcodec/arm/vp8dsp_init_arm.c
@@ -18,6 +18,7 @@
 
 #include <stdint.h>
 
+#include "libavutil/attributes.h"
 #include "libavutil/arm/cpu.h"
 #include "libavcodec/vp8dsp.h"
 #include "vp8dsp.h"
diff --git a/libavcodec/arm/vp8dsp_init_armv6.c b/libavcodec/arm/vp8dsp_init_armv6.c
index 85a803a..e15e191 100644
--- a/libavcodec/arm/vp8dsp_init_armv6.c
+++ b/libavcodec/arm/vp8dsp_init_armv6.c
@@ -17,16 +17,18 @@
  */
 
 #include <stdint.h>
+
+#include "libavutil/attributes.h"
 #include "libavcodec/vp8dsp.h"
 #include "vp8dsp.h"
 
-void ff_vp8_luma_dc_wht_armv6(DCTELEM block[4][4][16], DCTELEM dc[16]);
-void ff_vp8_luma_dc_wht_dc_armv6(DCTELEM block[4][4][16], DCTELEM dc[16]);
+void ff_vp8_luma_dc_wht_armv6(int16_t block[4][4][16], int16_t dc[16]);
+void ff_vp8_luma_dc_wht_dc_armv6(int16_t block[4][4][16], int16_t dc[16]);
 
-void ff_vp8_idct_add_armv6(uint8_t *dst, DCTELEM block[16], ptrdiff_t stride);
-void ff_vp8_idct_dc_add_armv6(uint8_t *dst, DCTELEM block[16], ptrdiff_t stride);
-void ff_vp8_idct_dc_add4y_armv6(uint8_t *dst, DCTELEM block[4][16], ptrdiff_t stride);
-void ff_vp8_idct_dc_add4uv_armv6(uint8_t *dst, DCTELEM block[4][16], ptrdiff_t stride);
+void ff_vp8_idct_add_armv6(uint8_t *dst, int16_t block[16], ptrdiff_t stride);
+void ff_vp8_idct_dc_add_armv6(uint8_t *dst, int16_t block[16], ptrdiff_t stride);
+void ff_vp8_idct_dc_add4y_armv6(uint8_t *dst, int16_t block[4][16], ptrdiff_t stride);
+void ff_vp8_idct_dc_add4uv_armv6(uint8_t *dst, int16_t block[4][16], ptrdiff_t stride);
 
 VP8_LF(armv6);
 
diff --git a/libavcodec/arm/vp8dsp_init_neon.c b/libavcodec/arm/vp8dsp_init_neon.c
index dbe5b9f..0468181 100644
--- a/libavcodec/arm/vp8dsp_init_neon.c
+++ b/libavcodec/arm/vp8dsp_init_neon.c
@@ -17,15 +17,17 @@
  */
 
 #include <stdint.h>
+
+#include "libavutil/attributes.h"
 #include "libavcodec/vp8dsp.h"
 #include "vp8dsp.h"
 
-void ff_vp8_luma_dc_wht_neon(DCTELEM block[4][4][16], DCTELEM dc[16]);
+void ff_vp8_luma_dc_wht_neon(int16_t block[4][4][16], int16_t dc[16]);
 
-void ff_vp8_idct_add_neon(uint8_t *dst, DCTELEM block[16], ptrdiff_t stride);
-void ff_vp8_idct_dc_add_neon(uint8_t *dst, DCTELEM block[16], ptrdiff_t stride);
-void ff_vp8_idct_dc_add4y_neon(uint8_t *dst, DCTELEM block[4][16], ptrdiff_t stride);
-void ff_vp8_idct_dc_add4uv_neon(uint8_t *dst, DCTELEM block[4][16], ptrdiff_t stride);
+void ff_vp8_idct_add_neon(uint8_t *dst, int16_t block[16], ptrdiff_t stride);
+void ff_vp8_idct_dc_add_neon(uint8_t *dst, int16_t block[16], ptrdiff_t stride);
+void ff_vp8_idct_dc_add4y_neon(uint8_t *dst, int16_t block[4][16], ptrdiff_t stride);
+void ff_vp8_idct_dc_add4uv_neon(uint8_t *dst, int16_t block[4][16], ptrdiff_t stride);
 
 VP8_LF(neon);
 
diff --git a/libavcodec/ass_split.c b/libavcodec/ass_split.c
index 7ee48b4..413e9c8 100644
--- a/libavcodec/ass_split.c
+++ b/libavcodec/ass_split.c
@@ -250,7 +250,9 @@
                         ptr = struct_ptr + section->fields[order[i]].offset;
                         convert_func[type](ptr, buf, len);
                     }
-                    buf = skip_space(buf + len + !last);
+                    buf += len;
+                    if (!last && *buf) buf++;
+                    buf = skip_space(buf);
                 }
             }
         } else {
@@ -267,7 +269,8 @@
                     }
             }
         }
-        buf += strcspn(buf, "\n") + 1;
+        buf += strcspn(buf, "\n");
+        buf += !!*buf;
     }
     return buf;
 }
@@ -282,14 +285,17 @@
 
     while (buf && *buf) {
         if (sscanf(buf, "[%15[0-9A-Za-z+ ]]%c", section, &c) == 2) {
-            buf += strcspn(buf, "\n") + 1;
+            buf += strcspn(buf, "\n");
+            buf += !!*buf;
             for (i=0; i<FF_ARRAY_ELEMS(ass_sections); i++)
                 if (!strcmp(section, ass_sections[i].section)) {
                     ctx->current_section = i;
                     buf = ass_split_section(ctx, buf);
                 }
-        } else
-            buf += strcspn(buf, "\n") + 1;
+        } else {
+            buf += strcspn(buf, "\n");
+            buf += !!*buf;
+        }
     }
     return buf ? 0 : AVERROR_INVALIDDATA;
 }
@@ -368,7 +374,7 @@
     char new_line[2];
     int text_len = 0;
 
-    while (*buf) {
+    while (buf && *buf) {
         if (text && callbacks->text &&
             (sscanf(buf, "\\%1[nN]", new_line) == 1 ||
              !strncmp(buf, "{\\", 2))) {
diff --git a/libavcodec/assdec.c b/libavcodec/assdec.c
index 5a51703..d790656 100644
--- a/libavcodec/assdec.c
+++ b/libavcodec/assdec.c
@@ -29,10 +29,11 @@
 
 static av_cold int ass_decode_init(AVCodecContext *avctx)
 {
-    avctx->subtitle_header = av_malloc(avctx->extradata_size);
+    avctx->subtitle_header = av_malloc(avctx->extradata_size + 1);
     if (!avctx->subtitle_header)
         return AVERROR(ENOMEM);
     memcpy(avctx->subtitle_header, avctx->extradata, avctx->extradata_size);
+    avctx->subtitle_header[avctx->extradata_size] = 0;
     avctx->subtitle_header_size = avctx->extradata_size;
     avctx->priv_data = ff_ass_split(avctx->extradata);
     if(!avctx->priv_data)
diff --git a/libavcodec/assenc.c b/libavcodec/assenc.c
index 7ed21ee..50b89c0 100644
--- a/libavcodec/assenc.c
+++ b/libavcodec/assenc.c
@@ -28,11 +28,12 @@
 
 static av_cold int ass_encode_init(AVCodecContext *avctx)
 {
-    avctx->extradata = av_malloc(avctx->subtitle_header_size);
+    avctx->extradata = av_malloc(avctx->subtitle_header_size + 1);
     if (!avctx->extradata)
         return AVERROR(ENOMEM);
     memcpy(avctx->extradata, avctx->subtitle_header, avctx->subtitle_header_size);
     avctx->extradata_size = avctx->subtitle_header_size;
+    avctx->extradata[avctx->extradata_size] = 0;
     return 0;
 }
 
diff --git a/libavcodec/asv.c b/libavcodec/asv.c
index 34622b4..21f179b 100644
--- a/libavcodec/asv.c
+++ b/libavcodec/asv.c
@@ -27,7 +27,6 @@
 
 #include "asv.h"
 #include "avcodec.h"
-#include "dsputil.h"
 
 const uint8_t ff_asv_scantab[64] = {
     0x00,0x08,0x01,0x09,0x10,0x18,0x11,0x19,
diff --git a/libavcodec/asv.h b/libavcodec/asv.h
index 4a6c799..ca67c67 100644
--- a/libavcodec/asv.h
+++ b/libavcodec/asv.h
@@ -28,7 +28,6 @@
 
 #include <stdint.h>
 
-#include "libavutil/attributes.h"
 #include "libavutil/mem.h"
 
 #include "avcodec.h"
@@ -48,7 +47,7 @@
     int mb_height;
     int mb_width2;
     int mb_height2;
-    DECLARE_ALIGNED(16, DCTELEM, block)[6][64];
+    DECLARE_ALIGNED(16, int16_t, block)[6][64];
     uint16_t intra_matrix[64];
     int q_intra_matrix[64];
     uint8_t *bitstream_buffer;
@@ -62,6 +61,6 @@
 extern const uint8_t ff_asv_ac_ccp_tab[16][2];
 extern const uint8_t ff_asv2_level_tab[63][2];
 
-av_cold void ff_asv_common_init(AVCodecContext *avctx);
+void ff_asv_common_init(AVCodecContext *avctx);
 
 #endif /* AVCODEC_ASV_H */
diff --git a/libavcodec/asvdec.c b/libavcodec/asvdec.c
index b9686a2..e7a04cd 100644
--- a/libavcodec/asvdec.c
+++ b/libavcodec/asvdec.c
@@ -29,7 +29,7 @@
 #include "asv.h"
 #include "avcodec.h"
 #include "put_bits.h"
-#include "dsputil.h"
+#include "internal.h"
 #include "mathops.h"
 #include "mpeg12data.h"
 
@@ -42,124 +42,148 @@
 static VLC ac_ccp_vlc;
 static VLC asv2_level_vlc;
 
-static av_cold void init_vlcs(ASV1Context *a){
+static av_cold void init_vlcs(ASV1Context *a)
+{
     static int done = 0;
 
     if (!done) {
         done = 1;
 
         INIT_VLC_STATIC(&ccp_vlc, VLC_BITS, 17,
-                 &ff_asv_ccp_tab[0][1], 2, 1,
-                 &ff_asv_ccp_tab[0][0], 2, 1, 64);
+                        &ff_asv_ccp_tab[0][1], 2, 1,
+                        &ff_asv_ccp_tab[0][0], 2, 1, 64);
         INIT_VLC_STATIC(&dc_ccp_vlc, VLC_BITS, 8,
-                 &ff_asv_dc_ccp_tab[0][1], 2, 1,
-                 &ff_asv_dc_ccp_tab[0][0], 2, 1, 64);
+                        &ff_asv_dc_ccp_tab[0][1], 2, 1,
+                        &ff_asv_dc_ccp_tab[0][0], 2, 1, 64);
         INIT_VLC_STATIC(&ac_ccp_vlc, VLC_BITS, 16,
-                 &ff_asv_ac_ccp_tab[0][1], 2, 1,
-                 &ff_asv_ac_ccp_tab[0][0], 2, 1, 64);
+                        &ff_asv_ac_ccp_tab[0][1], 2, 1,
+                        &ff_asv_ac_ccp_tab[0][0], 2, 1, 64);
         INIT_VLC_STATIC(&level_vlc,  VLC_BITS, 7,
-                 &ff_asv_level_tab[0][1], 2, 1,
-                 &ff_asv_level_tab[0][0], 2, 1, 64);
+                        &ff_asv_level_tab[0][1], 2, 1,
+                        &ff_asv_level_tab[0][0], 2, 1, 64);
         INIT_VLC_STATIC(&asv2_level_vlc, ASV2_LEVEL_VLC_BITS, 63,
-                 &ff_asv2_level_tab[0][1], 2, 1,
-                 &ff_asv2_level_tab[0][0], 2, 1, 1024);
+                        &ff_asv2_level_tab[0][1], 2, 1,
+                        &ff_asv2_level_tab[0][0], 2, 1, 1024);
     }
 }
 
 //FIXME write a reversed bitstream reader to avoid the double reverse
-static inline int asv2_get_bits(GetBitContext *gb, int n){
-    return ff_reverse[ get_bits(gb, n) << (8-n) ];
+static inline int asv2_get_bits(GetBitContext *gb, int n)
+{
+    return ff_reverse[get_bits(gb, n) << (8-n)];
 }
 
-static inline int asv1_get_level(GetBitContext *gb){
-    int code= get_vlc2(gb, level_vlc.table, VLC_BITS, 1);
+static inline int asv1_get_level(GetBitContext *gb)
+{
+    int code = get_vlc2(gb, level_vlc.table, VLC_BITS, 1);
 
-    if(code==3) return get_sbits(gb, 8);
-    else        return code - 3;
+    if (code == 3)
+        return get_sbits(gb, 8);
+    else
+        return code - 3;
 }
 
-static inline int asv2_get_level(GetBitContext *gb){
-    int code= get_vlc2(gb, asv2_level_vlc.table, ASV2_LEVEL_VLC_BITS, 1);
+static inline int asv2_get_level(GetBitContext *gb)
+{
+    int code = get_vlc2(gb, asv2_level_vlc.table, ASV2_LEVEL_VLC_BITS, 1);
 
-    if(code==31) return (int8_t)asv2_get_bits(gb, 8);
-    else         return code - 31;
+    if (code == 31)
+        return (int8_t)asv2_get_bits(gb, 8);
+    else
+        return code - 31;
 }
 
-static inline int asv1_decode_block(ASV1Context *a, DCTELEM block[64]){
+static inline int asv1_decode_block(ASV1Context *a, int16_t block[64])
+{
     int i;
 
-    block[0]= 8*get_bits(&a->gb, 8);
+    block[0] = 8 * get_bits(&a->gb, 8);
 
-    for(i=0; i<11; i++){
-        const int ccp= get_vlc2(&a->gb, ccp_vlc.table, VLC_BITS, 1);
+    for (i = 0; i < 11; i++) {
+        const int ccp = get_vlc2(&a->gb, ccp_vlc.table, VLC_BITS, 1);
 
-        if(ccp){
-            if(ccp == 16) break;
-            if(ccp < 0 || i>=10){
+        if (ccp) {
+            if (ccp == 16)
+                break;
+            if (ccp < 0 || i >= 10) {
                 av_log(a->avctx, AV_LOG_ERROR, "coded coeff pattern damaged\n");
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
 
-            if(ccp&8) block[a->scantable.permutated[4*i+0]]= (asv1_get_level(&a->gb) * a->intra_matrix[4*i+0])>>4;
-            if(ccp&4) block[a->scantable.permutated[4*i+1]]= (asv1_get_level(&a->gb) * a->intra_matrix[4*i+1])>>4;
-            if(ccp&2) block[a->scantable.permutated[4*i+2]]= (asv1_get_level(&a->gb) * a->intra_matrix[4*i+2])>>4;
-            if(ccp&1) block[a->scantable.permutated[4*i+3]]= (asv1_get_level(&a->gb) * a->intra_matrix[4*i+3])>>4;
+            if (ccp & 8)
+                block[a->scantable.permutated[4 * i + 0]] = (asv1_get_level(&a->gb) * a->intra_matrix[4 * i + 0]) >> 4;
+            if (ccp & 4)
+                block[a->scantable.permutated[4 * i + 1]] = (asv1_get_level(&a->gb) * a->intra_matrix[4 * i + 1]) >> 4;
+            if (ccp & 2)
+                block[a->scantable.permutated[4 * i + 2]] = (asv1_get_level(&a->gb) * a->intra_matrix[4 * i + 2]) >> 4;
+            if (ccp & 1)
+                block[a->scantable.permutated[4 * i + 3]] = (asv1_get_level(&a->gb) * a->intra_matrix[4 * i + 3]) >> 4;
         }
     }
 
     return 0;
 }
 
-static inline int asv2_decode_block(ASV1Context *a, DCTELEM block[64]){
+static inline int asv2_decode_block(ASV1Context *a, int16_t block[64])
+{
     int i, count, ccp;
 
-    count= asv2_get_bits(&a->gb, 4);
+    count = asv2_get_bits(&a->gb, 4);
 
-    block[0]= 8*asv2_get_bits(&a->gb, 8);
+    block[0] = 8 * asv2_get_bits(&a->gb, 8);
 
-    ccp= get_vlc2(&a->gb, dc_ccp_vlc.table, VLC_BITS, 1);
-    if(ccp){
-        if(ccp&4) block[a->scantable.permutated[1]]= (asv2_get_level(&a->gb) * a->intra_matrix[1])>>4;
-        if(ccp&2) block[a->scantable.permutated[2]]= (asv2_get_level(&a->gb) * a->intra_matrix[2])>>4;
-        if(ccp&1) block[a->scantable.permutated[3]]= (asv2_get_level(&a->gb) * a->intra_matrix[3])>>4;
+    ccp = get_vlc2(&a->gb, dc_ccp_vlc.table, VLC_BITS, 1);
+    if (ccp) {
+        if (ccp & 4)
+            block[a->scantable.permutated[1]] = (asv2_get_level(&a->gb) * a->intra_matrix[1]) >> 4;
+        if (ccp & 2)
+            block[a->scantable.permutated[2]] = (asv2_get_level(&a->gb) * a->intra_matrix[2]) >> 4;
+        if (ccp & 1)
+            block[a->scantable.permutated[3]] = (asv2_get_level(&a->gb) * a->intra_matrix[3]) >> 4;
     }
 
-    for(i=1; i<count+1; i++){
-        const int ccp= get_vlc2(&a->gb, ac_ccp_vlc.table, VLC_BITS, 1);
+    for (i = 1; i < count + 1; i++) {
+        const int ccp = get_vlc2(&a->gb, ac_ccp_vlc.table, VLC_BITS, 1);
 
-        if(ccp){
-            if(ccp&8) block[a->scantable.permutated[4*i+0]]= (asv2_get_level(&a->gb) * a->intra_matrix[4*i+0])>>4;
-            if(ccp&4) block[a->scantable.permutated[4*i+1]]= (asv2_get_level(&a->gb) * a->intra_matrix[4*i+1])>>4;
-            if(ccp&2) block[a->scantable.permutated[4*i+2]]= (asv2_get_level(&a->gb) * a->intra_matrix[4*i+2])>>4;
-            if(ccp&1) block[a->scantable.permutated[4*i+3]]= (asv2_get_level(&a->gb) * a->intra_matrix[4*i+3])>>4;
+        if (ccp) {
+            if (ccp & 8)
+                block[a->scantable.permutated[4*i + 0]] = (asv2_get_level(&a->gb) * a->intra_matrix[4*i + 0]) >> 4;
+            if (ccp & 4)
+                block[a->scantable.permutated[4*i + 1]] = (asv2_get_level(&a->gb) * a->intra_matrix[4*i + 1]) >> 4;
+            if (ccp & 2)
+                block[a->scantable.permutated[4*i + 2]] = (asv2_get_level(&a->gb) * a->intra_matrix[4*i + 2]) >> 4;
+            if (ccp & 1)
+                block[a->scantable.permutated[4*i + 3]] = (asv2_get_level(&a->gb) * a->intra_matrix[4*i + 3]) >> 4;
         }
     }
 
     return 0;
 }
 
-static inline int decode_mb(ASV1Context *a, DCTELEM block[6][64]){
+static inline int decode_mb(ASV1Context *a, int16_t block[6][64])
+{
     int i;
 
     a->dsp.clear_blocks(block[0]);
 
-    if(a->avctx->codec_id == AV_CODEC_ID_ASV1){
-        for(i=0; i<6; i++){
-            if( asv1_decode_block(a, block[i]) < 0)
+    if (a->avctx->codec_id == AV_CODEC_ID_ASV1) {
+        for (i = 0; i < 6; i++) {
+            if (asv1_decode_block(a, block[i]) < 0)
                 return -1;
         }
-    }else{
-        for(i=0; i<6; i++){
-            if( asv2_decode_block(a, block[i]) < 0)
+    } else {
+        for (i = 0; i < 6; i++) {
+            if (asv2_decode_block(a, block[i]) < 0)
                 return -1;
         }
     }
     return 0;
 }
 
-static inline void idct_put(ASV1Context *a, int mb_x, int mb_y){
-    DCTELEM (*block)[64]= a->block;
-    int linesize= a->picture.linesize[0];
+static inline void idct_put(ASV1Context *a, int mb_x, int mb_y)
+{
+    int16_t (*block)[64] = a->block;
+    int linesize         = a->picture.linesize[0];
 
     uint8_t *dest_y  = a->picture.data[0] + (mb_y * 16* linesize              ) + mb_x * 16;
     uint8_t *dest_cb = a->picture.data[1] + (mb_y * 8 * a->picture.linesize[1]) + mb_x * 8;
@@ -170,127 +194,129 @@
     a->dsp.idct_put(dest_y + 8*linesize    , linesize, block[2]);
     a->dsp.idct_put(dest_y + 8*linesize + 8, linesize, block[3]);
 
-    if(!(a->avctx->flags&CODEC_FLAG_GRAY)){
+    if (!(a->avctx->flags&CODEC_FLAG_GRAY)) {
         a->dsp.idct_put(dest_cb, a->picture.linesize[1], block[4]);
         a->dsp.idct_put(dest_cr, a->picture.linesize[2], block[5]);
     }
 }
 
 static int decode_frame(AVCodecContext *avctx,
-                        void *data, int *data_size,
+                        void *data, int *got_frame,
                         AVPacket *avpkt)
 {
-    const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
     ASV1Context * const a = avctx->priv_data;
-    AVFrame *picture = data;
-    AVFrame * const p= &a->picture;
-    int mb_x, mb_y;
+    const uint8_t *buf    = avpkt->data;
+    int buf_size          = avpkt->size;
+    AVFrame *picture      = data;
+    AVFrame * const p     = &a->picture;
+    int mb_x, mb_y, ret;
 
-    if(p->data[0])
+    if (p->data[0])
         avctx->release_buffer(avctx, p);
 
-    p->reference= 0;
-    if(avctx->get_buffer(avctx, p) < 0){
+    p->reference = 0;
+    if ((ret = ff_get_buffer(avctx, p)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
-    p->pict_type= AV_PICTURE_TYPE_I;
-    p->key_frame= 1;
+    p->pict_type = AV_PICTURE_TYPE_I;
+    p->key_frame = 1;
 
     av_fast_padded_malloc(&a->bitstream_buffer, &a->bitstream_buffer_size,
                           buf_size);
     if (!a->bitstream_buffer)
         return AVERROR(ENOMEM);
 
-    if(avctx->codec_id == AV_CODEC_ID_ASV1)
+    if (avctx->codec_id == AV_CODEC_ID_ASV1)
         a->dsp.bswap_buf((uint32_t*)a->bitstream_buffer, (const uint32_t*)buf, buf_size/4);
-    else{
+    else {
         int i;
-        for(i=0; i<buf_size; i++)
-            a->bitstream_buffer[i]= ff_reverse[ buf[i] ];
+        for (i = 0; i < buf_size; i++)
+            a->bitstream_buffer[i] = ff_reverse[buf[i]];
     }
 
     init_get_bits(&a->gb, a->bitstream_buffer, buf_size*8);
 
-    for(mb_y=0; mb_y<a->mb_height2; mb_y++){
-        for(mb_x=0; mb_x<a->mb_width2; mb_x++){
-            if( decode_mb(a, a->block) <0)
-                return -1;
+    for (mb_y = 0; mb_y < a->mb_height2; mb_y++) {
+        for (mb_x = 0; mb_x < a->mb_width2; mb_x++) {
+            if ((ret = decode_mb(a, a->block)) < 0)
+                return ret;
 
             idct_put(a, mb_x, mb_y);
         }
     }
 
-    if(a->mb_width2 != a->mb_width){
-        mb_x= a->mb_width2;
-        for(mb_y=0; mb_y<a->mb_height2; mb_y++){
-            if( decode_mb(a, a->block) <0)
-                return -1;
+    if (a->mb_width2 != a->mb_width) {
+        mb_x = a->mb_width2;
+        for (mb_y = 0; mb_y < a->mb_height2; mb_y++) {
+            if ((ret = decode_mb(a, a->block)) < 0)
+                return ret;
 
             idct_put(a, mb_x, mb_y);
         }
     }
 
-    if(a->mb_height2 != a->mb_height){
-        mb_y= a->mb_height2;
-        for(mb_x=0; mb_x<a->mb_width; mb_x++){
-            if( decode_mb(a, a->block) <0)
-                return -1;
+    if (a->mb_height2 != a->mb_height) {
+        mb_y = a->mb_height2;
+        for (mb_x = 0; mb_x < a->mb_width; mb_x++) {
+            if ((ret = decode_mb(a, a->block)) < 0)
+                return ret;
 
             idct_put(a, mb_x, mb_y);
         }
     }
 
     *picture   = a->picture;
-    *data_size = sizeof(AVPicture);
+    *got_frame = 1;
 
     emms_c();
 
-    return (get_bits_count(&a->gb)+31)/32*4;
+    return (get_bits_count(&a->gb) + 31) / 32 * 4;
 }
 
-static av_cold int decode_init(AVCodecContext *avctx){
+static av_cold int decode_init(AVCodecContext *avctx)
+{
     ASV1Context * const a = avctx->priv_data;
-    AVFrame *p= &a->picture;
+    AVFrame *p            = &a->picture;
+    const int scale       = avctx->codec_id == AV_CODEC_ID_ASV1 ? 1 : 2;
     int i;
-    const int scale= avctx->codec_id == AV_CODEC_ID_ASV1 ? 1 : 2;
 
     ff_asv_common_init(avctx);
     init_vlcs(a);
     ff_init_scantable(a->dsp.idct_permutation, &a->scantable, ff_asv_scantab);
-    avctx->pix_fmt= AV_PIX_FMT_YUV420P;
+    avctx->pix_fmt = AV_PIX_FMT_YUV420P;
 
-    if(avctx->extradata_size < 1 || (a->inv_qscale= avctx->extradata[0]) == 0){
+    if (avctx->extradata_size < 1 || (a->inv_qscale = avctx->extradata[0]) == 0) {
         av_log(avctx, AV_LOG_ERROR, "illegal qscale 0\n");
-        if(avctx->codec_id == AV_CODEC_ID_ASV1)
-            a->inv_qscale= 6;
+        if (avctx->codec_id == AV_CODEC_ID_ASV1)
+            a->inv_qscale = 6;
         else
-            a->inv_qscale= 10;
+            a->inv_qscale = 10;
     }
 
-    for(i=0; i<64; i++){
+    for (i = 0; i < 64; i++) {
         int index = ff_asv_scantab[i];
 
-        a->intra_matrix[i]= 64*scale*ff_mpeg1_default_intra_matrix[index] / a->inv_qscale;
+        a->intra_matrix[i] = 64 * scale * ff_mpeg1_default_intra_matrix[index] / a->inv_qscale;
     }
 
-    p->qstride= a->mb_width;
-    p->qscale_table= av_malloc( p->qstride * a->mb_height);
-    p->quality= (32*scale + a->inv_qscale/2)/a->inv_qscale;
-    memset(p->qscale_table, p->quality, p->qstride*a->mb_height);
+    p->qstride      = a->mb_width;
+    p->qscale_table = av_malloc(p->qstride * a->mb_height);
+    p->quality      = (32 * scale + a->inv_qscale / 2) / a->inv_qscale;
+    memset(p->qscale_table, p->quality, p->qstride * a->mb_height);
 
     return 0;
 }
 
-static av_cold int decode_end(AVCodecContext *avctx){
+static av_cold int decode_end(AVCodecContext *avctx)
+{
     ASV1Context * const a = avctx->priv_data;
 
     av_freep(&a->bitstream_buffer);
     av_freep(&a->picture.qscale_table);
-    a->bitstream_buffer_size=0;
+    a->bitstream_buffer_size = 0;
 
-    if(a->picture.data[0])
+    if (a->picture.data[0])
         avctx->release_buffer(avctx, &a->picture);
 
     return 0;
diff --git a/libavcodec/asvenc.c b/libavcodec/asvenc.c
index 259cd68..a09aa73 100644
--- a/libavcodec/asvenc.c
+++ b/libavcodec/asvenc.c
@@ -56,7 +56,7 @@
     }
 }
 
-static inline void asv1_encode_block(ASV1Context *a, DCTELEM block[64]){
+static inline void asv1_encode_block(ASV1Context *a, int16_t block[64]){
     int i;
     int nc_count=0;
 
@@ -89,7 +89,7 @@
     put_bits(&a->pb, ff_asv_ccp_tab[16][1], ff_asv_ccp_tab[16][0]);
 }
 
-static inline void asv2_encode_block(ASV1Context *a, DCTELEM block[64]){
+static inline void asv2_encode_block(ASV1Context *a, int16_t block[64]){
     int i;
     int count=0;
 
@@ -130,7 +130,7 @@
 
 #define MAX_MB_SIZE (30*16*16*3/2/8)
 
-static inline int encode_mb(ASV1Context *a, DCTELEM block[6][64]){
+static inline int encode_mb(ASV1Context *a, int16_t block[6][64]){
     int i;
 
     if (a->pb.buf_end - a->pb.buf - (put_bits_count(&a->pb)>>3) < MAX_MB_SIZE) {
@@ -149,7 +149,7 @@
 }
 
 static inline void dct_get(ASV1Context *a, int mb_x, int mb_y){
-    DCTELEM (*block)[64]= a->block;
+    int16_t (*block)[64]= a->block;
     int linesize= a->picture.linesize[0];
     int i;
 
@@ -267,7 +267,8 @@
     .priv_data_size = sizeof(ASV1Context),
     .init           = encode_init,
     .encode2        = encode_frame,
-    .pix_fmts       = (const enum PixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
+    .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P,
+                                                    AV_PIX_FMT_NONE },
     .long_name      = NULL_IF_CONFIG_SMALL("ASUS V1"),
 };
 #endif
@@ -280,7 +281,8 @@
     .priv_data_size = sizeof(ASV1Context),
     .init           = encode_init,
     .encode2        = encode_frame,
-    .pix_fmts       = (const enum PixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
+    .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P,
+                                                    AV_PIX_FMT_NONE },
     .long_name      = NULL_IF_CONFIG_SMALL("ASUS V2"),
 };
 #endif
diff --git a/libavcodec/atrac.c b/libavcodec/atrac.c
index cb2f7ba..ea342a0 100644
--- a/libavcodec/atrac.c
+++ b/libavcodec/atrac.c
@@ -30,7 +30,6 @@
 #include <string.h>
 
 #include "avcodec.h"
-#include "dsputil.h"
 #include "atrac.h"
 
 float ff_atrac_sf_table[64];
diff --git a/libavcodec/atrac1.c b/libavcodec/atrac1.c
index 1ba5593..72c1b50 100644
--- a/libavcodec/atrac1.c
+++ b/libavcodec/atrac1.c
@@ -32,10 +32,11 @@
 #include <stddef.h>
 #include <stdio.h>
 
+#include "libavutil/float_dsp.h"
 #include "avcodec.h"
 #include "get_bits.h"
-#include "dsputil.h"
 #include "fft.h"
+#include "internal.h"
 #include "sinewin.h"
 
 #include "atrac.h"
@@ -71,7 +72,6 @@
  * The atrac1 context, holds all needed parameters for decoding
  */
 typedef struct {
-    AVFrame frame;
     AT1SUCtx            SUs[AT1_MAX_CHANNELS];              ///< channel sound unit
     DECLARE_ALIGNED(32, float, spec)[AT1_SU_SAMPLES];      ///< the mdct spectrum buffer
 
@@ -80,7 +80,7 @@
     DECLARE_ALIGNED(32, float, high)[512];
     float*              bands[3];
     FFTContext          mdct_ctx[3];
-    DSPContext          dsp;
+    AVFloatDSPContext   fdsp;
 } AT1Ctx;
 
 /** size of the transform in samples in the long mode for each QMF band */
@@ -140,8 +140,8 @@
             at1_imdct(q, &q->spec[pos], &su->spectrum[0][ref_pos + start_pos], nbits, band_num);
 
             /* overlap and window */
-            q->dsp.vector_fmul_window(&q->bands[band_num][start_pos], prev_buf,
-                                      &su->spectrum[0][ref_pos + start_pos], ff_sine_32, 16);
+            q->fdsp.vector_fmul_window(&q->bands[band_num][start_pos], prev_buf,
+                                       &su->spectrum[0][ref_pos + start_pos], ff_sine_32, 16);
 
             prev_buf = &su->spectrum[0][ref_pos+start_pos + 16];
             start_pos += block_size;
@@ -272,6 +272,7 @@
 static int atrac1_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;
     AT1Ctx *q          = avctx->priv_data;
@@ -285,8 +286,8 @@
     }
 
     /* get output buffer */
-    q->frame.nb_samples = AT1_SU_SAMPLES;
-    if ((ret = avctx->get_buffer(avctx, &q->frame)) < 0) {
+    frame->nb_samples = AT1_SU_SAMPLES;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -308,11 +309,10 @@
         ret = at1_imdct_block(su, q);
         if (ret < 0)
             return ret;
-        at1_subband_synthesis(q, su, (float *)q->frame.extended_data[ch]);
+        at1_subband_synthesis(q, su, (float *)frame->extended_data[ch]);
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = q->frame;
+    *got_frame_ptr = 1;
 
     return avctx->block_align;
 }
@@ -361,7 +361,7 @@
 
     ff_atrac_generate_tables();
 
-    ff_dsputil_init(&q->dsp, avctx);
+    avpriv_float_dsp_init(&q->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
 
     q->bands[0] = q->low;
     q->bands[1] = q->mid;
@@ -373,9 +373,6 @@
     q->SUs[1].spectrum[0] = q->SUs[1].spec1;
     q->SUs[1].spectrum[1] = q->SUs[1].spec2;
 
-    avcodec_get_frame_defaults(&q->frame);
-    avctx->coded_frame = &q->frame;
-
     return 0;
 }
 
diff --git a/libavcodec/atrac3.c b/libavcodec/atrac3.c
index 052bef0..6216536 100644
--- a/libavcodec/atrac3.c
+++ b/libavcodec/atrac3.c
@@ -43,6 +43,7 @@
 #include "fft.h"
 #include "fmtconvert.h"
 #include "get_bits.h"
+#include "internal.h"
 
 #include "atrac.h"
 #include "atrac3data.h"
@@ -86,7 +87,6 @@
 } ChannelUnit;
 
 typedef struct ATRAC3Context {
-    AVFrame frame;
     GetBitContext gb;
     //@{
     /** stream data */
@@ -517,7 +517,7 @@
         output   = &spectrum[components[i].pos];
 
         for (j = 0; j < components[i].num_coefs; j++)
-            output[i] += input[i];
+            output[j] += input[j];
     }
 
     return last_pos;
@@ -739,7 +739,7 @@
 
 
         /* set the bitstream reader at the start of the second Sound Unit*/
-        init_get_bits(&q->gb, ptr1, avctx->block_align * 8);
+        init_get_bits8(&q->gb, ptr1, q->decoded_bytes_buffer + avctx->block_align - ptr1);
 
         /* Fill the Weighting coeffs delay buffer */
         memmove(q->weighting_delay, &q->weighting_delay[2],
@@ -798,6 +798,7 @@
 static int atrac3_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;
     ATRAC3Context *q = avctx->priv_data;
@@ -811,8 +812,8 @@
     }
 
     /* get output buffer */
-    q->frame.nb_samples = SAMPLES_PER_FRAME;
-    if ((ret = avctx->get_buffer(avctx, &q->frame)) < 0) {
+    frame->nb_samples = SAMPLES_PER_FRAME;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -825,14 +826,13 @@
         databuf = buf;
     }
 
-    ret = decode_frame(avctx, databuf, (float **)q->frame.extended_data);
+    ret = decode_frame(avctx, databuf, (float **)frame->extended_data);
     if (ret) {
         av_log(NULL, AV_LOG_ERROR, "Frame decoding error!\n");
         return ret;
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = q->frame;
+    *got_frame_ptr = 1;
 
     return avctx->block_align;
 }
@@ -907,7 +907,7 @@
                    avctx->channels, frame_factor);
             return AVERROR_INVALIDDATA;
         }
-    } else if (avctx->extradata_size == 10) {
+    } else if (avctx->extradata_size == 12 || avctx->extradata_size == 10) {
         /* Parse the extradata, RM format. */
         version                = bytestream_get_be32(&edata_ptr);
         samples_per_frame      = bytestream_get_be16(&edata_ptr);
@@ -996,9 +996,6 @@
         return AVERROR(ENOMEM);
     }
 
-    avcodec_get_frame_defaults(&q->frame);
-    avctx->coded_frame = &q->frame;
-
     return 0;
 }
 
diff --git a/libavcodec/audio_frame_queue.c b/libavcodec/audio_frame_queue.c
index 7db0091..ba6e225 100644
--- a/libavcodec/audio_frame_queue.c
+++ b/libavcodec/audio_frame_queue.c
@@ -35,7 +35,7 @@
 void ff_af_queue_close(AudioFrameQueue *afq)
 {
     if(afq->frame_count)
-        av_log(afq->avctx, AV_LOG_WARNING, "%d frames left in que on closing\n", afq->frame_count);
+        av_log(afq->avctx, AV_LOG_WARNING, "%d frames left in the queue on closing\n", afq->frame_count);
     av_freep(&afq->frames);
     memset(afq, 0, sizeof(*afq));
 }
@@ -57,7 +57,7 @@
                                       (AVRational){ 1, afq->avctx->sample_rate });
         new->pts -= afq->remaining_delay;
         if(afq->frame_count && new[-1].pts >= new->pts)
-            av_log(afq->avctx, AV_LOG_WARNING, "Que input is backward in time\n");
+            av_log(afq->avctx, AV_LOG_WARNING, "Queue input is backward in time\n");
     } else {
         new->pts = AV_NOPTS_VALUE;
     }
@@ -83,7 +83,7 @@
             out_pts = afq->frames->pts;
     }
     if(!afq->frame_count)
-        av_log(afq->avctx, AV_LOG_WARNING, "Trying to remove %d samples, but que empty\n", nb_samples);
+        av_log(afq->avctx, AV_LOG_WARNING, "Trying to remove %d samples, but the queue is empty\n", nb_samples);
     if (pts)
         *pts = ff_samples_to_time_base(afq->avctx, out_pts);
 
@@ -105,7 +105,7 @@
         av_assert0(afq->remaining_samples == afq->remaining_delay);
         if(afq->frames && afq->frames[0].pts != AV_NOPTS_VALUE)
             afq->frames[0].pts += nb_samples;
-        av_log(afq->avctx, AV_LOG_DEBUG, "Trying to remove %d more samples than are in the que\n", nb_samples);
+        av_log(afq->avctx, AV_LOG_DEBUG, "Trying to remove %d more samples than there are in the queue\n", nb_samples);
     }
     if (duration)
         *duration = ff_samples_to_time_base(afq->avctx, removed_samples);
diff --git a/libavcodec/aura.c b/libavcodec/aura.c
index 669ef48..c591f2f 100644
--- a/libavcodec/aura.c
+++ b/libavcodec/aura.c
@@ -24,6 +24,7 @@
  */
 
 #include "avcodec.h"
+#include "internal.h"
 #include "libavutil/internal.h"
 
 typedef struct AuraDecodeContext {
@@ -38,7 +39,7 @@
     s->avctx = avctx;
     /* width needs to be divisible by 4 for this codec to work */
     if (avctx->width & 0x3)
-        return -1;
+        return AVERROR(EINVAL);
     avctx->pix_fmt = AV_PIX_FMT_YUV422P;
     avcodec_get_frame_defaults(&s->frame);
 
@@ -46,14 +47,13 @@
 }
 
 static int aura_decode_frame(AVCodecContext *avctx,
-                             void *data, int *data_size,
+                             void *data, int *got_frame,
                              AVPacket *pkt)
 {
-    AuraDecodeContext *s=avctx->priv_data;
-
+    AuraDecodeContext *s = avctx->priv_data;
     uint8_t *Y, *U, *V;
     uint8_t val;
-    int x, y;
+    int x, y, ret;
     const uint8_t *buf = pkt->data;
 
     /* prediction error tables (make it clear that they are signed values) */
@@ -62,20 +62,20 @@
     if (pkt->size != 48 + avctx->height * avctx->width) {
         av_log(avctx, AV_LOG_ERROR, "got a buffer with %d bytes when %d were expected\n",
                pkt->size, 48 + avctx->height * avctx->width);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     /* pixel data starts 48 bytes in, after 3x16-byte tables */
     buf += 48;
 
-    if(s->frame.data[0])
+    if (s->frame.data[0])
         avctx->release_buffer(avctx, &s->frame);
 
     s->frame.buffer_hints = FF_BUFFER_HINTS_VALID;
     s->frame.reference = 0;
-    if(avctx->get_buffer(avctx, &s->frame) < 0) {
+    if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     Y = s->frame.data[0];
@@ -85,31 +85,31 @@
     /* iterate through each line in the height */
     for (y = 0; y < avctx->height; y++) {
         /* reset predictors */
-        val = *buf++;
+        val  = *buf++;
         U[0] = val & 0xF0;
         Y[0] = val << 4;
-        val = *buf++;
+        val  = *buf++;
         V[0] = val & 0xF0;
         Y[1] = Y[0] + delta_table[val & 0xF];
-        Y += 2; U++; V++;
+        Y   += 2; U++; V++;
 
         /* iterate through the remaining pixel groups (4 pixels/group) */
         for (x = 1; x < (avctx->width >> 1); x++) {
-            val = *buf++;
+            val  = *buf++;
             U[0] = U[-1] + delta_table[val >> 4];
             Y[0] = Y[-1] + delta_table[val & 0xF];
-            val = *buf++;
+            val  = *buf++;
             V[0] = V[-1] + delta_table[val >> 4];
             Y[1] = Y[ 0] + delta_table[val & 0xF];
-            Y += 2; U++; V++;
+            Y   += 2; U++; V++;
         }
         Y += s->frame.linesize[0] -  avctx->width;
         U += s->frame.linesize[1] - (avctx->width >> 1);
         V += s->frame.linesize[2] - (avctx->width >> 1);
     }
 
-    *data_size=sizeof(AVFrame);
-    *(AVFrame*)data= s->frame;
+    *got_frame = 1;
+    *(AVFrame*)data = s->frame;
 
     return pkt->size;
 }
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index aa06348..f809e3d 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -274,6 +274,7 @@
     AV_CODEC_ID_EXR        = MKBETAG('0','E','X','R'),
     AV_CODEC_ID_AVRP       = MKBETAG('A','V','R','P'),
 
+    AV_CODEC_ID_012V       = MKBETAG('0','1','2','V'),
     AV_CODEC_ID_G2M        = MKBETAG( 0 ,'G','2','M'),
     AV_CODEC_ID_AVUI       = MKBETAG('A','V','U','I'),
     AV_CODEC_ID_AYUV       = MKBETAG('A','Y','U','V'),
@@ -286,6 +287,9 @@
     AV_CODEC_ID_AVRN       = MKBETAG('A','V','R','n'),
     AV_CODEC_ID_CPIA       = MKBETAG('C','P','I','A'),
     AV_CODEC_ID_XFACE      = MKBETAG('X','F','A','C'),
+    AV_CODEC_ID_SGIRLE     = MKBETAG('S','G','I','R'),
+    AV_CODEC_ID_MVC1       = MKBETAG('M','V','C','1'),
+    AV_CODEC_ID_MVC2       = MKBETAG('M','V','C','2'),
 
     /* various PCM "codecs" */
     AV_CODEC_ID_FIRST_AUDIO = 0x10000,     ///< A dummy id pointing at the start of audio codecs
@@ -434,13 +438,18 @@
     AV_CODEC_ID_ILBC,
     AV_CODEC_ID_OPUS_DEPRECATED,
     AV_CODEC_ID_COMFORT_NOISE,
+    AV_CODEC_ID_TAK_DEPRECATED,
     AV_CODEC_ID_FFWAVESYNTH = MKBETAG('F','F','W','S'),
+#if LIBAVCODEC_VERSION_MAJOR <= 54
     AV_CODEC_ID_8SVX_RAW    = MKBETAG('8','S','V','X'),
+#endif
     AV_CODEC_ID_SONIC       = MKBETAG('S','O','N','C'),
     AV_CODEC_ID_SONIC_LS    = MKBETAG('S','O','N','L'),
     AV_CODEC_ID_PAF_AUDIO   = MKBETAG('P','A','F','A'),
     AV_CODEC_ID_OPUS        = MKBETAG('O','P','U','S'),
     AV_CODEC_ID_TAK         = MKBETAG('t','B','a','K'),
+    AV_CODEC_ID_EVRC        = MKBETAG('s','e','v','c'),
+    AV_CODEC_ID_SMV         = MKBETAG('s','s','m','v'),
 
     /* subtitle codecs */
     AV_CODEC_ID_FIRST_SUBTITLE = 0x17000,          ///< A dummy ID pointing at the start of subtitle codecs.
@@ -458,9 +467,13 @@
     AV_CODEC_ID_JACOSUB    = MKBETAG('J','S','U','B'),
     AV_CODEC_ID_SAMI       = MKBETAG('S','A','M','I'),
     AV_CODEC_ID_REALTEXT   = MKBETAG('R','T','X','T'),
+    AV_CODEC_ID_SUBVIEWER1 = MKBETAG('S','b','V','1'),
     AV_CODEC_ID_SUBVIEWER  = MKBETAG('S','u','b','V'),
     AV_CODEC_ID_SUBRIP     = MKBETAG('S','R','i','p'),
     AV_CODEC_ID_WEBVTT     = MKBETAG('W','V','T','T'),
+    AV_CODEC_ID_MPL2       = MKBETAG('M','P','L','2'),
+    AV_CODEC_ID_VPLAYER    = MKBETAG('V','P','l','r'),
+    AV_CODEC_ID_PJS        = MKBETAG('P','h','J','S'),
 
     /* other specific kind of codecs (generally used for attachments) */
     AV_CODEC_ID_FIRST_UNKNOWN = 0x18000,           ///< A dummy ID pointing at the start of various fake codecs.
@@ -469,6 +482,7 @@
     AV_CODEC_ID_XBIN       = MKBETAG('X','B','I','N'),
     AV_CODEC_ID_IDF        = MKBETAG( 0 ,'I','D','F'),
     AV_CODEC_ID_OTF        = MKBETAG( 0 ,'O','T','F'),
+    AV_CODEC_ID_SMPTE_KLV  = MKBETAG('K','L','V','A'),
 
     AV_CODEC_ID_PROBE = 0x19000, ///< codec_id is not known (like AV_CODEC_ID_NONE) but lavf should attempt to identify it
 
@@ -526,6 +540,10 @@
  * Codec supports lossless compression. Audio and video codecs only.
  */
 #define AV_CODEC_PROP_LOSSLESS      (1 << 2)
+/**
+ * Subtitle codec is bitmap based
+ */
+#define AV_CODEC_PROP_BITMAP_SUB    (1 << 16)
 
 #if FF_API_OLD_DECODE_AUDIO
 /* in bytes */
@@ -699,6 +717,8 @@
 #define CODEC_FLAG2_NO_OUTPUT     0x00000004 ///< Skip bitstream encoding.
 #define CODEC_FLAG2_LOCAL_HEADER  0x00000008 ///< Place global headers at every keyframe instead of in extradata.
 #define CODEC_FLAG2_DROP_FRAME_TIMECODE 0x00002000 ///< timecode is in drop frame format. DEPRECATED!!!!
+#define CODEC_FLAG2_IGNORE_CROP   0x00010000 ///< Discard cropping information from SPS.
+
 #if FF_API_MPV_GLOBAL_OPTS
 #define CODEC_FLAG_CBP_RD         0x04000000 ///< Use rate distortion optimization for cbp.
 #define CODEC_FLAG_QP_RD          0x08000000 ///< Use rate distortion optimization for qp selectioon.
@@ -967,6 +987,14 @@
      * @endcode
      */
     AV_PKT_DATA_SUBTITLE_POSITION,
+
+    /**
+     * Data found in BlockAdditional element of matroska container. There is
+     * no end marker for the data, so it is required to rely on the side data
+     * size to recognize the end. 8 byte id (as found in BlockAddId) followed
+     * by data.
+     */
+    AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL,
 };
 
 /**
@@ -1068,14 +1096,22 @@
  */
 
 /**
- * Audio Video Frame.
- * New fields can be added to the end of AVFRAME with minor version
- * bumps. Similarly fields that are marked as to be only accessed by
+ * This structure describes decoded (raw) audio or video data.
+ *
+ * AVFrame must be allocated using avcodec_alloc_frame() and freed with
+ * avcodec_free_frame(). Note that this allocates only the AVFrame itself. The
+ * buffers for the data must be managed through other means.
+ *
+ * AVFrame is typically allocated once and then reused multiple times to hold
+ * different data (e.g. a single AVFrame to hold frames received from a
+ * decoder). In such a case, avcodec_get_frame_defaults() should be used to
+ * reset the frame to its original clean state before it is reused again.
+ *
+ * sizeof(AVFrame) is not a part of the public ABI, so new fields may be added
+ * to the end with a minor bump.
+ * Similarly fields that are marked as to be only accessed by
  * av_opt_ptr() can be reordered. This allows 2 forks to add fields
  * without breaking compatibility with each other.
- * Removal, reordering and changes in the remaining cases require
- * a major version bump.
- * sizeof(AVFrame) must not be used outside libavcodec.
  */
 typedef struct AVFrame {
 #define AV_NUM_DATA_POINTERS 8
@@ -1179,14 +1215,14 @@
     int64_t pts;
 
     /**
-     * reordered pts from the last AVPacket that has been input into the decoder
+     * pts copied from the AVPacket that was decoded to produce this frame
      * - encoding: unused
      * - decoding: Read by user.
      */
     int64_t pkt_pts;
 
     /**
-     * dts from the last AVPacket that has been input into the decoder
+     * dts copied from the AVPacket that triggered returning this frame
      * - encoding: unused
      * - decoding: Read by user.
      */
@@ -1465,7 +1501,17 @@
      * - encoding: unused
      * - decoding: Read by user.
      */
-    int64_t channels;
+    int channels;
+
+    /**
+     * size of the corresponding packet containing the compressed
+     * frame. It must be accessed using av_frame_get_pkt_size() and
+     * av_frame_set_pkt_size().
+     * It is set to a negative value if unknown.
+     * - encoding: unused
+     * - decoding: set by libavcodec, read by user.
+     */
+    int pkt_size;
 } AVFrame;
 
 /**
@@ -1489,6 +1535,8 @@
 void          av_frame_set_metadata       (AVFrame *frame, AVDictionary *val);
 int     av_frame_get_decode_error_flags   (const AVFrame *frame);
 void    av_frame_set_decode_error_flags   (AVFrame *frame, int     val);
+int     av_frame_get_pkt_size(const AVFrame *frame);
+void    av_frame_set_pkt_size(AVFrame *frame, int val);
 
 struct AVCodecInternal;
 
@@ -2856,20 +2904,22 @@
 #define FF_IDCT_ALTIVEC       8
 #define FF_IDCT_SH4           9
 #define FF_IDCT_SIMPLEARM     10
-#define FF_IDCT_H264          11
-#define FF_IDCT_VP3           12
 #define FF_IDCT_IPP           13
 #define FF_IDCT_XVIDMMX       14
-#define FF_IDCT_CAVS          15
 #define FF_IDCT_SIMPLEARMV5TE 16
 #define FF_IDCT_SIMPLEARMV6   17
 #define FF_IDCT_SIMPLEVIS     18
-#define FF_IDCT_WMV2          19
 #define FF_IDCT_FAAN          20
-#define FF_IDCT_EA            21
 #define FF_IDCT_SIMPLENEON    22
 #define FF_IDCT_SIMPLEALPHA   23
+#if FF_API_IDCT
+#define FF_IDCT_H264          11
+#define FF_IDCT_VP3           12
+#define FF_IDCT_CAVS          15
+#define FF_IDCT_WMV2          19
+#define FF_IDCT_EA            21
 #define FF_IDCT_BINK          24
+#endif
 
 #if FF_API_DSP_MASK
     /**
@@ -3127,7 +3177,7 @@
     /**
      * Timebase in which pkt_dts/pts and AVPacket.dts/pts are.
      * Code outside libavcodec should access this field using:
-     * avcodec_set_pkt_timebase(avctx)
+     * av_codec_{get,set}_pkt_timebase(avctx)
      * - encoding unused.
      * - decodimg set by user
      */
@@ -3136,7 +3186,7 @@
     /**
      * AVCodecDescriptor
      * Code outside libavcodec should access this field using:
-     * avcodec_get_codec_descriptior(avctx)
+     * av_codec_{get,set}_codec_descriptor(avctx)
      * - encoding: unused.
      * - decoding: set by libavcodec.
      */
@@ -3158,6 +3208,24 @@
      * - encoding: unused
      */
     AVDictionary *metadata;
+
+    /**
+     * Character encoding of the input subtitles file.
+     * - decoding: set by user
+     * - encoding: unused
+     */
+    char *sub_charenc;
+
+    /**
+     * Subtitles character encoding mode. Formats or codecs might be adjusting
+     * this setting (if they are doing the conversion themselves for instance).
+     * - decoding: set by libavcodec
+     * - encoding: unused
+     */
+    int sub_charenc_mode;
+#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);
@@ -4773,7 +4841,12 @@
 //FIXME func typedef
 
 /**
- * Fill audio frame data and linesize.
+ * Fill AVFrame audio data and linesize pointers.
+ *
+ * The buffer buf must be a preallocated buffer with a size big enough
+ * to contain the specified samples amount. The filled AVFrame data
+ * pointers will point to this buffer.
+ *
  * AVFrame extended_data channel pointers are allocated if necessary for
  * planar audio.
  *
@@ -4787,8 +4860,8 @@
  * @param buf_size    size of buffer
  * @param align       plane size sample alignment (0 = default)
  * @return            >=0 on success, negative error code on failure
- * @todo return the size of the allocated frame size in case of
- * success, at the next libavutil bump
+ * @todo return the size in bytes required to store the samples in
+ * case of success, at the next libavutil bump
  */
 int avcodec_fill_audio_frame(AVFrame *frame, int nb_channels,
                              enum AVSampleFormat sample_fmt, const uint8_t *buf,
@@ -4892,7 +4965,7 @@
 
 /**
  * Same behaviour av_fast_malloc but the buffer has additional
- * FF_INPUT_PADDING_SIZE at the end which will will always be 0.
+ * FF_INPUT_BUFFER_PADDING_SIZE at the end which will 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/avpacket.c b/libavcodec/avpacket.c
index 516f1c9..dea72e5 100644
--- a/libavcodec/avpacket.c
+++ b/libavcodec/avpacket.c
@@ -41,8 +41,6 @@
     av_free(pkt->data);
     pkt->data = NULL;
     pkt->size = 0;
-
-    ff_packet_free_side_data(pkt);
 }
 
 void av_init_packet(AVPacket *pkt)
@@ -174,11 +172,16 @@
 void av_free_packet(AVPacket *pkt)
 {
     if (pkt) {
+        int i;
+
         if (pkt->destruct)
             pkt->destruct(pkt);
         pkt->data            = NULL;
         pkt->size            = 0;
-        pkt->side_data       = NULL;
+
+        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;
     }
 }
diff --git a/libavcodec/avrndec.c b/libavcodec/avrndec.c
index 2205a42..0fc431d 100644
--- a/libavcodec/avrndec.c
+++ b/libavcodec/avrndec.c
@@ -20,6 +20,7 @@
  */
 
 #include "avcodec.h"
+#include "internal.h"
 #include "mjpeg.h"
 #include "mjpegdec.h"
 #include "libavutil/imgutils.h"
@@ -79,7 +80,8 @@
     return 0;
 }
 
-static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt)
+static int decode_frame(AVCodecContext *avctx, void *data,
+                        int *got_frame, AVPacket *avpkt)
 {
     AVRnContext *a = avctx->priv_data;
     AVFrame *p = &a->frame;
@@ -88,7 +90,7 @@
     int y, ret, true_height;
 
     if(a->is_mjpeg)
-        return ff_mjpeg_decode_frame(avctx, data, data_size, avpkt);
+        return ff_mjpeg_decode_frame(avctx, data, got_frame, avpkt);
 
     true_height    = buf_size / (2*avctx->width);
     if(p->data[0])
@@ -99,7 +101,7 @@
         return AVERROR_INVALIDDATA;
     }
 
-    if((ret = avctx->get_buffer(avctx, p)) < 0){
+    if((ret = ff_get_buffer(avctx, p)) < 0){
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -122,7 +124,7 @@
     }
 
     *(AVFrame*)data = a->frame;
-    *data_size      = sizeof(AVFrame);
+    *got_frame      = 1;
     return buf_size;
 }
 
diff --git a/libavcodec/avs.c b/libavcodec/avs.c
index 4b05bf9..e3d2070 100644
--- a/libavcodec/avs.c
+++ b/libavcodec/avs.c
@@ -44,7 +44,7 @@
 
 static int
 avs_decode_frame(AVCodecContext * avctx,
-                 void *data, int *data_size, AVPacket *avpkt)
+                 void *data, int *got_frame, AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
     const uint8_t *buf_end = avpkt->data + avpkt->size;
@@ -54,14 +54,14 @@
     AVFrame *const p =  &avs->picture;
     const uint8_t *table, *vect;
     uint8_t *out;
-    int i, j, x, y, stride, vect_w = 3, vect_h = 3;
+    int i, j, x, y, stride, ret, vect_w = 3, vect_h = 3;
     AvsVideoSubType sub_type;
     AvsBlockType type;
-    GetBitContext change_map;
+    GetBitContext change_map = {0}; //init to silence warning
 
-    if (avctx->reget_buffer(avctx, p)) {
+    if ((ret = avctx->reget_buffer(avctx, p)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-        return -1;
+        return ret;
     }
     p->reference = 3;
     p->pict_type = AV_PICTURE_TYPE_P;
@@ -96,7 +96,7 @@
     }
 
     if (type != AVS_VIDEO)
-        return -1;
+        return AVERROR_INVALIDDATA;
 
     switch (sub_type) {
     case AVS_I_FRAME:
@@ -118,7 +118,7 @@
         break;
 
     default:
-      return -1;
+      return AVERROR_INVALIDDATA;
     }
 
     if (buf_end - buf < 256 * vect_w * vect_h)
@@ -152,7 +152,7 @@
     }
 
     *picture   = avs->picture;
-    *data_size = sizeof(AVPicture);
+    *got_frame = 1;
 
     return buf_size;
 }
diff --git a/libavcodec/avuidec.c b/libavcodec/avuidec.c
index 52d8090..22af719 100644
--- a/libavcodec/avuidec.c
+++ b/libavcodec/avuidec.c
@@ -21,6 +21,7 @@
  */
 
 #include "avcodec.h"
+#include "internal.h"
 #include "libavutil/intreadwrite.h"
 
 static av_cold int avui_decode_init(AVCodecContext *avctx)
@@ -38,7 +39,7 @@
 }
 
 static int avui_decode_frame(AVCodecContext *avctx, void *data,
-                             int *data_size, AVPacket *avpkt)
+                             int *got_frame, AVPacket *avpkt)
 {
     AVFrame *pic = avctx->coded_frame;
     const uint8_t *src = avpkt->data, *extradata = avctx->extradata;
@@ -79,7 +80,7 @@
 
     pic->reference = 0;
 
-    if (avctx->get_buffer(avctx, pic) < 0) {
+    if (ff_get_buffer(avctx, pic) < 0) {
         av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
         return AVERROR(ENOMEM);
     }
@@ -127,7 +128,7 @@
         src  += 4;
         srca += 4;
     }
-    *data_size = sizeof(AVFrame);
+    *got_frame       = 1;
     *(AVFrame *)data = *pic;
 
     return avpkt->size;
diff --git a/libavcodec/bethsoftvideo.c b/libavcodec/bethsoftvideo.c
index 8eec5b7..2a03f1a 100644
--- a/libavcodec/bethsoftvideo.c
+++ b/libavcodec/bethsoftvideo.c
@@ -28,7 +28,7 @@
  */
 
 #include "libavutil/common.h"
-#include "dsputil.h"
+#include "avcodec.h"
 #include "bethsoftvideo.h"
 #include "bytestream.h"
 
@@ -65,7 +65,7 @@
 }
 
 static int bethsoftvid_decode_frame(AVCodecContext *avctx,
-                              void *data, int *data_size,
+                              void *data, int *got_frame,
                               AVPacket *avpkt)
 {
     BethsoftvidContext * vid = avctx->priv_data;
@@ -97,7 +97,7 @@
 
     switch(block_type = bytestream2_get_byte(&vid->g)){
         case PALETTE_BLOCK: {
-            *data_size = 0;
+            *got_frame = 0;
             if ((ret = set_palette(vid)) < 0) {
                 av_log(avctx, AV_LOG_ERROR, "error reading palette\n");
                 return ret;
@@ -138,7 +138,7 @@
     }
     end:
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*)data = vid->frame;
 
     return avpkt->size;
diff --git a/libavcodec/bfi.c b/libavcodec/bfi.c
index f7df68e..231ee62 100644
--- a/libavcodec/bfi.c
+++ b/libavcodec/bfi.c
@@ -29,6 +29,7 @@
 #include "libavutil/common.h"
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 
 typedef struct BFIContext {
     AVCodecContext *avctx;
@@ -47,7 +48,7 @@
 }
 
 static int bfi_decode_frame(AVCodecContext *avctx, void *data,
-                            int *data_size, AVPacket *avpkt)
+                            int *got_frame, AVPacket *avpkt)
 {
     GetByteContext g;
     int buf_size    = avpkt->size;
@@ -56,16 +57,16 @@
     uint8_t *src, *dst_offset, colour1, colour2;
     uint8_t *frame_end = bfi->dst + avctx->width * avctx->height;
     uint32_t *pal;
-    int i, j, height = avctx->height;
+    int i, j, ret, height = avctx->height;
 
     if (bfi->frame.data[0])
         avctx->release_buffer(avctx, &bfi->frame);
 
     bfi->frame.reference = 3;
 
-    if (avctx->get_buffer(avctx, &bfi->frame) < 0) {
+    if ((ret = ff_get_buffer(avctx, &bfi->frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     bytestream2_init(&g, avpkt->data, buf_size);
@@ -77,7 +78,7 @@
         /* Setting the palette */
         if (avctx->extradata_size > 768) {
             av_log(NULL, AV_LOG_ERROR, "Palette is too large.\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
         pal = (uint32_t *)bfi->frame.data[1];
         for (i = 0; i < avctx->extradata_size / 3; i++) {
@@ -108,7 +109,7 @@
         if (!bytestream2_get_bytes_left(&g)) {
             av_log(avctx, AV_LOG_ERROR,
                    "Input resolution larger than actual frame.\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
 
         /* Get length and offset (if required) */
@@ -134,7 +135,7 @@
         case 0:                // normal chain
             if (length >= bytestream2_get_bytes_left(&g)) {
                 av_log(avctx, AV_LOG_ERROR, "Frame larger than buffer.\n");
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
             bytestream2_get_buffer(&g, dst, length);
             dst += length;
@@ -168,7 +169,7 @@
         src += avctx->width;
         dst += bfi->frame.linesize[0];
     }
-    *data_size       = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame *)data = bfi->frame;
     return buf_size;
 }
diff --git a/libavcodec/bfin/Makefile b/libavcodec/bfin/Makefile
index be81e6c..d1b41bc 100644
--- a/libavcodec/bfin/Makefile
+++ b/libavcodec/bfin/Makefile
@@ -2,7 +2,7 @@
         bfin/fdct_bfin.o                                                \
         bfin/idct_bfin.o                                                \
         bfin/pixels_bfin.o                                              \
-        bfin/vp3_bfin.o                                                 \
-        bfin/vp3_idct_bfin.o                                            \
 
 OBJS-$(CONFIG_MPEGVIDEOENC)             += bfin/mpegvideo_bfin.o
+OBJS-$(CONFIG_VP3DSP)                   += bfin/vp3_bfin.o              \
+                                           bfin/vp3_idct_bfin.o
diff --git a/libavcodec/bfin/config_bfin.h b/libavcodec/bfin/config_bfin.h
index f3a2c6e..3643953 100644
--- a/libavcodec/bfin/config_bfin.h
+++ b/libavcodec/bfin/config_bfin.h
@@ -21,7 +21,7 @@
    low level assembler interface wrapper
 
 DEFUN(put_pixels_clamped,mL1,
-        (DCTELEM *block, uint8_t *dest, int line_size)):
+        (int16_t *block, uint8_t *dest, int line_size)):
 
       body
 
diff --git a/libavcodec/bfin/dsputil_bfin.c b/libavcodec/bfin/dsputil_bfin.c
index 434d2a7..ce04753 100644
--- a/libavcodec/bfin/dsputil_bfin.c
+++ b/libavcodec/bfin/dsputil_bfin.c
@@ -21,26 +21,27 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavcodec/avcodec.h"
 #include "libavcodec/dsputil.h"
 #include "dsputil_bfin.h"
 
 int off;
 
-static void bfin_idct_add (uint8_t *dest, int line_size, DCTELEM *block)
+static void bfin_idct_add (uint8_t *dest, int line_size, int16_t *block)
 {
     ff_bfin_idct (block);
     ff_bfin_add_pixels_clamped (block, dest, line_size);
 }
 
-static void bfin_idct_put (uint8_t *dest, int line_size, DCTELEM *block)
+static void bfin_idct_put (uint8_t *dest, int line_size, int16_t *block)
 {
     ff_bfin_idct (block);
     ff_bfin_put_pixels_clamped (block, dest, line_size);
 }
 
 
-static void bfin_clear_blocks (DCTELEM *blocks)
+static void bfin_clear_blocks (int16_t *blocks)
 {
     // This is just a simple memset.
     //
@@ -55,73 +56,73 @@
 
 
 
-static void bfin_put_pixels8 (uint8_t *block, const uint8_t *pixels, int line_size, int h)
+static void bfin_put_pixels8 (uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
 {
     ff_bfin_put_pixels8uc (block, pixels, pixels, line_size, line_size, h);
 }
 
-static void bfin_put_pixels8_x2(uint8_t *block, const uint8_t *pixels, int line_size, int h)
+static void bfin_put_pixels8_x2(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
 {
     ff_bfin_put_pixels8uc (block, pixels, pixels+1, line_size, line_size, h);
 }
 
-static void bfin_put_pixels8_y2 (uint8_t *block, const uint8_t *pixels, int line_size, int h)
+static void bfin_put_pixels8_y2 (uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
 {
     ff_bfin_put_pixels8uc (block, pixels, pixels+line_size, line_size, line_size, h);
 }
 
-static void bfin_put_pixels8_xy2 (uint8_t *block, const uint8_t *s0, int line_size, int h)
+static void bfin_put_pixels8_xy2 (uint8_t *block, const uint8_t *s0, ptrdiff_t line_size, int h)
 {
     ff_bfin_z_put_pixels8_xy2 (block,s0,line_size, line_size, h);
 }
 
-static void bfin_put_pixels16 (uint8_t *block, const uint8_t *pixels, int line_size, int h)
+static void bfin_put_pixels16 (uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
 {
     ff_bfin_put_pixels16uc (block, pixels, pixels, line_size, line_size, h);
 }
 
-static void bfin_put_pixels16_x2 (uint8_t *block, const uint8_t *pixels, int line_size, int h)
+static void bfin_put_pixels16_x2 (uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
 {
     ff_bfin_put_pixels16uc (block, pixels, pixels+1, line_size, line_size, h);
 }
 
-static void bfin_put_pixels16_y2 (uint8_t *block, const uint8_t *pixels, int line_size, int h)
+static void bfin_put_pixels16_y2 (uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
 {
     ff_bfin_put_pixels16uc (block, pixels, pixels+line_size, line_size, line_size, h);
 }
 
-static void bfin_put_pixels16_xy2 (uint8_t *block, const uint8_t *s0, int line_size, int h)
+static void bfin_put_pixels16_xy2 (uint8_t *block, const uint8_t *s0, ptrdiff_t line_size, int h)
 {
     ff_bfin_z_put_pixels16_xy2 (block,s0,line_size, line_size, h);
 }
 
-static void bfin_put_pixels8_nornd (uint8_t *block, const uint8_t *pixels, int line_size, int h)
+static void bfin_put_pixels8_nornd (uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
 {
     ff_bfin_put_pixels8uc_nornd (block, pixels, pixels, line_size, h);
 }
 
-static void bfin_put_pixels8_x2_nornd (uint8_t *block, const uint8_t *pixels, int line_size, int h)
+static void bfin_put_pixels8_x2_nornd (uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
 {
     ff_bfin_put_pixels8uc_nornd (block, pixels, pixels+1, line_size, h);
 }
 
-static void bfin_put_pixels8_y2_nornd (uint8_t *block, const uint8_t *pixels, int line_size, int h)
+static void bfin_put_pixels8_y2_nornd (uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
 {
     ff_bfin_put_pixels8uc_nornd (block, pixels, pixels+line_size, line_size, h);
 }
 
 
-static void bfin_put_pixels16_nornd (uint8_t *block, const uint8_t *pixels, int line_size, int h)
+static void bfin_put_pixels16_nornd (uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
 {
     ff_bfin_put_pixels16uc_nornd (block, pixels, pixels, line_size, h);
 }
 
-static void bfin_put_pixels16_x2_nornd (uint8_t *block, const uint8_t *pixels, int line_size, int h)
+static void bfin_put_pixels16_x2_nornd (uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
 {
     ff_bfin_put_pixels16uc_nornd (block, pixels, pixels+1, line_size, h);
 }
 
-static void bfin_put_pixels16_y2_nornd (uint8_t *block, const uint8_t *pixels, int line_size, int h)
+static void bfin_put_pixels16_y2_nornd (uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
 {
     ff_bfin_put_pixels16uc_nornd (block, pixels, pixels+line_size, line_size, h);
 }
@@ -195,7 +196,7 @@
 
 */
 
-void ff_dsputil_init_bfin( DSPContext* c, AVCodecContext *avctx )
+av_cold void ff_dsputil_init_bfin(DSPContext *c, AVCodecContext *avctx)
 {
     const int high_bit_depth = avctx->bits_per_raw_sample > 8;
 
@@ -257,12 +258,7 @@
         if (avctx->dct_algo == FF_DCT_AUTO)
             c->fdct                  = ff_bfin_fdct;
 
-        if (avctx->idct_algo == FF_IDCT_VP3) {
-            c->idct_permutation_type = FF_NO_IDCT_PERM;
-            c->idct                  = ff_bfin_vp3_idct;
-            c->idct_add              = ff_bfin_vp3_idct_add;
-            c->idct_put              = ff_bfin_vp3_idct_put;
-        } else if (avctx->idct_algo == FF_IDCT_AUTO) {
+    if (avctx->idct_algo == FF_IDCT_AUTO) {
             c->idct_permutation_type = FF_NO_IDCT_PERM;
             c->idct                  = ff_bfin_idct;
             c->idct_add              = bfin_idct_add;
diff --git a/libavcodec/bfin/dsputil_bfin.h b/libavcodec/bfin/dsputil_bfin.h
index 43ac39c..2930923 100644
--- a/libavcodec/bfin/dsputil_bfin.h
+++ b/libavcodec/bfin/dsputil_bfin.h
@@ -24,8 +24,9 @@
 #ifndef AVCODEC_BFIN_DSPUTIL_BFIN_H
 #define AVCODEC_BFIN_DSPUTIL_BFIN_H
 
+#include <stdint.h>
+
 #include "config.h"
-#include "libavcodec/dsputil.h"
 
 #if defined(__FDPIC__) && CONFIG_SRAM
 #define attribute_l1_text  __attribute__ ((l1_text))
@@ -35,15 +36,12 @@
 #define attribute_l1_data_b
 #endif
 
-void ff_bfin_idct (DCTELEM *block) attribute_l1_text;
-void ff_bfin_fdct (DCTELEM *block) attribute_l1_text;
-void ff_bfin_vp3_idct (DCTELEM *block);
-void ff_bfin_vp3_idct_put (uint8_t *dest, int line_size, DCTELEM *block);
-void ff_bfin_vp3_idct_add (uint8_t *dest, int line_size, DCTELEM *block);
-void ff_bfin_add_pixels_clamped (const DCTELEM *block, uint8_t *dest, int line_size) attribute_l1_text;
-void ff_bfin_put_pixels_clamped (const DCTELEM *block, uint8_t *dest, int line_size) attribute_l1_text;
-void ff_bfin_diff_pixels (DCTELEM *block, const uint8_t *s1, const uint8_t *s2, int stride)  attribute_l1_text;
-void ff_bfin_get_pixels  (DCTELEM *av_restrict block, const uint8_t *pixels, int line_size) attribute_l1_text;
+void ff_bfin_idct (int16_t *block) attribute_l1_text;
+void ff_bfin_fdct (int16_t *block) attribute_l1_text;
+void ff_bfin_add_pixels_clamped (const int16_t *block, uint8_t *dest, int line_size) attribute_l1_text;
+void ff_bfin_put_pixels_clamped (const int16_t *block, uint8_t *dest, int line_size) attribute_l1_text;
+void ff_bfin_diff_pixels (int16_t *block, const uint8_t *s1, const uint8_t *s2, int stride)  attribute_l1_text;
+void ff_bfin_get_pixels  (int16_t *restrict block, const uint8_t *pixels, int line_size) attribute_l1_text;
 int  ff_bfin_pix_norm1  (uint8_t * pix, int line_size) attribute_l1_text;
 int  ff_bfin_z_sad8x8   (uint8_t *blk1, uint8_t *blk2, int dsz, int line_size, int h) attribute_l1_text;
 int  ff_bfin_z_sad16x16 (uint8_t *blk1, uint8_t *blk2, int dsz, int line_size, int h) attribute_l1_text;
diff --git a/libavcodec/bfin/fdct_bfin.S b/libavcodec/bfin/fdct_bfin.S
index e15acb6..9169574 100644
--- a/libavcodec/bfin/fdct_bfin.S
+++ b/libavcodec/bfin/fdct_bfin.S
@@ -20,7 +20,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 /*
-  void ff_bfin_fdct (DCTELEM *buf);
+  void ff_bfin_fdct (int16_t *buf);
 
   This implementation works only for 8x8 input. The range of input
   must be -256 to 255 i.e. 8bit input represented in a 16bit data
@@ -61,9 +61,9 @@
   Other registers used:
         I0, I1, I2, I3, B0, B2, B3, M0, M1, L3 registers and LC0.
 
-  Input - r0 - pointer to start of DCTELEM *block
+  Input - r0 - pointer to start of int16_t *block
 
-  Output - The DCT output coefficients in the DCTELEM *block
+  Output - The DCT output coefficients in the int16_t *block
 
   Register constraint:
                This code is called from jpeg_encode.
@@ -147,7 +147,7 @@
 
 .text
 DEFUN(fdct,mL1,
-        (DCTELEM *block)):
+        (int16_t *block)):
     [--SP] = (R7:4, P5:3);          // Push the registers onto the stack.
 
     b0 = r0;
diff --git a/libavcodec/bfin/idct_bfin.S b/libavcodec/bfin/idct_bfin.S
index 6643009..bd80447 100644
--- a/libavcodec/bfin/idct_bfin.S
+++ b/libavcodec/bfin/idct_bfin.S
@@ -22,7 +22,7 @@
 /*
    This blackfin DSP code implements an 8x8 inverse type II DCT.
 
-Prototype       : void ff_bfin_idct(DCTELEM *in)
+Prototype       : void ff_bfin_idct(int16_t *in)
 
 Registers Used  : A0, A1, R0-R7, I0-I3, B0, B2, B3, M0-M2, L0-L3, P0-P5, LC0.
 
@@ -90,7 +90,7 @@
 
 .text
 DEFUN(idct,mL1,
-        (DCTELEM *block)):
+        (int16_t *block)):
 
 /********************** Function Prologue *********************************/
     link 16;
diff --git a/libavcodec/bfin/mpegvideo_bfin.c b/libavcodec/bfin/mpegvideo_bfin.c
index f7f3d72..458e7dc 100644
--- a/libavcodec/bfin/mpegvideo_bfin.c
+++ b/libavcodec/bfin/mpegvideo_bfin.c
@@ -20,13 +20,13 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavcodec/avcodec.h"
-#include "libavcodec/dsputil.h"
 #include "libavcodec/mpegvideo.h"
 #include "dsputil_bfin.h"
 
 static int dct_quantize_bfin (MpegEncContext *s,
-                              DCTELEM *block, int n,
+                              int16_t *block, int n,
                               int qscale, int *overflow)
 {
     int last_non_zero, q, start_i;
@@ -146,7 +146,7 @@
     return last_non_zero;
 }
 
-void ff_MPV_common_init_bfin (MpegEncContext *s)
+av_cold void ff_MPV_common_init_bfin (MpegEncContext *s)
 {
 /*     s->dct_quantize= dct_quantize_bfin; */
 }
diff --git a/libavcodec/bfin/pixels_bfin.S b/libavcodec/bfin/pixels_bfin.S
index 995d7b8..2e3cd0f 100644
--- a/libavcodec/bfin/pixels_bfin.S
+++ b/libavcodec/bfin/pixels_bfin.S
@@ -21,7 +21,7 @@
 #include "config_bfin.h"
 
 DEFUN(put_pixels_clamped,mL1,
-        (DCTELEM *block, uint8_t *dest, int line_size)):
+        (int16_t *block, uint8_t *dest, int line_size)):
     [--SP] = (R7:4);
     R4 = 0;
     R5.l = 0x00ff;
@@ -51,7 +51,7 @@
 DEFUN_END(put_pixels_clamped)
 
 DEFUN(add_pixels_clamped,mL1,
-        (DCTELEM *block, uint8_t *dest, int line_size)):
+        (int16_t *block, uint8_t *dest, int line_size)):
     [-- SP] = (R7:4);
     R4 = 0;
     I0 = 0;
@@ -442,7 +442,7 @@
         rts;
 
 DEFUN(diff_pixels,mL1,
-       (DCTELEM *block, uint8_t *s1, uint8_t *s2, int stride)):
+       (int16_t *block, uint8_t *s1, uint8_t *s2, int stride)):
         link 0;
         [--sp] = (r7:4);
         p0=8;
@@ -518,7 +518,7 @@
 
 
 DEFUN(get_pixels,mL1,
-        (DCTELEM *av_restrict block, const uint8_t *pixels, int line_size)):
+        (int16_t *av_restrict block, const uint8_t *pixels, int line_size)):
         [--sp] = (r7:4);
         i3=r0;        // dest
         i0=r1;        // src0
diff --git a/libavcodec/bfin/vp3_bfin.c b/libavcodec/bfin/vp3_bfin.c
index 6d6ac82..e823a04 100644
--- a/libavcodec/bfin/vp3_bfin.c
+++ b/libavcodec/bfin/vp3_bfin.c
@@ -18,12 +18,17 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <string.h>
+
+#include "libavutil/attributes.h"
 #include "libavcodec/avcodec.h"
+#include "libavcodec/vp3dsp.h"
 #include "libavcodec/dsputil.h"
 #include "dsputil_bfin.h"
+#include "vp3_bfin.h"
 
 /* Intra iDCT offset 128 */
-void ff_bfin_vp3_idct_put (uint8_t *dest, int line_size, DCTELEM *block)
+void ff_bfin_vp3_idct_put (uint8_t *dest, int line_size, int16_t *block)
 {
     uint8_t *cm = ff_cropTbl + MAX_NEG_CROP + 128;
     int i,j;
@@ -33,11 +38,21 @@
     for (i=0;i<8;i++)
         for (j=0;j<8;j++)
             dest[line_size*i+j]=cm[block[i*8+j]];
+
+    memset(block, 0, 128);
 }
 
 /* Inter iDCT */
-void ff_bfin_vp3_idct_add (uint8_t *dest, int line_size, DCTELEM *block)
+void ff_bfin_vp3_idct_add (uint8_t *dest, int line_size, int16_t *block)
 {
     ff_bfin_vp3_idct (block);
     ff_bfin_add_pixels_clamped (block, dest, line_size);
+
+    memset(block, 0, 128);
+}
+
+av_cold void ff_vp3dsp_init_bfin(VP3DSPContext *c, int flags)
+{
+    c->idct_add = ff_bfin_vp3_idct_add;
+    c->idct_put = ff_bfin_vp3_idct_put;
 }
diff --git a/libavcodec/arm/dsputil_init_vfp.c b/libavcodec/bfin/vp3_bfin.h
similarity index 66%
copy from libavcodec/arm/dsputil_init_vfp.c
copy to libavcodec/bfin/vp3_bfin.h
index 5713c71..f0bf824 100644
--- a/libavcodec/arm/dsputil_init_vfp.c
+++ b/libavcodec/bfin/vp3_bfin.h
@@ -1,6 +1,4 @@
 /*
- * Copyright (c) 2008 Siarhei Siamashka <ssvb@users.sourceforge.net>
- *
  * This file is part of FFmpeg.
  *
  * FFmpeg is free software; you can redistribute it and/or
@@ -18,13 +16,14 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavcodec/dsputil.h"
-#include "dsputil_arm.h"
 
-void ff_vector_fmul_reverse_vfp(float *dst, const float *src0,
-                                const float *src1, int len);
+#ifndef AVCODEC_BFIN_VP3_BFIN_H
+#define AVCODEC_BFIN_VP3_BFIN_H
 
-void ff_dsputil_init_vfp(DSPContext* c, AVCodecContext *avctx)
-{
-    c->vector_fmul_reverse = ff_vector_fmul_reverse_vfp;
-}
+#include <stdint.h>
+
+void ff_bfin_vp3_idct(int16_t *block);
+void ff_bfin_vp3_idct_put(uint8_t *dest, int line_size, int16_t *block);
+void ff_bfin_vp3_idct_add(uint8_t *dest, int line_size, int16_t *block);
+
+#endif /* AVCODEC_BFIN_VP3_BFIN_H */
diff --git a/libavcodec/bfin/vp3_idct_bfin.S b/libavcodec/bfin/vp3_idct_bfin.S
index 83747f9..4e20045 100644
--- a/libavcodec/bfin/vp3_idct_bfin.S
+++ b/libavcodec/bfin/vp3_idct_bfin.S
@@ -22,7 +22,7 @@
 /*
    This blackfin DSP code implements an 8x8 inverse type II DCT.
 
-Prototype       : void ff_bfin_vp3_idct(DCTELEM *in)
+Prototype       : void ff_bfin_vp3_idct(int16_t *in)
 
 Registers Used  : A0, A1, R0-R7, I0-I3, B0, B2, B3, M0-M2, L0-L3, P0-P5, LC0.
 
@@ -63,7 +63,7 @@
 
 .text
 DEFUN(vp3_idct,mL1,
-        (DCTELEM *block)):
+        (int16_t *block)):
 
 /********************** Function Prologue *********************************/
     link 16;
diff --git a/libavcodec/bink.c b/libavcodec/bink.c
index bb202ca..5d000a8 100644
--- a/libavcodec/bink.c
+++ b/libavcodec/bink.c
@@ -21,10 +21,12 @@
  */
 
 #include "libavutil/imgutils.h"
+#include "libavutil/internal.h"
 #include "avcodec.h"
 #include "dsputil.h"
 #include "binkdata.h"
 #include "binkdsp.h"
+#include "internal.h"
 #include "mathops.h"
 
 #define BITSTREAM_READER_LE
@@ -111,7 +113,7 @@
     AVCodecContext *avctx;
     DSPContext     dsp;
     BinkDSPContext bdsp;
-    AVFrame        pic, last;
+    AVFrame        *pic, *last;
     int            version;              ///< internal Bink file version
     int            has_alpha;
     int            swap_planes;
@@ -169,7 +171,7 @@
  *
  * @param c decoder context
  */
-static av_cold void init_bundles(BinkContext *c)
+static av_cold int init_bundles(BinkContext *c)
 {
     int bw, bh, blocks;
     int i;
@@ -180,8 +182,12 @@
 
     for (i = 0; i < BINKB_NB_SRC; i++) {
         c->bundle[i].data = av_malloc(blocks * 64);
+        if (!c->bundle[i].data)
+            return AVERROR(ENOMEM);
         c->bundle[i].data_end = c->bundle[i].data + blocks * 64;
     }
+
+    return 0;
 }
 
 /**
@@ -312,7 +318,7 @@
     dec_end = b->cur_dec + t;
     if (dec_end > b->data_end) {
         av_log(avctx, AV_LOG_ERROR, "Run value went out of bounds\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     if (get_bits1(gb)) {
         v = get_bits(gb, 4);
@@ -334,7 +340,7 @@
     dec_end = b->cur_dec + t;
     if (dec_end > b->data_end) {
         av_log(avctx, AV_LOG_ERROR, "Too many motion values\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     if (get_bits1(gb)) {
         v = get_bits(gb, 4);
@@ -369,7 +375,7 @@
     dec_end = b->cur_dec + t;
     if (dec_end > b->data_end) {
         av_log(avctx, AV_LOG_ERROR, "Too many block type values\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     if (get_bits1(gb)) {
         v = get_bits(gb, 4);
@@ -385,7 +391,7 @@
                 int run = bink_rlelens[v - 12];
 
                 if (dec_end - b->cur_dec < run)
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 memset(b->cur_dec, last, run);
                 b->cur_dec += run;
             }
@@ -403,7 +409,7 @@
     dec_end = b->cur_dec + t;
     if (dec_end > b->data_end) {
         av_log(avctx, AV_LOG_ERROR, "Too many pattern values\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     while (b->cur_dec < dec_end) {
         v  = GET_HUFF(gb, b->tree);
@@ -423,7 +429,7 @@
     dec_end = b->cur_dec + t;
     if (dec_end > b->data_end) {
         av_log(c->avctx, AV_LOG_ERROR, "Too many color values\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     if (get_bits1(gb)) {
         c->col_lastval = GET_HUFF(gb, c->col_high[c->col_lastval]);
@@ -469,13 +475,13 @@
         v = (v ^ sign) - sign;
     }
     if (dst_end - dst < 1)
-        return -1;
+        return AVERROR_INVALIDDATA;
     *dst++ = v;
     len--;
     for (i = 0; i < len; i += 8) {
         len2 = FFMIN(len - i, 8);
         if (dst_end - dst < len2)
-            return -1;
+            return AVERROR_INVALIDDATA;
         bsize = get_bits(gb, 4);
         if (bsize) {
             for (j = 0; j < len2; j++) {
@@ -488,7 +494,7 @@
                 *dst++ = v;
                 if (v < -32768 || v > 32767) {
                     av_log(avctx, AV_LOG_ERROR, "DC value went out of bounds: %d\n", v);
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 }
             }
         } else {
@@ -544,7 +550,7 @@
 
     CHECK_READ_VAL(gb, b, len);
     if (b->data_end - b->cur_dec < len * (1 + (bits > 8)))
-        return -1;
+        return AVERROR_INVALIDDATA;
     if (bits <= 8) {
         if (!issigned) {
             for (i = 0; i < len; i++)
@@ -699,7 +705,7 @@
  * @param masks_count number of masks to decode
  * @return 0 on success, negative value in other cases
  */
-static int read_residue(GetBitContext *gb, DCTELEM block[64], int masks_count)
+static int read_residue(GetBitContext *gb, int16_t block[64], int masks_count)
 {
     int coef_list[128];
     int mode_list[128];
@@ -797,36 +803,36 @@
 static int binkb_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx,
                               int is_key, int is_chroma)
 {
-    int blk;
+    int blk, ret;
     int i, j, bx, by;
     uint8_t *dst, *ref, *ref_start, *ref_end;
     int v, col[2];
     const uint8_t *scan;
     int xoff, yoff;
-    LOCAL_ALIGNED_16(DCTELEM, block, [64]);
+    LOCAL_ALIGNED_16(int16_t, block, [64]);
     LOCAL_ALIGNED_16(int32_t, dctblock, [64]);
     int coordmap[64];
     int ybias = is_key ? -15 : 0;
     int qp;
 
-    const int stride = c->pic.linesize[plane_idx];
+    const int stride = c->pic->linesize[plane_idx];
     int bw = is_chroma ? (c->avctx->width  + 15) >> 4 : (c->avctx->width  + 7) >> 3;
     int bh = is_chroma ? (c->avctx->height + 15) >> 4 : (c->avctx->height + 7) >> 3;
 
     binkb_init_bundles(c);
-    ref_start = c->pic.data[plane_idx];
-    ref_end   = c->pic.data[plane_idx] + (bh * c->pic.linesize[plane_idx] + bw) * 8;
+    ref_start = c->pic->data[plane_idx];
+    ref_end   = c->pic->data[plane_idx] + (bh * c->pic->linesize[plane_idx] + bw) * 8;
 
     for (i = 0; i < 64; i++)
         coordmap[i] = (i & 7) + (i >> 3) * stride;
 
     for (by = 0; by < bh; by++) {
         for (i = 0; i < BINKB_NB_SRC; i++) {
-            if (binkb_read_bundle(c, gb, i) < 0)
-                return -1;
+            if ((ret = binkb_read_bundle(c, gb, i)) < 0)
+                return ret;
         }
 
-        dst  = c->pic.data[plane_idx]  + 8*by*stride;
+        dst  = c->pic->data[plane_idx]  + 8*by*stride;
         for (bx = 0; bx < bw; bx++, dst += 8) {
             blk = binkb_get_value(c, BINKB_SRC_BLOCK_TYPES);
             switch (blk) {
@@ -844,7 +850,7 @@
                     i += run;
                     if (i > 64) {
                         av_log(c->avctx, AV_LOG_ERROR, "Run went out of bounds\n");
-                        return -1;
+                        return AVERROR_INVALIDDATA;
                     }
                     if (mode) {
                         v = binkb_get_value(c, BINKB_SRC_COLORS);
@@ -930,7 +936,7 @@
                 break;
             default:
                 av_log(c->avctx, AV_LOG_ERROR, "Unknown block type %d\n", blk);
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
         }
     }
@@ -943,18 +949,18 @@
 static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx,
                              int is_chroma)
 {
-    int blk;
+    int blk, ret;
     int i, j, bx, by;
     uint8_t *dst, *prev, *ref, *ref_start, *ref_end;
     int v, col[2];
     const uint8_t *scan;
     int xoff, yoff;
-    LOCAL_ALIGNED_16(DCTELEM, block, [64]);
+    LOCAL_ALIGNED_16(int16_t, block, [64]);
     LOCAL_ALIGNED_16(uint8_t, ublock, [64]);
     LOCAL_ALIGNED_16(int32_t, dctblock, [64]);
     int coordmap[64];
 
-    const int stride = c->pic.linesize[plane_idx];
+    const int stride = c->pic->linesize[plane_idx];
     int bw = is_chroma ? (c->avctx->width  + 15) >> 4 : (c->avctx->width  + 7) >> 3;
     int bh = is_chroma ? (c->avctx->height + 15) >> 4 : (c->avctx->height + 7) >> 3;
     int width = c->avctx->width >> is_chroma;
@@ -963,39 +969,39 @@
     for (i = 0; i < BINK_NB_SRC; i++)
         read_bundle(gb, c, i);
 
-    ref_start = c->last.data[plane_idx] ? c->last.data[plane_idx]
-                                        : c->pic.data[plane_idx];
+    ref_start = c->last->data[plane_idx] ? c->last->data[plane_idx]
+                                        : c->pic->data[plane_idx];
     ref_end   = ref_start
-                + (bw - 1 + c->last.linesize[plane_idx] * (bh - 1)) * 8;
+                + (bw - 1 + c->last->linesize[plane_idx] * (bh - 1)) * 8;
 
     for (i = 0; i < 64; i++)
         coordmap[i] = (i & 7) + (i >> 3) * stride;
 
     for (by = 0; by < bh; by++) {
-        if (read_block_types(c->avctx, gb, &c->bundle[BINK_SRC_BLOCK_TYPES]) < 0)
-            return -1;
-        if (read_block_types(c->avctx, gb, &c->bundle[BINK_SRC_SUB_BLOCK_TYPES]) < 0)
-            return -1;
-        if (read_colors(gb, &c->bundle[BINK_SRC_COLORS], c) < 0)
-            return -1;
-        if (read_patterns(c->avctx, gb, &c->bundle[BINK_SRC_PATTERN]) < 0)
-            return -1;
-        if (read_motion_values(c->avctx, gb, &c->bundle[BINK_SRC_X_OFF]) < 0)
-            return -1;
-        if (read_motion_values(c->avctx, gb, &c->bundle[BINK_SRC_Y_OFF]) < 0)
-            return -1;
-        if (read_dcs(c->avctx, gb, &c->bundle[BINK_SRC_INTRA_DC], DC_START_BITS, 0) < 0)
-            return -1;
-        if (read_dcs(c->avctx, gb, &c->bundle[BINK_SRC_INTER_DC], DC_START_BITS, 1) < 0)
-            return -1;
-        if (read_runs(c->avctx, gb, &c->bundle[BINK_SRC_RUN]) < 0)
-            return -1;
+        if ((ret = read_block_types(c->avctx, gb, &c->bundle[BINK_SRC_BLOCK_TYPES])) < 0)
+            return ret;
+        if ((ret = read_block_types(c->avctx, gb, &c->bundle[BINK_SRC_SUB_BLOCK_TYPES])) < 0)
+            return ret;
+        if ((ret = read_colors(gb, &c->bundle[BINK_SRC_COLORS], c)) < 0)
+            return ret;
+        if ((ret = read_patterns(c->avctx, gb, &c->bundle[BINK_SRC_PATTERN])) < 0)
+            return ret;
+        if ((ret = read_motion_values(c->avctx, gb, &c->bundle[BINK_SRC_X_OFF])) < 0)
+            return ret;
+        if ((ret = read_motion_values(c->avctx, gb, &c->bundle[BINK_SRC_Y_OFF])) < 0)
+            return ret;
+        if ((ret = read_dcs(c->avctx, gb, &c->bundle[BINK_SRC_INTRA_DC], DC_START_BITS, 0)) < 0)
+            return ret;
+        if ((ret = read_dcs(c->avctx, gb, &c->bundle[BINK_SRC_INTER_DC], DC_START_BITS, 1)) < 0)
+            return ret;
+        if ((ret = read_runs(c->avctx, gb, &c->bundle[BINK_SRC_RUN])) < 0)
+            return ret;
 
         if (by == bh)
             break;
-        dst  = c->pic.data[plane_idx]  + 8*by*stride;
-        prev = (c->last.data[plane_idx] ? c->last.data[plane_idx]
-                                        : c->pic.data[plane_idx]) + 8*by*stride;
+        dst  = c->pic->data[plane_idx]  + 8*by*stride;
+        prev = (c->last->data[plane_idx] ? c->last->data[plane_idx]
+                                         : c->pic->data[plane_idx]) + 8*by*stride;
         for (bx = 0; bx < bw; bx++, dst += 8, prev += 8) {
             blk = get_value(c, BINK_SRC_BLOCK_TYPES);
             // 16x16 block type on odd line means part of the already decoded block, so skip it
@@ -1021,7 +1027,7 @@
                         i += run;
                         if (i > 64) {
                             av_log(c->avctx, AV_LOG_ERROR, "Run went out of bounds\n");
-                            return -1;
+                            return AVERROR_INVALIDDATA;
                         }
                         if (get_bits1(gb)) {
                             v = get_value(c, BINK_SRC_COLORS);
@@ -1061,7 +1067,7 @@
                     break;
                 default:
                     av_log(c->avctx, AV_LOG_ERROR, "Incorrect 16x16 block type %d\n", blk);
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 }
                 if (blk != FILL_BLOCK)
                 c->bdsp.scale_block(ublock, dst, stride);
@@ -1076,7 +1082,7 @@
                 if (ref < ref_start || ref > ref_end) {
                     av_log(c->avctx, AV_LOG_ERROR, "Copy out of bounds @%d, %d\n",
                            bx*8 + xoff, by*8 + yoff);
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 }
                 c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8);
                 break;
@@ -1089,7 +1095,7 @@
                     i += run;
                     if (i > 64) {
                         av_log(c->avctx, AV_LOG_ERROR, "Run went out of bounds\n");
-                        return -1;
+                        return AVERROR_INVALIDDATA;
                     }
                     if (get_bits1(gb)) {
                         v = get_value(c, BINK_SRC_COLORS);
@@ -1110,7 +1116,7 @@
                 if (ref < ref_start || ref > ref_end) {
                     av_log(c->avctx, AV_LOG_ERROR, "Copy out of bounds @%d, %d\n",
                            bx*8 + xoff, by*8 + yoff);
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 }
                 c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8);
                 c->dsp.clear_block(block);
@@ -1159,7 +1165,7 @@
                 break;
             default:
                 av_log(c->avctx, AV_LOG_ERROR, "Unknown block type %d\n", blk);
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
         }
     }
@@ -1169,25 +1175,25 @@
     return 0;
 }
 
-static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *pkt)
+static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *pkt)
 {
     BinkContext * const c = avctx->priv_data;
     GetBitContext gb;
-    int plane, plane_idx;
+    int plane, plane_idx, ret;
     int bits_count = pkt->size << 3;
 
     if (c->version > 'b') {
-        if(c->pic.data[0])
-            avctx->release_buffer(avctx, &c->pic);
+        if(c->pic->data[0])
+            avctx->release_buffer(avctx, c->pic);
 
-        if(avctx->get_buffer(avctx, &c->pic) < 0){
+        if ((ret = ff_get_buffer(avctx, c->pic)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-            return -1;
+            return ret;
         }
     } else {
-        if(avctx->reget_buffer(avctx, &c->pic) < 0){
+        if ((ret = avctx->reget_buffer(avctx, c->pic)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-            return -1;
+            return ret;
         }
     }
 
@@ -1195,8 +1201,8 @@
     if (c->has_alpha) {
         if (c->version >= 'i')
             skip_bits_long(&gb, 32);
-        if (bink_decode_plane(c, &gb, 3, 0) < 0)
-            return -1;
+        if ((ret = bink_decode_plane(c, &gb, 3, 0)) < 0)
+            return ret;
     }
     if (c->version >= 'i')
         skip_bits_long(&gb, 32);
@@ -1205,22 +1211,23 @@
         plane_idx = (!plane || !c->swap_planes) ? plane : (plane ^ 3);
 
         if (c->version > 'b') {
-            if (bink_decode_plane(c, &gb, plane_idx, !!plane) < 0)
-                return -1;
+            if ((ret = bink_decode_plane(c, &gb, plane_idx, !!plane)) < 0)
+                return ret;
         } else {
-            if (binkb_decode_plane(c, &gb, plane_idx, !pkt->pts, !!plane) < 0)
-                return -1;
+            if ((ret = binkb_decode_plane(c, &gb, plane_idx,
+                                          !avctx->frame_number, !!plane)) < 0)
+                return ret;
         }
         if (get_bits_count(&gb) >= bits_count)
             break;
     }
     emms_c();
 
-    *data_size = sizeof(AVFrame);
-    *(AVFrame*)data = c->pic;
+    *got_frame = 1;
+    *(AVFrame*)data = *c->pic;
 
     if (c->version > 'b')
-        FFSWAP(AVFrame, c->pic, c->last);
+        FFSWAP(AVFrame*, c->pic, c->last);
 
     /* always report that the buffer was completely consumed */
     return pkt->size;
@@ -1263,13 +1270,13 @@
     BinkContext * const c = avctx->priv_data;
     static VLC_TYPE table[16 * 128][2];
     static int binkb_initialised = 0;
-    int i;
+    int i, ret;
     int flags;
 
     c->version = avctx->codec_tag >> 24;
     if (avctx->extradata_size < 4) {
         av_log(avctx, AV_LOG_ERROR, "Extradata missing or too short\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     flags = AV_RL32(avctx->extradata);
     c->has_alpha = flags & BINK_FLAG_ALPHA;
@@ -1286,19 +1293,26 @@
     }
     c->avctx = avctx;
 
-    c->pic.data[0] = NULL;
-
-    if (av_image_check_size(avctx->width, avctx->height, 0, avctx) < 0) {
-        return 1;
+    c->pic  = avcodec_alloc_frame();
+    c->last = avcodec_alloc_frame();
+    if (!c->pic || !c->last) {
+        avcodec_free_frame(&c->pic);
+        avcodec_free_frame(&c->last);
+        return AVERROR(ENOMEM);
     }
 
+    if ((ret = av_image_check_size(avctx->width, avctx->height, 0, avctx)) < 0)
+        return ret;
+
     avctx->pix_fmt = c->has_alpha ? AV_PIX_FMT_YUVA420P : AV_PIX_FMT_YUV420P;
 
-    avctx->idct_algo = FF_IDCT_BINK;
     ff_dsputil_init(&c->dsp, avctx);
     ff_binkdsp_init(&c->bdsp);
 
-    init_bundles(c);
+    if ((ret = init_bundles(c)) < 0) {
+        free_bundles(c);
+        return ret;
+    }
 
     if (c->version == 'b') {
         if (!binkb_initialised) {
@@ -1314,10 +1328,12 @@
 {
     BinkContext * const c = avctx->priv_data;
 
-    if (c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
-    if (c->last.data[0])
-        avctx->release_buffer(avctx, &c->last);
+    if (c->pic->data[0])
+        avctx->release_buffer(avctx, c->pic);
+    if (c->last->data[0])
+        avctx->release_buffer(avctx, c->last);
+    avcodec_free_frame(&c->pic);
+    avcodec_free_frame(&c->last);
 
     free_bundles(c);
     return 0;
diff --git a/libavcodec/binkaudio.c b/libavcodec/binkaudio.c
index a1a91eb..5ba77a6 100644
--- a/libavcodec/binkaudio.c
+++ b/libavcodec/binkaudio.c
@@ -32,10 +32,10 @@
 #include "avcodec.h"
 #define BITSTREAM_READER_LE
 #include "get_bits.h"
-#include "dsputil.h"
 #include "dct.h"
 #include "rdft.h"
 #include "fmtconvert.h"
+#include "internal.h"
 #include "libavutil/intfloat.h"
 
 extern const uint16_t ff_wma_critical_freqs[25];
@@ -46,7 +46,6 @@
 #define BINK_BLOCK_MAX_SIZE (MAX_CHANNELS << 11)
 
 typedef struct {
-    AVFrame frame;
     GetBitContext gb;
     int version_b;          ///< Bink version 'b'
     int first;
@@ -142,9 +141,6 @@
     else
         return -1;
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     return 0;
 }
 
@@ -293,6 +289,7 @@
                         int *got_frame_ptr, AVPacket *avpkt)
 {
     BinkAudioContext *s = avctx->priv_data;
+    AVFrame *frame      = data;
     GetBitContext *gb = &s->gb;
     int ret, consumed = 0;
 
@@ -320,22 +317,21 @@
     }
 
     /* get output buffer */
-    s->frame.nb_samples = s->frame_len;
-    if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = s->frame_len;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
 
-    if (decode_block(s, (float **)s->frame.extended_data,
+    if (decode_block(s, (float **)frame->extended_data,
                      avctx->codec->id == AV_CODEC_ID_BINKAUDIO_DCT)) {
         av_log(avctx, AV_LOG_ERROR, "Incomplete packet\n");
         return AVERROR_INVALIDDATA;
     }
     get_bits_align32(gb);
 
-    s->frame.nb_samples = s->block_size / avctx->channels;
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
+    frame->nb_samples = s->block_size / avctx->channels;
+    *got_frame_ptr    = 1;
 
     return consumed;
 }
diff --git a/libavcodec/binkdsp.h b/libavcodec/binkdsp.h
index d105f71..4968413 100644
--- a/libavcodec/binkdsp.h
+++ b/libavcodec/binkdsp.h
@@ -27,7 +27,7 @@
 #ifndef AVCODEC_BINKDSP_H
 #define AVCODEC_BINKDSP_H
 
-#include "dsputil.h"
+#include <stdint.h>
 
 typedef struct BinkDSPContext {
     void (*idct_put)(uint8_t *dest/*align 8*/, int line_size, int32_t *block/*align 16*/);
diff --git a/libavcodec/bintext.c b/libavcodec/bintext.c
index 9c36b6b..1c9bc3e 100644
--- a/libavcodec/bintext.c
+++ b/libavcodec/bintext.c
@@ -129,7 +129,7 @@
 }
 
 static int decode_frame(AVCodecContext *avctx,
-                            void *data, int *data_size,
+                            void *data, int *got_frame,
                             AVPacket *avpkt)
 {
     XbinContext *s = avctx->priv_data;
@@ -201,7 +201,7 @@
         }
     }
 
-    *data_size = sizeof(AVFrame);
+    *got_frame      = 1;
     *(AVFrame*)data = s->frame;
     return buf_size;
 }
diff --git a/libavcodec/bit_depth_template.c b/libavcodec/bit_depth_template.c
index 6b757fc..1a6d007 100644
--- a/libavcodec/bit_depth_template.c
+++ b/libavcodec/bit_depth_template.c
@@ -16,7 +16,8 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "dsputil.h"
+#include "rnd_avg.h"
+#include "libavutil/intreadwrite.h"
 
 #ifndef BIT_DEPTH
 #define BIT_DEPTH 8
diff --git a/libavcodec/bitstream.c b/libavcodec/bitstream.c
index ce83ee0..6bcdadb 100644
--- a/libavcodec/bitstream.c
+++ b/libavcodec/bitstream.c
@@ -172,7 +172,7 @@
         table[i][0] = -1; //codes
     }
 
-    /* first pass: map codes and compute auxillary table sizes */
+    /* first pass: map codes and compute auxiliary table sizes */
     for (i = 0; i < nb_codes; i++) {
         n = codes[i].bits;
         code = codes[i].code;
@@ -270,11 +270,24 @@
 
     vlc->bits = nb_bits;
     if(flags & INIT_VLC_USE_NEW_STATIC){
-        if(vlc->table_size && vlc->table_size == vlc->table_allocated){
+        VLC dyn_vlc = *vlc;
+
+        if (vlc->table_size)
             return 0;
-        }else if(vlc->table_size){
-            abort(); // fatal error, we are called on a partially initialized table
-        }
+
+        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;
         vlc->table_allocated = 0;
@@ -316,8 +329,6 @@
         av_freep(&vlc->table);
         return -1;
     }
-    if((flags & INIT_VLC_USE_NEW_STATIC) && vlc->table_size != vlc->table_allocated)
-        av_log(NULL, AV_LOG_ERROR, "needed %d had %d\n", vlc->table_size, vlc->table_allocated);
     return 0;
 }
 
diff --git a/libavcodec/bmp.c b/libavcodec/bmp.c
index 9aee375..fb69396 100644
--- a/libavcodec/bmp.c
+++ b/libavcodec/bmp.c
@@ -22,9 +22,11 @@
 #include "avcodec.h"
 #include "bytestream.h"
 #include "bmp.h"
+#include "internal.h"
 #include "msrledec.h"
 
-static av_cold int bmp_decode_init(AVCodecContext *avctx){
+static av_cold int bmp_decode_init(AVCodecContext *avctx)
+{
     BMPContext *s = avctx->priv_data;
 
     avcodec_get_frame_defaults(&s->picture);
@@ -34,40 +36,40 @@
 }
 
 static int bmp_decode_frame(AVCodecContext *avctx,
-                            void *data, int *data_size,
+                            void *data, int *got_frame,
                             AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
-    BMPContext *s = avctx->priv_data;
-    AVFrame *picture = data;
-    AVFrame *p = &s->picture;
+    int buf_size       = avpkt->size;
+    BMPContext *s      = avctx->priv_data;
+    AVFrame *picture   = data;
+    AVFrame *p         = &s->picture;
     unsigned int fsize, hsize;
     int width, height;
     unsigned int depth;
     BiCompression comp;
     unsigned int ihsize;
-    int i, j, n, linesize;
-    uint32_t rgb[3];
+    int i, j, n, linesize, ret;
+    uint32_t rgb[3] = {0};
     uint32_t alpha = 0;
     uint8_t *ptr;
     int dsize;
     const uint8_t *buf0 = buf;
     GetByteContext gb;
 
-    if(buf_size < 14){
+    if (buf_size < 14) {
         av_log(avctx, AV_LOG_ERROR, "buf size too small (%d)\n", buf_size);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
-    if(bytestream_get_byte(&buf) != 'B' ||
-       bytestream_get_byte(&buf) != 'M') {
+    if (bytestream_get_byte(&buf) != 'B' ||
+        bytestream_get_byte(&buf) != 'M') {
         av_log(avctx, AV_LOG_ERROR, "bad magic number\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     fsize = bytestream_get_le32(&buf);
-    if(buf_size < fsize){
+    if (buf_size < fsize) {
         av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %d), trying to decode anyway\n",
                buf_size, fsize);
         fsize = buf_size;
@@ -76,30 +78,30 @@
     buf += 2; /* reserved1 */
     buf += 2; /* reserved2 */
 
-    hsize = bytestream_get_le32(&buf); /* header size */
-    ihsize = bytestream_get_le32(&buf);       /* more header size */
-    if(ihsize + 14 > hsize){
+    hsize  = bytestream_get_le32(&buf); /* header size */
+    ihsize = bytestream_get_le32(&buf); /* more header size */
+    if (ihsize + 14 > hsize) {
         av_log(avctx, AV_LOG_ERROR, "invalid header size %d\n", hsize);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     /* sometimes file size is set to some headers size, set a real size in that case */
-    if(fsize == 14 || fsize == ihsize + 14)
+    if (fsize == 14 || fsize == ihsize + 14)
         fsize = buf_size - 2;
 
-    if(fsize <= hsize){
+    if (fsize <= hsize) {
         av_log(avctx, AV_LOG_ERROR, "declared file size is less than header size (%d < %d)\n",
                fsize, hsize);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
-    switch(ihsize){
+    switch (ihsize) {
     case  40: // windib
     case  56: // windib v3
     case  64: // OS/2 v2
     case 108: // windib v4
     case 124: // windib v5
-        width = bytestream_get_le32(&buf);
+        width  = bytestream_get_le32(&buf);
         height = bytestream_get_le32(&buf);
         break;
     case  12: // OS/2 v1
@@ -108,12 +110,13 @@
         break;
     default:
         av_log(avctx, AV_LOG_ERROR, "unsupported BMP file, patch welcome\n");
-        return -1;
+        return AVERROR_PATCHWELCOME;
     }
 
-    if(bytestream_get_le16(&buf) != 1){ /* planes */
+    /* planes */
+    if (bytestream_get_le16(&buf) != 1) {
         av_log(avctx, AV_LOG_ERROR, "invalid BMP header\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     depth = bytestream_get_le16(&buf);
@@ -123,12 +126,13 @@
     else
         comp = BMP_RGB;
 
-    if(comp != BMP_RGB && comp != BMP_BITFIELDS && comp != BMP_RLE4 && comp != BMP_RLE8){
+    if (comp != BMP_RGB && comp != BMP_BITFIELDS && comp != BMP_RLE4 &&
+        comp != BMP_RLE8) {
         av_log(avctx, AV_LOG_ERROR, "BMP coding %d not supported\n", comp);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
-    if(comp == BMP_BITFIELDS){
+    if (comp == BMP_BITFIELDS) {
         buf += 20;
         rgb[0] = bytestream_get_le32(&buf);
         rgb[1] = bytestream_get_le32(&buf);
@@ -136,14 +140,14 @@
         alpha = bytestream_get_le32(&buf);
     }
 
-    avctx->width = width;
-    avctx->height = height > 0? height: -height;
+    avctx->width  = width;
+    avctx->height = height > 0 ? height : -height;
 
     avctx->pix_fmt = AV_PIX_FMT_NONE;
 
-    switch(depth){
+    switch (depth) {
     case 32:
-        if(comp == BMP_BITFIELDS){
+        if (comp == BMP_BITFIELDS) {
             if (rgb[0] == 0xFF000000 && rgb[1] == 0x00FF0000 && rgb[2] == 0x0000FF00)
                 avctx->pix_fmt = alpha ? AV_PIX_FMT_ABGR : AV_PIX_FMT_0BGR;
             else if (rgb[0] == 0x00FF0000 && rgb[1] == 0x0000FF00 && rgb[2] == 0x000000FF)
@@ -164,7 +168,7 @@
         avctx->pix_fmt = AV_PIX_FMT_BGR24;
         break;
     case 16:
-        if(comp == BMP_RGB)
+        if (comp == BMP_RGB)
             avctx->pix_fmt = AV_PIX_FMT_RGB555;
         else if (comp == BMP_BITFIELDS) {
             if (rgb[0] == 0xF800 && rgb[1] == 0x07E0 && rgb[2] == 0x001F)
@@ -180,103 +184,108 @@
         }
         break;
     case 8:
-        if(hsize - ihsize - 14 > 0)
+        if (hsize - ihsize - 14 > 0)
             avctx->pix_fmt = AV_PIX_FMT_PAL8;
         else
             avctx->pix_fmt = AV_PIX_FMT_GRAY8;
         break;
     case 1:
     case 4:
-        if(hsize - ihsize - 14 > 0){
+        if (hsize - ihsize - 14 > 0) {
             avctx->pix_fmt = AV_PIX_FMT_PAL8;
-        }else{
+        } else {
             av_log(avctx, AV_LOG_ERROR, "Unknown palette for %d-colour BMP\n", 1<<depth);
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
         break;
     default:
         av_log(avctx, AV_LOG_ERROR, "depth %d not supported\n", depth);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
-    if(avctx->pix_fmt == AV_PIX_FMT_NONE){
+    if (avctx->pix_fmt == AV_PIX_FMT_NONE) {
         av_log(avctx, AV_LOG_ERROR, "unsupported pixel format\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
-    if(p->data[0])
+    if (p->data[0])
         avctx->release_buffer(avctx, p);
 
     p->reference = 0;
-    if(avctx->get_buffer(avctx, p) < 0){
+    if ((ret = ff_get_buffer(avctx, p)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
     p->pict_type = AV_PICTURE_TYPE_I;
     p->key_frame = 1;
 
-    buf = buf0 + hsize;
+    buf   = buf0 + hsize;
     dsize = buf_size - hsize;
 
     /* Line size in file multiple of 4 */
     n = ((avctx->width * depth + 31) / 8) & ~3;
 
-    if(n * avctx->height > dsize && comp != BMP_RLE4 && comp != BMP_RLE8){
+    if (n * avctx->height > dsize && comp != BMP_RLE4 && comp != BMP_RLE8) {
         av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %d)\n",
                dsize, n * avctx->height);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     // RLE may skip decoding some picture areas, so blank picture before decoding
-    if(comp == BMP_RLE4 || comp == BMP_RLE8)
+    if (comp == BMP_RLE4 || comp == BMP_RLE8)
         memset(p->data[0], 0, avctx->height * p->linesize[0]);
 
-    if(height > 0){
-        ptr = p->data[0] + (avctx->height - 1) * p->linesize[0];
+    if (height > 0) {
+        ptr      = p->data[0] + (avctx->height - 1) * p->linesize[0];
         linesize = -p->linesize[0];
     } else {
-        ptr = p->data[0];
+        ptr      = p->data[0];
         linesize = p->linesize[0];
     }
 
-    if(avctx->pix_fmt == AV_PIX_FMT_PAL8){
+    if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
         int colors = 1 << depth;
 
         memset(p->data[1], 0, 1024);
 
-        if(ihsize >= 36){
+        if (ihsize >= 36) {
             int t;
             buf = buf0 + 46;
-            t = bytestream_get_le32(&buf);
-            if(t < 0 || t > (1 << depth)){
+            t   = bytestream_get_le32(&buf);
+            if (t < 0 || t > (1 << depth)) {
                 av_log(avctx, AV_LOG_ERROR, "Incorrect number of colors - %X for bitdepth %d\n", t, depth);
-            }else if(t){
+            } else if (t) {
                 colors = t;
             }
         }
         buf = buf0 + 14 + ihsize; //palette location
-        if((hsize-ihsize-14) < (colors << 2)){ // OS/2 bitmap, 3 bytes per palette entry
-            for(i = 0; i < colors; i++)
+        // 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");
+                return AVERROR_INVALIDDATA;
+            }
+            for (i = 0; i < colors; i++)
                 ((uint32_t*)p->data[1])[i] = (0xFFU<<24) | bytestream_get_le24(&buf);
-        }else{
-            for(i = 0; i < colors; i++)
+        } else {
+            for (i = 0; i < colors; i++)
                 ((uint32_t*)p->data[1])[i] = 0xFFU << 24 | bytestream_get_le32(&buf);
         }
         buf = buf0 + hsize;
     }
-    if(comp == BMP_RLE4 || comp == BMP_RLE8){
-        if(height < 0){
-            p->data[0] += p->linesize[0] * (avctx->height - 1);
+    if (comp == BMP_RLE4 || comp == BMP_RLE8) {
+        if (height < 0) {
+            p->data[0]    +=  p->linesize[0] * (avctx->height - 1);
             p->linesize[0] = -p->linesize[0];
         }
         bytestream2_init(&gb, buf, dsize);
         ff_msrle_decode(avctx, (AVPicture*)p, depth, &gb);
-        if(height < 0){
-            p->data[0] += p->linesize[0] * (avctx->height - 1);
+        if (height < 0) {
+            p->data[0]    +=  p->linesize[0] * (avctx->height - 1);
             p->linesize[0] = -p->linesize[0];
         }
-    }else{
-        switch(depth){
+    } else {
+        switch (depth) {
         case 1:
             for (i = 0; i < avctx->height; i++) {
                 int j;
@@ -297,16 +306,16 @@
         case 8:
         case 24:
         case 32:
-            for(i = 0; i < avctx->height; i++){
+            for (i = 0; i < avctx->height; i++) {
                 memcpy(ptr, buf, n);
                 buf += n;
                 ptr += linesize;
             }
             break;
         case 4:
-            for(i = 0; i < avctx->height; i++){
+            for (i = 0; i < avctx->height; i++) {
                 int j;
-                for(j = 0; j < n; j++){
+                for (j = 0; j < n; j++) {
                     ptr[j*2+0] = (buf[j] >> 4) & 0xF;
                     ptr[j*2+1] = buf[j] & 0xF;
                 }
@@ -315,11 +324,11 @@
             }
             break;
         case 16:
-            for(i = 0; i < avctx->height; i++){
+            for (i = 0; i < avctx->height; i++) {
                 const uint16_t *src = (const uint16_t *) buf;
-                uint16_t *dst = (uint16_t *) ptr;
+                uint16_t *dst       = (uint16_t *) ptr;
 
-                for(j = 0; j < avctx->width; j++)
+                for (j = 0; j < avctx->width; j++)
                     *dst++ = av_le2ne16(*src++);
 
                 buf += n;
@@ -328,12 +337,12 @@
             break;
         default:
             av_log(avctx, AV_LOG_ERROR, "BMP decoder is broken\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
     }
 
     *picture = s->picture;
-    *data_size = sizeof(AVPicture);
+    *got_frame = 1;
 
     return buf_size;
 }
diff --git a/libavcodec/bmv.c b/libavcodec/bmv.c
index fa44c6c..c480815 100644
--- a/libavcodec/bmv.c
+++ b/libavcodec/bmv.c
@@ -19,10 +19,11 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/avassert.h"
 #include "libavutil/channel_layout.h"
 #include "avcodec.h"
 #include "bytestream.h"
-#include "libavutil/avassert.h"
+#include "internal.h"
 
 enum BMVFlags{
     BMV_NOP = 0,
@@ -67,7 +68,7 @@
     int i;
 
     if (src_len <= 0)
-        return -1;
+        return AVERROR_INVALIDDATA;
 
     if (forward) {
         src = source;
@@ -91,7 +92,7 @@
          */
         if (!mode || (tmplen == 4)) {
             if (src < source || src >= source_end)
-                return -1;
+                return AVERROR_INVALIDDATA;
             val = *src;
             read_two_nibbles = 1;
         } else {
@@ -104,7 +105,7 @@
                     return -1;
                 if (!read_two_nibbles) {
                     if (src < source || src >= source_end)
-                        return -1;
+                        return AVERROR_INVALIDDATA;
                     shift += 2;
                     val |= *src << shift;
                     if (*src & 0xC)
@@ -140,7 +141,7 @@
         if (mode >= 4)
             mode -= 3;
         if (FFABS(dst_end - dst) < len)
-            return -1;
+            return AVERROR_INVALIDDATA;
         switch (mode) {
         case 1:
             if (forward) {
@@ -148,7 +149,7 @@
                         dst - frame + SCREEN_WIDE + frame_off < 0 ||
                         frame_end - dst < frame_off + len ||
                         frame_end - dst < len)
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 for (i = 0; i < len; i++)
                     dst[i] = dst[frame_off + i];
                 dst += len;
@@ -158,7 +159,7 @@
                         dst - frame + SCREEN_WIDE + frame_off < 0 ||
                         frame_end - dst < frame_off + len ||
                         frame_end - dst < len)
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 for (i = len - 1; i >= 0; i--)
                     dst[i] = dst[frame_off + i];
             }
@@ -166,13 +167,13 @@
         case 2:
             if (forward) {
                 if (source + src_len - src < len)
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 memcpy(dst, src, len);
                 dst += len;
                 src += len;
             } else {
                 if (src - source < len)
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 dst -= len;
                 src -= len;
                 memcpy(dst, src, len);
@@ -195,7 +196,8 @@
     return 0;
 }
 
-static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *pkt)
+static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
+                        AVPacket *pkt)
 {
     BMVDecContext * const c = avctx->priv_data;
     int type, scr_off;
@@ -244,7 +246,7 @@
         avctx->release_buffer(avctx, &c->pic);
 
     c->pic.reference = 3;
-    if ((ret = avctx->get_buffer(avctx, &c->pic)) < 0) {
+    if ((ret = ff_get_buffer(avctx, &c->pic)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -266,7 +268,7 @@
         outptr += c->pic.linesize[0];
     }
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*)data = c->pic;
 
     /* always report that the buffer was completely consumed */
@@ -300,32 +302,23 @@
     return 0;
 }
 
-typedef struct BMVAudioDecContext {
-    AVFrame frame;
-} BMVAudioDecContext;
-
 static const int bmv_aud_mults[16] = {
     16512, 8256, 4128, 2064, 1032, 516, 258, 192, 129, 88, 64, 56, 48, 40, 36, 32
 };
 
 static av_cold int bmv_aud_decode_init(AVCodecContext *avctx)
 {
-    BMVAudioDecContext *c = avctx->priv_data;
-
     avctx->channels       = 2;
     avctx->channel_layout = AV_CH_LAYOUT_STEREO;
     avctx->sample_fmt     = AV_SAMPLE_FMT_S16;
 
-    avcodec_get_frame_defaults(&c->frame);
-    avctx->coded_frame = &c->frame;
-
     return 0;
 }
 
 static int bmv_aud_decode_frame(AVCodecContext *avctx, void *data,
                                 int *got_frame_ptr, AVPacket *avpkt)
 {
-    BMVAudioDecContext *c = avctx->priv_data;
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     int blocks = 0, total_blocks, i;
@@ -341,12 +334,12 @@
     }
 
     /* get output buffer */
-    c->frame.nb_samples = total_blocks * 32;
-    if ((ret = avctx->get_buffer(avctx, &c->frame)) < 0) {
+    frame->nb_samples = total_blocks * 32;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    output_samples = (int16_t *)c->frame.data[0];
+    output_samples = (int16_t *)frame->data[0];
 
     for (blocks = 0; blocks < total_blocks; blocks++) {
         uint8_t code = *buf++;
@@ -359,8 +352,7 @@
         }
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = c->frame;
+    *got_frame_ptr = 1;
 
     return buf_size;
 }
@@ -381,7 +373,6 @@
     .name           = "bmv_audio",
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_BMV_AUDIO,
-    .priv_data_size = sizeof(BMVAudioDecContext),
     .init           = bmv_aud_decode_init,
     .decode         = bmv_aud_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
diff --git a/libavcodec/brender_pix.c b/libavcodec/brender_pix.c
index 886e8fb..6c63244 100644
--- a/libavcodec/brender_pix.c
+++ b/libavcodec/brender_pix.c
@@ -28,6 +28,7 @@
 #include "libavutil/imgutils.h"
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 
 typedef struct BRPixContext {
     AVFrame frame;
@@ -69,7 +70,7 @@
 }
 
 static int brpix_decode_frame(AVCodecContext *avctx,
-                              void *data, int *data_size_out,
+                              void *data, int *got_frame,
                               AVPacket *avpkt)
 {
     BRPixContext *s = avctx->priv_data;
@@ -151,7 +152,7 @@
     if (hdr.width != avctx->width || hdr.height != avctx->height)
         avcodec_set_dimensions(avctx, hdr.width, hdr.height);
 
-    if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -192,6 +193,14 @@
         s->frame.palette_has_changed = 1;
 
         chunk_type = bytestream2_get_be32(&gb);
+    } else if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
+        uint32_t *pal_out = (uint32_t *)s->frame.data[1];
+        int i;
+
+        for (i = 0; i < 256; ++i) {
+            *pal_out++ = (0xFFU << 24) | (i * 0x010101);
+        }
+        s->frame.palette_has_changed = 1;
     }
 
     data_len = bytestream2_get_be32(&gb);
@@ -216,7 +225,7 @@
     }
 
     *frame_out = s->frame;
-    *data_size_out = sizeof(AVFrame);
+    *got_frame = 1;
 
     return avpkt->size;
 }
diff --git a/libavcodec/c93.c b/libavcodec/c93.c
index b53ee1b..e5f371b 100644
--- a/libavcodec/c93.c
+++ b/libavcodec/c93.c
@@ -117,7 +117,7 @@
 }
 
 static int decode_frame(AVCodecContext *avctx, void *data,
-                            int *data_size, AVPacket *avpkt)
+                        int *got_frame, AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
@@ -134,7 +134,7 @@
     newpic->reference = 3;
     newpic->buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE |
                          FF_BUFFER_HINTS_REUSABLE | FF_BUFFER_HINTS_READABLE;
-    if ((ret = avctx->reget_buffer(avctx, newpic))) {
+    if ((ret = avctx->reget_buffer(avctx, newpic)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
         return ret;
     }
@@ -166,8 +166,8 @@
             switch (block_type) {
             case C93_8X8_FROM_PREV:
                 offset = bytestream2_get_le16(&gb);
-                if (copy_block(avctx, out, copy_from, offset, 8, stride))
-                    return AVERROR_INVALIDDATA;
+                if ((ret = copy_block(avctx, out, copy_from, offset, 8, stride)) < 0)
+                    return ret;
                 break;
 
             case C93_4X4_FROM_CURR:
@@ -176,9 +176,9 @@
                 for (j = 0; j < 8; j += 4) {
                     for (i = 0; i < 8; i += 4) {
                         offset = bytestream2_get_le16(&gb);
-                        if (copy_block(avctx, &out[j*stride+i],
-                                           copy_from, offset, 4, stride))
-                            return AVERROR_INVALIDDATA;
+                        if ((ret = copy_block(avctx, &out[j*stride+i],
+                                              copy_from, offset, 4, stride)) < 0)
+                            return ret;
                     }
                 }
                 break;
@@ -237,13 +237,14 @@
         for (i = 0; i < 256; i++) {
             palette[i] = 0xFFU << 24 | bytestream2_get_be24(&gb);
         }
+        newpic->palette_has_changed = 1;
     } else {
         if (oldpic->data[1])
             memcpy(newpic->data[1], oldpic->data[1], 256 * 4);
     }
 
     *picture = *newpic;
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
 
     return buf_size;
 }
diff --git a/libavcodec/cavs.c b/libavcodec/cavs.c
index 65e12dd..adf0eca 100644
--- a/libavcodec/cavs.c
+++ b/libavcodec/cavs.c
@@ -28,6 +28,7 @@
 #include "avcodec.h"
 #include "get_bits.h"
 #include "golomb.h"
+#include "h264chroma.h"
 #include "mathops.h"
 #include "cavs.h"
 
@@ -67,27 +68,28 @@
  *
  ****************************************************************************/
 
-static inline int get_bs(cavs_vector *mvP, cavs_vector *mvQ, int b) {
-    if((mvP->ref == REF_INTRA) || (mvQ->ref == REF_INTRA))
+static inline int get_bs(cavs_vector *mvP, cavs_vector *mvQ, int b)
+{
+    if ((mvP->ref == REF_INTRA) || (mvQ->ref == REF_INTRA))
         return 2;
-    if( (abs(mvP->x - mvQ->x) >= 4) ||  (abs(mvP->y - mvQ->y) >= 4) )
+    if ((abs(mvP->x - mvQ->x) >= 4) || (abs(mvP->y - mvQ->y) >= 4))
         return 1;
-    if(b){
+    if (b) {
         mvP += MV_BWD_OFFS;
         mvQ += MV_BWD_OFFS;
-        if( (abs(mvP->x - mvQ->x) >= 4) ||  (abs(mvP->y - mvQ->y) >= 4) )
+        if ((abs(mvP->x - mvQ->x) >= 4) ||  (abs(mvP->y - mvQ->y) >= 4))
             return 1;
-    }else{
-        if(mvP->ref != mvQ->ref)
+    } else {
+        if (mvP->ref != mvQ->ref)
             return 1;
     }
     return 0;
 }
 
-#define SET_PARAMS                                            \
-    alpha = alpha_tab[av_clip(qp_avg + h->alpha_offset,0,63)];   \
-    beta  =  beta_tab[av_clip(qp_avg + h->beta_offset, 0,63)];   \
-    tc    =    tc_tab[av_clip(qp_avg + h->alpha_offset,0,63)];
+#define SET_PARAMS                                                \
+    alpha = alpha_tab[av_clip(qp_avg + h->alpha_offset, 0, 63)];  \
+    beta  =  beta_tab[av_clip(qp_avg + h->beta_offset,  0, 63)];  \
+    tc    =    tc_tab[av_clip(qp_avg + h->alpha_offset, 0, 63)];
 
 /**
  * in-loop deblocking filter for a single macroblock
@@ -101,35 +103,36 @@
  * ---------
  *
  */
-void ff_cavs_filter(AVSContext *h, enum cavs_mb mb_type) {
+void ff_cavs_filter(AVSContext *h, enum cavs_mb mb_type)
+{
     uint8_t bs[8];
     int qp_avg, alpha, beta, tc;
     int i;
 
     /* save un-deblocked lines */
-    h->topleft_border_y = h->top_border_y[h->mbx*16+15];
-    h->topleft_border_u = h->top_border_u[h->mbx*10+8];
-    h->topleft_border_v = h->top_border_v[h->mbx*10+8];
-    memcpy(&h->top_border_y[h->mbx*16], h->cy + 15* h->l_stride,16);
-    memcpy(&h->top_border_u[h->mbx*10+1], h->cu +  7* h->c_stride,8);
-    memcpy(&h->top_border_v[h->mbx*10+1], h->cv +  7* h->c_stride,8);
-    for(i=0;i<8;i++) {
-        h->left_border_y[i*2+1] = *(h->cy + 15 + (i*2+0)*h->l_stride);
-        h->left_border_y[i*2+2] = *(h->cy + 15 + (i*2+1)*h->l_stride);
-        h->left_border_u[i+1] = *(h->cu + 7 + i*h->c_stride);
-        h->left_border_v[i+1] = *(h->cv + 7 + i*h->c_stride);
+    h->topleft_border_y = h->top_border_y[h->mbx * 16 + 15];
+    h->topleft_border_u = h->top_border_u[h->mbx * 10 + 8];
+    h->topleft_border_v = h->top_border_v[h->mbx * 10 + 8];
+    memcpy(&h->top_border_y[h->mbx * 16],     h->cy + 15 * h->l_stride, 16);
+    memcpy(&h->top_border_u[h->mbx * 10 + 1], h->cu +  7 * h->c_stride, 8);
+    memcpy(&h->top_border_v[h->mbx * 10 + 1], h->cv +  7 * h->c_stride, 8);
+    for (i = 0; i < 8; i++) {
+        h->left_border_y[i * 2 + 1] = *(h->cy + 15 + (i * 2 + 0) * h->l_stride);
+        h->left_border_y[i * 2 + 2] = *(h->cy + 15 + (i * 2 + 1) * h->l_stride);
+        h->left_border_u[i + 1]     = *(h->cu + 7  +  i          * h->c_stride);
+        h->left_border_v[i + 1]     = *(h->cv + 7  +  i          * h->c_stride);
     }
-    if(!h->loop_filter_disable) {
+    if (!h->loop_filter_disable) {
         /* determine bs */
-        if(mb_type == I_8X8)
-            memset(bs,2,8);
+        if (mb_type == I_8X8)
+            memset(bs, 2, 8);
         else{
-            memset(bs,0,8);
-            if(ff_cavs_partition_flags[mb_type] & SPLITV){
+            memset(bs, 0, 8);
+            if (ff_cavs_partition_flags[mb_type] & SPLITV) {
                 bs[2] = get_bs(&h->mv[MV_FWD_X0], &h->mv[MV_FWD_X1], mb_type > P_8X8);
                 bs[3] = get_bs(&h->mv[MV_FWD_X2], &h->mv[MV_FWD_X3], mb_type > P_8X8);
             }
-            if(ff_cavs_partition_flags[mb_type] & SPLITH){
+            if (ff_cavs_partition_flags[mb_type] & SPLITH) {
                 bs[6] = get_bs(&h->mv[MV_FWD_X0], &h->mv[MV_FWD_X2], mb_type > P_8X8);
                 bs[7] = get_bs(&h->mv[MV_FWD_X1], &h->mv[MV_FWD_X3], mb_type > P_8X8);
             }
@@ -138,30 +141,29 @@
             bs[4] = get_bs(&h->mv[MV_FWD_B2], &h->mv[MV_FWD_X0], mb_type > P_8X8);
             bs[5] = get_bs(&h->mv[MV_FWD_B3], &h->mv[MV_FWD_X1], mb_type > P_8X8);
         }
-        if(AV_RN64(bs)) {
-            if(h->flags & A_AVAIL) {
+        if (AV_RN64(bs)) {
+            if (h->flags & A_AVAIL) {
                 qp_avg = (h->qp + h->left_qp + 1) >> 1;
                 SET_PARAMS;
-                h->cdsp.cavs_filter_lv(h->cy,h->l_stride,alpha,beta,tc,bs[0],bs[1]);
-                h->cdsp.cavs_filter_cv(h->cu,h->c_stride,alpha,beta,tc,bs[0],bs[1]);
-                h->cdsp.cavs_filter_cv(h->cv,h->c_stride,alpha,beta,tc,bs[0],bs[1]);
+                h->cdsp.cavs_filter_lv(h->cy, h->l_stride, alpha, beta, tc, bs[0], bs[1]);
+                h->cdsp.cavs_filter_cv(h->cu, h->c_stride, alpha, beta, tc, bs[0], bs[1]);
+                h->cdsp.cavs_filter_cv(h->cv, h->c_stride, alpha, beta, tc, bs[0], bs[1]);
             }
             qp_avg = h->qp;
             SET_PARAMS;
-            h->cdsp.cavs_filter_lv(h->cy + 8,h->l_stride,alpha,beta,tc,bs[2],bs[3]);
-            h->cdsp.cavs_filter_lh(h->cy + 8*h->l_stride,h->l_stride,alpha,beta,tc,
-                           bs[6],bs[7]);
+            h->cdsp.cavs_filter_lv(h->cy + 8,               h->l_stride, alpha, beta, tc, bs[2], bs[3]);
+            h->cdsp.cavs_filter_lh(h->cy + 8 * h->l_stride, h->l_stride, alpha, beta, tc, bs[6], bs[7]);
 
-            if(h->flags & B_AVAIL) {
+            if (h->flags & B_AVAIL) {
                 qp_avg = (h->qp + h->top_qp[h->mbx] + 1) >> 1;
                 SET_PARAMS;
-                h->cdsp.cavs_filter_lh(h->cy,h->l_stride,alpha,beta,tc,bs[4],bs[5]);
-                h->cdsp.cavs_filter_ch(h->cu,h->c_stride,alpha,beta,tc,bs[4],bs[5]);
-                h->cdsp.cavs_filter_ch(h->cv,h->c_stride,alpha,beta,tc,bs[4],bs[5]);
+                h->cdsp.cavs_filter_lh(h->cy, h->l_stride, alpha, beta, tc, bs[4], bs[5]);
+                h->cdsp.cavs_filter_ch(h->cu, h->c_stride, alpha, beta, tc, bs[4], bs[5]);
+                h->cdsp.cavs_filter_ch(h->cv, h->c_stride, alpha, beta, tc, bs[4], bs[5]);
             }
         }
     }
-    h->left_qp = h->qp;
+    h->left_qp        = h->qp;
     h->top_qp[h->mbx] = h->qp;
 }
 
@@ -174,155 +176,166 @@
  ****************************************************************************/
 
 void ff_cavs_load_intra_pred_luma(AVSContext *h, uint8_t *top,
-                                        uint8_t **left, int block) {
+                                  uint8_t **left, int block)
+{
     int i;
 
-    switch(block) {
+    switch (block) {
     case 0:
-        *left = h->left_border_y;
+        *left               = h->left_border_y;
         h->left_border_y[0] = h->left_border_y[1];
-        memset(&h->left_border_y[17],h->left_border_y[16],9);
-        memcpy(&top[1],&h->top_border_y[h->mbx*16],16);
+        memset(&h->left_border_y[17], h->left_border_y[16], 9);
+        memcpy(&top[1], &h->top_border_y[h->mbx * 16], 16);
         top[17] = top[16];
-        top[0] = top[1];
-        if((h->flags & A_AVAIL) && (h->flags & B_AVAIL))
+        top[0]  = top[1];
+        if ((h->flags & A_AVAIL) && (h->flags & B_AVAIL))
             h->left_border_y[0] = top[0] = h->topleft_border_y;
         break;
     case 1:
         *left = h->intern_border_y;
-        for(i=0;i<8;i++)
-            h->intern_border_y[i+1] = *(h->cy + 7 + i*h->l_stride);
-        memset(&h->intern_border_y[9],h->intern_border_y[8],9);
+        for (i = 0; i < 8; i++)
+            h->intern_border_y[i + 1] = *(h->cy + 7 + i * h->l_stride);
+        memset(&h->intern_border_y[9], h->intern_border_y[8], 9);
         h->intern_border_y[0] = h->intern_border_y[1];
-        memcpy(&top[1],&h->top_border_y[h->mbx*16+8],8);
-        if(h->flags & C_AVAIL)
-            memcpy(&top[9],&h->top_border_y[(h->mbx + 1)*16],8);
+        memcpy(&top[1], &h->top_border_y[h->mbx * 16 + 8], 8);
+        if (h->flags & C_AVAIL)
+            memcpy(&top[9], &h->top_border_y[(h->mbx + 1) * 16], 8);
         else
-            memset(&top[9],top[8],9);
+            memset(&top[9], top[8], 9);
         top[17] = top[16];
-        top[0] = top[1];
-        if(h->flags & B_AVAIL)
-            h->intern_border_y[0] = top[0] = h->top_border_y[h->mbx*16+7];
+        top[0]  = top[1];
+        if (h->flags & B_AVAIL)
+            h->intern_border_y[0] = top[0] = h->top_border_y[h->mbx * 16 + 7];
         break;
     case 2:
         *left = &h->left_border_y[8];
-        memcpy(&top[1],h->cy + 7*h->l_stride,16);
+        memcpy(&top[1], h->cy + 7 * h->l_stride, 16);
         top[17] = top[16];
-        top[0] = top[1];
-        if(h->flags & A_AVAIL)
+        top[0]  = top[1];
+        if (h->flags & A_AVAIL)
             top[0] = h->left_border_y[8];
         break;
     case 3:
         *left = &h->intern_border_y[8];
-        for(i=0;i<8;i++)
-            h->intern_border_y[i+9] = *(h->cy + 7 + (i+8)*h->l_stride);
-        memset(&h->intern_border_y[17],h->intern_border_y[16],9);
-        memcpy(&top[0],h->cy + 7 + 7*h->l_stride,9);
-        memset(&top[9],top[8],9);
+        for (i = 0; i < 8; i++)
+            h->intern_border_y[i + 9] = *(h->cy + 7 + (i + 8) * h->l_stride);
+        memset(&h->intern_border_y[17], h->intern_border_y[16], 9);
+        memcpy(&top[0], h->cy + 7 + 7 * h->l_stride, 9);
+        memset(&top[9], top[8], 9);
         break;
     }
 }
 
-void ff_cavs_load_intra_pred_chroma(AVSContext *h) {
+void ff_cavs_load_intra_pred_chroma(AVSContext *h)
+{
     /* extend borders by one pixel */
     h->left_border_u[9] = h->left_border_u[8];
     h->left_border_v[9] = h->left_border_v[8];
-    h->top_border_u[h->mbx*10+9] = h->top_border_u[h->mbx*10+8];
-    h->top_border_v[h->mbx*10+9] = h->top_border_v[h->mbx*10+8];
-    if(h->mbx && h->mby) {
-        h->top_border_u[h->mbx*10] = h->left_border_u[0] = h->topleft_border_u;
-        h->top_border_v[h->mbx*10] = h->left_border_v[0] = h->topleft_border_v;
+    h->top_border_u[h->mbx * 10 + 9] = h->top_border_u[h->mbx * 10 + 8];
+    h->top_border_v[h->mbx * 10 + 9] = h->top_border_v[h->mbx * 10 + 8];
+    if (h->mbx && h->mby) {
+        h->top_border_u[h->mbx * 10] = h->left_border_u[0] = h->topleft_border_u;
+        h->top_border_v[h->mbx * 10] = h->left_border_v[0] = h->topleft_border_v;
     } else {
         h->left_border_u[0] = h->left_border_u[1];
         h->left_border_v[0] = h->left_border_v[1];
-        h->top_border_u[h->mbx*10] = h->top_border_u[h->mbx*10+1];
-        h->top_border_v[h->mbx*10] = h->top_border_v[h->mbx*10+1];
+        h->top_border_u[h->mbx * 10] = h->top_border_u[h->mbx * 10 + 1];
+        h->top_border_v[h->mbx * 10] = h->top_border_v[h->mbx * 10 + 1];
     }
 }
 
-static void intra_pred_vert(uint8_t *d,uint8_t *top,uint8_t *left,int stride) {
+static void intra_pred_vert(uint8_t *d,uint8_t *top,uint8_t *left,int stride)
+{
     int y;
     uint64_t a = AV_RN64(&top[1]);
-    for(y=0;y<8;y++) {
-        *((uint64_t *)(d+y*stride)) = a;
+    for (y = 0; y < 8; y++) {
+        *((uint64_t *)(d + y * stride)) = a;
     }
 }
 
-static void intra_pred_horiz(uint8_t *d,uint8_t *top,uint8_t *left,int stride) {
+static void intra_pred_horiz(uint8_t *d,uint8_t *top,uint8_t *left,int stride)
+{
     int y;
     uint64_t a;
-    for(y=0;y<8;y++) {
-        a = left[y+1] * 0x0101010101010101ULL;
-        *((uint64_t *)(d+y*stride)) = a;
+    for (y = 0; y < 8; y++) {
+        a = left[y + 1] * 0x0101010101010101ULL;
+        *((uint64_t *)(d + y * stride)) = a;
     }
 }
 
-static void intra_pred_dc_128(uint8_t *d,uint8_t *top,uint8_t *left,int stride) {
+static void intra_pred_dc_128(uint8_t *d,uint8_t *top,uint8_t *left,int stride)
+{
     int y;
     uint64_t a = 0x8080808080808080ULL;
-    for(y=0;y<8;y++)
-        *((uint64_t *)(d+y*stride)) = a;
+    for (y = 0; y < 8; y++)
+        *((uint64_t *)(d + y * stride)) = a;
 }
 
-static void intra_pred_plane(uint8_t *d,uint8_t *top,uint8_t *left,int stride) {
-    int x,y,ia;
+static void intra_pred_plane(uint8_t *d,uint8_t *top,uint8_t *left,int stride)
+{
+    int x, y, ia;
     int ih = 0;
     int iv = 0;
     uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
 
-    for(x=0; x<4; x++) {
-        ih += (x+1)*(top[5+x]-top[3-x]);
-        iv += (x+1)*(left[5+x]-left[3-x]);
+    for (x = 0; x < 4; x++) {
+        ih += (x + 1) * (top [5 + x] - top [3 - x]);
+        iv += (x + 1) * (left[5 + x] - left[3 - x]);
     }
-    ia = (top[8]+left[8])<<4;
-    ih = (17*ih+16)>>5;
-    iv = (17*iv+16)>>5;
-    for(y=0; y<8; y++)
-        for(x=0; x<8; x++)
-            d[y*stride+x] = cm[(ia+(x-3)*ih+(y-3)*iv+16)>>5];
+    ia = (top[8] + left[8]) << 4;
+    ih = (17 * ih + 16) >> 5;
+    iv = (17 * iv + 16) >> 5;
+    for (y = 0; y < 8; y++)
+        for (x = 0; x < 8; x++)
+            d[y * stride + x] = cm[(ia + (x - 3) * ih + (y - 3) * iv + 16) >> 5];
 }
 
 #define LOWPASS(ARRAY,INDEX)                                            \
-    (( ARRAY[(INDEX)-1] + 2*ARRAY[(INDEX)] + ARRAY[(INDEX)+1] + 2) >> 2)
+    ((ARRAY[(INDEX) - 1] + 2 * ARRAY[(INDEX)] + ARRAY[(INDEX) + 1] + 2) >> 2)
 
-static void intra_pred_lp(uint8_t *d,uint8_t *top,uint8_t *left,int stride) {
-    int x,y;
-    for(y=0; y<8; y++)
-        for(x=0; x<8; x++)
-            d[y*stride+x] = (LOWPASS(top,x+1) + LOWPASS(left,y+1)) >> 1;
+static void intra_pred_lp(uint8_t *d,uint8_t *top,uint8_t *left,int stride)
+{
+    int x, y;
+    for (y = 0; y < 8; y++)
+        for (x = 0; x < 8; x++)
+            d[y * stride + x] = (LOWPASS(top, x + 1) + LOWPASS(left, y + 1)) >> 1;
 }
 
-static void intra_pred_down_left(uint8_t *d,uint8_t *top,uint8_t *left,int stride) {
-    int x,y;
-    for(y=0; y<8; y++)
-        for(x=0; x<8; x++)
-            d[y*stride+x] = (LOWPASS(top,x+y+2) + LOWPASS(left,x+y+2)) >> 1;
+static void intra_pred_down_left(uint8_t *d,uint8_t *top,uint8_t *left,int stride)
+{
+    int x, y;
+    for (y = 0; y < 8; y++)
+        for (x = 0; x < 8; x++)
+            d[y * stride + x] = (LOWPASS(top, x + y + 2) + LOWPASS(left, x + y + 2)) >> 1;
 }
 
-static void intra_pred_down_right(uint8_t *d,uint8_t *top,uint8_t *left,int stride) {
-    int x,y;
-    for(y=0; y<8; y++)
-        for(x=0; x<8; x++)
-            if(x==y)
-                d[y*stride+x] = (left[1]+2*top[0]+top[1]+2)>>2;
-            else if(x>y)
-                d[y*stride+x] = LOWPASS(top,x-y);
+static void intra_pred_down_right(uint8_t *d,uint8_t *top,uint8_t *left,int stride)
+{
+    int x, y;
+    for (y = 0; y < 8; y++)
+        for (x = 0; x < 8; x++)
+            if (x == y)
+                d[y * stride + x] = (left[1] + 2 * top[0] + top[1] + 2) >> 2;
+            else if (x > y)
+                d[y * stride + x] = LOWPASS(top, x - y);
             else
-                d[y*stride+x] = LOWPASS(left,y-x);
+                d[y * stride + x] = LOWPASS(left, y - x);
 }
 
-static void intra_pred_lp_left(uint8_t *d,uint8_t *top,uint8_t *left,int stride) {
-    int x,y;
-    for(y=0; y<8; y++)
-        for(x=0; x<8; x++)
-            d[y*stride+x] = LOWPASS(left,y+1);
+static void intra_pred_lp_left(uint8_t *d,uint8_t *top,uint8_t *left,int stride)
+{
+    int x, y;
+    for (y = 0; y < 8; y++)
+        for (x = 0; x < 8; x++)
+            d[y * stride + x] = LOWPASS(left, y + 1);
 }
 
-static void intra_pred_lp_top(uint8_t *d,uint8_t *top,uint8_t *left,int stride) {
-    int x,y;
-    for(y=0; y<8; y++)
-        for(x=0; x<8; x++)
-            d[y*stride+x] = LOWPASS(top,x+1);
+static void intra_pred_lp_top(uint8_t *d,uint8_t *top,uint8_t *left,int stride)
+{
+    int x, y;
+    for (y = 0; y < 8; y++)
+        for (x = 0; x < 8; x++)
+            d[y * stride + x] = LOWPASS(top, x + 1);
 }
 
 #undef LOWPASS
@@ -330,26 +343,27 @@
 static inline void modify_pred(const int8_t *mod_table, int *mode)
 {
     *mode = mod_table[*mode];
-    if(*mode < 0) {
+    if (*mode < 0) {
         av_log(NULL, AV_LOG_ERROR, "Illegal intra prediction mode\n");
         *mode = 0;
     }
 }
 
-void ff_cavs_modify_mb_i(AVSContext *h, int *pred_mode_uv) {
+void ff_cavs_modify_mb_i(AVSContext *h, int *pred_mode_uv)
+{
     /* save pred modes before they get modified */
     h->pred_mode_Y[3] =  h->pred_mode_Y[5];
     h->pred_mode_Y[6] =  h->pred_mode_Y[8];
-    h->top_pred_Y[h->mbx*2+0] = h->pred_mode_Y[7];
-    h->top_pred_Y[h->mbx*2+1] = h->pred_mode_Y[8];
+    h->top_pred_Y[h->mbx * 2 + 0] = h->pred_mode_Y[7];
+    h->top_pred_Y[h->mbx * 2 + 1] = h->pred_mode_Y[8];
 
     /* modify pred modes according to availability of neighbour samples */
-    if(!(h->flags & A_AVAIL)) {
+    if (!(h->flags & A_AVAIL)) {
         modify_pred(left_modifier_l, &h->pred_mode_Y[4]);
         modify_pred(left_modifier_l, &h->pred_mode_Y[7]);
         modify_pred(left_modifier_c, pred_mode_uv);
     }
-    if(!(h->flags & B_AVAIL)) {
+    if (!(h->flags & B_AVAIL)) {
         modify_pred(top_modifier_l, &h->pred_mode_Y[4]);
         modify_pred(top_modifier_l, &h->pred_mode_Y[5]);
         modify_pred(top_modifier_c, pred_mode_uv);
@@ -362,20 +376,19 @@
  *
  ****************************************************************************/
 
-static inline void mc_dir_part(AVSContext *h,Picture *pic,
+static inline void mc_dir_part(AVSContext *h, AVFrame *pic,
                                int chroma_height,int delta,int list,uint8_t *dest_y,
                                uint8_t *dest_cb,uint8_t *dest_cr,int src_x_offset,
                                int src_y_offset,qpel_mc_func *qpix_op,
                                h264_chroma_mc_func chroma_op,cavs_vector *mv)
 {
-    MpegEncContext * const s = &h->s;
     const int mx= mv->x + src_x_offset*8;
     const int my= mv->y + src_y_offset*8;
     const int luma_xy= (mx&3) + ((my&3)<<2);
-    uint8_t * src_y  = pic->f.data[0] + (mx >> 2) + (my >> 2) * h->l_stride;
-    uint8_t * src_cb = pic->f.data[1] + (mx >> 3) + (my >> 3) * h->c_stride;
-    uint8_t * src_cr = pic->f.data[2] + (mx >> 3) + (my >> 3) * h->c_stride;
-    int extra_width= 0; //(s->flags&CODEC_FLAG_EMU_EDGE) ? 0 : 16;
+    uint8_t * src_y  = pic->data[0] + (mx >> 2) + (my >> 2) * h->l_stride;
+    uint8_t * src_cb = pic->data[1] + (mx >> 3) + (my >> 3) * h->c_stride;
+    uint8_t * src_cr = pic->data[2] + (mx >> 3) + (my >> 3) * h->c_stride;
+    int extra_width = 0;
     int extra_height= extra_width;
     int emu=0;
     const int full_mx= mx>>2;
@@ -383,7 +396,7 @@
     const int pic_width  = 16*h->mb_width;
     const int pic_height = 16*h->mb_height;
 
-    if(!pic->f.data[0])
+    if (!pic->data[0])
         return;
     if(mx&7) extra_width -= 3;
     if(my&7) extra_height -= 3;
@@ -392,25 +405,25 @@
           || full_my < 0-extra_height
           || full_mx + 16/*FIXME*/ > pic_width + extra_width
           || full_my + 16/*FIXME*/ > pic_height + extra_height){
-        s->dsp.emulated_edge_mc(s->edge_emu_buffer, src_y - 2 - 2*h->l_stride, h->l_stride,
+        h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_y - 2 - 2*h->l_stride, h->l_stride,
                             16+5, 16+5/*FIXME*/, full_mx-2, full_my-2, pic_width, pic_height);
-        src_y= s->edge_emu_buffer + 2 + 2*h->l_stride;
+        src_y= h->edge_emu_buffer + 2 + 2*h->l_stride;
         emu=1;
     }
 
     qpix_op[luma_xy](dest_y, src_y, h->l_stride); //FIXME try variable height perhaps?
 
     if(emu){
-        s->dsp.emulated_edge_mc(s->edge_emu_buffer, src_cb, h->c_stride,
+        h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cb, h->c_stride,
                             9, 9/*FIXME*/, (mx>>3), (my>>3), pic_width>>1, pic_height>>1);
-        src_cb= s->edge_emu_buffer;
+        src_cb= h->edge_emu_buffer;
     }
     chroma_op(dest_cb, src_cb, h->c_stride, chroma_height, mx&7, my&7);
 
     if(emu){
-        s->dsp.emulated_edge_mc(s->edge_emu_buffer, src_cr, h->c_stride,
+        h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cr, h->c_stride,
                             9, 9/*FIXME*/, (mx>>3), (my>>3), pic_width>>1, pic_height>>1);
-        src_cr= s->edge_emu_buffer;
+        src_cr= h->edge_emu_buffer;
     }
     chroma_op(dest_cr, src_cr, h->c_stride, chroma_height, mx&7, my&7);
 }
@@ -431,7 +444,7 @@
     y_offset += 8*h->mby;
 
     if(mv->ref >= 0){
-        Picture *ref= &h->DPB[mv->ref];
+        AVFrame *ref = h->DPB[mv->ref].f;
         mc_dir_part(h, ref, chroma_height, delta, 0,
                     dest_y, dest_cb, dest_cr, x_offset, y_offset,
                     qpix_op, chroma_op, mv);
@@ -441,7 +454,7 @@
     }
 
     if((mv+MV_BWD_OFFS)->ref >= 0){
-        Picture *ref= &h->DPB[0];
+        AVFrame *ref = h->DPB[0].f;
         mc_dir_part(h, ref, chroma_height, delta, 1,
                     dest_y, dest_cb, dest_cr, x_offset, y_offset,
                     qpix_op, chroma_op, mv+MV_BWD_OFFS);
@@ -452,30 +465,35 @@
     if(ff_cavs_partition_flags[mb_type] == 0){ // 16x16
         mc_part_std(h, 8, 0, h->cy, h->cu, h->cv, 0, 0,
                 h->cdsp.put_cavs_qpel_pixels_tab[0],
-                h->s.dsp.put_h264_chroma_pixels_tab[0],
+                h->h264chroma.put_h264_chroma_pixels_tab[0],
                 h->cdsp.avg_cavs_qpel_pixels_tab[0],
-                h->s.dsp.avg_h264_chroma_pixels_tab[0],&h->mv[MV_FWD_X0]);
+                h->h264chroma.avg_h264_chroma_pixels_tab[0],
+                &h->mv[MV_FWD_X0]);
     }else{
         mc_part_std(h, 4, 0, h->cy, h->cu, h->cv, 0, 0,
                 h->cdsp.put_cavs_qpel_pixels_tab[1],
-                h->s.dsp.put_h264_chroma_pixels_tab[1],
+                h->h264chroma.put_h264_chroma_pixels_tab[1],
                 h->cdsp.avg_cavs_qpel_pixels_tab[1],
-                h->s.dsp.avg_h264_chroma_pixels_tab[1],&h->mv[MV_FWD_X0]);
+                h->h264chroma.avg_h264_chroma_pixels_tab[1],
+                &h->mv[MV_FWD_X0]);
         mc_part_std(h, 4, 0, h->cy, h->cu, h->cv, 4, 0,
                 h->cdsp.put_cavs_qpel_pixels_tab[1],
-                h->s.dsp.put_h264_chroma_pixels_tab[1],
+                h->h264chroma.put_h264_chroma_pixels_tab[1],
                 h->cdsp.avg_cavs_qpel_pixels_tab[1],
-                h->s.dsp.avg_h264_chroma_pixels_tab[1],&h->mv[MV_FWD_X1]);
+                h->h264chroma.avg_h264_chroma_pixels_tab[1],
+                &h->mv[MV_FWD_X1]);
         mc_part_std(h, 4, 0, h->cy, h->cu, h->cv, 0, 4,
                 h->cdsp.put_cavs_qpel_pixels_tab[1],
-                h->s.dsp.put_h264_chroma_pixels_tab[1],
+                h->h264chroma.put_h264_chroma_pixels_tab[1],
                 h->cdsp.avg_cavs_qpel_pixels_tab[1],
-                h->s.dsp.avg_h264_chroma_pixels_tab[1],&h->mv[MV_FWD_X2]);
+                h->h264chroma.avg_h264_chroma_pixels_tab[1],
+                &h->mv[MV_FWD_X2]);
         mc_part_std(h, 4, 0, h->cy, h->cu, h->cv, 4, 4,
                 h->cdsp.put_cavs_qpel_pixels_tab[1],
-                h->s.dsp.put_h264_chroma_pixels_tab[1],
+                h->h264chroma.put_h264_chroma_pixels_tab[1],
                 h->cdsp.avg_cavs_qpel_pixels_tab[1],
-                h->s.dsp.avg_h264_chroma_pixels_tab[1],&h->mv[MV_FWD_X3]);
+                h->h264chroma.avg_h264_chroma_pixels_tab[1],
+                &h->mv[MV_FWD_X3]);
     }
 }
 
@@ -556,8 +574,8 @@
         mv_pred_median(h, mvP, mvA, mvB, mvC);
 
     if(mode < MV_PRED_PSKIP) {
-        mvP->x += get_se_golomb(&h->s.gb);
-        mvP->y += get_se_golomb(&h->s.gb);
+        mvP->x += get_se_golomb(&h->gb);
+        mvP->y += get_se_golomb(&h->gb);
     }
     set_mvs(mvP,size);
 }
@@ -639,9 +657,9 @@
         h->mbx = 0;
         h->mby++;
         /* re-calculate sample pointers */
-        h->cy = h->picture.f.data[0] + h->mby * 16 * h->l_stride;
-        h->cu = h->picture.f.data[1] + h->mby *  8 * h->c_stride;
-        h->cv = h->picture.f.data[2] + h->mby *  8 * h->c_stride;
+        h->cy = h->cur.f->data[0] + h->mby * 16 * h->l_stride;
+        h->cu = h->cur.f->data[1] + h->mby *  8 * h->c_stride;
+        h->cv = h->cur.f->data[2] + h->mby *  8 * h->c_stride;
         if(h->mby == h->mb_height) { //frame end
             return 0;
         }
@@ -655,7 +673,7 @@
  *
  ****************************************************************************/
 
-void ff_cavs_init_pic(AVSContext *h) {
+int ff_cavs_init_pic(AVSContext *h) {
     int i;
 
     /* clear some predictors */
@@ -666,15 +684,17 @@
     h->mv[MV_FWD_X0] = ff_cavs_dir_mv;
     set_mvs(&h->mv[MV_FWD_X0], BLK_16X16);
     h->pred_mode_Y[3] = h->pred_mode_Y[6] = NOT_AVAIL;
-    h->cy           = h->picture.f.data[0];
-    h->cu           = h->picture.f.data[1];
-    h->cv           = h->picture.f.data[2];
-    h->l_stride     = h->picture.f.linesize[0];
-    h->c_stride     = h->picture.f.linesize[1];
+    h->cy           = h->cur.f->data[0];
+    h->cu           = h->cur.f->data[1];
+    h->cv           = h->cur.f->data[2];
+    h->l_stride     = h->cur.f->linesize[0];
+    h->c_stride     = h->cur.f->linesize[1];
     h->luma_scan[2] = 8*h->l_stride;
     h->luma_scan[3] = 8*h->l_stride+8;
     h->mbx = h->mby = h->mbidx = 0;
     h->flags = 0;
+
+    return 0;
 }
 
 /*****************************************************************************
@@ -701,19 +721,31 @@
     /* alloc space for co-located MVs and types */
     h->col_mv       = av_mallocz( h->mb_width*h->mb_height*4*sizeof(cavs_vector));
     h->col_type_base = av_mallocz(h->mb_width*h->mb_height);
-    h->block        = av_mallocz(64*sizeof(DCTELEM));
+    h->block        = av_mallocz(64*sizeof(int16_t));
 }
 
 av_cold int ff_cavs_init(AVCodecContext *avctx) {
     AVSContext *h = avctx->priv_data;
-    MpegEncContext * const s = &h->s;
 
-    ff_MPV_decode_defaults(s);
+    ff_dsputil_init(&h->dsp, avctx);
+    ff_h264chroma_init(&h->h264chroma, 8);
+    ff_videodsp_init(&h->vdsp, 8);
     ff_cavsdsp_init(&h->cdsp, avctx);
-    s->avctx = avctx;
+    ff_init_scantable_permutation(h->dsp.idct_permutation,
+                                  h->cdsp.idct_perm);
+    ff_init_scantable(h->dsp.idct_permutation, &h->scantable, ff_zigzag_direct);
 
+    h->avctx = avctx;
     avctx->pix_fmt= AV_PIX_FMT_YUV420P;
 
+    h->cur.f    = avcodec_alloc_frame();
+    h->DPB[0].f = avcodec_alloc_frame();
+    h->DPB[1].f = avcodec_alloc_frame();
+    if (!h->cur.f || !h->DPB[0].f || !h->DPB[1].f) {
+        ff_cavs_end(avctx);
+        return AVERROR(ENOMEM);
+    }
+
     h->luma_scan[0] = 0;
     h->luma_scan[1] = 8;
     h->intra_pred_l[      INTRA_L_VERT] = intra_pred_vert;
@@ -739,7 +771,15 @@
 av_cold int ff_cavs_end(AVCodecContext *avctx) {
     AVSContext *h = avctx->priv_data;
 
-    ff_MPV_common_end(&h->s);
+    if (h->cur.f->data[0])
+        avctx->release_buffer(avctx, h->cur.f);
+    if (h->DPB[0].f->data[0])
+        avctx->release_buffer(avctx, h->DPB[0].f);
+    if (h->DPB[1].f->data[0])
+        avctx->release_buffer(avctx, h->DPB[1].f);
+    avcodec_free_frame(&h->cur.f);
+    avcodec_free_frame(&h->DPB[0].f);
+    avcodec_free_frame(&h->DPB[1].f);
 
     av_free(h->top_qp);
     av_free(h->top_mv[0]);
@@ -751,5 +791,6 @@
     av_free(h->col_mv);
     av_free(h->col_type_base);
     av_free(h->block);
+    av_freep(&h->edge_emu_buffer);
     return 0;
 }
diff --git a/libavcodec/cavs.h b/libavcodec/cavs.h
index 039053d..b0cdb8f 100644
--- a/libavcodec/cavs.h
+++ b/libavcodec/cavs.h
@@ -22,9 +22,11 @@
 #ifndef AVCODEC_CAVS_H
 #define AVCODEC_CAVS_H
 
-#include "dsputil.h"
-#include "mpegvideo.h"
 #include "cavsdsp.h"
+#include "dsputil.h"
+#include "h264chroma.h"
+#include "get_bits.h"
+#include "videodsp.h"
 
 #define SLICE_MAX_START_CODE    0x000001af
 #define EXT_START_CODE          0x000001b5
@@ -152,16 +154,26 @@
   int8_t max_run;
 };
 
+typedef struct AVSFrame {
+    AVFrame *f;
+    int poc;
+} AVSFrame;
+
 typedef struct AVSContext {
-    MpegEncContext s;
-    CAVSDSPContext cdsp;
-    Picture picture; ///< currently decoded frame
-    Picture DPB[2];  ///< reference frames
+    AVCodecContext *avctx;
+    DSPContext       dsp;
+    H264ChromaContext h264chroma;
+    VideoDSPContext vdsp;
+    CAVSDSPContext  cdsp;
+    GetBitContext gb;
+    AVSFrame cur;     ///< currently decoded frame
+    AVSFrame DPB[2];  ///< reference frames
     int dist[2];     ///< temporal distances from current frame to ref frames
+    int low_delay;
     int profile, level;
     int aspect_ratio;
     int mb_width, mb_height;
-    int pic_type;
+    int width, height;
     int stream_revision; ///<0 for samples from 2006, 1 for rm52j encoder
     int progressive;
     int pic_structure;
@@ -221,8 +233,10 @@
     int direct_den[2]; ///< for scaling in direct B block
     int scale_den[2];  ///< for scaling neighbouring MVs
 
+    uint8_t *edge_emu_buffer;
+
     int got_keyframe;
-    DCTELEM *block;
+    int16_t *block;
 } AVSContext;
 
 extern const uint8_t     ff_cavs_partition_flags[30];
@@ -253,7 +267,7 @@
                 enum cavs_mv_pred mode, enum cavs_block size, int ref);
 void ff_cavs_init_mb(AVSContext *h);
 int  ff_cavs_next_mb(AVSContext *h);
-void ff_cavs_init_pic(AVSContext *h);
+int ff_cavs_init_pic(AVSContext *h);
 void ff_cavs_init_top_lines(AVSContext *h);
 int ff_cavs_init(AVCodecContext *avctx);
 int ff_cavs_end (AVCodecContext *avctx);
diff --git a/libavcodec/cavsdec.c b/libavcodec/cavsdec.c
index 02d0d81..fa60d6c 100644
--- a/libavcodec/cavsdec.c
+++ b/libavcodec/cavsdec.c
@@ -30,427 +30,427 @@
 #include "get_bits.h"
 #include "golomb.h"
 #include "cavs.h"
+#include "internal.h"
+#include "mpeg12data.h"
+#include "mpegvideo.h"
 
 static const uint8_t mv_scan[4] = {
-    MV_FWD_X0,MV_FWD_X1,
-    MV_FWD_X2,MV_FWD_X3
+    MV_FWD_X0, MV_FWD_X1,
+    MV_FWD_X2, MV_FWD_X3
 };
 
 static const uint8_t cbp_tab[64][2] = {
-  {63, 0},{15,15},{31,63},{47,31},{ 0,16},{14,32},{13,47},{11,13},
-  { 7,14},{ 5,11},{10,12},{ 8, 5},{12,10},{61, 7},{ 4,48},{55, 3},
-  { 1, 2},{ 2, 8},{59, 4},{ 3, 1},{62,61},{ 9,55},{ 6,59},{29,62},
-  {45,29},{51,27},{23,23},{39,19},{27,30},{46,28},{53, 9},{30, 6},
-  {43,60},{37,21},{60,44},{16,26},{21,51},{28,35},{19,18},{35,20},
-  {42,24},{26,53},{44,17},{32,37},{58,39},{24,45},{20,58},{17,43},
-  {18,42},{48,46},{22,36},{33,33},{25,34},{49,40},{40,52},{36,49},
-  {34,50},{50,56},{52,25},{54,22},{41,54},{56,57},{38,41},{57,38}
+  { 63,  0 }, { 15, 15 }, { 31, 63 }, { 47, 31 }, {  0, 16 }, { 14, 32 }, { 13, 47 }, { 11, 13 },
+  {  7, 14 }, {  5, 11 }, { 10, 12 }, {  8,  5 }, { 12, 10 }, { 61,  7 }, {  4, 48 }, { 55,  3 },
+  {  1,  2 }, {  2,  8 }, { 59,  4 }, {  3,  1 }, { 62, 61 }, {  9, 55 }, {  6, 59 }, { 29, 62 },
+  { 45, 29 }, { 51, 27 }, { 23, 23 }, { 39, 19 }, { 27, 30 }, { 46, 28 }, { 53,  9 }, { 30,  6 },
+  { 43, 60 }, { 37, 21 }, { 60, 44 }, { 16, 26 }, { 21, 51 }, { 28, 35 }, { 19, 18 }, { 35, 20 },
+  { 42, 24 }, { 26, 53 }, { 44, 17 }, { 32, 37 }, { 58, 39 }, { 24, 45 }, { 20, 58 }, { 17, 43 },
+  { 18, 42 }, { 48, 46 }, { 22, 36 }, { 33, 33 }, { 25, 34 }, { 49, 40 }, { 40, 52 }, { 36, 49 },
+  { 34, 50 }, { 50, 56 }, { 52, 25 }, { 54, 22 }, { 41, 54 }, { 56, 57 }, { 38, 41 }, { 57, 38 }
 };
 
 static const uint8_t scan3x3[4] = { 4, 5, 7, 8 };
 
 static const uint8_t cavs_chroma_qp[64] = {
-  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,36,37,38,39,40,41,42,42,43,43,44,44,
-  45,45,46,46,47,47,48,48,48,49,49,49,50,50,50,51
+   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, 36, 37, 38, 39, 40, 41, 42, 42, 43, 43, 44, 44,
+  45, 45, 46, 46, 47, 47, 48, 48, 48, 49, 49, 49, 50, 50, 50, 51
 };
 
 static const uint8_t dequant_shift[64] = {
-  14,14,14,14,14,14,14,14,
-  13,13,13,13,13,13,13,13,
-  13,12,12,12,12,12,12,12,
-  11,11,11,11,11,11,11,11,
-  11,10,10,10,10,10,10,10,
-  10, 9, 9, 9, 9, 9, 9, 9,
-  9, 8, 8, 8, 8, 8, 8, 8,
-  7, 7, 7, 7, 7, 7, 7, 7
+  14, 14, 14, 14, 14, 14, 14, 14,
+  13, 13, 13, 13, 13, 13, 13, 13,
+  13, 12, 12, 12, 12, 12, 12, 12,
+  11, 11, 11, 11, 11, 11, 11, 11,
+  11, 10, 10, 10, 10, 10, 10, 10,
+  10,  9,  9,  9,  9,  9,  9,  9,
+  9,   8,  8,  8,  8,  8,  8,  8,
+  7,   7,  7,  7,  7,  7,  7,  7
 };
 
 static const uint16_t dequant_mul[64] = {
-  32768,36061,38968,42495,46341,50535,55437,60424,
-  32932,35734,38968,42495,46177,50535,55109,59933,
-  65535,35734,38968,42577,46341,50617,55027,60097,
-  32809,35734,38968,42454,46382,50576,55109,60056,
-  65535,35734,38968,42495,46320,50515,55109,60076,
-  65535,35744,38968,42495,46341,50535,55099,60087,
-  65535,35734,38973,42500,46341,50535,55109,60097,
-  32771,35734,38965,42497,46341,50535,55109,60099
+  32768, 36061, 38968, 42495, 46341, 50535, 55437, 60424,
+  32932, 35734, 38968, 42495, 46177, 50535, 55109, 59933,
+  65535, 35734, 38968, 42577, 46341, 50617, 55027, 60097,
+  32809, 35734, 38968, 42454, 46382, 50576, 55109, 60056,
+  65535, 35734, 38968, 42495, 46320, 50515, 55109, 60076,
+  65535, 35744, 38968, 42495, 46341, 50535, 55099, 60087,
+  65535, 35734, 38973, 42500, 46341, 50535, 55109, 60097,
+  32771, 35734, 38965, 42497, 46341, 50535, 55109, 60099
 };
 
-#define EOB 0,0,0
+#define EOB 0, 0, 0
 
 static const struct dec_2dvlc intra_dec[7] = {
-  {
-    { //level / run / table_inc
-      {  1, 1, 1},{ -1, 1, 1},{  1, 2, 1},{ -1, 2, 1},{  1, 3, 1},{ -1, 3, 1},
-      {  1, 4, 1},{ -1, 4, 1},{  1, 5, 1},{ -1, 5, 1},{  1, 6, 1},{ -1, 6, 1},
-      {  1, 7, 1},{ -1, 7, 1},{  1, 8, 1},{ -1, 8, 1},{  1, 9, 1},{ -1, 9, 1},
-      {  1,10, 1},{ -1,10, 1},{  1,11, 1},{ -1,11, 1},{  2, 1, 2},{ -2, 1, 2},
-      {  1,12, 1},{ -1,12, 1},{  1,13, 1},{ -1,13, 1},{  1,14, 1},{ -1,14, 1},
-      {  1,15, 1},{ -1,15, 1},{  2, 2, 2},{ -2, 2, 2},{  1,16, 1},{ -1,16, 1},
-      {  1,17, 1},{ -1,17, 1},{  3, 1, 3},{ -3, 1, 3},{  1,18, 1},{ -1,18, 1},
-      {  1,19, 1},{ -1,19, 1},{  2, 3, 2},{ -2, 3, 2},{  1,20, 1},{ -1,20, 1},
-      {  1,21, 1},{ -1,21, 1},{  2, 4, 2},{ -2, 4, 2},{  1,22, 1},{ -1,22, 1},
-      {  2, 5, 2},{ -2, 5, 2},{  1,23, 1},{ -1,23, 1},{   EOB   }
+    {
+        { //level / run / table_inc
+            {  1,  1,  1 }, { -1,  1,  1 }, {  1,  2,  1 }, { -1,  2,  1 }, {  1,  3,  1 }, { -1,  3, 1 },
+            {  1,  4,  1 }, { -1,  4,  1 }, {  1,  5,  1 }, { -1,  5,  1 }, {  1,  6,  1 }, { -1,  6, 1 },
+            {  1,  7,  1 }, { -1,  7,  1 }, {  1,  8,  1 }, { -1,  8,  1 }, {  1,  9,  1 }, { -1,  9, 1 },
+            {  1, 10,  1 }, { -1, 10,  1 }, {  1, 11,  1 }, { -1, 11,  1 }, {  2,  1,  2 }, { -2,  1, 2 },
+            {  1, 12,  1 }, { -1, 12,  1 }, {  1, 13,  1 }, { -1, 13,  1 }, {  1, 14,  1 }, { -1, 14, 1 },
+            {  1, 15,  1 }, { -1, 15,  1 }, {  2,  2,  2 }, { -2,  2,  2 }, {  1, 16,  1 }, { -1, 16, 1 },
+            {  1, 17,  1 }, { -1, 17,  1 }, {  3,  1,  3 }, { -3,  1,  3 }, {  1, 18,  1 }, { -1, 18, 1 },
+            {  1, 19,  1 }, { -1, 19,  1 }, {  2,  3,  2 }, { -2,  3,  2 }, {  1, 20,  1 }, { -1, 20, 1 },
+            {  1, 21,  1 }, { -1, 21,  1 }, {  2,  4,  2 }, { -2,  4,  2 }, {  1, 22,  1 }, { -1, 22, 1 },
+            {  2,  5,  2 }, { -2,  5,  2 }, {  1, 23,  1 }, { -1, 23,  1 }, {   EOB    }
+        },
+        //level_add
+        { 0, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -1, -1, -1 },
+        2, //golomb_order
+        0, //inc_limit
+        23, //max_run
     },
-    //level_add
-    { 0, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-      2, 2, 2, 2, 2, 2, 2,-1,-1,-1},
-    2, //golomb_order
-    0, //inc_limit
-    23, //max_run
-  },{
-    { //level / run
-      {  1, 1, 0},{ -1, 1, 0},{  1, 2, 0},{ -1, 2, 0},{  2, 1, 1},{ -2, 1, 1},
-      {  1, 3, 0},{ -1, 3, 0},{   EOB   },{  1, 4, 0},{ -1, 4, 0},{  1, 5, 0},
-      { -1, 5, 0},{  1, 6, 0},{ -1, 6, 0},{  3, 1, 2},{ -3, 1, 2},{  2, 2, 1},
-      { -2, 2, 1},{  1, 7, 0},{ -1, 7, 0},{  1, 8, 0},{ -1, 8, 0},{  1, 9, 0},
-      { -1, 9, 0},{  2, 3, 1},{ -2, 3, 1},{  4, 1, 2},{ -4, 1, 2},{  1,10, 0},
-      { -1,10, 0},{  1,11, 0},{ -1,11, 0},{  2, 4, 1},{ -2, 4, 1},{  3, 2, 2},
-      { -3, 2, 2},{  1,12, 0},{ -1,12, 0},{  2, 5, 1},{ -2, 5, 1},{  5, 1, 3},
-      { -5, 1, 3},{  1,13, 0},{ -1,13, 0},{  2, 6, 1},{ -2, 6, 1},{  1,14, 0},
-      { -1,14, 0},{  2, 7, 1},{ -2, 7, 1},{  2, 8, 1},{ -2, 8, 1},{  3, 3, 2},
-      { -3, 3, 2},{  6, 1, 3},{ -6, 1, 3},{  1,15, 0},{ -1,15, 0}
+    {
+        { //level / run
+            {  1,  1,  0 }, { -1,  1,  0 }, {  1,  2,  0 }, { -1,  2,  0 }, {  2,  1,  1 }, { -2,  1,  1 },
+            {  1,  3,  0 }, { -1,  3,  0 }, {     EOB    }, {  1,  4,  0 }, { -1,  4,  0 }, {  1,  5,  0 },
+            { -1,  5,  0 }, {  1,  6,  0 }, { -1,  6,  0 }, {  3,  1,  2 }, { -3,  1,  2 }, {  2,  2,  1 },
+            { -2,  2,  1 }, {  1,  7,  0 }, { -1,  7,  0 }, {  1,  8,  0 }, { -1,  8,  0 }, {  1,  9,  0 },
+            { -1,  9,  0 }, {  2,  3,  1 }, { -2,  3,  1 }, {  4,  1,  2 }, { -4,  1,  2 }, {  1, 10,  0 },
+            { -1, 10,  0 }, {  1, 11,  0 }, { -1, 11,  0 }, {  2,  4,  1 }, { -2,  4,  1 }, {  3,  2,  2 },
+            { -3,  2,  2 }, {  1, 12,  0 }, { -1, 12,  0 }, {  2,  5,  1 }, { -2,  5,  1 }, {  5,  1,  3 },
+            { -5,  1,  3 }, {  1, 13,  0 }, { -1, 13,  0 }, {  2,  6,  1 }, { -2,  6,  1 }, {  1, 14,  0 },
+            { -1, 14,  0 }, {  2,  7,  1 }, { -2,  7,  1 }, {  2,  8,  1 }, { -2,  8,  1 }, {  3,  3,  2 },
+            { -3,  3,  2 }, {  6,  1,  3 }, { -6,  1,  3 }, {  1, 15,  0 }, { -1, 15,  0 }
+        },
+        //level_add
+        { 0, 7, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+        2, //golomb_order
+        1, //inc_limit
+        15, //max_run
     },
-    //level_add
-    { 0, 7, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2,-1,
-      -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
-    2, //golomb_order
-    1, //inc_limit
-    15, //max_run
-  },{
-    { //level / run
-      {  1, 1, 0},{ -1, 1, 0},{  2, 1, 0},{ -2, 1, 0},{  1, 2, 0},{ -1, 2, 0},
-      {  3, 1, 1},{ -3, 1, 1},{   EOB   },{  1, 3, 0},{ -1, 3, 0},{  2, 2, 0},
-      { -2, 2, 0},{  4, 1, 1},{ -4, 1, 1},{  1, 4, 0},{ -1, 4, 0},{  5, 1, 2},
-      { -5, 1, 2},{  1, 5, 0},{ -1, 5, 0},{  3, 2, 1},{ -3, 2, 1},{  2, 3, 0},
-      { -2, 3, 0},{  1, 6, 0},{ -1, 6, 0},{  6, 1, 2},{ -6, 1, 2},{  2, 4, 0},
-      { -2, 4, 0},{  1, 7, 0},{ -1, 7, 0},{  4, 2, 1},{ -4, 2, 1},{  7, 1, 2},
-      { -7, 1, 2},{  3, 3, 1},{ -3, 3, 1},{  2, 5, 0},{ -2, 5, 0},{  1, 8, 0},
-      { -1, 8, 0},{  2, 6, 0},{ -2, 6, 0},{  8, 1, 3},{ -8, 1, 3},{  1, 9, 0},
-      { -1, 9, 0},{  5, 2, 2},{ -5, 2, 2},{  3, 4, 1},{ -3, 4, 1},{  2, 7, 0},
-      { -2, 7, 0},{  9, 1, 3},{ -9, 1, 3},{  1,10, 0},{ -1,10, 0}
+    {
+        { //level / run
+            {  1,  1,  0 }, { -1,  1,  0 }, {  2,  1,  0 }, { -2,  1,  0 }, {  1,  2,  0 }, { -1,  2,  0 },
+            {  3,  1,  1 }, { -3,  1,  1 }, {     EOB    }, {  1,  3,  0 }, { -1,  3,  0 }, {  2,  2,  0 },
+            { -2,  2,  0 }, {  4,  1,  1 }, { -4,  1,  1 }, {  1,  4,  0 }, { -1,  4,  0 }, {  5,  1,  2 },
+            { -5,  1,  2 }, {  1,  5,  0 }, { -1,  5,  0 }, {  3,  2,  1 }, { -3,  2,  1 }, {  2,  3,  0 },
+            { -2,  3,  0 }, {  1,  6,  0 }, { -1,  6,  0 }, {  6,  1,  2 }, { -6,  1,  2 }, {  2,  4,  0 },
+            { -2,  4,  0 }, {  1,  7,  0 }, { -1,  7,  0 }, {  4,  2,  1 }, { -4,  2,  1 }, {  7,  1,  2 },
+            { -7,  1,  2 }, {  3,  3,  1 }, { -3,  3,  1 }, {  2,  5,  0 }, { -2,  5,  0 }, {  1,  8,  0 },
+            { -1,  8,  0 }, {  2,  6,  0 }, { -2,  6,  0 }, {  8,  1,  3 }, { -8,  1,  3 }, {  1,  9,  0 },
+            { -1,  9,  0 }, {  5,  2,  2 }, { -5,  2,  2 }, {  3,  4,  1 }, { -3,  4,  1 }, {  2,  7,  0 },
+            { -2,  7,  0 }, {  9,  1,  3 }, { -9,  1,  3 }, {  1, 10,  0 }, { -1, 10,  0 }
+        },
+        //level_add
+        { 0, 10, 6, 4, 4, 3, 3, 3, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+        2, //golomb_order
+        2, //inc_limit
+        10, //max_run
     },
-    //level_add
-    { 0,10, 6, 4, 4, 3, 3, 3, 2, 2, 2,-1,-1,-1,-1,-1,-1,
-     -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
-    2, //golomb_order
-    2, //inc_limit
-    10, //max_run
-  },{
-    { //level / run
-      {  1, 1, 0},{ -1, 1, 0},{  2, 1, 0},{ -2, 1, 0},{  3, 1, 0},{ -3, 1, 0},
-      {  1, 2, 0},{ -1, 2, 0},{   EOB   },{  4, 1, 0},{ -4, 1, 0},{  5, 1, 1},
-      { -5, 1, 1},{  2, 2, 0},{ -2, 2, 0},{  1, 3, 0},{ -1, 3, 0},{  6, 1, 1},
-      { -6, 1, 1},{  3, 2, 0},{ -3, 2, 0},{  7, 1, 1},{ -7, 1, 1},{  1, 4, 0},
-      { -1, 4, 0},{  8, 1, 2},{ -8, 1, 2},{  2, 3, 0},{ -2, 3, 0},{  4, 2, 0},
-      { -4, 2, 0},{  1, 5, 0},{ -1, 5, 0},{  9, 1, 2},{ -9, 1, 2},{  5, 2, 1},
-      { -5, 2, 1},{  2, 4, 0},{ -2, 4, 0},{ 10, 1, 2},{-10, 1, 2},{  3, 3, 0},
-      { -3, 3, 0},{  1, 6, 0},{ -1, 6, 0},{ 11, 1, 3},{-11, 1, 3},{  6, 2, 1},
-      { -6, 2, 1},{  1, 7, 0},{ -1, 7, 0},{  2, 5, 0},{ -2, 5, 0},{  3, 4, 0},
-      { -3, 4, 0},{ 12, 1, 3},{-12, 1, 3},{  4, 3, 0},{ -4, 3, 0}
+    {
+        { //level / run
+            {  1,  1,  0 }, { -1,  1,  0 }, {  2,  1,  0 }, { -2,  1,  0 }, {  3,  1,  0 }, { -3,  1,  0 },
+            {  1,  2,  0 }, { -1,  2,  0 }, {     EOB    }, {  4,  1,  0 }, { -4,  1,  0 }, {  5,  1,  1 },
+            { -5,  1,  1 }, {  2,  2,  0 }, { -2,  2,  0 }, {  1,  3,  0 }, { -1,  3,  0 }, {  6,  1,  1 },
+            { -6,  1,  1 }, {  3,  2,  0 }, { -3,  2,  0 }, {  7,  1,  1 }, { -7,  1,  1 }, {  1,  4,  0 },
+            { -1,  4,  0 }, {  8,  1,  2 }, { -8,  1,  2 }, {  2,  3,  0 }, { -2,  3,  0 }, {  4,  2,  0 },
+            { -4,  2,  0 }, {  1,  5,  0 }, { -1,  5,  0 }, {  9,  1,  2 }, { -9,  1,  2 }, {  5,  2,  1 },
+            { -5,  2,  1 }, {  2,  4,  0 }, { -2,  4,  0 }, { 10,  1,  2 }, {-10,  1,  2 }, {  3,  3,  0 },
+            { -3,  3,  0 }, {  1,  6,  0 }, { -1,  6,  0 }, { 11,  1,  3 }, {-11,  1,  3 }, {  6,  2,  1 },
+            { -6,  2,  1 }, {  1,  7,  0 }, { -1,  7,  0 }, {  2,  5,  0 }, { -2,  5,  0 }, {  3,  4,  0 },
+            { -3,  4,  0 }, { 12,  1,  3 }, {-12,  1,  3 }, {  4,  3,  0 }, { -4,  3,  0 }
+         },
+        //level_add
+        { 0, 13, 7, 5, 4, 3, 2, 2, -1, -1, -1 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+        2, //golomb_order
+        4, //inc_limit
+        7, //max_run
     },
-    //level_add
-    { 0,13, 7, 5, 4, 3, 2, 2,-1,-1,-1 -1,-1,-1,-1,-1,-1,
-     -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
-    2, //golomb_order
-    4, //inc_limit
-    7, //max_run
-  },{
-    { //level / run
-      {  1, 1, 0},{ -1, 1, 0},{  2, 1, 0},{ -2, 1, 0},{  3, 1, 0},{ -3, 1, 0},
-      {   EOB   },{  4, 1, 0},{ -4, 1, 0},{  5, 1, 0},{ -5, 1, 0},{  6, 1, 0},
-      { -6, 1, 0},{  1, 2, 0},{ -1, 2, 0},{  7, 1, 0},{ -7, 1, 0},{  8, 1, 1},
-      { -8, 1, 1},{  2, 2, 0},{ -2, 2, 0},{  9, 1, 1},{ -9, 1, 1},{ 10, 1, 1},
-      {-10, 1, 1},{  1, 3, 0},{ -1, 3, 0},{  3, 2, 0},{ -3, 2, 0},{ 11, 1, 2},
-      {-11, 1, 2},{  4, 2, 0},{ -4, 2, 0},{ 12, 1, 2},{-12, 1, 2},{ 13, 1, 2},
-      {-13, 1, 2},{  5, 2, 0},{ -5, 2, 0},{  1, 4, 0},{ -1, 4, 0},{  2, 3, 0},
-      { -2, 3, 0},{ 14, 1, 2},{-14, 1, 2},{  6, 2, 0},{ -6, 2, 0},{ 15, 1, 2},
-      {-15, 1, 2},{ 16, 1, 2},{-16, 1, 2},{  3, 3, 0},{ -3, 3, 0},{  1, 5, 0},
-      { -1, 5, 0},{  7, 2, 0},{ -7, 2, 0},{ 17, 1, 2},{-17, 1, 2}
+    {
+        { //level / run
+            {  1,  1,  0 }, { -1,  1,  0 }, {  2,  1,  0 }, { -2,  1,  0 }, {  3,  1,  0 }, { -3,  1,  0 },
+            {     EOB    }, {  4,  1,  0 }, { -4,  1,  0 }, {  5,  1,  0 }, { -5,  1,  0 }, {  6,  1,  0 },
+            { -6,  1,  0 }, {  1,  2,  0 }, { -1,  2,  0 }, {  7,  1,  0 }, { -7,  1,  0 }, {  8,  1,  1 },
+            { -8,  1,  1 }, {  2,  2,  0 }, { -2,  2,  0 }, {  9,  1,  1 }, { -9,  1,  1 }, { 10,  1,  1 },
+            {-10,  1,  1 }, {  1,  3,  0 }, { -1,  3,  0 }, {  3,  2,  0 }, { -3,  2,  0 }, { 11,  1,  2 },
+            {-11,  1,  2 }, {  4,  2,  0 }, { -4,  2,  0 }, { 12,  1,  2 }, {-12,  1,  2 }, { 13,  1,  2 },
+            {-13,  1,  2 }, {  5,  2,  0 }, { -5,  2,  0 }, {  1,  4,  0 }, { -1,  4,  0 }, {  2,  3,  0 },
+            { -2,  3,  0 }, { 14,  1,  2 }, {-14,  1,  2 }, {  6,  2,  0 }, { -6,  2,  0 }, { 15,  1,  2 },
+            {-15,  1,  2 }, { 16,  1,  2 }, {-16,  1,  2 }, {  3,  3,  0 }, { -3,  3,  0 }, {  1,  5,  0 },
+            { -1,  5,  0 }, {  7,  2,  0 }, { -7,  2,  0 }, { 17,  1,  2 }, {-17,  1,  2 }
+        },
+        //level_add
+        { 0,18, 8, 4, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+        2, //golomb_order
+        7, //inc_limit
+        5, //max_run
     },
-    //level_add
-    { 0,18, 8, 4, 2, 2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-     -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
-    2, //golomb_order
-    7, //inc_limit
-    5, //max_run
-  },{
-    { //level / run
-      {   EOB   },{  1, 1, 0},{ -1, 1, 0},{  2, 1, 0},{ -2, 1, 0},{  3, 1, 0},
-      { -3, 1, 0},{  4, 1, 0},{ -4, 1, 0},{  5, 1, 0},{ -5, 1, 0},{  6, 1, 0},
-      { -6, 1, 0},{  7, 1, 0},{ -7, 1, 0},{  8, 1, 0},{ -8, 1, 0},{  9, 1, 0},
-      { -9, 1, 0},{ 10, 1, 0},{-10, 1, 0},{  1, 2, 0},{ -1, 2, 0},{ 11, 1, 1},
-      {-11, 1, 1},{ 12, 1, 1},{-12, 1, 1},{ 13, 1, 1},{-13, 1, 1},{  2, 2, 0},
-      { -2, 2, 0},{ 14, 1, 1},{-14, 1, 1},{ 15, 1, 1},{-15, 1, 1},{  3, 2, 0},
-      { -3, 2, 0},{ 16, 1, 1},{-16, 1, 1},{  1, 3, 0},{ -1, 3, 0},{ 17, 1, 1},
-      {-17, 1, 1},{  4, 2, 0},{ -4, 2, 0},{ 18, 1, 1},{-18, 1, 1},{  5, 2, 0},
-      { -5, 2, 0},{ 19, 1, 1},{-19, 1, 1},{ 20, 1, 1},{-20, 1, 1},{  6, 2, 0},
-      { -6, 2, 0},{ 21, 1, 1},{-21, 1, 1},{  2, 3, 0},{ -2, 3, 0}
+    {
+        { //level / run
+            {     EOB    }, {  1,  1,  0 }, { -1,  1,  0 }, {  2,  1,  0 }, { -2,  1,  0 }, {  3,  1,  0 },
+            { -3,  1,  0 }, {  4,  1,  0 }, { -4,  1,  0 }, {  5,  1,  0 }, { -5,  1,  0 }, {  6,  1,  0 },
+            { -6,  1,  0 }, {  7,  1,  0 }, { -7,  1,  0 }, {  8,  1,  0 }, { -8,  1,  0 }, {  9,  1,  0 },
+            { -9,  1,  0 }, { 10,  1,  0 }, {-10,  1,  0 }, {  1,  2,  0 }, { -1,  2,  0 }, { 11,  1,  1 },
+            {-11,  1,  1 }, { 12,  1,  1 }, {-12,  1,  1 }, { 13,  1,  1 }, {-13,  1,  1 }, {  2,  2,  0 },
+            { -2,  2,  0 }, { 14,  1,  1 }, {-14,  1,  1 }, { 15,  1,  1 }, {-15,  1,  1 }, {  3,  2,  0 },
+            { -3,  2,  0 }, { 16,  1,  1 }, {-16,  1,  1 }, {  1,  3,  0 }, { -1,  3,  0 }, { 17,  1,  1 },
+            {-17,  1,  1 }, {  4,  2,  0 }, { -4,  2,  0 }, { 18,  1,  1 }, {-18,  1,  1 }, {  5,  2,  0 },
+            { -5,  2,  0 }, { 19,  1,  1 }, {-19,  1,  1 }, { 20,  1,  1 }, {-20,  1,  1 }, {  6,  2,  0 },
+            { -6,  2,  0 }, { 21,  1,  1 }, {-21,  1,  1 }, {  2,  3,  0 }, { -2,  3,  0 }
+        },
+        //level_add
+        { 0, 22, 7, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+        2, //golomb_order
+        10, //inc_limit
+        3, //max_run
     },
-    //level_add
-    { 0,22, 7, 3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-     -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
-    2, //golomb_order
-    10, //inc_limit
-    3, //max_run
-  },{
-    { //level / run
-      {   EOB   },{  1, 1, 0},{ -1, 1, 0},{  2, 1, 0},{ -2, 1, 0},{  3, 1, 0},
-      { -3, 1, 0},{  4, 1, 0},{ -4, 1, 0},{  5, 1, 0},{ -5, 1, 0},{  6, 1, 0},
-      { -6, 1, 0},{  7, 1, 0},{ -7, 1, 0},{  8, 1, 0},{ -8, 1, 0},{  9, 1, 0},
-      { -9, 1, 0},{ 10, 1, 0},{-10, 1, 0},{ 11, 1, 0},{-11, 1, 0},{ 12, 1, 0},
-      {-12, 1, 0},{ 13, 1, 0},{-13, 1, 0},{ 14, 1, 0},{-14, 1, 0},{ 15, 1, 0},
-      {-15, 1, 0},{ 16, 1, 0},{-16, 1, 0},{  1, 2, 0},{ -1, 2, 0},{ 17, 1, 0},
-      {-17, 1, 0},{ 18, 1, 0},{-18, 1, 0},{ 19, 1, 0},{-19, 1, 0},{ 20, 1, 0},
-      {-20, 1, 0},{ 21, 1, 0},{-21, 1, 0},{  2, 2, 0},{ -2, 2, 0},{ 22, 1, 0},
-      {-22, 1, 0},{ 23, 1, 0},{-23, 1, 0},{ 24, 1, 0},{-24, 1, 0},{ 25, 1, 0},
-      {-25, 1, 0},{  3, 2, 0},{ -3, 2, 0},{ 26, 1, 0},{-26, 1, 0}
-    },
-    //level_add
-    { 0,27, 4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-     -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
-    2, //golomb_order
-    INT_MAX, //inc_limit
-    2, //max_run
-  }
+    {
+        { //level / run
+            {     EOB    }, {  1,  1,  0 }, { -1,  1,  0 }, {  2,  1,  0 }, { -2,  1,  0 }, {  3,  1,  0 },
+            { -3,  1,  0 }, {  4,  1,  0 }, { -4,  1,  0 }, {  5,  1,  0 }, { -5,  1,  0 }, {  6,  1,  0 },
+            { -6,  1,  0 }, {  7,  1,  0 }, { -7,  1,  0 }, {  8,  1,  0 }, { -8,  1,  0 }, {  9,  1,  0 },
+            { -9,  1,  0 }, { 10,  1,  0 }, {-10,  1,  0 }, { 11,  1,  0 }, {-11,  1,  0 }, { 12,  1,  0 },
+            {-12,  1,  0 }, { 13,  1,  0 }, {-13,  1,  0 }, { 14,  1,  0 }, {-14,  1,  0 }, { 15,  1,  0 },
+            {-15,  1,  0 }, { 16,  1,  0 }, {-16,  1,  0 }, {  1,  2,  0 }, { -1,  2,  0 }, { 17,  1,  0 },
+            {-17,  1,  0 }, { 18,  1,  0 }, {-18,  1,  0 }, { 19,  1,  0 }, {-19,  1,  0 }, { 20,  1,  0 },
+            {-20,  1,  0 }, { 21,  1,  0 }, {-21,  1,  0 }, {  2,  2,  0 }, { -2,  2,  0 }, { 22,  1,  0 },
+            {-22,  1,  0 }, { 23,  1,  0 }, {-23,  1,  0 }, { 24,  1,  0 }, {-24,  1,  0 }, { 25,  1,  0 },
+            {-25,  1,  0 }, {  3,  2,  0 }, { -3,  2,  0 }, { 26,  1,  0 }, {-26,  1,  0 }
+        },
+        //level_add
+        { 0, 27, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+        2, //golomb_order
+        INT_MAX, //inc_limit
+        2, //max_run
+    }
 };
 
 static const struct dec_2dvlc inter_dec[7] = {
-  {
-    { //level / run
-      {  1, 1, 1},{ -1, 1, 1},{  1, 2, 1},{ -1, 2, 1},{  1, 3, 1},{ -1, 3, 1},
-      {  1, 4, 1},{ -1, 4, 1},{  1, 5, 1},{ -1, 5, 1},{  1, 6, 1},{ -1, 6, 1},
-      {  1, 7, 1},{ -1, 7, 1},{  1, 8, 1},{ -1, 8, 1},{  1, 9, 1},{ -1, 9, 1},
-      {  1,10, 1},{ -1,10, 1},{  1,11, 1},{ -1,11, 1},{  1,12, 1},{ -1,12, 1},
-      {  1,13, 1},{ -1,13, 1},{  2, 1, 2},{ -2, 1, 2},{  1,14, 1},{ -1,14, 1},
-      {  1,15, 1},{ -1,15, 1},{  1,16, 1},{ -1,16, 1},{  1,17, 1},{ -1,17, 1},
-      {  1,18, 1},{ -1,18, 1},{  1,19, 1},{ -1,19, 1},{  3, 1, 3},{ -3, 1, 3},
-      {  1,20, 1},{ -1,20, 1},{  1,21, 1},{ -1,21, 1},{  2, 2, 2},{ -2, 2, 2},
-      {  1,22, 1},{ -1,22, 1},{  1,23, 1},{ -1,23, 1},{  1,24, 1},{ -1,24, 1},
-      {  1,25, 1},{ -1,25, 1},{  1,26, 1},{ -1,26, 1},{   EOB   }
+    {
+        { //level / run
+            {  1,  1,  1 }, { -1,  1,  1 }, {  1,  2,  1 }, { -1,  2,  1 }, {  1,  3,  1 }, { -1,  3,  1 },
+            {  1,  4,  1 }, { -1,  4,  1 }, {  1,  5,  1 }, { -1,  5,  1 }, {  1,  6,  1 }, { -1,  6,  1 },
+            {  1,  7,  1 }, { -1,  7,  1 }, {  1,  8,  1 }, { -1,  8,  1 }, {  1,  9,  1 }, { -1,  9,  1 },
+            {  1, 10,  1 }, { -1, 10,  1 }, {  1, 11,  1 }, { -1, 11,  1 }, {  1, 12,  1 }, { -1, 12,  1 },
+            {  1, 13,  1 }, { -1, 13,  1 }, {  2,  1,  2 }, { -2,  1,  2 }, {  1, 14,  1 }, { -1, 14,  1 },
+            {  1, 15,  1 }, { -1, 15,  1 }, {  1, 16,  1 }, { -1, 16,  1 }, {  1, 17,  1 }, { -1, 17,  1 },
+            {  1, 18,  1 }, { -1, 18,  1 }, {  1, 19,  1 }, { -1, 19,  1 }, {  3,  1,  3 }, { -3,  1,  3 },
+            {  1, 20,  1 }, { -1, 20,  1 }, {  1, 21,  1 }, { -1, 21,  1 }, {  2,  2,  2 }, { -2,  2,  2 },
+            {  1, 22,  1 }, { -1, 22,  1 }, {  1, 23,  1 }, { -1, 23,  1 }, {  1, 24,  1 }, { -1, 24,  1 },
+            {  1, 25,  1 }, { -1, 25,  1 }, {  1, 26,  1 }, { -1, 26,  1 }, {   EOB    }
+        },
+        //level_add
+        { 0, 4, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
+        3, //golomb_order
+        0, //inc_limit
+        26 //max_run
     },
-    //level_add
-    { 0, 4, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-      2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
-    3, //golomb_order
-    0, //inc_limit
-    26 //max_run
-  },{
-    { //level / run
-      {  1, 1, 0},{ -1, 1, 0},{   EOB   },{  1, 2, 0},{ -1, 2, 0},{  1, 3, 0},
-      { -1, 3, 0},{  1, 4, 0},{ -1, 4, 0},{  1, 5, 0},{ -1, 5, 0},{  1, 6, 0},
-      { -1, 6, 0},{  2, 1, 1},{ -2, 1, 1},{  1, 7, 0},{ -1, 7, 0},{  1, 8, 0},
-      { -1, 8, 0},{  1, 9, 0},{ -1, 9, 0},{  1,10, 0},{ -1,10, 0},{  2, 2, 1},
-      { -2, 2, 1},{  1,11, 0},{ -1,11, 0},{  1,12, 0},{ -1,12, 0},{  3, 1, 2},
-      { -3, 1, 2},{  1,13, 0},{ -1,13, 0},{  1,14, 0},{ -1,14, 0},{  2, 3, 1},
-      { -2, 3, 1},{  1,15, 0},{ -1,15, 0},{  2, 4, 1},{ -2, 4, 1},{  1,16, 0},
-      { -1,16, 0},{  2, 5, 1},{ -2, 5, 1},{  1,17, 0},{ -1,17, 0},{  4, 1, 3},
-      { -4, 1, 3},{  2, 6, 1},{ -2, 6, 1},{  1,18, 0},{ -1,18, 0},{  1,19, 0},
-      { -1,19, 0},{  2, 7, 1},{ -2, 7, 1},{  3, 2, 2},{ -3, 2, 2}
+    {
+        { //level / run
+            {  1,  1,  0 }, { -1,  1,  0 }, {     EOB    }, {  1,  2,  0 }, { -1,  2,  0 }, {  1,  3,  0 },
+            { -1,  3,  0 }, {  1,  4,  0 }, { -1,  4,  0 }, {  1,  5,  0 }, { -1,  5,  0 }, {  1,  6,  0 },
+            { -1,  6,  0 }, {  2,  1,  1 }, { -2,  1,  1 }, {  1,  7,  0 }, { -1,  7,  0 }, {  1,  8,  0 },
+            { -1,  8,  0 }, {  1,  9,  0 }, { -1,  9,  0 }, {  1, 10,  0 }, { -1, 10,  0 }, {  2,  2,  1 },
+            { -2,  2,  1 }, {  1, 11,  0 }, { -1, 11,  0 }, {  1, 12,  0 }, { -1, 12,  0 }, {  3,  1,  2 },
+            { -3,  1,  2 }, {  1, 13,  0 }, { -1, 13,  0 }, {  1, 14,  0 }, { -1, 14,  0 }, {  2,  3,  1 },
+            { -2,  3,  1 }, {  1, 15,  0 }, { -1, 15,  0 }, {  2,  4,  1 }, { -2,  4,  1 }, {  1, 16,  0 },
+            { -1, 16,  0 }, {  2,  5,  1 }, { -2,  5,  1 }, {  1, 17,  0 }, { -1, 17,  0 }, {  4,  1,  3 },
+            { -4,  1,  3 }, {  2,  6,  1 }, { -2,  6,  1 }, {  1, 18,  0 }, { -1, 18,  0 }, {  1, 19,  0 },
+            { -1, 19,  0 }, {  2,  7,  1 }, { -2,  7,  1 }, {  3,  2,  2 }, { -3,  2,  2 }
+        },
+        //level_add
+        { 0, 5, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1 },
+        2, //golomb_order
+        1, //inc_limit
+        19 //max_run
     },
-    //level_add
-    { 0, 5, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-      2, 2, 2,-1,-1,-1,-1,-1,-1,-1},
-    2, //golomb_order
-    1, //inc_limit
-    19 //max_run
-  },{
-    { //level / run
-      {  1, 1, 0},{ -1, 1, 0},{   EOB   },{  1, 2, 0},{ -1, 2, 0},{  2, 1, 0},
-      { -2, 1, 0},{  1, 3, 0},{ -1, 3, 0},{  1, 4, 0},{ -1, 4, 0},{  3, 1, 1},
-      { -3, 1, 1},{  2, 2, 0},{ -2, 2, 0},{  1, 5, 0},{ -1, 5, 0},{  1, 6, 0},
-      { -1, 6, 0},{  1, 7, 0},{ -1, 7, 0},{  2, 3, 0},{ -2, 3, 0},{  4, 1, 2},
-      { -4, 1, 2},{  1, 8, 0},{ -1, 8, 0},{  3, 2, 1},{ -3, 2, 1},{  2, 4, 0},
-      { -2, 4, 0},{  1, 9, 0},{ -1, 9, 0},{  1,10, 0},{ -1,10, 0},{  5, 1, 2},
-      { -5, 1, 2},{  2, 5, 0},{ -2, 5, 0},{  1,11, 0},{ -1,11, 0},{  2, 6, 0},
-      { -2, 6, 0},{  1,12, 0},{ -1,12, 0},{  3, 3, 1},{ -3, 3, 1},{  6, 1, 2},
-      { -6, 1, 2},{  4, 2, 2},{ -4, 2, 2},{  1,13, 0},{ -1,13, 0},{  2, 7, 0},
-      { -2, 7, 0},{  3, 4, 1},{ -3, 4, 1},{  1,14, 0},{ -1,14, 0}
+    {
+        { //level / run
+            {  1,  1,  0 }, { -1,  1,  0 }, {     EOB    }, {  1,  2,  0 }, { -1,  2,  0 }, {  2,  1,  0 },
+            { -2,  1,  0 }, {  1,  3,  0 }, { -1,  3,  0 }, {  1,  4,  0 }, { -1,  4,  0 }, {  3,  1,  1 },
+            { -3,  1,  1 }, {  2,  2,  0 }, { -2,  2,  0 }, {  1,  5,  0 }, { -1,  5,  0 }, {  1,  6,  0 },
+            { -1,  6,  0 }, {  1,  7,  0 }, { -1,  7,  0 }, {  2,  3,  0 }, { -2,  3,  0 }, {  4,  1,  2 },
+            { -4,  1,  2 }, {  1,  8,  0 }, { -1,  8,  0 }, {  3,  2,  1 }, { -3,  2,  1 }, {  2,  4,  0 },
+            { -2,  4,  0 }, {  1,  9,  0 }, { -1,  9,  0 }, {  1, 10,  0 }, { -1, 10,  0 }, {  5,  1,  2 },
+            { -5,  1,  2 }, {  2,  5,  0 }, { -2,  5,  0 }, {  1, 11,  0 }, { -1, 11,  0 }, {  2,  6,  0 },
+            { -2,  6,  0 }, {  1, 12,  0 }, { -1, 12,  0 }, {  3,  3,  1 }, { -3,  3,  1 }, {  6,  1,  2 },
+            { -6,  1,  2 }, {  4,  2,  2 }, { -4,  2,  2 }, {  1, 13,  0 }, { -1, 13,  0 }, {  2,  7,  0 },
+            { -2,  7,  0 }, {  3,  4,  1 }, { -3,  4,  1 }, {  1, 14,  0 }, { -1, 14,  0 }
+        },
+        //level_add
+        { 0, 7, 5, 4, 4, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+        2, //golomb_order
+        2, //inc_limit
+        14 //max_run
     },
-    //level_add
-    { 0, 7, 5, 4, 4, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2,-1,-1,
-      -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
-    2, //golomb_order
-    2, //inc_limit
-    14 //max_run
-  },{
-    { //level / run
-      {  1, 1, 0},{ -1, 1, 0},{   EOB   },{  2, 1, 0},{ -2, 1, 0},{  1, 2, 0},
-      { -1, 2, 0},{  3, 1, 0},{ -3, 1, 0},{  1, 3, 0},{ -1, 3, 0},{  2, 2, 0},
-      { -2, 2, 0},{  4, 1, 1},{ -4, 1, 1},{  1, 4, 0},{ -1, 4, 0},{  5, 1, 1},
-      { -5, 1, 1},{  1, 5, 0},{ -1, 5, 0},{  3, 2, 0},{ -3, 2, 0},{  2, 3, 0},
-      { -2, 3, 0},{  1, 6, 0},{ -1, 6, 0},{  6, 1, 1},{ -6, 1, 1},{  2, 4, 0},
-      { -2, 4, 0},{  1, 7, 0},{ -1, 7, 0},{  4, 2, 1},{ -4, 2, 1},{  7, 1, 2},
-      { -7, 1, 2},{  3, 3, 0},{ -3, 3, 0},{  1, 8, 0},{ -1, 8, 0},{  2, 5, 0},
-      { -2, 5, 0},{  8, 1, 2},{ -8, 1, 2},{  1, 9, 0},{ -1, 9, 0},{  3, 4, 0},
-      { -3, 4, 0},{  2, 6, 0},{ -2, 6, 0},{  5, 2, 1},{ -5, 2, 1},{  1,10, 0},
-      { -1,10, 0},{  9, 1, 2},{ -9, 1, 2},{  4, 3, 1},{ -4, 3, 1}
+    {
+        { //level / run
+            {  1,  1,  0 }, { -1,  1,  0 }, {     EOB    }, {  2,  1,  0 }, { -2,  1,  0 }, {  1,  2,  0 },
+            { -1,  2,  0 }, {  3,  1,  0 }, { -3,  1,  0 }, {  1,  3,  0 }, { -1,  3,  0 }, {  2,  2,  0 },
+            { -2,  2,  0 }, {  4,  1,  1 }, { -4,  1,  1 }, {  1,  4,  0 }, { -1,  4,  0 }, {  5,  1,  1 },
+            { -5,  1,  1 }, {  1,  5,  0 }, { -1,  5,  0 }, {  3,  2,  0 }, { -3,  2,  0 }, {  2,  3,  0 },
+            { -2,  3,  0 }, {  1,  6,  0 }, { -1,  6,  0 }, {  6,  1,  1 }, { -6,  1,  1 }, {  2,  4,  0 },
+            { -2,  4,  0 }, {  1,  7,  0 }, { -1,  7,  0 }, {  4,  2,  1 }, { -4,  2,  1 }, {  7,  1,  2 },
+            { -7,  1,  2 }, {  3,  3,  0 }, { -3,  3,  0 }, {  1,  8,  0 }, { -1,  8,  0 }, {  2,  5,  0 },
+            { -2,  5,  0 }, {  8,  1,  2 }, { -8,  1,  2 }, {  1,  9,  0 }, { -1,  9,  0 }, {  3,  4,  0 },
+            { -3,  4,  0 }, {  2,  6,  0 }, { -2,  6,  0 }, {  5,  2,  1 }, { -5,  2,  1 }, {  1, 10,  0 },
+            { -1, 10,  0 }, {  9,  1,  2 }, { -9,  1,  2 }, {  4,  3,  1 }, { -4,  3,  1 }
+        },
+        //level_add
+        { 0,10, 6, 5, 4, 3, 3, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+        2, //golomb_order
+        3, //inc_limit
+        10 //max_run
     },
-    //level_add
-    { 0,10, 6, 5, 4, 3, 3, 2, 2, 2, 2,-1,-1,-1,-1,-1,-1,
-     -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
-    2, //golomb_order
-    3, //inc_limit
-    10 //max_run
-  },{
-    { //level / run
-      {  1, 1, 0},{ -1, 1, 0},{   EOB   },{  2, 1, 0},{ -2, 1, 0},{  3, 1, 0},
-      { -3, 1, 0},{  1, 2, 0},{ -1, 2, 0},{  4, 1, 0},{ -4, 1, 0},{  5, 1, 0},
-      { -5, 1, 0},{  2, 2, 0},{ -2, 2, 0},{  1, 3, 0},{ -1, 3, 0},{  6, 1, 0},
-      { -6, 1, 0},{  3, 2, 0},{ -3, 2, 0},{  7, 1, 1},{ -7, 1, 1},{  1, 4, 0},
-      { -1, 4, 0},{  8, 1, 1},{ -8, 1, 1},{  2, 3, 0},{ -2, 3, 0},{  4, 2, 0},
-      { -4, 2, 0},{  1, 5, 0},{ -1, 5, 0},{  9, 1, 1},{ -9, 1, 1},{  5, 2, 0},
-      { -5, 2, 0},{  2, 4, 0},{ -2, 4, 0},{  1, 6, 0},{ -1, 6, 0},{ 10, 1, 2},
-      {-10, 1, 2},{  3, 3, 0},{ -3, 3, 0},{ 11, 1, 2},{-11, 1, 2},{  1, 7, 0},
-      { -1, 7, 0},{  6, 2, 0},{ -6, 2, 0},{  3, 4, 0},{ -3, 4, 0},{  2, 5, 0},
-      { -2, 5, 0},{ 12, 1, 2},{-12, 1, 2},{  4, 3, 0},{ -4, 3, 0}
+    {
+        { //level / run
+            {  1,  1,  0 }, { -1,  1,  0 }, {     EOB    }, {  2,  1,  0 }, { -2,  1,  0 }, {  3,  1,  0 },
+            { -3,  1,  0 }, {  1,  2,  0 }, { -1,  2,  0 }, {  4,  1,  0 }, { -4,  1,  0 }, {  5,  1,  0 },
+            { -5,  1,  0 }, {  2,  2,  0 }, { -2,  2,  0 }, {  1,  3,  0 }, { -1,  3,  0 }, {  6,  1,  0 },
+            { -6,  1,  0 }, {  3,  2,  0 }, { -3,  2,  0 }, {  7,  1,  1 }, { -7,  1,  1 }, {  1,  4,  0 },
+            { -1,  4,  0 }, {  8,  1,  1 }, { -8,  1,  1 }, {  2,  3,  0 }, { -2,  3,  0 }, {  4,  2,  0 },
+            { -4,  2,  0 }, {  1,  5,  0 }, { -1,  5,  0 }, {  9,  1,  1 }, { -9,  1,  1 }, {  5,  2,  0 },
+            { -5,  2,  0 }, {  2,  4,  0 }, { -2,  4,  0 }, {  1,  6,  0 }, { -1,  6,  0 }, { 10,  1,  2 },
+            {-10,  1,  2 }, {  3,  3,  0 }, { -3,  3,  0 }, { 11,  1,  2 }, {-11,  1,  2 }, {  1,  7,  0 },
+            { -1,  7,  0 }, {  6,  2,  0 }, { -6,  2,  0 }, {  3,  4,  0 }, { -3,  4,  0 }, {  2,  5,  0 },
+            { -2,  5,  0 }, { 12,  1,  2 }, {-12,  1,  2 }, {  4,  3,  0 }, { -4,  3,  0 }
+        },
+        //level_add
+        { 0, 13, 7, 5, 4, 3, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+        2, //golomb_order
+        6, //inc_limit
+        7  //max_run
     },
-    //level_add
-    { 0,13, 7, 5, 4, 3, 2, 2,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-     -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
-    2, //golomb_order
-    6, //inc_limit
-    7  //max_run
-  },{
-    { //level / run
-      {   EOB   },{  1, 1, 0},{ -1, 1, 0},{  2, 1, 0},{ -2, 1, 0},{  3, 1, 0},
-      { -3, 1, 0},{  4, 1, 0},{ -4, 1, 0},{  5, 1, 0},{ -5, 1, 0},{  1, 2, 0},
-      { -1, 2, 0},{  6, 1, 0},{ -6, 1, 0},{  7, 1, 0},{ -7, 1, 0},{  8, 1, 0},
-      { -8, 1, 0},{  2, 2, 0},{ -2, 2, 0},{  9, 1, 0},{ -9, 1, 0},{  1, 3, 0},
-      { -1, 3, 0},{ 10, 1, 1},{-10, 1, 1},{  3, 2, 0},{ -3, 2, 0},{ 11, 1, 1},
-      {-11, 1, 1},{  4, 2, 0},{ -4, 2, 0},{ 12, 1, 1},{-12, 1, 1},{  1, 4, 0},
-      { -1, 4, 0},{  2, 3, 0},{ -2, 3, 0},{ 13, 1, 1},{-13, 1, 1},{  5, 2, 0},
-      { -5, 2, 0},{ 14, 1, 1},{-14, 1, 1},{  6, 2, 0},{ -6, 2, 0},{  1, 5, 0},
-      { -1, 5, 0},{ 15, 1, 1},{-15, 1, 1},{  3, 3, 0},{ -3, 3, 0},{ 16, 1, 1},
-      {-16, 1, 1},{  2, 4, 0},{ -2, 4, 0},{  7, 2, 0},{ -7, 2, 0}
+    {
+        { //level / run
+            {      EOB    }, {  1,  1,  0 }, {  -1,  1,  0 }, {  2,  1,  0 }, {  -2,  1,  0 }, {  3,  1,  0 },
+            {  -3,  1,  0 }, {  4,  1,  0 }, {  -4,  1,  0 }, {  5,  1,  0 }, {  -5,  1,  0 }, {  1,  2,  0 },
+            {  -1,  2,  0 }, {  6,  1,  0 }, {  -6,  1,  0 }, {  7,  1,  0 }, {  -7,  1,  0 }, {  8,  1,  0 },
+            {  -8,  1,  0 }, {  2,  2,  0 }, {  -2,  2,  0 }, {  9,  1,  0 }, {  -9,  1,  0 }, {  1,  3,  0 },
+            {  -1,  3,  0 }, { 10,  1,  1 }, { -10,  1,  1 }, {  3,  2,  0 }, {  -3,  2,  0 }, { 11,  1,  1 },
+            { -11,  1,  1 }, {  4,  2,  0 }, {  -4,  2,  0 }, { 12,  1,  1 }, { -12,  1,  1 }, {  1,  4,  0 },
+            {  -1,  4,  0 }, {  2,  3,  0 }, {  -2,  3,  0 }, { 13,  1,  1 }, { -13,  1,  1 }, {  5,  2,  0 },
+            {  -5,  2,  0 }, { 14,  1,  1 }, { -14,  1,  1 }, {  6,  2,  0 }, {  -6,  2,  0 }, {  1,  5,  0 },
+            {  -1,  5,  0 }, { 15,  1,  1 }, { -15,  1,  1 }, {  3,  3,  0 }, {  -3,  3,  0 }, { 16,  1,  1 },
+            { -16,  1,  1 }, {  2,  4,  0 }, {  -2,  4,  0 }, {  7,  2,  0 }, {  -7,  2,  0 }
+        },
+        //level_add
+        { 0, 17, 8, 4, 3, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+        2, //golomb_order
+        9, //inc_limit
+        5  //max_run
     },
-    //level_add
-    { 0,17, 8, 4, 3, 2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-     -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
-    2, //golomb_order
-    9, //inc_limit
-    5  //max_run
-  },{
-    { //level / run
-      {   EOB   },{  1, 1, 0},{ -1, 1, 0},{  2, 1, 0},{ -2, 1, 0},{  3, 1, 0},
-      { -3, 1, 0},{  4, 1, 0},{ -4, 1, 0},{  5, 1, 0},{ -5, 1, 0},{  6, 1, 0},
-      { -6, 1, 0},{  7, 1, 0},{ -7, 1, 0},{  1, 2, 0},{ -1, 2, 0},{  8, 1, 0},
-      { -8, 1, 0},{  9, 1, 0},{ -9, 1, 0},{ 10, 1, 0},{-10, 1, 0},{ 11, 1, 0},
-      {-11, 1, 0},{ 12, 1, 0},{-12, 1, 0},{  2, 2, 0},{ -2, 2, 0},{ 13, 1, 0},
-      {-13, 1, 0},{  1, 3, 0},{ -1, 3, 0},{ 14, 1, 0},{-14, 1, 0},{ 15, 1, 0},
-      {-15, 1, 0},{  3, 2, 0},{ -3, 2, 0},{ 16, 1, 0},{-16, 1, 0},{ 17, 1, 0},
-      {-17, 1, 0},{ 18, 1, 0},{-18, 1, 0},{  4, 2, 0},{ -4, 2, 0},{ 19, 1, 0},
-      {-19, 1, 0},{ 20, 1, 0},{-20, 1, 0},{  2, 3, 0},{ -2, 3, 0},{  1, 4, 0},
-      { -1, 4, 0},{  5, 2, 0},{ -5, 2, 0},{ 21, 1, 0},{-21, 1, 0}
-    },
-    //level_add
-    { 0,22, 6, 3, 2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-     -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
-    2, //golomb_order
-    INT_MAX, //inc_limit
-    4 //max_run
-  }
+    {
+        { //level / run
+            {      EOB    }, {  1,  1,  0 }, {  -1,  1,  0 }, {  2,  1,  0 }, {  -2,  1,  0 }, {   3,  1,  0 },
+            {  -3,  1,  0 }, {  4,  1,  0 }, {  -4,  1,  0 }, {  5,  1,  0 }, {  -5,  1,  0 }, {   6,  1,  0 },
+            {  -6,  1,  0 }, {  7,  1,  0 }, {  -7,  1,  0 }, {  1,  2,  0 }, {  -1,  2,  0 }, {   8,  1,  0 },
+            {  -8,  1,  0 }, {  9,  1,  0 }, {  -9,  1,  0 }, { 10,  1,  0 }, { -10,  1,  0 }, {  11,  1,  0 },
+            { -11,  1,  0 }, { 12,  1,  0 }, { -12,  1,  0 }, {  2,  2,  0 }, {  -2,  2,  0 }, {  13,  1,  0 },
+            { -13,  1,  0 }, {  1,  3,  0 }, {  -1,  3,  0 }, { 14,  1,  0 }, { -14,  1,  0 }, {  15,  1,  0 },
+            { -15,  1,  0 }, {  3,  2,  0 }, {  -3,  2,  0 }, { 16,  1,  0 }, { -16,  1,  0 }, {  17,  1,  0 },
+            { -17,  1,  0 }, { 18,  1,  0 }, { -18,  1,  0 }, {  4,  2,  0 }, {  -4,  2,  0 }, {  19,  1,  0 },
+            { -19,  1,  0 }, { 20,  1,  0 }, { -20,  1,  0 }, {  2,  3,  0 }, {  -2,  3,  0 }, {   1,  4,  0 },
+            {  -1,  4,  0 }, {  5,  2,  0 }, {  -5,  2,  0 }, { 21,  1,  0 }, { -21,  1,  0 }
+        },
+        //level_add
+        { 0, 22, 6, 3, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+        2, //golomb_order
+        INT_MAX, //inc_limit
+        4 //max_run
+    }
 };
 
 static const struct dec_2dvlc chroma_dec[5] = {
-  {
-    { //level / run
-      {  1, 1, 1},{ -1, 1, 1},{  1, 2, 1},{ -1, 2, 1},{  1, 3, 1},{ -1, 3, 1},
-      {  1, 4, 1},{ -1, 4, 1},{  1, 5, 1},{ -1, 5, 1},{  1, 6, 1},{ -1, 6, 1},
-      {  1, 7, 1},{ -1, 7, 1},{  2, 1, 2},{ -2, 1, 2},{  1, 8, 1},{ -1, 8, 1},
-      {  1, 9, 1},{ -1, 9, 1},{  1,10, 1},{ -1,10, 1},{  1,11, 1},{ -1,11, 1},
-      {  1,12, 1},{ -1,12, 1},{  1,13, 1},{ -1,13, 1},{  1,14, 1},{ -1,14, 1},
-      {  1,15, 1},{ -1,15, 1},{  3, 1, 3},{ -3, 1, 3},{  1,16, 1},{ -1,16, 1},
-      {  1,17, 1},{ -1,17, 1},{  1,18, 1},{ -1,18, 1},{  1,19, 1},{ -1,19, 1},
-      {  1,20, 1},{ -1,20, 1},{  1,21, 1},{ -1,21, 1},{  1,22, 1},{ -1,22, 1},
-      {  2, 2, 2},{ -2, 2, 2},{  1,23, 1},{ -1,23, 1},{  1,24, 1},{ -1,24, 1},
-      {  1,25, 1},{ -1,25, 1},{  4, 1, 3},{ -4, 1, 3},{   EOB   }
+    {
+        { //level / run
+            {  1,  1,  1 }, { -1,  1,  1 }, {  1,  2,  1 }, { -1,  2,  1 }, {  1,  3,  1 }, { -1,  3,  1 },
+            {  1,  4,  1 }, { -1,  4,  1 }, {  1,  5,  1 }, { -1,  5,  1 }, {  1,  6,  1 }, { -1,  6,  1 },
+            {  1,  7,  1 }, { -1,  7,  1 }, {  2,  1,  2 }, { -2,  1,  2 }, {  1,  8,  1 }, { -1,  8,  1 },
+            {  1,  9,  1 }, { -1,  9,  1 }, {  1, 10,  1 }, { -1, 10,  1 }, {  1, 11,  1 }, { -1, 11,  1 },
+            {  1, 12,  1 }, { -1, 12,  1 }, {  1, 13,  1 }, { -1, 13,  1 }, {  1, 14,  1 }, { -1, 14,  1 },
+            {  1, 15,  1 }, { -1, 15,  1 }, {  3,  1,  3 }, { -3,  1,  3 }, {  1, 16,  1 }, { -1, 16,  1 },
+            {  1, 17,  1 }, { -1, 17,  1 }, {  1, 18,  1 }, { -1, 18,  1 }, {  1, 19,  1 }, { -1, 19,  1 },
+            {  1, 20,  1 }, { -1, 20,  1 }, {  1, 21,  1 }, { -1, 21,  1 }, {  1, 22,  1 }, { -1, 22,  1 },
+            {  2,  2,  2 }, { -2,  2,  2 }, {  1, 23,  1 }, { -1, 23,  1 }, {  1, 24,  1 }, { -1, 24,  1 },
+            {  1, 25,  1 }, { -1, 25,  1 }, {  4,  1,  3 }, { -4,  1,  3 }, {   EOB    }
+        },
+        //level_add
+        { 0, 5, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -1 },
+        2, //golomb_order
+        0, //inc_limit
+        25 //max_run
     },
-    //level_add
-    { 0, 5, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-      2, 2, 2, 2, 2, 2, 2, 2, 2,-1},
-    2, //golomb_order
-    0, //inc_limit
-    25 //max_run
-  },{
-    { //level / run
-      {   EOB   },{  1, 1, 0},{ -1, 1, 0},{  1, 2, 0},{ -1, 2, 0},{  2, 1, 1},
-      { -2, 1, 1},{  1, 3, 0},{ -1, 3, 0},{  1, 4, 0},{ -1, 4, 0},{  1, 5, 0},
-      { -1, 5, 0},{  1, 6, 0},{ -1, 6, 0},{  3, 1, 2},{ -3, 1, 2},{  1, 7, 0},
-      { -1, 7, 0},{  1, 8, 0},{ -1, 8, 0},{  2, 2, 1},{ -2, 2, 1},{  1, 9, 0},
-      { -1, 9, 0},{  1,10, 0},{ -1,10, 0},{  1,11, 0},{ -1,11, 0},{  4, 1, 2},
-      { -4, 1, 2},{  1,12, 0},{ -1,12, 0},{  1,13, 0},{ -1,13, 0},{  1,14, 0},
-      { -1,14, 0},{  2, 3, 1},{ -2, 3, 1},{  1,15, 0},{ -1,15, 0},{  2, 4, 1},
-      { -2, 4, 1},{  5, 1, 3},{ -5, 1, 3},{  3, 2, 2},{ -3, 2, 2},{  1,16, 0},
-      { -1,16, 0},{  1,17, 0},{ -1,17, 0},{  1,18, 0},{ -1,18, 0},{  2, 5, 1},
-      { -2, 5, 1},{  1,19, 0},{ -1,19, 0},{  1,20, 0},{ -1,20, 0}
+    {
+        { //level / run
+            {     EOB    }, {  1,  1,  0 }, { -1,  1,  0 }, {  1,  2,  0 }, { -1,  2,  0 }, {  2,  1,  1 },
+            { -2,  1,  1 }, {  1,  3,  0 }, { -1,  3,  0 }, {  1,  4,  0 }, { -1,  4,  0 }, {  1,  5,  0 },
+            { -1,  5,  0 }, {  1,  6,  0 }, { -1,  6,  0 }, {  3,  1,  2 }, { -3,  1,  2 }, {  1,  7,  0 },
+            { -1,  7,  0 }, {  1,  8,  0 }, { -1,  8,  0 }, {  2,  2,  1 }, { -2,  2,  1 }, {  1,  9,  0 },
+            { -1,  9,  0 }, {  1, 10,  0 }, { -1, 10,  0 }, {  1, 11,  0 }, { -1, 11,  0 }, {  4,  1,  2 },
+            { -4,  1,  2 }, {  1, 12,  0 }, { -1, 12,  0 }, {  1, 13,  0 }, { -1, 13,  0 }, {  1, 14,  0 },
+            { -1, 14,  0 }, {  2,  3,  1 }, { -2,  3,  1 }, {  1, 15,  0 }, { -1, 15,  0 }, {  2,  4,  1 },
+            { -2,  4,  1 }, {  5,  1,  3 }, { -5,  1,  3 }, {  3,  2,  2 }, { -3,  2,  2 }, {  1, 16,  0 },
+            { -1, 16,  0 }, {  1, 17,  0 }, { -1, 17,  0 }, {  1, 18,  0 }, { -1, 18,  0 }, {  2,  5,  1 },
+            { -2,  5,  1 }, {  1, 19,  0 }, { -1, 19,  0 }, {  1, 20,  0 }, { -1, 20,  0 }
+        },
+        //level_add
+        { 0, 6, 4, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1 },
+        0, //golomb_order
+        1, //inc_limit
+        20 //max_run
     },
-    //level_add
-    { 0, 6, 4, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-      2, 2, 2, 2,-1,-1,-1,-1,-1,-1},
-    0, //golomb_order
-    1, //inc_limit
-    20 //max_run
-  },{
-    { //level / run
-      {  1, 1, 0},{ -1, 1, 0},{   EOB   },{  2, 1, 0},{ -2, 1, 0},{  1, 2, 0},
-      { -1, 2, 0},{  3, 1, 1},{ -3, 1, 1},{  1, 3, 0},{ -1, 3, 0},{  4, 1, 1},
-      { -4, 1, 1},{  2, 2, 0},{ -2, 2, 0},{  1, 4, 0},{ -1, 4, 0},{  5, 1, 2},
-      { -5, 1, 2},{  1, 5, 0},{ -1, 5, 0},{  3, 2, 1},{ -3, 2, 1},{  2, 3, 0},
-      { -2, 3, 0},{  1, 6, 0},{ -1, 6, 0},{  6, 1, 2},{ -6, 1, 2},{  1, 7, 0},
-      { -1, 7, 0},{  2, 4, 0},{ -2, 4, 0},{  7, 1, 2},{ -7, 1, 2},{  1, 8, 0},
-      { -1, 8, 0},{  4, 2, 1},{ -4, 2, 1},{  1, 9, 0},{ -1, 9, 0},{  3, 3, 1},
-      { -3, 3, 1},{  2, 5, 0},{ -2, 5, 0},{  2, 6, 0},{ -2, 6, 0},{  8, 1, 2},
-      { -8, 1, 2},{  1,10, 0},{ -1,10, 0},{  1,11, 0},{ -1,11, 0},{  9, 1, 2},
-      { -9, 1, 2},{  5, 2, 2},{ -5, 2, 2},{  3, 4, 1},{ -3, 4, 1},
+    {
+        { //level / run
+            {  1,  1,  0 }, { -1,  1,  0 }, {     EOB    }, {  2,  1,  0 }, { -2,  1,  0 }, {  1,  2,  0 },
+            { -1,  2,  0 }, {  3,  1,  1 }, { -3,  1,  1 }, {  1,  3,  0 }, { -1,  3,  0 }, {  4,  1,  1 },
+            { -4,  1,  1 }, {  2,  2,  0 }, { -2,  2,  0 }, {  1,  4,  0 }, { -1,  4,  0 }, {  5,  1,  2 },
+            { -5,  1,  2 }, {  1,  5,  0 }, { -1,  5,  0 }, {  3,  2,  1 }, { -3,  2,  1 }, {  2,  3,  0 },
+            { -2,  3,  0 }, {  1,  6,  0 }, { -1,  6,  0 }, {  6,  1,  2 }, { -6,  1,  2 }, {  1,  7,  0 },
+            { -1,  7,  0 }, {  2,  4,  0 }, { -2,  4,  0 }, {  7,  1,  2 }, { -7,  1,  2 }, {  1,  8,  0 },
+            { -1,  8,  0 }, {  4,  2,  1 }, { -4,  2,  1 }, {  1,  9,  0 }, { -1,  9,  0 }, {  3,  3,  1 },
+            { -3,  3,  1 }, {  2,  5,  0 }, { -2,  5,  0 }, {  2,  6,  0 }, { -2,  6,  0 }, {  8,  1,  2 },
+            { -8,  1,  2 }, {  1, 10,  0 }, { -1, 10,  0 }, {  1, 11,  0 }, { -1, 11,  0 }, {  9,  1,  2 },
+            { -9,  1,  2 }, {  5,  2,  2 }, { -5,  2,  2 }, {  3,  4,  1 }, { -3,  4,  1 },
+        },
+        //level_add
+        { 0,10, 6, 4, 4, 3, 3, 2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+        1, //golomb_order
+        2, //inc_limit
+        11 //max_run
     },
-    //level_add
-    { 0,10, 6, 4, 4, 3, 3, 2, 2, 2, 2, 2,-1,-1,-1,-1,-1,
-     -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
-    1, //golomb_order
-    2, //inc_limit
-    11 //max_run
-  },{
-    { //level / run
-      {   EOB   },{  1, 1, 0},{ -1, 1, 0},{  2, 1, 0},{ -2, 1, 0},{  3, 1, 0},
-      { -3, 1, 0},{  4, 1, 0},{ -4, 1, 0},{  1, 2, 0},{ -1, 2, 0},{  5, 1, 1},
-      { -5, 1, 1},{  2, 2, 0},{ -2, 2, 0},{  6, 1, 1},{ -6, 1, 1},{  1, 3, 0},
-      { -1, 3, 0},{  7, 1, 1},{ -7, 1, 1},{  3, 2, 0},{ -3, 2, 0},{  8, 1, 1},
-      { -8, 1, 1},{  1, 4, 0},{ -1, 4, 0},{  2, 3, 0},{ -2, 3, 0},{  9, 1, 1},
-      { -9, 1, 1},{  4, 2, 0},{ -4, 2, 0},{  1, 5, 0},{ -1, 5, 0},{ 10, 1, 1},
-      {-10, 1, 1},{  3, 3, 0},{ -3, 3, 0},{  5, 2, 1},{ -5, 2, 1},{  2, 4, 0},
-      { -2, 4, 0},{ 11, 1, 1},{-11, 1, 1},{  1, 6, 0},{ -1, 6, 0},{ 12, 1, 1},
-      {-12, 1, 1},{  1, 7, 0},{ -1, 7, 0},{  6, 2, 1},{ -6, 2, 1},{ 13, 1, 1},
-      {-13, 1, 1},{  2, 5, 0},{ -2, 5, 0},{  1, 8, 0},{ -1, 8, 0},
+    {
+        { //level / run
+            {     EOB    }, {  1,  1,  0 }, { -1,  1,  0 }, {  2,  1,  0 }, { -2,  1,  0 }, {  3,  1,  0 },
+            { -3,  1,  0 }, {  4,  1,  0 }, { -4,  1,  0 }, {  1,  2,  0 }, { -1,  2,  0 }, {  5,  1,  1 },
+            { -5,  1,  1 }, {  2,  2,  0 }, { -2,  2,  0 }, {  6,  1,  1 }, { -6,  1,  1 }, {  1,  3,  0 },
+            { -1,  3,  0 }, {  7,  1,  1 }, { -7,  1,  1 }, {  3,  2,  0 }, { -3,  2,  0 }, {  8,  1,  1 },
+            { -8,  1,  1 }, {  1,  4,  0 }, { -1,  4,  0 }, {  2,  3,  0 }, { -2,  3,  0 }, {  9,  1,  1 },
+            { -9,  1,  1 }, {  4,  2,  0 }, { -4,  2,  0 }, {  1,  5,  0 }, { -1,  5,  0 }, { 10,  1,  1 },
+            {-10,  1,  1 }, {  3,  3,  0 }, { -3,  3,  0 }, {  5,  2,  1 }, { -5,  2,  1 }, {  2,  4,  0 },
+            { -2,  4,  0 }, { 11,  1,  1 }, {-11,  1,  1 }, {  1,  6,  0 }, { -1,  6,  0 }, { 12,  1,  1 },
+            {-12,  1,  1 }, {  1,  7,  0 }, { -1,  7,  0 }, {  6,  2,  1 }, { -6,  2,  1 }, { 13,  1,  1 },
+            {-13,  1,  1 }, {  2,  5,  0 }, { -2,  5,  0 }, {  1,  8,  0 }, { -1,  8,  0 },
+        },
+        //level_add
+        { 0, 14, 7, 4, 3, 3, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+        1, //golomb_order
+        4, //inc_limit
+        8  //max_run
     },
-    //level_add
-    { 0,14, 7, 4, 3, 3, 2, 2, 2,-1,-1,-1,-1,-1,-1,-1,-1,
-     -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
-    1, //golomb_order
-    4, //inc_limit
-    8  //max_run
-  },{
-    { //level / run
-      {   EOB   },{  1, 1, 0},{ -1, 1, 0},{  2, 1, 0},{ -2, 1, 0},{  3, 1, 0},
-      { -3, 1, 0},{  4, 1, 0},{ -4, 1, 0},{  5, 1, 0},{ -5, 1, 0},{  6, 1, 0},
-      { -6, 1, 0},{  7, 1, 0},{ -7, 1, 0},{  8, 1, 0},{ -8, 1, 0},{  1, 2, 0},
-      { -1, 2, 0},{  9, 1, 0},{ -9, 1, 0},{ 10, 1, 0},{-10, 1, 0},{ 11, 1, 0},
-      {-11, 1, 0},{  2, 2, 0},{ -2, 2, 0},{ 12, 1, 0},{-12, 1, 0},{ 13, 1, 0},
-      {-13, 1, 0},{  3, 2, 0},{ -3, 2, 0},{ 14, 1, 0},{-14, 1, 0},{  1, 3, 0},
-      { -1, 3, 0},{ 15, 1, 0},{-15, 1, 0},{  4, 2, 0},{ -4, 2, 0},{ 16, 1, 0},
-      {-16, 1, 0},{ 17, 1, 0},{-17, 1, 0},{  5, 2, 0},{ -5, 2, 0},{  1, 4, 0},
-      { -1, 4, 0},{  2, 3, 0},{ -2, 3, 0},{ 18, 1, 0},{-18, 1, 0},{  6, 2, 0},
-      { -6, 2, 0},{ 19, 1, 0},{-19, 1, 0},{  1, 5, 0},{ -1, 5, 0},
-    },
-    //level_add
-    { 0,20, 7, 3, 2, 2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-     -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
-    0, //golomb_order
-    INT_MAX, //inc_limit
-    5, //max_run
-  }
+    {
+        { //level / run
+            {      EOB    }, {  1,  1,  0 }, {  -1,  1,  0 }, {  2,  1,  0 }, {  -2,  1,  0 }, {  3,  1,  0 },
+            {  -3,  1,  0 }, {  4,  1,  0 }, {  -4,  1,  0 }, {  5,  1,  0 }, {  -5,  1,  0 }, {  6,  1,  0 },
+            {  -6,  1,  0 }, {  7,  1,  0 }, {  -7,  1,  0 }, {  8,  1,  0 }, {  -8,  1,  0 }, {  1,  2,  0 },
+            {  -1,  2,  0 }, {  9,  1,  0 }, {  -9,  1,  0 }, { 10,  1,  0 }, { -10,  1,  0 }, { 11,  1,  0 },
+            { -11,  1,  0 }, {  2,  2,  0 }, {  -2,  2,  0 }, { 12,  1,  0 }, { -12,  1,  0 }, { 13,  1,  0 },
+            { -13,  1,  0 }, {  3,  2,  0 }, {  -3,  2,  0 }, { 14,  1,  0 }, { -14,  1,  0 }, {  1,  3,  0 },
+            {  -1,  3,  0 }, { 15,  1,  0 }, { -15,  1,  0 }, {  4,  2,  0 }, {  -4,  2,  0 }, { 16,  1,  0 },
+            { -16,  1,  0 }, { 17,  1,  0 }, { -17,  1,  0 }, {  5,  2,  0 }, {  -5,  2,  0 }, {  1,  4,  0 },
+            {  -1,  4,  0 }, {  2,  3,  0 }, {  -2,  3,  0 }, { 18,  1,  0 }, { -18,  1,  0 }, {  6,  2,  0 },
+            {  -6,  2,  0 }, { 19,  1,  0 }, { -19,  1,  0 }, {  1,  5,  0 }, {  -1,  5,  0 },
+        },
+        //level_add
+        { 0, 20, 7, 3, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+        0, //golomb_order
+        INT_MAX, //inc_limit
+        5, //max_run
+    }
 };
 
 #undef EOB
@@ -461,15 +461,17 @@
  *
  ****************************************************************************/
 
-static inline void store_mvs(AVSContext *h) {
-    h->col_mv[h->mbidx*4 + 0] = h->mv[MV_FWD_X0];
-    h->col_mv[h->mbidx*4 + 1] = h->mv[MV_FWD_X1];
-    h->col_mv[h->mbidx*4 + 2] = h->mv[MV_FWD_X2];
-    h->col_mv[h->mbidx*4 + 3] = h->mv[MV_FWD_X3];
+static inline void store_mvs(AVSContext *h)
+{
+    h->col_mv[h->mbidx * 4 + 0] = h->mv[MV_FWD_X0];
+    h->col_mv[h->mbidx * 4 + 1] = h->mv[MV_FWD_X1];
+    h->col_mv[h->mbidx * 4 + 2] = h->mv[MV_FWD_X2];
+    h->col_mv[h->mbidx * 4 + 3] = h->mv[MV_FWD_X3];
 }
 
 static inline void mv_pred_direct(AVSContext *h, cavs_vector *pmv_fw,
-                                  cavs_vector *col_mv) {
+                                  cavs_vector *col_mv)
+{
     cavs_vector *pmv_bw = pmv_fw + MV_BWD_OFFS;
     int den = h->direct_den[col_mv->ref];
     int m = col_mv->x >> 31;
@@ -479,14 +481,16 @@
     pmv_fw->ref = 1;
     pmv_bw->ref = 0;
     /* scale the co-located motion vector according to its temporal span */
-    pmv_fw->x = (((den+(den*col_mv->x*pmv_fw->dist^m)-m-1)>>14)^m)-m;
-    pmv_bw->x = m-(((den+(den*col_mv->x*pmv_bw->dist^m)-m-1)>>14)^m);
+    pmv_fw->x =     (((den + (den * col_mv->x * pmv_fw->dist ^ m) - m - 1) >> 14) ^ m) - m;
+    pmv_bw->x = m - (((den + (den * col_mv->x * pmv_bw->dist ^ m) - m - 1) >> 14) ^ m);
     m = col_mv->y >> 31;
-    pmv_fw->y = (((den+(den*col_mv->y*pmv_fw->dist^m)-m-1)>>14)^m)-m;
-    pmv_bw->y = m-(((den+(den*col_mv->y*pmv_bw->dist^m)-m-1)>>14)^m);
+    pmv_fw->y =     (((den + (den * col_mv->y * pmv_fw->dist ^ m) - m - 1) >> 14) ^ m) - m;
+    pmv_bw->y = m - (((den + (den * col_mv->y * pmv_bw->dist ^ m) - m - 1) >> 14) ^ m);
 }
 
-static inline void mv_pred_sym(AVSContext *h, cavs_vector *src, enum cavs_block size) {
+static inline void mv_pred_sym(AVSContext *h, cavs_vector *src,
+                               enum cavs_block size)
+{
     cavs_vector *dst = src + MV_BWD_OFFS;
 
     /* backward mv is the scaled and negated forward mv */
@@ -504,30 +508,36 @@
  ****************************************************************************/
 
 /** kth-order exponential golomb code */
-static inline int get_ue_code(GetBitContext *gb, int order) {
-    if(order) {
-        int ret = get_ue_golomb(gb) << order;
-        return ret + get_bits(gb,order);
+static inline int get_ue_code(GetBitContext *gb, int order)
+{
+    unsigned ret = get_ue_golomb(gb);
+    if (ret >= ((1U<<31)>>order)) {
+        av_log(NULL, AV_LOG_ERROR, "get_ue_code: value too larger\n");
+        return AVERROR_INVALIDDATA;
     }
-    return get_ue_golomb(gb);
+    if (order) {
+        return (ret<<order) + get_bits(gb, order);
+    }
+    return ret;
 }
 
-static inline int dequant(AVSContext *h, DCTELEM *level_buf, uint8_t *run_buf,
-                          DCTELEM *dst, int mul, int shift, int coeff_num) {
+static inline int dequant(AVSContext *h, int16_t *level_buf, uint8_t *run_buf,
+                          int16_t *dst, int mul, int shift, int coeff_num)
+{
     int round = 1 << (shift - 1);
     int pos = -1;
     const uint8_t *scantab = h->scantable.permutated;
 
     /* inverse scan and dequantization */
-    while(--coeff_num >= 0){
+    while (--coeff_num >= 0) {
         pos += run_buf[coeff_num];
-        if(pos > 63) {
-            av_log(h->s.avctx, AV_LOG_ERROR,
-                "position out of block bounds at pic %d MB(%d,%d)\n",
-                h->picture.poc, h->mbx, h->mby);
+        if (pos > 63) {
+            av_log(h->avctx, AV_LOG_ERROR,
+                   "position out of block bounds at pic %d MB(%d,%d)\n",
+                   h->cur.poc, h->mbx, h->mby);
             return -1;
         }
-        dst[scantab[pos]] = (level_buf[coeff_num]*mul + round) >> shift;
+        dst[scantab[pos]] = (level_buf[coeff_num] * mul + round) >> shift;
     }
     return 0;
 }
@@ -543,70 +553,73 @@
  */
 static int decode_residual_block(AVSContext *h, GetBitContext *gb,
                                  const struct dec_2dvlc *r, int esc_golomb_order,
-                                 int qp, uint8_t *dst, int stride) {
+                                 int qp, uint8_t *dst, int stride)
+{
     int i, esc_code, level, mask;
     unsigned int level_code, run;
-    DCTELEM level_buf[65];
+    int16_t level_buf[65];
     uint8_t run_buf[65];
-    DCTELEM *block = h->block;
+    int16_t *block = h->block;
 
-    for(i=0;i<65;i++) {
-        level_code = get_ue_code(gb,r->golomb_order);
-        if(level_code >= ESCAPE_CODE) {
-            run = ((level_code - ESCAPE_CODE) >> 1) + 1;
+    for (i = 0; i < 65; i++) {
+        level_code = get_ue_code(gb, r->golomb_order);
+        if (level_code >= ESCAPE_CODE) {
+            run      = ((level_code - ESCAPE_CODE) >> 1) + 1;
             if(run > 64)
                 return -1;
-            esc_code = get_ue_code(gb,esc_golomb_order);
-            level = esc_code + (run > r->max_run ? 1 : r->level_add[run]);
-            while(level > r->inc_limit)
+            esc_code = get_ue_code(gb, esc_golomb_order);
+            level    = esc_code + (run > r->max_run ? 1 : r->level_add[run]);
+            while (level > r->inc_limit)
                 r++;
-            mask = -(level_code & 1);
-            level = (level^mask) - mask;
+            mask  = -(level_code & 1);
+            level = (level ^ mask) - mask;
         } else {
             level = r->rltab[level_code][0];
-            if(!level) //end of block signal
+            if (!level) //end of block signal
                 break;
-            run   = r->rltab[level_code][1];
-            r += r->rltab[level_code][2];
+            run = r->rltab[level_code][1];
+            r  += r->rltab[level_code][2];
         }
         level_buf[i] = level;
-        run_buf[i] = run;
+        run_buf[i]   = run;
     }
     if (dequant(h, level_buf, run_buf, block, dequant_mul[qp],
                 dequant_shift[qp], i))
         return -1;
-    h->cdsp.cavs_idct8_add(dst,block,stride);
-    h->s.dsp.clear_block(block);
+    h->cdsp.cavs_idct8_add(dst, block, stride);
+    h->dsp.clear_block(block);
     return 0;
 }
 
 
-static inline void decode_residual_chroma(AVSContext *h) {
-    if(h->cbp & (1<<4))
-        decode_residual_block(h, &h->s.gb, chroma_dec, 0,
+static inline void decode_residual_chroma(AVSContext *h)
+{
+    if (h->cbp & (1 << 4))
+        decode_residual_block(h, &h->gb, chroma_dec, 0,
                               cavs_chroma_qp[h->qp], h->cu, h->c_stride);
-    if(h->cbp & (1<<5))
-        decode_residual_block(h, &h->s.gb, chroma_dec, 0,
+    if (h->cbp & (1 << 5))
+        decode_residual_block(h, &h->gb, chroma_dec, 0,
                               cavs_chroma_qp[h->qp], h->cv, h->c_stride);
 }
 
-static inline int decode_residual_inter(AVSContext *h) {
+static inline int decode_residual_inter(AVSContext *h)
+{
     int block;
 
     /* get coded block pattern */
-    int cbp= get_ue_golomb(&h->s.gb);
-    if(cbp > 63U){
-        av_log(h->s.avctx, AV_LOG_ERROR, "illegal inter cbp\n");
+    int cbp = get_ue_golomb(&h->gb);
+    if (cbp > 63U) {
+        av_log(h->avctx, AV_LOG_ERROR, "illegal inter cbp\n");
         return -1;
     }
     h->cbp = cbp_tab[cbp][1];
 
     /* get quantizer */
-    if(h->cbp && !h->qp_fixed)
-        h->qp = (h->qp + get_se_golomb(&h->s.gb)) & 63;
-    for(block=0;block<4;block++)
-        if(h->cbp & (1<<block))
-            decode_residual_block(h, &h->s.gb, inter_dec, 0, h->qp,
+    if (h->cbp && !h->qp_fixed)
+        h->qp = (h->qp + get_se_golomb(&h->gb)) & 63;
+    for (block = 0; block < 4; block++)
+        if (h->cbp & (1 << block))
+            decode_residual_block(h, &h->gb, inter_dec, 0, h->qp,
                                   h->cy + h->luma_scan[block], h->l_stride);
     decode_residual_chroma(h);
 
@@ -619,17 +632,19 @@
  *
  ****************************************************************************/
 
-static inline void set_mv_intra(AVSContext *h) {
+static inline void set_mv_intra(AVSContext *h)
+{
     h->mv[MV_FWD_X0] = ff_cavs_intra_mv;
     set_mvs(&h->mv[MV_FWD_X0], BLK_16X16);
     h->mv[MV_BWD_X0] = ff_cavs_intra_mv;
     set_mvs(&h->mv[MV_BWD_X0], BLK_16X16);
-    if(h->pic_type != AV_PICTURE_TYPE_B)
+    if (h->cur.f->pict_type != AV_PICTURE_TYPE_B)
         h->col_type_base[h->mbidx] = I_8X8;
 }
 
-static int decode_mb_i(AVSContext *h, int cbp_code) {
-    GetBitContext *gb = &h->s.gb;
+static int decode_mb_i(AVSContext *h, int cbp_code)
+{
+    GetBitContext *gb = &h->gb;
     unsigned pred_mode_uv;
     int block;
     uint8_t top[18];
@@ -639,84 +654,86 @@
     ff_cavs_init_mb(h);
 
     /* get intra prediction modes from stream */
-    for(block=0;block<4;block++) {
-        int nA,nB,predpred;
+    for (block = 0; block < 4; block++) {
+        int nA, nB, predpred;
         int pos = scan3x3[block];
 
-        nA = h->pred_mode_Y[pos-1];
-        nB = h->pred_mode_Y[pos-3];
-        predpred = FFMIN(nA,nB);
-        if(predpred == NOT_AVAIL) // if either is not available
+        nA = h->pred_mode_Y[pos - 1];
+        nB = h->pred_mode_Y[pos - 3];
+        predpred = FFMIN(nA, nB);
+        if (predpred == NOT_AVAIL) // if either is not available
             predpred = INTRA_L_LP;
-        if(!get_bits1(gb)){
-            int rem_mode= get_bits(gb, 2);
-            predpred = rem_mode + (rem_mode >= predpred);
+        if (!get_bits1(gb)) {
+            int rem_mode = get_bits(gb, 2);
+            predpred     = rem_mode + (rem_mode >= predpred);
         }
         h->pred_mode_Y[pos] = predpred;
     }
     pred_mode_uv = get_ue_golomb(gb);
-    if(pred_mode_uv > 6) {
-        av_log(h->s.avctx, AV_LOG_ERROR, "illegal intra chroma pred mode\n");
+    if (pred_mode_uv > 6) {
+        av_log(h->avctx, AV_LOG_ERROR, "illegal intra chroma pred mode\n");
         return -1;
     }
     ff_cavs_modify_mb_i(h, &pred_mode_uv);
 
     /* get coded block pattern */
-    if(h->pic_type == AV_PICTURE_TYPE_I)
+    if (h->cur.f->pict_type == AV_PICTURE_TYPE_I)
         cbp_code = get_ue_golomb(gb);
-    if(cbp_code > 63U){
-        av_log(h->s.avctx, AV_LOG_ERROR, "illegal intra cbp\n");
+    if (cbp_code > 63U) {
+        av_log(h->avctx, AV_LOG_ERROR, "illegal intra cbp\n");
         return -1;
     }
     h->cbp = cbp_tab[cbp_code][0];
-    if(h->cbp && !h->qp_fixed)
+    if (h->cbp && !h->qp_fixed)
         h->qp = (h->qp + get_se_golomb(gb)) & 63; //qp_delta
 
     /* luma intra prediction interleaved with residual decode/transform/add */
-    for(block=0;block<4;block++) {
+    for (block = 0; block < 4; block++) {
         d = h->cy + h->luma_scan[block];
         ff_cavs_load_intra_pred_luma(h, top, &left, block);
         h->intra_pred_l[h->pred_mode_Y[scan3x3[block]]]
             (d, top, left, h->l_stride);
-        if(h->cbp & (1<<block))
+        if (h->cbp & (1<<block))
             decode_residual_block(h, gb, intra_dec, 1, h->qp, d, h->l_stride);
     }
 
     /* chroma intra prediction */
     ff_cavs_load_intra_pred_chroma(h);
-    h->intra_pred_c[pred_mode_uv](h->cu, &h->top_border_u[h->mbx*10],
+    h->intra_pred_c[pred_mode_uv](h->cu, &h->top_border_u[h->mbx * 10],
                                   h->left_border_u, h->c_stride);
-    h->intra_pred_c[pred_mode_uv](h->cv, &h->top_border_v[h->mbx*10],
+    h->intra_pred_c[pred_mode_uv](h->cv, &h->top_border_v[h->mbx * 10],
                                   h->left_border_v, h->c_stride);
 
     decode_residual_chroma(h);
-    ff_cavs_filter(h,I_8X8);
+    ff_cavs_filter(h, I_8X8);
     set_mv_intra(h);
     return 0;
 }
 
-static inline void set_intra_mode_default(AVSContext *h) {
-    if(h->stream_revision > 0) {
+static inline void set_intra_mode_default(AVSContext *h)
+{
+    if (h->stream_revision > 0) {
         h->pred_mode_Y[3] =  h->pred_mode_Y[6] = NOT_AVAIL;
-        h->top_pred_Y[h->mbx*2+0] = h->top_pred_Y[h->mbx*2+1] = NOT_AVAIL;
+        h->top_pred_Y[h->mbx * 2 + 0] = h->top_pred_Y[h->mbx * 2 + 1] = NOT_AVAIL;
     } else {
         h->pred_mode_Y[3] =  h->pred_mode_Y[6] = INTRA_L_LP;
-        h->top_pred_Y[h->mbx*2+0] = h->top_pred_Y[h->mbx*2+1] = INTRA_L_LP;
+        h->top_pred_Y[h->mbx * 2 + 0] = h->top_pred_Y[h->mbx * 2 + 1] = INTRA_L_LP;
     }
 }
 
-static void decode_mb_p(AVSContext *h, enum cavs_mb mb_type) {
-    GetBitContext *gb = &h->s.gb;
+static void decode_mb_p(AVSContext *h, enum cavs_mb mb_type)
+{
+    GetBitContext *gb = &h->gb;
     int ref[4];
 
     ff_cavs_init_mb(h);
-    switch(mb_type) {
+    switch (mb_type) {
     case P_SKIP:
         ff_cavs_mv(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_PSKIP,  BLK_16X16, 0);
         break;
     case P_16X16:
         ref[0] = h->ref_flag ? 0 : get_bits1(gb);
-        ff_cavs_mv(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_MEDIAN, BLK_16X16,ref[0]);
+        ff_cavs_mv(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_MEDIAN, BLK_16X16, ref[0]);
         break;
     case P_16X8:
         ref[0] = h->ref_flag ? 0 : get_bits1(gb);
@@ -727,8 +744,8 @@
     case P_8X16:
         ref[0] = h->ref_flag ? 0 : get_bits1(gb);
         ref[1] = h->ref_flag ? 0 : get_bits1(gb);
-        ff_cavs_mv(h, MV_FWD_X0, MV_FWD_B3, MV_PRED_LEFT,   BLK_8X16, ref[0]);
-        ff_cavs_mv(h, MV_FWD_X1, MV_FWD_C2, MV_PRED_TOPRIGHT,BLK_8X16, ref[1]);
+        ff_cavs_mv(h, MV_FWD_X0, MV_FWD_B3, MV_PRED_LEFT,     BLK_8X16, ref[0]);
+        ff_cavs_mv(h, MV_FWD_X1, MV_FWD_C2, MV_PRED_TOPRIGHT, BLK_8X16, ref[1]);
         break;
     case P_8X8:
         ref[0] = h->ref_flag ? 0 : get_bits1(gb);
@@ -743,13 +760,14 @@
     ff_cavs_inter(h, mb_type);
     set_intra_mode_default(h);
     store_mvs(h);
-    if(mb_type != P_SKIP)
+    if (mb_type != P_SKIP)
         decode_residual_inter(h);
-    ff_cavs_filter(h,mb_type);
+    ff_cavs_filter(h, mb_type);
     h->col_type_base[h->mbidx] = mb_type;
 }
 
-static int decode_mb_b(AVSContext *h, enum cavs_mb mb_type) {
+static int decode_mb_b(AVSContext *h, enum cavs_mb mb_type)
+{
     int block;
     enum cavs_sub_mb sub_type[4];
     int flags;
@@ -761,18 +779,18 @@
     set_mvs(&h->mv[MV_FWD_X0], BLK_16X16);
     h->mv[MV_BWD_X0] = ff_cavs_dir_mv;
     set_mvs(&h->mv[MV_BWD_X0], BLK_16X16);
-    switch(mb_type) {
+    switch (mb_type) {
     case B_SKIP:
     case B_DIRECT:
-        if(!h->col_type_base[h->mbidx]) {
+        if (!h->col_type_base[h->mbidx]) {
             /* intra MB at co-location, do in-plane prediction */
             ff_cavs_mv(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_BSKIP, BLK_16X16, 1);
             ff_cavs_mv(h, MV_BWD_X0, MV_BWD_C2, MV_PRED_BSKIP, BLK_16X16, 0);
         } else
             /* direct prediction from co-located P MB, block-wise */
-            for(block=0;block<4;block++)
-                mv_pred_direct(h,&h->mv[mv_scan[block]],
-                                 &h->col_mv[h->mbidx*4 + block]);
+            for (block = 0; block < 4; block++)
+                mv_pred_direct(h, &h->mv[mv_scan[block]],
+                               &h->col_mv[h->mbidx * 4 + block]);
         break;
     case B_FWD_16X16:
         ff_cavs_mv(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_MEDIAN, BLK_16X16, 1);
@@ -785,80 +803,80 @@
         ff_cavs_mv(h, MV_BWD_X0, MV_BWD_C2, MV_PRED_MEDIAN, BLK_16X16, 0);
         break;
     case B_8X8:
-        for(block=0;block<4;block++)
-            sub_type[block] = get_bits(&h->s.gb,2);
-        for(block=0;block<4;block++) {
-            switch(sub_type[block]) {
+        for (block = 0; block < 4; block++)
+            sub_type[block] = get_bits(&h->gb, 2);
+        for (block = 0; block < 4; block++) {
+            switch (sub_type[block]) {
             case B_SUB_DIRECT:
-                if(!h->col_type_base[h->mbidx]) {
+                if (!h->col_type_base[h->mbidx]) {
                     /* intra MB at co-location, do in-plane prediction */
-                    ff_cavs_mv(h, mv_scan[block], mv_scan[block]-3,
-                            MV_PRED_BSKIP, BLK_8X8, 1);
-                    ff_cavs_mv(h, mv_scan[block]+MV_BWD_OFFS,
-                            mv_scan[block]-3+MV_BWD_OFFS,
-                            MV_PRED_BSKIP, BLK_8X8, 0);
+                    ff_cavs_mv(h, mv_scan[block], mv_scan[block] - 3,
+                               MV_PRED_BSKIP, BLK_8X8, 1);
+                    ff_cavs_mv(h, mv_scan[block] + MV_BWD_OFFS,
+                               mv_scan[block] - 3 + MV_BWD_OFFS,
+                               MV_PRED_BSKIP, BLK_8X8, 0);
                 } else
-                    mv_pred_direct(h,&h->mv[mv_scan[block]],
-                                   &h->col_mv[h->mbidx*4 + block]);
+                    mv_pred_direct(h, &h->mv[mv_scan[block]],
+                                   &h->col_mv[h->mbidx * 4 + block]);
                 break;
             case B_SUB_FWD:
-                ff_cavs_mv(h, mv_scan[block], mv_scan[block]-3,
-                        MV_PRED_MEDIAN, BLK_8X8, 1);
+                ff_cavs_mv(h, mv_scan[block], mv_scan[block] - 3,
+                           MV_PRED_MEDIAN, BLK_8X8, 1);
                 break;
             case B_SUB_SYM:
-                ff_cavs_mv(h, mv_scan[block], mv_scan[block]-3,
-                        MV_PRED_MEDIAN, BLK_8X8, 1);
+                ff_cavs_mv(h, mv_scan[block], mv_scan[block] - 3,
+                           MV_PRED_MEDIAN, BLK_8X8, 1);
                 mv_pred_sym(h, &h->mv[mv_scan[block]], BLK_8X8);
                 break;
             }
         }
-        for(block=0;block<4;block++) {
-            if(sub_type[block] == B_SUB_BWD)
-                ff_cavs_mv(h, mv_scan[block]+MV_BWD_OFFS,
-                        mv_scan[block]+MV_BWD_OFFS-3,
-                        MV_PRED_MEDIAN, BLK_8X8, 0);
+        for (block = 0; block < 4; block++) {
+            if (sub_type[block] == B_SUB_BWD)
+                ff_cavs_mv(h, mv_scan[block] + MV_BWD_OFFS,
+                           mv_scan[block] + MV_BWD_OFFS - 3,
+                           MV_PRED_MEDIAN, BLK_8X8, 0);
         }
         break;
     default:
         if (mb_type <= B_SYM_16X16) {
-            av_log(h->s.avctx, AV_LOG_ERROR, "Invalid mb_type %d in B frame\n", mb_type);
+            av_log(h->avctx, AV_LOG_ERROR, "Invalid mb_type %d in B frame\n", mb_type);
             return AVERROR_INVALIDDATA;
         }
         av_assert2(mb_type < B_8X8);
         flags = ff_cavs_partition_flags[mb_type];
-        if(mb_type & 1) { /* 16x8 macroblock types */
-            if(flags & FWD0)
+        if (mb_type & 1) { /* 16x8 macroblock types */
+            if (flags & FWD0)
                 ff_cavs_mv(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_TOP,  BLK_16X8, 1);
-            if(flags & SYM0)
+            if (flags & SYM0)
                 mv_pred_sym(h, &h->mv[MV_FWD_X0], BLK_16X8);
-            if(flags & FWD1)
+            if (flags & FWD1)
                 ff_cavs_mv(h, MV_FWD_X2, MV_FWD_A1, MV_PRED_LEFT, BLK_16X8, 1);
-            if(flags & SYM1)
+            if (flags & SYM1)
                 mv_pred_sym(h, &h->mv[MV_FWD_X2], BLK_16X8);
-            if(flags & BWD0)
+            if (flags & BWD0)
                 ff_cavs_mv(h, MV_BWD_X0, MV_BWD_C2, MV_PRED_TOP,  BLK_16X8, 0);
-            if(flags & BWD1)
+            if (flags & BWD1)
                 ff_cavs_mv(h, MV_BWD_X2, MV_BWD_A1, MV_PRED_LEFT, BLK_16X8, 0);
         } else {          /* 8x16 macroblock types */
-            if(flags & FWD0)
+            if (flags & FWD0)
                 ff_cavs_mv(h, MV_FWD_X0, MV_FWD_B3, MV_PRED_LEFT, BLK_8X16, 1);
-            if(flags & SYM0)
+            if (flags & SYM0)
                 mv_pred_sym(h, &h->mv[MV_FWD_X0], BLK_8X16);
-            if(flags & FWD1)
-                ff_cavs_mv(h,MV_FWD_X1,MV_FWD_C2,MV_PRED_TOPRIGHT,BLK_8X16,1);
-            if(flags & SYM1)
+            if (flags & FWD1)
+                ff_cavs_mv(h, MV_FWD_X1, MV_FWD_C2, MV_PRED_TOPRIGHT, BLK_8X16, 1);
+            if (flags & SYM1)
                 mv_pred_sym(h, &h->mv[MV_FWD_X1], BLK_8X16);
-            if(flags & BWD0)
+            if (flags & BWD0)
                 ff_cavs_mv(h, MV_BWD_X0, MV_BWD_B3, MV_PRED_LEFT, BLK_8X16, 0);
-            if(flags & BWD1)
-                ff_cavs_mv(h,MV_BWD_X1,MV_BWD_C2,MV_PRED_TOPRIGHT,BLK_8X16,0);
+            if (flags & BWD1)
+                ff_cavs_mv(h, MV_BWD_X1, MV_BWD_C2, MV_PRED_TOPRIGHT, BLK_8X16, 0);
         }
     }
     ff_cavs_inter(h, mb_type);
     set_intra_mode_default(h);
-    if(mb_type != B_SKIP)
+    if (mb_type != B_SKIP)
         decode_residual_inter(h);
-    ff_cavs_filter(h,mb_type);
+    ff_cavs_filter(h, mb_type);
 
     return 0;
 }
@@ -869,47 +887,50 @@
  *
  ****************************************************************************/
 
-static inline int decode_slice_header(AVSContext *h, GetBitContext *gb) {
-    if(h->stc > 0xAF)
-        av_log(h->s.avctx, AV_LOG_ERROR, "unexpected start code 0x%02x\n", h->stc);
+static inline int decode_slice_header(AVSContext *h, GetBitContext *gb)
+{
+    if (h->stc > 0xAF)
+        av_log(h->avctx, AV_LOG_ERROR, "unexpected start code 0x%02x\n", h->stc);
 
     if (h->stc >= h->mb_height)
         return -1;
 
-    h->mby = h->stc;
-    h->mbidx = h->mby*h->mb_width;
+    h->mby   = h->stc;
+    h->mbidx = h->mby * h->mb_width;
 
     /* mark top macroblocks as unavailable */
-    h->flags &= ~(B_AVAIL|C_AVAIL);
-    if((h->mby == 0) && (!h->qp_fixed)){
+    h->flags &= ~(B_AVAIL | C_AVAIL);
+    if ((h->mby == 0) && (!h->qp_fixed)) {
         h->qp_fixed = get_bits1(gb);
-        h->qp = get_bits(gb,6);
+        h->qp       = get_bits(gb, 6);
     }
     /* inter frame or second slice can have weighting params */
-    if((h->pic_type != AV_PICTURE_TYPE_I) || (!h->pic_structure && h->mby >= h->mb_width/2))
-        if(get_bits1(gb)) { //slice_weighting_flag
-            av_log(h->s.avctx, AV_LOG_ERROR,
+    if ((h->cur.f->pict_type != AV_PICTURE_TYPE_I) ||
+        (!h->pic_structure && h->mby >= h->mb_width / 2))
+        if (get_bits1(gb)) { //slice_weighting_flag
+            av_log(h->avctx, AV_LOG_ERROR,
                    "weighted prediction not yet supported\n");
         }
     return 0;
 }
 
-static inline int check_for_slice(AVSContext *h) {
-    GetBitContext *gb = &h->s.gb;
+static inline int check_for_slice(AVSContext *h)
+{
+    GetBitContext *gb = &h->gb;
     int align;
 
-    if(h->mbx)
+    if (h->mbx)
         return 0;
     align = (-get_bits_count(gb)) & 7;
     /* check for stuffing byte */
-    if(!align && (show_bits(gb,8) == 0x80))
+    if (!align && (show_bits(gb, 8) == 0x80))
         align = 8;
-    if((show_bits_long(gb,24+align) & 0xFFFFFF) == 0x000001) {
-        skip_bits_long(gb,24+align);
-        h->stc = get_bits(gb,8);
+    if ((show_bits_long(gb, 24 + align) & 0xFFFFFF) == 0x000001) {
+        skip_bits_long(gb, 24 + align);
+        h->stc = get_bits(gb, 8);
         if (h->stc >= h->mb_height)
             return 0;
-        decode_slice_header(h,gb);
+        decode_slice_header(h, gb);
         return 1;
     }
     return 0;
@@ -921,140 +942,143 @@
  *
  ****************************************************************************/
 
-static int decode_pic(AVSContext *h) {
-    MpegEncContext *s = &h->s;
-    int skip_count = -1;
+static int decode_pic(AVSContext *h)
+{
+    int skip_count    = -1;
+    int ret;
     enum cavs_mb mb_type;
 
-    if (!s->context_initialized) {
-        if (ff_MPV_common_init(s) < 0)
-            return -1;
-        ff_init_scantable_permutation(s->dsp.idct_permutation,
-                                      h->cdsp.idct_perm);
-        ff_init_scantable(s->dsp.idct_permutation,&h->scantable,ff_zigzag_direct);
-    }
-    skip_bits(&s->gb,16);//bbv_dwlay
-    if(h->stc == PIC_PB_START_CODE) {
-        h->pic_type = get_bits(&s->gb,2) + AV_PICTURE_TYPE_I;
-        if(h->pic_type > AV_PICTURE_TYPE_B) {
-            av_log(s->avctx, AV_LOG_ERROR, "illegal picture type\n");
+    skip_bits(&h->gb, 16);//bbv_dwlay
+    if (h->stc == PIC_PB_START_CODE) {
+        h->cur.f->pict_type = get_bits(&h->gb, 2) + AV_PICTURE_TYPE_I;
+        if (h->cur.f->pict_type > AV_PICTURE_TYPE_B) {
+            av_log(h->avctx, AV_LOG_ERROR, "illegal picture type\n");
             return -1;
         }
         /* make sure we have the reference frames we need */
-        if(!h->DPB[0].f.data[0] ||
-          (!h->DPB[1].f.data[0] && h->pic_type == AV_PICTURE_TYPE_B))
+        if (!h->DPB[0].f->data[0] ||
+           (!h->DPB[1].f->data[0] && h->cur.f->pict_type == AV_PICTURE_TYPE_B))
             return -1;
     } else {
-        h->pic_type = AV_PICTURE_TYPE_I;
-        if(get_bits1(&s->gb))
-            skip_bits(&s->gb,24);//time_code
+        h->cur.f->pict_type = AV_PICTURE_TYPE_I;
+        if (get_bits1(&h->gb))
+            skip_bits(&h->gb, 24);//time_code
         /* old sample clips were all progressive and no low_delay,
            bump stream revision if detected otherwise */
-        if (s->low_delay || !(show_bits(&s->gb,9) & 1))
+        if (h->low_delay || !(show_bits(&h->gb, 9) & 1))
             h->stream_revision = 1;
         /* similarly test top_field_first and repeat_first_field */
-        else if(show_bits(&s->gb,11) & 3)
+        else if (show_bits(&h->gb, 11) & 3)
             h->stream_revision = 1;
-        if(h->stream_revision > 0)
-            skip_bits(&s->gb,1); //marker_bit
+        if (h->stream_revision > 0)
+            skip_bits(&h->gb, 1); //marker_bit
     }
     /* release last B frame */
-    if(h->picture.f.data[0])
-        s->avctx->release_buffer(s->avctx, &h->picture.f);
+    if (h->cur.f->data[0])
+        h->avctx->release_buffer(h->avctx, h->cur.f);
 
-    s->avctx->get_buffer(s->avctx, &h->picture.f);
-    ff_cavs_init_pic(h);
-    h->picture.poc = get_bits(&s->gb,8)*2;
+    if ((ret = ff_get_buffer(h->avctx, h->cur.f)) < 0)
+        return ret;
+
+    if (!h->edge_emu_buffer) {
+        int alloc_size = FFALIGN(FFABS(h->cur.f->linesize[0]) + 32, 32);
+        h->edge_emu_buffer = av_mallocz(alloc_size * 2 * 24);
+        if (!h->edge_emu_buffer)
+            return AVERROR(ENOMEM);
+    }
+
+    if ((ret = ff_cavs_init_pic(h)) < 0)
+        return ret;
+    h->cur.poc = get_bits(&h->gb, 8) * 2;
 
     /* get temporal distances and MV scaling factors */
-    if(h->pic_type != AV_PICTURE_TYPE_B) {
-        h->dist[0] = (h->picture.poc - h->DPB[0].poc  + 512) % 512;
+    if (h->cur.f->pict_type != AV_PICTURE_TYPE_B) {
+        h->dist[0] = (h->cur.poc - h->DPB[0].poc  + 512) % 512;
     } else {
-        h->dist[0] = (h->DPB[0].poc  - h->picture.poc + 512) % 512;
+        h->dist[0] = (h->DPB[0].poc  - h->cur.poc + 512) % 512;
     }
-    h->dist[1] = (h->picture.poc - h->DPB[1].poc  + 512) % 512;
+    h->dist[1] = (h->cur.poc - h->DPB[1].poc  + 512) % 512;
     h->scale_den[0] = h->dist[0] ? 512/h->dist[0] : 0;
     h->scale_den[1] = h->dist[1] ? 512/h->dist[1] : 0;
-    if(h->pic_type == AV_PICTURE_TYPE_B) {
-        h->sym_factor = h->dist[0]*h->scale_den[1];
+    if (h->cur.f->pict_type == AV_PICTURE_TYPE_B) {
+        h->sym_factor = h->dist[0] * h->scale_den[1];
     } else {
-        h->direct_den[0] = h->dist[0] ? 16384/h->dist[0] : 0;
-        h->direct_den[1] = h->dist[1] ? 16384/h->dist[1] : 0;
+        h->direct_den[0] = h->dist[0] ? 16384 / h->dist[0] : 0;
+        h->direct_den[1] = h->dist[1] ? 16384 / h->dist[1] : 0;
     }
 
-    if(s->low_delay)
-        get_ue_golomb(&s->gb); //bbv_check_times
-    h->progressive             = get_bits1(&s->gb);
+    if (h->low_delay)
+        get_ue_golomb(&h->gb); //bbv_check_times
+    h->progressive   = get_bits1(&h->gb);
     h->pic_structure = 1;
-    if(!h->progressive)
-        h->pic_structure = get_bits1(&s->gb);
-    if(!h->pic_structure && h->stc == PIC_PB_START_CODE)
-        skip_bits1(&s->gb);     //advanced_pred_mode_disable
-    skip_bits1(&s->gb);        //top_field_first
-    skip_bits1(&s->gb);        //repeat_first_field
-    h->qp_fixed                = get_bits1(&s->gb);
-    h->qp                      = get_bits(&s->gb,6);
-    if(h->pic_type == AV_PICTURE_TYPE_I) {
-        if(!h->progressive && !h->pic_structure)
-            skip_bits1(&s->gb);//what is this?
-        skip_bits(&s->gb,4);   //reserved bits
+    if (!h->progressive)
+        h->pic_structure = get_bits1(&h->gb);
+    if (!h->pic_structure && h->stc == PIC_PB_START_CODE)
+        skip_bits1(&h->gb);     //advanced_pred_mode_disable
+    skip_bits1(&h->gb);        //top_field_first
+    skip_bits1(&h->gb);        //repeat_first_field
+    h->qp_fixed = get_bits1(&h->gb);
+    h->qp       = get_bits(&h->gb, 6);
+    if (h->cur.f->pict_type == AV_PICTURE_TYPE_I) {
+        if (!h->progressive && !h->pic_structure)
+            skip_bits1(&h->gb);//what is this?
+        skip_bits(&h->gb, 4);   //reserved bits
     } else {
-        if(!(h->pic_type == AV_PICTURE_TYPE_B && h->pic_structure == 1))
-            h->ref_flag        = get_bits1(&s->gb);
-        skip_bits(&s->gb,4);   //reserved bits
-        h->skip_mode_flag      = get_bits1(&s->gb);
+        if (!(h->cur.f->pict_type == AV_PICTURE_TYPE_B && h->pic_structure == 1))
+            h->ref_flag        = get_bits1(&h->gb);
+        skip_bits(&h->gb, 4);   //reserved bits
+        h->skip_mode_flag      = get_bits1(&h->gb);
     }
-    h->loop_filter_disable     = get_bits1(&s->gb);
-    if(!h->loop_filter_disable && get_bits1(&s->gb)) {
-        h->alpha_offset        = get_se_golomb(&s->gb);
-        h->beta_offset         = get_se_golomb(&s->gb);
+    h->loop_filter_disable     = get_bits1(&h->gb);
+    if (!h->loop_filter_disable && get_bits1(&h->gb)) {
+        h->alpha_offset        = get_se_golomb(&h->gb);
+        h->beta_offset         = get_se_golomb(&h->gb);
     } else {
         h->alpha_offset = h->beta_offset  = 0;
     }
-    if(h->pic_type == AV_PICTURE_TYPE_I) {
+    if (h->cur.f->pict_type == AV_PICTURE_TYPE_I) {
         do {
             check_for_slice(h);
             decode_mb_i(h, 0);
-        } while(ff_cavs_next_mb(h));
-    } else if(h->pic_type == AV_PICTURE_TYPE_P) {
+        } while (ff_cavs_next_mb(h));
+    } else if (h->cur.f->pict_type == AV_PICTURE_TYPE_P) {
         do {
-            if(check_for_slice(h))
+            if (check_for_slice(h))
                 skip_count = -1;
-            if(h->skip_mode_flag && (skip_count < 0))
-                skip_count = get_ue_golomb(&s->gb);
-            if(h->skip_mode_flag && skip_count--) {
-                decode_mb_p(h,P_SKIP);
+            if (h->skip_mode_flag && (skip_count < 0))
+                skip_count = get_ue_golomb(&h->gb);
+            if (h->skip_mode_flag && skip_count--) {
+                decode_mb_p(h, P_SKIP);
             } else {
-                mb_type = get_ue_golomb(&s->gb) + P_SKIP + h->skip_mode_flag;
-                if(mb_type > P_8X8)
+                mb_type = get_ue_golomb(&h->gb) + P_SKIP + h->skip_mode_flag;
+                if (mb_type > P_8X8)
                     decode_mb_i(h, mb_type - P_8X8 - 1);
                 else
-                    decode_mb_p(h,mb_type);
+                    decode_mb_p(h, mb_type);
             }
-        } while(ff_cavs_next_mb(h));
+        } while (ff_cavs_next_mb(h));
     } else { /* AV_PICTURE_TYPE_B */
         do {
-            if(check_for_slice(h))
+            if (check_for_slice(h))
                 skip_count = -1;
-            if(h->skip_mode_flag && (skip_count < 0))
-                skip_count = get_ue_golomb(&s->gb);
-            if(h->skip_mode_flag && skip_count--) {
-                decode_mb_b(h,B_SKIP);
+            if (h->skip_mode_flag && (skip_count < 0))
+                skip_count = get_ue_golomb(&h->gb);
+            if (h->skip_mode_flag && skip_count--) {
+                decode_mb_b(h, B_SKIP);
             } else {
-                mb_type = get_ue_golomb(&s->gb) + B_SKIP + h->skip_mode_flag;
-                if(mb_type > B_8X8)
+                mb_type = get_ue_golomb(&h->gb) + B_SKIP + h->skip_mode_flag;
+                if (mb_type > B_8X8)
                     decode_mb_i(h, mb_type - B_8X8 - 1);
                 else
-                    decode_mb_b(h,mb_type);
+                    decode_mb_b(h, mb_type);
             }
-        } while(ff_cavs_next_mb(h));
+        } while (ff_cavs_next_mb(h));
     }
-    if(h->pic_type != AV_PICTURE_TYPE_B) {
-        if(h->DPB[1].f.data[0])
-            s->avctx->release_buffer(s->avctx, &h->DPB[1].f);
-        h->DPB[1] = h->DPB[0];
-        h->DPB[0] = h->picture;
-        memset(&h->picture,0,sizeof(Picture));
+    if (h->cur.f->pict_type != AV_PICTURE_TYPE_B) {
+        if (h->DPB[1].f->data[0])
+            h->avctx->release_buffer(h->avctx, h->DPB[1].f);
+        FFSWAP(AVSFrame, h->cur, h->DPB[1]);
+        FFSWAP(AVSFrame, h->DPB[0], h->DPB[1]);
     }
     return 0;
 }
@@ -1065,71 +1089,72 @@
  *
  ****************************************************************************/
 
-static int decode_seq_header(AVSContext *h) {
-    MpegEncContext *s = &h->s;
+static int decode_seq_header(AVSContext *h)
+{
     int frame_rate_code;
     int width, height;
 
-    h->profile =         get_bits(&s->gb,8);
-    h->level =           get_bits(&s->gb,8);
-    skip_bits1(&s->gb); //progressive sequence
+    h->profile = get_bits(&h->gb, 8);
+    h->level   = get_bits(&h->gb, 8);
+    skip_bits1(&h->gb); //progressive sequence
 
-    width  = get_bits(&s->gb, 14);
-    height = get_bits(&s->gb, 14);
-    if ((s->width || s->height) && (s->width != width || s->height != height)) {
-        av_log_missing_feature(s, "Width/height changing in CAVS", 0);
+    width  = get_bits(&h->gb, 14);
+    height = get_bits(&h->gb, 14);
+    if ((h->width || h->height) && (h->width != width || h->height != height)) {
+        av_log_missing_feature(h->avctx, "Width/height changing in CAVS", 0);
         return AVERROR_PATCHWELCOME;
     }
     if (width <= 0 || height <= 0) {
-        av_log(s, AV_LOG_ERROR, "Dimensions invalid\n");
+        av_log(h->avctx, AV_LOG_ERROR, "Dimensions invalid\n");
         return AVERROR_INVALIDDATA;
     }
-    s->width  = width;
-    s->height = height;
+    h->width  = width;
+    h->height = height;
 
-    skip_bits(&s->gb,2); //chroma format
-    skip_bits(&s->gb,3); //sample_precision
-    h->aspect_ratio =    get_bits(&s->gb,4);
-    frame_rate_code =    get_bits(&s->gb,4);
-    skip_bits(&s->gb,18);//bit_rate_lower
-    skip_bits1(&s->gb);  //marker_bit
-    skip_bits(&s->gb,12);//bit_rate_upper
-    s->low_delay =       get_bits1(&s->gb);
-    h->mb_width  = (s->width  + 15) >> 4;
-    h->mb_height = (s->height + 15) >> 4;
-    h->s.avctx->time_base.den = ff_mpeg12_frame_rate_tab[frame_rate_code].num;
-    h->s.avctx->time_base.num = ff_mpeg12_frame_rate_tab[frame_rate_code].den;
-    h->s.avctx->width  = s->width;
-    h->s.avctx->height = s->height;
-    if(!h->top_qp)
+    skip_bits(&h->gb, 2); //chroma format
+    skip_bits(&h->gb, 3); //sample_precision
+    h->aspect_ratio = get_bits(&h->gb, 4);
+    frame_rate_code = get_bits(&h->gb, 4);
+    skip_bits(&h->gb, 18); //bit_rate_lower
+    skip_bits1(&h->gb);    //marker_bit
+    skip_bits(&h->gb, 12); //bit_rate_upper
+    h->low_delay =  get_bits1(&h->gb);
+    h->mb_width  = (h->width  + 15) >> 4;
+    h->mb_height = (h->height + 15) >> 4;
+    h->avctx->time_base.den = ff_mpeg12_frame_rate_tab[frame_rate_code].num;
+    h->avctx->time_base.num = ff_mpeg12_frame_rate_tab[frame_rate_code].den;
+    h->avctx->width  = h->width;
+    h->avctx->height = h->height;
+    if (!h->top_qp)
         ff_cavs_init_top_lines(h);
     return 0;
 }
 
-static void cavs_flush(AVCodecContext * avctx) {
+static void cavs_flush(AVCodecContext * avctx)
+{
     AVSContext *h = avctx->priv_data;
     h->got_keyframe = 0;
 }
 
-static int cavs_decode_frame(AVCodecContext * avctx,void *data, int *data_size,
-                             AVPacket *avpkt) {
+static int cavs_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
+                             AVPacket *avpkt)
+{
+    AVSContext *h      = avctx->priv_data;
     const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
-    AVSContext *h = avctx->priv_data;
-    MpegEncContext *s = &h->s;
+    int buf_size       = avpkt->size;
+    AVFrame *picture   = data;
+    uint32_t stc       = -1;
     int input_size;
     const uint8_t *buf_end;
     const uint8_t *buf_ptr;
-    AVFrame *picture = data;
-    uint32_t stc = -1;
-
-    s->avctx = avctx;
 
     if (buf_size == 0) {
-        if (!s->low_delay && h->DPB[0].f.data[0]) {
-            *data_size = sizeof(AVPicture);
-            *picture = h->DPB[0].f;
-            memset(&h->DPB[0], 0, sizeof(h->DPB[0]));
+        if (!h->low_delay && h->DPB[0].f->data[0]) {
+            *got_frame = 1;
+            *picture = *h->DPB[0].f;
+            if (h->cur.f->data[0])
+                avctx->release_buffer(avctx, h->cur.f);
+            FFSWAP(AVSFrame, h->cur, h->DPB[0]);
         }
         return 0;
     }
@@ -1137,53 +1162,53 @@
     buf_ptr = buf;
     buf_end = buf + buf_size;
     for(;;) {
-        buf_ptr = avpriv_mpv_find_start_code(buf_ptr,buf_end, &stc);
-        if((stc & 0xFFFFFE00) || buf_ptr == buf_end)
-            return FFMAX(0, buf_ptr - buf - s->parse_context.last_index);
-        input_size = (buf_end - buf_ptr)*8;
-        switch(stc) {
+        buf_ptr = avpriv_mpv_find_start_code(buf_ptr, buf_end, &stc);
+        if ((stc & 0xFFFFFE00) || buf_ptr == buf_end)
+            return FFMAX(0, buf_ptr - buf);
+        input_size = (buf_end - buf_ptr) * 8;
+        switch (stc) {
         case CAVS_START_CODE:
-            init_get_bits(&s->gb, buf_ptr, input_size);
+            init_get_bits(&h->gb, buf_ptr, input_size);
             decode_seq_header(h);
             break;
         case PIC_I_START_CODE:
-            if(!h->got_keyframe) {
-                if(h->DPB[0].f.data[0])
-                    avctx->release_buffer(avctx, &h->DPB[0].f);
-                if(h->DPB[1].f.data[0])
-                    avctx->release_buffer(avctx, &h->DPB[1].f);
+            if (!h->got_keyframe) {
+                if(h->DPB[0].f->data[0])
+                    avctx->release_buffer(avctx, h->DPB[0].f);
+                if(h->DPB[1].f->data[0])
+                    avctx->release_buffer(avctx, h->DPB[1].f);
                 h->got_keyframe = 1;
             }
         case PIC_PB_START_CODE:
-            *data_size = 0;
-            if(!h->got_keyframe)
+            *got_frame = 0;
+            if (!h->got_keyframe)
                 break;
             if(!h->top_qp)
                 break;
-            init_get_bits(&s->gb, buf_ptr, input_size);
+            init_get_bits(&h->gb, buf_ptr, input_size);
             h->stc = stc;
-            if(decode_pic(h))
+            if (decode_pic(h))
                 break;
-            *data_size = sizeof(AVPicture);
-            if(h->pic_type != AV_PICTURE_TYPE_B) {
-                if(h->DPB[1].f.data[0]) {
-                    *picture = h->DPB[1].f;
+            *got_frame = 1;
+            if (h->cur.f->pict_type != AV_PICTURE_TYPE_B) {
+                if (h->DPB[1].f->data[0]) {
+                    *picture = *h->DPB[1].f;
                 } else {
-                    *data_size = 0;
+                    *got_frame = 0;
                 }
             } else
-                *picture = h->picture.f;
+                *picture = *h->cur.f;
             break;
         case EXT_START_CODE:
-            //mpeg_decode_extension(avctx,buf_ptr, input_size);
+            //mpeg_decode_extension(avctx, buf_ptr, input_size);
             break;
         case USER_START_CODE:
-            //mpeg_decode_user_data(avctx,buf_ptr, input_size);
+            //mpeg_decode_user_data(avctx, buf_ptr, input_size);
             break;
         default:
             if (stc <= SLICE_MAX_START_CODE) {
-                init_get_bits(&s->gb, buf_ptr, input_size);
-                decode_slice_header(h, &s->gb);
+                init_get_bits(&h->gb, buf_ptr, input_size);
+                decode_slice_header(h, &h->gb);
             }
             break;
         }
diff --git a/libavcodec/cavsdsp.c b/libavcodec/cavsdsp.c
index a9b136e..f66cabc 100644
--- a/libavcodec/cavsdsp.c
+++ b/libavcodec/cavsdsp.c
@@ -183,9 +183,9 @@
  *
  ****************************************************************************/
 
-static void cavs_idct8_add_c(uint8_t *dst, DCTELEM *block, int stride) {
+static void cavs_idct8_add_c(uint8_t *dst, int16_t *block, int stride) {
     int i;
-    DCTELEM (*src)[8] = (DCTELEM(*)[8])block;
+    int16_t (*src)[8] = (int16_t(*)[8])block;
     uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
 
     src[0][0] += 8;
diff --git a/libavcodec/cavsdsp.h b/libavcodec/cavsdsp.h
index f6e3e18..4598c7d 100644
--- a/libavcodec/cavsdsp.h
+++ b/libavcodec/cavsdsp.h
@@ -32,7 +32,7 @@
     void (*cavs_filter_lh)(uint8_t *pix, int stride, int alpha, int beta, int tc, int bs1, int bs2);
     void (*cavs_filter_cv)(uint8_t *pix, int stride, int alpha, int beta, int tc, int bs1, int bs2);
     void (*cavs_filter_ch)(uint8_t *pix, int stride, int alpha, int beta, int tc, int bs1, int bs2);
-    void (*cavs_idct8_add)(uint8_t *dst, DCTELEM *block, int stride);
+    void (*cavs_idct8_add)(uint8_t *dst, int16_t *block, int stride);
     int idct_perm;
 } CAVSDSPContext;
 
diff --git a/libavcodec/cdgraphics.c b/libavcodec/cdgraphics.c
index eb31532..202211d 100644
--- a/libavcodec/cdgraphics.c
+++ b/libavcodec/cdgraphics.c
@@ -21,6 +21,7 @@
 
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 
 /**
  * @file
@@ -266,7 +267,7 @@
 }
 
 static int cdg_decode_frame(AVCodecContext *avctx,
-                            void *data, int *data_size, AVPacket *avpkt)
+                            void *data, int *got_frame, AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
@@ -290,6 +291,10 @@
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
         return ret;
     }
+    if (!avctx->frame_number) {
+        memset(cc->frame.data[0], 0, cc->frame.linesize[0] * avctx->height);
+        memset(cc->frame.data[1], 0, AVPALETTE_SIZE);
+    }
 
     command = bytestream_get_byte(&buf);
     inst    = bytestream_get_byte(&buf);
@@ -337,7 +342,7 @@
             }
 
             cdg_init_frame(&new_frame);
-            ret = avctx->get_buffer(avctx, &new_frame);
+            ret = ff_get_buffer(avctx, &new_frame);
             if (ret) {
                 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
                 return ret;
@@ -351,9 +356,9 @@
             break;
         }
 
-        *data_size = sizeof(AVFrame);
+        *got_frame = 1;
     } else {
-        *data_size = 0;
+        *got_frame = 0;
         buf_size   = 0;
     }
 
diff --git a/libavcodec/cdxl.c b/libavcodec/cdxl.c
index abcd073..e10ce4b 100644
--- a/libavcodec/cdxl.c
+++ b/libavcodec/cdxl.c
@@ -23,6 +23,7 @@
 #include "libavutil/imgutils.h"
 #include "avcodec.h"
 #include "get_bits.h"
+#include "internal.h"
 
 #define BIT_PLANAR   0x00
 #define CHUNKY       0x20
@@ -116,6 +117,7 @@
 {
     uint32_t *new_palette = (uint32_t *)c->frame.data[1];
 
+    memset(c->frame.data[1], 0, AVPALETTE_SIZE);
     import_palette(c, new_palette);
     import_format(c, c->frame.linesize[0], c->frame.data[0]);
 }
@@ -207,7 +209,7 @@
 }
 
 static int cdxl_decode_frame(AVCodecContext *avctx, void *data,
-                             int *data_size, AVPacket *pkt)
+                             int *got_frame, AVPacket *pkt)
 {
     CDXLVideoContext *c = avctx->priv_data;
     AVFrame * const p = &c->frame;
@@ -262,7 +264,7 @@
         avctx->release_buffer(avctx, p);
 
     p->reference = 0;
-    if ((ret = avctx->get_buffer(avctx, p)) < 0) {
+    if ((ret = ff_get_buffer(avctx, p)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -280,7 +282,7 @@
     } else {
         cdxl_decode_rgb(c);
     }
-    *data_size      = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*)data = c->frame;
 
     return buf_size;
diff --git a/libavcodec/cinepak.c b/libavcodec/cinepak.c
index 9ae63b7..5bd3f13 100644
--- a/libavcodec/cinepak.c
+++ b/libavcodec/cinepak.c
@@ -28,6 +28,9 @@
  *   http://www.csse.monash.edu.au/~timf/
  * @see For more information on the quirky data inside Sega FILM/CPK files, visit:
  *   http://wiki.multimedia.cx/index.php?title=Sega_FILM
+ *
+ * Cinepak colorspace support (c) 2013 Rl, Aetey Global Technologies AB
+ * @author Cinepak colorspace, Rl, Aetey Global Technologies AB
  */
 
 #include <stdio.h>
@@ -39,10 +42,7 @@
 #include "avcodec.h"
 
 
-typedef struct {
-    uint8_t  y0, y1, y2, y3;
-    uint8_t  u, v;
-} cvid_codebook;
+typedef uint8_t cvid_codebook[12];
 
 #define MAX_STRIPS      32
 
@@ -78,12 +78,14 @@
     const uint8_t *eod = (data + size);
     uint32_t flag, mask;
     int      i, n;
+    uint8_t *p;
 
     /* check if this chunk contains 4- or 6-element vectors */
     n    = (chunk_id & 0x04) ? 4 : 6;
     flag = 0;
     mask = 0;
 
+    p = codebook[0];
     for (i=0; i < 256; i++) {
         if ((chunk_id & 0x01) && !(mask >>= 1)) {
             if ((data + 4) > eod)
@@ -95,28 +97,33 @@
         }
 
         if (!(chunk_id & 0x01) || (flag & mask)) {
+            int k, kk;
+
             if ((data + n) > eod)
                 break;
 
-            if (n == 6) {
-                codebook[i].y0 = *data++;
-                codebook[i].y1 = *data++;
-                codebook[i].y2 = *data++;
-                codebook[i].y3 = *data++;
-                codebook[i].u  = 128 + *data++;
-                codebook[i].v  = 128 + *data++;
-            } else {
-                /* this codebook type indicates either greyscale or
-                 * palettized video; if palettized, U & V components will
-                 * not be used so it is safe to set them to 128 for the
-                 * benefit of greyscale rendering in YUV420P */
-                codebook[i].y0 = *data++;
-                codebook[i].y1 = *data++;
-                codebook[i].y2 = *data++;
-                codebook[i].y3 = *data++;
-                codebook[i].u  = 128;
-                codebook[i].v  = 128;
+            for (k = 0; k < 4; ++k) {
+                int r = *data++;
+                for (kk = 0; kk < 3; ++kk)
+                    *p++ = r;
             }
+            if (n == 6) {
+                int r, g, b, u, v;
+                u = *(int8_t *)data++;
+                v = *(int8_t *)data++;
+                p -= 12;
+                for(k=0; k<4; ++k) {
+                    r = *p++ + v*2;
+                    g = *p++ - (u/2) - v;
+                    b = *p   + u*2;
+                    p -= 2;
+                    *p++ = av_clip_uint8(r);
+                    *p++ = av_clip_uint8(g);
+                    *p++ = av_clip_uint8(b);
+                }
+            }
+        } else {
+            p += 12;
         }
     }
 }
@@ -126,25 +133,31 @@
 {
     const uint8_t   *eod = (data + size);
     uint32_t         flag, mask;
-    cvid_codebook   *codebook;
+    uint8_t         *cb0, *cb1, *cb2, *cb3;
     unsigned int     x, y;
-    uint32_t         iy[4];
-    uint32_t         iu[2];
-    uint32_t         iv[2];
+    char            *ip0, *ip1, *ip2, *ip3;
 
     flag = 0;
     mask = 0;
 
     for (y=strip->y1; y < strip->y2; y+=4) {
 
-        iy[0] = strip->x1 + (y * s->frame.linesize[0]);
-        iy[1] = iy[0] + s->frame.linesize[0];
-        iy[2] = iy[1] + s->frame.linesize[0];
-        iy[3] = iy[2] + s->frame.linesize[0];
-        iu[0] = (strip->x1/2) + ((y/2) * s->frame.linesize[1]);
-        iu[1] = iu[0] + s->frame.linesize[1];
-        iv[0] = (strip->x1/2) + ((y/2) * s->frame.linesize[2]);
-        iv[1] = iv[0] + s->frame.linesize[2];
+/* take care of y dimension not being multiple of 4, such streams exist */
+        ip0 = ip1 = ip2 = ip3 = s->frame.data[0] +
+          (s->palette_video?strip->x1:strip->x1*3) + (y * s->frame.linesize[0]);
+        if(s->avctx->height - y > 1) {
+            ip1 = ip0 + s->frame.linesize[0];
+            if(s->avctx->height - y > 2) {
+                ip2 = ip1 + s->frame.linesize[0];
+                if(s->avctx->height - y > 3) {
+                    ip3 = ip2 + s->frame.linesize[0];
+                }
+            }
+        }
+/* to get the correct picture for not-multiple-of-4 cases let us fill
+ * each block from the bottom up, thus possibly overwriting the top line
+ * more than once but ending with the correct data in place
+ * (instead of in-loop checking) */
 
         for (x=strip->x1; x < strip->x2; x+=4) {
             if ((chunk_id & 0x01) && !(mask >>= 1)) {
@@ -167,97 +180,82 @@
                 }
 
                 if ((chunk_id & 0x02) || (~flag & mask)) {
+                    uint8_t *p;
                     if (data >= eod)
                         return AVERROR_INVALIDDATA;
 
-                    codebook = &strip->v1_codebook[*data++];
-                    s->frame.data[0][iy[0] + 0] = codebook->y0;
-                    s->frame.data[0][iy[0] + 1] = codebook->y0;
-                    s->frame.data[0][iy[1] + 0] = codebook->y0;
-                    s->frame.data[0][iy[1] + 1] = codebook->y0;
-                    if (!s->palette_video) {
-                        s->frame.data[1][iu[0]] = codebook->u;
-                        s->frame.data[2][iv[0]] = codebook->v;
-                    }
-
-                    s->frame.data[0][iy[0] + 2] = codebook->y1;
-                    s->frame.data[0][iy[0] + 3] = codebook->y1;
-                    s->frame.data[0][iy[1] + 2] = codebook->y1;
-                    s->frame.data[0][iy[1] + 3] = codebook->y1;
-                    if (!s->palette_video) {
-                        s->frame.data[1][iu[0] + 1] = codebook->u;
-                        s->frame.data[2][iv[0] + 1] = codebook->v;
-                    }
-
-                    s->frame.data[0][iy[2] + 0] = codebook->y2;
-                    s->frame.data[0][iy[2] + 1] = codebook->y2;
-                    s->frame.data[0][iy[3] + 0] = codebook->y2;
-                    s->frame.data[0][iy[3] + 1] = codebook->y2;
-                    if (!s->palette_video) {
-                        s->frame.data[1][iu[1]] = codebook->u;
-                        s->frame.data[2][iv[1]] = codebook->v;
-                    }
-
-                    s->frame.data[0][iy[2] + 2] = codebook->y3;
-                    s->frame.data[0][iy[2] + 3] = codebook->y3;
-                    s->frame.data[0][iy[3] + 2] = codebook->y3;
-                    s->frame.data[0][iy[3] + 3] = codebook->y3;
-                    if (!s->palette_video) {
-                        s->frame.data[1][iu[1] + 1] = codebook->u;
-                        s->frame.data[2][iv[1] + 1] = codebook->v;
+                    p = strip->v1_codebook[*data++];
+                    if (s->palette_video) {
+                        ip3[0] = ip3[1] = ip2[0] = ip2[1] = p[6];
+                        ip3[2] = ip3[3] = ip2[2] = ip2[3] = p[9];
+                        ip1[0] = ip1[1] = ip0[0] = ip0[1] = p[0];
+                        ip1[2] = ip1[3] = ip0[2] = ip0[3] = p[3];
+                    } else {
+                        p += 6;
+                        memcpy(ip3 + 0, p, 3); memcpy(ip3 + 3, p, 3);
+                        memcpy(ip2 + 0, p, 3); memcpy(ip2 + 3, p, 3);
+                        p += 3; /* ... + 9 */
+                        memcpy(ip3 + 6, p, 3); memcpy(ip3 + 9, p, 3);
+                        memcpy(ip2 + 6, p, 3); memcpy(ip2 + 9, p, 3);
+                        p -= 9; /* ... + 0 */
+                        memcpy(ip1 + 0, p, 3); memcpy(ip1 + 3, p, 3);
+                        memcpy(ip0 + 0, p, 3); memcpy(ip0 + 3, p, 3);
+                        p += 3; /* ... + 3 */
+                        memcpy(ip1 + 6, p, 3); memcpy(ip1 + 9, p, 3);
+                        memcpy(ip0 + 6, p, 3); memcpy(ip0 + 9, p, 3);
                     }
 
                 } else if (flag & mask) {
                     if ((data + 4) > eod)
                         return AVERROR_INVALIDDATA;
 
-                    codebook = &strip->v4_codebook[*data++];
-                    s->frame.data[0][iy[0] + 0] = codebook->y0;
-                    s->frame.data[0][iy[0] + 1] = codebook->y1;
-                    s->frame.data[0][iy[1] + 0] = codebook->y2;
-                    s->frame.data[0][iy[1] + 1] = codebook->y3;
-                    if (!s->palette_video) {
-                        s->frame.data[1][iu[0]] = codebook->u;
-                        s->frame.data[2][iv[0]] = codebook->v;
-                    }
-
-                    codebook = &strip->v4_codebook[*data++];
-                    s->frame.data[0][iy[0] + 2] = codebook->y0;
-                    s->frame.data[0][iy[0] + 3] = codebook->y1;
-                    s->frame.data[0][iy[1] + 2] = codebook->y2;
-                    s->frame.data[0][iy[1] + 3] = codebook->y3;
-                    if (!s->palette_video) {
-                        s->frame.data[1][iu[0] + 1] = codebook->u;
-                        s->frame.data[2][iv[0] + 1] = codebook->v;
-                    }
-
-                    codebook = &strip->v4_codebook[*data++];
-                    s->frame.data[0][iy[2] + 0] = codebook->y0;
-                    s->frame.data[0][iy[2] + 1] = codebook->y1;
-                    s->frame.data[0][iy[3] + 0] = codebook->y2;
-                    s->frame.data[0][iy[3] + 1] = codebook->y3;
-                    if (!s->palette_video) {
-                        s->frame.data[1][iu[1]] = codebook->u;
-                        s->frame.data[2][iv[1]] = codebook->v;
-                    }
-
-                    codebook = &strip->v4_codebook[*data++];
-                    s->frame.data[0][iy[2] + 2] = codebook->y0;
-                    s->frame.data[0][iy[2] + 3] = codebook->y1;
-                    s->frame.data[0][iy[3] + 2] = codebook->y2;
-                    s->frame.data[0][iy[3] + 3] = codebook->y3;
-                    if (!s->palette_video) {
-                        s->frame.data[1][iu[1] + 1] = codebook->u;
-                        s->frame.data[2][iv[1] + 1] = codebook->v;
+                    cb0 = strip->v4_codebook[*data++];
+                    cb1 = strip->v4_codebook[*data++];
+                    cb2 = strip->v4_codebook[*data++];
+                    cb3 = strip->v4_codebook[*data++];
+                    if (s->palette_video) {
+                        uint8_t *p;
+                        p = ip3;
+                        *p++ = cb2[6];
+                        *p++ = cb2[9];
+                        *p++ = cb3[6];
+                        *p   = cb3[9];
+                        p = ip2;
+                        *p++ = cb2[0];
+                        *p++ = cb2[3];
+                        *p++ = cb3[0];
+                        *p   = cb3[3];
+                        p = ip1;
+                        *p++ = cb0[6];
+                        *p++ = cb0[9];
+                        *p++ = cb1[6];
+                        *p   = cb1[9];
+                        p = ip0;
+                        *p++ = cb0[0];
+                        *p++ = cb0[3];
+                        *p++ = cb1[0];
+                        *p   = cb1[3];
+                    } else {
+                        memcpy(ip3 + 0, cb2 + 6, 6);
+                        memcpy(ip3 + 6, cb3 + 6, 6);
+                        memcpy(ip2 + 0, cb2 + 0, 6);
+                        memcpy(ip2 + 6, cb3 + 0, 6);
+                        memcpy(ip1 + 0, cb0 + 6, 6);
+                        memcpy(ip1 + 6, cb1 + 6, 6);
+                        memcpy(ip0 + 0, cb0 + 0, 6);
+                        memcpy(ip0 + 6, cb1 + 0, 6);
                     }
 
                 }
             }
 
-            iy[0] += 4;  iy[1] += 4;
-            iy[2] += 4;  iy[3] += 4;
-            iu[0] += 2;  iu[1] += 2;
-            iv[0] += 2;  iv[1] += 2;
+            if (s->palette_video) {
+                ip0 += 4;  ip1 += 4;
+                ip2 += 4;  ip3 += 4;
+            } else {
+                ip0 += 12;  ip1 += 12;
+                ip2 += 12;  ip3 += 12;
+            }
         }
     }
 
@@ -334,7 +332,7 @@
     if (s->sega_film_skip_bytes == -1) {
         if (!encoded_buf_size) {
             av_log_ask_for_sample(s->avctx, "encoded_buf_size is 0");
-            return AVERROR_INVALIDDATA;
+            return AVERROR_PATCHWELCOME;
         }
         if (encoded_buf_size != s->size && (s->size % encoded_buf_size) != 0) {
             /* If the encoded frame size differs from the frame size as indicated
@@ -368,10 +366,13 @@
             return AVERROR_INVALIDDATA;
 
         s->strips[i].id = s->data[0];
-        s->strips[i].y1 = y0;
-        s->strips[i].x1 = 0;
-        s->strips[i].y2 = y0 + AV_RB16 (&s->data[8]);
-        s->strips[i].x2 = s->avctx->width;
+/* zero y1 means "relative to the previous stripe" */
+        if (!(s->strips[i].y1 = AV_RB16 (&s->data[4])))
+            s->strips[i].y2 = (s->strips[i].y1 = y0) + AV_RB16 (&s->data[8]);
+        else
+            s->strips[i].y2 = AV_RB16 (&s->data[8]);
+        s->strips[i].x1 = AV_RB16 (&s->data[6]);
+        s->strips[i].x2 = AV_RB16 (&s->data[10]);
 
         if (s->strips[i].id == 0x10)
             s->frame.key_frame = 1;
@@ -407,12 +408,13 @@
     s->avctx = avctx;
     s->width = (avctx->width + 3) & ~3;
     s->height = (avctx->height + 3) & ~3;
+
     s->sega_film_skip_bytes = -1;  /* uninitialized state */
 
     // check for paletted data
     if (avctx->bits_per_coded_sample != 8) {
         s->palette_video = 0;
-        avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+        avctx->pix_fmt = AV_PIX_FMT_RGB24;
     } else {
         s->palette_video = 1;
         avctx->pix_fmt = AV_PIX_FMT_PAL8;
@@ -425,7 +427,7 @@
 }
 
 static int cinepak_decode_frame(AVCodecContext *avctx,
-                                void *data, int *data_size,
+                                void *data, int *got_frame,
                                 AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
@@ -451,12 +453,14 @@
         }
     }
 
-    cinepak_decode(s);
+    if ((ret = cinepak_decode(s)) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "cinepak_decode failed\n");
+    }
 
     if (s->palette_video)
         memcpy (s->frame.data[1], s->pal, AVPALETTE_SIZE);
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*)data = s->frame;
 
     /* report that the buffer was completely consumed */
diff --git a/libavcodec/cljr.c b/libavcodec/cljr.c
index 87c8fc2..b93997f 100644
--- a/libavcodec/cljr.c
+++ b/libavcodec/cljr.c
@@ -48,7 +48,7 @@
 
 #if CONFIG_CLJR_DECODER
 static int decode_frame(AVCodecContext *avctx,
-                        void *data, int *data_size,
+                        void *data, int *got_frame,
                         AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
@@ -74,7 +74,7 @@
     }
 
     p->reference = 0;
-    if ((ret = avctx->get_buffer(avctx, p)) < 0) {
+    if ((ret = ff_get_buffer(avctx, p)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -99,7 +99,7 @@
     }
 
     *picture   = a->picture;
-    *data_size = sizeof(AVPicture);
+    *got_frame = 1;
 
     return buf_size;
 }
diff --git a/libavcodec/cllc.c b/libavcodec/cllc.c
index b588331..d14de60 100644
--- a/libavcodec/cllc.c
+++ b/libavcodec/cllc.c
@@ -24,6 +24,7 @@
 #include "dsputil.h"
 #include "get_bits.h"
 #include "avcodec.h"
+#include "internal.h"
 
 typedef struct CLLCContext {
     DSPContext dsp;
@@ -333,7 +334,7 @@
         avctx->pix_fmt             = AV_PIX_FMT_RGB24;
         avctx->bits_per_raw_sample = 8;
 
-        ret = avctx->get_buffer(avctx, pic);
+        ret = ff_get_buffer(avctx, pic);
         if (ret < 0) {
             av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
             return ret;
@@ -348,7 +349,7 @@
         avctx->pix_fmt             = AV_PIX_FMT_ARGB;
         avctx->bits_per_raw_sample = 8;
 
-        ret = avctx->get_buffer(avctx, pic);
+        ret = ff_get_buffer(avctx, pic);
         if (ret < 0) {
             av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
             return ret;
diff --git a/libavcodec/cngdec.c b/libavcodec/cngdec.c
index 9b6dfef..edfdd3e 100644
--- a/libavcodec/cngdec.c
+++ b/libavcodec/cngdec.c
@@ -24,10 +24,10 @@
 #include "libavutil/common.h"
 #include "avcodec.h"
 #include "celp_filters.h"
+#include "internal.h"
 #include "libavutil/lfg.h"
 
 typedef struct CNGContext {
-    AVFrame avframe;
     float *refl_coef, *target_refl_coef;
     float *lpc_coef;
     int order;
@@ -57,8 +57,6 @@
     avctx->channels    = 1;
     avctx->sample_rate = 8000;
 
-    avcodec_get_frame_defaults(&p->avframe);
-    avctx->coded_frame  = &p->avframe;
     p->order            = 12;
     avctx->frame_size   = 640;
     p->refl_coef        = av_mallocz(p->order * sizeof(*p->refl_coef));
@@ -104,7 +102,7 @@
 static int cng_decode_frame(AVCodecContext *avctx, void *data,
                             int *got_frame_ptr, AVPacket *avpkt)
 {
-
+    AVFrame *frame = data;
     CNGContext *p = avctx->priv_data;
     int buf_size  = avpkt->size;
     int ret, i;
@@ -143,19 +141,18 @@
     ff_celp_lp_synthesis_filterf(p->filter_out + p->order, p->lpc_coef,
                                  p->excitation, avctx->frame_size, p->order);
 
-    p->avframe.nb_samples = avctx->frame_size;
-    if ((ret = avctx->get_buffer(avctx, &p->avframe)) < 0) {
+    frame->nb_samples = avctx->frame_size;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    buf_out = (int16_t *)p->avframe.data[0];
+    buf_out = (int16_t *)frame->data[0];
     for (i = 0; i < avctx->frame_size; i++)
         buf_out[i] = p->filter_out[i + p->order];
     memcpy(p->filter_out, p->filter_out + avctx->frame_size,
            p->order * sizeof(*p->filter_out));
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = p->avframe;
+    *got_frame_ptr = 1;
 
     return buf_size;
 }
diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
index 5e4f357..673f971 100644
--- a/libavcodec/codec_desc.c
+++ b/libavcodec/codec_desc.c
@@ -749,7 +749,14 @@
         .type      = AVMEDIA_TYPE_VIDEO,
         .name      = "sgi",
         .long_name = NULL_IF_CONFIG_SMALL("SGI image"),
-        .props     = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
+        .props     = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS,
+    },
+    {
+        .id        = AV_CODEC_ID_SGIRLE,
+        .type      = AVMEDIA_TYPE_VIDEO,
+        .name      = "sgirle",
+        .long_name = NULL_IF_CONFIG_SMALL("SGI RLE 8-bit"),
+        .props     = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS,
     },
     {
         .id        = AV_CODEC_ID_C93,
@@ -937,7 +944,7 @@
         .type      = AVMEDIA_TYPE_VIDEO,
         .name      = "dpx",
         .long_name = NULL_IF_CONFIG_SMALL("DPX image"),
-        .props     = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
+        .props     = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS,
     },
     {
         .id        = AV_CODEC_ID_MAD,
@@ -1024,6 +1031,13 @@
         .props     = AV_CODEC_PROP_LOSSY,
     },
     {
+        .id        = AV_CODEC_ID_VP9,
+        .type      = AVMEDIA_TYPE_VIDEO,
+        .name      = "vp9",
+        .long_name = NULL_IF_CONFIG_SMALL("Google VP9"),
+        .props     = AV_CODEC_PROP_LOSSY,
+    },
+    {
         .id        = AV_CODEC_ID_PICTOR,
         .type      = AVMEDIA_TYPE_VIDEO,
         .name      = "pictor",
@@ -1059,6 +1073,20 @@
         .props     = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS,
     },
     {
+        .id        = AV_CODEC_ID_MVC1,
+        .type      = AVMEDIA_TYPE_VIDEO,
+        .name      = "mvc1",
+        .long_name = NULL_IF_CONFIG_SMALL("Silicon Graphics Motion Video Compressor 1"),
+        .props     = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
+    },
+    {
+        .id        = AV_CODEC_ID_MVC2,
+        .type      = AVMEDIA_TYPE_VIDEO,
+        .name      = "mvc2",
+        .long_name = NULL_IF_CONFIG_SMALL("Silicon Graphics Motion Video Compressor 2"),
+        .props     = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
+    },
+    {
         .id        = AV_CODEC_ID_MXPEG,
         .type      = AVMEDIA_TYPE_VIDEO,
         .name      = "mxpeg",
@@ -1242,6 +1270,13 @@
         .props     = AV_CODEC_PROP_INTRA_ONLY,
     },
     {
+        .id        = AV_CODEC_ID_012V,
+        .type      = AVMEDIA_TYPE_VIDEO,
+        .name      = "012v",
+        .long_name = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"),
+        .props     = AV_CODEC_PROP_INTRA_ONLY,
+    },
+    {
         .id        = AV_CODEC_ID_G2M,
         .type      = AVMEDIA_TYPE_VIDEO,
         .name      = "g2m",
@@ -1320,12 +1355,14 @@
         .type      = AVMEDIA_TYPE_VIDEO,
         .name      = "xface",
         .long_name = NULL_IF_CONFIG_SMALL("X-face image"),
+        .props     = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
     },
     {
         .id        = AV_CODEC_ID_BRENDER_PIX,
         .type      = AVMEDIA_TYPE_VIDEO,
         .name      = "brender_pix",
         .long_name = NULL_IF_CONFIG_SMALL("BRender PIX image"),
+        .props     = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS,
     },
 
     /* various PCM "codecs" */
@@ -2276,12 +2313,6 @@
         .long_name = NULL_IF_CONFIG_SMALL("Wave synthesis pseudo-codec"),
     },
     {
-        .id        = AV_CODEC_ID_8SVX_RAW,
-        .type      = AVMEDIA_TYPE_AUDIO,
-        .name      = "8svx_raw",
-        .long_name = NULL_IF_CONFIG_SMALL("8SVX raw"),
-    },
-    {
         .id        = AV_CODEC_ID_SONIC,
         .type      = AVMEDIA_TYPE_AUDIO,
         .name      = "sonic",
@@ -2321,6 +2352,20 @@
         .long_name = NULL_IF_CONFIG_SMALL("TAK (Tom's lossless Audio Kompressor)"),
         .props     = AV_CODEC_PROP_LOSSLESS,
     },
+    {
+        .id        = AV_CODEC_ID_EVRC,
+        .type      = AVMEDIA_TYPE_AUDIO,
+        .name      = "evrc",
+        .long_name = NULL_IF_CONFIG_SMALL("EVRC (Enhanced Variable Rate Codec)"),
+        .props     = AV_CODEC_PROP_LOSSY,
+    },
+    {
+        .id        = AV_CODEC_ID_SMV,
+        .type      = AVMEDIA_TYPE_AUDIO,
+        .name      = "smv",
+        .long_name = NULL_IF_CONFIG_SMALL("SMV (Selectable Mode Vocoder)"),
+        .props     = AV_CODEC_PROP_LOSSY,
+    },
 
     /* subtitle codecs */
     {
@@ -2328,12 +2373,14 @@
         .type      = AVMEDIA_TYPE_SUBTITLE,
         .name      = "dvd_subtitle",
         .long_name = NULL_IF_CONFIG_SMALL("DVD subtitles"),
+        .props     = AV_CODEC_PROP_BITMAP_SUB,
     },
     {
         .id        = AV_CODEC_ID_DVB_SUBTITLE,
         .type      = AVMEDIA_TYPE_SUBTITLE,
         .name      = "dvb_subtitle",
         .long_name = NULL_IF_CONFIG_SMALL("DVB subtitles"),
+        .props     = AV_CODEC_PROP_BITMAP_SUB,
     },
     {
         .id        = AV_CODEC_ID_TEXT,
@@ -2346,6 +2393,7 @@
         .type      = AVMEDIA_TYPE_SUBTITLE,
         .name      = "xsub",
         .long_name = NULL_IF_CONFIG_SMALL("XSUB"),
+        .props     = AV_CODEC_PROP_BITMAP_SUB,
     },
     {
         .id        = AV_CODEC_ID_SSA,
@@ -2364,6 +2412,7 @@
         .type      = AVMEDIA_TYPE_SUBTITLE,
         .name      = "hdmv_pgs_subtitle",
         .long_name = NULL_IF_CONFIG_SMALL("HDMV Presentation Graphic Stream subtitles"),
+        .props     = AV_CODEC_PROP_BITMAP_SUB,
     },
     {
         .id        = AV_CODEC_ID_DVB_TELETEXT,
@@ -2390,6 +2439,12 @@
         .long_name = NULL_IF_CONFIG_SMALL("MicroDVD subtitle"),
     },
     {
+        .id        = AV_CODEC_ID_MPL2,
+        .type      = AVMEDIA_TYPE_SUBTITLE,
+        .name      = "mpl2",
+        .long_name = NULL_IF_CONFIG_SMALL("MPL2 subtitle"),
+    },
+    {
         .id        = AV_CODEC_ID_EIA_608,
         .type      = AVMEDIA_TYPE_SUBTITLE,
         .name      = "eia_608",
@@ -2402,6 +2457,12 @@
         .long_name = NULL_IF_CONFIG_SMALL("JACOsub subtitle"),
     },
     {
+        .id        = AV_CODEC_ID_PJS,
+        .type      = AVMEDIA_TYPE_SUBTITLE,
+        .name      = "pjs",
+        .long_name = NULL_IF_CONFIG_SMALL("PJS (Phoenix Japanimation Society) subtitle"),
+    },
+    {
         .id        = AV_CODEC_ID_SAMI,
         .type      = AVMEDIA_TYPE_SUBTITLE,
         .name      = "sami",
@@ -2414,12 +2475,24 @@
         .long_name = NULL_IF_CONFIG_SMALL("RealText subtitle"),
     },
     {
+        .id        = AV_CODEC_ID_SUBVIEWER1,
+        .type      = AVMEDIA_TYPE_SUBTITLE,
+        .name      = "subviewer1",
+        .long_name = NULL_IF_CONFIG_SMALL("SubViewer v1 subtitle"),
+    },
+    {
         .id        = AV_CODEC_ID_SUBVIEWER,
         .type      = AVMEDIA_TYPE_SUBTITLE,
         .name      = "subviewer",
         .long_name = NULL_IF_CONFIG_SMALL("SubViewer subtitle"),
     },
     {
+        .id        = AV_CODEC_ID_VPLAYER,
+        .type      = AVMEDIA_TYPE_SUBTITLE,
+        .name      = "vplayer",
+        .long_name = NULL_IF_CONFIG_SMALL("VPlayer subtitle"),
+    },
+    {
         .id        = AV_CODEC_ID_WEBVTT,
         .type      = AVMEDIA_TYPE_SUBTITLE,
         .name      = "webvtt",
@@ -2446,6 +2519,12 @@
         .long_name = NULL_IF_CONFIG_SMALL("iCEDraw text"),
         .props     = AV_CODEC_PROP_INTRA_ONLY,
     },
+    {
+        .id        = AV_CODEC_ID_SMPTE_KLV,
+        .type      = AVMEDIA_TYPE_DATA,
+        .name      = "klv",
+        .long_name = NULL_IF_CONFIG_SMALL("SMPTE 336M Key-Length-Value (KLV) metadata"),
+    },
 
 };
 
diff --git a/libavcodec/cook.c b/libavcodec/cook.c
index 63f6be2..7dcf655 100644
--- a/libavcodec/cook.c
+++ b/libavcodec/cook.c
@@ -49,6 +49,7 @@
 #include "dsputil.h"
 #include "bytestream.h"
 #include "fft.h"
+#include "internal.h"
 #include "sinewin.h"
 
 #include "cookdata.h"
@@ -122,7 +123,6 @@
 
     AVCodecContext*     avctx;
     DSPContext          dsp;
-    AVFrame             frame;
     GetBitContext       gb;
     /* stream data */
     int                 num_vectors;
@@ -955,6 +955,7 @@
 static int cook_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;
     COOKContext *q = avctx->priv_data;
@@ -968,12 +969,12 @@
 
     /* get output buffer */
     if (q->discarded_packets >= 2) {
-        q->frame.nb_samples = q->samples_per_channel;
-        if ((ret = avctx->get_buffer(avctx, &q->frame)) < 0) {
+        frame->nb_samples = q->samples_per_channel;
+        if ((ret = ff_get_buffer(avctx, frame)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
             return ret;
         }
-        samples = (float **)q->frame.extended_data;
+        samples = (float **)frame->extended_data;
     }
 
     /* estimate subpacket sizes */
@@ -1014,8 +1015,7 @@
         return avctx->block_align;
     }
 
-    *got_frame_ptr    = 1;
-    *(AVFrame *) data = q->frame;
+    *got_frame_ptr = 1;
 
     return avctx->block_align;
 }
@@ -1091,6 +1091,11 @@
         if (extradata_size >= 8) {
             bytestream_get_be32(&edata_ptr);    // Unknown unused
             q->subpacket[s].js_subband_start = bytestream_get_be16(&edata_ptr);
+            if (q->subpacket[s].js_subband_start >= 51) {
+                av_log(avctx, AV_LOG_ERROR, "js_subband_start %d is too large\n", q->subpacket[s].js_subband_start);
+                return AVERROR_INVALIDDATA;
+            }
+
             q->subpacket[s].js_vlc_bits = bytestream_get_be16(&edata_ptr);
             extradata_size -= 8;
         }
@@ -1268,9 +1273,6 @@
     else
         avctx->channel_layout = (avctx->channels == 2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO;
 
-    avcodec_get_frame_defaults(&q->frame);
-    avctx->coded_frame = &q->frame;
-
 #ifdef DEBUG
     dump_cook_context(q);
 #endif
diff --git a/libavcodec/copy_block.h b/libavcodec/copy_block.h
new file mode 100644
index 0000000..a73910d
--- /dev/null
+++ b/libavcodec/copy_block.h
@@ -0,0 +1,94 @@
+/*
+ * 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_COPY_BLOCK_H
+#define AVCODEC_COPY_BLOCK_H
+
+#include <stdint.h>
+
+#include "libavutil/intreadwrite.h"
+
+static inline void copy_block2(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
+{
+    int i;
+    for(i=0; i<h; i++)
+    {
+        AV_COPY16U(dst, src);
+        dst+=dstStride;
+        src+=srcStride;
+    }
+}
+
+static inline void copy_block4(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
+{
+    int i;
+    for(i=0; i<h; i++)
+    {
+        AV_COPY32U(dst, src);
+        dst+=dstStride;
+        src+=srcStride;
+    }
+}
+
+static inline void copy_block8(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
+{
+    int i;
+    for(i=0; i<h; i++)
+    {
+        AV_COPY64U(dst, src);
+        dst+=dstStride;
+        src+=srcStride;
+    }
+}
+
+static inline void copy_block16(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
+{
+    int i;
+    for(i=0; i<h; i++)
+    {
+        AV_COPY128U(dst, src);
+        dst+=dstStride;
+        src+=srcStride;
+    }
+}
+
+static inline void copy_block9(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
+{
+    int i;
+    for(i=0; i<h; i++)
+    {
+        AV_COPY64U(dst, src);
+        dst[8]= src[8];
+        dst+=dstStride;
+        src+=srcStride;
+    }
+}
+
+static inline void copy_block17(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
+{
+    int i;
+    for(i=0; i<h; i++)
+    {
+        AV_COPY128U(dst, src);
+        dst[16]= src[16];
+        dst+=dstStride;
+        src+=srcStride;
+    }
+}
+
+#endif /* AVCODEC_COPY_BLOCK_H */
diff --git a/libavcodec/cos_tablegen.c b/libavcodec/cos_tablegen.c
index af9391d..313a1d2 100644
--- a/libavcodec/cos_tablegen.c
+++ b/libavcodec/cos_tablegen.c
@@ -56,7 +56,7 @@
     printf("#include \"libavcodec/%s\"\n", do_sin ? "rdft.h" : "fft.h");
     for (i = 4; i <= BITS; i++) {
         int m = 1 << i;
-        double freq = 2*M_PI/m;
+        double freq = 2*3.14159265358979323846/m;
         printf("%s(%i) = {\n   ", do_sin ? "SINTABLE" : "COSTABLE", m);
         for (j = 0; j < m/2 - 1; j++) {
             int idx = j > m/4 ? m/2 - j : j;
diff --git a/libavcodec/cpia.c b/libavcodec/cpia.c
index 26e067a..f741eb9 100644
--- a/libavcodec/cpia.c
+++ b/libavcodec/cpia.c
@@ -46,8 +46,8 @@
 } CpiaContext;
 
 
-static int cpia_decode_frame(AVCodecContext* avctx,
-        void* data, int* data_size, AVPacket* avpkt)
+static int cpia_decode_frame(AVCodecContext *avctx,
+                             void *data, int *got_frame, AVPacket* avpkt)
 {
     CpiaContext* const cpia = avctx->priv_data;
     int i,j,ret;
@@ -183,7 +183,7 @@
         }
     }
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*) data = *frame;
 
     return avpkt->size;
diff --git a/libavcodec/crystalhd.c b/libavcodec/crystalhd.c
index bf846d3..e2596a2 100644
--- a/libavcodec/crystalhd.c
+++ b/libavcodec/crystalhd.c
@@ -85,6 +85,7 @@
 
 #include "avcodec.h"
 #include "h264.h"
+#include "internal.h"
 #include "libavutil/imgutils.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/opt.h"
@@ -535,7 +536,7 @@
 
 static inline CopyRet copy_frame(AVCodecContext *avctx,
                                  BC_DTS_PROC_OUT *output,
-                                 void *data, int *data_size)
+                                 void *data, int *got_frame)
 {
     BC_STATUS ret;
     BC_DTS_STATUS decoder_status = { 0, };
@@ -642,7 +643,7 @@
     priv->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE |
                              FF_BUFFER_HINTS_REUSABLE;
     if (!priv->pic.data[0]) {
-        if (avctx->get_buffer(avctx, &priv->pic) < 0) {
+        if (ff_get_buffer(avctx, &priv->pic) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
             return RET_ERROR;
         }
@@ -695,7 +696,7 @@
     priv->pic.pkt_pts = pkt_pts;
 
     if (!priv->need_second_field) {
-        *data_size       = sizeof(AVFrame);
+        *got_frame       = 1;
         *(AVFrame *)data = priv->pic;
     }
 
@@ -732,7 +733,7 @@
 
 
 static inline CopyRet receive_frame(AVCodecContext *avctx,
-                                    void *data, int *data_size)
+                                    void *data, int *got_frame)
 {
     BC_STATUS ret;
     BC_DTS_PROC_OUT output = {
@@ -742,7 +743,7 @@
     CHDContext *priv = avctx->priv_data;
     HANDLE dev       = priv->dev;
 
-    *data_size = 0;
+    *got_frame = 0;
 
     // Request decoded data from the driver
     ret = DtsProcOutputNoCopy(dev, OUTPUT_PROC_TIMEOUT, &output);
@@ -839,8 +840,8 @@
                priv->last_picture = output.PicInfo.picture_number - 1;
             }
 
-            copy_ret = copy_frame(avctx, &output, data, data_size);
-            if (*data_size > 0) {
+            copy_ret = copy_frame(avctx, &output, data, got_frame);
+            if (*got_frame > 0) {
                 avctx->has_b_frames--;
                 priv->last_picture++;
                 av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: Pipeline length: %u\n",
@@ -867,7 +868,7 @@
 }
 
 
-static int decode(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt)
+static int decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
 {
     BC_STATUS ret;
     BC_DTS_STATUS decoder_status = { 0, };
@@ -931,8 +932,8 @@
                 } else {
                     av_log(avctx, AV_LOG_VERBOSE,
                            "CrystalHD: parser picture type %d\n",
-                           h->s.picture_structure);
-                    pic_type = h->s.picture_structure;
+                           h->picture_structure);
+                    pic_type = h->picture_structure;
                 }
             } else {
                 av_log(avctx, AV_LOG_WARNING,
@@ -1025,8 +1026,8 @@
     }
 
     do {
-        rec_ret = receive_frame(avctx, data, data_size);
-        if (rec_ret == RET_OK && *data_size == 0) {
+        rec_ret = receive_frame(avctx, data, got_frame);
+        if (rec_ret == RET_OK && *got_frame == 0) {
             /*
              * This case is for when the encoded fields are stored
              * separately and we get a separate avpkt for each one. To keep
@@ -1051,8 +1052,8 @@
                 ret = DtsGetDriverStatus(dev, &decoder_status);
                 if (ret == BC_STS_SUCCESS &&
                     decoder_status.ReadyListCount > 0) {
-                    rec_ret = receive_frame(avctx, data, data_size);
-                    if ((rec_ret == RET_OK && *data_size > 0) ||
+                    rec_ret = receive_frame(avctx, data, got_frame);
+                    if ((rec_ret == RET_OK && *got_frame > 0) ||
                         rec_ret == RET_ERROR)
                         break;
                 }
diff --git a/libavcodec/cscd.c b/libavcodec/cscd.c
index 8ba5de3..110b06f 100644
--- a/libavcodec/cscd.c
+++ b/libavcodec/cscd.c
@@ -22,6 +22,7 @@
 #include <stdlib.h>
 
 #include "avcodec.h"
+#include "internal.h"
 #include "libavutil/common.h"
 
 #if CONFIG_ZLIB
@@ -61,24 +62,25 @@
     }
 }
 
-static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         AVPacket *avpkt) {
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     CamStudioContext *c = avctx->priv_data;
     AVFrame *picture = data;
+    int ret;
 
     if (buf_size < 2) {
         av_log(avctx, AV_LOG_ERROR, "coded frame too small\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     c->pic.reference = 3;
     c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_READABLE |
                           FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if (avctx->reget_buffer(avctx, &c->pic) < 0) {
+    if ((ret = avctx->reget_buffer(avctx, &c->pic)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     // decompress data
@@ -97,12 +99,12 @@
             break;
 #else
             av_log(avctx, AV_LOG_ERROR, "compiled without zlib support\n");
-            return -1;
+            return AVERROR(ENOSYS);
 #endif
         }
         default:
             av_log(avctx, AV_LOG_ERROR, "unknown compression\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
     }
 
     // flip upside down, add difference frame
@@ -119,7 +121,7 @@
     }
 
     *picture = c->pic;
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     return buf_size;
 }
 
diff --git a/libavcodec/cyuv.c b/libavcodec/cyuv.c
index 74c1077..b3bf4f2 100644
--- a/libavcodec/cyuv.c
+++ b/libavcodec/cyuv.c
@@ -33,7 +33,7 @@
 #include <string.h>
 
 #include "avcodec.h"
-#include "dsputil.h"
+#include "internal.h"
 #include "libavutil/internal.h"
 
 
@@ -51,7 +51,7 @@
     s->width = avctx->width;
     /* width needs to be divisible by 4 for this codec to work */
     if (s->width & 0x3)
-        return -1;
+        return AVERROR_INVALIDDATA;
     s->height = avctx->height;
     avcodec_get_frame_defaults(&s->frame);
 
@@ -59,7 +59,7 @@
 }
 
 static int cyuv_decode_frame(AVCodecContext *avctx,
-                             void *data, int *data_size,
+                             void *data, int *got_frame,
                              AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
@@ -83,6 +83,7 @@
     unsigned char cur_byte;
     int pixel_groups;
     int rawsize = s->height * FFALIGN(s->width,2) * 2;
+    int ret;
 
     if (avctx->codec_id == AV_CODEC_ID_AURA) {
         y_table = u_table;
@@ -99,7 +100,7 @@
     } else {
         av_log(avctx, AV_LOG_ERROR, "got a buffer with %d bytes when %d were expected\n",
                buf_size, 48 + s->height * (s->width * 3 / 4));
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     /* pixel data starts 48 bytes in, after 3x16-byte tables */
@@ -110,9 +111,9 @@
 
     s->frame.buffer_hints = FF_BUFFER_HINTS_VALID;
     s->frame.reference = 0;
-    if (avctx->get_buffer(avctx, &s->frame) < 0) {
+    if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     y_plane = s->frame.data[0];
@@ -177,7 +178,7 @@
     }
     }
 
-    *data_size=sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*)data= s->frame;
 
     return buf_size;
diff --git a/libavcodec/dcadec.c b/libavcodec/dcadec.c
index acbabd6..1b955e4 100644
--- a/libavcodec/dcadec.c
+++ b/libavcodec/dcadec.c
@@ -29,12 +29,11 @@
 #include "libavutil/channel_layout.h"
 #include "libavutil/common.h"
 #include "libavutil/float_dsp.h"
-#include "libavutil/intmath.h"
+#include "libavutil/internal.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/samplefmt.h"
 #include "avcodec.h"
-#include "dsputil.h"
 #include "fft.h"
 #include "get_bits.h"
 #include "put_bits.h"
@@ -42,9 +41,11 @@
 #include "dcahuff.h"
 #include "dca.h"
 #include "dca_parser.h"
+#include "mathops.h"
 #include "synth_filter.h"
 #include "dcadsp.h"
 #include "fmtconvert.h"
+#include "internal.h"
 
 #if ARCH_ARM
 #   include "arm/dca.h"
@@ -348,7 +349,6 @@
 
 typedef struct {
     AVCodecContext *avctx;
-    AVFrame frame;
     /* Frame header */
     int frame_type;             ///< type of the current frame
     int samples_deficit;        ///< deficit sample count
@@ -2066,6 +2066,7 @@
 static int dca_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;
     int channel_mask;
@@ -2246,6 +2247,8 @@
                 } else {
                     s->channel_order_tab = dca_channel_reorder_nolfe_xch[s->amode];
                 }
+                if (s->channel_order_tab[s->xch_base_channel] < 0)
+                    return AVERROR_INVALIDDATA;
             } else {
                 channels = num_core_channels + !!s->lfe;
                 s->xch_present = 0; /* disable further xch processing */
@@ -2351,17 +2354,17 @@
     }
 
     /* get output buffer */
-    s->frame.nb_samples = 256 * (s->sample_blocks / 8);
-    if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = 256 * (s->sample_blocks / 8);
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    samples_flt = (float  **) s->frame.extended_data;
+    samples_flt = (float **)frame->extended_data;
 
     /* allocate buffer for extra channels if downmixing */
     if (avctx->channels < full_channels) {
         ret = av_samples_get_buffer_size(NULL, full_channels - channels,
-                                         s->frame.nb_samples,
+                                         frame->nb_samples,
                                          avctx->sample_fmt, 0);
         if (ret < 0)
             return ret;
@@ -2374,7 +2377,7 @@
         ret = av_samples_fill_arrays((uint8_t **)s->extra_channels, NULL,
                                      s->extra_channels_buffer,
                                      full_channels - channels,
-                                     s->frame.nb_samples, avctx->sample_fmt, 0);
+                                     frame->nb_samples, avctx->sample_fmt, 0);
         if (ret < 0)
             return ret;
     }
@@ -2453,8 +2456,7 @@
     for (i = 0; i < 2 * s->lfe * 4; i++)
         s->lfe_data[i] = s->lfe_data[i + lfe_samples];
 
-    *got_frame_ptr    = 1;
-    *(AVFrame *) data = s->frame;
+    *got_frame_ptr = 1;
 
     return buf_size;
 }
@@ -2488,9 +2490,6 @@
         avctx->channels = avctx->request_channels;
     }
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     return 0;
 }
 
diff --git a/libavcodec/dcaenc.c b/libavcodec/dcaenc.c
index 7d55bb5..2c9daee 100644
--- a/libavcodec/dcaenc.c
+++ b/libavcodec/dcaenc.c
@@ -25,7 +25,6 @@
 #include "libavutil/common.h"
 #include "libavutil/avassert.h"
 #include "avcodec.h"
-#include "get_bits.h"
 #include "internal.h"
 #include "put_bits.h"
 #include "dcaenc.h"
diff --git a/libavcodec/dct-test.c b/libavcodec/dct-test.c
index 7727f0b..29f47e8 100644
--- a/libavcodec/dct-test.c
+++ b/libavcodec/dct-test.c
@@ -39,6 +39,7 @@
 #include "libavutil/lfg.h"
 #include "libavutil/time.h"
 
+#include "dct.h"
 #include "simple_idct.h"
 #include "aandcttab.h"
 #include "faandct.h"
@@ -48,28 +49,28 @@
 
 #undef printf
 
-void ff_mmx_idct(DCTELEM *data);
-void ff_mmxext_idct(DCTELEM *data);
+void ff_mmx_idct(int16_t *data);
+void ff_mmxext_idct(int16_t *data);
 
 // BFIN
-void ff_bfin_idct(DCTELEM *block);
-void ff_bfin_fdct(DCTELEM *block);
+void ff_bfin_idct(int16_t *block);
+void ff_bfin_fdct(int16_t *block);
 
 // ALTIVEC
-void ff_fdct_altivec(DCTELEM *block);
+void ff_fdct_altivec(int16_t *block);
 
 // ARM
-void ff_j_rev_dct_arm(DCTELEM *data);
-void ff_simple_idct_arm(DCTELEM *data);
-void ff_simple_idct_armv5te(DCTELEM *data);
-void ff_simple_idct_armv6(DCTELEM *data);
-void ff_simple_idct_neon(DCTELEM *data);
+void ff_j_rev_dct_arm(int16_t *data);
+void ff_simple_idct_arm(int16_t *data);
+void ff_simple_idct_armv5te(int16_t *data);
+void ff_simple_idct_armv6(int16_t *data);
+void ff_simple_idct_neon(int16_t *data);
 
-void ff_simple_idct_axp(DCTELEM *data);
+void ff_simple_idct_axp(int16_t *data);
 
 struct algo {
     const char *name;
-    void (*func)(DCTELEM *block);
+    void (*func)(int16_t *block);
     enum formattag { NO_PERM, MMX_PERM, MMX_SIMPLE_PERM, SCALE_PERM,
                      SSE2_PERM, PARTTRANS_PERM, TRANSPOSE_PERM } format;
     int mm_support;
@@ -103,9 +104,9 @@
 
 #if ARCH_X86_64 && HAVE_MMX && HAVE_YASM
 void ff_prores_idct_put_10_sse2(uint16_t *dst, int linesize,
-                                DCTELEM *block, int16_t *qmat);
+                                int16_t *block, int16_t *qmat);
 
-static void ff_prores_idct_put_10_sse2_wrap(DCTELEM *dst){
+static void ff_prores_idct_put_10_sse2_wrap(int16_t *dst){
     DECLARE_ALIGNED(16, static int16_t, qmat)[64];
     DECLARE_ALIGNED(16, static int16_t, tmp)[64];
     int i;
@@ -147,13 +148,13 @@
     { "INT-ARM",        ff_j_rev_dct_arm,      MMX_PERM },
 #endif
 #if HAVE_ARMV5TE
-    { "SIMPLE-ARMV5TE", ff_simple_idct_armv5te,NO_PERM  },
+    { "SIMPLE-ARMV5TE", ff_simple_idct_armv5te,NO_PERM,   AV_CPU_FLAG_ARMV5TE },
 #endif
 #if HAVE_ARMV6
-    { "SIMPLE-ARMV6",   ff_simple_idct_armv6,  MMX_PERM },
+    { "SIMPLE-ARMV6",   ff_simple_idct_armv6,  MMX_PERM,  AV_CPU_FLAG_ARMV6   },
 #endif
 #if HAVE_NEON
-    { "SIMPLE-NEON",    ff_simple_idct_neon,   PARTTRANS_PERM },
+    { "SIMPLE-NEON",    ff_simple_idct_neon, PARTTRANS_PERM, AV_CPU_FLAG_NEON },
 #endif
 
 #if ARCH_ALPHA
@@ -193,10 +194,10 @@
     }
 }
 
-DECLARE_ALIGNED(16, static DCTELEM, block)[64];
-DECLARE_ALIGNED(8,  static DCTELEM, block1)[64];
+DECLARE_ALIGNED(16, static int16_t, block)[64];
+DECLARE_ALIGNED(8,  static int16_t, block1)[64];
 
-static void init_block(DCTELEM block[64], int test, int is_idct, AVLFG *prng, int vals)
+static void init_block(int16_t block[64], int test, int is_idct, AVLFG *prng, int vals)
 {
     int i, j;
 
@@ -226,7 +227,7 @@
     }
 }
 
-static void permute(DCTELEM dst[64], const DCTELEM src[64], int perm)
+static void permute(int16_t dst[64], const int16_t src[64], int perm)
 {
     int i;
 
@@ -253,7 +254,7 @@
 
 static int dct_error(const struct algo *dct, int test, int is_idct, int speed, const int bits)
 {
-    void (*ref)(DCTELEM *block) = is_idct ? ff_ref_idct : ff_ref_fdct;
+    void (*ref)(int16_t *block) = is_idct ? ff_ref_idct : ff_ref_fdct;
     int it, i, scale;
     int err_inf, v;
     int64_t err2, ti, ti1, it1, err_sum = 0;
diff --git a/libavcodec/dct.h b/libavcodec/dct.h
index 8995f10..a500521 100644
--- a/libavcodec/dct.h
+++ b/libavcodec/dct.h
@@ -24,6 +24,8 @@
 #ifndef AVCODEC_DCT_H
 #define AVCODEC_DCT_H
 
+#include <stdint.h>
+
 #include "rdft.h"
 
 struct DCTContext {
@@ -49,4 +51,20 @@
 
 void ff_dct_init_x86(DCTContext *s);
 
+void ff_fdct_ifast(int16_t *data);
+void ff_fdct_ifast248(int16_t *data);
+void ff_jpeg_fdct_islow_8(int16_t *data);
+void ff_jpeg_fdct_islow_10(int16_t *data);
+void ff_fdct248_islow_8(int16_t *data);
+void ff_fdct248_islow_10(int16_t *data);
+
+void ff_j_rev_dct(int16_t *data);
+void ff_j_rev_dct4(int16_t *data);
+void ff_j_rev_dct2(int16_t *data);
+void ff_j_rev_dct1(int16_t *data);
+
+void ff_fdct_mmx(int16_t *block);
+void ff_fdct_mmxext(int16_t *block);
+void ff_fdct_sse2(int16_t *block);
+
 #endif /* AVCODEC_DCT_H */
diff --git a/libavcodec/dfa.c b/libavcodec/dfa.c
index 548a649..b324c6e 100644
--- a/libavcodec/dfa.c
+++ b/libavcodec/dfa.c
@@ -23,6 +23,7 @@
 #include "libavutil/avassert.h"
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 
 #include "libavutil/imgutils.h"
 #include "libavutil/mem.h"
@@ -313,7 +314,7 @@
 };
 
 static int dfa_decode_frame(AVCodecContext *avctx,
-                            void *data, int *data_size,
+                            void *data, int *got_frame,
                             AVPacket *avpkt)
 {
     DfaContext *s = avctx->priv_data;
@@ -327,7 +328,7 @@
     if (s->pic.data[0])
         avctx->release_buffer(avctx, &s->pic);
 
-    if ((ret = avctx->get_buffer(avctx, &s->pic))) {
+    if ((ret = ff_get_buffer(avctx, &s->pic))) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -368,7 +369,7 @@
     }
     memcpy(s->pic.data[1], s->pal, sizeof(s->pal));
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*)data = s->pic;
 
     return avpkt->size;
diff --git a/libavcodec/dirac.c b/libavcodec/dirac.c
index 4fcb3a2..e132acc 100644
--- a/libavcodec/dirac.c
+++ b/libavcodec/dirac.c
@@ -119,6 +119,7 @@
     AVRational frame_rate = {0,0};
     unsigned luma_depth = 8, luma_offset = 16;
     int idx;
+    int chroma_x_shift, chroma_y_shift;
 
     /* [DIRAC_STD] 10.3.2 Frame size. frame_size(video_params) */
     /* [DIRAC_STD] custom_dimensions_flag */
@@ -235,6 +236,12 @@
         av_log(avctx, AV_LOG_WARNING, "Bitdepth greater than 8\n");
 
     avctx->pix_fmt = dirac_pix_fmt[!luma_offset][source->chroma_format];
+    avcodec_get_chroma_sub_sample(avctx->pix_fmt, &chroma_x_shift, &chroma_y_shift);
+    if ((source->width % (1<<chroma_x_shift)) || (source->height % (1<<chroma_y_shift))) {
+        av_log(avctx, AV_LOG_ERROR, "Dimensions must be a integer multiply of the chroma subsampling\n");
+        return AVERROR_INVALIDDATA;
+    }
+
 
     /* [DIRAC_STD] 10.3.9 Colour specification. colour_spec(video_params) */
     if (get_bits1(gb)) { /* [DIRAC_STD] custom_colour_spec_flag */
diff --git a/libavcodec/dirac_dwt.c b/libavcodec/dirac_dwt.c
new file mode 100644
index 0000000..a2848f0
--- /dev/null
+++ b/libavcodec/dirac_dwt.c
@@ -0,0 +1,585 @@
+/*
+ * Copyright (C) 2004-2010 Michael Niedermayer <michaelni@gmx.at>
+ * Copyright (C) 2008 David Conrad
+ *
+ * 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/attributes.h"
+#include "libavutil/avassert.h"
+#include "libavutil/common.h"
+#include "dsputil.h"
+#include "dirac_dwt.h"
+#include "libavcodec/x86/dirac_dwt.h"
+
+
+static inline int mirror(int v, int m)
+{
+    while ((unsigned)v > (unsigned)m) {
+        v = -v;
+        if (v < 0)
+            v += 2 * m;
+    }
+    return v;
+}
+
+static void vertical_compose53iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
+                                  int width)
+{
+    int i;
+
+    for (i = 0; i < width; i++)
+        b1[i] -= (b0[i] + b2[i] + 2) >> 2;
+}
+
+
+static av_always_inline
+void interleave(IDWTELEM *dst, IDWTELEM *src0, IDWTELEM *src1, int w2, int add, int shift)
+{
+    int i;
+    for (i = 0; i < w2; i++) {
+        dst[2*i  ] = (src0[i] + add) >> shift;
+        dst[2*i+1] = (src1[i] + add) >> shift;
+    }
+}
+
+static void horizontal_compose_dirac53i(IDWTELEM *b, IDWTELEM *temp, int w)
+{
+    const int w2 = w >> 1;
+    int x;
+
+    temp[0] = COMPOSE_53iL0(b[w2], b[0], b[w2]);
+    for (x = 1; x < w2; x++) {
+        temp[x     ] = COMPOSE_53iL0     (b[x+w2-1], b[x     ], b[x+w2]);
+        temp[x+w2-1] = COMPOSE_DIRAC53iH0(temp[x-1], b[x+w2-1], temp[x]);
+    }
+    temp[w-1] = COMPOSE_DIRAC53iH0(temp[w2-1], b[w-1], temp[w2-1]);
+
+    interleave(b, temp, temp+w2, w2, 1, 1);
+}
+
+static void horizontal_compose_dd97i(IDWTELEM *b, IDWTELEM *tmp, int w)
+{
+    const int w2 = w >> 1;
+    int x;
+
+    tmp[0] = COMPOSE_53iL0(b[w2], b[0], b[w2]);
+    for (x = 1; x < w2; x++)
+        tmp[x] = COMPOSE_53iL0(b[x+w2-1], b[x], b[x+w2]);
+
+    // extend the edges
+    tmp[-1]   = tmp[0];
+    tmp[w2+1] = tmp[w2] = tmp[w2-1];
+
+    for (x = 0; x < w2; x++) {
+        b[2*x  ] = (tmp[x] + 1)>>1;
+        b[2*x+1] = (COMPOSE_DD97iH0(tmp[x-1], tmp[x], b[x+w2], tmp[x+1], tmp[x+2]) + 1)>>1;
+    }
+}
+
+static void horizontal_compose_dd137i(IDWTELEM *b, IDWTELEM *tmp, int w)
+{
+    const int w2 = w >> 1;
+    int x;
+
+    tmp[0] = COMPOSE_DD137iL0(b[w2], b[w2], b[0], b[w2  ], b[w2+1]);
+    tmp[1] = COMPOSE_DD137iL0(b[w2], b[w2], b[1], b[w2+1], b[w2+2]);
+    for (x = 2; x < w2-1; x++)
+        tmp[x] = COMPOSE_DD137iL0(b[x+w2-2], b[x+w2-1], b[x], b[x+w2], b[x+w2+1]);
+    tmp[w2-1] = COMPOSE_DD137iL0(b[w-3], b[w-2], b[w2-1], b[w-1], b[w-1]);
+
+    // extend the edges
+    tmp[-1]   = tmp[0];
+    tmp[w2+1] = tmp[w2] = tmp[w2-1];
+
+    for (x = 0; x < w2; x++) {
+        b[2*x  ] = (tmp[x] + 1)>>1;
+        b[2*x+1] = (COMPOSE_DD97iH0(tmp[x-1], tmp[x], b[x+w2], tmp[x+1], tmp[x+2]) + 1)>>1;
+    }
+}
+
+static av_always_inline
+void horizontal_compose_haari(IDWTELEM *b, IDWTELEM *temp, int w, int shift)
+{
+    const int w2 = w >> 1;
+    int x;
+
+    for (x = 0; x < w2; x++) {
+        temp[x   ] = COMPOSE_HAARiL0(b[x   ], b[x+w2]);
+        temp[x+w2] = COMPOSE_HAARiH0(b[x+w2], temp[x]);
+    }
+
+    interleave(b, temp, temp+w2, w2, shift, shift);
+}
+
+static void horizontal_compose_haar0i(IDWTELEM *b, IDWTELEM *temp, int w)
+{
+    horizontal_compose_haari(b, temp, w, 0);
+}
+
+static void horizontal_compose_haar1i(IDWTELEM *b, IDWTELEM *temp, int w)
+{
+    horizontal_compose_haari(b, temp, w, 1);
+}
+
+static void horizontal_compose_fidelityi(IDWTELEM *b, IDWTELEM *tmp, int w)
+{
+    const int w2 = w >> 1;
+    int i, x;
+    IDWTELEM v[8];
+
+    for (x = 0; x < w2; x++) {
+        for (i = 0; i < 8; i++)
+            v[i] = b[av_clip(x-3+i, 0, w2-1)];
+        tmp[x] = COMPOSE_FIDELITYiH0(v[0], v[1], v[2], v[3], b[x+w2], v[4], v[5], v[6], v[7]);
+    }
+
+    for (x = 0; x < w2; x++) {
+        for (i = 0; i < 8; i++)
+            v[i] = tmp[av_clip(x-4+i, 0, w2-1)];
+        tmp[x+w2] = COMPOSE_FIDELITYiL0(v[0], v[1], v[2], v[3], b[x], v[4], v[5], v[6], v[7]);
+    }
+
+    interleave(b, tmp+w2, tmp, w2, 0, 0);
+}
+
+static void horizontal_compose_daub97i(IDWTELEM *b, IDWTELEM *temp, int w)
+{
+    const int w2 = w >> 1;
+    int x, b0, b1, b2;
+
+    temp[0] = COMPOSE_DAUB97iL1(b[w2], b[0], b[w2]);
+    for (x = 1; x < w2; x++) {
+        temp[x     ] = COMPOSE_DAUB97iL1(b[x+w2-1], b[x     ], b[x+w2]);
+        temp[x+w2-1] = COMPOSE_DAUB97iH1(temp[x-1], b[x+w2-1], temp[x]);
+    }
+    temp[w-1] = COMPOSE_DAUB97iH1(temp[w2-1], b[w-1], temp[w2-1]);
+
+    // second stage combined with interleave and shift
+    b0 = b2 = COMPOSE_DAUB97iL0(temp[w2], temp[0], temp[w2]);
+    b[0] = (b0 + 1) >> 1;
+    for (x = 1; x < w2; x++) {
+        b2 = COMPOSE_DAUB97iL0(temp[x+w2-1], temp[x     ], temp[x+w2]);
+        b1 = COMPOSE_DAUB97iH0(          b0, temp[x+w2-1], b2        );
+        b[2*x-1] = (b1 + 1) >> 1;
+        b[2*x  ] = (b2 + 1) >> 1;
+        b0 = b2;
+    }
+    b[w-1] = (COMPOSE_DAUB97iH0(b2, temp[w-1], b2) + 1) >> 1;
+}
+
+static void vertical_compose_dirac53iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width)
+{
+    int i;
+
+    for(i=0; i<width; i++){
+        b1[i] = COMPOSE_DIRAC53iH0(b0[i], b1[i], b2[i]);
+    }
+}
+
+static void vertical_compose_dd97iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
+                                  IDWTELEM *b3, IDWTELEM *b4, int width)
+{
+    int i;
+
+    for(i=0; i<width; i++){
+        b2[i] = COMPOSE_DD97iH0(b0[i], b1[i], b2[i], b3[i], b4[i]);
+    }
+}
+
+static void vertical_compose_dd137iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
+                                      IDWTELEM *b3, IDWTELEM *b4, int width)
+{
+    int i;
+
+    for(i=0; i<width; i++){
+        b2[i] = COMPOSE_DD137iL0(b0[i], b1[i], b2[i], b3[i], b4[i]);
+    }
+}
+
+static void vertical_compose_haar(IDWTELEM *b0, IDWTELEM *b1, int width)
+{
+    int i;
+
+    for (i = 0; i < width; i++) {
+        b0[i] = COMPOSE_HAARiL0(b0[i], b1[i]);
+        b1[i] = COMPOSE_HAARiH0(b1[i], b0[i]);
+    }
+}
+
+static void vertical_compose_fidelityiH0(IDWTELEM *dst, IDWTELEM *b[8], int width)
+{
+    int i;
+
+    for(i=0; i<width; i++){
+        dst[i] = COMPOSE_FIDELITYiH0(b[0][i], b[1][i], b[2][i], b[3][i], dst[i], b[4][i], b[5][i], b[6][i], b[7][i]);
+    }
+}
+
+static void vertical_compose_fidelityiL0(IDWTELEM *dst, IDWTELEM *b[8], int width)
+{
+    int i;
+
+    for(i=0; i<width; i++){
+        dst[i] = COMPOSE_FIDELITYiL0(b[0][i], b[1][i], b[2][i], b[3][i], dst[i], b[4][i], b[5][i], b[6][i], b[7][i]);
+    }
+}
+
+static void vertical_compose_daub97iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width)
+{
+    int i;
+
+    for(i=0; i<width; i++){
+        b1[i] = COMPOSE_DAUB97iH0(b0[i], b1[i], b2[i]);
+    }
+}
+
+static void vertical_compose_daub97iH1(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width)
+{
+    int i;
+
+    for(i=0; i<width; i++){
+        b1[i] = COMPOSE_DAUB97iH1(b0[i], b1[i], b2[i]);
+    }
+}
+
+static void vertical_compose_daub97iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width)
+{
+    int i;
+
+    for(i=0; i<width; i++){
+        b1[i] = COMPOSE_DAUB97iL0(b0[i], b1[i], b2[i]);
+    }
+}
+
+static void vertical_compose_daub97iL1(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width)
+{
+    int i;
+
+    for(i=0; i<width; i++){
+        b1[i] = COMPOSE_DAUB97iL1(b0[i], b1[i], b2[i]);
+    }
+}
+
+
+static void spatial_compose_dd97i_dy(DWTContext *d, int level, int width, int height, int stride)
+{
+    vertical_compose_3tap vertical_compose_l0 = (void*)d->vertical_compose_l0;
+    vertical_compose_5tap vertical_compose_h0 = (void*)d->vertical_compose_h0;
+    DWTCompose *cs = d->cs + level;
+
+    int i, y = cs->y;
+    IDWTELEM *b[8];
+    for (i = 0; i < 6; i++)
+        b[i] = cs->b[i];
+    b[6] = d->buffer + av_clip(y+5, 0, height-2)*stride;
+    b[7] = d->buffer + av_clip(y+6, 1, height-1)*stride;
+
+        if(y+5<(unsigned)height) vertical_compose_l0(      b[5], b[6], b[7],       width);
+        if(y+1<(unsigned)height) vertical_compose_h0(b[0], b[2], b[3], b[4], b[6], width);
+
+        if(y-1<(unsigned)height) d->horizontal_compose(b[0], d->temp, width);
+        if(y+0<(unsigned)height) d->horizontal_compose(b[1], d->temp, width);
+
+    for (i = 0; i < 6; i++)
+        cs->b[i] = b[i+2];
+    cs->y += 2;
+}
+
+static void spatial_compose_dirac53i_dy(DWTContext *d, int level, int width, int height, int stride)
+{
+    vertical_compose_3tap vertical_compose_l0 = (void*)d->vertical_compose_l0;
+    vertical_compose_3tap vertical_compose_h0 = (void*)d->vertical_compose_h0;
+    DWTCompose *cs = d->cs + level;
+
+    int y= cs->y;
+    IDWTELEM *b[4] = { cs->b[0], cs->b[1] };
+    b[2] = d->buffer + mirror(y+1, height-1)*stride;
+    b[3] = d->buffer + mirror(y+2, height-1)*stride;
+
+        if(y+1<(unsigned)height) vertical_compose_l0(b[1], b[2], b[3], width);
+        if(y+0<(unsigned)height) vertical_compose_h0(b[0], b[1], b[2], width);
+
+        if(y-1<(unsigned)height) d->horizontal_compose(b[0], d->temp, width);
+        if(y+0<(unsigned)height) d->horizontal_compose(b[1], d->temp, width);
+
+    cs->b[0] = b[2];
+    cs->b[1] = b[3];
+    cs->y += 2;
+}
+
+
+static void spatial_compose_dd137i_dy(DWTContext *d, int level, int width, int height, int stride)
+{
+    vertical_compose_5tap vertical_compose_l0 = (void*)d->vertical_compose_l0;
+    vertical_compose_5tap vertical_compose_h0 = (void*)d->vertical_compose_h0;
+    DWTCompose *cs = d->cs + level;
+
+    int i, y = cs->y;
+    IDWTELEM *b[10];
+    for (i = 0; i < 8; i++)
+        b[i] = cs->b[i];
+    b[8] = d->buffer + av_clip(y+7, 0, height-2)*stride;
+    b[9] = d->buffer + av_clip(y+8, 1, height-1)*stride;
+
+        if(y+5<(unsigned)height) vertical_compose_l0(b[3], b[5], b[6], b[7], b[9], width);
+        if(y+1<(unsigned)height) vertical_compose_h0(b[0], b[2], b[3], b[4], b[6], width);
+
+        if(y-1<(unsigned)height) d->horizontal_compose(b[0], d->temp, width);
+        if(y+0<(unsigned)height) d->horizontal_compose(b[1], d->temp, width);
+
+    for (i = 0; i < 8; i++)
+        cs->b[i] = b[i+2];
+    cs->y += 2;
+}
+
+// haar makes the assumption that height is even (always true for dirac)
+static void spatial_compose_haari_dy(DWTContext *d, int level, int width, int height, int stride)
+{
+    vertical_compose_2tap vertical_compose = (void*)d->vertical_compose;
+    int y = d->cs[level].y;
+    IDWTELEM *b0 = d->buffer + (y-1)*stride;
+    IDWTELEM *b1 = d->buffer + (y  )*stride;
+
+    vertical_compose(b0, b1, width);
+    d->horizontal_compose(b0, d->temp, width);
+    d->horizontal_compose(b1, d->temp, width);
+
+    d->cs[level].y += 2;
+}
+
+// Don't do sliced idwt for fidelity; the 9 tap filter makes it a bit annoying
+// Fortunately, this filter isn't used in practice.
+static void spatial_compose_fidelity(DWTContext *d, int level, int width, int height, int stride)
+{
+    vertical_compose_9tap vertical_compose_l0 = (void*)d->vertical_compose_l0;
+    vertical_compose_9tap vertical_compose_h0 = (void*)d->vertical_compose_h0;
+    int i, y;
+    IDWTELEM *b[8];
+
+    for (y = 1; y < height; y += 2) {
+        for (i = 0; i < 8; i++)
+            b[i] = d->buffer + av_clip((y-7 + 2*i), 0, height-2)*stride;
+        vertical_compose_h0(d->buffer + y*stride, b, width);
+    }
+
+    for (y = 0; y < height; y += 2) {
+        for (i = 0; i < 8; i++)
+            b[i] = d->buffer + av_clip((y-7 + 2*i), 1, height-1)*stride;
+        vertical_compose_l0(d->buffer + y*stride, b, width);
+    }
+
+    for (y = 0; y < height; y++)
+        d->horizontal_compose(d->buffer + y*stride, d->temp, width);
+
+    d->cs[level].y = height+1;
+}
+
+static void spatial_compose_daub97i_dy(DWTContext *d, int level, int width, int height, int stride)
+{
+    vertical_compose_3tap vertical_compose_l0 = (void*)d->vertical_compose_l0;
+    vertical_compose_3tap vertical_compose_h0 = (void*)d->vertical_compose_h0;
+    vertical_compose_3tap vertical_compose_l1 = (void*)d->vertical_compose_l1;
+    vertical_compose_3tap vertical_compose_h1 = (void*)d->vertical_compose_h1;
+    DWTCompose *cs = d->cs + level;
+
+    int i, y = cs->y;
+    IDWTELEM *b[6];
+    for (i = 0; i < 4; i++)
+        b[i] = cs->b[i];
+    b[4] = d->buffer + mirror(y+3, height-1)*stride;
+    b[5] = d->buffer + mirror(y+4, height-1)*stride;
+
+        if(y+3<(unsigned)height) vertical_compose_l1(b[3], b[4], b[5], width);
+        if(y+2<(unsigned)height) vertical_compose_h1(b[2], b[3], b[4], width);
+        if(y+1<(unsigned)height) vertical_compose_l0(b[1], b[2], b[3], width);
+        if(y+0<(unsigned)height) vertical_compose_h0(b[0], b[1], b[2], width);
+
+        if(y-1<(unsigned)height) d->horizontal_compose(b[0], d->temp, width);
+        if(y+0<(unsigned)height) d->horizontal_compose(b[1], d->temp, width);
+
+    for (i = 0; i < 4; i++)
+        cs->b[i] = b[i+2];
+    cs->y += 2;
+}
+
+
+static void spatial_compose97i_init2(DWTCompose *cs, IDWTELEM *buffer, int height, int stride)
+{
+    cs->b[0] = buffer + mirror(-3-1, height-1)*stride;
+    cs->b[1] = buffer + mirror(-3  , height-1)*stride;
+    cs->b[2] = buffer + mirror(-3+1, height-1)*stride;
+    cs->b[3] = buffer + mirror(-3+2, height-1)*stride;
+    cs->y = -3;
+}
+
+static void spatial_compose53i_init2(DWTCompose *cs, IDWTELEM *buffer, int height, int stride)
+{
+    cs->b[0] = buffer + mirror(-1-1, height-1)*stride;
+    cs->b[1] = buffer + mirror(-1  , height-1)*stride;
+    cs->y = -1;
+}
+
+static void spatial_compose_dd97i_init(DWTCompose *cs, IDWTELEM *buffer, int height, int stride)
+{
+    cs->b[0] = buffer + av_clip(-5-1, 0, height-2)*stride;
+    cs->b[1] = buffer + av_clip(-5  , 1, height-1)*stride;
+    cs->b[2] = buffer + av_clip(-5+1, 0, height-2)*stride;
+    cs->b[3] = buffer + av_clip(-5+2, 1, height-1)*stride;
+    cs->b[4] = buffer + av_clip(-5+3, 0, height-2)*stride;
+    cs->b[5] = buffer + av_clip(-5+4, 1, height-1)*stride;
+    cs->y = -5;
+}
+
+static void spatial_compose_dd137i_init(DWTCompose *cs, IDWTELEM *buffer, int height, int stride)
+{
+    cs->b[0] = buffer + av_clip(-5-1, 0, height-2)*stride;
+    cs->b[1] = buffer + av_clip(-5  , 1, height-1)*stride;
+    cs->b[2] = buffer + av_clip(-5+1, 0, height-2)*stride;
+    cs->b[3] = buffer + av_clip(-5+2, 1, height-1)*stride;
+    cs->b[4] = buffer + av_clip(-5+3, 0, height-2)*stride;
+    cs->b[5] = buffer + av_clip(-5+4, 1, height-1)*stride;
+    cs->b[6] = buffer + av_clip(-5+5, 0, height-2)*stride;
+    cs->b[7] = buffer + av_clip(-5+6, 1, height-1)*stride;
+    cs->y = -5;
+}
+
+int ff_spatial_idwt_init2(DWTContext *d, IDWTELEM *buffer, int width, int height,
+                          int stride, enum dwt_type type, int decomposition_count,
+                          IDWTELEM *temp)
+{
+    int level;
+
+    d->buffer = buffer;
+    d->width = width;
+    d->height = height;
+    d->stride = stride;
+    d->decomposition_count = decomposition_count;
+    d->temp = temp + 8;
+
+    for(level=decomposition_count-1; level>=0; level--){
+        int hl = height >> level;
+        int stride_l = stride << level;
+
+        switch(type){
+        case DWT_DIRAC_DD9_7:
+            spatial_compose_dd97i_init(d->cs+level, buffer, hl, stride_l);
+            break;
+        case DWT_DIRAC_LEGALL5_3:
+            spatial_compose53i_init2(d->cs+level, buffer, hl, stride_l);
+            break;
+        case DWT_DIRAC_DD13_7:
+            spatial_compose_dd137i_init(d->cs+level, buffer, hl, stride_l);
+            break;
+        case DWT_DIRAC_HAAR0:
+        case DWT_DIRAC_HAAR1:
+            d->cs[level].y = 1;
+            break;
+        case DWT_DIRAC_DAUB9_7:
+            spatial_compose97i_init2(d->cs+level, buffer, hl, stride_l);
+            break;
+        default:
+            d->cs[level].y = 0;
+            break;
+        }
+    }
+
+    switch (type) {
+    case DWT_DIRAC_DD9_7:
+        d->spatial_compose = spatial_compose_dd97i_dy;
+        d->vertical_compose_l0 = (void*)vertical_compose53iL0;
+        d->vertical_compose_h0 = (void*)vertical_compose_dd97iH0;
+        d->horizontal_compose = horizontal_compose_dd97i;
+        d->support = 7;
+        break;
+    case DWT_DIRAC_LEGALL5_3:
+        d->spatial_compose = spatial_compose_dirac53i_dy;
+        d->vertical_compose_l0 = (void*)vertical_compose53iL0;
+        d->vertical_compose_h0 = (void*)vertical_compose_dirac53iH0;
+        d->horizontal_compose = horizontal_compose_dirac53i;
+        d->support = 3;
+        break;
+    case DWT_DIRAC_DD13_7:
+        d->spatial_compose = spatial_compose_dd137i_dy;
+        d->vertical_compose_l0 = (void*)vertical_compose_dd137iL0;
+        d->vertical_compose_h0 = (void*)vertical_compose_dd97iH0;
+        d->horizontal_compose = horizontal_compose_dd137i;
+        d->support = 7;
+        break;
+    case DWT_DIRAC_HAAR0:
+    case DWT_DIRAC_HAAR1:
+        d->spatial_compose = spatial_compose_haari_dy;
+        d->vertical_compose = (void*)vertical_compose_haar;
+        if (type == DWT_DIRAC_HAAR0)
+            d->horizontal_compose = horizontal_compose_haar0i;
+        else
+            d->horizontal_compose = horizontal_compose_haar1i;
+        d->support = 1;
+        break;
+    case DWT_DIRAC_FIDELITY:
+        d->spatial_compose = spatial_compose_fidelity;
+        d->vertical_compose_l0 = (void*)vertical_compose_fidelityiL0;
+        d->vertical_compose_h0 = (void*)vertical_compose_fidelityiH0;
+        d->horizontal_compose = horizontal_compose_fidelityi;
+        break;
+    case DWT_DIRAC_DAUB9_7:
+        d->spatial_compose = spatial_compose_daub97i_dy;
+        d->vertical_compose_l0 = (void*)vertical_compose_daub97iL0;
+        d->vertical_compose_h0 = (void*)vertical_compose_daub97iH0;
+        d->vertical_compose_l1 = (void*)vertical_compose_daub97iL1;
+        d->vertical_compose_h1 = (void*)vertical_compose_daub97iH1;
+        d->horizontal_compose = horizontal_compose_daub97i;
+        d->support = 5;
+        break;
+    default:
+        av_log(NULL, AV_LOG_ERROR, "Unknown wavelet type %d\n", type);
+        return -1;
+    }
+
+    if (HAVE_MMX) ff_spatial_idwt_init_mmx(d, type);
+
+    return 0;
+}
+
+void ff_spatial_idwt_slice2(DWTContext *d, int y)
+{
+    int level, support = d->support;
+
+    for (level = d->decomposition_count-1; level >= 0; level--) {
+        int wl = d->width  >> level;
+        int hl = d->height >> level;
+        int stride_l = d->stride << level;
+
+        while (d->cs[level].y <= FFMIN((y>>level)+support, hl))
+            d->spatial_compose(d, level, wl, hl, stride_l);
+    }
+}
+
+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
new file mode 100644
index 0000000..9514e95
--- /dev/null
+++ b/libavcodec/dirac_dwt.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2004-2010 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
+ */
+
+#ifndef AVCODEC_DIRAC_DWT_H
+#define AVCODEC_DIRAC_DWT_H
+
+#include <stdint.h>
+
+typedef int DWTELEM;
+typedef short IDWTELEM;
+
+#define MAX_DWT_SUPPORT 8
+#define MAX_DECOMPOSITIONS 8
+
+typedef struct DWTCompose {
+    IDWTELEM *b[MAX_DWT_SUPPORT];
+    int y;
+} DWTCompose;
+
+struct DWTContext;
+
+// Possible prototypes for vertical_compose functions
+typedef void (*vertical_compose_2tap)(IDWTELEM *b0, IDWTELEM *b1, int width);
+typedef void (*vertical_compose_3tap)(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width);
+typedef void (*vertical_compose_5tap)(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, IDWTELEM *b3, IDWTELEM *b4, int width);
+typedef void (*vertical_compose_9tap)(IDWTELEM *dst, IDWTELEM *b[8], int width);
+
+typedef struct DWTContext {
+    IDWTELEM *buffer;
+    IDWTELEM *temp;
+    int width;
+    int height;
+    int stride;
+    int decomposition_count;
+    int support;
+
+    void (*spatial_compose)(struct DWTContext *cs, int level, int width, int height, int stride);
+    void (*vertical_compose_l0)(void);
+    void (*vertical_compose_h0)(void);
+    void (*vertical_compose_l1)(void);
+    void (*vertical_compose_h1)(void);
+    void (*vertical_compose)(void);     ///< one set of lowpass and highpass combined
+    void (*horizontal_compose)(IDWTELEM *b, IDWTELEM *tmp, int width);
+
+    DWTCompose cs[MAX_DECOMPOSITIONS];
+} DWTContext;
+
+enum dwt_type {
+    DWT_SNOW_DAUB9_7,
+    DWT_SNOW_LEGALL5_3,
+    DWT_DIRAC_DD9_7,
+    DWT_DIRAC_LEGALL5_3,
+    DWT_DIRAC_DD13_7,
+    DWT_DIRAC_HAAR0,
+    DWT_DIRAC_HAAR1,
+    DWT_DIRAC_FIDELITY,
+    DWT_DIRAC_DAUB9_7,
+    DWT_NUM_TYPES
+};
+
+// -1 if an error occurred, e.g. the dwt_type isn't recognized
+int ff_spatial_idwt_init2(DWTContext *d, IDWTELEM *buffer, int width, int height,
+                          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
+#define COMPOSE_53iL0(b0, b1, b2)\
+    (b1 - ((b0 + b2 + 2) >> 2))
+
+#define COMPOSE_DIRAC53iH0(b0, b1, b2)\
+    (b1 + ((b0 + b2 + 1) >> 1))
+
+#define COMPOSE_DD97iH0(b0, b1, b2, b3, b4)\
+    (b2 + ((-b0 + 9*b1 + 9*b3 - b4 + 8) >> 4))
+
+#define COMPOSE_DD137iL0(b0, b1, b2, b3, b4)\
+    (b2 - ((-b0 + 9*b1 + 9*b3 - b4 + 16) >> 5))
+
+#define COMPOSE_HAARiL0(b0, b1)\
+    (b0 - ((b1 + 1) >> 1))
+
+#define COMPOSE_HAARiH0(b0, b1)\
+    (b0 + b1)
+
+#define COMPOSE_FIDELITYiL0(b0, b1, b2, b3, b4, b5, b6, b7, b8)\
+    (b4 - ((-8*(b0+b8) + 21*(b1+b7) - 46*(b2+b6) + 161*(b3+b5) + 128) >> 8))
+
+#define COMPOSE_FIDELITYiH0(b0, b1, b2, b3, b4, b5, b6, b7, b8)\
+    (b4 + ((-2*(b0+b8) + 10*(b1+b7) - 25*(b2+b6) + 81*(b3+b5) + 128) >> 8))
+
+#define COMPOSE_DAUB97iL1(b0, b1, b2)\
+    (b1 - ((1817*(b0 + b2) + 2048) >> 12))
+
+#define COMPOSE_DAUB97iH1(b0, b1, b2)\
+    (b1 - (( 113*(b0 + b2) + 64) >> 7))
+
+#define COMPOSE_DAUB97iL0(b0, b1, b2)\
+    (b1 + (( 217*(b0 + b2) + 2048) >> 12))
+
+#define COMPOSE_DAUB97iH0(b0, b1, b2)\
+    (b1 + ((6497*(b0 + b2) + 2048) >> 12))
+
+
+#endif /* AVCODEC_DWT_H */
diff --git a/libavcodec/dirac_parser.c b/libavcodec/dirac_parser.c
index a7c7c32..a2a22ee 100644
--- a/libavcodec/dirac_parser.c
+++ b/libavcodec/dirac_parser.c
@@ -161,7 +161,9 @@
          * we can be pretty sure that we have a valid parse unit */
         if (!unpack_parse_unit(&pu1, pc, pc->index - 13)                     ||
             !unpack_parse_unit(&pu, pc, pc->index - 13 - pu1.prev_pu_offset) ||
-            pu.next_pu_offset != pu1.prev_pu_offset) {
+            pu.next_pu_offset != pu1.prev_pu_offset                          ||
+            pc->index < pc->dirac_unit_size + 13LL + pu1.prev_pu_offset
+        ) {
             pc->index -= 9;
             *buf_size = next-9;
             pc->header_bytes_needed = 9;
diff --git a/libavcodec/diracdec.c b/libavcodec/diracdec.c
index 6e81491..a791e88 100644
--- a/libavcodec/diracdec.c
+++ b/libavcodec/diracdec.c
@@ -30,12 +30,14 @@
 #include "dsputil.h"
 #include "get_bits.h"
 #include "bytestream.h"
+#include "internal.h"
 #include "golomb.h"
 #include "dirac_arith.h"
 #include "mpeg12data.h"
-#include "dwt.h"
+#include "dirac_dwt.h"
 #include "dirac.h"
 #include "diracdsp.h"
+#include "videodsp.h" // for ff_emulated_edge_mc_8
 
 /**
  * The spec limits the number of wavelet decompositions to 4 for both
@@ -349,10 +351,10 @@
     s->blmotion = av_malloc(sbwidth * sbheight * 16 * sizeof(*s->blmotion));
     s->edge_emu_buffer_base = av_malloc((w+64)*MAX_BLOCKSIZE);
 
-    s->mctmp     = av_malloc((w+64+MAX_BLOCKSIZE) * (h*MAX_BLOCKSIZE) * sizeof(*s->mctmp));
+    s->mctmp     = av_malloc((w+64+MAX_BLOCKSIZE) * (h+MAX_BLOCKSIZE) * sizeof(*s->mctmp));
     s->mcscratch = av_malloc((w+64)*MAX_BLOCKSIZE);
 
-    if (!s->sbsplit || !s->blmotion)
+    if (!s->sbsplit || !s->blmotion || !s->mctmp || !s->mcscratch)
         return AVERROR(ENOMEM);
     return 0;
 }
@@ -1408,8 +1410,9 @@
     }
 
     /* fixme: v/h _edge_pos */
-    if ((unsigned)x > FFMAX(p->width +EDGE_WIDTH/2 - p->xblen, 0) ||
-        (unsigned)y > FFMAX(p->height+EDGE_WIDTH/2 - p->yblen, 0)) {
+    if (x + p->xblen > p->width +EDGE_WIDTH/2 ||
+        y + p->yblen > p->height+EDGE_WIDTH/2 ||
+        x < 0 || y < 0) {
         for (i = 0; i < nplanes; i++) {
             ff_emulated_edge_mc(s->edge_emu_buffer[i], src[i], p->stride,
                                 p->xblen, p->yblen, x, y,
@@ -1668,7 +1671,7 @@
             for (j = 0; j < MAX_FRAMES; j++)
                 if (!s->all_frames[j].avframe.data[0]) {
                     s->ref_pics[i] = &s->all_frames[j];
-                    s->avctx->get_buffer(s->avctx, &s->ref_pics[i]->avframe);
+                    ff_get_buffer(s->avctx, &s->ref_pics[i]->avframe);
                     break;
                 }
     }
@@ -1705,7 +1708,7 @@
     return 0;
 }
 
-static int get_delayed_pic(DiracContext *s, AVFrame *picture, int *data_size)
+static int get_delayed_pic(DiracContext *s, AVFrame *picture, int *got_frame)
 {
     DiracFrame *out = s->delay_frames[0];
     int i, out_idx  = 0;
@@ -1722,7 +1725,7 @@
 
     if (out) {
         out->avframe.reference ^= DELAYED_PIC_REF;
-        *data_size = sizeof(AVFrame);
+        *got_frame = 1;
         *(AVFrame *)picture = out->avframe;
     }
 
@@ -1806,7 +1809,7 @@
         pic->avframe.key_frame = s->num_refs == 0;             /* [DIRAC_STD] is_intra()      */
         pic->avframe.pict_type = s->num_refs + 1;              /* Definition of AVPictureType in avutil.h */
 
-        if (avctx->get_buffer(avctx, &pic->avframe) < 0) {
+        if (ff_get_buffer(avctx, &pic->avframe) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
             return -1;
         }
@@ -1826,7 +1829,7 @@
     return 0;
 }
 
-static int dirac_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *pkt)
+static int dirac_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *pkt)
 {
     DiracContext *s     = avctx->priv_data;
     DiracFrame *picture = data;
@@ -1842,11 +1845,11 @@
         }
 
     s->current_picture = NULL;
-    *data_size = 0;
+    *got_frame = 0;
 
     /* end of stream, so flush delayed pics */
     if (buf_size == 0)
-        return get_delayed_pic(s, (AVFrame *)data, data_size);
+        return get_delayed_pic(s, (AVFrame *)data, got_frame);
 
     for (;;) {
         /*[DIRAC_STD] Here starts the code from parse_info() defined in 9.6
@@ -1904,15 +1907,15 @@
         if (delayed_frame) {
             delayed_frame->avframe.reference ^= DELAYED_PIC_REF;
             *(AVFrame*)data = delayed_frame->avframe;
-            *data_size = sizeof(AVFrame);
+            *got_frame = 1;
         }
     } else if (s->current_picture->avframe.display_picture_number == s->frame_number) {
         /* The right frame at the right time :-) */
         *(AVFrame*)data = s->current_picture->avframe;
-        *data_size = sizeof(AVFrame);
+        *got_frame = 1;
     }
 
-    if (*data_size)
+    if (*got_frame)
         s->frame_number = picture->avframe.display_picture_number + 1;
 
     return buf_idx;
diff --git a/libavcodec/dnxhddata.c b/libavcodec/dnxhddata.c
index 9e2e014..669b806 100644
--- a/libavcodec/dnxhddata.c
+++ b/libavcodec/dnxhddata.c
@@ -952,70 +952,80 @@
       dnxhd_1235_1241_ac_codes, dnxhd_1235_1241_ac_bits, dnxhd_1235_1241_ac_level,
       dnxhd_1235_1241_ac_flags,
       dnxhd_1235_1238_1241_run_codes, dnxhd_1235_1238_1241_run_bits, dnxhd_1235_1241_run,
-      { 175, 185, 365, 440 } },
+      { 175, 185, 365, 440 },
+      { { 24000, 1001 }, { 25, 1 }, { 50, 1 }, { 60000, 1001 } } },
     { 1237, 1920, 1080, 0, 606208, 606208, 4, 8, 3,
       dnxhd_1237_luma_weight, dnxhd_1237_chroma_weight,
       dnxhd_1237_dc_codes, dnxhd_1237_dc_bits,
       dnxhd_1237_ac_codes, dnxhd_1237_ac_bits, dnxhd_1237_ac_level,
       dnxhd_1237_ac_flags,
       dnxhd_1237_run_codes, dnxhd_1237_run_bits, dnxhd_1237_run,
-      { 115, 120, 145, 240, 290 } },
+      { 115, 120, 145, 240, 290 },
+      { { 24000, 1001 }, { 25, 1 }, { 30000, 1001 }, { 50, 1 }, { 60000, 1001 } } },
     { 1238, 1920, 1080, 0, 917504, 917504, 4, 8, 4,
       dnxhd_1238_luma_weight, dnxhd_1238_chroma_weight,
       dnxhd_1238_dc_codes, dnxhd_1238_dc_bits,
       dnxhd_1238_ac_codes, dnxhd_1238_ac_bits, dnxhd_1238_ac_level,
       dnxhd_1238_ac_flags,
       dnxhd_1235_1238_1241_run_codes, dnxhd_1235_1238_1241_run_bits, dnxhd_1238_run,
-      { 175, 185, 220, 365, 440 } },
+      { 175, 185, 220, 365, 440 },
+      { { 24000, 1001 }, { 25, 1 }, { 30000, 1001 }, { 50, 1 }, { 60000, 1001 } } },
     { 1241, 1920, 1080, 1, 917504, 458752, 6, 10, 4,
       dnxhd_1241_luma_weight, dnxhd_1241_chroma_weight,
       dnxhd_1235_1241_dc_codes, dnxhd_1235_1241_dc_bits,
       dnxhd_1235_1241_ac_codes, dnxhd_1235_1241_ac_bits, dnxhd_1235_1241_ac_level,
       dnxhd_1235_1241_ac_flags,
       dnxhd_1235_1238_1241_run_codes, dnxhd_1235_1238_1241_run_bits, dnxhd_1235_1241_run,
-      { 185, 220 } },
+      { 185, 220 },
+      { { 25, 1 }, { 30000, 1001 } } },
     { 1242, 1920, 1080, 1, 606208, 303104, 4, 8, 3,
       dnxhd_1242_luma_weight, dnxhd_1242_chroma_weight,
       dnxhd_1237_dc_codes, dnxhd_1237_dc_bits,
       dnxhd_1237_ac_codes, dnxhd_1237_ac_bits, dnxhd_1237_ac_level,
       dnxhd_1237_ac_flags,
       dnxhd_1237_run_codes, dnxhd_1237_run_bits, dnxhd_1237_run,
-      { 120, 145 } },
+      { 120, 145 },
+      { { 25, 1 }, { 30000, 1001 } } },
     { 1243, 1920, 1080, 1, 917504, 458752, 4, 8, 4,
       dnxhd_1243_luma_weight, dnxhd_1243_chroma_weight,
       dnxhd_1238_dc_codes, dnxhd_1238_dc_bits,
       dnxhd_1238_ac_codes, dnxhd_1238_ac_bits, dnxhd_1238_ac_level,
       dnxhd_1238_ac_flags,
       dnxhd_1235_1238_1241_run_codes, dnxhd_1235_1238_1241_run_bits, dnxhd_1238_run,
-      { 185, 220 } },
+      { 185, 220 },
+      { { 25, 1 }, { 30000, 1001 } } },
     { 1250, 1280,  720, 0, 458752, 458752, 6, 10, 4,
       dnxhd_1250_luma_weight, dnxhd_1250_chroma_weight,
       dnxhd_1250_dc_codes, dnxhd_1250_dc_bits,
       dnxhd_1250_ac_codes, dnxhd_1250_ac_bits, dnxhd_1250_ac_level,
       dnxhd_1250_ac_flags,
       dnxhd_1250_run_codes, dnxhd_1250_run_bits, dnxhd_1250_run,
-      { 90, 180, 220 } },
+      { 90, 90, 180, 220 },
+      { { 24000, 1001 }, { 25, 1 }, { 50, 1 }, { 60000, 1001 } } },
     { 1251, 1280,  720, 0, 458752, 458752, 4, 8, 4,
       dnxhd_1251_luma_weight, dnxhd_1251_chroma_weight,
       dnxhd_1251_dc_codes, dnxhd_1251_dc_bits,
       dnxhd_1251_ac_codes, dnxhd_1251_ac_bits, dnxhd_1251_ac_level,
       dnxhd_1251_ac_flags,
       dnxhd_1251_run_codes, dnxhd_1251_run_bits, dnxhd_1251_run,
-      { 90, 110, 175, 220 } },
+      { 90, 90, 110, 180, 220 },
+      { { 24000, 1001 }, { 25, 1 }, { 30000, 1001 }, { 50, 1 }, { 60000, 1001 } } },
     { 1252, 1280,  720, 0, 303104, 303104, 4, 8, 5,
       dnxhd_1252_luma_weight, dnxhd_1252_chroma_weight,
       dnxhd_1252_dc_codes, dnxhd_1252_dc_bits,
       dnxhd_1252_ac_codes, dnxhd_1252_ac_bits, dnxhd_1252_ac_level,
       dnxhd_1252_ac_flags,
       dnxhd_1251_run_codes, dnxhd_1251_run_bits, dnxhd_1251_run,
-      { 60, 75, 115, 145 } },
+      { 60, 60, 75, 120, 145 },
+      { { 24000, 1001 }, { 25, 1 }, { 30000, 1001 }, { 50, 1 }, { 60000, 1001 } } },
     { 1253, 1920, 1080, 0, 188416, 188416, 4, 8, 3,
       dnxhd_1237_luma_weight, dnxhd_1237_chroma_weight,
       dnxhd_1237_dc_codes, dnxhd_1237_dc_bits,
       dnxhd_1237_ac_codes, dnxhd_1237_ac_bits, dnxhd_1237_ac_level,
       dnxhd_1237_ac_flags,
       dnxhd_1237_run_codes, dnxhd_1237_run_bits, dnxhd_1237_run,
-      { 36, 45, 75, 90 } },
+      { 36, 36, 45, 75, 90 },
+      { { 24000, 1001 }, { 25, 1 }, { 30000, 1001 }, { 50, 1 }, { 60000, 1001 } } },
 };
 
 int ff_dnxhd_get_cid_table(int cid)
@@ -1027,6 +1037,14 @@
     return -1;
 }
 
+int avpriv_dnxhd_get_frame_size(int cid)
+{
+    int i = ff_dnxhd_get_cid_table(cid);
+    if (i<0)
+        return i;
+    return ff_dnxhd_cid_table[i].frame_size;
+}
+
 int ff_dnxhd_find_cid(AVCodecContext *avctx, int bit_depth)
 {
     int i, j;
@@ -1046,3 +1064,19 @@
     }
     return 0;
 }
+
+void ff_dnxhd_print_profiles(AVCodecContext *avctx, int loglevel)
+{
+    int i, j;
+    for (i = 0; i < FF_ARRAY_ELEMS(ff_dnxhd_cid_table); i++) {
+        const CIDEntry *cid = &ff_dnxhd_cid_table[i];
+        for (j = 0; j < FF_ARRAY_ELEMS(cid->bit_rates); j++) {
+            if (!cid->bit_rates[j])
+                break;
+
+            av_log(avctx, loglevel, "Frame size: %dx%d%c; bitrate: %dMbps; pixel format: %s; framerate: %d/%d\n",
+                   cid->width, cid->height, cid->interlaced ? 'i' : 'p', cid->bit_rates[j],
+                   cid->bit_depth == 10 ? "yuv422p10" : "yuv422p", cid->frame_rates[j].num, cid->frame_rates[j].den);
+        }
+    }
+}
diff --git a/libavcodec/dnxhddata.h b/libavcodec/dnxhddata.h
index 01c3f58..b8bcb21 100644
--- a/libavcodec/dnxhddata.h
+++ b/libavcodec/dnxhddata.h
@@ -43,11 +43,15 @@
     const uint16_t *run_codes;
     const uint8_t *run_bits, *run;
     int bit_rates[5]; ///< Helpher to choose variants, rounded to nearest 5Mb/s
+    AVRational frame_rates[5];
 } CIDEntry;
 
 extern av_export const CIDEntry ff_dnxhd_cid_table[];
 
 int ff_dnxhd_get_cid_table(int cid);
 int ff_dnxhd_find_cid(AVCodecContext *avctx, int bit_depth);
+void ff_dnxhd_print_profiles(AVCodecContext *avctx, int loglevel);
+
+int avpriv_dnxhd_get_frame_size(int cid);
 
 #endif /* AVCODEC_DNXHDDATA_H */
diff --git a/libavcodec/dnxhddec.c b/libavcodec/dnxhddec.c
index 4f3968a..0af685e 100644
--- a/libavcodec/dnxhddec.c
+++ b/libavcodec/dnxhddec.c
@@ -30,13 +30,14 @@
 #include "get_bits.h"
 #include "dnxhddata.h"
 #include "dsputil.h"
+#include "internal.h"
 #include "thread.h"
 
 typedef struct DNXHDContext {
     AVCodecContext *avctx;
     AVFrame picture;
     GetBitContext gb;
-    int cid;                            ///< compression id
+    int64_t cid;                        ///< compression id
     unsigned int width, height;
     unsigned int mb_width, mb_height;
     uint32_t mb_scan_index[68];         /* max for 1080p */
@@ -44,11 +45,11 @@
     VLC ac_vlc, dc_vlc, run_vlc;
     int last_dc[3];
     DSPContext dsp;
-    DECLARE_ALIGNED(16, DCTELEM, blocks)[8][64];
+    DECLARE_ALIGNED(16, int16_t, blocks)[8][64];
     ScanTable scantable;
     const CIDEntry *cid_table;
     int bit_depth; // 8, 10 or 0 if not initialized at all.
-    void (*decode_dct_block)(struct DNXHDContext *ctx, DCTELEM *block,
+    void (*decode_dct_block)(struct DNXHDContext *ctx, int16_t *block,
                              int n, int qscale);
     int last_qscale;
     int luma_scale[64];
@@ -58,8 +59,8 @@
 #define DNXHD_VLC_BITS 9
 #define DNXHD_DC_VLC_BITS 7
 
-static void dnxhd_decode_dct_block_8(DNXHDContext *ctx, DCTELEM *block, int n, int qscale);
-static void dnxhd_decode_dct_block_10(DNXHDContext *ctx, DCTELEM *block, int n, int qscale);
+static void dnxhd_decode_dct_block_8(DNXHDContext *ctx, int16_t *block, int n, int qscale);
+static void dnxhd_decode_dct_block_10(DNXHDContext *ctx, int16_t *block, int n, int qscale);
 
 static av_cold int dnxhd_decode_init(AVCodecContext *avctx)
 {
@@ -70,10 +71,11 @@
     avcodec_get_frame_defaults(&ctx->picture);
     ctx->picture.type = AV_PICTURE_TYPE_I;
     ctx->picture.key_frame = 1;
+    ctx->cid = -1;
     return 0;
 }
 
-static int dnxhd_init_vlc(DNXHDContext *ctx, int cid)
+static int dnxhd_init_vlc(DNXHDContext *ctx, uint32_t cid)
 {
     if (cid != ctx->cid) {
         int index;
@@ -178,7 +180,7 @@
     for (i = 0; i < ctx->mb_height; i++) {
         ctx->mb_scan_index[i] = AV_RB32(buf + 0x170 + (i<<2));
         av_dlog(ctx->avctx, "mb scan index %d\n", ctx->mb_scan_index[i]);
-        if (buf_size < ctx->mb_scan_index[i] + 0x280) {
+        if (buf_size < ctx->mb_scan_index[i] + 0x280LL) {
             av_log(ctx->avctx, AV_LOG_ERROR, "invalid mb scan index\n");
             return -1;
         }
@@ -188,7 +190,7 @@
 }
 
 static av_always_inline void dnxhd_decode_dct_block(DNXHDContext *ctx,
-                                                    DCTELEM *block, int n,
+                                                    int16_t *block, int n,
                                                     int qscale,
                                                     int index_bits,
                                                     int level_bias,
@@ -270,13 +272,13 @@
     CLOSE_READER(bs, &ctx->gb);
 }
 
-static void dnxhd_decode_dct_block_8(DNXHDContext *ctx, DCTELEM *block,
+static void dnxhd_decode_dct_block_8(DNXHDContext *ctx, int16_t *block,
                                      int n, int qscale)
 {
     dnxhd_decode_dct_block(ctx, block, n, qscale, 4, 32, 6);
 }
 
-static void dnxhd_decode_dct_block_10(DNXHDContext *ctx, DCTELEM *block,
+static void dnxhd_decode_dct_block_10(DNXHDContext *ctx, int16_t *block,
                                       int n, int qscale)
 {
     dnxhd_decode_dct_block(ctx, block, n, qscale, 6, 8, 4);
@@ -357,7 +359,7 @@
     return 0;
 }
 
-static int dnxhd_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+static int dnxhd_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                               AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
@@ -403,7 +405,7 @@
     }
 
     *picture = ctx->picture;
-    *data_size = sizeof(AVPicture);
+    *got_frame = 1;
     return buf_size;
 }
 
diff --git a/libavcodec/dnxhdenc.c b/libavcodec/dnxhdenc.c
index 690e64f..4b6ce2f 100644
--- a/libavcodec/dnxhdenc.c
+++ b/libavcodec/dnxhdenc.c
@@ -26,6 +26,7 @@
 //#define DEBUG
 #define RC_VARIANCE 1 // use variance or ssd for fast rc
 
+#include "libavutil/internal.h"
 #include "libavutil/opt.h"
 #include "avcodec.h"
 #include "dsputil.h"
@@ -51,7 +52,7 @@
 
 #define LAMBDA_FRAC_BITS 10
 
-static void dnxhd_8bit_get_pixels_8x4_sym(DCTELEM *av_restrict block, const uint8_t *pixels, int line_size)
+static void dnxhd_8bit_get_pixels_8x4_sym(int16_t *av_restrict block, const uint8_t *pixels, int line_size)
 {
     int i;
     for (i = 0; i < 4; i++) {
@@ -68,7 +69,7 @@
     memcpy(block + 24, block - 32, sizeof(*block) * 8);
 }
 
-static av_always_inline void dnxhd_10bit_get_pixels_8x4_sym(DCTELEM *av_restrict block, const uint8_t *pixels, int line_size)
+static av_always_inline void dnxhd_10bit_get_pixels_8x4_sym(int16_t *av_restrict block, const uint8_t *pixels, int line_size)
 {
     int i;
     const uint16_t* pixels16 = (const uint16_t*)pixels;
@@ -88,7 +89,7 @@
     memcpy(block + 24, block - 32, sizeof(*block) * 8);
 }
 
-static int dnxhd_10bit_dct_quantize(MpegEncContext *ctx, DCTELEM *block,
+static int dnxhd_10bit_dct_quantize(MpegEncContext *ctx, int16_t *block,
                                     int n, int qscale, int *overflow)
 {
     const uint8_t *scantable= ctx->intra_scantable.scantable;
@@ -266,7 +267,8 @@
 
     ctx->cid = ff_dnxhd_find_cid(avctx, bit_depth);
     if (!ctx->cid) {
-        av_log(avctx, AV_LOG_ERROR, "video parameters incompatible with DNxHD\n");
+        av_log(avctx, AV_LOG_ERROR, "video parameters incompatible with DNxHD. Valid DNxHD profiles:\n");
+        ff_dnxhd_print_profiles(avctx, AV_LOG_ERROR);
         return -1;
     }
     av_log(avctx, AV_LOG_DEBUG, "cid %d\n", ctx->cid);
@@ -392,7 +394,7 @@
              (ctx->cid_table->dc_codes[nbits]<<nbits) + (diff & ((1 << nbits) - 1)));
 }
 
-static av_always_inline void dnxhd_encode_block(DNXHDEncContext *ctx, DCTELEM *block, int last_index, int n)
+static av_always_inline void dnxhd_encode_block(DNXHDEncContext *ctx, int16_t *block, int last_index, int n)
 {
     int last_non_zero = 0;
     int slevel, i, j;
@@ -415,7 +417,7 @@
     put_bits(&ctx->m.pb, ctx->vlc_bits[0], ctx->vlc_codes[0]); // EOB
 }
 
-static av_always_inline void dnxhd_unquantize_c(DNXHDEncContext *ctx, DCTELEM *block, int n, int qscale, int last_index)
+static av_always_inline void dnxhd_unquantize_c(DNXHDEncContext *ctx, int16_t *block, int n, int qscale, int last_index)
 {
     const uint8_t *weight_matrix;
     int level;
@@ -456,7 +458,7 @@
     }
 }
 
-static av_always_inline int dnxhd_ssd_block(DCTELEM *qblock, DCTELEM *block)
+static av_always_inline int dnxhd_ssd_block(int16_t *qblock, int16_t *block)
 {
     int score = 0;
     int i;
@@ -465,7 +467,7 @@
     return score;
 }
 
-static av_always_inline int dnxhd_calc_ac_bits(DNXHDEncContext *ctx, DCTELEM *block, int last_index)
+static av_always_inline int dnxhd_calc_ac_bits(DNXHDEncContext *ctx, int16_t *block, int last_index)
 {
     int last_non_zero = 0;
     int bits = 0;
@@ -527,7 +529,7 @@
     DNXHDEncContext *ctx = avctx->priv_data;
     int mb_y = jobnr, mb_x;
     int qscale = ctx->qscale;
-    LOCAL_ALIGNED_16(DCTELEM, block, [64]);
+    LOCAL_ALIGNED_16(int16_t, block, [64]);
     ctx = ctx->thread[threadnr];
 
     ctx->m.last_dc[0] =
@@ -544,7 +546,7 @@
         dnxhd_get_blocks(ctx, mb_x, mb_y);
 
         for (i = 0; i < 8; i++) {
-            DCTELEM *src_block = ctx->blocks[i];
+            int16_t *src_block = ctx->blocks[i];
             int overflow, nbits, diff, last_index;
             int n = dnxhd_switch_matrix(ctx, i);
 
@@ -593,7 +595,7 @@
         dnxhd_get_blocks(ctx, mb_x, mb_y);
 
         for (i = 0; i < 8; i++) {
-            DCTELEM *block = ctx->blocks[i];
+            int16_t *block = ctx->blocks[i];
             int overflow, n = dnxhd_switch_matrix(ctx, i);
             int last_index = ctx->m.dct_quantize(&ctx->m, block, 4&(2*i), qscale, &overflow);
             //START_TIMER;
@@ -629,14 +631,35 @@
 static int dnxhd_mb_var_thread(AVCodecContext *avctx, void *arg, int jobnr, int threadnr)
 {
     DNXHDEncContext *ctx = avctx->priv_data;
-    int mb_y = jobnr, mb_x;
+    int mb_y = jobnr, mb_x, x, y;
+    int partial_last_row = (mb_y == ctx->m.mb_height - 1) &&
+                           ((avctx->height >> ctx->interlaced) & 0xF);
+
     ctx = ctx->thread[threadnr];
     if (ctx->cid_table->bit_depth == 8) {
         uint8_t *pix = ctx->thread[0]->src[0] + ((mb_y<<4) * ctx->m.linesize);
         for (mb_x = 0; mb_x < ctx->m.mb_width; ++mb_x, pix += 16) {
             unsigned mb  = mb_y * ctx->m.mb_width + mb_x;
-            int sum = ctx->m.dsp.pix_sum(pix, ctx->m.linesize);
-            int varc = (ctx->m.dsp.pix_norm1(pix, ctx->m.linesize) - (((unsigned)sum*sum)>>8)+128)>>8;
+            int sum;
+            int varc;
+
+            if (!partial_last_row && mb_x * 16 <= avctx->width - 16) {
+                sum  = ctx->m.dsp.pix_sum(pix, ctx->m.linesize);
+                varc = ctx->m.dsp.pix_norm1(pix, ctx->m.linesize);
+            } else {
+                int bw = FFMIN(avctx->width - 16 * mb_x, 16);
+                int bh = FFMIN((avctx->height >> ctx->interlaced) - 16 * mb_y, 16);
+                sum = varc = 0;
+                for (y = 0; y < bh; y++) {
+                    for (x = 0; x < bw; x++) {
+                        uint8_t val = pix[x + y * ctx->m.linesize];
+                        sum  += val;
+                        varc += val * val;
+                    }
+                }
+            }
+            varc = (varc - (((unsigned)sum * sum) >> 8) + 128) >> 8;
+
             ctx->mb_cmp[mb].value = varc;
             ctx->mb_cmp[mb].mb = mb;
         }
diff --git a/libavcodec/dnxhdenc.h b/libavcodec/dnxhdenc.h
index 36a42fb..9b59b96 100644
--- a/libavcodec/dnxhdenc.h
+++ b/libavcodec/dnxhdenc.h
@@ -64,7 +64,7 @@
     int nitris_compat;
     unsigned min_padding;
 
-    DECLARE_ALIGNED(16, DCTELEM, blocks)[8][64];
+    DECLARE_ALIGNED(16, int16_t, blocks)[8][64];
 
     int      (*qmatrix_c)     [64];
     int      (*qmatrix_l)     [64];
@@ -90,7 +90,7 @@
     RCCMPEntry *mb_cmp;
     RCEntry   (*mb_rc)[8160];
 
-    void (*get_pixels_8x4_sym)(DCTELEM * /*align 16*/, const uint8_t *, int);
+    void (*get_pixels_8x4_sym)(int16_t * /*align 16*/, const uint8_t *, int);
 } DNXHDEncContext;
 
 void ff_dnxhdenc_init_x86(DNXHDEncContext *ctx);
diff --git a/libavcodec/dpcm.c b/libavcodec/dpcm.c
index c9c45c6..1ec8370 100644
--- a/libavcodec/dpcm.c
+++ b/libavcodec/dpcm.c
@@ -40,10 +40,10 @@
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 #include "mathops.h"
 
 typedef struct DPCMContext {
-    AVFrame frame;
     int16_t roq_square_array[256];
     int sample[2];                  ///< previous sample (for SOL_DPCM)
     const int8_t *sol_table;        ///< delta table for SOL_DPCM
@@ -162,9 +162,6 @@
     else
         avctx->sample_fmt = AV_SAMPLE_FMT_S16;
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     return 0;
 }
 
@@ -174,6 +171,7 @@
 {
     int buf_size = avpkt->size;
     DPCMContext *s = avctx->priv_data;
+    AVFrame *frame = data;
     int out = 0, ret;
     int predictor[2];
     int ch = 0;
@@ -212,12 +210,12 @@
     }
 
     /* get output buffer */
-    s->frame.nb_samples = (out + avctx->channels - 1) / avctx->channels;
-    if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = (out + avctx->channels - 1) / avctx->channels;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    output_samples = (int16_t *)s->frame.data[0];
+    output_samples = (int16_t *)frame->data[0];
     samples_end = output_samples + out;
 
     switch(avctx->codec->id) {
@@ -297,7 +295,7 @@
     }
     case AV_CODEC_ID_SOL_DPCM:
         if (avctx->codec_tag != 3) {
-            uint8_t *output_samples_u8 = s->frame.data[0],
+            uint8_t *output_samples_u8 = frame->data[0],
                     *samples_end_u8 = output_samples_u8 + out;
             while (output_samples_u8 < samples_end_u8) {
                 int n = bytestream2_get_byteu(&gb);
@@ -324,8 +322,7 @@
         break;
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
+    *got_frame_ptr = 1;
 
     return avpkt->size;
 }
diff --git a/libavcodec/dpx.c b/libavcodec/dpx.c
index 4d09efe..310036b 100644
--- a/libavcodec/dpx.c
+++ b/libavcodec/dpx.c
@@ -23,6 +23,7 @@
 #include "libavutil/imgutils.h"
 #include "bytestream.h"
 #include "avcodec.h"
+#include "internal.h"
 
 typedef struct DPXContext {
     AVFrame picture;
@@ -58,7 +59,7 @@
 
 static int decode_frame(AVCodecContext *avctx,
                         void *data,
-                        int *data_size,
+                        int *got_frame,
                         AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
@@ -70,7 +71,7 @@
 
     unsigned int offset;
     int magic_num, endian;
-    int x, y, i;
+    int x, y, i, ret;
     int w, h, bits_per_color, descriptor, elements, packing, total_size;
 
     unsigned int rgbBuffer = 0;
@@ -92,7 +93,7 @@
         endian = 1;
     } else {
         av_log(avctx, AV_LOG_ERROR, "DPX marker not found\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     offset = read32(&buf, endian);
@@ -104,8 +105,8 @@
     buf = avpkt->data + 0x304;
     w = read32(&buf, endian);
     h = read32(&buf, endian);
-    if (av_image_check_size(w, h, 0, avctx))
-        return AVERROR(EINVAL);
+    if ((ret = av_image_check_size(w, h, 0, avctx)) < 0)
+        return ret;
 
     if (w != avctx->width || h != avctx->height)
         avcodec_set_dimensions(avctx, w, h);
@@ -140,7 +141,7 @@
             break;
         default:
             av_log(avctx, AV_LOG_ERROR, "Unsupported descriptor %d\n", descriptor);
-            return -1;
+            return AVERROR_INVALIDDATA;
     }
 
     switch (bits_per_color) {
@@ -158,7 +159,7 @@
                 return -1;
             }
             avctx->pix_fmt = AV_PIX_FMT_GBRP10;
-            total_size = (4 * avctx->width * avctx->height * elements) / 3;
+            total_size = (avctx->width * avctx->height * elements + 2) / 3 * 4;
             break;
         case 12:
             if (!packing) {
@@ -182,14 +183,14 @@
             break;
         default:
             av_log(avctx, AV_LOG_ERROR, "Unsupported color depth : %d\n", bits_per_color);
-            return -1;
+            return AVERROR_INVALIDDATA;
     }
 
     if (s->picture.data[0])
         avctx->release_buffer(avctx, &s->picture);
-    if (avctx->get_buffer(avctx, p) < 0) {
+    if ((ret = ff_get_buffer(avctx, p)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     // Move pointer to offset from start of file
@@ -198,9 +199,9 @@
     for (i=0; i<AV_NUM_DATA_POINTERS; i++)
         ptr[i] = p->data[i];
 
-    if (total_size > avpkt->size) {
+    if (total_size + (int64_t)offset > avpkt->size) {
         av_log(avctx, AV_LOG_ERROR, "Overread buffer. Invalid header?\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     switch (bits_per_color) {
     case 10:
@@ -262,7 +263,7 @@
     }
 
     *picture   = s->picture;
-    *data_size = sizeof(AVPicture);
+    *got_frame = 1;
 
     return buf_size;
 }
diff --git a/libavcodec/dsicinav.c b/libavcodec/dsicinav.c
index 0290f5a..85eafcf 100644
--- a/libavcodec/dsicinav.c
+++ b/libavcodec/dsicinav.c
@@ -27,6 +27,7 @@
 #include "libavutil/channel_layout.h"
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 #include "mathops.h"
 
 
@@ -45,7 +46,6 @@
 } CinVideoContext;
 
 typedef struct CinAudioContext {
-    AVFrame frame;
     int initial_decode_frame;
     int delta;
 } CinAudioContext;
@@ -224,7 +224,7 @@
 }
 
 static int cinvideo_decode_frame(AVCodecContext *avctx,
-                                 void *data, int *data_size,
+                                 void *data, int *got_frame,
                                  AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
@@ -320,7 +320,7 @@
 
     FFSWAP(uint8_t *, cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_table[CIN_PRE_BMP]);
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame *)data = cin->frame;
 
     return buf_size;
@@ -348,15 +348,13 @@
     avctx->channels           = 1;
     avctx->channel_layout     = AV_CH_LAYOUT_MONO;
 
-    avcodec_get_frame_defaults(&cin->frame);
-    avctx->coded_frame = &cin->frame;
-
     return 0;
 }
 
 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;
     const uint8_t *buf_end = buf + avpkt->size;
@@ -364,12 +362,12 @@
     int delta, ret;
 
     /* get output buffer */
-    cin->frame.nb_samples = avpkt->size - cin->initial_decode_frame;
-    if ((ret = avctx->get_buffer(avctx, &cin->frame)) < 0) {
+    frame->nb_samples = avpkt->size - cin->initial_decode_frame;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    samples = (int16_t *)cin->frame.data[0];
+    samples = (int16_t *)frame->data[0];
 
     delta = cin->delta;
     if (cin->initial_decode_frame) {
@@ -385,8 +383,7 @@
     }
     cin->delta = delta;
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = cin->frame;
+    *got_frame_ptr = 1;
 
     return avpkt->size;
 }
diff --git a/libavcodec/dsputil.c b/libavcodec/dsputil.c
index 7997885..2bcc3ee 100644
--- a/libavcodec/dsputil.c
+++ b/libavcodec/dsputil.c
@@ -28,21 +28,23 @@
  */
 
 #include "libavutil/imgutils.h"
+#include "libavutil/internal.h"
 #include "avcodec.h"
+#include "copy_block.h"
+#include "dct.h"
 #include "dsputil.h"
 #include "simple_idct.h"
 #include "faandct.h"
 #include "faanidct.h"
+#include "imgconvert.h"
 #include "mathops.h"
 #include "mpegvideo.h"
 #include "config.h"
-#include "vorbis.h"
 #include "diracdsp.h"
 
 uint8_t ff_cropTbl[256 + 2 * MAX_NEG_CROP] = {0, };
 uint32_t ff_squareTbl[512] = {0, };
 
-#define pixeltmp int16_t
 #define BIT_DEPTH 9
 #include "dsputil_template.c"
 #undef BIT_DEPTH
@@ -51,8 +53,6 @@
 #include "dsputil_template.c"
 #undef BIT_DEPTH
 
-#undef pixeltmp
-#define pixeltmp int32_t
 #define BIT_DEPTH 12
 #include "dsputil_template.c"
 #undef BIT_DEPTH
@@ -61,11 +61,8 @@
 #include "dsputil_template.c"
 #undef BIT_DEPTH
 
-#undef pixeltmp
-#define pixeltmp int16_t
 #define BIT_DEPTH 8
 #include "dsputil_template.c"
-#undef pixeltmp
 
 // 0x7f7f7f7f or 0x7f7f7f7f7f7f7f7f or whatever, depending on the cpu's native arithmetic size
 #define pb_7f (~0UL/255 * 0x7f)
@@ -352,7 +349,7 @@
     return s;
 }
 
-static void diff_pixels_c(DCTELEM *av_restrict block, const uint8_t *s1,
+static void diff_pixels_c(int16_t *av_restrict block, const uint8_t *s1,
                           const uint8_t *s2, int stride){
     int i;
 
@@ -372,8 +369,7 @@
     }
 }
 
-
-static void put_pixels_clamped_c(const DCTELEM *block, uint8_t *av_restrict pixels,
+static void put_pixels_clamped_c(const int16_t *block, uint8_t *av_restrict pixels,
                                  int line_size)
 {
     int i;
@@ -394,7 +390,7 @@
     }
 }
 
-static void put_pixels_clamped4_c(const DCTELEM *block, uint8_t *av_restrict pixels,
+static void put_pixels_clamped4_c(const int16_t *block, uint8_t *av_restrict pixels,
                                  int line_size)
 {
     int i;
@@ -411,7 +407,7 @@
     }
 }
 
-static void put_pixels_clamped2_c(const DCTELEM *block, uint8_t *av_restrict pixels,
+static void put_pixels_clamped2_c(const int16_t *block, uint8_t *av_restrict pixels,
                                  int line_size)
 {
     int i;
@@ -426,7 +422,7 @@
     }
 }
 
-static void put_signed_pixels_clamped_c(const DCTELEM *block,
+static void put_signed_pixels_clamped_c(const int16_t *block,
                                         uint8_t *av_restrict pixels,
                                         int line_size)
 {
@@ -447,7 +443,27 @@
     }
 }
 
-static void add_pixels_clamped_c(const DCTELEM *block, uint8_t *av_restrict pixels,
+static void add_pixels8_c(uint8_t *av_restrict pixels,
+                          int16_t *block,
+                          int line_size)
+{
+    int i;
+
+    for(i=0;i<8;i++) {
+        pixels[0] += block[0];
+        pixels[1] += block[1];
+        pixels[2] += block[2];
+        pixels[3] += block[3];
+        pixels[4] += block[4];
+        pixels[5] += block[5];
+        pixels[6] += block[6];
+        pixels[7] += block[7];
+        pixels += line_size;
+        block += 8;
+    }
+}
+
+static void add_pixels_clamped_c(const int16_t *block, uint8_t *av_restrict pixels,
                                  int line_size)
 {
     int i;
@@ -467,7 +483,7 @@
     }
 }
 
-static void add_pixels_clamped4_c(const DCTELEM *block, uint8_t *av_restrict pixels,
+static void add_pixels_clamped4_c(const int16_t *block, uint8_t *av_restrict pixels,
                           int line_size)
 {
     int i;
@@ -483,7 +499,7 @@
     }
 }
 
-static void add_pixels_clamped2_c(const DCTELEM *block, uint8_t *av_restrict pixels,
+static void add_pixels_clamped2_c(const int16_t *block, uint8_t *av_restrict pixels,
                           int line_size)
 {
     int i;
@@ -497,7 +513,7 @@
     }
 }
 
-static int sum_abs_dctelem_c(DCTELEM *block)
+static int sum_abs_dctelem_c(int16_t *block)
 {
     int sum=0, i;
     for(i=0; i<64; i++)
@@ -1827,35 +1843,6 @@
     }
 }
 
-/**
- * Permute an 8x8 block.
- * @param block the block which will be permuted according to the given permutation vector
- * @param permutation the permutation vector
- * @param last the last non zero coefficient in scantable order, used to speed the permutation up
- * @param scantable the used scantable, this is only used to speed the permutation up, the block is not
- *                  (inverse) permutated to scantable order!
- */
-void ff_block_permute(DCTELEM *block, uint8_t *permutation, const uint8_t *scantable, int last)
-{
-    int i;
-    DCTELEM temp[64];
-
-    if(last<=0) return;
-    //if(permutation[1]==1) return; //FIXME it is ok but not clean and might fail for some permutations
-
-    for(i=0; i<=last; i++){
-        const int j= scantable[i];
-        temp[j]= block[j];
-        block[j]=0;
-    }
-
-    for(i=0; i<=last; i++){
-        const int j= scantable[i];
-        const int perm_j= permutation[j];
-        block[perm_j]= temp[j];
-    }
-}
-
 static int zero_cmp(void *s, uint8_t *a, uint8_t *b, int stride, int h){
     return 0;
 }
@@ -2161,7 +2148,7 @@
 
 static int dct_sad8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){
     MpegEncContext * const s= (MpegEncContext *)c;
-    LOCAL_ALIGNED_16(DCTELEM, temp, [64]);
+    LOCAL_ALIGNED_16(int16_t, temp, [64]);
 
     av_assert2(h==8);
 
@@ -2200,7 +2187,7 @@
 
 static int dct264_sad8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){
     MpegEncContext * const s= (MpegEncContext *)c;
-    DCTELEM dct[8][8];
+    int16_t dct[8][8];
     int i;
     int sum=0;
 
@@ -2225,7 +2212,7 @@
 
 static int dct_max8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){
     MpegEncContext * const s= (MpegEncContext *)c;
-    LOCAL_ALIGNED_16(DCTELEM, temp, [64]);
+    LOCAL_ALIGNED_16(int16_t, temp, [64]);
     int sum=0, i;
 
     av_assert2(h==8);
@@ -2241,8 +2228,8 @@
 
 static int quant_psnr8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){
     MpegEncContext * const s= (MpegEncContext *)c;
-    LOCAL_ALIGNED_16(DCTELEM, temp, [64*2]);
-    DCTELEM * const bak = temp+64;
+    LOCAL_ALIGNED_16(int16_t, temp, [64*2]);
+    int16_t * const bak = temp+64;
     int sum=0, i;
 
     av_assert2(h==8);
@@ -2250,7 +2237,7 @@
 
     s->dsp.diff_pixels(temp, src1, src2, stride);
 
-    memcpy(bak, temp, 64*sizeof(DCTELEM));
+    memcpy(bak, temp, 64*sizeof(int16_t));
 
     s->block_last_index[0/*FIXME*/]= s->fast_dct_quantize(s, temp, 0/*FIXME*/, s->qscale, &i);
     s->dct_unquantize_inter(s, temp, 0, s->qscale);
@@ -2265,7 +2252,7 @@
 static int rd8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){
     MpegEncContext * const s= (MpegEncContext *)c;
     const uint8_t *scantable= s->intra_scantable.permutated;
-    LOCAL_ALIGNED_16(DCTELEM, temp, [64]);
+    LOCAL_ALIGNED_16(int16_t, temp, [64]);
     LOCAL_ALIGNED_16(uint8_t, lsrc1, [64]);
     LOCAL_ALIGNED_16(uint8_t, lsrc2, [64]);
     int i, last, run, bits, level, distortion, start_i;
@@ -2341,7 +2328,7 @@
 static int bit8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){
     MpegEncContext * const s= (MpegEncContext *)c;
     const uint8_t *scantable= s->intra_scantable.permutated;
-    LOCAL_ALIGNED_16(DCTELEM, temp, [64]);
+    LOCAL_ALIGNED_16(int16_t, temp, [64]);
     int i, last, run, bits, level, start_i;
     const int esc_length= s->ac_esc_length;
     uint8_t * length;
@@ -2473,6 +2460,20 @@
     return score;
 }
 
+#define WRAPPER8_16_SQ(name8, name16)\
+static int name16(void /*MpegEncContext*/ *s, uint8_t *dst, uint8_t *src, int stride, int h){\
+    int score=0;\
+    score +=name8(s, dst           , src           , stride, 8);\
+    score +=name8(s, dst+8         , src+8         , stride, 8);\
+    if(h==16){\
+        dst += 8*stride;\
+        src += 8*stride;\
+        score +=name8(s, dst           , src           , stride, 8);\
+        score +=name8(s, dst+8         , src+8         , stride, 8);\
+    }\
+    return score;\
+}
+
 WRAPPER8_16_SQ(hadamard8_diff8x8_c, hadamard8_diff16_c)
 WRAPPER8_16_SQ(hadamard8_intra8x8_c, hadamard8_intra16_c)
 WRAPPER8_16_SQ(dct_sad8x8_c, dct_sad16_c)
@@ -2484,70 +2485,6 @@
 WRAPPER8_16_SQ(rd8x8_c, rd16_c)
 WRAPPER8_16_SQ(bit8x8_c, bit16_c)
 
-static void vector_fmul_reverse_c(float *dst, const float *src0, const float *src1, int len){
-    int i;
-    src1 += len-1;
-    for(i=0; i<len; i++)
-        dst[i] = src0[i] * src1[-i];
-}
-
-static void vector_fmul_add_c(float *dst, const float *src0, const float *src1, const float *src2, int len){
-    int i;
-    for(i=0; i<len; i++)
-        dst[i] = src0[i] * src1[i] + src2[i];
-}
-
-static void vector_fmul_window_c(float *dst, const float *src0,
-                                 const float *src1, const float *win, int len)
-{
-    int i,j;
-    dst += len;
-    win += len;
-    src0+= len;
-    for(i=-len, j=len-1; i<0; i++, j--) {
-        float s0 = src0[i];
-        float s1 = src1[j];
-        float wi = win[i];
-        float wj = win[j];
-        dst[i] = s0*wj - s1*wi;
-        dst[j] = s0*wi + s1*wj;
-    }
-}
-
-static void butterflies_float_c(float *av_restrict v1, float *av_restrict v2,
-                                int len)
-{
-    int i;
-    for (i = 0; i < len; i++) {
-        float t = v1[i] - v2[i];
-        v1[i] += v2[i];
-        v2[i] = t;
-    }
-}
-
-static void butterflies_float_interleave_c(float *dst, const float *src0,
-                                           const float *src1, int len)
-{
-    int i;
-    for (i = 0; i < len; i++) {
-        float f1 = src0[i];
-        float f2 = src1[i];
-        dst[2*i    ] = f1 + f2;
-        dst[2*i + 1] = f1 - f2;
-    }
-}
-
-float ff_scalarproduct_float_c(const float *v1, const float *v2, int len)
-{
-    float p = 0.0;
-    int i;
-
-    for (i = 0; i < len; i++)
-        p += v1[i] * v2[i];
-
-    return p;
-}
-
 static inline uint32_t clipf_c_one(uint32_t a, uint32_t mini,
                    uint32_t maxi, uint32_t maxisign)
 {
@@ -2642,134 +2579,48 @@
     } while (len > 0);
 }
 
-#define W0 2048
-#define W1 2841 /* 2048*sqrt (2)*cos (1*pi/16) */
-#define W2 2676 /* 2048*sqrt (2)*cos (2*pi/16) */
-#define W3 2408 /* 2048*sqrt (2)*cos (3*pi/16) */
-#define W4 2048 /* 2048*sqrt (2)*cos (4*pi/16) */
-#define W5 1609 /* 2048*sqrt (2)*cos (5*pi/16) */
-#define W6 1108 /* 2048*sqrt (2)*cos (6*pi/16) */
-#define W7 565  /* 2048*sqrt (2)*cos (7*pi/16) */
-
-static void wmv2_idct_row(short * b)
-{
-    int s1,s2;
-    int a0,a1,a2,a3,a4,a5,a6,a7;
-    /*step 1*/
-    a1 = W1*b[1]+W7*b[7];
-    a7 = W7*b[1]-W1*b[7];
-    a5 = W5*b[5]+W3*b[3];
-    a3 = W3*b[5]-W5*b[3];
-    a2 = W2*b[2]+W6*b[6];
-    a6 = W6*b[2]-W2*b[6];
-    a0 = W0*b[0]+W0*b[4];
-    a4 = W0*b[0]-W0*b[4];
-    /*step 2*/
-    s1 = (181*(a1-a5+a7-a3)+128)>>8;//1,3,5,7,
-    s2 = (181*(a1-a5-a7+a3)+128)>>8;
-    /*step 3*/
-    b[0] = (a0+a2+a1+a5 + (1<<7))>>8;
-    b[1] = (a4+a6 +s1   + (1<<7))>>8;
-    b[2] = (a4-a6 +s2   + (1<<7))>>8;
-    b[3] = (a0-a2+a7+a3 + (1<<7))>>8;
-    b[4] = (a0-a2-a7-a3 + (1<<7))>>8;
-    b[5] = (a4-a6 -s2   + (1<<7))>>8;
-    b[6] = (a4+a6 -s1   + (1<<7))>>8;
-    b[7] = (a0+a2-a1-a5 + (1<<7))>>8;
-}
-static void wmv2_idct_col(short * b)
-{
-    int s1,s2;
-    int a0,a1,a2,a3,a4,a5,a6,a7;
-    /*step 1, with extended precision*/
-    a1 = (W1*b[8*1]+W7*b[8*7] + 4)>>3;
-    a7 = (W7*b[8*1]-W1*b[8*7] + 4)>>3;
-    a5 = (W5*b[8*5]+W3*b[8*3] + 4)>>3;
-    a3 = (W3*b[8*5]-W5*b[8*3] + 4)>>3;
-    a2 = (W2*b[8*2]+W6*b[8*6] + 4)>>3;
-    a6 = (W6*b[8*2]-W2*b[8*6] + 4)>>3;
-    a0 = (W0*b[8*0]+W0*b[8*4]    )>>3;
-    a4 = (W0*b[8*0]-W0*b[8*4]    )>>3;
-    /*step 2*/
-    s1 = (181*(a1-a5+a7-a3)+128)>>8;
-    s2 = (181*(a1-a5-a7+a3)+128)>>8;
-    /*step 3*/
-    b[8*0] = (a0+a2+a1+a5 + (1<<13))>>14;
-    b[8*1] = (a4+a6 +s1   + (1<<13))>>14;
-    b[8*2] = (a4-a6 +s2   + (1<<13))>>14;
-    b[8*3] = (a0-a2+a7+a3 + (1<<13))>>14;
-
-    b[8*4] = (a0-a2-a7-a3 + (1<<13))>>14;
-    b[8*5] = (a4-a6 -s2   + (1<<13))>>14;
-    b[8*6] = (a4+a6 -s1   + (1<<13))>>14;
-    b[8*7] = (a0+a2-a1-a5 + (1<<13))>>14;
-}
-void ff_wmv2_idct_c(short * block){
-    int i;
-
-    for(i=0;i<64;i+=8){
-        wmv2_idct_row(block+i);
-    }
-    for(i=0;i<8;i++){
-        wmv2_idct_col(block+i);
-    }
-}
-/* XXX: those functions should be suppressed ASAP when all IDCTs are
- converted */
-static void ff_wmv2_idct_put_c(uint8_t *dest, int line_size, DCTELEM *block)
-{
-    ff_wmv2_idct_c(block);
-    put_pixels_clamped_c(block, dest, line_size);
-}
-static void ff_wmv2_idct_add_c(uint8_t *dest, int line_size, DCTELEM *block)
-{
-    ff_wmv2_idct_c(block);
-    add_pixels_clamped_c(block, dest, line_size);
-}
-static void ff_jref_idct_put(uint8_t *dest, int line_size, DCTELEM *block)
+static void ff_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, DCTELEM *block)
+static void ff_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);
 }
 
-static void ff_jref_idct4_put(uint8_t *dest, int line_size, DCTELEM *block)
+static void ff_jref_idct4_put(uint8_t *dest, int line_size, int16_t *block)
 {
     ff_j_rev_dct4 (block);
     put_pixels_clamped4_c(block, dest, line_size);
 }
-static void ff_jref_idct4_add(uint8_t *dest, int line_size, DCTELEM *block)
+static void ff_jref_idct4_add(uint8_t *dest, int line_size, int16_t *block)
 {
     ff_j_rev_dct4 (block);
     add_pixels_clamped4_c(block, dest, line_size);
 }
 
-static void ff_jref_idct2_put(uint8_t *dest, int line_size, DCTELEM *block)
+static void ff_jref_idct2_put(uint8_t *dest, int line_size, int16_t *block)
 {
     ff_j_rev_dct2 (block);
     put_pixels_clamped2_c(block, dest, line_size);
 }
-static void ff_jref_idct2_add(uint8_t *dest, int line_size, DCTELEM *block)
+static void ff_jref_idct2_add(uint8_t *dest, int line_size, int16_t *block)
 {
     ff_j_rev_dct2 (block);
     add_pixels_clamped2_c(block, dest, line_size);
 }
 
-static void ff_jref_idct1_put(uint8_t *dest, int line_size, DCTELEM *block)
+static void ff_jref_idct1_put(uint8_t *dest, int line_size, int16_t *block)
 {
     dest[0] = av_clip_uint8((block[0] + 4)>>3);
 }
-static void ff_jref_idct1_add(uint8_t *dest, int line_size, DCTELEM *block)
+static void ff_jref_idct1_add(uint8_t *dest, int line_size, int16_t *block)
 {
     dest[0] = av_clip_uint8(dest[0] + ((block[0] + 4)>>3));
 }
 
-static void just_return(void *mem av_unused, int stride av_unused, int h av_unused) { return; }
-
 /* init static data */
 av_cold void ff_dsputil_static_init(void)
 {
@@ -2810,8 +2661,6 @@
 
 av_cold void ff_dsputil_init(DSPContext* c, AVCodecContext *avctx)
 {
-    int i, j;
-
     ff_check_alignment();
 
 #if CONFIG_ENCODERS
@@ -2861,11 +2710,6 @@
             c->idct_add= ff_jref_idct_add;
             c->idct    = ff_j_rev_dct;
             c->idct_permutation_type= FF_LIBMPEG2_IDCT_PERM;
-        }else if(avctx->idct_algo==FF_IDCT_WMV2){
-            c->idct_put= ff_wmv2_idct_put_c;
-            c->idct_add= ff_wmv2_idct_add_c;
-            c->idct    = ff_wmv2_idct_c;
-            c->idct_permutation_type= FF_NO_IDCT_PERM;
         }else if(avctx->idct_algo==FF_IDCT_FAAN){
             c->idct_put= ff_faanidct_put;
             c->idct_add= ff_faanidct_add;
@@ -2992,7 +2836,7 @@
     c->vsse[5]= vsse_intra8_c;
     c->nsse[0]= nsse16_c;
     c->nsse[1]= nsse8_c;
-#if CONFIG_DWT
+#if CONFIG_SNOW_DECODER || CONFIG_SNOW_ENCODER
     ff_dsputil_init_dwt(c);
 #endif
 
@@ -3017,99 +2861,47 @@
     c->try_8x8basis= try_8x8basis_c;
     c->add_8x8basis= add_8x8basis_c;
 
-#if CONFIG_VORBIS_DECODER
-    c->vorbis_inverse_coupling = ff_vorbis_inverse_coupling;
-#endif
-    c->vector_fmul_reverse = vector_fmul_reverse_c;
-    c->vector_fmul_add = vector_fmul_add_c;
-    c->vector_fmul_window = vector_fmul_window_c;
     c->vector_clipf = vector_clipf_c;
     c->scalarproduct_int16 = scalarproduct_int16_c;
     c->scalarproduct_and_madd_int16 = scalarproduct_and_madd_int16_c;
     c->apply_window_int16 = apply_window_int16_c;
     c->vector_clip_int32 = vector_clip_int32_c;
-    c->scalarproduct_float = ff_scalarproduct_float_c;
-    c->butterflies_float = butterflies_float_c;
-    c->butterflies_float_interleave = butterflies_float_interleave_c;
 
     c->shrink[0]= av_image_copy_plane;
     c->shrink[1]= ff_shrink22;
     c->shrink[2]= ff_shrink44;
     c->shrink[3]= ff_shrink88;
 
-    c->prefetch= just_return;
+    c->add_pixels8 = add_pixels8_c;
 
-    memset(c->put_2tap_qpel_pixels_tab, 0, sizeof(c->put_2tap_qpel_pixels_tab));
-    memset(c->avg_2tap_qpel_pixels_tab, 0, sizeof(c->avg_2tap_qpel_pixels_tab));
+#define hpel_funcs(prefix, idx, num) \
+    c->prefix ## _pixels_tab idx [0] = prefix ## _pixels ## num ## _8_c; \
+    c->prefix ## _pixels_tab idx [1] = prefix ## _pixels ## num ## _x2_8_c; \
+    c->prefix ## _pixels_tab idx [2] = prefix ## _pixels ## num ## _y2_8_c; \
+    c->prefix ## _pixels_tab idx [3] = prefix ## _pixels ## num ## _xy2_8_c
+
+    hpel_funcs(put, [0], 16);
+    hpel_funcs(put, [1],  8);
+    hpel_funcs(put, [2],  4);
+    hpel_funcs(put, [3],  2);
+    hpel_funcs(put_no_rnd, [0], 16);
+    hpel_funcs(put_no_rnd, [1],  8);
+    hpel_funcs(avg, [0], 16);
+    hpel_funcs(avg, [1],  8);
+    hpel_funcs(avg, [2],  4);
+    hpel_funcs(avg, [3],  2);
+    hpel_funcs(avg_no_rnd,, 16);
 
 #undef FUNC
 #undef FUNCC
 #define FUNC(f, depth) f ## _ ## depth
 #define FUNCC(f, depth) f ## _ ## depth ## _c
 
-#define dspfunc1(PFX, IDX, NUM, depth)\
-    c->PFX ## _pixels_tab[IDX][0] = FUNCC(PFX ## _pixels ## NUM        , depth);\
-    c->PFX ## _pixels_tab[IDX][1] = FUNCC(PFX ## _pixels ## NUM ## _x2 , depth);\
-    c->PFX ## _pixels_tab[IDX][2] = FUNCC(PFX ## _pixels ## NUM ## _y2 , depth);\
-    c->PFX ## _pixels_tab[IDX][3] = FUNCC(PFX ## _pixels ## NUM ## _xy2, depth)
-
-#define dspfunc2(PFX, IDX, NUM, depth)\
-    c->PFX ## _pixels_tab[IDX][ 0] = FUNCC(PFX ## NUM ## _mc00, depth);\
-    c->PFX ## _pixels_tab[IDX][ 1] = FUNCC(PFX ## NUM ## _mc10, depth);\
-    c->PFX ## _pixels_tab[IDX][ 2] = FUNCC(PFX ## NUM ## _mc20, depth);\
-    c->PFX ## _pixels_tab[IDX][ 3] = FUNCC(PFX ## NUM ## _mc30, depth);\
-    c->PFX ## _pixels_tab[IDX][ 4] = FUNCC(PFX ## NUM ## _mc01, depth);\
-    c->PFX ## _pixels_tab[IDX][ 5] = FUNCC(PFX ## NUM ## _mc11, depth);\
-    c->PFX ## _pixels_tab[IDX][ 6] = FUNCC(PFX ## NUM ## _mc21, depth);\
-    c->PFX ## _pixels_tab[IDX][ 7] = FUNCC(PFX ## NUM ## _mc31, depth);\
-    c->PFX ## _pixels_tab[IDX][ 8] = FUNCC(PFX ## NUM ## _mc02, depth);\
-    c->PFX ## _pixels_tab[IDX][ 9] = FUNCC(PFX ## NUM ## _mc12, depth);\
-    c->PFX ## _pixels_tab[IDX][10] = FUNCC(PFX ## NUM ## _mc22, depth);\
-    c->PFX ## _pixels_tab[IDX][11] = FUNCC(PFX ## NUM ## _mc32, depth);\
-    c->PFX ## _pixels_tab[IDX][12] = FUNCC(PFX ## NUM ## _mc03, depth);\
-    c->PFX ## _pixels_tab[IDX][13] = FUNCC(PFX ## NUM ## _mc13, depth);\
-    c->PFX ## _pixels_tab[IDX][14] = FUNCC(PFX ## NUM ## _mc23, depth);\
-    c->PFX ## _pixels_tab[IDX][15] = FUNCC(PFX ## NUM ## _mc33, depth)
-
-
 #define BIT_DEPTH_FUNCS(depth, dct)\
     c->get_pixels                    = FUNCC(get_pixels   ## dct   , depth);\
     c->draw_edges                    = FUNCC(draw_edges            , depth);\
-    c->emulated_edge_mc              = FUNC (ff_emulated_edge_mc   , depth);\
     c->clear_block                   = FUNCC(clear_block  ## dct   , depth);\
     c->clear_blocks                  = FUNCC(clear_blocks ## dct   , depth);\
-    c->add_pixels8                   = FUNCC(add_pixels8  ## dct   , depth);\
-    c->add_pixels4                   = FUNCC(add_pixels4  ## dct   , depth);\
-    c->put_no_rnd_pixels_l2[0]       = FUNCC(put_no_rnd_pixels16_l2, depth);\
-    c->put_no_rnd_pixels_l2[1]       = FUNCC(put_no_rnd_pixels8_l2 , depth);\
-\
-    c->put_h264_chroma_pixels_tab[0] = FUNCC(put_h264_chroma_mc8   , depth);\
-    c->put_h264_chroma_pixels_tab[1] = FUNCC(put_h264_chroma_mc4   , depth);\
-    c->put_h264_chroma_pixels_tab[2] = FUNCC(put_h264_chroma_mc2   , depth);\
-    c->avg_h264_chroma_pixels_tab[0] = FUNCC(avg_h264_chroma_mc8   , depth);\
-    c->avg_h264_chroma_pixels_tab[1] = FUNCC(avg_h264_chroma_mc4   , depth);\
-    c->avg_h264_chroma_pixels_tab[2] = FUNCC(avg_h264_chroma_mc2   , depth);\
-\
-    dspfunc1(put       , 0, 16, depth);\
-    dspfunc1(put       , 1,  8, depth);\
-    dspfunc1(put       , 2,  4, depth);\
-    dspfunc1(put       , 3,  2, depth);\
-    dspfunc1(put_no_rnd, 0, 16, depth);\
-    dspfunc1(put_no_rnd, 1,  8, depth);\
-    dspfunc1(avg       , 0, 16, depth);\
-    dspfunc1(avg       , 1,  8, depth);\
-    dspfunc1(avg       , 2,  4, depth);\
-    dspfunc1(avg       , 3,  2, depth);\
-    dspfunc1(avg_no_rnd, 0, 16, depth);\
-    dspfunc1(avg_no_rnd, 1,  8, depth);\
-\
-    dspfunc2(put_h264_qpel, 0, 16, depth);\
-    dspfunc2(put_h264_qpel, 1,  8, depth);\
-    dspfunc2(put_h264_qpel, 2,  4, depth);\
-    dspfunc2(put_h264_qpel, 3,  2, depth);\
-    dspfunc2(avg_h264_qpel, 0, 16, depth);\
-    dspfunc2(avg_h264_qpel, 1,  8, depth);\
-    dspfunc2(avg_h264_qpel, 2,  4, depth);
 
     switch (avctx->bits_per_raw_sample) {
     case 9:
@@ -3155,18 +2947,6 @@
     if (ARCH_PPC)        ff_dsputil_init_ppc   (c, avctx);
     if (ARCH_SH4)        ff_dsputil_init_sh4   (c, avctx);
     if (ARCH_BFIN)       ff_dsputil_init_bfin  (c, avctx);
-    if (HAVE_MIPSFPU)    ff_dsputil_init_mips  (c, avctx);
-
-    for (i = 0; i < 4; i++) {
-        for (j = 0; j < 16; j++) {
-            if(!c->put_2tap_qpel_pixels_tab[i][j])
-                c->put_2tap_qpel_pixels_tab[i][j] =
-                    c->put_h264_qpel_pixels_tab[i][j];
-            if(!c->avg_2tap_qpel_pixels_tab[i][j])
-                c->avg_2tap_qpel_pixels_tab[i][j] =
-                    c->avg_h264_qpel_pixels_tab[i][j];
-        }
-    }
 
     ff_init_scantable_permutation(c->idct_permutation,
                                   c->idct_permutation_type);
diff --git a/libavcodec/dsputil.h b/libavcodec/dsputil.h
index 1fef07e..7d12fe3 100644
--- a/libavcodec/dsputil.h
+++ b/libavcodec/dsputil.h
@@ -35,48 +35,6 @@
 
 
 //#define DEBUG
-/* dct code */
-typedef short DCTELEM;
-
-void ff_fdct_ifast (DCTELEM *data);
-void ff_fdct_ifast248 (DCTELEM *data);
-void ff_jpeg_fdct_islow_8(DCTELEM *data);
-void ff_jpeg_fdct_islow_10(DCTELEM *data);
-void ff_fdct248_islow_8(DCTELEM *data);
-void ff_fdct248_islow_10(DCTELEM *data);
-
-void ff_j_rev_dct (DCTELEM *data);
-void ff_j_rev_dct4 (DCTELEM *data);
-void ff_j_rev_dct2 (DCTELEM *data);
-void ff_j_rev_dct1 (DCTELEM *data);
-void ff_wmv2_idct_c(DCTELEM *data);
-
-void ff_fdct_mmx(DCTELEM *block);
-void ff_fdct_mmxext(DCTELEM *block);
-void ff_fdct_sse2(DCTELEM *block);
-
-#define H264_IDCT(depth) \
-void ff_h264_idct8_add_ ## depth ## _c(uint8_t *dst, DCTELEM *block, int stride);\
-void ff_h264_idct_add_ ## depth ## _c(uint8_t *dst, DCTELEM *block, int stride);\
-void ff_h264_idct8_dc_add_ ## depth ## _c(uint8_t *dst, DCTELEM *block, int stride);\
-void ff_h264_idct_dc_add_ ## depth ## _c(uint8_t *dst, DCTELEM *block, int stride);\
-void ff_h264_idct_add16_ ## depth ## _c(uint8_t *dst, const int *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]);\
-void ff_h264_idct_add16intra_ ## depth ## _c(uint8_t *dst, const int *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]);\
-void ff_h264_idct8_add4_ ## depth ## _c(uint8_t *dst, const int *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]);\
-void ff_h264_idct_add8_422_ ## depth ## _c(uint8_t **dest, const int *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]);\
-void ff_h264_idct_add8_ ## depth ## _c(uint8_t **dest, const int *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]);\
-void ff_h264_luma_dc_dequant_idct_ ## depth ## _c(DCTELEM *output, DCTELEM *input, int qmul);\
-void ff_h264_chroma422_dc_dequant_idct_ ## depth ## _c(DCTELEM *block, int qmul);\
-void ff_h264_chroma_dc_dequant_idct_ ## depth ## _c(DCTELEM *block, int qmul);
-
-H264_IDCT( 8)
-H264_IDCT( 9)
-H264_IDCT(10)
-H264_IDCT(12)
-H264_IDCT(14)
-
-void ff_svq3_luma_dc_dequant_idct_c(DCTELEM *output, DCTELEM *input, int qp);
-void ff_svq3_add_idct_c(uint8_t *dst, DCTELEM *block, int stride, int qp, int dc);
 
 /* encoding scans */
 extern const uint8_t ff_alternate_horizontal_scan[64];
@@ -114,11 +72,6 @@
 void ff_put_rv40_qpel8_mc33_c(uint8_t *dst, uint8_t *src, int stride);
 void ff_avg_rv40_qpel8_mc33_c(uint8_t *dst, uint8_t *src, int stride);
 
-/* 1/2^n downscaling functions from imgconvert.c */
-void ff_shrink22(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height);
-void ff_shrink44(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height);
-void ff_shrink88(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height);
-
 void ff_gmc_c(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);
 
@@ -135,21 +88,12 @@
 !future video codecs might need functions with less strict alignment
 */
 
-/*
-void get_pixels_c(DCTELEM *block, const uint8_t *pixels, int line_size);
-void diff_pixels_c(DCTELEM *block, const uint8_t *s1, const uint8_t *s2, int stride);
-void put_pixels_clamped_c(const DCTELEM *block, uint8_t *pixels, int line_size);
-void add_pixels_clamped_c(const DCTELEM *block, uint8_t *pixels, int line_size);
-void clear_blocks_c(DCTELEM *blocks);
-*/
-
 /* add and put pixel (decoding) */
 // blocksizes for op_pixels_func are 8x4,8x8 16x8 16x16
 //h for op_pixels_func is limited to {width/2, width} but never larger than 16 and never smaller than 4
-typedef void (*op_pixels_func)(uint8_t *block/*align width (8 or 16)*/, const uint8_t *pixels/*align 1*/, int line_size, int h);
+typedef void (*op_pixels_func)(uint8_t *block/*align width (8 or 16)*/, const uint8_t *pixels/*align 1*/, ptrdiff_t line_size, int h);
 typedef void (*tpel_mc_func)(uint8_t *block/*align width (8 or 16)*/, const uint8_t *pixels/*align 1*/, int line_size, int w, int h);
 typedef void (*qpel_mc_func)(uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, int stride);
-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 void (*op_fill_func)(uint8_t *block/*align width (8 or 16)*/, uint8_t value, int line_size, int h);
 
@@ -172,7 +116,7 @@
 DEF_OLD_QPEL(qpel8_mc33_old_c)
 
 #define CALL_2X_PIXELS(a, b, n)\
-static void a(uint8_t *block, const uint8_t *pixels, int line_size, int h){\
+static void a(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){\
     b(block  , pixels  , line_size, h);\
     b(block+n, pixels+n, line_size, h);\
 }
@@ -195,17 +139,6 @@
 void ff_init_scantable_permutation(uint8_t *idct_permutation,
                                    int idct_permutation_type);
 
-#define EMULATED_EDGE(depth) \
-void ff_emulated_edge_mc_ ## depth (uint8_t *buf, const uint8_t *src, int linesize,\
-                         int block_w, int block_h,\
-                         int src_x, int src_y, int w, int h);
-
-EMULATED_EDGE(8)
-EMULATED_EDGE(9)
-EMULATED_EDGE(10)
-EMULATED_EDGE(12)
-EMULATED_EDGE(14)
-
 /**
  * DSPContext.
  */
@@ -216,29 +149,13 @@
     int dct_bits;
 
     /* pixel ops : interface with DCT */
-    void (*get_pixels)(DCTELEM *block/*align 16*/, const uint8_t *pixels/*align 8*/, int line_size);
-    void (*diff_pixels)(DCTELEM *block/*align 16*/, const uint8_t *s1/*align 8*/, const uint8_t *s2/*align 8*/, int stride);
-    void (*put_pixels_clamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size);
-    void (*put_signed_pixels_clamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size);
-    void (*add_pixels_clamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size);
-    void (*add_pixels8)(uint8_t *pixels, DCTELEM *block, int line_size);
-    void (*add_pixels4)(uint8_t *pixels, DCTELEM *block, int line_size);
-    int (*sum_abs_dctelem)(DCTELEM *block/*align 16*/);
-    /**
-     * Motion estimation with emulated edge values.
-     * @param buf pointer to destination buffer (unaligned)
-     * @param src pointer to pixel source (unaligned)
-     * @param linesize width (in pixels) for src/buf
-     * @param block_w number of pixels (per row) to copy to buf
-     * @param block_h nummber of pixel rows to copy to buf
-     * @param src_x offset of src to start of row - this may be negative
-     * @param src_y offset of src to top of image - this may be negative
-     * @param w width of src in pixels
-     * @param h height of src in pixels
-     */
-    void (*emulated_edge_mc)(uint8_t *buf, const uint8_t *src, int linesize,
-                             int block_w, int block_h,
-                             int src_x, int src_y, int w, int h);
+    void (*get_pixels)(int16_t *block/*align 16*/, const uint8_t *pixels/*align 8*/, int line_size);
+    void (*diff_pixels)(int16_t *block/*align 16*/, const uint8_t *s1/*align 8*/, const uint8_t *s2/*align 8*/, int stride);
+    void (*put_pixels_clamped)(const int16_t *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size);
+    void (*put_signed_pixels_clamped)(const int16_t *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size);
+    void (*add_pixels_clamped)(const int16_t *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size);
+    void (*add_pixels8)(uint8_t *pixels, int16_t *block, int line_size);
+    int (*sum_abs_dctelem)(int16_t *block/*align 16*/);
     /**
      * translational global motion compensation.
      */
@@ -248,8 +165,8 @@
      */
     void (*gmc )(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, 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 (*clear_block)(DCTELEM *block/*align 16*/);
-    void (*clear_blocks)(DCTELEM *blocks/*align 16*/);
+    void (*clear_block)(int16_t *block/*align 16*/);
+    void (*clear_blocks)(int16_t *blocks/*align 16*/);
     int (*pix_sum)(uint8_t * pix, int line_size);
     int (*pix_norm1)(uint8_t * pix, int line_size);
 // 16x16 8x8 4x4 2x2 16x8 8x4 4x2 8x16 4x8 2x4
@@ -317,17 +234,15 @@
 
     /**
      * Halfpel motion compensation with no rounding (a+b)>>1.
-     * this is an array[2][4] of motion compensation functions for 2
-     * horizontal blocksizes (8,16) and the 4 halfpel positions<br>
-     * *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ]
+     * this is an array[4] of motion compensation functions for 1
+     * horizontal blocksize (16) and the 4 halfpel positions<br>
+     * *pixels_tab[0][ xhalfpel + 2*yhalfpel ]
      * @param block destination into which the result is averaged (a+b)>>1
      * @param pixels source
      * @param line_size number of bytes in a horizontal line of block
      * @param h height
      */
-    op_pixels_func avg_no_rnd_pixels_tab[4][4];
-
-    void (*put_no_rnd_pixels_l2[2])(uint8_t *block/*align width (8 or 16)*/, const uint8_t *a/*align 1*/, const uint8_t *b/*align 1*/, int line_size, int h);
+    op_pixels_func avg_no_rnd_pixels_tab[4];
 
     /**
      * Thirdpel motion compensation with rounding (a+b+1)>>1.
@@ -345,21 +260,8 @@
     qpel_mc_func put_qpel_pixels_tab[2][16];
     qpel_mc_func avg_qpel_pixels_tab[2][16];
     qpel_mc_func put_no_rnd_qpel_pixels_tab[2][16];
-    qpel_mc_func avg_no_rnd_qpel_pixels_tab[2][16];
     qpel_mc_func put_mspel_pixels_tab[8];
 
-    /**
-     * h264 Chroma MC
-     */
-    h264_chroma_mc_func put_h264_chroma_pixels_tab[3];
-    h264_chroma_mc_func avg_h264_chroma_pixels_tab[3];
-
-    qpel_mc_func put_h264_qpel_pixels_tab[4][16];
-    qpel_mc_func avg_h264_qpel_pixels_tab[4][16];
-
-    qpel_mc_func put_2tap_qpel_pixels_tab[4][16];
-    qpel_mc_func avg_2tap_qpel_pixels_tab[4][16];
-
     me_cmp_func pix_abs[2][4];
 
     /* huffyuv specific */
@@ -382,67 +284,28 @@
 
     void (*h261_loop_filter)(uint8_t *src, int stride);
 
-    /* assume len is a multiple of 4, and arrays are 16-byte aligned */
-    void (*vorbis_inverse_coupling)(float *mag, float *ang, int blocksize);
-    /* assume len is a multiple of 16, and arrays are 32-byte aligned */
-    void (*vector_fmul_reverse)(float *dst, const float *src0, const float *src1, int len);
-    /* assume len is a multiple of 8, and src arrays are 16-byte aligned */
-    void (*vector_fmul_add)(float *dst, const float *src0, const float *src1, const float *src2, int len);
-    /* assume len is a multiple of 4, and arrays are 16-byte aligned */
-    void (*vector_fmul_window)(float *dst, const float *src0, const float *src1, const float *win, int len);
     /* assume len is a multiple of 8, and arrays are 16-byte aligned */
     void (*vector_clipf)(float *dst /* align 16 */, const float *src /* align 16 */, float min, float max, int len /* align 16 */);
-    /**
-     * Calculate the scalar product of two vectors of floats.
-     * @param v1  first vector, 16-byte aligned
-     * @param v2  second vector, 16-byte aligned
-     * @param len length of vectors, multiple of 4
-     */
-    float (*scalarproduct_float)(const float *v1, const float *v2, int len);
-    /**
-     * Calculate the sum and difference of two vectors of floats.
-     * @param v1  first input vector, sum output, 16-byte aligned
-     * @param v2  second input vector, difference output, 16-byte aligned
-     * @param len length of vectors, multiple of 4
-     */
-    void (*butterflies_float)(float *av_restrict v1, float *av_restrict v2, int len);
-
-    /**
-     * Calculate the sum and difference of two vectors of floats and interleave
-     * results into a separate output vector of floats, with each sum
-     * positioned before the corresponding difference.
-     *
-     * @param dst  output vector
-     *             constraints: 16-byte aligned
-     * @param src0 first input vector
-     *             constraints: 32-byte aligned
-     * @param src1 second input vector
-     *             constraints: 32-byte aligned
-     * @param len  number of elements in the input
-     *             constraints: multiple of 8
-     */
-    void (*butterflies_float_interleave)(float *dst, const float *src0,
-                                         const float *src1, int len);
 
     /* (I)DCT */
-    void (*fdct)(DCTELEM *block/* align 16*/);
-    void (*fdct248)(DCTELEM *block/* align 16*/);
+    void (*fdct)(int16_t *block/* align 16*/);
+    void (*fdct248)(int16_t *block/* align 16*/);
 
     /* IDCT really*/
-    void (*idct)(DCTELEM *block/* align 16*/);
+    void (*idct)(int16_t *block/* align 16*/);
 
     /**
      * block -> idct -> clip to unsigned 8 bit -> dest.
      * (-1392, 0, 0, ...) -> idct -> (-174, -174, ...) -> put -> (0, 0, ...)
      * @param line_size size in bytes of a horizontal line of dest
      */
-    void (*idct_put)(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/);
+    void (*idct_put)(uint8_t *dest/*align 8*/, int line_size, int16_t *block/*align 16*/);
 
     /**
      * block -> idct -> add dest -> clip to unsigned 8 bit -> dest.
      * @param line_size size in bytes of a horizontal line of dest
      */
-    void (*idct_add)(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/);
+    void (*idct_add)(uint8_t *dest/*align 8*/, int line_size, int16_t *block/*align 16*/);
 
     /**
      * idct input permutation.
@@ -475,8 +338,6 @@
 #define EDGE_TOP    1
 #define EDGE_BOTTOM 2
 
-    void (*prefetch)(void *mem, int stride, int h);
-
     void (*shrink[4])(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height);
 
     /**
@@ -531,72 +392,8 @@
 
 int ff_check_alignment(void);
 
-/**
- * Return the scalar product of two vectors.
- *
- * @param v1  first input vector
- * @param v2  first input vector
- * @param len number of elements
- *
- * @return sum of elementwise products
- */
-float ff_scalarproduct_float_c(const float *v1, const float *v2, int len);
-
-/**
- * permute block according to permuatation.
- * @param last last non zero element in scantable order
- */
-void ff_block_permute(DCTELEM *block, uint8_t *permutation, const uint8_t *scantable, int last);
-
 void ff_set_cmp(DSPContext* c, me_cmp_func *cmp, int type);
 
-#define         BYTE_VEC32(c)   ((c)*0x01010101UL)
-#define         BYTE_VEC64(c)   ((c)*0x0001000100010001UL)
-
-static inline uint32_t rnd_avg32(uint32_t a, uint32_t b)
-{
-    return (a | b) - (((a ^ b) & ~BYTE_VEC32(0x01)) >> 1);
-}
-
-static inline uint32_t no_rnd_avg32(uint32_t a, uint32_t b)
-{
-    return (a & b) + (((a ^ b) & ~BYTE_VEC32(0x01)) >> 1);
-}
-
-static inline uint64_t rnd_avg64(uint64_t a, uint64_t b)
-{
-    return (a | b) - (((a ^ b) & ~BYTE_VEC64(0x01)) >> 1);
-}
-
-static inline uint64_t no_rnd_avg64(uint64_t a, uint64_t b)
-{
-    return (a & b) + (((a ^ b) & ~BYTE_VEC64(0x01)) >> 1);
-}
-
-static inline int get_penalty_factor(int lambda, int lambda2, int type){
-    switch(type&0xFF){
-    default:
-    case FF_CMP_SAD:
-        return lambda>>FF_LAMBDA_SHIFT;
-    case FF_CMP_DCT:
-        return (3*lambda)>>(FF_LAMBDA_SHIFT+1);
-    case FF_CMP_W53:
-        return (4*lambda)>>(FF_LAMBDA_SHIFT);
-    case FF_CMP_W97:
-        return (2*lambda)>>(FF_LAMBDA_SHIFT);
-    case FF_CMP_SATD:
-    case FF_CMP_DCT264:
-        return (2*lambda)>>FF_LAMBDA_SHIFT;
-    case FF_CMP_RD:
-    case FF_CMP_PSNR:
-    case FF_CMP_SSE:
-    case FF_CMP_NSSE:
-        return lambda2>>FF_LAMBDA_SHIFT;
-    case FF_CMP_BIT:
-        return 1;
-    }
-}
-
 void ff_dsputil_init_alpha(DSPContext* c, AVCodecContext *avctx);
 void ff_dsputil_init_arm(DSPContext* c, AVCodecContext *avctx);
 void ff_dsputil_init_bfin(DSPContext* c, AVCodecContext *avctx);
@@ -604,127 +401,7 @@
 void ff_dsputil_init_ppc(DSPContext* c, AVCodecContext *avctx);
 void ff_dsputil_init_sh4(DSPContext* c, AVCodecContext *avctx);
 void ff_dsputil_init_vis(DSPContext* c, AVCodecContext *avctx);
-void ff_dsputil_init_mips(DSPContext* c, AVCodecContext *avctx);
 
 void ff_dsputil_init_dwt(DSPContext *c);
 
-#if (ARCH_ARM && HAVE_NEON) || ARCH_PPC || HAVE_MMX
-#   define STRIDE_ALIGN 16
-#else
-#   define STRIDE_ALIGN 8
-#endif
-
-// Some broken preprocessors need a second expansion
-// to be forced to tokenize __VA_ARGS__
-#define E(x) x
-
-#define LOCAL_ALIGNED_A(a, t, v, s, o, ...)             \
-    uint8_t la_##v[sizeof(t s o) + (a)];                \
-    t (*v) o = (void *)FFALIGN((uintptr_t)la_##v, a)
-
-#define LOCAL_ALIGNED_D(a, t, v, s, o, ...) DECLARE_ALIGNED(a, t, v) s o
-
-#define LOCAL_ALIGNED(a, t, v, ...) E(LOCAL_ALIGNED_A(a, t, v, __VA_ARGS__,,))
-
-#if HAVE_LOCAL_ALIGNED_8
-#   define LOCAL_ALIGNED_8(t, v, ...) E(LOCAL_ALIGNED_D(8, t, v, __VA_ARGS__,,))
-#else
-#   define LOCAL_ALIGNED_8(t, v, ...) LOCAL_ALIGNED(8, t, v, __VA_ARGS__)
-#endif
-
-#if HAVE_LOCAL_ALIGNED_16
-#   define LOCAL_ALIGNED_16(t, v, ...) E(LOCAL_ALIGNED_D(16, t, v, __VA_ARGS__,,))
-#else
-#   define LOCAL_ALIGNED_16(t, v, ...) LOCAL_ALIGNED(16, t, v, __VA_ARGS__)
-#endif
-
-#define WRAPPER8_16(name8, name16)\
-static int name16(void /*MpegEncContext*/ *s, uint8_t *dst, uint8_t *src, int stride, int h){\
-    return name8(s, dst           , src           , stride, h)\
-          +name8(s, dst+8         , src+8         , stride, h);\
-}
-
-#define WRAPPER8_16_SQ(name8, name16)\
-static int name16(void /*MpegEncContext*/ *s, uint8_t *dst, uint8_t *src, int stride, int h){\
-    int score=0;\
-    score +=name8(s, dst           , src           , stride, 8);\
-    score +=name8(s, dst+8         , src+8         , stride, 8);\
-    if(h==16){\
-        dst += 8*stride;\
-        src += 8*stride;\
-        score +=name8(s, dst           , src           , stride, 8);\
-        score +=name8(s, dst+8         , src+8         , stride, 8);\
-    }\
-    return score;\
-}
-
-
-static inline void copy_block2(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
-{
-    int i;
-    for(i=0; i<h; i++)
-    {
-        AV_COPY16U(dst, src);
-        dst+=dstStride;
-        src+=srcStride;
-    }
-}
-
-static inline void copy_block4(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
-{
-    int i;
-    for(i=0; i<h; i++)
-    {
-        AV_COPY32U(dst, src);
-        dst+=dstStride;
-        src+=srcStride;
-    }
-}
-
-static inline void copy_block8(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
-{
-    int i;
-    for(i=0; i<h; i++)
-    {
-        AV_COPY64U(dst, src);
-        dst+=dstStride;
-        src+=srcStride;
-    }
-}
-
-static inline void copy_block9(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
-{
-    int i;
-    for(i=0; i<h; i++)
-    {
-        AV_COPY64U(dst, src);
-        dst[8]= src[8];
-        dst+=dstStride;
-        src+=srcStride;
-    }
-}
-
-static inline void copy_block16(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
-{
-    int i;
-    for(i=0; i<h; i++)
-    {
-        AV_COPY128U(dst, src);
-        dst+=dstStride;
-        src+=srcStride;
-    }
-}
-
-static inline void copy_block17(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
-{
-    int i;
-    for(i=0; i<h; i++)
-    {
-        AV_COPY128U(dst, src);
-        dst[16]= src[16];
-        dst+=dstStride;
-        src+=srcStride;
-    }
-}
-
 #endif /* AVCODEC_DSPUTIL_H */
diff --git a/libavcodec/dsputil_template.c b/libavcodec/dsputil_template.c
index eacf59b..8517ded 100644
--- a/libavcodec/dsputil_template.c
+++ b/libavcodec/dsputil_template.c
@@ -29,54 +29,6 @@
 
 #include "bit_depth_template.c"
 
-static inline void FUNC(copy_block2)(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
-{
-    int i;
-    for(i=0; i<h; i++)
-    {
-        AV_WN2P(dst   , AV_RN2P(src   ));
-        dst+=dstStride;
-        src+=srcStride;
-    }
-}
-
-static inline void FUNC(copy_block4)(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
-{
-    int i;
-    for(i=0; i<h; i++)
-    {
-        AV_WN4P(dst   , AV_RN4P(src   ));
-        dst+=dstStride;
-        src+=srcStride;
-    }
-}
-
-static inline void FUNC(copy_block8)(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
-{
-    int i;
-    for(i=0; i<h; i++)
-    {
-        AV_WN4P(dst                , AV_RN4P(src                ));
-        AV_WN4P(dst+4*sizeof(pixel), AV_RN4P(src+4*sizeof(pixel)));
-        dst+=dstStride;
-        src+=srcStride;
-    }
-}
-
-static inline void FUNC(copy_block16)(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
-{
-    int i;
-    for(i=0; i<h; i++)
-    {
-        AV_WN4P(dst                 , AV_RN4P(src                 ));
-        AV_WN4P(dst+ 4*sizeof(pixel), AV_RN4P(src+ 4*sizeof(pixel)));
-        AV_WN4P(dst+ 8*sizeof(pixel), AV_RN4P(src+ 8*sizeof(pixel)));
-        AV_WN4P(dst+12*sizeof(pixel), AV_RN4P(src+12*sizeof(pixel)));
-        dst+=dstStride;
-        src+=srcStride;
-    }
-}
-
 /* draw the edges of width 'w' of an image of size width, height */
 //FIXME check that this is ok for mpeg4 interlaced
 static void FUNCC(draw_edges)(uint8_t *p_buf, int p_wrap, int width, int height, int w, int h, int sides)
@@ -113,89 +65,8 @@
             memcpy(last_line + (i + 1) * wrap, last_line, (width + w + w) * sizeof(pixel)); // bottom
 }
 
-/**
- * Copy a rectangular area of samples to a temporary buffer and replicate the border samples.
- * @param buf destination buffer
- * @param src source buffer
- * @param linesize number of bytes between 2 vertically adjacent samples in both the source and destination buffers
- * @param block_w width of block
- * @param block_h height of block
- * @param src_x x coordinate of the top left sample of the block in the source buffer
- * @param src_y y coordinate of the top left sample of the block in the source buffer
- * @param w width of the source buffer
- * @param h height of the source buffer
- */
-void FUNC(ff_emulated_edge_mc)(uint8_t *buf, const uint8_t *src, int linesize, int block_w, int block_h,
-                                    int src_x, int src_y, int w, int h){
-    int x, y;
-    int start_y, start_x, end_y, end_x;
-
-    if(src_y>= h){
-        src-= src_y*linesize;
-        src+= (h-1)*linesize;
-        src_y=h-1;
-    }else if(src_y<=-block_h){
-        src-= src_y*linesize;
-        src+= (1-block_h)*linesize;
-        src_y=1-block_h;
-    }
-    if(src_x>= w){
-        src+= (w-1-src_x)*sizeof(pixel);
-        src_x=w-1;
-    }else if(src_x<=-block_w){
-        src+= (1-block_w-src_x)*sizeof(pixel);
-        src_x=1-block_w;
-    }
-
-    start_y= FFMAX(0, -src_y);
-    start_x= FFMAX(0, -src_x);
-    end_y= FFMIN(block_h, h-src_y);
-    end_x= FFMIN(block_w, w-src_x);
-    av_assert2(start_y < end_y && block_h);
-    av_assert2(start_x < end_x && block_w);
-
-    w    = end_x - start_x;
-    src += start_y*linesize + start_x*sizeof(pixel);
-    buf += start_x*sizeof(pixel);
-
-    //top
-    for(y=0; y<start_y; y++){
-        memcpy(buf, src, w*sizeof(pixel));
-        buf += linesize;
-    }
-
-    // copy existing part
-    for(; y<end_y; y++){
-        memcpy(buf, src, w*sizeof(pixel));
-        src += linesize;
-        buf += linesize;
-    }
-
-    //bottom
-    src -= linesize;
-    for(; y<block_h; y++){
-        memcpy(buf, src, w*sizeof(pixel));
-        buf += linesize;
-    }
-
-    buf -= block_h * linesize + start_x*sizeof(pixel);
-    while (block_h--){
-        pixel *bufp = (pixel*)buf;
-       //left
-        for(x=0; x<start_x; x++){
-            bufp[x] = bufp[start_x];
-        }
-
-       //right
-        for(x=end_x; x<block_w; x++){
-            bufp[x] = bufp[end_x - 1];
-        }
-        buf += linesize;
-    }
-}
-
 #define DCTELEM_FUNCS(dctcoef, suffix)                                  \
-static void FUNCC(get_pixels ## suffix)(DCTELEM *av_restrict _block,    \
+static void FUNCC(get_pixels ## suffix)(int16_t *av_restrict _block,    \
                                         const uint8_t *_pixels,         \
                                         int line_size)                  \
 {                                                                       \
@@ -218,96 +89,27 @@
     }                                                                   \
 }                                                                       \
                                                                         \
-static void FUNCC(add_pixels8 ## suffix)(uint8_t *av_restrict _pixels,  \
-                                         DCTELEM *_block,               \
-                                         int line_size)                 \
-{                                                                       \
-    int i;                                                              \
-    pixel *av_restrict pixels = (pixel *av_restrict)_pixels;            \
-    dctcoef *block = (dctcoef*)_block;                                  \
-    line_size /= sizeof(pixel);                                         \
-                                                                        \
-    for(i=0;i<8;i++) {                                                  \
-        pixels[0] += block[0];                                          \
-        pixels[1] += block[1];                                          \
-        pixels[2] += block[2];                                          \
-        pixels[3] += block[3];                                          \
-        pixels[4] += block[4];                                          \
-        pixels[5] += block[5];                                          \
-        pixels[6] += block[6];                                          \
-        pixels[7] += block[7];                                          \
-        pixels += line_size;                                            \
-        block += 8;                                                     \
-    }                                                                   \
-}                                                                       \
-                                                                        \
-static void FUNCC(add_pixels4 ## suffix)(uint8_t *av_restrict _pixels,  \
-                                         DCTELEM *_block,               \
-                                         int line_size)                 \
-{                                                                       \
-    int i;                                                              \
-    pixel *av_restrict pixels = (pixel *av_restrict)_pixels;            \
-    dctcoef *block = (dctcoef*)_block;                                  \
-    line_size /= sizeof(pixel);                                         \
-                                                                        \
-    for(i=0;i<4;i++) {                                                  \
-        pixels[0] += block[0];                                          \
-        pixels[1] += block[1];                                          \
-        pixels[2] += block[2];                                          \
-        pixels[3] += block[3];                                          \
-        pixels += line_size;                                            \
-        block += 4;                                                     \
-    }                                                                   \
-}                                                                       \
-                                                                        \
-static void FUNCC(clear_block ## suffix)(DCTELEM *block)                \
+static void FUNCC(clear_block ## suffix)(int16_t *block)                \
 {                                                                       \
     memset(block, 0, sizeof(dctcoef)*64);                               \
 }                                                                       \
                                                                         \
 /**                                                                     \
- * memset(blocks, 0, sizeof(DCTELEM)*6*64)                              \
+ * memset(blocks, 0, sizeof(int16_t)*6*64)                              \
  */                                                                     \
-static void FUNCC(clear_blocks ## suffix)(DCTELEM *blocks)              \
+static void FUNCC(clear_blocks ## suffix)(int16_t *blocks)              \
 {                                                                       \
     memset(blocks, 0, sizeof(dctcoef)*6*64);                            \
 }
 
-DCTELEM_FUNCS(DCTELEM, _16)
+DCTELEM_FUNCS(int16_t, _16)
 #if BIT_DEPTH > 8
 DCTELEM_FUNCS(dctcoef, _32)
 #endif
 
+#include "hpel_template.c"
+
 #define PIXOP2(OPNAME, OP) \
-static void FUNCC(OPNAME ## _pixels2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){\
-    int i;\
-    for(i=0; i<h; i++){\
-        OP(*((pixel2*)(block  )), AV_RN2P(pixels  ));\
-        pixels+=line_size;\
-        block +=line_size;\
-    }\
-}\
-static void FUNCC(OPNAME ## _pixels4)(uint8_t *block, const uint8_t *pixels, int line_size, int h){\
-    int i;\
-    for(i=0; i<h; i++){\
-        OP(*((pixel4*)(block  )), AV_RN4P(pixels  ));\
-        pixels+=line_size;\
-        block +=line_size;\
-    }\
-}\
-static void FUNCC(OPNAME ## _pixels8)(uint8_t *block, const uint8_t *pixels, int line_size, int h){\
-    int i;\
-    for(i=0; i<h; i++){\
-        OP(*((pixel4*)(block                )), AV_RN4P(pixels                ));\
-        OP(*((pixel4*)(block+4*sizeof(pixel))), AV_RN4P(pixels+4*sizeof(pixel)));\
-        pixels+=line_size;\
-        block +=line_size;\
-    }\
-}\
-static inline void FUNCC(OPNAME ## _no_rnd_pixels8)(uint8_t *block, const uint8_t *pixels, int line_size, int h){\
-    FUNCC(OPNAME ## _pixels8)(block, pixels, line_size, h);\
-}\
-\
 static inline void FUNC(OPNAME ## _no_rnd_pixels8_l2)(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, \
                                                 int src_stride1, int src_stride2, int h){\
     int i;\
@@ -322,67 +124,25 @@
     }\
 }\
 \
-static inline void FUNC(OPNAME ## _pixels8_l2)(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, \
-                                                int src_stride1, int src_stride2, int h){\
-    int i;\
-    for(i=0; i<h; i++){\
-        pixel4 a,b;\
-        a= AV_RN4P(&src1[i*src_stride1  ]);\
-        b= AV_RN4P(&src2[i*src_stride2  ]);\
-        OP(*((pixel4*)&dst[i*dst_stride  ]), rnd_avg_pixel4(a, b));\
-        a= AV_RN4P(&src1[i*src_stride1+4*sizeof(pixel)]);\
-        b= AV_RN4P(&src2[i*src_stride2+4*sizeof(pixel)]);\
-        OP(*((pixel4*)&dst[i*dst_stride+4*sizeof(pixel)]), rnd_avg_pixel4(a, b));\
-    }\
-}\
-\
-static inline void FUNC(OPNAME ## _pixels4_l2)(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, \
-                                                int src_stride1, int src_stride2, int h){\
-    int i;\
-    for(i=0; i<h; i++){\
-        pixel4 a,b;\
-        a= AV_RN4P(&src1[i*src_stride1  ]);\
-        b= AV_RN4P(&src2[i*src_stride2  ]);\
-        OP(*((pixel4*)&dst[i*dst_stride  ]), rnd_avg_pixel4(a, b));\
-    }\
-}\
-\
-static inline void FUNC(OPNAME ## _pixels2_l2)(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, \
-                                                int src_stride1, int src_stride2, int h){\
-    int i;\
-    for(i=0; i<h; i++){\
-        pixel4 a,b;\
-        a= AV_RN2P(&src1[i*src_stride1  ]);\
-        b= AV_RN2P(&src2[i*src_stride2  ]);\
-        OP(*((pixel2*)&dst[i*dst_stride  ]), rnd_avg_pixel4(a, b));\
-    }\
-}\
-\
-static inline void FUNC(OPNAME ## _pixels16_l2)(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, \
-                                                int src_stride1, int src_stride2, int h){\
-    FUNC(OPNAME ## _pixels8_l2)(dst  , src1  , src2  , dst_stride, src_stride1, src_stride2, h);\
-    FUNC(OPNAME ## _pixels8_l2)(dst+8*sizeof(pixel), src1+8*sizeof(pixel), src2+8*sizeof(pixel), dst_stride, src_stride1, src_stride2, h);\
-}\
-\
 static inline void FUNC(OPNAME ## _no_rnd_pixels16_l2)(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, \
                                                 int src_stride1, int src_stride2, int h){\
     FUNC(OPNAME ## _no_rnd_pixels8_l2)(dst  , src1  , src2  , dst_stride, src_stride1, src_stride2, h);\
     FUNC(OPNAME ## _no_rnd_pixels8_l2)(dst+8*sizeof(pixel), src1+8*sizeof(pixel), src2+8*sizeof(pixel), dst_stride, src_stride1, src_stride2, h);\
 }\
 \
-static inline void FUNCC(OPNAME ## _no_rnd_pixels8_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){\
+static inline void FUNCC(OPNAME ## _no_rnd_pixels8_x2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){\
     FUNC(OPNAME ## _no_rnd_pixels8_l2)(block, pixels, pixels+sizeof(pixel), line_size, line_size, line_size, h);\
 }\
 \
-static inline void FUNCC(OPNAME ## _pixels8_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){\
+static inline void FUNCC(OPNAME ## _pixels8_x2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){\
     FUNC(OPNAME ## _pixels8_l2)(block, pixels, pixels+sizeof(pixel), line_size, line_size, line_size, h);\
 }\
 \
-static inline void FUNCC(OPNAME ## _no_rnd_pixels8_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){\
+static inline void FUNCC(OPNAME ## _no_rnd_pixels8_y2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){\
     FUNC(OPNAME ## _no_rnd_pixels8_l2)(block, pixels, pixels+line_size, line_size, line_size, line_size, h);\
 }\
 \
-static inline void FUNCC(OPNAME ## _pixels8_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){\
+static inline void FUNCC(OPNAME ## _pixels8_y2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){\
     FUNC(OPNAME ## _pixels8_l2)(block, pixels, pixels+line_size, line_size, line_size, line_size, h);\
 }\
 \
@@ -423,19 +183,19 @@
     }\
 }\
 \
-static inline void FUNCC(OPNAME ## _pixels4_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){\
+static inline void FUNCC(OPNAME ## _pixels4_x2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){\
     FUNC(OPNAME ## _pixels4_l2)(block, pixels, pixels+sizeof(pixel), line_size, line_size, line_size, h);\
 }\
 \
-static inline void FUNCC(OPNAME ## _pixels4_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){\
+static inline void FUNCC(OPNAME ## _pixels4_y2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){\
     FUNC(OPNAME ## _pixels4_l2)(block, pixels, pixels+line_size, line_size, line_size, line_size, h);\
 }\
 \
-static inline void FUNCC(OPNAME ## _pixels2_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){\
+static inline void FUNCC(OPNAME ## _pixels2_x2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){\
     FUNC(OPNAME ## _pixels2_l2)(block, pixels, pixels+sizeof(pixel), line_size, line_size, line_size, h);\
 }\
 \
-static inline void FUNCC(OPNAME ## _pixels2_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){\
+static inline void FUNCC(OPNAME ## _pixels2_y2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){\
     FUNC(OPNAME ## _pixels2_l2)(block, pixels, pixels+line_size, line_size, line_size, line_size, h);\
 }\
 \
@@ -486,11 +246,11 @@
     FUNC(OPNAME ## _no_rnd_pixels8_l4)(dst+8*sizeof(pixel), src1+8*sizeof(pixel), src2+8*sizeof(pixel), src3+8*sizeof(pixel), src4+8*sizeof(pixel), dst_stride, src_stride1, src_stride2, src_stride3, src_stride4, h);\
 }\
 \
-static inline void FUNCC(OPNAME ## _pixels2_xy2)(uint8_t *p_block, const uint8_t *p_pixels, int line_size, int h)\
+static inline void FUNCC(OPNAME ## _pixels2_xy2)(uint8_t *_block, const uint8_t *_pixels, ptrdiff_t line_size, int h)\
 {\
         int i, a0, b0, a1, b1;\
-        pixel *block = (pixel*)p_block;\
-        const pixel *pixels = (const pixel*)p_pixels;\
+        pixel *block = (pixel*)_block;\
+        const pixel *pixels = (const pixel*)_pixels;\
         line_size >>= sizeof(pixel)-1;\
         a0= pixels[0];\
         b0= pixels[1] + 2;\
@@ -522,7 +282,7 @@
         }\
 }\
 \
-static inline void FUNCC(OPNAME ## _pixels4_xy2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)\
+static inline void FUNCC(OPNAME ## _pixels4_xy2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)\
 {\
         /* FIXME HIGH BIT DEPTH */\
         int i;\
@@ -559,7 +319,7 @@
         }\
 }\
 \
-static inline void FUNCC(OPNAME ## _pixels8_xy2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)\
+static inline void FUNCC(OPNAME ## _pixels8_xy2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)\
 {\
     /* FIXME HIGH BIT DEPTH */\
     int j;\
@@ -601,7 +361,7 @@
     }\
 }\
 \
-static inline void FUNCC(OPNAME ## _no_rnd_pixels8_xy2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)\
+static inline void FUNCC(OPNAME ## _no_rnd_pixels8_xy2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)\
 {\
     /* FIXME HIGH BIT DEPTH */\
     int j;\
@@ -643,7 +403,6 @@
     }\
 }\
 \
-CALL_2X_PIXELS(FUNCC(OPNAME ## _pixels16)    , FUNCC(OPNAME ## _pixels8)    , 8*sizeof(pixel))\
 CALL_2X_PIXELS(FUNCC(OPNAME ## _pixels16_x2) , FUNCC(OPNAME ## _pixels8_x2) , 8*sizeof(pixel))\
 CALL_2X_PIXELS(FUNCC(OPNAME ## _pixels16_y2) , FUNCC(OPNAME ## _pixels8_y2) , 8*sizeof(pixel))\
 CALL_2X_PIXELS(FUNCC(OPNAME ## _pixels16_xy2), FUNCC(OPNAME ## _pixels8_xy2), 8*sizeof(pixel))\
@@ -654,628 +413,13 @@
 
 #define op_avg(a, b) a = rnd_avg_pixel4(a, b)
 #define op_put(a, b) a = b
-
+#if BIT_DEPTH == 8
+#define put_no_rnd_pixels8_8_c put_pixels8_8_c
 PIXOP2(avg, op_avg)
 PIXOP2(put, op_put)
-#undef op_avg
-#undef op_put
-
-#define put_no_rnd_pixels8_c  put_pixels8_c
-#define put_no_rnd_pixels16_c put_pixels16_c
-
-static void FUNCC(put_no_rnd_pixels16_l2)(uint8_t *dst, const uint8_t *a, const uint8_t *b, int stride, int h){
-    FUNC(put_no_rnd_pixels16_l2)(dst, a, b, stride, stride, stride, h);
-}
-
-static void FUNCC(put_no_rnd_pixels8_l2)(uint8_t *dst, const uint8_t *a, const uint8_t *b, int stride, int h){
-    FUNC(put_no_rnd_pixels8_l2)(dst, a, b, stride, stride, stride, h);
-}
-
-#define H264_CHROMA_MC(OPNAME, OP)\
-static void FUNCC(OPNAME ## h264_chroma_mc2)(uint8_t *p_dst/*align 8*/, uint8_t *p_src/*align 1*/, int stride, int h, int x, int y){\
-    pixel *dst = (pixel*)p_dst;\
-    pixel *src = (pixel*)p_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]));\
-            OP(dst[1], (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2]));\
-            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]));\
-            OP(dst[1], (A*src[1] + E*src[step+1]));\
-            dst+= stride;\
-            src+= stride;\
-        }\
-    }\
-}\
-\
-static void FUNCC(OPNAME ## h264_chroma_mc4)(uint8_t *p_dst/*align 8*/, uint8_t *p_src/*align 1*/, int stride, int h, int x, int y){\
-    pixel *dst = (pixel*)p_dst;\
-    pixel *src = (pixel*)p_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]));\
-            OP(dst[1], (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2]));\
-            OP(dst[2], (A*src[2] + B*src[3] + C*src[stride+2] + D*src[stride+3]));\
-            OP(dst[3], (A*src[3] + B*src[4] + C*src[stride+3] + D*src[stride+4]));\
-            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]));\
-            OP(dst[1], (A*src[1] + E*src[step+1]));\
-            OP(dst[2], (A*src[2] + E*src[step+2]));\
-            OP(dst[3], (A*src[3] + E*src[step+3]));\
-            dst+= stride;\
-            src+= stride;\
-        }\
-    }\
-}\
-\
-static void FUNCC(OPNAME ## h264_chroma_mc8)(uint8_t *p_dst/*align 8*/, uint8_t *p_src/*align 1*/, int stride, int h, int x, int y){\
-    pixel *dst = (pixel*)p_dst;\
-    pixel *src = (pixel*)p_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]));\
-            OP(dst[1], (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2]));\
-            OP(dst[2], (A*src[2] + B*src[3] + C*src[stride+2] + D*src[stride+3]));\
-            OP(dst[3], (A*src[3] + B*src[4] + C*src[stride+3] + D*src[stride+4]));\
-            OP(dst[4], (A*src[4] + B*src[5] + C*src[stride+4] + D*src[stride+5]));\
-            OP(dst[5], (A*src[5] + B*src[6] + C*src[stride+5] + D*src[stride+6]));\
-            OP(dst[6], (A*src[6] + B*src[7] + C*src[stride+6] + D*src[stride+7]));\
-            OP(dst[7], (A*src[7] + B*src[8] + C*src[stride+7] + D*src[stride+8]));\
-            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]));\
-            OP(dst[1], (A*src[1] + E*src[step+1]));\
-            OP(dst[2], (A*src[2] + E*src[step+2]));\
-            OP(dst[3], (A*src[3] + E*src[step+3]));\
-            OP(dst[4], (A*src[4] + E*src[step+4]));\
-            OP(dst[5], (A*src[5] + E*src[step+5]));\
-            OP(dst[6], (A*src[6] + E*src[step+6]));\
-            OP(dst[7], (A*src[7] + E*src[step+7]));\
-            dst+= stride;\
-            src+= stride;\
-        }\
-    }\
-}
-
-#define op_avg(a, b) a = (((a)+(((b) + 32)>>6)+1)>>1)
-#define op_put(a, b) a = (((b) + 32)>>6)
-
-H264_CHROMA_MC(put_       , op_put)
-H264_CHROMA_MC(avg_       , op_avg)
-#undef op_avg
-#undef op_put
-
-#define H264_LOWPASS(OPNAME, OP, OP2) \
-static av_unused void FUNC(OPNAME ## h264_qpel2_h_lowpass)(uint8_t *p_dst, uint8_t *p_src, int dstStride, int srcStride){\
-    const int h=2;\
-    INIT_CLIP\
-    int i;\
-    pixel *dst = (pixel*)p_dst;\
-    pixel *src = (pixel*)p_src;\
-    dstStride >>= sizeof(pixel)-1;\
-    srcStride >>= sizeof(pixel)-1;\
-    for(i=0; i<h; i++)\
-    {\
-        OP(dst[0], (src[0]+src[1])*20 - (src[-1]+src[2])*5 + (src[-2]+src[3]));\
-        OP(dst[1], (src[1]+src[2])*20 - (src[0 ]+src[3])*5 + (src[-1]+src[4]));\
-        dst+=dstStride;\
-        src+=srcStride;\
-    }\
-}\
-\
-static av_unused void FUNC(OPNAME ## h264_qpel2_v_lowpass)(uint8_t *p_dst, uint8_t *p_src, int dstStride, int srcStride){\
-    const int w=2;\
-    INIT_CLIP\
-    int i;\
-    pixel *dst = (pixel*)p_dst;\
-    pixel *src = (pixel*)p_src;\
-    dstStride >>= sizeof(pixel)-1;\
-    srcStride >>= sizeof(pixel)-1;\
-    for(i=0; i<w; i++)\
-    {\
-        const int srcB= src[-2*srcStride];\
-        const int srcA= src[-1*srcStride];\
-        const int src0= src[0 *srcStride];\
-        const int src1= src[1 *srcStride];\
-        const int src2= src[2 *srcStride];\
-        const int src3= src[3 *srcStride];\
-        const int src4= src[4 *srcStride];\
-        OP(dst[0*dstStride], (src0+src1)*20 - (srcA+src2)*5 + (srcB+src3));\
-        OP(dst[1*dstStride], (src1+src2)*20 - (src0+src3)*5 + (srcA+src4));\
-        dst++;\
-        src++;\
-    }\
-}\
-\
-static av_unused void FUNC(OPNAME ## h264_qpel2_hv_lowpass)(uint8_t *p_dst, pixeltmp *tmp, uint8_t *p_src, int dstStride, int tmpStride, int srcStride){\
-    const int h=2;\
-    const int w=2;\
-    const int pad = (BIT_DEPTH == 10) ? (-10 * ((1<<BIT_DEPTH)-1)) : 0;\
-    INIT_CLIP\
-    int i;\
-    pixel *dst = (pixel*)p_dst;\
-    pixel *src = (pixel*)p_src;\
-    dstStride >>= sizeof(pixel)-1;\
-    srcStride >>= sizeof(pixel)-1;\
-    src -= 2*srcStride;\
-    for(i=0; i<h+5; i++)\
-    {\
-        tmp[0]= (src[0]+src[1])*20 - (src[-1]+src[2])*5 + (src[-2]+src[3]) + pad;\
-        tmp[1]= (src[1]+src[2])*20 - (src[0 ]+src[3])*5 + (src[-1]+src[4]) + pad;\
-        tmp+=tmpStride;\
-        src+=srcStride;\
-    }\
-    tmp -= tmpStride*(h+5-2);\
-    for(i=0; i<w; i++)\
-    {\
-        const int tmpB= tmp[-2*tmpStride] - pad;\
-        const int tmpA= tmp[-1*tmpStride] - pad;\
-        const int tmp0= tmp[0 *tmpStride] - pad;\
-        const int tmp1= tmp[1 *tmpStride] - pad;\
-        const int tmp2= tmp[2 *tmpStride] - pad;\
-        const int tmp3= tmp[3 *tmpStride] - pad;\
-        const int tmp4= tmp[4 *tmpStride] - pad;\
-        OP2(dst[0*dstStride], (tmp0+tmp1)*20 - (tmpA+tmp2)*5 + (tmpB+tmp3));\
-        OP2(dst[1*dstStride], (tmp1+tmp2)*20 - (tmp0+tmp3)*5 + (tmpA+tmp4));\
-        dst++;\
-        tmp++;\
-    }\
-}\
-static void FUNC(OPNAME ## h264_qpel4_h_lowpass)(uint8_t *p_dst, uint8_t *p_src, int dstStride, int srcStride){\
-    const int h=4;\
-    INIT_CLIP\
-    int i;\
-    pixel *dst = (pixel*)p_dst;\
-    pixel *src = (pixel*)p_src;\
-    dstStride >>= sizeof(pixel)-1;\
-    srcStride >>= sizeof(pixel)-1;\
-    for(i=0; i<h; i++)\
-    {\
-        OP(dst[0], (src[0]+src[1])*20 - (src[-1]+src[2])*5 + (src[-2]+src[3]));\
-        OP(dst[1], (src[1]+src[2])*20 - (src[0 ]+src[3])*5 + (src[-1]+src[4]));\
-        OP(dst[2], (src[2]+src[3])*20 - (src[1 ]+src[4])*5 + (src[0 ]+src[5]));\
-        OP(dst[3], (src[3]+src[4])*20 - (src[2 ]+src[5])*5 + (src[1 ]+src[6]));\
-        dst+=dstStride;\
-        src+=srcStride;\
-    }\
-}\
-\
-static void FUNC(OPNAME ## h264_qpel4_v_lowpass)(uint8_t *p_dst, uint8_t *p_src, int dstStride, int srcStride){\
-    const int w=4;\
-    INIT_CLIP\
-    int i;\
-    pixel *dst = (pixel*)p_dst;\
-    pixel *src = (pixel*)p_src;\
-    dstStride >>= sizeof(pixel)-1;\
-    srcStride >>= sizeof(pixel)-1;\
-    for(i=0; i<w; i++)\
-    {\
-        const int srcB= src[-2*srcStride];\
-        const int srcA= src[-1*srcStride];\
-        const int src0= src[0 *srcStride];\
-        const int src1= src[1 *srcStride];\
-        const int src2= src[2 *srcStride];\
-        const int src3= src[3 *srcStride];\
-        const int src4= src[4 *srcStride];\
-        const int src5= src[5 *srcStride];\
-        const int src6= src[6 *srcStride];\
-        OP(dst[0*dstStride], (src0+src1)*20 - (srcA+src2)*5 + (srcB+src3));\
-        OP(dst[1*dstStride], (src1+src2)*20 - (src0+src3)*5 + (srcA+src4));\
-        OP(dst[2*dstStride], (src2+src3)*20 - (src1+src4)*5 + (src0+src5));\
-        OP(dst[3*dstStride], (src3+src4)*20 - (src2+src5)*5 + (src1+src6));\
-        dst++;\
-        src++;\
-    }\
-}\
-\
-static void FUNC(OPNAME ## h264_qpel4_hv_lowpass)(uint8_t *p_dst, pixeltmp *tmp, uint8_t *p_src, int dstStride, int tmpStride, int srcStride){\
-    const int h=4;\
-    const int w=4;\
-    const int pad = (BIT_DEPTH == 10) ? (-10 * ((1<<BIT_DEPTH)-1)) : 0;\
-    INIT_CLIP\
-    int i;\
-    pixel *dst = (pixel*)p_dst;\
-    pixel *src = (pixel*)p_src;\
-    dstStride >>= sizeof(pixel)-1;\
-    srcStride >>= sizeof(pixel)-1;\
-    src -= 2*srcStride;\
-    for(i=0; i<h+5; i++)\
-    {\
-        tmp[0]= (src[0]+src[1])*20 - (src[-1]+src[2])*5 + (src[-2]+src[3]) + pad;\
-        tmp[1]= (src[1]+src[2])*20 - (src[0 ]+src[3])*5 + (src[-1]+src[4]) + pad;\
-        tmp[2]= (src[2]+src[3])*20 - (src[1 ]+src[4])*5 + (src[0 ]+src[5]) + pad;\
-        tmp[3]= (src[3]+src[4])*20 - (src[2 ]+src[5])*5 + (src[1 ]+src[6]) + pad;\
-        tmp+=tmpStride;\
-        src+=srcStride;\
-    }\
-    tmp -= tmpStride*(h+5-2);\
-    for(i=0; i<w; i++)\
-    {\
-        const int tmpB= tmp[-2*tmpStride] - pad;\
-        const int tmpA= tmp[-1*tmpStride] - pad;\
-        const int tmp0= tmp[0 *tmpStride] - pad;\
-        const int tmp1= tmp[1 *tmpStride] - pad;\
-        const int tmp2= tmp[2 *tmpStride] - pad;\
-        const int tmp3= tmp[3 *tmpStride] - pad;\
-        const int tmp4= tmp[4 *tmpStride] - pad;\
-        const int tmp5= tmp[5 *tmpStride] - pad;\
-        const int tmp6= tmp[6 *tmpStride] - pad;\
-        OP2(dst[0*dstStride], (tmp0+tmp1)*20 - (tmpA+tmp2)*5 + (tmpB+tmp3));\
-        OP2(dst[1*dstStride], (tmp1+tmp2)*20 - (tmp0+tmp3)*5 + (tmpA+tmp4));\
-        OP2(dst[2*dstStride], (tmp2+tmp3)*20 - (tmp1+tmp4)*5 + (tmp0+tmp5));\
-        OP2(dst[3*dstStride], (tmp3+tmp4)*20 - (tmp2+tmp5)*5 + (tmp1+tmp6));\
-        dst++;\
-        tmp++;\
-    }\
-}\
-\
-static void FUNC(OPNAME ## h264_qpel8_h_lowpass)(uint8_t *p_dst, uint8_t *p_src, int dstStride, int srcStride){\
-    const int h=8;\
-    INIT_CLIP\
-    int i;\
-    pixel *dst = (pixel*)p_dst;\
-    pixel *src = (pixel*)p_src;\
-    dstStride >>= sizeof(pixel)-1;\
-    srcStride >>= sizeof(pixel)-1;\
-    for(i=0; i<h; i++)\
-    {\
-        OP(dst[0], (src[0]+src[1])*20 - (src[-1]+src[2])*5 + (src[-2]+src[3 ]));\
-        OP(dst[1], (src[1]+src[2])*20 - (src[0 ]+src[3])*5 + (src[-1]+src[4 ]));\
-        OP(dst[2], (src[2]+src[3])*20 - (src[1 ]+src[4])*5 + (src[0 ]+src[5 ]));\
-        OP(dst[3], (src[3]+src[4])*20 - (src[2 ]+src[5])*5 + (src[1 ]+src[6 ]));\
-        OP(dst[4], (src[4]+src[5])*20 - (src[3 ]+src[6])*5 + (src[2 ]+src[7 ]));\
-        OP(dst[5], (src[5]+src[6])*20 - (src[4 ]+src[7])*5 + (src[3 ]+src[8 ]));\
-        OP(dst[6], (src[6]+src[7])*20 - (src[5 ]+src[8])*5 + (src[4 ]+src[9 ]));\
-        OP(dst[7], (src[7]+src[8])*20 - (src[6 ]+src[9])*5 + (src[5 ]+src[10]));\
-        dst+=dstStride;\
-        src+=srcStride;\
-    }\
-}\
-\
-static void FUNC(OPNAME ## h264_qpel8_v_lowpass)(uint8_t *p_dst, uint8_t *p_src, int dstStride, int srcStride){\
-    const int w=8;\
-    INIT_CLIP\
-    int i;\
-    pixel *dst = (pixel*)p_dst;\
-    pixel *src = (pixel*)p_src;\
-    dstStride >>= sizeof(pixel)-1;\
-    srcStride >>= sizeof(pixel)-1;\
-    for(i=0; i<w; i++)\
-    {\
-        const int srcB= src[-2*srcStride];\
-        const int srcA= src[-1*srcStride];\
-        const int src0= src[0 *srcStride];\
-        const int src1= src[1 *srcStride];\
-        const int src2= src[2 *srcStride];\
-        const int src3= src[3 *srcStride];\
-        const int src4= src[4 *srcStride];\
-        const int src5= src[5 *srcStride];\
-        const int src6= src[6 *srcStride];\
-        const int src7= src[7 *srcStride];\
-        const int src8= src[8 *srcStride];\
-        const int src9= src[9 *srcStride];\
-        const int src10=src[10*srcStride];\
-        OP(dst[0*dstStride], (src0+src1)*20 - (srcA+src2)*5 + (srcB+src3));\
-        OP(dst[1*dstStride], (src1+src2)*20 - (src0+src3)*5 + (srcA+src4));\
-        OP(dst[2*dstStride], (src2+src3)*20 - (src1+src4)*5 + (src0+src5));\
-        OP(dst[3*dstStride], (src3+src4)*20 - (src2+src5)*5 + (src1+src6));\
-        OP(dst[4*dstStride], (src4+src5)*20 - (src3+src6)*5 + (src2+src7));\
-        OP(dst[5*dstStride], (src5+src6)*20 - (src4+src7)*5 + (src3+src8));\
-        OP(dst[6*dstStride], (src6+src7)*20 - (src5+src8)*5 + (src4+src9));\
-        OP(dst[7*dstStride], (src7+src8)*20 - (src6+src9)*5 + (src5+src10));\
-        dst++;\
-        src++;\
-    }\
-}\
-\
-static void FUNC(OPNAME ## h264_qpel8_hv_lowpass)(uint8_t *p_dst, pixeltmp *tmp, uint8_t *p_src, int dstStride, int tmpStride, int srcStride){\
-    const int h=8;\
-    const int w=8;\
-    const int pad = (BIT_DEPTH == 10) ? (-10 * ((1<<BIT_DEPTH)-1)) : 0;\
-    INIT_CLIP\
-    int i;\
-    pixel *dst = (pixel*)p_dst;\
-    pixel *src = (pixel*)p_src;\
-    dstStride >>= sizeof(pixel)-1;\
-    srcStride >>= sizeof(pixel)-1;\
-    src -= 2*srcStride;\
-    for(i=0; i<h+5; i++)\
-    {\
-        tmp[0]= (src[0]+src[1])*20 - (src[-1]+src[2])*5 + (src[-2]+src[3 ]) + pad;\
-        tmp[1]= (src[1]+src[2])*20 - (src[0 ]+src[3])*5 + (src[-1]+src[4 ]) + pad;\
-        tmp[2]= (src[2]+src[3])*20 - (src[1 ]+src[4])*5 + (src[0 ]+src[5 ]) + pad;\
-        tmp[3]= (src[3]+src[4])*20 - (src[2 ]+src[5])*5 + (src[1 ]+src[6 ]) + pad;\
-        tmp[4]= (src[4]+src[5])*20 - (src[3 ]+src[6])*5 + (src[2 ]+src[7 ]) + pad;\
-        tmp[5]= (src[5]+src[6])*20 - (src[4 ]+src[7])*5 + (src[3 ]+src[8 ]) + pad;\
-        tmp[6]= (src[6]+src[7])*20 - (src[5 ]+src[8])*5 + (src[4 ]+src[9 ]) + pad;\
-        tmp[7]= (src[7]+src[8])*20 - (src[6 ]+src[9])*5 + (src[5 ]+src[10]) + pad;\
-        tmp+=tmpStride;\
-        src+=srcStride;\
-    }\
-    tmp -= tmpStride*(h+5-2);\
-    for(i=0; i<w; i++)\
-    {\
-        const int tmpB= tmp[-2*tmpStride] - pad;\
-        const int tmpA= tmp[-1*tmpStride] - pad;\
-        const int tmp0= tmp[0 *tmpStride] - pad;\
-        const int tmp1= tmp[1 *tmpStride] - pad;\
-        const int tmp2= tmp[2 *tmpStride] - pad;\
-        const int tmp3= tmp[3 *tmpStride] - pad;\
-        const int tmp4= tmp[4 *tmpStride] - pad;\
-        const int tmp5= tmp[5 *tmpStride] - pad;\
-        const int tmp6= tmp[6 *tmpStride] - pad;\
-        const int tmp7= tmp[7 *tmpStride] - pad;\
-        const int tmp8= tmp[8 *tmpStride] - pad;\
-        const int tmp9= tmp[9 *tmpStride] - pad;\
-        const int tmp10=tmp[10*tmpStride] - pad;\
-        OP2(dst[0*dstStride], (tmp0+tmp1)*20 - (tmpA+tmp2)*5 + (tmpB+tmp3));\
-        OP2(dst[1*dstStride], (tmp1+tmp2)*20 - (tmp0+tmp3)*5 + (tmpA+tmp4));\
-        OP2(dst[2*dstStride], (tmp2+tmp3)*20 - (tmp1+tmp4)*5 + (tmp0+tmp5));\
-        OP2(dst[3*dstStride], (tmp3+tmp4)*20 - (tmp2+tmp5)*5 + (tmp1+tmp6));\
-        OP2(dst[4*dstStride], (tmp4+tmp5)*20 - (tmp3+tmp6)*5 + (tmp2+tmp7));\
-        OP2(dst[5*dstStride], (tmp5+tmp6)*20 - (tmp4+tmp7)*5 + (tmp3+tmp8));\
-        OP2(dst[6*dstStride], (tmp6+tmp7)*20 - (tmp5+tmp8)*5 + (tmp4+tmp9));\
-        OP2(dst[7*dstStride], (tmp7+tmp8)*20 - (tmp6+tmp9)*5 + (tmp5+tmp10));\
-        dst++;\
-        tmp++;\
-    }\
-}\
-\
-static void FUNC(OPNAME ## h264_qpel16_v_lowpass)(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\
-    FUNC(OPNAME ## h264_qpel8_v_lowpass)(dst                , src                , dstStride, srcStride);\
-    FUNC(OPNAME ## h264_qpel8_v_lowpass)(dst+8*sizeof(pixel), src+8*sizeof(pixel), dstStride, srcStride);\
-    src += 8*srcStride;\
-    dst += 8*dstStride;\
-    FUNC(OPNAME ## h264_qpel8_v_lowpass)(dst                , src                , dstStride, srcStride);\
-    FUNC(OPNAME ## h264_qpel8_v_lowpass)(dst+8*sizeof(pixel), src+8*sizeof(pixel), dstStride, srcStride);\
-}\
-\
-static void FUNC(OPNAME ## h264_qpel16_h_lowpass)(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\
-    FUNC(OPNAME ## h264_qpel8_h_lowpass)(dst                , src                , dstStride, srcStride);\
-    FUNC(OPNAME ## h264_qpel8_h_lowpass)(dst+8*sizeof(pixel), src+8*sizeof(pixel), dstStride, srcStride);\
-    src += 8*srcStride;\
-    dst += 8*dstStride;\
-    FUNC(OPNAME ## h264_qpel8_h_lowpass)(dst                , src                , dstStride, srcStride);\
-    FUNC(OPNAME ## h264_qpel8_h_lowpass)(dst+8*sizeof(pixel), src+8*sizeof(pixel), dstStride, srcStride);\
-}\
-\
-static void FUNC(OPNAME ## h264_qpel16_hv_lowpass)(uint8_t *dst, pixeltmp *tmp, uint8_t *src, int dstStride, int tmpStride, int srcStride){\
-    FUNC(OPNAME ## h264_qpel8_hv_lowpass)(dst                , tmp  , src                , dstStride, tmpStride, srcStride);\
-    FUNC(OPNAME ## h264_qpel8_hv_lowpass)(dst+8*sizeof(pixel), tmp+8, src+8*sizeof(pixel), dstStride, tmpStride, srcStride);\
-    src += 8*srcStride;\
-    dst += 8*dstStride;\
-    FUNC(OPNAME ## h264_qpel8_hv_lowpass)(dst                , tmp  , src                , dstStride, tmpStride, srcStride);\
-    FUNC(OPNAME ## h264_qpel8_hv_lowpass)(dst+8*sizeof(pixel), tmp+8, src+8*sizeof(pixel), dstStride, tmpStride, srcStride);\
-}\
-
-#define H264_MC(OPNAME, SIZE) \
-static av_unused void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc00)(uint8_t *dst, uint8_t *src, int stride){\
-    FUNCC(OPNAME ## pixels ## SIZE)(dst, src, stride, SIZE);\
-}\
-\
-static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc10)(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t half[SIZE*SIZE*sizeof(pixel)];\
-    FUNC(put_h264_qpel ## SIZE ## _h_lowpass)(half, src, SIZE*sizeof(pixel), stride);\
-    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, src, half, stride, stride, SIZE*sizeof(pixel), SIZE);\
-}\
-\
-static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc20)(uint8_t *dst, uint8_t *src, int stride){\
-    FUNC(OPNAME ## h264_qpel ## SIZE ## _h_lowpass)(dst, src, stride, stride);\
-}\
-\
-static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc30)(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t half[SIZE*SIZE*sizeof(pixel)];\
-    FUNC(put_h264_qpel ## SIZE ## _h_lowpass)(half, src, SIZE*sizeof(pixel), stride);\
-    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, src+sizeof(pixel), half, stride, stride, SIZE*sizeof(pixel), SIZE);\
-}\
-\
-static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc01)(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[SIZE*(SIZE+5)*sizeof(pixel)];\
-    uint8_t * const full_mid= full + SIZE*2*sizeof(pixel);\
-    uint8_t half[SIZE*SIZE*sizeof(pixel)];\
-    FUNC(copy_block ## SIZE )(full, src - stride*2, SIZE*sizeof(pixel),  stride, SIZE + 5);\
-    FUNC(put_h264_qpel ## SIZE ## _v_lowpass)(half, full_mid, SIZE*sizeof(pixel), SIZE*sizeof(pixel));\
-    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, full_mid, half, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\
-}\
-\
-static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc02)(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[SIZE*(SIZE+5)*sizeof(pixel)];\
-    uint8_t * const full_mid= full + SIZE*2*sizeof(pixel);\
-    FUNC(copy_block ## SIZE )(full, src - stride*2, SIZE*sizeof(pixel),  stride, SIZE + 5);\
-    FUNC(OPNAME ## h264_qpel ## SIZE ## _v_lowpass)(dst, full_mid, stride, SIZE*sizeof(pixel));\
-}\
-\
-static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc03)(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[SIZE*(SIZE+5)*sizeof(pixel)];\
-    uint8_t * const full_mid= full + SIZE*2*sizeof(pixel);\
-    uint8_t half[SIZE*SIZE*sizeof(pixel)];\
-    FUNC(copy_block ## SIZE )(full, src - stride*2, SIZE*sizeof(pixel),  stride, SIZE + 5);\
-    FUNC(put_h264_qpel ## SIZE ## _v_lowpass)(half, full_mid, SIZE*sizeof(pixel), SIZE*sizeof(pixel));\
-    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, full_mid+SIZE*sizeof(pixel), half, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\
-}\
-\
-static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc11)(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[SIZE*(SIZE+5)*sizeof(pixel)];\
-    uint8_t * const full_mid= full + SIZE*2*sizeof(pixel);\
-    uint8_t halfH[SIZE*SIZE*sizeof(pixel)];\
-    uint8_t halfV[SIZE*SIZE*sizeof(pixel)];\
-    FUNC(put_h264_qpel ## SIZE ## _h_lowpass)(halfH, src, SIZE*sizeof(pixel), stride);\
-    FUNC(copy_block ## SIZE )(full, src - stride*2, SIZE*sizeof(pixel),  stride, SIZE + 5);\
-    FUNC(put_h264_qpel ## SIZE ## _v_lowpass)(halfV, full_mid, SIZE*sizeof(pixel), SIZE*sizeof(pixel));\
-    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, halfH, halfV, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\
-}\
-\
-static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc31)(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[SIZE*(SIZE+5)*sizeof(pixel)];\
-    uint8_t * const full_mid= full + SIZE*2*sizeof(pixel);\
-    uint8_t halfH[SIZE*SIZE*sizeof(pixel)];\
-    uint8_t halfV[SIZE*SIZE*sizeof(pixel)];\
-    FUNC(put_h264_qpel ## SIZE ## _h_lowpass)(halfH, src, SIZE*sizeof(pixel), stride);\
-    FUNC(copy_block ## SIZE )(full, src - stride*2 + sizeof(pixel), SIZE*sizeof(pixel),  stride, SIZE + 5);\
-    FUNC(put_h264_qpel ## SIZE ## _v_lowpass)(halfV, full_mid, SIZE*sizeof(pixel), SIZE*sizeof(pixel));\
-    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, halfH, halfV, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\
-}\
-\
-static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc13)(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[SIZE*(SIZE+5)*sizeof(pixel)];\
-    uint8_t * const full_mid= full + SIZE*2*sizeof(pixel);\
-    uint8_t halfH[SIZE*SIZE*sizeof(pixel)];\
-    uint8_t halfV[SIZE*SIZE*sizeof(pixel)];\
-    FUNC(put_h264_qpel ## SIZE ## _h_lowpass)(halfH, src + stride, SIZE*sizeof(pixel), stride);\
-    FUNC(copy_block ## SIZE )(full, src - stride*2, SIZE*sizeof(pixel),  stride, SIZE + 5);\
-    FUNC(put_h264_qpel ## SIZE ## _v_lowpass)(halfV, full_mid, SIZE*sizeof(pixel), SIZE*sizeof(pixel));\
-    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, halfH, halfV, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\
-}\
-\
-static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc33)(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[SIZE*(SIZE+5)*sizeof(pixel)];\
-    uint8_t * const full_mid= full + SIZE*2*sizeof(pixel);\
-    uint8_t halfH[SIZE*SIZE*sizeof(pixel)];\
-    uint8_t halfV[SIZE*SIZE*sizeof(pixel)];\
-    FUNC(put_h264_qpel ## SIZE ## _h_lowpass)(halfH, src + stride, SIZE*sizeof(pixel), stride);\
-    FUNC(copy_block ## SIZE )(full, src - stride*2 + sizeof(pixel), SIZE*sizeof(pixel),  stride, SIZE + 5);\
-    FUNC(put_h264_qpel ## SIZE ## _v_lowpass)(halfV, full_mid, SIZE*sizeof(pixel), SIZE*sizeof(pixel));\
-    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, halfH, halfV, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\
-}\
-\
-static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc22)(uint8_t *dst, uint8_t *src, int stride){\
-    pixeltmp tmp[SIZE*(SIZE+5)*sizeof(pixel)];\
-    FUNC(OPNAME ## h264_qpel ## SIZE ## _hv_lowpass)(dst, tmp, src, stride, SIZE*sizeof(pixel), stride);\
-}\
-\
-static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc21)(uint8_t *dst, uint8_t *src, int stride){\
-    pixeltmp tmp[SIZE*(SIZE+5)*sizeof(pixel)];\
-    uint8_t halfH[SIZE*SIZE*sizeof(pixel)];\
-    uint8_t halfHV[SIZE*SIZE*sizeof(pixel)];\
-    FUNC(put_h264_qpel ## SIZE ## _h_lowpass)(halfH, src, SIZE*sizeof(pixel), stride);\
-    FUNC(put_h264_qpel ## SIZE ## _hv_lowpass)(halfHV, tmp, src, SIZE*sizeof(pixel), SIZE*sizeof(pixel), stride);\
-    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, halfH, halfHV, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\
-}\
-\
-static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc23)(uint8_t *dst, uint8_t *src, int stride){\
-    pixeltmp tmp[SIZE*(SIZE+5)*sizeof(pixel)];\
-    uint8_t halfH[SIZE*SIZE*sizeof(pixel)];\
-    uint8_t halfHV[SIZE*SIZE*sizeof(pixel)];\
-    FUNC(put_h264_qpel ## SIZE ## _h_lowpass)(halfH, src + stride, SIZE*sizeof(pixel), stride);\
-    FUNC(put_h264_qpel ## SIZE ## _hv_lowpass)(halfHV, tmp, src, SIZE*sizeof(pixel), SIZE*sizeof(pixel), stride);\
-    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, halfH, halfHV, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\
-}\
-\
-static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc12)(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[SIZE*(SIZE+5)*sizeof(pixel)];\
-    uint8_t * const full_mid= full + SIZE*2*sizeof(pixel);\
-    pixeltmp tmp[SIZE*(SIZE+5)*sizeof(pixel)];\
-    uint8_t halfV[SIZE*SIZE*sizeof(pixel)];\
-    uint8_t halfHV[SIZE*SIZE*sizeof(pixel)];\
-    FUNC(copy_block ## SIZE )(full, src - stride*2, SIZE*sizeof(pixel),  stride, SIZE + 5);\
-    FUNC(put_h264_qpel ## SIZE ## _v_lowpass)(halfV, full_mid, SIZE*sizeof(pixel), SIZE*sizeof(pixel));\
-    FUNC(put_h264_qpel ## SIZE ## _hv_lowpass)(halfHV, tmp, src, SIZE*sizeof(pixel), SIZE*sizeof(pixel), stride);\
-    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, halfV, halfHV, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\
-}\
-\
-static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc32)(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[SIZE*(SIZE+5)*sizeof(pixel)];\
-    uint8_t * const full_mid= full + SIZE*2*sizeof(pixel);\
-    pixeltmp tmp[SIZE*(SIZE+5)*sizeof(pixel)];\
-    uint8_t halfV[SIZE*SIZE*sizeof(pixel)];\
-    uint8_t halfHV[SIZE*SIZE*sizeof(pixel)];\
-    FUNC(copy_block ## SIZE )(full, src - stride*2 + sizeof(pixel), SIZE*sizeof(pixel),  stride, SIZE + 5);\
-    FUNC(put_h264_qpel ## SIZE ## _v_lowpass)(halfV, full_mid, SIZE*sizeof(pixel), SIZE*sizeof(pixel));\
-    FUNC(put_h264_qpel ## SIZE ## _hv_lowpass)(halfHV, tmp, src, SIZE*sizeof(pixel), SIZE*sizeof(pixel), stride);\
-    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, halfV, halfHV, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\
-}\
-
-#define op_avg(a, b)  a = (((a)+CLIP(((b) + 16)>>5)+1)>>1)
-//#define op_avg2(a, b) a = (((a)*w1+cm[((b) + 16)>>5]*w2 + o + 64)>>7)
-#define op_put(a, b)  a = CLIP(((b) + 16)>>5)
-#define op2_avg(a, b)  a = (((a)+CLIP(((b) + 512)>>10)+1)>>1)
-#define op2_put(a, b)  a = CLIP(((b) + 512)>>10)
-
-H264_LOWPASS(put_       , op_put, op2_put)
-H264_LOWPASS(avg_       , op_avg, op2_avg)
-H264_MC(put_, 2)
-H264_MC(put_, 4)
-H264_MC(put_, 8)
-H264_MC(put_, 16)
-H264_MC(avg_, 4)
-H264_MC(avg_, 8)
-H264_MC(avg_, 16)
-
-#undef op_avg
-#undef op_put
-#undef op2_avg
-#undef op2_put
-
-#if BIT_DEPTH == 8
-#   define put_h264_qpel8_mc00_8_c  ff_put_pixels8x8_8_c
-#   define avg_h264_qpel8_mc00_8_c  ff_avg_pixels8x8_8_c
-#   define put_h264_qpel16_mc00_8_c ff_put_pixels16x16_8_c
-#   define avg_h264_qpel16_mc00_8_c ff_avg_pixels16x16_8_c
-#elif BIT_DEPTH == 9
-#   define put_h264_qpel8_mc00_9_c  ff_put_pixels8x8_9_c
-#   define avg_h264_qpel8_mc00_9_c  ff_avg_pixels8x8_9_c
-#   define put_h264_qpel16_mc00_9_c ff_put_pixels16x16_9_c
-#   define avg_h264_qpel16_mc00_9_c ff_avg_pixels16x16_9_c
-#elif BIT_DEPTH == 10
-#   define put_h264_qpel8_mc00_10_c  ff_put_pixels8x8_10_c
-#   define avg_h264_qpel8_mc00_10_c  ff_avg_pixels8x8_10_c
-#   define put_h264_qpel16_mc00_10_c ff_put_pixels16x16_10_c
-#   define avg_h264_qpel16_mc00_10_c ff_avg_pixels16x16_10_c
-#elif BIT_DEPTH == 12
-#   define put_h264_qpel8_mc00_12_c  ff_put_pixels8x8_12_c
-#   define avg_h264_qpel8_mc00_12_c  ff_avg_pixels8x8_12_c
-#   define put_h264_qpel16_mc00_12_c ff_put_pixels16x16_12_c
-#   define avg_h264_qpel16_mc00_12_c ff_avg_pixels16x16_12_c
-#elif BIT_DEPTH == 14
-#   define put_h264_qpel8_mc00_14_c  ff_put_pixels8x8_14_c
-#   define avg_h264_qpel8_mc00_14_c  ff_avg_pixels8x8_14_c
-#   define put_h264_qpel16_mc00_14_c ff_put_pixels16x16_14_c
-#   define avg_h264_qpel16_mc00_14_c ff_avg_pixels16x16_14_c
 #endif
+#undef op_avg
+#undef op_put
 
 void FUNCC(ff_put_pixels8x8)(uint8_t *dst, uint8_t *src, int stride) {
     FUNCC(put_pixels8)(dst, src, stride, 8);
diff --git a/libavcodec/dv.c b/libavcodec/dv.c
index 18c90c2..0812dbb 100644
--- a/libavcodec/dv.c
+++ b/libavcodec/dv.c
@@ -38,9 +38,9 @@
  * DV codec.
  */
 
+#include "libavutil/internal.h"
 #include "libavutil/pixdesc.h"
 #include "avcodec.h"
-#include "dsputil.h"
 #include "get_bits.h"
 #include "internal.h"
 #include "put_bits.h"
@@ -417,7 +417,7 @@
     int      cur_ac;
     int      cno;
     int      dct_mode;
-    DCTELEM  mb[64];
+    int16_t  mb[64];
     uint8_t  next[64];
     uint8_t  sign[64];
     uint8_t  partial_bit_count;
@@ -506,7 +506,7 @@
 {
     const int *weight;
     const uint8_t* zigzag_scan;
-    LOCAL_ALIGNED_16(DCTELEM, blk, [64]);
+    LOCAL_ALIGNED_16(int16_t, blk, [64]);
     int i, area;
     /* We offer two different methods for class number assignment: the
        method suggested in SMPTE 314M Table 22, and an improved
diff --git a/libavcodec/dv_profile.c b/libavcodec/dv_profile.c
index 05d4aba..a1d9881 100644
--- a/libavcodec/dv_profile.c
+++ b/libavcodec/dv_profile.c
@@ -298,7 +298,11 @@
         return &dv_profiles[2];
     }
 
-    if(stype == 0 && codec && codec->codec_tag==AV_RL32("dvsd") && codec->coded_width==720 && codec->coded_height==576)
+    if(   stype == 0
+       && codec
+       && (codec->codec_tag==AV_RL32("dvsd") || codec->codec_tag==AV_RL32("CDVC"))
+       && codec->coded_width ==720
+       && codec->coded_height==576)
         return &dv_profiles[1];
 
     for (i = 0; i < FF_ARRAY_ELEMS(dv_profiles); i++)
diff --git a/libavcodec/dvbsub_parser.c b/libavcodec/dvbsub_parser.c
index 5274fd6..d15c891 100644
--- a/libavcodec/dvbsub_parser.c
+++ b/libavcodec/dvbsub_parser.c
@@ -19,7 +19,6 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include "avcodec.h"
-#include "dsputil.h"
 #include "get_bits.h"
 
 /* Parser (mostly) copied from dvdsub.c */
diff --git a/libavcodec/dvdata.h b/libavcodec/dvdata.h
index b1fa44a..97c20e3 100644
--- a/libavcodec/dvdata.h
+++ b/libavcodec/dvdata.h
@@ -40,9 +40,9 @@
 
     uint8_t  dv_zigzag[2][64];
 
-    void (*get_pixels)(DCTELEM *block, const uint8_t *pixels, int line_size);
-    void (*fdct[2])(DCTELEM *block);
-    void (*idct_put[2])(uint8_t *dest, int line_size, DCTELEM *block);
+    void (*get_pixels)(int16_t *block, const uint8_t *pixels, int line_size);
+    void (*fdct[2])(int16_t *block);
+    void (*idct_put[2])(uint8_t *dest, int line_size, int16_t *block);
     me_cmp_func ildct_cmp;
 } DVVideoContext;
 
diff --git a/libavcodec/dvdec.c b/libavcodec/dvdec.c
index d3a1234..64d2259 100644
--- a/libavcodec/dvdec.c
+++ b/libavcodec/dvdec.c
@@ -36,9 +36,10 @@
  */
 
 #include "libavutil/avassert.h"
+#include "libavutil/internal.h"
 #include "libavutil/pixdesc.h"
 #include "avcodec.h"
-#include "dsputil.h"
+#include "internal.h"
 #include "get_bits.h"
 #include "put_bits.h"
 #include "simple_idct.h"
@@ -48,7 +49,7 @@
     const uint32_t *factor_table;
     const uint8_t *scan_table;
     uint8_t pos; /* position in block */
-    void (*idct_put)(uint8_t *dest, int line_size, DCTELEM *block);
+    void (*idct_put)(uint8_t *dest, int line_size, int16_t *block);
     uint8_t partial_bit_count;
     uint32_t partial_bit_buffer;
     int shift_offset;
@@ -57,7 +58,7 @@
 static const int dv_iweight_bits = 14;
 
 /* decode AC coefficients */
-static void dv_decode_ac(GetBitContext *gb, BlockInfo *mb, DCTELEM *block)
+static void dv_decode_ac(GetBitContext *gb, BlockInfo *mb, int16_t *block)
 {
     int last_index = gb->size_in_bits;
     const uint8_t  *scan_table   = mb->scan_table;
@@ -135,14 +136,14 @@
     int quant, dc, dct_mode, class1, j;
     int mb_index, mb_x, mb_y, last_index;
     int y_stride, linesize;
-    DCTELEM *block, *block1;
+    int16_t *block, *block1;
     int c_offset;
     uint8_t *y_ptr;
     const uint8_t *buf_ptr;
     PutBitContext pb, vs_pb;
     GetBitContext gb;
     BlockInfo mb_data[5 * DV_MAX_BPM], *mb, *mb1;
-    LOCAL_ALIGNED_16(DCTELEM, sblock, [5*DV_MAX_BPM], [64]);
+    LOCAL_ALIGNED_16(int16_t, sblock, [5*DV_MAX_BPM], [64]);
     LOCAL_ALIGNED_16(uint8_t, mb_bit_buffer, [  80 + FF_INPUT_BUFFER_PADDING_SIZE]); /* allow some slack */
     LOCAL_ALIGNED_16(uint8_t, vs_bit_buffer, [5*80 + FF_INPUT_BUFFER_PADDING_SIZE]); /* allow some slack */
     const int log2_blocksize = 3-s->avctx->lowres;
@@ -311,7 +312,7 @@
 /* NOTE: exactly one frame must be given (120000 bytes for NTSC,
    144000 bytes for PAL - or twice those for 50Mbps) */
 static int dvvideo_decode_frame(AVCodecContext *avctx,
-                                 void *data, int *data_size,
+                                 void *data, int *got_frame,
                                  AVPacket *avpkt)
 {
     uint8_t *buf = avpkt->data;
@@ -336,7 +337,7 @@
     avctx->pix_fmt   = s->sys->pix_fmt;
     avctx->time_base = s->sys->time_base;
     avcodec_set_dimensions(avctx, s->sys->width, s->sys->height);
-    if (avctx->get_buffer(avctx, &s->picture) < 0) {
+    if (ff_get_buffer(avctx, &s->picture) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return -1;
     }
@@ -359,7 +360,7 @@
     emms_c();
 
     /* return image */
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*)data = s->picture;
 
     return s->sys->frame_size;
diff --git a/libavcodec/dvdsubdec.c b/libavcodec/dvdsubdec.c
index 9c2dd8c..a5c90cd 100644
--- a/libavcodec/dvdsubdec.c
+++ b/libavcodec/dvdsubdec.c
@@ -22,13 +22,16 @@
 #include "get_bits.h"
 #include "dsputil.h"
 #include "libavutil/colorspace.h"
+#include "libavutil/opt.h"
 #include "libavutil/imgutils.h"
 
 //#define DEBUG
 
 typedef struct DVDSubContext
 {
+  AVClass *class;
   uint32_t palette[16];
+  char    *palette_str;
   int      has_palette;
   uint8_t  colormap[4];
   uint8_t  alpha[256];
@@ -124,8 +127,8 @@
     return 0;
 }
 
-static void guess_palette(uint32_t *rgba_palette,
-                          DVDSubContext* ctx,
+static void guess_palette(DVDSubContext* ctx,
+                          uint32_t *rgba_palette,
                           uint32_t subtitle_color)
 {
     static const uint8_t level_map[4][4] = {
@@ -143,7 +146,7 @@
     if(ctx->has_palette) {
         for(i = 0; i < 4; i++)
             rgba_palette[i] = (ctx->palette[colormap[i]] & 0x00ffffff)
-                              | ((alpha[i] * 17) << 24);
+                              | ((alpha[i] * 17U) << 24);
         return;
     }
 
@@ -348,7 +351,7 @@
                     yuv_a_to_rgba(yuv_palette, alpha, (uint32_t*)sub_header->rects[0]->pict.data[1], 256);
                 } else {
                     sub_header->rects[0]->nb_colors = 4;
-                    guess_palette((uint32_t*)sub_header->rects[0]->pict.data[1], ctx,
+                    guess_palette(ctx, (uint32_t*)sub_header->rects[0]->pict.data[1],
                                   0xffff00);
                 }
                 sub_header->rects[0]->x = x1;
@@ -484,7 +487,7 @@
                          void *data, int *data_size,
                          AVPacket *avpkt)
 {
-    DVDSubContext *ctx = (DVDSubContext*) avctx->priv_data;
+    DVDSubContext *ctx = avctx->priv_data;
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     AVSubtitle *sub = data;
@@ -513,7 +516,19 @@
     return buf_size;
 }
 
-static int dvdsub_init(AVCodecContext *avctx)
+static void parse_palette(DVDSubContext *ctx, char *p)
+{
+    int i;
+
+    ctx->has_palette = 1;
+    for(i=0;i<16;i++) {
+        ctx->palette[i] = strtoul(p, &p, 16);
+        while(*p == ',' || isspace(*p))
+            p++;
+    }
+}
+
+static int dvdsub_parse_extradata(AVCodecContext *avctx)
 {
     DVDSubContext *ctx = (DVDSubContext*) avctx->priv_data;
     char *dataorig, *data;
@@ -533,14 +548,7 @@
             break;
 
         if (strncmp("palette:", data, 8) == 0) {
-            int i;
-            char *p = data+8;
-            ctx->has_palette = 1;
-            for(i=0;i<16;i++) {
-                ctx->palette[i] = strtoul(p, &p, 16);
-                while(*p == ',' || isspace(*p))
-                    p++;
-            }
+            parse_palette(ctx, data + 8);
         } else if (strncmp("size:", data, 5) == 0) {
             int w, h;
             if (sscanf(data + 5, "%dx%d", &w, &h) == 2 &&
@@ -552,6 +560,20 @@
         data += strspn(data, "\n\r");
     }
 
+    av_free(dataorig);
+    return 1;
+}
+
+static int dvdsub_init(AVCodecContext *avctx)
+{
+    DVDSubContext *ctx = avctx->priv_data;
+    int ret;
+
+    if ((ret = dvdsub_parse_extradata(avctx)) < 0)
+        return ret;
+
+    if (ctx->palette_str)
+        parse_palette(ctx, ctx->palette_str);
     if (ctx->has_palette) {
         int i;
         av_log(avctx, AV_LOG_DEBUG, "palette:");
@@ -560,10 +582,22 @@
         av_log(avctx, AV_LOG_DEBUG, "\n");
     }
 
-    av_free(dataorig);
     return 1;
 }
 
+#define OFFSET(field) offsetof(DVDSubContext, field)
+#define VD AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_DECODING_PARAM
+static const AVOption options[] = {
+    { "palette", "set the global palette", OFFSET(palette_str), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, VD },
+    { NULL }
+};
+static const AVClass class = {
+    .class_name = "dvdsubdec",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 AVCodec ff_dvdsub_decoder = {
     .name           = "dvdsub",
     .type           = AVMEDIA_TYPE_SUBTITLE,
@@ -572,4 +606,5 @@
     .init           = dvdsub_init,
     .decode         = dvdsub_decode,
     .long_name      = NULL_IF_CONFIG_SMALL("DVD subtitles"),
+    .priv_class     = &class,
 };
diff --git a/libavcodec/dvdsubenc.c b/libavcodec/dvdsubenc.c
index 2e0c37d..6e19623 100644
--- a/libavcodec/dvdsubenc.c
+++ b/libavcodec/dvdsubenc.c
@@ -20,6 +20,7 @@
  */
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 #include "libavutil/avassert.h"
 #include "libavutil/bprint.h"
 #include "libavutil/imgutils.h"
@@ -93,10 +94,14 @@
 static int color_distance(uint32_t a, uint32_t b)
 {
     int r = 0, d, i;
+    int alpha_a = 8, alpha_b = 8;
 
-    for (i = 0; i < 32; i += 8) {
-        d = ((a >> i) & 0xFF) - ((b >> i) & 0xFF);
+    for (i = 24; i >= 0; i -= 8) {
+        d = alpha_a * (int)((a >> i) & 0xFF) -
+            alpha_b * (int)((b >> i) & 0xFF);
         r += d * d;
+        alpha_a = a >> 28;
+        alpha_b = b >> 28;
     }
     return r;
 }
@@ -129,7 +134,8 @@
         if (match) {
             best_d = INT_MAX;
             for (j = 0; j < 16; j++) {
-                d = color_distance(color & 0xFFFFFF, dvdc->global_palette[j]);
+                d = color_distance(0xFF000000 | color,
+                                   0xFF000000 | dvdc->global_palette[j]);
                 if (d < best_d) {
                     best_d = d;
                     best_j = j;
@@ -201,7 +207,7 @@
 
 static void build_color_map(AVCodecContext *avctx, int cmap[],
                             const uint32_t palette[],
-                            const int out_palette[], int const out_alpha[])
+                            const int out_palette[], unsigned int const out_alpha[])
 {
     DVDSubtitleContext *dvdc = avctx->priv_data;
     int i, j, d, best_d;
@@ -408,9 +414,9 @@
         av_bprintf(&extradata, " %06"PRIx32"%c",
                    dvdc->global_palette[i] & 0xFFFFFF, i < 15 ? ',' : '\n');
 
-    if ((ret = av_bprint_finalize(&extradata, (char **)&avctx->extradata)) < 0)
+    ret = avpriv_bprint_to_extradata(avctx, &extradata);
+    if (ret < 0)
         return ret;
-    avctx->extradata_size = extradata.len;
 
     return 0;
 }
diff --git a/libavcodec/dwt.h b/libavcodec/dwt.h
deleted file mode 100644
index d82e510..0000000
--- a/libavcodec/dwt.h
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Copyright (C) 2004-2010 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
- */
-
-#ifndef AVCODEC_DWT_H
-#define AVCODEC_DWT_H
-
-#include <stdint.h>
-
-typedef int DWTELEM;
-typedef short IDWTELEM;
-
-#define MAX_DWT_SUPPORT 8
-#define MAX_DECOMPOSITIONS 8
-
-typedef struct DWTCompose {
-    IDWTELEM *b[MAX_DWT_SUPPORT];
-
-    IDWTELEM *b0;
-    IDWTELEM *b1;
-    IDWTELEM *b2;
-    IDWTELEM *b3;
-    int y;
-} DWTCompose;
-
-/** Used to minimize the amount of memory used in order to
- *  optimize cache performance. **/
-typedef struct slice_buffer_s {
-    IDWTELEM **line;   ///< For use by idwt and predict_slices.
-    IDWTELEM **data_stack;   ///< Used for internal purposes.
-    int data_stack_top;
-    int line_count;
-    int line_width;
-    int data_count;
-    IDWTELEM *base_buffer;  ///< Buffer that this structure is caching.
-} slice_buffer;
-
-struct DWTContext;
-
-// Possible prototypes for vertical_compose functions
-typedef void (*vertical_compose_2tap)(IDWTELEM *b0, IDWTELEM *b1, int width);
-typedef void (*vertical_compose_3tap)(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width);
-typedef void (*vertical_compose_5tap)(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, IDWTELEM *b3, IDWTELEM *b4, int width);
-typedef void (*vertical_compose_9tap)(IDWTELEM *dst, IDWTELEM *b[8], int width);
-
-typedef struct DWTContext {
-    IDWTELEM *buffer;
-    IDWTELEM *temp;
-    int width;
-    int height;
-    int stride;
-    int decomposition_count;
-    int support;
-
-    void (*spatial_compose)(struct DWTContext *cs, int level, int width, int height, int stride);
-    void (*vertical_compose_l0)(void);
-    void (*vertical_compose_h0)(void);
-    void (*vertical_compose_l1)(void);
-    void (*vertical_compose_h1)(void);
-    void (*vertical_compose)(void);     ///< one set of lowpass and highpass combined
-    void (*horizontal_compose)(IDWTELEM *b, IDWTELEM *tmp, int width);
-
-    void (*vertical_compose97i)(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
-                                IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5,
-                                int width);
-    void (*horizontal_compose97i)(IDWTELEM *b, IDWTELEM *temp, int width);
-    void (*inner_add_yblock)(const uint8_t *obmc, const int obmc_stride,
-                             uint8_t **block, int b_w, int b_h, int src_x,
-                             int src_y, int src_stride, slice_buffer *sb,
-                             int add, uint8_t *dst8);
-
-    DWTCompose cs[MAX_DECOMPOSITIONS];
-} DWTContext;
-
-enum dwt_type {
-    DWT_SNOW_DAUB9_7,
-    DWT_SNOW_LEGALL5_3,
-    DWT_DIRAC_DD9_7,
-    DWT_DIRAC_LEGALL5_3,
-    DWT_DIRAC_DD13_7,
-    DWT_DIRAC_HAAR0,
-    DWT_DIRAC_HAAR1,
-    DWT_DIRAC_FIDELITY,
-    DWT_DIRAC_DAUB9_7,
-    DWT_NUM_TYPES
-};
-
-// -1 if an error occurred, e.g. the dwt_type isn't recognized
-int ff_spatial_idwt_init2(DWTContext *d, IDWTELEM *buffer, int width, int height,
-                          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
-#define COMPOSE_53iL0(b0, b1, b2)\
-    (b1 - ((b0 + b2 + 2) >> 2))
-
-#define COMPOSE_DIRAC53iH0(b0, b1, b2)\
-    (b1 + ((b0 + b2 + 1) >> 1))
-
-#define COMPOSE_DD97iH0(b0, b1, b2, b3, b4)\
-    (b2 + ((-b0 + 9*b1 + 9*b3 - b4 + 8) >> 4))
-
-#define COMPOSE_DD137iL0(b0, b1, b2, b3, b4)\
-    (b2 - ((-b0 + 9*b1 + 9*b3 - b4 + 16) >> 5))
-
-#define COMPOSE_HAARiL0(b0, b1)\
-    (b0 - ((b1 + 1) >> 1))
-
-#define COMPOSE_HAARiH0(b0, b1)\
-    (b0 + b1)
-
-#define COMPOSE_FIDELITYiL0(b0, b1, b2, b3, b4, b5, b6, b7, b8)\
-    (b4 - ((-8*(b0+b8) + 21*(b1+b7) - 46*(b2+b6) + 161*(b3+b5) + 128) >> 8))
-
-#define COMPOSE_FIDELITYiH0(b0, b1, b2, b3, b4, b5, b6, b7, b8)\
-    (b4 + ((-2*(b0+b8) + 10*(b1+b7) - 25*(b2+b6) + 81*(b3+b5) + 128) >> 8))
-
-#define COMPOSE_DAUB97iL1(b0, b1, b2)\
-    (b1 - ((1817*(b0 + b2) + 2048) >> 12))
-
-#define COMPOSE_DAUB97iH1(b0, b1, b2)\
-    (b1 - (( 113*(b0 + b2) + 64) >> 7))
-
-#define COMPOSE_DAUB97iL0(b0, b1, b2)\
-    (b1 + (( 217*(b0 + b2) + 2048) >> 12))
-
-#define COMPOSE_DAUB97iH0(b0, b1, b2)\
-    (b1 + ((6497*(b0 + b2) + 2048) >> 12))
-
-
-
-#define DWT_97 0
-#define DWT_53 1
-
-#define liftS lift
-#define W_AM 3
-#define W_AO 0
-#define W_AS 1
-
-#undef liftS
-#define W_BM 1
-#define W_BO 8
-#define W_BS 4
-
-#define W_CM 1
-#define W_CO 0
-#define W_CS 0
-
-#define W_DM 3
-#define W_DO 4
-#define W_DS 3
-
-#define slice_buffer_get_line(slice_buf, line_num)                          \
-    ((slice_buf)->line[line_num] ? (slice_buf)->line[line_num]              \
-                                 : ff_slice_buffer_load_line((slice_buf),   \
-                                                             (line_num)))
-
-int ff_slice_buffer_init(slice_buffer *buf, int line_count,
-                         int max_allocated_lines, int line_width,
-                         IDWTELEM *base_buffer);
-void ff_slice_buffer_release(slice_buffer *buf, int line);
-void ff_slice_buffer_flush(slice_buffer *buf);
-void ff_slice_buffer_destroy(slice_buffer *buf);
-IDWTELEM *ff_slice_buffer_load_line(slice_buffer *buf, int line);
-
-void ff_snow_vertical_compose97i(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
-                                 IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5,
-                                 int width);
-void ff_snow_horizontal_compose97i(IDWTELEM *b, IDWTELEM *temp, int width);
-void ff_snow_inner_add_yblock(const uint8_t *obmc, const int obmc_stride,
-                              uint8_t **block, int b_w, int b_h, int src_x,
-                              int src_y, int src_stride, slice_buffer *sb,
-                              int add, uint8_t *dst8);
-
-int ff_w53_32_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h);
-int ff_w97_32_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h);
-
-void ff_spatial_dwt(int *buffer, int *temp, int width, int height, int stride,
-                    int type, int decomposition_count);
-
-void ff_spatial_idwt_buffered_init(DWTCompose *cs, slice_buffer *sb, int width,
-                                   int height, int stride_line, int type,
-                                   int decomposition_count);
-void ff_spatial_idwt_buffered_slice(DWTContext *dsp, DWTCompose *cs,
-                                    slice_buffer *slice_buf, IDWTELEM *temp,
-                                    int width, int height, int stride_line,
-                                    int type, int decomposition_count, int y);
-void ff_spatial_idwt(IDWTELEM *buffer, IDWTELEM *temp, int width, int height,
-                     int stride, int type, int decomposition_count);
-
-void ff_dwt_init(DWTContext *c);
-void ff_dwt_init_x86(DWTContext *c);
-
-#endif /* AVCODEC_DWT_H */
diff --git a/libavcodec/dxa.c b/libavcodec/dxa.c
index cf8ce0c..a2fe557 100644
--- a/libavcodec/dxa.c
+++ b/libavcodec/dxa.c
@@ -29,7 +29,9 @@
 
 #include "libavutil/common.h"
 #include "libavutil/intreadwrite.h"
+#include "bytestream.h"
 #include "avcodec.h"
+#include "internal.h"
 
 #include <zlib.h>
 
@@ -179,7 +181,7 @@
                 break;
             default:
                 av_log(avctx, AV_LOG_ERROR, "Unknown opcode %d\n", type);
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
         }
         dst += stride * 4;
@@ -188,36 +190,30 @@
     return 0;
 }
 
-static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt)
+static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
 {
-    const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
     DxaDecContext * const c = avctx->priv_data;
     uint8_t *outptr, *srcptr, *tmpptr;
     unsigned long dsize;
-    int i, j, compr;
+    int i, j, compr, ret;
     int stride;
-    int orig_buf_size = buf_size;
     int pc = 0;
+    GetByteContext gb;
+
+    bytestream2_init(&gb, avpkt->data, avpkt->size);
 
     /* make the palette available on the way out */
-    if(buf[0]=='C' && buf[1]=='M' && buf[2]=='A' && buf[3]=='P'){
-        int r, g, b;
-
-        buf += 4;
+    if (bytestream2_peek_le32(&gb) == MKTAG('C','M','A','P')) {
+        bytestream2_skip(&gb, 4);
         for(i = 0; i < 256; i++){
-            r = *buf++;
-            g = *buf++;
-            b = *buf++;
-            c->pal[i] = 0xFFU << 24 | r << 16 | g << 8 | b;
+            c->pal[i] = 0xFFU << 24 | bytestream2_get_be24(&gb);
         }
         pc = 1;
-        buf_size -= 768+4;
     }
 
-    if(avctx->get_buffer(avctx, &c->pic) < 0){
+    if ((ret = ff_get_buffer(avctx, &c->pic)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
     memcpy(c->pic.data[1], c->pal, AVPALETTE_SIZE);
     c->pic.palette_has_changed = pc;
@@ -227,15 +223,19 @@
     tmpptr = c->prev.data[0];
     stride = c->pic.linesize[0];
 
-    if(buf[0]=='N' && buf[1]=='U' && buf[2]=='L' && buf[3]=='L')
+    if (bytestream2_get_le32(&gb) == MKTAG('N','U','L','L'))
         compr = -1;
     else
-        compr = buf[4];
+        compr = bytestream2_get_byte(&gb);
 
     dsize = c->dsize;
-    if((compr != 4 && compr != -1) && uncompress(c->decomp_buf, &dsize, buf + 9, buf_size - 9) != Z_OK){
-        av_log(avctx, AV_LOG_ERROR, "Uncompress failed!\n");
-        return -1;
+    if (compr != 4 && compr != -1) {
+        bytestream2_skip(&gb, 4);
+        if (uncompress(c->decomp_buf, &dsize, avpkt->data + bytestream2_tell(&gb),
+                       bytestream2_get_bytes_left(&gb)) != Z_OK) {
+            av_log(avctx, AV_LOG_ERROR, "Uncompress failed!\n");
+            return AVERROR_UNKNOWN;
+        }
     }
     switch(compr){
     case -1:
@@ -277,19 +277,19 @@
         decode_13(avctx, c, c->pic.data[0], srcptr, c->prev.data[0]);
         break;
     default:
-        av_log(avctx, AV_LOG_ERROR, "Unknown/unsupported compression type %d\n", buf[4]);
-        return -1;
+        av_log(avctx, AV_LOG_ERROR, "Unknown/unsupported compression type %d\n", compr);
+        return AVERROR_INVALIDDATA;
     }
 
     FFSWAP(AVFrame, c->pic, c->prev);
     if(c->pic.data[0])
         avctx->release_buffer(avctx, &c->pic);
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*)data = c->prev;
 
     /* always report that the buffer was completely consumed */
-    return orig_buf_size;
+    return avpkt->size;
 }
 
 static av_cold int decode_init(AVCodecContext *avctx)
@@ -302,9 +302,10 @@
     avcodec_get_frame_defaults(&c->prev);
 
     c->dsize = avctx->width * avctx->height * 2;
-    if((c->decomp_buf = av_malloc(c->dsize)) == NULL) {
+    c->decomp_buf = av_malloc(c->dsize);
+    if (!c->decomp_buf) {
         av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");
-        return -1;
+        return AVERROR(ENOMEM);
     }
 
     return 0;
diff --git a/libavcodec/dxtory.c b/libavcodec/dxtory.c
index da43c47..30983f8 100644
--- a/libavcodec/dxtory.c
+++ b/libavcodec/dxtory.c
@@ -21,6 +21,7 @@
  */
 
 #include "avcodec.h"
+#include "internal.h"
 #include "libavutil/common.h"
 #include "libavutil/intreadwrite.h"
 
@@ -34,7 +35,7 @@
     return 0;
 }
 
-static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         AVPacket *avpkt)
 {
     int h, w;
@@ -52,7 +53,7 @@
     }
 
     pic->reference = 0;
-    if ((ret = avctx->get_buffer(avctx, pic)) < 0)
+    if ((ret = ff_get_buffer(avctx, pic)) < 0)
         return ret;
 
     pic->pict_type = AV_PICTURE_TYPE_I;
@@ -82,7 +83,7 @@
         V  += pic->linesize[2];
     }
 
-    *data_size      = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*)data = *pic;
 
     return avpkt->size;
diff --git a/libavcodec/dxva2.c b/libavcodec/dxva2.c
index d866071..0997c73 100644
--- a/libavcodec/dxva2.c
+++ b/libavcodec/dxva2.c
@@ -76,7 +76,7 @@
     return result;
 }
 
-int ff_dxva2_common_end_frame(AVCodecContext *avctx, MpegEncContext *s,
+int ff_dxva2_common_end_frame(AVCodecContext *avctx, Picture *pic,
                               const void *pp, unsigned pp_size,
                               const void *qm, unsigned qm_size,
                               int (*commit_bs_si)(AVCodecContext *,
@@ -90,7 +90,7 @@
     int      result;
 
     if (FAILED(IDirectXVideoDecoder_BeginFrame(ctx->decoder,
-                                               ff_dxva2_get_surface(s->current_picture_ptr),
+                                               ff_dxva2_get_surface(pic),
                                                NULL))) {
         av_log(avctx, AV_LOG_ERROR, "Failed to begin frame\n");
         return -1;
@@ -146,7 +146,5 @@
         result = -1;
     }
 
-    if (!result)
-        ff_draw_horiz_band(s, 0, s->avctx->height);
     return result;
 }
diff --git a/libavcodec/dxva2.h b/libavcodec/dxva2.h
index 7d27ca5..ac39e06 100644
--- a/libavcodec/dxva2.h
+++ b/libavcodec/dxva2.h
@@ -29,8 +29,15 @@
  * Public libavcodec DXVA2 header.
  */
 
-#include <stdint.h>
+#if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0600
+#undef _WIN32_WINNT
+#endif
 
+#if !defined(_WIN32_WINNT)
+#define _WIN32_WINNT 0x0600
+#endif
+
+#include <stdint.h>
 #include <d3d9.h>
 #include <dxva2api.h>
 
diff --git a/libavcodec/dxva2_h264.c b/libavcodec/dxva2_h264.c
index f7d4e5d..ce9e3ff 100644
--- a/libavcodec/dxva2_h264.c
+++ b/libavcodec/dxva2_h264.c
@@ -44,15 +44,14 @@
 static void fill_picture_parameters(struct dxva_context *ctx, const H264Context *h,
                                     DXVA_PicParams_H264 *pp)
 {
-    const MpegEncContext *s = &h->s;
-    const Picture *current_picture = s->current_picture_ptr;
+    const Picture *current_picture = h->cur_pic_ptr;
     int i, j;
 
     memset(pp, 0, sizeof(*pp));
     /* Configure current picture */
     fill_picture_entry(&pp->CurrPic,
                        ff_dxva2_get_surface_index(ctx, current_picture),
-                       s->picture_structure == PICT_BOTTOM_FIELD);
+                       h->picture_structure == PICT_BOTTOM_FIELD);
     /* Configure the set of references */
     pp->UsedForReferenceFlags  = 0;
     pp->NonExistingFrameFlags  = 0;
@@ -88,13 +87,13 @@
         }
     }
 
-    pp->wFrameWidthInMbsMinus1        = s->mb_width  - 1;
-    pp->wFrameHeightInMbsMinus1       = s->mb_height - 1;
+    pp->wFrameWidthInMbsMinus1        = h->mb_width  - 1;
+    pp->wFrameHeightInMbsMinus1       = h->mb_height - 1;
     pp->num_ref_frames                = h->sps.ref_frame_count;
 
-    pp->wBitFields                    = ((s->picture_structure != PICT_FRAME) <<  0) |
+    pp->wBitFields                    = ((h->picture_structure != PICT_FRAME) <<  0) |
                                         ((h->sps.mb_aff &&
-                                        (s->picture_structure == PICT_FRAME)) <<  1) |
+                                        (h->picture_structure == PICT_FRAME)) <<  1) |
                                         (h->sps.residual_color_transform_flag <<  2) |
                                         /* sp_for_switch_flag (not implemented by FFmpeg) */
                                         (0                                    <<  3) |
@@ -120,11 +119,11 @@
         pp->Reserved16Bits            = 3; /* FIXME is there a way to detect the right mode ? */
     pp->StatusReportFeedbackNumber    = 1 + ctx->report_id++;
     pp->CurrFieldOrderCnt[0] = 0;
-    if ((s->picture_structure & PICT_TOP_FIELD) &&
+    if ((h->picture_structure & PICT_TOP_FIELD) &&
         current_picture->field_poc[0] != INT_MAX)
         pp->CurrFieldOrderCnt[0] = current_picture->field_poc[0];
     pp->CurrFieldOrderCnt[1] = 0;
-    if ((s->picture_structure & PICT_BOTTOM_FIELD) &&
+    if ((h->picture_structure & PICT_BOTTOM_FIELD) &&
         current_picture->field_poc[1] != INT_MAX)
         pp->CurrFieldOrderCnt[1] = current_picture->field_poc[1];
     pp->pic_init_qs_minus26           = h->pps.init_qs - 26;
@@ -200,7 +199,6 @@
 {
     const H264Context *h = avctx->priv_data;
     struct dxva_context *ctx = avctx->hwaccel_context;
-    const MpegEncContext *s = &h->s;
     unsigned list;
 
     memset(slice, 0, sizeof(*slice));
@@ -208,9 +206,9 @@
     slice->SliceBytesInBuffer    = size;
     slice->wBadSliceChopping     = 0;
 
-    slice->first_mb_in_slice     = (s->mb_y >> FIELD_OR_MBAFF_PICTURE) * s->mb_width + s->mb_x;
+    slice->first_mb_in_slice     = (h->mb_y >> FIELD_OR_MBAFF_PICTURE) * h->mb_width + h->mb_x;
     slice->NumMbsForSlice        = 0; /* XXX it is set once we have all slices */
-    slice->BitOffsetToSliceData  = get_bits_count(&s->gb);
+    slice->BitOffsetToSliceData  = get_bits_count(&h->gb);
     slice->slice_type            = ff_h264_get_slice_type(h);
     if (h->slice_type_fixed)
         slice->slice_type += 5;
@@ -260,7 +258,7 @@
         }
     }
     slice->slice_qs_delta    = 0; /* XXX not implemented by FFmpeg */
-    slice->slice_qp_delta    = s->qscale - h->pps.init_qp;
+    slice->slice_qp_delta    = h->qscale - h->pps.init_qp;
     slice->redundant_pic_cnt = h->redundant_pic_count;
     if (h->slice_type == AV_PICTURE_TYPE_B)
         slice->direct_spatial_mv_pred_flag = h->direct_spatial_mv_pred;
@@ -277,10 +275,9 @@
                                              DXVA2_DecodeBufferDesc *sc)
 {
     const H264Context *h = avctx->priv_data;
-    const MpegEncContext *s = &h->s;
-    const unsigned mb_count = s->mb_width * s->mb_height;
+    const unsigned mb_count = h->mb_width * h->mb_height;
     struct dxva_context *ctx = avctx->hwaccel_context;
-    const Picture *current_picture = h->s.current_picture_ptr;
+    const Picture *current_picture = h->cur_pic_ptr;
     struct dxva2_picture_context *ctx_pic = current_picture->f.hwaccel_picture_private;
     DXVA_Slice_H264_Short *slice = NULL;
     uint8_t  *dxva_data, *current, *end;
@@ -376,7 +373,7 @@
 {
     const H264Context *h = avctx->priv_data;
     struct dxva_context *ctx = avctx->hwaccel_context;
-    struct dxva2_picture_context *ctx_pic = h->s.current_picture_ptr->f.hwaccel_picture_private;
+    struct dxva2_picture_context *ctx_pic = h->cur_pic_ptr->f.hwaccel_picture_private;
 
     if (!ctx->decoder || !ctx->cfg || ctx->surface_count <= 0)
         return -1;
@@ -399,7 +396,7 @@
 {
     const H264Context *h = avctx->priv_data;
     struct dxva_context *ctx = avctx->hwaccel_context;
-    const Picture *current_picture = h->s.current_picture_ptr;
+    const Picture *current_picture = h->cur_pic_ptr;
     struct dxva2_picture_context *ctx_pic = current_picture->f.hwaccel_picture_private;
     unsigned position;
 
@@ -427,16 +424,19 @@
 static int end_frame(AVCodecContext *avctx)
 {
     H264Context *h = avctx->priv_data;
-    MpegEncContext *s = &h->s;
     struct dxva2_picture_context *ctx_pic =
-        h->s.current_picture_ptr->f.hwaccel_picture_private;
+        h->cur_pic_ptr->f.hwaccel_picture_private;
+    int ret;
 
     if (ctx_pic->slice_count <= 0 || ctx_pic->bitstream_size <= 0)
         return -1;
-    return ff_dxva2_common_end_frame(avctx, s,
-                                     &ctx_pic->pp, sizeof(ctx_pic->pp),
-                                     &ctx_pic->qm, sizeof(ctx_pic->qm),
-                                     commit_bitstream_and_slice_buffer);
+    ret = ff_dxva2_common_end_frame(avctx, h->cur_pic_ptr,
+                                    &ctx_pic->pp, sizeof(ctx_pic->pp),
+                                    &ctx_pic->qm, sizeof(ctx_pic->qm),
+                                    commit_bitstream_and_slice_buffer);
+    if (!ret)
+        ff_h264_draw_horiz_band(h, 0, h->avctx->height);
+    return ret;
 }
 
 AVHWAccel ff_h264_dxva2_hwaccel = {
diff --git a/libavcodec/dxva2_internal.h b/libavcodec/dxva2_internal.h
index fcf45bc..8a454c1 100644
--- a/libavcodec/dxva2_internal.h
+++ b/libavcodec/dxva2_internal.h
@@ -23,7 +23,6 @@
 #ifndef AVCODEC_DXVA_INTERNAL_H
 #define AVCODEC_DXVA_INTERNAL_H
 
-#define _WIN32_WINNT 0x0600
 #define COBJMACROS
 
 #include "config.h"
@@ -47,7 +46,7 @@
                            unsigned mb_count);
 
 
-int ff_dxva2_common_end_frame(AVCodecContext *, MpegEncContext *,
+int ff_dxva2_common_end_frame(AVCodecContext *, Picture *,
                               const void *pp, unsigned pp_size,
                               const void *qm, unsigned qm_size,
                               int (*commit_bs_si)(AVCodecContext *,
diff --git a/libavcodec/dxva2_mpeg2.c b/libavcodec/dxva2_mpeg2.c
index f050ed9..2c012a7 100644
--- a/libavcodec/dxva2_mpeg2.c
+++ b/libavcodec/dxva2_mpeg2.c
@@ -251,13 +251,17 @@
     struct MpegEncContext *s = avctx->priv_data;
     struct dxva2_picture_context *ctx_pic =
         s->current_picture_ptr->f.hwaccel_picture_private;
+    int ret;
 
     if (ctx_pic->slice_count <= 0 || ctx_pic->bitstream_size <= 0)
         return -1;
-    return ff_dxva2_common_end_frame(avctx, s,
-                                     &ctx_pic->pp, sizeof(ctx_pic->pp),
-                                     &ctx_pic->qm, sizeof(ctx_pic->qm),
-                                     commit_bitstream_and_slice_buffer);
+    ret = ff_dxva2_common_end_frame(avctx, s->current_picture_ptr,
+                                    &ctx_pic->pp, sizeof(ctx_pic->pp),
+                                    &ctx_pic->qm, sizeof(ctx_pic->qm),
+                                    commit_bitstream_and_slice_buffer);
+    if (!ret)
+        ff_mpeg_draw_horiz_band(s, 0, avctx->height);
+    return ret;
 }
 
 AVHWAccel ff_mpeg2_dxva2_hwaccel = {
diff --git a/libavcodec/dxva2_vc1.c b/libavcodec/dxva2_vc1.c
index ed4836d..cba685d 100644
--- a/libavcodec/dxva2_vc1.c
+++ b/libavcodec/dxva2_vc1.c
@@ -257,14 +257,18 @@
 {
     VC1Context *v = avctx->priv_data;
     struct dxva2_picture_context *ctx_pic = v->s.current_picture_ptr->f.hwaccel_picture_private;
+    int ret;
 
     if (ctx_pic->bitstream_size <= 0)
         return -1;
 
-    return ff_dxva2_common_end_frame(avctx, &v->s,
-                                     &ctx_pic->pp, sizeof(ctx_pic->pp),
-                                     NULL, 0,
-                                     commit_bitstream_and_slice_buffer);
+    ret = ff_dxva2_common_end_frame(avctx, v->s.current_picture_ptr,
+                                    &ctx_pic->pp, sizeof(ctx_pic->pp),
+                                    NULL, 0,
+                                    commit_bitstream_and_slice_buffer);
+    if (!ret)
+        ff_mpeg_draw_horiz_band(&v->s, 0, avctx->height);
+    return ret;
 }
 
 #if CONFIG_WMV3_DXVA2_HWACCEL
diff --git a/libavcodec/eacmv.c b/libavcodec/eacmv.c
index d3de7ca..33c6145 100644
--- a/libavcodec/eacmv.c
+++ b/libavcodec/eacmv.c
@@ -32,6 +32,7 @@
 #include "libavutil/intreadwrite.h"
 #include "libavutil/imgutils.h"
 #include "avcodec.h"
+#include "internal.h"
 
 typedef struct CmvContext {
     AVCodecContext *avctx;
@@ -131,8 +132,13 @@
 
     s->width  = AV_RL16(&buf[4]);
     s->height = AV_RL16(&buf[6]);
-    if (s->avctx->width!=s->width || s->avctx->height!=s->height)
+    if (s->avctx->width!=s->width || s->avctx->height!=s->height) {
         avcodec_set_dimensions(s->avctx, s->width, s->height);
+        if (s->frame.data[0])
+            s->avctx->release_buffer(s->avctx, &s->frame);
+        if (s->last_frame.data[0])
+            s->avctx->release_buffer(s->avctx, &s->last_frame);
+    }
 
     s->avctx->time_base.num = 1;
     s->avctx->time_base.den = AV_RL16(&buf[10]);
@@ -151,7 +157,7 @@
 #define MVIh_TAG MKTAG('M', 'V', 'I', 'h')
 
 static int cmv_decode_frame(AVCodecContext *avctx,
-                            void *data, int *data_size,
+                            void *data, int *got_frame,
                             AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
@@ -183,7 +189,7 @@
     s->frame.buffer_hints = FF_BUFFER_HINTS_VALID |
                             FF_BUFFER_HINTS_READABLE |
                             FF_BUFFER_HINTS_PRESERVE;
-    if (avctx->get_buffer(avctx, &s->frame)<0) {
+    if (ff_get_buffer(avctx, &s->frame)<0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return -1;
     }
@@ -201,7 +207,7 @@
         cmv_decode_intra(s, buf+2, buf_end);
     }
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*)data = s->frame;
 
     return buf_size;
diff --git a/libavcodec/eaidct.c b/libavcodec/eaidct.c
index 175c1c4..e4840f2 100644
--- a/libavcodec/eaidct.c
+++ b/libavcodec/eaidct.c
@@ -25,7 +25,6 @@
  * @author Peter Ross <pross@xvid.org>
  */
 
-#include "dsputil.h"
 #include "eaidct.h"
 #include "libavutil/common.h"
 
@@ -64,7 +63,7 @@
 #define MUNGE_8BIT(x) av_clip_uint8((x)>>4)
 #define IDCT_ROW(dest,src) IDCT_TRANSFORM(dest,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,MUNGE_8BIT,src)
 
-static inline void ea_idct_col(DCTELEM *dest, const DCTELEM *src) {
+static inline void ea_idct_col(int16_t *dest, const int16_t *src) {
     if ((src[8]|src[16]|src[24]|src[32]|src[40]|src[48]|src[56])==0) {
         dest[0]  =
         dest[8]  =
@@ -78,9 +77,9 @@
         IDCT_COL(dest, src);
 }
 
-void ff_ea_idct_put_c(uint8_t *dest, int linesize, DCTELEM *block) {
+void ff_ea_idct_put_c(uint8_t *dest, int linesize, int16_t *block) {
     int i;
-    DCTELEM temp[64];
+    int16_t temp[64];
     block[0] += 4;
     for (i=0; i<8; i++)
         ea_idct_col(&temp[i], &block[i]);
diff --git a/libavcodec/eaidct.h b/libavcodec/eaidct.h
index a436673..6b9ec1c 100644
--- a/libavcodec/eaidct.h
+++ b/libavcodec/eaidct.h
@@ -20,8 +20,7 @@
 #define AVCODEC_EAIDCT_H
 
 #include <stdint.h>
-#include "dsputil.h"
 
-void ff_ea_idct_put_c(uint8_t *dest, int linesize, DCTELEM *block);
+void ff_ea_idct_put_c(uint8_t *dest, int linesize, int16_t *block);
 
 #endif /* AVCODEC_EAIDCT_H */
diff --git a/libavcodec/eamad.c b/libavcodec/eamad.c
index 0dad58b..b9679bc 100644
--- a/libavcodec/eamad.c
+++ b/libavcodec/eamad.c
@@ -30,9 +30,9 @@
 
 #include "avcodec.h"
 #include "get_bits.h"
-#include "dsputil.h"
 #include "aandcttab.h"
 #include "eaidct.h"
+#include "internal.h"
 #include "mpeg12.h"
 #include "mpeg12data.h"
 #include "libavutil/imgutils.h"
@@ -50,7 +50,7 @@
     GetBitContext gb;
     void *bitstream_buf;
     unsigned int bitstream_buf_size;
-    DECLARE_ALIGNED(16, DCTELEM, block)[64];
+    DECLARE_ALIGNED(16, int16_t, block)[64];
     ScanTable scantable;
     uint16_t quant_matrix[64];
     int mb_x;
@@ -101,7 +101,7 @@
     }
 }
 
-static inline void idct_put(MadContext *t, DCTELEM *block, int mb_x, int mb_y, int j)
+static inline void idct_put(MadContext *t, int16_t *block, int mb_x, int mb_y, int j)
 {
     if (j < 4) {
         ff_ea_idct_put_c(
@@ -115,7 +115,7 @@
     }
 }
 
-static inline int decode_block_intra(MadContext *s, DCTELEM * block)
+static inline int decode_block_intra(MadContext *s, int16_t * block)
 {
     int level, i, j, run;
     RLTable *rl = &ff_rl_mpeg1;
@@ -226,7 +226,7 @@
 }
 
 static int decode_frame(AVCodecContext *avctx,
-                        void *data, int *data_size,
+                        void *data, int *got_frame,
                         AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
@@ -239,7 +239,7 @@
 
     if (buf_size < 26) {
         av_log(avctx, AV_LOG_ERROR, "Input buffer too small\n");
-        *data_size = 0;
+        *got_frame = 0;
         return AVERROR_INVALIDDATA;
     }
 
@@ -269,13 +269,14 @@
 
     s->frame.reference = 3;
     if (!s->frame.data[0]) {
-        if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+        if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
             return ret;
         }
     }
 
-    av_fast_malloc(&s->bitstream_buf, &s->bitstream_buf_size, (buf_end-buf) + FF_INPUT_BUFFER_PADDING_SIZE);
+    av_fast_padded_malloc(&s->bitstream_buf, &s->bitstream_buf_size,
+                          buf_end - buf);
     if (!s->bitstream_buf)
         return AVERROR(ENOMEM);
     s->dsp.bswap16_buf(s->bitstream_buf, (const uint16_t*)buf, (buf_end-buf)/2);
@@ -287,7 +288,7 @@
             if(decode_mb(s, inter) < 0)
                 return AVERROR_INVALIDDATA;
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*)data = s->frame;
 
     if (chunk_type != MADe_TAG)
diff --git a/libavcodec/eatgq.c b/libavcodec/eatgq.c
index f8d9010..524798b 100644
--- a/libavcodec/eatgq.c
+++ b/libavcodec/eatgq.c
@@ -35,141 +35,146 @@
 #include "dsputil.h"
 #include "aandcttab.h"
 #include "eaidct.h"
+#include "internal.h"
 
 typedef struct TgqContext {
     AVCodecContext *avctx;
     AVFrame frame;
-    int width,height;
+    int width, height;
     ScanTable scantable;
     int qtable[64];
-    DECLARE_ALIGNED(16, DCTELEM, block)[6][64];
+    DECLARE_ALIGNED(16, int16_t, block)[6][64];
     GetByteContext gb;
 } TgqContext;
 
-static av_cold int tgq_decode_init(AVCodecContext *avctx){
+static av_cold int tgq_decode_init(AVCodecContext *avctx)
+{
     TgqContext *s = avctx->priv_data;
     uint8_t idct_permutation[64];
     s->avctx = avctx;
     ff_init_scantable_permutation(idct_permutation, FF_NO_IDCT_PERM);
     ff_init_scantable(idct_permutation, &s->scantable, ff_zigzag_direct);
     avctx->time_base = (AVRational){1, 15};
-    avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+    avctx->pix_fmt   = AV_PIX_FMT_YUV420P;
     return 0;
 }
 
-static void tgq_decode_block(TgqContext *s, DCTELEM block[64], GetBitContext *gb){
+static void tgq_decode_block(TgqContext *s, int16_t block[64], GetBitContext *gb)
+{
     uint8_t *perm = s->scantable.permutated;
-    int i,j,value;
-    block[0] = get_sbits(gb,8) * s->qtable[0];
-    for(i=1; i<64; ) {
-        switch(show_bits(gb,3)) {
+    int i, j, value;
+    block[0] = get_sbits(gb, 8) * s->qtable[0];
+    for (i = 1; i < 64;) {
+        switch (show_bits(gb, 3)) {
         case 4:
             block[perm[i++]] = 0;
         case 0:
             block[perm[i++]] = 0;
-            skip_bits(gb,3);
+            skip_bits(gb, 3);
             break;
         case 5:
         case 1:
-            skip_bits(gb,2);
-            value = get_bits(gb,6);
-            for(j=0; j<value; j++)
+            skip_bits(gb, 2);
+            value = get_bits(gb, 6);
+            for (j = 0; j < value; j++)
                 block[perm[i++]] = 0;
             break;
         case 6:
-            skip_bits(gb,3);
+            skip_bits(gb, 3);
             block[perm[i]] = -s->qtable[perm[i]];
             i++;
             break;
         case 2:
-            skip_bits(gb,3);
+            skip_bits(gb, 3);
             block[perm[i]] = s->qtable[perm[i]];
             i++;
             break;
         case 7: // 111b
         case 3: // 011b
-            skip_bits(gb,2);
-            if (show_bits(gb,6)==0x3F) {
+            skip_bits(gb, 2);
+            if (show_bits(gb, 6) == 0x3F) {
                 skip_bits(gb, 6);
-                block[perm[i]] = get_sbits(gb,8)*s->qtable[perm[i]];
-            }else{
-                block[perm[i]] = get_sbits(gb,6)*s->qtable[perm[i]];
+                block[perm[i]] = get_sbits(gb, 8) * s->qtable[perm[i]];
+            } else {
+                block[perm[i]] = get_sbits(gb, 6) * s->qtable[perm[i]];
             }
             i++;
             break;
         }
     }
-    block[0] += 128<<4;
+    block[0] += 128 << 4;
 }
 
-static void tgq_idct_put_mb(TgqContext *s, DCTELEM (*block)[64], int mb_x, int mb_y){
-    int linesize= s->frame.linesize[0];
-    uint8_t *dest_y  = s->frame.data[0] + (mb_y * 16* linesize            ) + mb_x * 16;
-    uint8_t *dest_cb = s->frame.data[1] + (mb_y * 8 * s->frame.linesize[1]) + mb_x * 8;
-    uint8_t *dest_cr = s->frame.data[2] + (mb_y * 8 * s->frame.linesize[2]) + mb_x * 8;
+static void tgq_idct_put_mb(TgqContext *s, int16_t (*block)[64],
+                            int mb_x, int mb_y)
+{
+    int linesize = s->frame.linesize[0];
+    uint8_t *dest_y  = s->frame.data[0] + (mb_y * 16 * linesize)             + mb_x * 16;
+    uint8_t *dest_cb = s->frame.data[1] + (mb_y * 8  * s->frame.linesize[1]) + mb_x * 8;
+    uint8_t *dest_cr = s->frame.data[2] + (mb_y * 8  * s->frame.linesize[2]) + mb_x * 8;
 
-    ff_ea_idct_put_c(dest_y                 , linesize, block[0]);
-    ff_ea_idct_put_c(dest_y              + 8, linesize, block[1]);
-    ff_ea_idct_put_c(dest_y + 8*linesize    , linesize, block[2]);
-    ff_ea_idct_put_c(dest_y + 8*linesize + 8, linesize, block[3]);
-    if(!(s->avctx->flags&CODEC_FLAG_GRAY)){
+    ff_ea_idct_put_c(dest_y                   , linesize, block[0]);
+    ff_ea_idct_put_c(dest_y                + 8, linesize, block[1]);
+    ff_ea_idct_put_c(dest_y + 8 * linesize    , linesize, block[2]);
+    ff_ea_idct_put_c(dest_y + 8 * linesize + 8, linesize, block[3]);
+    if (!(s->avctx->flags & CODEC_FLAG_GRAY)) {
          ff_ea_idct_put_c(dest_cb, s->frame.linesize[1], block[4]);
          ff_ea_idct_put_c(dest_cr, s->frame.linesize[2], block[5]);
     }
 }
 
-static inline void tgq_dconly(TgqContext *s, unsigned char *dst, int dst_stride, int dc){
-    int level = av_clip_uint8((dc*s->qtable[0] + 2056)>>4);
+static inline void tgq_dconly(TgqContext *s, unsigned char *dst,
+                              int dst_stride, int dc)
+{
+    int level = av_clip_uint8((dc*s->qtable[0] + 2056) >> 4);
     int j;
-    for(j=0;j<8;j++)
-        memset(dst+j*dst_stride, level, 8);
+    for (j = 0; j < 8; j++)
+        memset(dst + j * dst_stride, level, 8);
 }
 
 static void tgq_idct_put_mb_dconly(TgqContext *s, int mb_x, int mb_y, const int8_t *dc)
 {
-    int linesize= s->frame.linesize[0];
-    uint8_t *dest_y  = s->frame.data[0] + (mb_y * 16* linesize            ) + mb_x * 16;
-    uint8_t *dest_cb = s->frame.data[1] + (mb_y * 8 * s->frame.linesize[1]) + mb_x * 8;
-    uint8_t *dest_cr = s->frame.data[2] + (mb_y * 8 * s->frame.linesize[2]) + mb_x * 8;
-    tgq_dconly(s,dest_y                 , linesize, dc[0]);
-    tgq_dconly(s,dest_y              + 8, linesize, dc[1]);
-    tgq_dconly(s,dest_y + 8*linesize    , linesize, dc[2]);
-    tgq_dconly(s,dest_y + 8*linesize + 8, linesize, dc[3]);
-    if(!(s->avctx->flags&CODEC_FLAG_GRAY)) {
-        tgq_dconly(s,dest_cb, s->frame.linesize[1], dc[4]);
-        tgq_dconly(s,dest_cr, s->frame.linesize[2], dc[5]);
+    int linesize = s->frame.linesize[0];
+    uint8_t *dest_y  = s->frame.data[0] + (mb_y * 16 * linesize)             + mb_x * 16;
+    uint8_t *dest_cb = s->frame.data[1] + (mb_y * 8  * s->frame.linesize[1]) + mb_x * 8;
+    uint8_t *dest_cr = s->frame.data[2] + (mb_y * 8  * s->frame.linesize[2]) + mb_x * 8;
+    tgq_dconly(s, dest_y,                    linesize, dc[0]);
+    tgq_dconly(s, dest_y                + 8, linesize, dc[1]);
+    tgq_dconly(s, dest_y + 8 * linesize,     linesize, dc[2]);
+    tgq_dconly(s, dest_y + 8 * linesize + 8, linesize, dc[3]);
+    if (!(s->avctx->flags & CODEC_FLAG_GRAY)) {
+        tgq_dconly(s, dest_cb, s->frame.linesize[1], dc[4]);
+        tgq_dconly(s, dest_cr, s->frame.linesize[2], dc[5]);
     }
 }
 
-/**
- * @return <0 on error
- */
-static int tgq_decode_mb(TgqContext *s, int mb_y, int mb_x){
+static int tgq_decode_mb(TgqContext *s, int mb_y, int mb_x)
+{
     int mode;
     int i;
     int8_t dc[6];
 
     mode = bytestream2_get_byte(&s->gb);
-    if (mode>12) {
+    if (mode > 12) {
         GetBitContext gb;
         init_get_bits(&gb, s->gb.buffer, FFMIN(bytestream2_get_bytes_left(&s->gb), mode) * 8);
-        for(i=0; i<6; i++)
+        for (i = 0; i < 6; i++)
             tgq_decode_block(s, s->block[i], &gb);
         tgq_idct_put_mb(s, s->block, mb_x, mb_y);
         bytestream2_skip(&s->gb, mode);
-    }else{
-        if (mode==3) {
+    } else {
+        if (mode == 3) {
             memset(dc, bytestream2_get_byte(&s->gb), 4);
             dc[4] = bytestream2_get_byte(&s->gb);
             dc[5] = bytestream2_get_byte(&s->gb);
-        }else if (mode==6) {
+        } else if (mode == 6) {
             bytestream2_get_buffer(&s->gb, dc, 6);
-        }else if (mode==12) {
+        } else if (mode == 12) {
             for (i = 0; i < 6; i++) {
                 dc[i] = bytestream2_get_byte(&s->gb);
                 bytestream2_skip(&s->gb, 1);
             }
-        }else{
+        } else {
             av_log(s->avctx, AV_LOG_ERROR, "unsupported mb mode %i\n", mode);
             return -1;
         }
@@ -178,27 +183,30 @@
     return 0;
 }
 
-static void tgq_calculate_qtable(TgqContext *s, int quant){
-    int i,j;
-    const int a = (14*(100-quant))/100 + 1;
-    const int b = (11*(100-quant))/100 + 4;
-    for(j=0;j<8;j++)
-    for(i=0;i<8;i++)
-        s->qtable[j*8+i] = ((a*(j+i)/(7+7) + b)*ff_inv_aanscales[j*8+i])>>(14-4);
+static void tgq_calculate_qtable(TgqContext *s, int quant)
+{
+    int i, j;
+    const int a = (14 * (100 - quant)) / 100 + 1;
+    const int b = (11 * (100 - quant)) / 100 + 4;
+    for (j = 0; j < 8; j++)
+        for (i = 0; i < 8; i++)
+            s->qtable[j * 8 + i] = ((a * (j + i) / (7 + 7) + b) *
+                                    ff_inv_aanscales[j * 8 + i]) >> (14 - 4);
 }
 
 static int tgq_decode_frame(AVCodecContext *avctx,
-                            void *data, int *data_size,
-                            AVPacket *avpkt){
+                            void *data, int *got_frame,
+                            AVPacket *avpkt)
+{
     const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
-    TgqContext *s = avctx->priv_data;
-    int x,y;
+    int buf_size       = avpkt->size;
+    TgqContext *s      = avctx->priv_data;
+    int x, y, ret;
     int big_endian;
 
     if (buf_size < 16) {
         av_log(avctx, AV_LOG_WARNING, "truncated header\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     big_endian = AV_RL32(&buf[4]) > 0x000FFFFF;
     bytestream2_init(&s->gb, buf + 8, buf_size - 8);
@@ -222,9 +230,9 @@
         s->frame.key_frame = 1;
         s->frame.pict_type = AV_PICTURE_TYPE_I;
         s->frame.buffer_hints = FF_BUFFER_HINTS_VALID;
-        if (avctx->get_buffer(avctx, &s->frame)) {
+        if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-            return -1;
+            return ret;
         }
     }
 
@@ -233,13 +241,14 @@
             if (tgq_decode_mb(s, y, x) < 0)
                 return AVERROR_INVALIDDATA;
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*)data = s->frame;
 
     return avpkt->size;
 }
 
-static av_cold int tgq_decode_end(AVCodecContext *avctx){
+static av_cold int tgq_decode_end(AVCodecContext *avctx)
+{
     TgqContext *s = avctx->priv_data;
     if (s->frame.data[0])
         s->avctx->release_buffer(avctx, &s->frame);
diff --git a/libavcodec/eatgv.c b/libavcodec/eatgv.c
index caee311..7092ba6 100644
--- a/libavcodec/eatgv.c
+++ b/libavcodec/eatgv.c
@@ -42,19 +42,20 @@
     AVFrame frame;
     AVFrame last_frame;
     int width,height;
-    unsigned int palette[AVPALETTE_COUNT];
+    uint32_t palette[AVPALETTE_COUNT];
 
     int (*mv_codebook)[2];
-    unsigned char (*block_codebook)[16];
+    uint8_t (*block_codebook)[16];
     int num_mvs;           ///< current length of mv_codebook
     int num_blocks_packed; ///< current length of block_codebook
 } TgvContext;
 
-static av_cold int tgv_decode_init(AVCodecContext *avctx){
+static av_cold int tgv_decode_init(AVCodecContext *avctx)
+{
     TgvContext *s = avctx->priv_data;
-    s->avctx = avctx;
+    s->avctx         = avctx;
     avctx->time_base = (AVRational){1, 15};
-    avctx->pix_fmt = AV_PIX_FMT_PAL8;
+    avctx->pix_fmt   = AV_PIX_FMT_PAL8;
     avcodec_get_frame_defaults(&s->frame);
     avcodec_get_frame_defaults(&s->last_frame);
     return 0;
@@ -64,10 +65,12 @@
  * Unpack buffer
  * @return 0 on success, -1 on critical buffer underflow
  */
-static int unpack(const uint8_t *src, const uint8_t *src_end, unsigned char *dst, int width, int height) {
-    unsigned char *dst_end = dst + width*height;
+static int unpack(const uint8_t *src, const uint8_t *src_end,
+                  uint8_t *dst, int width, int height)
+{
+    uint8_t *dst_end = dst + width*height;
     int size, size1, size2, offset, run;
-    unsigned char *dst_start = dst;
+    uint8_t *dst_start = dst;
 
     if (src[0] & 0x01)
         src += 5;
@@ -75,56 +78,56 @@
         src += 2;
 
     if (src_end - src < 3)
-        return -1;
+        return AVERROR_INVALIDDATA;
     size = AV_RB24(src);
     src += 3;
 
-    while(size>0 && src<src_end) {
+    while (size > 0 && src < src_end) {
 
         /* determine size1 and size2 */
         size1 = (src[0] & 3);
-        if ( src[0] & 0x80 ) {  // 1
+        if (src[0] & 0x80) {  // 1
             if (src[0] & 0x40 ) {  // 11
-                if ( src[0] & 0x20 ) {  // 111
-                    if ( src[0] < 0xFC )  // !(111111)
+                if (src[0] & 0x20) {  // 111
+                    if (src[0] < 0xFC)  // !(111111)
                         size1 = (((src[0] & 31) + 1) << 2);
                     src++;
                     size2 = 0;
                 } else {  // 110
                     offset = ((src[0] & 0x10) << 12) + AV_RB16(&src[1]) + 1;
-                    size2 = ((src[0] & 0xC) << 6) + src[3] + 5;
-                    src += 4;
+                    size2  = ((src[0] & 0xC) << 6) + src[3] + 5;
+                    src   += 4;
                 }
             } else {  // 10
-                size1 = ( ( src[1] & 0xC0) >> 6 );
+                size1  = ((src[1] & 0xC0) >> 6);
                 offset = (AV_RB16(&src[1]) & 0x3FFF) + 1;
-                size2 = (src[0] & 0x3F) + 4;
-                src += 3;
+                size2  = (src[0] & 0x3F) + 4;
+                src   += 3;
             }
         } else {  // 0
             offset = ((src[0] & 0x60) << 3) + src[1] + 1;
-            size2 = ((src[0] & 0x1C) >> 2) + 3;
-            src += 2;
+            size2  = ((src[0] & 0x1C) >> 2) + 3;
+            src   += 2;
         }
 
 
         /* fetch strip from src */
-        if (size1>src_end-src)
+        if (size1 > src_end - src)
             break;
 
-        if (size1>0) {
+        if (size1 > 0) {
             size -= size1;
-            run = FFMIN(size1, dst_end-dst);
+            run   = FFMIN(size1, dst_end - dst);
             memcpy(dst, src, run);
             dst += run;
             src += run;
         }
 
-        if (size2>0) {
-            if (dst-dst_start<offset)
+        if (size2 > 0) {
+            if (dst - dst_start < offset)
                 return 0;
             size -= size2;
-            run = FFMIN(size2, dst_end-dst);
+            run   = FFMIN(size2, dst_end - dst);
             av_memcpy_backptr(dst, offset, run);
             dst += run;
         }
@@ -137,7 +140,9 @@
  * Decode inter-frame
  * @return 0 on success, -1 on critical buffer underflow
  */
-static int tgv_decode_inter(TgvContext * s, const uint8_t *buf, const uint8_t *buf_end){
+static int tgv_decode_inter(TgvContext *s, const uint8_t *buf,
+                            const uint8_t *buf_end)
+{
     int num_mvs;
     int num_blocks_raw;
     int num_blocks_packed;
@@ -145,10 +150,10 @@
     int i,j,x,y;
     GetBitContext gb;
     int mvbits;
-    const unsigned char *blocks_raw;
+    const uint8_t *blocks_raw;
 
     if(buf_end - buf < 12)
-        return -1;
+        return AVERROR_INVALIDDATA;
 
     num_mvs           = AV_RL16(&buf[0]);
     num_blocks_raw    = AV_RL16(&buf[2]);
@@ -169,75 +174,75 @@
     }
 
     if (num_blocks_packed > s->num_blocks_packed) {
-        s->block_codebook = av_realloc(s->block_codebook, num_blocks_packed*16*sizeof(unsigned char));
+        s->block_codebook = av_realloc(s->block_codebook, num_blocks_packed*16);
         s->num_blocks_packed = num_blocks_packed;
     }
 
     /* read motion vectors */
-    mvbits = (num_mvs*2*10+31) & ~31;
+    mvbits = (num_mvs * 2 * 10 + 31) & ~31;
 
-    if (buf_end - buf < (mvbits>>3)+16*num_blocks_raw+8*num_blocks_packed)
-        return -1;
+    if (buf_end - buf < (mvbits>>3) + 16*num_blocks_raw + 8*num_blocks_packed)
+        return AVERROR_INVALIDDATA;
 
     init_get_bits(&gb, buf, mvbits);
-    for (i=0; i<num_mvs; i++) {
+    for (i = 0; i < num_mvs; i++) {
         s->mv_codebook[i][0] = get_sbits(&gb, 10);
         s->mv_codebook[i][1] = get_sbits(&gb, 10);
     }
-    buf += mvbits>>3;
+    buf += mvbits >> 3;
 
     /* note ptr to uncompressed blocks */
     blocks_raw = buf;
-    buf += num_blocks_raw*16;
+    buf       += num_blocks_raw * 16;
 
     /* read compressed blocks */
-    init_get_bits(&gb, buf, (buf_end-buf)<<3);
-    for (i=0; i<num_blocks_packed; i++) {
+    init_get_bits(&gb, buf, (buf_end - buf) << 3);
+    for (i = 0; i < num_blocks_packed; i++) {
         int tmp[4];
-        for(j=0; j<4; j++)
+        for (j = 0; j < 4; j++)
             tmp[j] = get_bits(&gb, 8);
-        for(j=0; j<16; j++)
+        for (j = 0; j < 16; j++)
             s->block_codebook[i][15-j] = tmp[get_bits(&gb, 2)];
     }
 
     if (get_bits_left(&gb) < vector_bits *
-        (s->avctx->height/4) * (s->avctx->width/4))
-        return -1;
+        (s->avctx->height / 4) * (s->avctx->width / 4))
+        return AVERROR_INVALIDDATA;
 
     /* read vectors and build frame */
-    for(y=0; y<s->avctx->height/4; y++)
-    for(x=0; x<s->avctx->width/4; x++) {
-        unsigned int vector = get_bits(&gb, vector_bits);
-        const unsigned char *src;
-        int src_stride;
+    for (y = 0; y < s->avctx->height / 4; y++)
+        for (x = 0; x < s->avctx->width / 4; x++) {
+            unsigned int vector = get_bits(&gb, vector_bits);
+            const uint8_t *src;
+            int src_stride;
 
-        if (vector < num_mvs) {
-            int mx = x * 4 + s->mv_codebook[vector][0];
-            int my = y * 4 + s->mv_codebook[vector][1];
+            if (vector < num_mvs) {
+                int mx = x * 4 + s->mv_codebook[vector][0];
+                int my = y * 4 + s->mv_codebook[vector][1];
 
-            if (   mx < 0 || mx + 4 > s->avctx->width
-                || my < 0 || my + 4 > s->avctx->height) {
-                av_log(s->avctx, AV_LOG_ERROR, "MV %d %d out of picture\n", mx, my);
-                continue;
+                if (mx < 0 || mx + 4 > s->avctx->width ||
+                    my < 0 || my + 4 > s->avctx->height) {
+                    av_log(s->avctx, AV_LOG_ERROR, "MV %d %d out of picture\n", mx, my);
+                    continue;
+                }
+
+                src = s->last_frame.data[0] + mx + my * s->last_frame.linesize[0];
+                src_stride = s->last_frame.linesize[0];
+            } else {
+                int offset = vector - num_mvs;
+                if (offset < num_blocks_raw)
+                    src = blocks_raw + 16*offset;
+                else if (offset - num_blocks_raw < num_blocks_packed)
+                    src = s->block_codebook[offset - num_blocks_raw];
+                else
+                    continue;
+                src_stride = 4;
             }
 
-            src = s->last_frame.data[0] + mx + my * s->last_frame.linesize[0];
-            src_stride = s->last_frame.linesize[0];
-        }else{
-            int offset = vector - num_mvs;
-            if (offset<num_blocks_raw)
-                src = blocks_raw + 16*offset;
-            else if (offset-num_blocks_raw<num_blocks_packed)
-                src = s->block_codebook[offset-num_blocks_raw];
-            else
-                continue;
-            src_stride = 4;
-        }
-
-        for(j=0; j<4; j++)
-        for(i=0; i<4; i++)
-            s->frame.data[0][ (y*4+j)*s->frame.linesize[0] + (x*4+i)  ] =
-               src[j*src_stride + i];
+            for (j = 0; j < 4; j++)
+                for (i = 0; i < 4; i++)
+                    s->frame.data[0][(y * 4 + j) * s->frame.linesize[0] + (x * 4 + i)] =
+                        src[j * src_stride + i];
     }
 
     return 0;
@@ -253,31 +258,31 @@
 }
 
 static int tgv_decode_frame(AVCodecContext *avctx,
-                            void *data, int *data_size,
+                            void *data, int *got_frame,
                             AVPacket *avpkt)
 {
-    const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
-    TgvContext *s = avctx->priv_data;
+    const uint8_t *buf     = avpkt->data;
+    int buf_size           = avpkt->size;
+    TgvContext *s          = avctx->priv_data;
     const uint8_t *buf_end = buf + buf_size;
-    int chunk_type;
+    int chunk_type, ret;
 
     if (buf_end - buf < EA_PREAMBLE_SIZE)
         return AVERROR_INVALIDDATA;
 
     chunk_type = AV_RL32(&buf[0]);
-    buf += EA_PREAMBLE_SIZE;
+    buf       += EA_PREAMBLE_SIZE;
 
-    if (chunk_type==kVGT_TAG) {
+    if (chunk_type == kVGT_TAG) {
         int pal_count, i;
         if(buf_end - buf < 12) {
             av_log(avctx, AV_LOG_WARNING, "truncated header\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
 
         s->width  = AV_RL16(&buf[0]);
         s->height = AV_RL16(&buf[2]);
-        if (s->avctx->width!=s->width || s->avctx->height!=s->height) {
+        if (s->avctx->width != s->width || s->avctx->height != s->height) {
             avcodec_set_dimensions(s->avctx, s->width, s->height);
             cond_release_buffer(&s->frame);
             cond_release_buffer(&s->last_frame);
@@ -285,14 +290,14 @@
 
         pal_count = AV_RL16(&buf[6]);
         buf += 12;
-        for(i=0; i<pal_count && i<AVPALETTE_COUNT && buf_end - buf >= 3; i++) {
+        for(i = 0; i < pal_count && i < AVPALETTE_COUNT && buf_end - buf >= 3; i++) {
             s->palette[i] = 0xFFU << 24 | AV_RB24(buf);
             buf += 3;
         }
     }
 
-    if (av_image_check_size(s->width, s->height, 0, avctx))
-        return -1;
+    if ((ret = av_image_check_size(s->width, s->height, 0, avctx)) < 0)
+        return ret;
 
     /* shuffle */
     FFSWAP(AVFrame, s->frame, s->last_frame);
@@ -312,27 +317,27 @@
     }
     memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE);
 
-    if(chunk_type==kVGT_TAG) {
+    if (chunk_type == kVGT_TAG) {
         s->frame.key_frame = 1;
         s->frame.pict_type = AV_PICTURE_TYPE_I;
-        if (unpack(buf, buf_end, s->frame.data[0], s->avctx->width, s->avctx->height)<0) {
+        if (unpack(buf, buf_end, s->frame.data[0], s->avctx->width, s->avctx->height) < 0) {
             av_log(avctx, AV_LOG_WARNING, "truncated intra frame\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
-    }else{
+    } else {
         if (!s->last_frame.data[0]) {
             av_log(avctx, AV_LOG_WARNING, "inter frame without corresponding intra frame\n");
             return buf_size;
         }
         s->frame.key_frame = 0;
         s->frame.pict_type = AV_PICTURE_TYPE_P;
-        if (tgv_decode_inter(s, buf, buf_end)<0) {
+        if (tgv_decode_inter(s, buf, buf_end) < 0) {
             av_log(avctx, AV_LOG_WARNING, "truncated inter frame\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
     }
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*)data = s->frame;
 
     return buf_size;
diff --git a/libavcodec/eatqi.c b/libavcodec/eatqi.c
index 62833d5..5513848 100644
--- a/libavcodec/eatqi.c
+++ b/libavcodec/eatqi.c
@@ -28,9 +28,9 @@
 
 #include "avcodec.h"
 #include "get_bits.h"
-#include "dsputil.h"
 #include "aandcttab.h"
 #include "eaidct.h"
+#include "internal.h"
 #include "mpeg12.h"
 #include "mpegvideo.h"
 
@@ -39,7 +39,7 @@
     AVFrame frame;
     void *bitstream_buf;
     unsigned int bitstream_buf_size;
-    DECLARE_ALIGNED(16, DCTELEM, block)[6][64];
+    DECLARE_ALIGNED(16, int16_t, block)[6][64];
 } TqiContext;
 
 static av_cold int tqi_decode_init(AVCodecContext *avctx)
@@ -57,7 +57,7 @@
     return 0;
 }
 
-static int tqi_decode_mb(MpegEncContext *s, DCTELEM (*block)[64])
+static int tqi_decode_mb(MpegEncContext *s, int16_t (*block)[64])
 {
     int n;
     s->dsp.clear_blocks(block[0]);
@@ -68,7 +68,7 @@
     return 0;
 }
 
-static inline void tqi_idct_put(TqiContext *t, DCTELEM (*block)[64])
+static inline void tqi_idct_put(TqiContext *t, int16_t (*block)[64])
 {
     MpegEncContext *s = &t->s;
     int linesize= t->frame.linesize[0];
@@ -96,7 +96,7 @@
 }
 
 static int tqi_decode_frame(AVCodecContext *avctx,
-                            void *data, int *data_size,
+                            void *data, int *got_frame,
                             AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
@@ -116,7 +116,7 @@
     if (s->avctx->width!=s->width || s->avctx->height!=s->height)
         avcodec_set_dimensions(s->avctx, s->width, s->height);
 
-    if(avctx->get_buffer(avctx, &t->frame) < 0) {
+    if(ff_get_buffer(avctx, &t->frame) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return -1;
     }
@@ -138,7 +138,7 @@
     }
     end:
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*)data = t->frame;
     return buf_size;
 }
diff --git a/libavcodec/error_resilience.c b/libavcodec/error_resilience.c
index 01f7424..d5fbcbd 100644
--- a/libavcodec/error_resilience.c
+++ b/libavcodec/error_resilience.c
@@ -28,73 +28,21 @@
 #include <limits.h>
 
 #include "avcodec.h"
-#include "dsputil.h"
+#include "error_resilience.h"
 #include "mpegvideo.h"
-#include "h264.h"
 #include "rectangle.h"
 #include "thread.h"
 
-/*
- * H264 redefines mb_intra so it is not mistakely used (its uninitialized in h264)
- * but error concealment must support both h264 and h263 thus we must undo this
- */
-#undef mb_intra
-
-static void decode_mb(MpegEncContext *s, int ref)
-{
-    s->dest[0] = s->current_picture.f.data[0] + (s->mb_y *  16                       * s->linesize)   + s->mb_x *  16;
-    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);
-
-    ff_init_block_index(s);
-    ff_update_block_index(s);
-    s->dest[1] += (16 >> s->chroma_x_shift) - 8;
-    s->dest[2] += (16 >> s->chroma_x_shift) - 8;
-
-    if (CONFIG_H264_DECODER && s->codec_id == AV_CODEC_ID_H264) {
-        H264Context *h = (void*)s;
-        h->mb_xy = s->mb_x + s->mb_y * s->mb_stride;
-        memset(h->non_zero_count_cache, 0, sizeof(h->non_zero_count_cache));
-        av_assert1(ref >= 0);
-        /* FIXME: It is possible albeit uncommon that slice references
-         * differ between slices. We take the easy approach and ignore
-         * it for now. If this turns out to have any relevance in
-         * practice then correct remapping should be added. */
-        if (ref >= h->ref_count[0])
-            ref = 0;
-        if (!h->ref_list[0][ref].f.data[0]) {
-            av_log(s->avctx, AV_LOG_DEBUG, "Reference not available for error concealing\n");
-            ref = 0;
-        }
-        if ((h->ref_list[0][ref].f.reference&3) != 3) {
-            av_log(s->avctx, AV_LOG_DEBUG, "Reference invalid\n");
-            return;
-        }
-        fill_rectangle(&s->current_picture.f.ref_index[0][4 * h->mb_xy],
-                       2, 2, 2, ref, 1);
-        fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, ref, 1);
-        fill_rectangle(h->mv_cache[0][scan8[0]], 4, 4, 8,
-                       pack16to32(s->mv[0][0][0], s->mv[0][0][1]), 4);
-        h->mb_mbaff =
-        h->mb_field_decoding_flag = 0;
-        ff_h264_hl_decode_mb(h);
-    } else {
-        assert(ref == 0);
-        ff_MPV_decode_mb(s, s->block);
-    }
-}
-
 /**
  * @param stride the number of MVs to get to the next row
  * @param mv_step the number of MVs per row or column in a macroblock
  */
-static void set_mv_strides(MpegEncContext *s, int *mv_step, int *stride)
+static void set_mv_strides(ERContext *s, int *mv_step, int *stride)
 {
-    if (s->codec_id == AV_CODEC_ID_H264) {
-        H264Context *h = (void*)s;
+    if (s->avctx->codec_id == AV_CODEC_ID_H264) {
         av_assert0(s->quarter_sample);
         *mv_step = 4;
-        *stride  = h->b_stride;
+        *stride  = s->mb_width * 4;
     } else {
         *mv_step = 2;
         *stride  = s->b8_stride;
@@ -104,9 +52,10 @@
 /**
  * Replace the current MB with a flat dc-only version.
  */
-static void put_dc(MpegEncContext *s, uint8_t *dest_y, uint8_t *dest_cb,
+static void put_dc(ERContext *s, uint8_t *dest_y, uint8_t *dest_cb,
                    uint8_t *dest_cr, int mb_x, int mb_y)
 {
+    int *linesize = s->cur_pic->f.linesize;
     int dc, dcu, dcv, y, i;
     for (i = 0; i < 4; i++) {
         dc = s->dc_val[0][mb_x * 2 + (i &  1) + (mb_y * 2 + (i >> 1)) * s->b8_stride];
@@ -117,7 +66,7 @@
         for (y = 0; y < 8; y++) {
             int x;
             for (x = 0; x < 8; x++)
-                dest_y[x + (i &  1) * 8 + (y + (i >> 1) * 8) * s->linesize] = dc / 8;
+                dest_y[x + (i &  1) * 8 + (y + (i >> 1) * 8) * linesize[0]] = dc / 8;
         }
     }
     dcu = s->dc_val[1][mb_x + mb_y * s->mb_stride];
@@ -133,8 +82,8 @@
     for (y = 0; y < 8; y++) {
         int x;
         for (x = 0; x < 8; x++) {
-            dest_cb[x + y * s->uvlinesize] = dcu / 8;
-            dest_cr[x + y * s->uvlinesize] = dcv / 8;
+            dest_cb[x + y * linesize[1]] = dcu / 8;
+            dest_cr[x + y * linesize[2]] = dcv / 8;
         }
     }
 }
@@ -180,7 +129,7 @@
  * @param w     width in 8 pixel blocks
  * @param h     height in 8 pixel blocks
  */
-static void guess_dc(MpegEncContext *s, int16_t *dc, int w,
+static void guess_dc(ERContext *s, int16_t *dc, int w,
                      int h, int stride, int is_luma)
 {
     int b_x, b_y;
@@ -198,7 +147,7 @@
         for(b_x=0; b_x<w; b_x++){
             int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
             int error_j= s->error_status_table[mb_index_j];
-            int intra_j = IS_INTRA(s->current_picture.f.mb_type[mb_index_j]);
+            int intra_j = IS_INTRA(s->cur_pic->f.mb_type[mb_index_j]);
             if(intra_j==0 || !(error_j&ER_DC_ERROR)){
                 color= dc[b_x + b_y*stride];
                 distance= b_x;
@@ -211,7 +160,7 @@
         for(b_x=w-1; b_x>=0; b_x--){
             int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
             int error_j= s->error_status_table[mb_index_j];
-            int intra_j = IS_INTRA(s->current_picture.f.mb_type[mb_index_j]);
+            int intra_j = IS_INTRA(s->cur_pic->f.mb_type[mb_index_j]);
             if(intra_j==0 || !(error_j&ER_DC_ERROR)){
                 color= dc[b_x + b_y*stride];
                 distance= b_x;
@@ -226,7 +175,7 @@
         for(b_y=0; b_y<h; b_y++){
             int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
             int error_j= s->error_status_table[mb_index_j];
-            int intra_j = IS_INTRA(s->current_picture.f.mb_type[mb_index_j]);
+            int intra_j = IS_INTRA(s->cur_pic->f.mb_type[mb_index_j]);
             if(intra_j==0 || !(error_j&ER_DC_ERROR)){
                 color= dc[b_x + b_y*stride];
                 distance= b_y;
@@ -239,7 +188,7 @@
         for(b_y=h-1; b_y>=0; b_y--){
             int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
             int error_j= s->error_status_table[mb_index_j];
-            int intra_j = IS_INTRA(s->current_picture.f.mb_type[mb_index_j]);
+            int intra_j = IS_INTRA(s->cur_pic->f.mb_type[mb_index_j]);
             if(intra_j==0 || !(error_j&ER_DC_ERROR)){
                 color= dc[b_x + b_y*stride];
                 distance= b_y;
@@ -256,7 +205,7 @@
             mb_index = (b_x >> is_luma) + (b_y >> is_luma) * s->mb_stride;
             error    = s->error_status_table[mb_index];
 
-            if (IS_INTER(s->current_picture.f.mb_type[mb_index]))
+            if (IS_INTER(s->cur_pic->f.mb_type[mb_index]))
                 continue; // inter
             if (!(error & ER_DC_ERROR))
                 continue; // dc-ok
@@ -283,7 +232,7 @@
  * @param w     width in 8 pixel blocks
  * @param h     height in 8 pixel blocks
  */
-static void h_block_filter(MpegEncContext *s, uint8_t *dst, int w,
+static void h_block_filter(ERContext *s, uint8_t *dst, int w,
                            int h, int stride, int is_luma)
 {
     int b_x, b_y, mvx_stride, mvy_stride;
@@ -297,13 +246,13 @@
             int y;
             int left_status  = s->error_status_table[( b_x      >> is_luma) + (b_y >> is_luma) * s->mb_stride];
             int right_status = s->error_status_table[((b_x + 1) >> is_luma) + (b_y >> is_luma) * s->mb_stride];
-            int left_intra   = IS_INTRA(s->current_picture.f.mb_type[( b_x      >> is_luma) + (b_y >> is_luma) * s->mb_stride]);
-            int right_intra  = IS_INTRA(s->current_picture.f.mb_type[((b_x + 1) >> is_luma) + (b_y >> is_luma) * s->mb_stride]);
+            int left_intra   = IS_INTRA(s->cur_pic->f.mb_type[( b_x      >> is_luma) + (b_y >> is_luma) * s->mb_stride]);
+            int right_intra  = IS_INTRA(s->cur_pic->f.mb_type[((b_x + 1) >> is_luma) + (b_y >> is_luma) * s->mb_stride]);
             int left_damage  = left_status & ER_MB_ERROR;
             int right_damage = right_status & ER_MB_ERROR;
             int offset       = b_x * 8 + b_y * stride * 8;
-            int16_t *left_mv  = s->current_picture.f.motion_val[0][mvy_stride * b_y + mvx_stride *  b_x];
-            int16_t *right_mv = s->current_picture.f.motion_val[0][mvy_stride * b_y + mvx_stride * (b_x + 1)];
+            int16_t *left_mv  = s->cur_pic->f.motion_val[0][mvy_stride * b_y + mvx_stride *  b_x];
+            int16_t *right_mv = s->cur_pic->f.motion_val[0][mvy_stride * b_y + mvx_stride * (b_x + 1)];
             if (!(left_damage || right_damage))
                 continue; // both undamaged
             if ((!left_intra) && (!right_intra) &&
@@ -351,7 +300,7 @@
  * @param w     width in 8 pixel blocks
  * @param h     height in 8 pixel blocks
  */
-static void v_block_filter(MpegEncContext *s, uint8_t *dst, int w, int h,
+static void v_block_filter(ERContext *s, uint8_t *dst, int w, int h,
                            int stride, int is_luma)
 {
     int b_x, b_y, mvx_stride, mvy_stride;
@@ -365,14 +314,14 @@
             int x;
             int top_status    = s->error_status_table[(b_x >> is_luma) +  (b_y      >> is_luma) * s->mb_stride];
             int bottom_status = s->error_status_table[(b_x >> is_luma) + ((b_y + 1) >> is_luma) * s->mb_stride];
-            int top_intra     = IS_INTRA(s->current_picture.f.mb_type[(b_x >> is_luma) + ( b_y      >> is_luma) * s->mb_stride]);
-            int bottom_intra  = IS_INTRA(s->current_picture.f.mb_type[(b_x >> is_luma) + ((b_y + 1) >> is_luma) * s->mb_stride]);
+            int top_intra     = IS_INTRA(s->cur_pic->f.mb_type[(b_x >> is_luma) + ( b_y      >> is_luma) * s->mb_stride]);
+            int bottom_intra  = IS_INTRA(s->cur_pic->f.mb_type[(b_x >> is_luma) + ((b_y + 1) >> is_luma) * s->mb_stride]);
             int top_damage    = top_status & ER_MB_ERROR;
             int bottom_damage = bottom_status & ER_MB_ERROR;
             int offset        = b_x * 8 + b_y * stride * 8;
 
-            int16_t *top_mv    = s->current_picture.f.motion_val[0][mvy_stride *  b_y      + mvx_stride * b_x];
-            int16_t *bottom_mv = s->current_picture.f.motion_val[0][mvy_stride * (b_y + 1) + mvx_stride * b_x];
+            int16_t *top_mv    = s->cur_pic->f.motion_val[0][mvy_stride *  b_y      + mvx_stride * b_x];
+            int16_t *bottom_mv = s->cur_pic->f.motion_val[0][mvy_stride * (b_y + 1) + mvx_stride * b_x];
 
             if (!(top_damage || bottom_damage))
                 continue; // both undamaged
@@ -417,7 +366,7 @@
     }
 }
 
-static void guess_mv(MpegEncContext *s)
+static void guess_mv(ERContext *s)
 {
     uint8_t *fixed = s->er_temp_buffer;
 #define MV_FROZEN    3
@@ -437,7 +386,7 @@
         int f = 0;
         int error = s->error_status_table[mb_xy];
 
-        if (IS_INTRA(s->current_picture.f.mb_type[mb_xy]))
+        if (IS_INTRA(s->cur_pic->f.mb_type[mb_xy]))
             f = MV_FROZEN; // intra // FIXME check
         if (!(error & ER_MV_ERROR))
             f = MV_FROZEN; // inter with undamaged MV
@@ -445,13 +394,13 @@
         fixed[mb_xy] = f;
         if (f == MV_FROZEN)
             num_avail++;
-        else if(s->last_picture.f.data[0] && s->last_picture.f.motion_val[0]){
+        else if(s->last_pic->f.data[0] && s->last_pic->f.motion_val[0]){
             const int mb_y= mb_xy / s->mb_stride;
             const int mb_x= mb_xy % s->mb_stride;
             const int mot_index= (mb_x + mb_y*mot_stride) * mot_step;
-            s->current_picture.f.motion_val[0][mot_index][0]= s->last_picture.f.motion_val[0][mot_index][0];
-            s->current_picture.f.motion_val[0][mot_index][1]= s->last_picture.f.motion_val[0][mot_index][1];
-            s->current_picture.f.ref_index[0][4*mb_xy]      = s->last_picture.f.ref_index[0][4*mb_xy];
+            s->cur_pic->f.motion_val[0][mot_index][0]= s->last_pic->f.motion_val[0][mot_index][0];
+            s->cur_pic->f.motion_val[0][mot_index][1]= s->last_pic->f.motion_val[0][mot_index][1];
+            s->cur_pic->f.ref_index[0][4*mb_xy]      = s->last_pic->f.ref_index[0][4*mb_xy];
         }
     }
 
@@ -460,25 +409,17 @@
         for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
             for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
                 const int mb_xy = mb_x + mb_y * s->mb_stride;
+                int mv_dir = (s->last_pic && s->last_pic->f.data[0]) ? MV_DIR_FORWARD : MV_DIR_BACKWARD;
 
-                if (IS_INTRA(s->current_picture.f.mb_type[mb_xy]))
+                if (IS_INTRA(s->cur_pic->f.mb_type[mb_xy]))
                     continue;
                 if (!(s->error_status_table[mb_xy] & ER_MV_ERROR))
                     continue;
 
-                s->mv_dir     = s->last_picture.f.data[0] ? MV_DIR_FORWARD
-                                                          : MV_DIR_BACKWARD;
-                s->mb_intra   = 0;
-                s->mv_type    = MV_TYPE_16X16;
-                s->mb_skipped = 0;
-
-                s->dsp.clear_blocks(s->block[0]);
-
-                s->mb_x        = mb_x;
-                s->mb_y        = mb_y;
                 s->mv[0][0][0] = 0;
                 s->mv[0][0][1] = 0;
-                decode_mb(s, 0);
+                s->decode_mb(s->opaque, 0, mv_dir, MV_TYPE_16X16, &s->mv,
+                             mb_x, mb_y, 0, 0);
             }
         }
         return;
@@ -511,8 +452,8 @@
 
                     if (fixed[mb_xy] == MV_FROZEN)
                         continue;
-                    av_assert1(!IS_INTRA(s->current_picture.f.mb_type[mb_xy]));
-                    av_assert1(s->last_picture_ptr && s->last_picture_ptr->f.data[0]);
+                    av_assert1(!IS_INTRA(s->cur_pic->f.mb_type[mb_xy]));
+                    av_assert1(s->last_pic && s->last_pic->f.data[0]);
 
                     j = 0;
                     if (mb_x > 0             && fixed[mb_xy - 1]         == MV_FROZEN)
@@ -542,38 +483,38 @@
 
                     if (mb_x > 0 && fixed[mb_xy - 1]) {
                         mv_predictor[pred_count][0] =
-                            s->current_picture.f.motion_val[0][mot_index - mot_step][0];
+                            s->cur_pic->f.motion_val[0][mot_index - mot_step][0];
                         mv_predictor[pred_count][1] =
-                            s->current_picture.f.motion_val[0][mot_index - mot_step][1];
+                            s->cur_pic->f.motion_val[0][mot_index - mot_step][1];
                         ref[pred_count] =
-                            s->current_picture.f.ref_index[0][4 * (mb_xy - 1)];
+                            s->cur_pic->f.ref_index[0][4 * (mb_xy - 1)];
                         pred_count++;
                     }
                     if (mb_x + 1 < mb_width && fixed[mb_xy + 1]) {
                         mv_predictor[pred_count][0] =
-                            s->current_picture.f.motion_val[0][mot_index + mot_step][0];
+                            s->cur_pic->f.motion_val[0][mot_index + mot_step][0];
                         mv_predictor[pred_count][1] =
-                            s->current_picture.f.motion_val[0][mot_index + mot_step][1];
+                            s->cur_pic->f.motion_val[0][mot_index + mot_step][1];
                         ref[pred_count] =
-                            s->current_picture.f.ref_index[0][4 * (mb_xy + 1)];
+                            s->cur_pic->f.ref_index[0][4 * (mb_xy + 1)];
                         pred_count++;
                     }
                     if (mb_y > 0 && fixed[mb_xy - mb_stride]) {
                         mv_predictor[pred_count][0] =
-                            s->current_picture.f.motion_val[0][mot_index - mot_stride * mot_step][0];
+                            s->cur_pic->f.motion_val[0][mot_index - mot_stride * mot_step][0];
                         mv_predictor[pred_count][1] =
-                            s->current_picture.f.motion_val[0][mot_index - mot_stride * mot_step][1];
+                            s->cur_pic->f.motion_val[0][mot_index - mot_stride * mot_step][1];
                         ref[pred_count] =
-                            s->current_picture.f.ref_index[0][4 * (mb_xy - s->mb_stride)];
+                            s->cur_pic->f.ref_index[0][4 * (mb_xy - s->mb_stride)];
                         pred_count++;
                     }
                     if (mb_y + 1<mb_height && fixed[mb_xy + mb_stride]) {
                         mv_predictor[pred_count][0] =
-                            s->current_picture.f.motion_val[0][mot_index + mot_stride * mot_step][0];
+                            s->cur_pic->f.motion_val[0][mot_index + mot_stride * mot_step][0];
                         mv_predictor[pred_count][1] =
-                            s->current_picture.f.motion_val[0][mot_index + mot_stride * mot_step][1];
+                            s->cur_pic->f.motion_val[0][mot_index + mot_stride * mot_step][1];
                         ref[pred_count] =
-                            s->current_picture.f.ref_index[0][4 * (mb_xy + s->mb_stride)];
+                            s->cur_pic->f.ref_index[0][4 * (mb_xy + s->mb_stride)];
                         pred_count++;
                     }
                     if (pred_count == 0)
@@ -631,19 +572,19 @@
                         if (s->avctx->codec_id == AV_CODEC_ID_H264) {
                             // FIXME
                         } else {
-                            ff_thread_await_progress(&s->last_picture_ptr->f,
+                            ff_thread_await_progress(&s->last_pic->f,
                                                      mb_y, 0);
                         }
-                        if (!s->last_picture.f.motion_val[0] ||
-                            !s->last_picture.f.ref_index[0])
+                        if (!s->last_pic->f.motion_val[0] ||
+                            !s->last_pic->f.ref_index[0])
                             goto skip_last_mv;
-                        prev_x   = s->last_picture.f.motion_val[0][mot_index][0];
-                        prev_y   = s->last_picture.f.motion_val[0][mot_index][1];
-                        prev_ref = s->last_picture.f.ref_index[0][4 * mb_xy];
+                        prev_x   = s->last_pic->f.motion_val[0][mot_index][0];
+                        prev_y   = s->last_pic->f.motion_val[0][mot_index][1];
+                        prev_ref = s->last_pic->f.ref_index[0][4 * mb_xy];
                     } else {
-                        prev_x   = s->current_picture.f.motion_val[0][mot_index][0];
-                        prev_y   = s->current_picture.f.motion_val[0][mot_index][1];
-                        prev_ref = s->current_picture.f.ref_index[0][4 * mb_xy];
+                        prev_x   = s->cur_pic->f.motion_val[0][mot_index][0];
+                        prev_y   = s->cur_pic->f.motion_val[0][mot_index][1];
+                        prev_ref = s->cur_pic->f.ref_index[0][4 * mb_xy];
                     }
 
                     /* last MV */
@@ -653,54 +594,47 @@
                     pred_count++;
 
 skip_last_mv:
-                    s->mv_dir     = MV_DIR_FORWARD;
-                    s->mb_intra   = 0;
-                    s->mv_type    = MV_TYPE_16X16;
-                    s->mb_skipped = 0;
-
-                    s->dsp.clear_blocks(s->block[0]);
-
-                    s->mb_x = mb_x;
-                    s->mb_y = mb_y;
 
                     for (j = 0; j < pred_count; j++) {
+                        int *linesize = s->cur_pic->f.linesize;
                         int score = 0;
-                        uint8_t *src = s->current_picture.f.data[0] +
-                                       mb_x * 16 + mb_y * 16 * s->linesize;
+                        uint8_t *src = s->cur_pic->f.data[0] +
+                                       mb_x * 16 + mb_y * 16 * linesize[0];
 
-                        s->current_picture.f.motion_val[0][mot_index][0] =
+                        s->cur_pic->f.motion_val[0][mot_index][0] =
                             s->mv[0][0][0] = mv_predictor[j][0];
-                        s->current_picture.f.motion_val[0][mot_index][1] =
+                        s->cur_pic->f.motion_val[0][mot_index][1] =
                             s->mv[0][0][1] = mv_predictor[j][1];
 
                         // predictor intra or otherwise not available
                         if (ref[j] < 0)
                             continue;
 
-                        decode_mb(s, ref[j]);
+                        s->decode_mb(s->opaque, ref[j], MV_DIR_FORWARD,
+                                     MV_TYPE_16X16, &s->mv, mb_x, mb_y, 0, 0);
 
                         if (mb_x > 0 && fixed[mb_xy - 1]) {
                             int k;
                             for (k = 0; k < 16; k++)
-                                score += FFABS(src[k * s->linesize - 1] -
-                                               src[k * s->linesize]);
+                                score += FFABS(src[k * linesize[0] - 1] -
+                                               src[k * linesize[0]]);
                         }
                         if (mb_x + 1 < mb_width && fixed[mb_xy + 1]) {
                             int k;
                             for (k = 0; k < 16; k++)
-                                score += FFABS(src[k * s->linesize + 15] -
-                                               src[k * s->linesize + 16]);
+                                score += FFABS(src[k * linesize[0] + 15] -
+                                               src[k * linesize[0] + 16]);
                         }
                         if (mb_y > 0 && fixed[mb_xy - mb_stride]) {
                             int k;
                             for (k = 0; k < 16; k++)
-                                score += FFABS(src[k - s->linesize] - src[k]);
+                                score += FFABS(src[k - linesize[0]] - src[k]);
                         }
                         if (mb_y + 1 < mb_height && fixed[mb_xy + mb_stride]) {
                             int k;
                             for (k = 0; k < 16; k++)
-                                score += FFABS(src[k + s->linesize * 15] -
-                                               src[k + s->linesize * 16]);
+                                score += FFABS(src[k + linesize[0] * 15] -
+                                               src[k + linesize[0] * 16]);
                         }
 
                         if (score <= best_score) { // <= will favor the last MV
@@ -714,11 +648,12 @@
 
                     for (i = 0; i < mot_step; i++)
                         for (j = 0; j < mot_step; j++) {
-                            s->current_picture.f.motion_val[0][mot_index + i + j * mot_stride][0] = s->mv[0][0][0];
-                            s->current_picture.f.motion_val[0][mot_index + i + j * mot_stride][1] = s->mv[0][0][1];
+                            s->cur_pic->f.motion_val[0][mot_index + i + j * mot_stride][0] = s->mv[0][0][0];
+                            s->cur_pic->f.motion_val[0][mot_index + i + j * mot_stride][1] = s->mv[0][0][1];
                         }
 
-                    decode_mb(s, ref[best_pred]);
+                    s->decode_mb(s->opaque, ref[best_pred], MV_DIR_FORWARD,
+                                 MV_TYPE_16X16, &s->mv, mb_x, mb_y, 0, 0);
 
 
                     if (s->mv[0][0][0] != prev_x || s->mv[0][0][1] != prev_y) {
@@ -741,11 +676,11 @@
     }
 }
 
-static int is_intra_more_likely(MpegEncContext *s)
+static int is_intra_more_likely(ERContext *s)
 {
     int is_intra_likely, i, j, undamaged_count, skip_amount, mb_x, mb_y;
 
-    if (!s->last_picture_ptr || !s->last_picture_ptr->f.data[0])
+    if (!s->last_pic || !s->last_pic->f.data[0])
         return 1; // no previous frame available -> use spatial prediction
 
     undamaged_count = 0;
@@ -756,12 +691,8 @@
             undamaged_count++;
     }
 
-    if (s->codec_id == AV_CODEC_ID_H264) {
-        H264Context *h = (void*) s;
-        if (h->list_count <= 0 || h->ref_count[0] <= 0 ||
-            !h->ref_list[0][0].f.data[0])
-            return 1;
-    }
+    if (s->avctx->codec_id == AV_CODEC_ID_H264 && s->ref_count <= 0)
+        return 1;
 
     if (undamaged_count < 5)
         return 0; // almost all MBs damaged -> use temporal prediction
@@ -769,7 +700,7 @@
     // prevent dsp.sad() check, that requires access to the image
     if (CONFIG_MPEG_XVMC_DECODER    &&
         s->avctx->xvmc_acceleration &&
-        s->pict_type == AV_PICTURE_TYPE_I)
+        s->cur_pic->f.pict_type == AV_PICTURE_TYPE_I)
         return 1;
 
     skip_amount     = FFMAX(undamaged_count / 50, 1); // check only up to 50 MBs
@@ -790,23 +721,26 @@
             if ((j % skip_amount) != 0)
                 continue;
 
-            if (s->pict_type == AV_PICTURE_TYPE_I) {
-                uint8_t *mb_ptr      = s->current_picture.f.data[0] +
-                                       mb_x * 16 + mb_y * 16 * s->linesize;
-                uint8_t *last_mb_ptr = s->last_picture.f.data[0] +
-                                       mb_x * 16 + mb_y * 16 * s->linesize;
+            if (s->cur_pic->f.pict_type == AV_PICTURE_TYPE_I) {
+                int *linesize = s->cur_pic->f.linesize;
+                uint8_t *mb_ptr      = s->cur_pic->f.data[0] +
+                                       mb_x * 16 + mb_y * 16 * linesize[0];
+                uint8_t *last_mb_ptr = s->last_pic->f.data[0] +
+                                       mb_x * 16 + mb_y * 16 * linesize[0];
 
                 if (s->avctx->codec_id == AV_CODEC_ID_H264) {
                     // FIXME
                 } else {
-                    ff_thread_await_progress(&s->last_picture_ptr->f,
-                                             mb_y, 0);
+                    ff_thread_await_progress(&s->last_pic->f, mb_y, 0);
                 }
-                is_intra_likely += s->dsp.sad[0](NULL, last_mb_ptr, mb_ptr                    , s->linesize, 16);
+                is_intra_likely += s->dsp->sad[0](NULL, last_mb_ptr, mb_ptr,
+                                                 linesize[0], 16);
                 // FIXME need await_progress() here
-                is_intra_likely -= s->dsp.sad[0](NULL, last_mb_ptr, last_mb_ptr+s->linesize*16, s->linesize, 16);
+                is_intra_likely -= s->dsp->sad[0](NULL, last_mb_ptr,
+                                                 last_mb_ptr + linesize[0] * 16,
+                                                 linesize[0], 16);
             } else {
-                if (IS_INTRA(s->current_picture.f.mb_type[mb_xy]))
+                if (IS_INTRA(s->cur_pic->f.mb_type[mb_xy]))
                    is_intra_likely++;
                 else
                    is_intra_likely--;
@@ -817,9 +751,9 @@
     return is_intra_likely > 0;
 }
 
-void ff_er_frame_start(MpegEncContext *s)
+void ff_er_frame_start(ERContext *s)
 {
-    if (!s->err_recognition)
+    if (!s->avctx->err_recognition)
         return;
 
     memset(s->error_status_table, ER_MB_ERROR | VP_START | ER_MB_END,
@@ -835,7 +769,7 @@
  * @param status the status at the end (ER_MV_END, ER_AC_ERROR, ...), it is
  *               assumed that no earlier end or error of the same type occurred
  */
-void ff_er_add_slice(MpegEncContext *s, int startx, int starty,
+void ff_er_add_slice(ERContext *s, int startx, int starty,
                      int endx, int endy, int status)
 {
     const int start_i  = av_clip(startx + starty * s->mb_width, 0, s->mb_num - 1);
@@ -853,7 +787,7 @@
         return;
     }
 
-    if (!s->err_recognition)
+    if (!s->avctx->err_recognition)
         return;
 
     mask &= ~VP_START;
@@ -903,37 +837,53 @@
     }
 }
 
-void ff_er_frame_end(MpegEncContext *s)
+void ff_er_frame_end(ERContext *s)
 {
+    int *linesize = s->cur_pic->f.linesize;
     int i, mb_x, mb_y, error, error_type, dc_error, mv_error, ac_error;
     int distance;
     int threshold_part[4] = { 100, 100, 100 };
     int threshold = 50;
     int is_intra_likely;
     int size = s->b8_stride * 2 * s->mb_height;
-    Picture *pic = s->current_picture_ptr;
 
     /* We do not support ER of field pictures yet,
      * though it should not crash if enabled. */
-    if (!s->err_recognition || s->error_count == 0 || s->avctx->lowres ||
+    if (!s->avctx->err_recognition || s->error_count == 0              ||
+        s->avctx->lowres                                               ||
         s->avctx->hwaccel                                              ||
         s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU          ||
-        s->picture_structure != PICT_FRAME                             ||
+        !s->cur_pic || s->cur_pic->field_picture                               ||
         s->error_count == 3 * s->mb_width *
                           (s->avctx->skip_top + s->avctx->skip_bottom)) {
         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 ||
+            s->last_pic->f.format != s->cur_pic->f.format) {
+            av_log(s->avctx, AV_LOG_WARNING, "Cannot use previous picture in error concealment\n");
+            s->last_pic = NULL;
+        }
+    }
+    if (s->next_pic) {
+        if (s->next_pic->f.width  != s->cur_pic->f.width  ||
+            s->next_pic->f.height != s->cur_pic->f.height ||
+            s->next_pic->f.format != s->cur_pic->f.format) {
+            av_log(s->avctx, AV_LOG_WARNING, "Cannot use next picture in error concealment\n");
+            s->next_pic = NULL;
+        }
+    }
 
-    if (s->current_picture.f.motion_val[0] == NULL) {
+    if (s->cur_pic->f.motion_val[0] == NULL) {
         av_log(s->avctx, AV_LOG_ERROR, "Warning MVs not available\n");
 
         for (i = 0; i < 2; i++) {
-            pic->f.ref_index[i]     = av_mallocz(s->mb_stride * s->mb_height * 4 * sizeof(uint8_t));
-            pic->motion_val_base[i] = av_mallocz((size + 4) * 2 * sizeof(uint16_t));
-            pic->f.motion_val[i]    = pic->motion_val_base[i] + 4;
+            s->cur_pic->f.ref_index[i]     = av_mallocz(s->mb_stride * s->mb_height * 4 * sizeof(uint8_t));
+            s->cur_pic->motion_val_base[i] = av_mallocz((size + 4) * 2 * sizeof(uint16_t));
+            s->cur_pic->f.motion_val[i]    = s->cur_pic->motion_val_base[i] + 4;
         }
-        pic->f.motion_subsample_log2 = 3;
-        s->current_picture = *s->current_picture_ptr;
+        s->cur_pic->f.motion_subsample_log2 = 3;
     }
 
     if (s->avctx->debug & FF_DEBUG_ER) {
@@ -994,7 +944,7 @@
     }
 #endif
     /* handle missing slices */
-    if (s->err_recognition & AV_EF_EXPLODE) {
+    if (s->avctx->err_recognition & AV_EF_EXPLODE) {
         int end_ok = 1;
 
         // FIXME + 100 hack
@@ -1084,7 +1034,7 @@
             mv_error++;
     }
     av_log(s->avctx, AV_LOG_INFO, "concealing %d DC, %d AC, %d MV errors in %c frame\n",
-           dc_error, ac_error, mv_error, av_get_picture_type_char(s->pict_type));
+           dc_error, ac_error, mv_error, av_get_picture_type_char(s->cur_pic->f.pict_type));
 
     is_intra_likely = is_intra_more_likely(s);
 
@@ -1096,25 +1046,28 @@
             continue;
 
         if (is_intra_likely)
-            s->current_picture.f.mb_type[mb_xy] = MB_TYPE_INTRA4x4;
+            s->cur_pic->f.mb_type[mb_xy] = MB_TYPE_INTRA4x4;
         else
-            s->current_picture.f.mb_type[mb_xy] = MB_TYPE_16x16 | MB_TYPE_L0;
+            s->cur_pic->f.mb_type[mb_xy] = MB_TYPE_16x16 | MB_TYPE_L0;
     }
 
     // change inter to intra blocks if no reference frames are available
-    if (!s->last_picture.f.data[0] && !s->next_picture.f.data[0])
+    if (!(s->last_pic && s->last_pic->f.data[0]) &&
+        !(s->next_pic && s->next_pic->f.data[0]))
         for (i = 0; i < s->mb_num; i++) {
             const int mb_xy = s->mb_index2xy[i];
-            if (!IS_INTRA(s->current_picture.f.mb_type[mb_xy]))
-                s->current_picture.f.mb_type[mb_xy] = MB_TYPE_INTRA4x4;
+            if (!IS_INTRA(s->cur_pic->f.mb_type[mb_xy]))
+                s->cur_pic->f.mb_type[mb_xy] = MB_TYPE_INTRA4x4;
         }
 
     /* handle inter blocks with damaged AC */
     for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
         for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
             const int mb_xy   = mb_x + mb_y * s->mb_stride;
-            const int mb_type = s->current_picture.f.mb_type[mb_xy];
-            int dir           = !s->last_picture.f.data[0];
+            const int mb_type = s->cur_pic->f.mb_type[mb_xy];
+            const int dir     = !(s->last_pic && s->last_pic->f.data[0]);
+            const int mv_dir  = dir ? MV_DIR_BACKWARD : MV_DIR_FORWARD;
+            int mv_type;
 
             error = s->error_status_table[mb_xy];
 
@@ -1125,38 +1078,33 @@
             if (!(error & ER_AC_ERROR))
                 continue; // undamaged inter
 
-            s->mv_dir     = dir ? MV_DIR_BACKWARD : MV_DIR_FORWARD;
-            s->mb_intra   = 0;
-            s->mb_skipped = 0;
             if (IS_8X8(mb_type)) {
                 int mb_index = mb_x * 2 + mb_y * 2 * s->b8_stride;
                 int j;
-                s->mv_type = MV_TYPE_8X8;
+                mv_type = MV_TYPE_8X8;
                 for (j = 0; j < 4; j++) {
-                    s->mv[0][j][0] = s->current_picture.f.motion_val[dir][mb_index + (j & 1) + (j >> 1) * s->b8_stride][0];
-                    s->mv[0][j][1] = s->current_picture.f.motion_val[dir][mb_index + (j & 1) + (j >> 1) * s->b8_stride][1];
+                    s->mv[0][j][0] = s->cur_pic->f.motion_val[dir][mb_index + (j & 1) + (j >> 1) * s->b8_stride][0];
+                    s->mv[0][j][1] = s->cur_pic->f.motion_val[dir][mb_index + (j & 1) + (j >> 1) * s->b8_stride][1];
                 }
             } else {
-                s->mv_type     = MV_TYPE_16X16;
-                s->mv[0][0][0] = s->current_picture.f.motion_val[dir][mb_x * 2 + mb_y * 2 * s->b8_stride][0];
-                s->mv[0][0][1] = s->current_picture.f.motion_val[dir][mb_x * 2 + mb_y * 2 * s->b8_stride][1];
+                mv_type     = MV_TYPE_16X16;
+                s->mv[0][0][0] = s->cur_pic->f.motion_val[dir][mb_x * 2 + mb_y * 2 * s->b8_stride][0];
+                s->mv[0][0][1] = s->cur_pic->f.motion_val[dir][mb_x * 2 + mb_y * 2 * s->b8_stride][1];
             }
 
-            s->dsp.clear_blocks(s->block[0]);
-
-            s->mb_x = mb_x;
-            s->mb_y = mb_y;
-            decode_mb(s, 0 /* FIXME h264 partitioned slices need this set */);
+            s->decode_mb(s->opaque, 0 /* FIXME h264 partitioned slices need this set */,
+                         mv_dir, mv_type, &s->mv, mb_x, mb_y, 0, 0);
         }
     }
 
     /* guess MVs */
-    if (s->pict_type == AV_PICTURE_TYPE_B) {
+    if (s->cur_pic->f.pict_type == AV_PICTURE_TYPE_B) {
         for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
             for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
                 int       xy      = mb_x * 2 + mb_y * 2 * s->b8_stride;
                 const int mb_xy   = mb_x + mb_y * s->mb_stride;
-                const int mb_type = s->current_picture.f.mb_type[mb_xy];
+                const int mb_type = s->cur_pic->f.mb_type[mb_xy];
+                int mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;
 
                 error = s->error_status_table[mb_xy];
 
@@ -1167,28 +1115,22 @@
                 if (!(error & ER_AC_ERROR))
                     continue; // undamaged inter
 
-                s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;
-                if (!s->last_picture.f.data[0])
-                    s->mv_dir &= ~MV_DIR_FORWARD;
-                if (!s->next_picture.f.data[0])
-                    s->mv_dir &= ~MV_DIR_BACKWARD;
-                s->mb_intra   = 0;
-                s->mv_type    = MV_TYPE_16X16;
-                s->mb_skipped = 0;
+                if (!(s->last_pic && s->last_pic->f.data[0]))
+                    mv_dir &= ~MV_DIR_FORWARD;
+                if (!(s->next_pic && s->next_pic->f.data[0]))
+                    mv_dir &= ~MV_DIR_BACKWARD;
 
                 if (s->pp_time) {
                     int time_pp = s->pp_time;
                     int time_pb = s->pb_time;
 
-                    if (s->avctx->codec_id == AV_CODEC_ID_H264) {
-                        // FIXME
-                    } else {
-                        ff_thread_await_progress(&s->next_picture_ptr->f, mb_y, 0);
-                    }
-                    s->mv[0][0][0] = s->next_picture.f.motion_val[0][xy][0] *  time_pb            / time_pp;
-                    s->mv[0][0][1] = s->next_picture.f.motion_val[0][xy][1] *  time_pb            / time_pp;
-                    s->mv[1][0][0] = s->next_picture.f.motion_val[0][xy][0] * (time_pb - time_pp) / time_pp;
-                    s->mv[1][0][1] = s->next_picture.f.motion_val[0][xy][1] * (time_pb - time_pp) / time_pp;
+                    av_assert0(s->avctx->codec_id != AV_CODEC_ID_H264);
+                    ff_thread_await_progress(&s->next_pic->f, mb_y, 0);
+
+                    s->mv[0][0][0] = s->next_pic->f.motion_val[0][xy][0] *  time_pb            / time_pp;
+                    s->mv[0][0][1] = s->next_pic->f.motion_val[0][xy][1] *  time_pb            / time_pp;
+                    s->mv[1][0][0] = s->next_pic->f.motion_val[0][xy][0] * (time_pb - time_pp) / time_pp;
+                    s->mv[1][0][1] = s->next_pic->f.motion_val[0][xy][1] * (time_pb - time_pp) / time_pp;
                 } else {
                     s->mv[0][0][0] = 0;
                     s->mv[0][0][1] = 0;
@@ -1196,10 +1138,8 @@
                     s->mv[1][0][1] = 0;
                 }
 
-                s->dsp.clear_blocks(s->block[0]);
-                s->mb_x = mb_x;
-                s->mb_y = mb_y;
-                decode_mb(s, 0);
+                s->decode_mb(s->opaque, 0, mv_dir, MV_TYPE_16X16, &s->mv,
+                             mb_x, mb_y, 0, 0);
             }
         }
     } else
@@ -1215,7 +1155,7 @@
             int16_t *dc_ptr;
             uint8_t *dest_y, *dest_cb, *dest_cr;
             const int mb_xy   = mb_x + mb_y * s->mb_stride;
-            const int mb_type = s->current_picture.f.mb_type[mb_xy];
+            const int mb_type = s->cur_pic->f.mb_type[mb_xy];
 
             error = s->error_status_table[mb_xy];
 
@@ -1224,9 +1164,9 @@
             // if (error & ER_MV_ERROR)
             //     continue; // inter data damaged FIXME is this good?
 
-            dest_y  = s->current_picture.f.data[0] + mb_x * 16 + mb_y * 16 * s->linesize;
-            dest_cb = s->current_picture.f.data[1] + mb_x *  8 + mb_y *  8 * s->uvlinesize;
-            dest_cr = s->current_picture.f.data[2] + mb_x *  8 + mb_y *  8 * s->uvlinesize;
+            dest_y  = s->cur_pic->f.data[0] + mb_x * 16 + mb_y * 16 * linesize[0];
+            dest_cb = s->cur_pic->f.data[1] + mb_x *  8 + mb_y *  8 * linesize[1];
+            dest_cr = s->cur_pic->f.data[2] + mb_x *  8 + mb_y *  8 * linesize[2];
 
             dc_ptr = &s->dc_val[0][mb_x * 2 + mb_y * 2 * s->b8_stride];
             for (n = 0; n < 4; n++) {
@@ -1235,7 +1175,7 @@
                     int x;
                     for (x = 0; x < 8; x++)
                        dc += dest_y[x + (n & 1) * 8 +
-                             (y + (n >> 1) * 8) * s->linesize];
+                             (y + (n >> 1) * 8) * linesize[0]];
                 }
                 dc_ptr[(n & 1) + (n >> 1) * s->b8_stride] = (dc + 4) >> 3;
             }
@@ -1244,8 +1184,8 @@
             for (y = 0; y < 8; y++) {
                 int x;
                 for (x = 0; x < 8; x++) {
-                    dcu += dest_cb[x + y * s->uvlinesize];
-                    dcv += dest_cr[x + y * s->uvlinesize];
+                    dcu += dest_cb[x + y * linesize[1]];
+                    dcv += dest_cr[x + y * linesize[2]];
                 }
             }
             s->dc_val[1][mb_x + mb_y * s->mb_stride] = (dcu + 4) >> 3;
@@ -1268,7 +1208,7 @@
         for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
             uint8_t *dest_y, *dest_cb, *dest_cr;
             const int mb_xy   = mb_x + mb_y * s->mb_stride;
-            const int mb_type = s->current_picture.f.mb_type[mb_xy];
+            const int mb_type = s->cur_pic->f.mb_type[mb_xy];
 
             error = s->error_status_table[mb_xy];
 
@@ -1277,9 +1217,9 @@
             if (!(error & ER_AC_ERROR))
                 continue; // undamaged
 
-            dest_y  = s->current_picture.f.data[0] + mb_x * 16 + mb_y * 16 * s->linesize;
-            dest_cb = s->current_picture.f.data[1] + mb_x *  8 + mb_y *  8 * s->uvlinesize;
-            dest_cr = s->current_picture.f.data[2] + mb_x *  8 + mb_y *  8 * s->uvlinesize;
+            dest_y  = s->cur_pic->f.data[0] + mb_x * 16 + mb_y * 16 * linesize[0];
+            dest_cb = s->cur_pic->f.data[1] + mb_x *  8 + mb_y *  8 * linesize[1];
+            dest_cr = s->cur_pic->f.data[2] + mb_x *  8 + mb_y *  8 * linesize[2];
 
             put_dc(s, dest_y, dest_cb, dest_cr, mb_x, mb_y);
         }
@@ -1288,20 +1228,20 @@
 
     if (s->avctx->error_concealment & FF_EC_DEBLOCK) {
         /* filter horizontal block boundaries */
-        h_block_filter(s, s->current_picture.f.data[0], s->mb_width * 2,
-                       s->mb_height * 2, s->linesize, 1);
-        h_block_filter(s, s->current_picture.f.data[1], s->mb_width,
-                       s->mb_height  , s->uvlinesize, 0);
-        h_block_filter(s, s->current_picture.f.data[2], s->mb_width,
-                       s->mb_height  , s->uvlinesize, 0);
+        h_block_filter(s, s->cur_pic->f.data[0], s->mb_width * 2,
+                       s->mb_height * 2, linesize[0], 1);
+        h_block_filter(s, s->cur_pic->f.data[1], s->mb_width,
+                       s->mb_height, linesize[1], 0);
+        h_block_filter(s, s->cur_pic->f.data[2], s->mb_width,
+                       s->mb_height, linesize[2], 0);
 
         /* filter vertical block boundaries */
-        v_block_filter(s, s->current_picture.f.data[0], s->mb_width * 2,
-                       s->mb_height * 2, s->linesize, 1);
-        v_block_filter(s, s->current_picture.f.data[1], s->mb_width,
-                       s->mb_height  , s->uvlinesize, 0);
-        v_block_filter(s, s->current_picture.f.data[2], s->mb_width,
-                       s->mb_height  , s->uvlinesize, 0);
+        v_block_filter(s, s->cur_pic->f.data[0], s->mb_width * 2,
+                       s->mb_height * 2, linesize[0], 1);
+        v_block_filter(s, s->cur_pic->f.data[1], s->mb_width,
+                       s->mb_height, linesize[1], 0);
+        v_block_filter(s, s->cur_pic->f.data[2], s->mb_width,
+                       s->mb_height, linesize[2], 0);
     }
 
 ec_clean:
@@ -1310,10 +1250,13 @@
         const int mb_xy = s->mb_index2xy[i];
         int       error = s->error_status_table[mb_xy];
 
-        if (s->pict_type != AV_PICTURE_TYPE_B &&
+        if (s->cur_pic->f.pict_type != AV_PICTURE_TYPE_B &&
             (error & (ER_DC_ERROR | ER_MV_ERROR | ER_AC_ERROR))) {
             s->mbskip_table[mb_xy] = 0;
         }
         s->mbintra_table[mb_xy] = 1;
     }
+    s->cur_pic = NULL;
+    s->next_pic    = NULL;
+    s->last_pic    = NULL;
 }
diff --git a/libavcodec/error_resilience.h b/libavcodec/error_resilience.h
new file mode 100644
index 0000000..970fdc2
--- /dev/null
+++ b/libavcodec/error_resilience.h
@@ -0,0 +1,79 @@
+/*
+ *
+ * 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_ERROR_RESILIENCE_H
+#define AVCODEC_ERROR_RESILIENCE_H
+
+#include <stdint.h>
+
+#include "avcodec.h"
+#include "dsputil.h"
+
+///< current MB is the first after a resync marker
+#define VP_START               1
+#define ER_AC_ERROR            2
+#define ER_DC_ERROR            4
+#define ER_MV_ERROR            8
+#define ER_AC_END              16
+#define ER_DC_END              32
+#define ER_MV_END              64
+
+#define ER_MB_ERROR (ER_AC_ERROR|ER_DC_ERROR|ER_MV_ERROR)
+#define ER_MB_END   (ER_AC_END|ER_DC_END|ER_MV_END)
+
+typedef struct ERContext {
+    AVCodecContext *avctx;
+    DSPContext *dsp;
+
+    int *mb_index2xy;
+    int mb_num;
+    int mb_width, mb_height;
+    int mb_stride;
+    int b8_stride;
+
+    int error_count, error_occurred;
+    uint8_t *error_status_table;
+    uint8_t *er_temp_buffer;
+    int16_t *dc_val[3];
+    uint8_t *mbskip_table;
+    uint8_t *mbintra_table;
+    int mv[2][4][2];
+
+    struct Picture *cur_pic;
+    struct Picture *last_pic;
+    struct Picture *next_pic;
+
+    uint16_t pp_time;
+    uint16_t pb_time;
+    int quarter_sample;
+    int partitioned_frame;
+    int ref_count;
+
+    void (*decode_mb)(void *opaque, int ref, int mv_dir, int mv_type,
+                      int (*mv)[2][4][2],
+                      int mb_x, int mb_y, int mb_intra, int mb_skipped);
+    void *opaque;
+} ERContext;
+
+void ff_er_frame_start(ERContext *s);
+void ff_er_frame_end(ERContext *s);
+void ff_er_add_slice(ERContext *s, int startx, int starty, int endx, int endy,
+                     int status);
+
+#endif /* AVCODEC_ERROR_RESILIENCE_H */
diff --git a/libavcodec/escape124.c b/libavcodec/escape124.c
index 94eadce..1865c38 100644
--- a/libavcodec/escape124.c
+++ b/libavcodec/escape124.c
@@ -20,6 +20,7 @@
  */
 
 #include "avcodec.h"
+#include "internal.h"
 
 #define BITSTREAM_READER_LE
 #include "get_bits.h"
@@ -197,7 +198,7 @@
                                        0x400, 0x800, 0x4000, 0x8000};
 
 static int escape124_decode_frame(AVCodecContext *avctx,
-                                  void *data, int *data_size,
+                                  void *data, int *got_frame,
                                   AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
@@ -233,7 +234,7 @@
     if (!(frame_flags & 0x114) || !(frame_flags & 0x7800000)) {
         av_log(NULL, AV_LOG_DEBUG, "Skipping frame\n");
 
-        *data_size = sizeof(AVFrame);
+        *got_frame = 1;
         *(AVFrame*)data = s->frame;
 
         return frame_size;
@@ -268,7 +269,7 @@
     }
 
     new_frame.reference = 3;
-    if (avctx->get_buffer(avctx, &new_frame)) {
+    if (ff_get_buffer(avctx, &new_frame)) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return -1;
     }
@@ -359,7 +360,7 @@
         avctx->release_buffer(avctx, &s->frame);
 
     *(AVFrame*)data = s->frame = new_frame;
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
 
     return frame_size;
 }
diff --git a/libavcodec/escape130.c b/libavcodec/escape130.c
index 97547bb..ca6a253 100644
--- a/libavcodec/escape130.c
+++ b/libavcodec/escape130.c
@@ -23,6 +23,8 @@
 
 #define BITSTREAM_READER_LE
 #include "get_bits.h"
+#include "internal.h"
+
 
 typedef struct Escape130Context {
     AVFrame frame;
@@ -91,13 +93,13 @@
  * Decode a single frame
  * @param avctx decoder context
  * @param data decoded frame
- * @param data_size size of the 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 *data_size,
+                                  void *data, int *got_frame,
                                   AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
@@ -129,7 +131,7 @@
     skip_bits_long(&gb, 128);
 
     new_frame.reference = 3;
-    if (avctx->get_buffer(avctx, &new_frame)) {
+    if (ff_get_buffer(avctx, &new_frame)) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return -1;
     }
@@ -300,7 +302,7 @@
         avctx->release_buffer(avctx, &s->frame);
 
     *(AVFrame*)data = s->frame = new_frame;
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
 
     return buf_size;
 }
diff --git a/libavcodec/evrcdata.h b/libavcodec/evrcdata.h
new file mode 100644
index 0000000..cde1f57
--- /dev/null
+++ b/libavcodec/evrcdata.h
@@ -0,0 +1,1499 @@
+/*
+ * Enhanced Variable Rate Codec, Service Option 3 decoder
+ * 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
+ */
+
+#ifndef AVCODEC_EVRCDATA_H
+#define AVCODEC_EVRCDATA_H
+
+/**
+ * @file
+ * Data tables for the EVRC decoder
+ * @author Paul B Mahol
+ */
+
+#include "libavutil/common.h"
+
+/**
+ * Rate 1/8 frame energy quantization
+ *
+ * TIA/IS-127 table 8-18
+ */
+static const float evrc_energy_quant[][3] = {
+{-0.2464E-01,-0.4005E-02,-0.1107E+00 }, { 0.8734E+00, 0.1004E+01, 0.9930E+00 },
+{ 0.4222E+00, 0.3894E+00, 0.5020E+00 }, { 0.1450E+01, 0.1328E+01, 0.1278E+01 },
+{ 0.1957E+00, 0.2169E+00, 0.2735E+00 }, { 0.1142E+01, 0.1240E+01, 0.1157E+01 },
+{ 0.7881E+00, 0.6778E+00, 0.4185E+00 }, { 0.1504E+01, 0.1468E+01, 0.1534E+01 },
+{ 0.3173E+00, 0.2693E+00,-0.9526E-01 }, { 0.1141E+01, 0.1154E+01, 0.1044E+01 },
+{ 0.5147E+00, 0.5784E+00, 0.8802E+00 }, { 0.1502E+01, 0.1407E+01, 0.1409E+01 },
+{ 0.3163E+00, 0.3592E+00, 0.2830E+00 }, { 0.1217E+01, 0.1213E+01, 0.1216E+01 },
+{ 0.1023E+01, 0.1139E+01,-0.9526E-01 }, { 0.1619E+01, 0.1655E+01, 0.1642E+01 },
+{ 0.1437E+00, 0.1505E+00, 0.6838E-01 }, { 0.9794E+00, 0.1021E+01, 0.1117E+01 },
+{ 0.4701E+00, 0.6426E+00, 0.5519E+00 }, { 0.1366E+01, 0.1397E+01, 0.1406E+01 },
+{ 0.2918E+00, 0.3022E+00, 0.2420E+00 }, { 0.1309E+01, 0.1241E+01, 0.1220E+01 },
+{ 0.7989E+00, 0.7654E+00, 0.7391E+00 }, { 0.1612E+01, 0.1502E+01, 0.1447E+01 },
+{ 0.2594E+00, 0.1948E+00, 0.2555E+00 }, { 0.1091E+01, 0.1150E+01, 0.1272E+01 },
+{ 0.3423E+00, 0.4150E+00, 0.1294E+01 }, { 0.1729E+01, 0.1377E+01, 0.1065E+01 },
+{ 0.4103E+00, 0.3287E+00, 0.3228E+00 }, { 0.1144E+01, 0.1281E+01, 0.1416E+01 },
+{ 0.1047E+01, 0.1117E+01, 0.6188E+00 }, { 0.1914E+01, 0.1777E+01, 0.1516E+01 },
+{-0.2117E-01, 0.2159E+00, 0.2351E+00 }, { 0.1093E+01, 0.1088E+01, 0.1026E+01 },
+{ 0.5567E+00, 0.5092E+00, 0.4654E+00 }, { 0.1510E+01, 0.1449E+01, 0.1201E+01 },
+{ 0.2362E+00, 0.3426E+00, 0.2549E+00 }, { 0.1340E+01, 0.1225E+01, 0.1117E+01 },
+{ 0.1203E+01, 0.3819E+00, 0.2269E+00 }, { 0.1373E+01, 0.1404E+01, 0.1830E+01 },
+{ 0.2570E+00, 0.2668E+00, 0.1636E+00 }, { 0.1219E+01, 0.1098E+01, 0.1122E+01 },
+{ 0.6985E+00, 0.8456E+00, 0.1069E+01 }, { 0.1550E+01, 0.1501E+01, 0.1388E+01 },
+{ 0.2870E+00, 0.3060E+00, 0.3599E+00 }, { 0.1178E+01, 0.1345E+01, 0.1302E+01 },
+{ 0.1270E+01, 0.1215E+01, 0.1812E+00 }, { 0.1725E+01, 0.1777E+01, 0.1693E+01 },
+{ 0.2074E+00, 0.2104E+00, 0.1539E+00 }, { 0.1105E+01, 0.1034E+01, 0.1104E+01 },
+{ 0.6683E+00, 0.6646E+00, 0.6639E+00 }, { 0.1403E+01, 0.1462E+01, 0.1435E+01 },
+{ 0.3389E+00, 0.3754E+00, 0.2150E+00 }, { 0.1288E+01, 0.1325E+01, 0.1257E+01 },
+{ 0.8933E+00, 0.8253E+00, 0.8133E+00 }, { 0.1555E+01, 0.1579E+01, 0.1565E+01 },
+{ 0.3264E+00, 0.2434E+00, 0.2852E+00 }, { 0.1242E+01, 0.1180E+01, 0.1202E+01 },
+{ 0.1314E+00, 0.1698E+00, 0.1646E+01 }, { 0.1797E+01, 0.1597E+01, 0.1241E+01 },
+{ 0.4721E+00, 0.5346E+00, 0.3066E+00 }, { 0.1274E+01, 0.1401E+01, 0.1351E+01 },
+{ 0.1455E+01, 0.1386E+01, 0.6430E+00 }, { 0.1828E+01, 0.1867E+01, 0.1825E+01 },
+{-0.3265E+00,-0.2956E+00,-0.2462E+00 }, { 0.1035E+01, 0.1020E+01, 0.1003E+01 },
+{ 0.3702E+00, 0.4307E+00, 0.7072E+00 }, { 0.1424E+01, 0.1345E+01, 0.1352E+01 },
+{ 0.2267E+00, 0.2680E+00, 0.3037E+00 }, { 0.1235E+01, 0.1249E+01, 0.1146E+01 },
+{ 0.9944E+00, 0.6485E+00, 0.5248E+00 }, { 0.1539E+01, 0.1492E+01, 0.1612E+01 },
+{ 0.3815E+00, 0.3360E+00,-0.9526E-01 }, { 0.1163E+01, 0.1144E+01, 0.1117E+01 },
+{ 0.6734E+00, 0.7656E+00, 0.1014E+01 }, { 0.1568E+01, 0.1438E+01, 0.1455E+01 },
+{ 0.3409E+00, 0.3317E+00, 0.3856E+00 }, { 0.1180E+01, 0.1284E+01, 0.1284E+01 },
+{ 0.1244E+01, 0.1214E+01,-0.9526E-01 }, { 0.1753E+01, 0.1598E+01, 0.1744E+01 },
+{ 0.1548E+00, 0.1388E+00, 0.2020E+00 }, { 0.1027E+01, 0.1133E+01, 0.1093E+01 },
+{ 0.3906E+00, 0.7505E+00, 0.5705E+00 }, { 0.1420E+01, 0.1357E+01, 0.1543E+01 },
+{ 0.3252E+00, 0.3136E+00, 0.2804E+00 }, { 0.1351E+01, 0.1309E+01, 0.1224E+01 },
+{ 0.8781E+00, 0.8095E+00, 0.7109E+00 }, { 0.1614E+01, 0.1580E+01, 0.1433E+01 },
+{ 0.3222E+00, 0.2298E+00, 0.2157E+00 }, { 0.1216E+01, 0.1077E+01, 0.1247E+01 },
+{ 0.1363E+01, 0.1280E+01, 0.1317E+01 }, { 0.1751E+01, 0.1457E+01, 0.1182E+01 },
+{ 0.4428E+00, 0.4082E+00, 0.3181E+00 }, { 0.1157E+01, 0.1227E+01, 0.1604E+01 },
+{ 0.1286E+01, 0.1268E+01, 0.8167E+00 }, { 0.1994E+01, 0.2018E+01, 0.1307E+01 },
+{ 0.2671E-01, 0.2594E+00, 0.3397E+00 }, { 0.1164E+01, 0.1080E+01, 0.9321E+00 },
+{ 0.5998E+00, 0.6076E+00, 0.5081E+00 }, { 0.1442E+01, 0.1442E+01, 0.1375E+01 },
+{ 0.2390E+00, 0.3554E+00, 0.3426E+00 }, { 0.1287E+01, 0.1307E+01, 0.1144E+01 },
+{ 0.1200E+01, 0.7495E+00, 0.3967E+00 }, { 0.1561E+01, 0.1517E+01, 0.1898E+01 },
+{ 0.3598E+00, 0.3463E+00, 0.1200E+00 }, { 0.1298E+01, 0.1125E+01, 0.1062E+01 },
+{ 0.7577E+00, 0.1013E+01, 0.1194E+01 }, { 0.1537E+01, 0.1513E+01, 0.1464E+01 },
+{ 0.4041E+00, 0.4038E+00, 0.3897E+00 }, { 0.1293E+01, 0.1219E+01, 0.1378E+01 },
+{ 0.1250E+01, 0.1391E+01, 0.2451E+00 }, { 0.1558E+01, 0.1764E+01, 0.1728E+01 },
+{ 0.2700E+00, 0.1894E+00, 0.1924E+00 }, { 0.1111E+01, 0.1112E+01, 0.1173E+01 },
+{ 0.7579E+00, 0.8342E+00, 0.4781E+00 }, { 0.1464E+01, 0.1477E+01, 0.1469E+01 },
+{ 0.4001E+00, 0.3104E+00, 0.2217E+00 }, { 0.1346E+01, 0.1421E+01, 0.1312E+01 },
+{ 0.1071E+01, 0.8967E+00, 0.7511E+00 }, { 0.1616E+01, 0.1551E+01, 0.1574E+01 },
+{ 0.3329E+00, 0.2785E+00, 0.3140E+00 }, { 0.1281E+01, 0.1209E+01, 0.1239E+01 },
+{ 0.2805E+00, 0.2687E+00, 0.1646E+01 }, { 0.1814E+01, 0.1514E+01, 0.1510E+01 },
+{ 0.6231E+00, 0.4200E+00, 0.3701E+00 }, { 0.1255E+01, 0.1429E+01, 0.1454E+01 },
+{ 0.1642E+01, 0.1581E+01, 0.7112E+00 }, { 0.1844E+01, 0.1963E+01, 0.1895E+01 },
+{-0.4208E-01,-0.1491E+00,-0.7639E-01 }, { 0.1046E+01, 0.9598E+00, 0.9176E+00 },
+{ 0.4478E+00, 0.4605E+00, 0.5111E+00 }, { 0.1521E+01, 0.1292E+01, 0.1342E+01 },
+{ 0.2220E+00, 0.2549E+00, 0.2510E+00 }, { 0.1186E+01, 0.1254E+01, 0.1171E+01 },
+{ 0.8999E+00, 0.4960E+00, 0.4943E+00 }, { 0.1423E+01, 0.1484E+01, 0.1620E+01 },
+{ 0.2796E+00, 0.2778E+00,-0.2820E+00 }, { 0.1170E+01, 0.1181E+01, 0.1076E+01 },
+{ 0.4068E+00, 0.8541E+00, 0.9352E+00 }, { 0.1584E+01, 0.1416E+01, 0.1387E+01 },
+{ 0.3325E+00, 0.3655E+00, 0.3340E+00 }, { 0.1224E+01, 0.1257E+01, 0.1245E+01 },
+{ 0.1061E+01, 0.1138E+01,-0.9526E-01 }, { 0.1681E+01, 0.1704E+01, 0.1673E+01 },
+{ 0.1932E+00, 0.1489E+00, 0.1258E+00 }, { 0.1023E+01, 0.1088E+01, 0.1145E+01 },
+{ 0.5190E+00, 0.6873E+00, 0.5172E+00 }, { 0.1380E+01, 0.1405E+01, 0.1474E+01 },
+{ 0.3393E+00, 0.3100E+00, 0.2231E+00 }, { 0.1354E+01, 0.1249E+01, 0.1270E+01 },
+{ 0.7363E+00, 0.8508E+00, 0.8247E+00 }, { 0.1612E+01, 0.1537E+01, 0.1509E+01 },
+{ 0.2952E+00, 0.2053E+00, 0.2590E+00 }, { 0.1138E+01, 0.1219E+01, 0.1262E+01 },
+{ 0.1345E+01, 0.1289E+01, 0.1338E+01 }, { 0.1437E+01, 0.1360E+01, 0.1442E+01 },
+{ 0.4826E+00, 0.3298E+00, 0.3842E+00 }, { 0.1219E+01, 0.1311E+01, 0.1413E+01 },
+{ 0.1212E+01, 0.1186E+01, 0.6357E+00 }, { 0.1873E+01, 0.1939E+01, 0.1674E+01 },
+{ 0.1260E+01, 0.1306E+01, 0.1368E+01 }, { 0.1146E+01, 0.1077E+01, 0.1025E+01 },
+{ 0.6029E+00, 0.5039E+00, 0.5781E+00 }, { 0.1514E+01, 0.1420E+01, 0.1324E+01 },
+{ 0.2652E+00, 0.3192E+00, 0.3042E+00 }, { 0.1368E+01, 0.1198E+01, 0.1200E+01 },
+{ 0.1234E+01, 0.4910E+00, 0.3464E-01 }, { 0.1347E+01, 0.1560E+01, 0.1861E+01 },
+{ 0.2766E+00, 0.2887E+00, 0.2029E+00 }, { 0.1257E+01, 0.1105E+01, 0.1145E+01 },
+{ 0.1351E+01, 0.1353E+01, 0.1406E+01 }, { 0.1506E+01, 0.1580E+01, 0.1362E+01 },
+{ 0.2794E+00, 0.3868E+00, 0.4277E+00 }, { 0.1234E+01, 0.1334E+01, 0.1336E+01 },
+{ 0.1280E+01, 0.1252E+01, 0.1805E+00 }, { 0.1387E+01, 0.1396E+01, 0.1434E+01 },
+{ 0.2902E+00, 0.1170E+00, 0.1698E+00 }, { 0.1134E+01, 0.1077E+01, 0.1117E+01 },
+{ 0.6986E+00, 0.7177E+00, 0.7366E+00 }, { 0.1370E+01, 0.1491E+01, 0.1495E+01 },
+{ 0.4031E+00, 0.5144E+00, 0.1751E+00 }, { 0.1333E+01, 0.1377E+01, 0.1257E+01 },
+{ 0.9212E+00, 0.8934E+00, 0.8897E+00 }, { 0.1589E+01, 0.1614E+01, 0.1523E+01 },
+{ 0.3152E+00, 0.2164E+00, 0.3230E+00 }, { 0.1300E+01, 0.1145E+01, 0.1212E+01 },
+{ 0.1269E+01, 0.1245E+01, 0.1497E+01 }, { 0.1763E+01, 0.1716E+01, 0.1311E+01 },
+{ 0.4702E+00, 0.5422E+00, 0.4306E+00 }, { 0.1342E+01, 0.1433E+01, 0.1423E+01 },
+{ 0.1472E+01, 0.1404E+01, 0.8371E+00 }, { 0.1936E+01, 0.1883E+01, 0.1838E+01 },
+{ 0.1266E+01, 0.1295E+01, 0.1302E+01 }, { 0.1074E+01, 0.1002E+01, 0.1023E+01 },
+{ 0.5206E+00, 0.4045E+00, 0.6549E+00 }, { 0.1457E+01, 0.1378E+01, 0.1363E+01 },
+{ 0.2715E+00, 0.2629E+00, 0.2841E+00 }, { 0.1264E+01, 0.1271E+01, 0.1175E+01 },
+{ 0.1337E+01, 0.1305E+01, 0.1306E+01 }, { 0.1555E+01, 0.1571E+01, 0.1657E+01 },
+{ 0.3341E+00, 0.4147E+00,-0.3648E+00 }, { 0.1188E+01, 0.1185E+01, 0.1161E+01 },
+{ 0.6198E+00, 0.7208E+00, 0.1157E+01 }, { 0.1582E+01, 0.1465E+01, 0.1513E+01 },
+{ 0.3839E+00, 0.3651E+00, 0.3814E+00 }, { 0.1214E+01, 0.1256E+01, 0.1292E+01 },
+{ 0.1361E+01, 0.1363E+01, 0.1312E+01 }, { 0.1793E+01, 0.1693E+01, 0.1669E+01 },
+{ 0.1889E+00, 0.1275E+00, 0.2534E+00 }, { 0.1066E+01, 0.1174E+01, 0.1133E+01 },
+{ 0.4999E+00, 0.8207E+00, 0.5813E+00 }, { 0.1478E+01, 0.1416E+01, 0.1497E+01 },
+{ 0.3814E+00, 0.3138E+00, 0.2889E+00 }, { 0.1396E+01, 0.1265E+01, 0.1233E+01 },
+{ 0.9458E+00, 0.9161E+00, 0.5875E+00 }, { 0.1672E+01, 0.1632E+01, 0.1553E+01 },
+{ 0.3505E+00, 0.2525E+00, 0.2364E+00 }, { 0.1211E+01, 0.1138E+01, 0.1235E+01 },
+{ 0.1391E+01, 0.1231E+01, 0.1355E+01 }, { 0.1783E+01, 0.1510E+01, 0.1199E+01 },
+{ 0.4227E+00, 0.4548E+00, 0.3671E+00 }, { 0.1281E+01, 0.1254E+01, 0.1661E+01 },
+{ 0.1338E+01, 0.1379E+01, 0.9531E+00 }, { 0.2148E+01, 0.1965E+01, 0.1584E+01 },
+{ 0.9324E-01, 0.3575E+00, 0.3522E+00 }, { 0.1212E+01, 0.1086E+01, 0.1044E+01 },
+{ 0.6128E+00, 0.6136E+00, 0.6060E+00 }, { 0.1484E+01, 0.1507E+01, 0.1396E+01 },
+{ 0.2820E+00, 0.3848E+00, 0.3156E+00 }, { 0.1368E+01, 0.1287E+01, 0.1128E+01 },
+{ 0.1369E+01, 0.1352E+01, 0.1358E+01 }, { 0.1381E+01, 0.1765E+01, 0.2113E+01 },
+{ 0.1314E+01, 0.1345E+01, 0.1334E+01 }, { 0.1290E+01, 0.1172E+01, 0.1119E+01 },
+{ 0.1304E+01, 0.1377E+01, 0.1427E+01 }, { 0.1490E+01, 0.1540E+01, 0.1536E+01 },
+{ 0.3994E+00, 0.4402E+00, 0.4173E+00 }, { 0.1323E+01, 0.1307E+01, 0.1392E+01 },
+{ 0.1400E+01, 0.1388E+01, 0.1369E+01 }, { 0.1669E+01, 0.1818E+01, 0.1834E+01 },
+{ 0.2742E+00, 0.2235E+00, 0.1986E+00 }, { 0.1137E+01, 0.1139E+01, 0.1201E+01 },
+{ 0.1324E+01, 0.1385E+01, 0.1349E+01 }, { 0.1455E+01, 0.1574E+01, 0.1454E+01 },
+{ 0.5019E+00, 0.3255E+00, 0.2555E+00 }, { 0.1388E+01, 0.1438E+01, 0.1300E+01 },
+{ 0.1394E+01, 0.1349E+01, 0.1411E+01 }, { 0.1639E+01, 0.1580E+01, 0.1681E+01 },
+{ 0.3920E+00, 0.2498E+00, 0.3523E+00 }, { 0.1301E+01, 0.1221E+01, 0.1285E+01 },
+{ 0.1318E+01, 0.1342E+01, 0.1494E+01 }, { 0.1910E+01, 0.1680E+01, 0.1470E+01 },
+{ 0.6082E+00, 0.5270E+00, 0.4173E+00 }, { 0.1255E+01, 0.1477E+01, 0.1503E+01 },
+{ 0.1807E+01, 0.1742E+01, 0.6553E+00 }, { 0.2000E+01, 0.2072E+01, 0.2051E+01 }};
+
+/**
+ * LSP vector quantization tables
+ *
+ * TIA/IS-127 tables 8-1 through 8-9
+ */
+
+static const float evrc_lspq_full_codebook1[64][2] = {
+{1.42016308E-2, 1.93881616E-2}, {2.91667543E-2, 6.51749149E-2},
+{2.06693150E-2, 4.97564934E-2}, {3.94719802E-2, 9.55850929E-2},
+{2.27012448E-2, 3.96625809E-2}, {5.38789518E-2, 6.28347769E-2},
+{2.90525518E-2, 5.73435798E-2}, {4.48280610E-2, 1.15364626E-1},
+{1.94110647E-2, 3.46889682E-2}, {4.37502973E-2, 6.75228462E-2},
+{3.55497338E-2, 4.94086780E-2}, {6.99219853E-2, 8.67279768E-2},
+{2.77880151E-2, 4.65748496E-2}, {5.79111017E-2, 6.74542487E-2},
+{4.74664383E-2, 5.50271496E-2}, {7.88898915E-2, 1.22443043E-1},
+{2.21715886E-2, 3.02628800E-2}, {3.39134485E-2, 7.17703998E-2},
+{3.17989141E-2, 4.98996116E-2}, {6.11555986E-2, 8.73361230E-2},
+{2.67506503E-2, 3.96735854E-2}, {4.44100983E-2, 8.26731324E-2},
+{3.89172547E-2, 5.65788932E-2}, {6.04800619E-2, 1.04536951E-1},
+{2.69156620E-2, 3.57168876E-2}, {4.11117189E-2, 7.33322948E-2},
+{4.12660725E-2, 4.85165231E-2}, {7.18049556E-2, 1.06202349E-1},
+{3.38037871E-2, 4.24300395E-2}, {5.91818243E-2, 7.97467977E-2},
+{4.70107906E-2, 6.28563762E-2}, {9.42011923E-2, 1.30053163E-1},
+{1.94244273E-2, 2.72732340E-2}, {3.70831676E-2, 6.64898157E-2},
+{2.80136354E-2, 5.15984930E-2}, {5.34461029E-2, 9.25904214E-2},
+{2.54959203E-2, 4.32844795E-2}, {5.51860742E-2, 7.36182332E-2},
+{3.39851119E-2, 6.05329126E-2}, {6.18182123E-2, 1.34581268E-1},
+{2.35669166E-2, 3.55242006E-2}, {5.10804243E-2, 6.79562539E-2},
+{3.83464955E-2, 5.23469411E-2}, {7.44275749E-2, 9.66108292E-2},
+{3.18591148E-2, 4.62123118E-2}, {6.18909821E-2, 7.33231753E-2},
+{4.41718437E-2, 5.79240918E-2}, {7.93596208E-2, 1.41177371E-1},
+{2.47412287E-2, 3.23629379E-2}, {3.36563922E-2, 8.04650635E-2},
+{3.37943695E-2, 5.44977151E-2}, {6.53648973E-2, 9.52775925E-2},
+{2.93364152E-2, 4.28411029E-2}, {5.27870469E-2, 8.16159397E-2},
+{4.00724895E-2, 6.18144684E-2}, {6.75848573E-2, 1.17196076E-1},
+{3.03064957E-2, 3.86914052E-2}, {4.83106263E-2, 7.42383003E-2},
+{4.37548272E-2, 5.22842295E-2}, {8.32310021E-2, 1.09881967E-1},
+{3.75600643E-2, 4.53217216E-2}, {6.60113171E-2, 7.97580183E-2},
+{5.03225066E-2, 5.90176322E-2}, {8.77133310E-2, 1.63187444E-1}};
+
+static const float evrc_lspq_full_codebook2[64][2] = {
+{5.21959551E-2, 8.38445649E-2}, {1.05874076E-1, 1.28694162E-1},
+{5.48323877E-2, 1.33842856E-1}, {1.17768474E-1, 1.94037274E-1},
+{5.36086522E-2, 1.11398734E-1}, {1.19989693E-1, 1.47474691E-1},
+{8.00373554E-2, 1.42999724E-1}, {1.64086595E-1, 2.09821835E-1},
+{5.21059223E-2, 9.95229408E-2}, {8.67567956E-2, 1.85966507E-1},
+{7.77341127E-2, 1.31506845E-1}, {1.60545513E-1, 1.81930289E-1},
+{7.42243677E-2, 1.10437103E-1}, {1.18635088E-1, 1.75306752E-1},
+{6.61557764E-2, 1.64441928E-1}, {1.96810856E-1, 2.16682002E-1},
+{6.05317838E-2, 9.45408568E-2}, {1.06271386E-1, 1.48013934E-1},
+{5.87486550E-2, 1.47724584E-1}, {1.34816468E-1, 2.01517954E-1},
+{6.59698322E-2, 1.16447397E-1}, {1.32297173E-1, 1.53267249E-1},
+{9.26660746E-2, 1.46725491E-1}, {1.79285541E-1, 2.19705954E-1},
+{7.06458464E-2, 9.99924466E-2}, {1.06500491E-1, 1.79443434E-1},
+{8.79249722E-2, 1.25287697E-1}, {1.53640196E-1, 1.97852716E-1},
+{8.88430104E-2, 1.12465657E-1}, {1.48286715E-1, 1.67517021E-1},
+{8.16568136E-2, 1.69274017E-1}, {2.07810536E-1, 2.31033549E-1},
+{6.14927970E-2, 8.36263224E-2}, {1.14473253E-1, 1.36779979E-1},
+{6.87129870E-2, 1.38099059E-1}, {1.10511415E-1, 2.15352878E-1},
+{5.55652268E-2, 1.22242786E-1}, {1.20557591E-1, 1.61072448E-1},
+{8.32249671E-2, 1.55475482E-1}, {1.61638483E-1, 2.28268847E-1},
+{6.29152283E-2, 1.06229566E-1}, {8.29186887E-2, 2.06774518E-1},
+{8.84756893E-2, 1.35799959E-1}, {1.69772223E-1, 1.93773940E-1},
+{7.77297840E-2, 1.20287232E-1}, {1.30648017E-1, 1.84331819E-1},
+{6.91939592E-2, 1.84218004E-1}, {2.03904077E-1, 2.49715164E-1},
+{7.07671717E-2, 9.03186128E-2}, {1.08471557E-1, 1.61966518E-1},
+{7.16886371E-2, 1.51093170E-1}, {1.38779536E-1, 2.18801782E-1},
+{6.75907061E-2, 1.26740307E-1}, {1.33412346E-1, 1.68838874E-1},
+{9.61822569E-2, 1.58728704E-1}, {1.86485633E-1, 2.36560926E-1},
+{8.23447108E-2, 1.02126025E-1}, {1.00336641E-1, 1.94918498E-1},
+{9.95981991E-2, 1.36425093E-1}, {1.82448462E-1, 2.03655198E-1},
+{9.78890732E-2, 1.21145472E-1}, {1.45453140E-1, 1.83604524E-1},
+{9.58395451E-2, 1.72194853E-1}, {2.23295853E-1, 2.46418610E-1}};
+
+static const float evrc_lspq_full_codebook3[512][3] = {
+{1.36425778E-1, 1.68651849E-1, 2.04688221E-1},
+{1.85717627E-1, 2.28756160E-1, 2.51958042E-1},
+{1.22760192E-1, 1.85950696E-1, 2.79446691E-1},
+{1.96468458E-1, 2.64484435E-1, 2.89318889E-1},
+{1.25653744E-1, 1.50529265E-1, 2.76144296E-1},
+{1.96301565E-1, 2.41699994E-1, 2.88230687E-1},
+{1.40099391E-1, 2.22365588E-1, 2.74666578E-1},
+{2.59952307E-1, 2.75394946E-1, 3.10975939E-1},
+{1.58452198E-1, 1.88591003E-1, 2.07339197E-1},
+{1.95616230E-1, 2.21379519E-1, 2.87022918E-1},
+{1.69424579E-1, 2.01614648E-1, 2.75669187E-1},
+{2.12393746E-1, 2.64250666E-1, 3.17967504E-1},
+{1.82965085E-1, 1.99547559E-1, 2.29538843E-1},
+{2.15200707E-1, 2.62409419E-1, 2.82432705E-1},
+{1.46404549E-1, 2.36966729E-1, 2.90067106E-1},
+{2.45338634E-1, 3.03358108E-1, 3.42260152E-1},
+{1.37478963E-1, 1.58276558E-1, 2.39217222E-1},
+{2.01999024E-1, 2.20102608E-1, 2.69546896E-1},
+{1.18350029E-1, 2.30206400E-1, 2.83554822E-1},
+{2.25519255E-1, 2.72272140E-1, 3.06072980E-1},
+{1.35661438E-1, 1.91633970E-1, 2.65912026E-1},
+{1.95733085E-1, 2.31926173E-1, 3.14376086E-1},
+{1.67998984E-1, 2.27706313E-1, 2.76947826E-1},
+{2.50170559E-1, 3.01627070E-1, 3.21084231E-1},
+{1.33492306E-1, 2.01223105E-1, 2.33893991E-1},
+{2.06442133E-1, 2.38704175E-1, 2.77560145E-1},
+{1.79048792E-1, 1.95776582E-1, 2.80656606E-1},
+{2.06193641E-1, 2.64055401E-1, 3.33098441E-1},
+{1.75185278E-1, 1.91166341E-1, 2.57540315E-1},
+{2.28398636E-1, 2.45296657E-1, 3.08980793E-1},
+{1.80859819E-1, 2.43579060E-1, 2.96631068E-1},
+{2.76152968E-1, 3.08256060E-1, 3.46822590E-1},
+{1.37115732E-1, 1.80057764E-1, 2.20953465E-1},
+{1.81370094E-1, 2.26770103E-1, 2.70392686E-1},
+{1.25246510E-1, 1.79606944E-1, 3.10376436E-1},
+{1.90708354E-1, 2.87734240E-1, 3.13476235E-1},
+{1.30486086E-1, 1.60435289E-1, 3.00243706E-1},
+{1.97318628E-1, 2.56378502E-1, 2.78474301E-1},
+{1.58597067E-1, 2.37381399E-1, 2.62910336E-1},
+{2.61825919E-1, 2.77717203E-1, 3.31382245E-1},
+{1.64160743E-1, 1.85841531E-1, 2.35615849E-1},
+{2.09486142E-1, 2.21452802E-1, 2.92153865E-1},
+{1.66807845E-1, 2.13641763E-1, 2.70675927E-1},
+{2.29834273E-1, 2.88374633E-1, 3.06238323E-1},
+{1.82154253E-1, 2.00822473E-1, 2.40169376E-1},
+{2.24944726E-1, 2.69813925E-1, 2.91401237E-1},
+{1.63940564E-1, 2.50341147E-1, 2.78307766E-1},
+{2.56727993E-1, 2.95103759E-1, 3.53297085E-1},
+{1.40218839E-1, 1.76687688E-1, 2.46773273E-1},
+{2.15291306E-1, 2.29216009E-1, 2.64283627E-1},
+{1.21002659E-1, 2.18333840E-1, 3.22341293E-1},
+{2.54243195E-1, 2.73986191E-1, 2.96262473E-1},
+{1.60385415E-1, 1.83762908E-1, 2.81598717E-1},
+{1.87832162E-1, 2.37420350E-1, 3.29777509E-1},
+{1.77788362E-1, 2.26703495E-1, 3.02322537E-1},
+{2.75108218E-1, 2.93730587E-1, 3.12373787E-1},
+{1.70116410E-1, 1.85232103E-1, 2.46125028E-1},
+{2.21754774E-1, 2.39912242E-1, 2.86891907E-1},
+{1.95083722E-1, 2.08337873E-1, 2.88349718E-1},
+{2.37536535E-1, 2.75004476E-1, 3.39786023E-1},
+{1.88369319E-1, 2.04371840E-1, 2.57375032E-1},
+{2.47250155E-1, 2.60551840E-1, 3.02137524E-1},
+{1.66944191E-1, 2.46912360E-1, 3.18894416E-1},
+{2.78118610E-1, 3.13011140E-1, 3.65329295E-1},
+{1.45213529E-1, 1.63051456E-1, 2.24912614E-1},
+{2.05692515E-1, 2.20831484E-1, 2.52817810E-1},
+{1.21125661E-1, 1.96374118E-1, 3.00122708E-1},
+{2.15566799E-1, 2.65657336E-1, 2.99202889E-1},
+{1.09134212E-1, 1.78472102E-1, 2.88323194E-1},
+{2.03508541E-1, 2.40347922E-1, 2.96309739E-1},
+{1.53101787E-1, 2.25415319E-1, 2.84843713E-1},
+{2.50233442E-1, 2.77736932E-1, 3.24840695E-1},
+{1.66308925E-1, 1.94173396E-1, 2.11635381E-1},
+{2.01289460E-1, 2.26062179E-1, 2.93246478E-1},
+{1.49518773E-1, 2.14201719E-1, 2.83894747E-1},
+{2.21836135E-1, 2.85231501E-1, 3.20082635E-1},
+{1.89573213E-1, 2.06577629E-1, 2.30332345E-1},
+{2.31247649E-1, 2.46864259E-1, 2.89846569E-1},
+{1.39116928E-1, 2.59189934E-1, 2.98019558E-1},
+{2.44512573E-1, 2.82671362E-1, 3.61258298E-1},
+{1.22530967E-1, 1.68514788E-1, 2.70879298E-1},
+{2.04372838E-1, 2.30398357E-1, 2.71792918E-1},
+{1.42643943E-1, 2.22405583E-1, 2.92057186E-1},
+{2.42643669E-1, 2.77429372E-1, 2.97135502E-1},
+{1.52048603E-1, 1.96921080E-1, 2.61013240E-1},
+{2.17875019E-1, 2.45840371E-1, 3.08138579E-1},
+{1.90109268E-1, 2.31099129E-1, 2.80178159E-1},
+{2.54314184E-1, 2.94079810E-1, 3.39649171E-1},
+{1.56698599E-1, 2.08597451E-1, 2.28010774E-1},
+{2.25088730E-1, 2.50014484E-1, 2.76250154E-1},
+{1.78219035E-1, 1.98228240E-1, 3.04198891E-1},
+{2.08567217E-1, 2.92395383E-1, 3.46786886E-1},
+{1.71052113E-1, 2.03438759E-1, 2.62644321E-1},
+{2.30275467E-1, 2.58817524E-1, 3.11986536E-1},
+{1.85333565E-1, 2.45760202E-1, 3.10553998E-1},
+{2.89413869E-1, 3.11095625E-1, 3.46476167E-1},
+{1.50332406E-1, 1.67538226E-1, 2.40182847E-1},
+{1.79971650E-1, 2.37168610E-1, 2.60899693E-1},
+{1.49866179E-1, 1.97890073E-1, 3.07916552E-1},
+{2.10799649E-1, 2.88180083E-1, 3.29747230E-1},
+{1.31711140E-1, 1.65906459E-1, 3.22898000E-1},
+{2.14832023E-1, 2.52822131E-1, 2.97547072E-1},
+{1.83760419E-1, 2.37523615E-1, 2.74610013E-1},
+{2.55575180E-1, 2.75439233E-1, 3.46021861E-1},
+{1.82662204E-1, 1.99470907E-1, 2.16051653E-1},
+{2.09240332E-1, 2.22406715E-1, 3.02382857E-1},
+{1.84088245E-1, 2.11327791E-1, 2.82538086E-1},
+{2.41171077E-1, 2.97036022E-1, 3.15979272E-1},
+{1.96804658E-1, 2.11815894E-1, 2.41647676E-1},
+{2.42761984E-1, 2.58586556E-1, 2.93204397E-1},
+{1.58905461E-1, 2.65077025E-1, 2.89881319E-1},
+{2.58060575E-1, 3.18903178E-1, 3.47846836E-1},
+{1.48766384E-1, 1.66853935E-1, 2.66827434E-1},
+{2.15942249E-1, 2.29938298E-1, 2.76041597E-1},
+{1.38410494E-1, 2.39283442E-1, 3.27972382E-1},
+{2.43765280E-1, 2.88408488E-1, 3.06048721E-1},
+{1.70157120E-1, 1.89986289E-1, 2.81219155E-1},
+{2.19117031E-1, 2.58005291E-1, 3.26571971E-1},
+{1.92163572E-1, 2.23614186E-1, 2.98683077E-1},
+{2.73545444E-1, 3.12078089E-1, 3.30766588E-1},
+{1.62452087E-1, 2.04930902E-1, 2.53337711E-1},
+{2.23855302E-1, 2.37671077E-1, 3.03202003E-1},
+{1.93955287E-1, 2.12335557E-1, 3.07566851E-1},
+{2.29912683E-1, 2.97581047E-1, 3.37499231E-1},
+{1.89335391E-1, 2.04148144E-1, 2.78609782E-1},
+{2.42303565E-1, 2.73163110E-1, 3.15361649E-1},
+{1.55009672E-1, 2.88095146E-1, 3.35996419E-1},
+{2.73716152E-1, 3.31215471E-1, 3.62539083E-1},
+{1.52389362E-1, 1.72619134E-1, 1.90585673E-1},
+{1.96988270E-1, 2.26309747E-1, 2.46197492E-1},
+{1.20555148E-1, 2.06369758E-1, 2.81199783E-1},
+{1.93709418E-1, 2.71900505E-1, 3.01332921E-1},
+{1.36701152E-1, 1.54093146E-1, 2.82258362E-1},
+{1.97299168E-1, 2.53656298E-1, 2.90315062E-1},
+{1.43463776E-1, 2.43872911E-1, 2.75533706E-1},
+{2.58477271E-1, 2.73279876E-1, 3.21119100E-1},
+{1.54406175E-1, 1.93793535E-1, 2.15884149E-1},
+{2.05979452E-1, 2.24277020E-1, 2.85732359E-1},
+{1.74535319E-1, 2.08482355E-1, 2.79668540E-1},
+{2.18844578E-1, 2.72486299E-1, 3.27095598E-1},
+{1.77609727E-1, 2.12990195E-1, 2.39119649E-1},
+{2.29163751E-1, 2.59165913E-1, 2.83514649E-1},
+{1.57353148E-1, 2.39961296E-1, 3.04263145E-1},
+{2.45613828E-1, 3.16824526E-1, 3.42909366E-1},
+{1.42953232E-1, 1.61905348E-1, 2.53710240E-1},
+{2.10192814E-1, 2.22847700E-1, 2.71103770E-1},
+{1.26843944E-1, 2.16709048E-1, 2.97734648E-1},
+{2.31000140E-1, 2.80109137E-1, 2.99707443E-1},
+{1.52980462E-1, 1.93996876E-1, 2.72895664E-1},
+{2.12860718E-1, 2.41545349E-1, 3.16518754E-1},
+{1.71154693E-1, 2.22469687E-1, 2.93786496E-1},
+{2.51988232E-1, 3.04254979E-1, 3.31269950E-1},
+{1.33188918E-1, 2.07924992E-1, 2.55362093E-1},
+{2.12044910E-1, 2.42189646E-1, 2.88903743E-1},
+{1.84612468E-1, 2.01143622E-1, 2.86360770E-1},
+{2.18286708E-1, 2.76752442E-1, 3.44581515E-1},
+{1.83562174E-1, 1.99478507E-1, 2.62156576E-1},
+{2.33130530E-1, 2.49596909E-1, 3.15842837E-1},
+{1.89898983E-1, 2.46874869E-1, 2.97132462E-1},
+{2.75022447E-1, 3.22490305E-1, 3.46977681E-1},
+{1.42305329E-1, 1.92689180E-1, 2.16155857E-1},
+{1.95676163E-1, 2.22268641E-1, 2.76587397E-1},
+{1.33241490E-1, 1.97791785E-1, 3.22897941E-1},
+{1.84865132E-1, 2.97106177E-1, 3.26105148E-1},
+{1.50203660E-1, 1.76781267E-1, 2.91536182E-1},
+{2.03144446E-1, 2.59616166E-1, 2.99156040E-1},
+{1.65488973E-1, 2.38342047E-1, 2.87493914E-1},
+{2.71071255E-1, 2.89544493E-1, 3.19521040E-1},
+{1.68598369E-1, 1.98825568E-1, 2.30347604E-1},
+{2.13811651E-1, 2.34471768E-1, 2.90959626E-1},
+{1.74605444E-1, 2.17256010E-1, 2.85688072E-1},
+{2.28503481E-1, 2.96190292E-1, 3.16534668E-1},
+{1.87172607E-1, 2.20547438E-1, 2.39688724E-1},
+{2.28884771E-1, 2.63583153E-1, 3.01329464E-1},
+{1.77897051E-1, 2.58131474E-1, 2.81487674E-1},
+{2.59513617E-1, 3.07204396E-1, 3.48793596E-1},
+{1.45224437E-1, 1.78715974E-1, 2.59186983E-1},
+{2.19062313E-1, 2.38223523E-1, 2.60461539E-1},
+{1.43650874E-1, 2.09760785E-1, 3.15830201E-1},
+{2.50127465E-1, 2.79182345E-1, 3.05153579E-1},
+{1.48986444E-1, 2.01226771E-1, 2.82543689E-1},
+{2.08387777E-1, 2.35603899E-1, 3.45363885E-1},
+{1.85830340E-1, 2.21607298E-1, 3.10773641E-1},
+{2.80904710E-1, 2.95469791E-1, 3.25499445E-1},
+{1.72967300E-1, 1.97078109E-1, 2.45801106E-1},
+{2.19495699E-1, 2.44767100E-1, 2.93587774E-1},
+{1.83909580E-1, 2.15004295E-1, 3.00334543E-1},
+{2.45338634E-1, 2.68595248E-1, 3.48330349E-1},
+{1.92957386E-1, 2.06625074E-1, 2.67336398E-1},
+{2.54845560E-1, 2.68642277E-1, 3.03547889E-1},
+{1.76853105E-1, 2.59330958E-1, 3.16200763E-1},
+{2.90929139E-1, 3.15634757E-1, 3.68723541E-1},
+{1.57116994E-1, 1.73552901E-1, 2.28736520E-1},
+{2.12509260E-1, 2.30501205E-1, 2.52217978E-1},
+{1.42521843E-1, 2.01979935E-1, 2.93012232E-1},
+{2.14919671E-1, 2.78065056E-1, 3.14176053E-1},
+{1.35947272E-1, 1.81055903E-1, 2.75475413E-1},
+{1.98416695E-1, 2.41673797E-1, 3.05173427E-1},
+{1.59517333E-1, 2.31580108E-1, 2.95412451E-1},
+{2.58203626E-1, 2.87348121E-1, 3.20351988E-1},
+{1.74840674E-1, 1.92883253E-1, 2.11250007E-1},
+{2.02168509E-1, 2.27025688E-1, 3.04884046E-1},
+{1.69532105E-1, 2.11826235E-1, 2.97355384E-1},
+{2.30033740E-1, 2.91504353E-1, 3.26589435E-1},
+{1.95046112E-1, 2.11709172E-1, 2.27705747E-1},
+{2.37926885E-1, 2.52411634E-1, 2.97752172E-1},
+{1.53762922E-1, 2.46541560E-1, 3.14768940E-1},
+{2.36075714E-1, 3.03568929E-1, 3.70624453E-1},
+{1.38660327E-1, 1.67949975E-1, 2.73515254E-1},
+{2.13806167E-1, 2.27267206E-1, 2.86276251E-1},
+{1.25080630E-1, 2.44098395E-1, 3.02548796E-1},
+{2.35714868E-1, 2.81208843E-1, 3.08903724E-1},
+{1.51691392E-1, 2.10877746E-1, 2.63812989E-1},
+{2.20730439E-1, 2.52777904E-1, 3.16413730E-1},
+{1.84924737E-1, 2.39424765E-1, 2.85120815E-1},
+{2.59548545E-1, 3.09809893E-1, 3.26423734E-1},
+{1.62930742E-1, 2.19900876E-1, 2.36148626E-1},
+{2.34194234E-1, 2.49944329E-1, 2.77549058E-1},
+{1.70870200E-1, 1.98291600E-1, 3.21412593E-1},
+{2.31566861E-1, 2.75015086E-1, 3.69710356E-1},
+{1.80002406E-1, 2.06701040E-1, 2.71204919E-1},
+{2.38075271E-1, 2.54006237E-1, 3.23827595E-1},
+{1.99148253E-1, 2.54273921E-1, 3.07479709E-1},
+{2.87428617E-1, 3.25045079E-1, 3.48634571E-1},
+{1.45285025E-1, 1.91359162E-1, 2.49691397E-1},
+{1.94659308E-1, 2.40821242E-1, 2.77302653E-1},
+{1.53150991E-1, 1.94375664E-1, 3.27550441E-1},
+{2.04085842E-1, 2.98595697E-1, 3.21480066E-1},
+{1.56009689E-1, 1.81012720E-1, 3.00931662E-1},
+{2.10962430E-1, 2.55770296E-1, 3.08086127E-1},
+{1.85444072E-1, 2.49021322E-1, 2.74029821E-1},
+{2.74493456E-1, 2.89441973E-1, 3.38794917E-1},
+{1.76941887E-1, 1.94476932E-1, 2.22077265E-1},
+{2.16377512E-1, 2.30735779E-1, 3.03689271E-1},
+{1.89683452E-1, 2.14660764E-1, 2.88445383E-1},
+{2.40827337E-1, 2.98141748E-1, 3.27378422E-1},
+{2.01787844E-1, 2.19441772E-1, 2.39327446E-1},
+{2.48812512E-1, 2.65865892E-1, 2.93382376E-1},
+{1.82027832E-1, 2.68279046E-1, 2.93991417E-1},
+{2.56498635E-1, 3.19984466E-1, 3.62663239E-1},
+{1.58799276E-1, 1.75433666E-1, 2.67389864E-1},
+{2.24259302E-1, 2.36668259E-1, 2.77639121E-1},
+{1.49203405E-1, 2.26585329E-1, 3.45255584E-1},
+{2.50655770E-1, 2.92264849E-1, 3.13574284E-1},
+{1.58096299E-1, 2.02193201E-1, 2.98711687E-1},
+{2.28820905E-1, 2.48557344E-1, 3.44726473E-1},
+{1.87972054E-1, 2.34109432E-1, 3.04235607E-1},
+{2.85657108E-1, 3.14878136E-1, 3.36931497E-1},
+{1.62680015E-1, 2.17820048E-1, 2.57436782E-1},
+{2.24049792E-1, 2.46739820E-1, 3.00795883E-1},
+{2.01354548E-1, 2.18286663E-1, 3.13036293E-1},
+{2.38028511E-1, 2.98103482E-1, 3.53503793E-1},
+{1.98829994E-1, 2.12877125E-1, 2.72980839E-1},
+{2.50616491E-1, 2.67659992E-1, 3.20611864E-1},
+{1.70901820E-1, 2.69330353E-1, 3.34428221E-1},
+{3.04988861E-1, 3.36196691E-1, 3.65235358E-1},
+{1.47624031E-1, 1.81272805E-1, 2.04707921E-1},
+{1.93751350E-1, 2.20973969E-1, 2.61775166E-1},
+{1.32089809E-1, 1.94851607E-1, 2.83547610E-1},
+{2.07739428E-1, 2.70596832E-1, 2.92264789E-1},
+{1.27733424E-1, 1.66896015E-1, 2.83891350E-1},
+{2.05309406E-1, 2.47807533E-1, 2.83632785E-1},
+{1.54211894E-1, 2.25014091E-1, 2.70082027E-1},
+{2.67574131E-1, 2.84426898E-1, 3.09334785E-1},
+{1.68846920E-1, 1.87004536E-1, 2.02433169E-1},
+{2.02441111E-1, 2.16733068E-1, 2.93079227E-1},
+{1.63621262E-1, 2.15616465E-1, 2.82792896E-1},
+{2.25509301E-1, 2.66283005E-1, 3.17886561E-1},
+{1.89110294E-1, 2.05609441E-1, 2.22113580E-1},
+{2.21240178E-1, 2.60288864E-1, 2.92541057E-1},
+{1.55563369E-1, 2.46850818E-1, 2.89648801E-1},
+{2.48406157E-1, 3.05291861E-1, 3.55316669E-1},
+{1.27122149E-1, 1.58053726E-1, 2.54164368E-1},
+{2.04998836E-1, 2.19476849E-1, 2.78342038E-1},
+{1.33302316E-1, 2.29614019E-1, 2.86947161E-1},
+{2.36777052E-1, 2.67918199E-1, 3.08230907E-1},
+{1.40853569E-1, 2.03414679E-1, 2.73257107E-1},
+{2.07684264E-1, 2.34520018E-1, 3.24583262E-1},
+{1.77181646E-1, 2.29595393E-1, 2.83539146E-1},
+{2.61378348E-1, 3.01160187E-1, 3.21707100E-1},
+{1.48595735E-1, 2.07772017E-1, 2.46946126E-1},
+{2.14334831E-1, 2.48061299E-1, 2.72259146E-1},
+{1.76380262E-1, 1.96897894E-1, 2.92286903E-1},
+{1.98193476E-1, 2.75483340E-1, 3.49037558E-1},
+{1.76153168E-1, 1.93248957E-1, 2.69548506E-1},
+{2.36968622E-1, 2.50065804E-1, 3.06820840E-1},
+{1.76060721E-1, 2.54037619E-1, 3.03566784E-1},
+{2.82952905E-1, 3.01765054E-1, 3.53956312E-1},
+{1.45353720E-1, 1.83678836E-1, 2.34750062E-1},
+{1.93842635E-1, 2.30635554E-1, 2.67817765E-1},
+{1.38958976E-1, 1.86760783E-1, 3.13113242E-1},
+{1.99944481E-1, 2.77624756E-1, 3.25046331E-1},
+{1.42966077E-1, 1.71310842E-1, 3.03013414E-1},
+{2.07741663E-1, 2.58691758E-1, 2.88766950E-1},
+{1.71776935E-1, 2.40246087E-1, 2.73284525E-1},
+{2.71046638E-1, 2.85170943E-1, 3.27401131E-1},
+{1.69854626E-1, 1.87545776E-1, 2.24484712E-1},
+{2.15221986E-1, 2.27339745E-1, 2.95008808E-1},
+{1.75596640E-1, 2.17936546E-1, 2.74879605E-1},
+{2.34665439E-1, 2.89530903E-1, 3.16494375E-1},
+{1.89946994E-1, 2.04953820E-1, 2.46955171E-1},
+{2.37297818E-1, 2.68316716E-1, 2.90684313E-1},
+{1.69963166E-1, 2.53367484E-1, 2.92533010E-1},
+{2.70659864E-1, 2.97146112E-1, 3.56183976E-1},
+{1.52539685E-1, 1.70138955E-1, 2.52703935E-1},
+{2.19119206E-1, 2.35900700E-1, 2.69739121E-1},
+{1.42245665E-1, 2.18184620E-1, 3.28218073E-1},
+{2.61472821E-1, 2.78025657E-1, 3.02375883E-1},
+{1.53526023E-1, 1.90727741E-1, 2.92820841E-1},
+{2.09240988E-1, 2.49808684E-1, 3.24709088E-1},
+{1.75176397E-1, 2.38646746E-1, 3.06392699E-1},
+{2.73218870E-1, 3.03954989E-1, 3.20513874E-1},
+{1.63911596E-1, 1.89611584E-1, 2.56272525E-1},
+{2.26953760E-1, 2.40120232E-1, 2.92728513E-1},
+{1.95565715E-1, 2.11956203E-1, 2.97374696E-1},
+{2.41045550E-1, 2.88497001E-1, 3.36352319E-1},
+{1.94948331E-1, 2.09475279E-1, 2.56309658E-1},
+{2.47884631E-1, 2.63356417E-1, 3.11270863E-1},
+{1.69189706E-1, 2.35864580E-1, 3.36249381E-1},
+{2.86001563E-1, 3.25423747E-1, 3.59607369E-1},
+{1.56258598E-1, 1.76704943E-1, 2.14393437E-1},
+{2.08996847E-1, 2.23968685E-1, 2.60886759E-1},
+{1.35765389E-1, 2.03580052E-1, 3.05503219E-1},
+{2.18961373E-1, 2.79463500E-1, 2.99450845E-1},
+{1.34064749E-1, 1.78332120E-1, 2.90169626E-1},
+{2.13298395E-1, 2.40031511E-1, 3.00345927E-1},
+{1.64373413E-1, 2.26438701E-1, 2.87171155E-1},
+{2.50739604E-1, 2.80812472E-1, 3.35349351E-1},
+{1.63649514E-1, 1.97108001E-1, 2.21165180E-1},
+{2.08139613E-1, 2.30869800E-1, 2.96137065E-1},
+{1.59113124E-1, 2.18189180E-1, 2.95531958E-1},
+{2.39883497E-1, 2.81831235E-1, 3.26045603E-1},
+{1.89394727E-1, 2.08127141E-1, 2.38446414E-1},
+{2.32995704E-1, 2.59603471E-1, 2.93427974E-1},
+{1.60558835E-1, 2.55164832E-1, 3.02872926E-1},
+{2.53509283E-1, 2.96028465E-1, 3.67721587E-1},
+{1.30124375E-1, 1.74838990E-1, 2.60486037E-1},
+{2.10203990E-1, 2.33570784E-1, 2.83061892E-1},
+{1.52365491E-1, 2.25338757E-1, 3.03720981E-1},
+{2.40558609E-1, 2.77192205E-1, 3.05891901E-1},
+{1.63728818E-1, 1.94779396E-1, 2.69253582E-1},
+{2.25709423E-1, 2.40902692E-1, 3.18060607E-1},
+{1.92055091E-1, 2.29857832E-1, 2.89826721E-1},
+{2.62759686E-1, 3.04292172E-1, 3.35680574E-1},
+{1.66071162E-1, 2.06819177E-1, 2.39712462E-1},
+{2.23915562E-1, 2.50106871E-1, 2.85296232E-1},
+{1.88402340E-1, 2.03793734E-1, 3.03041130E-1},
+{2.30698988E-1, 2.87044138E-1, 3.49802762E-1},
+{1.82025358E-1, 2.14073509E-1, 2.63470024E-1},
+{2.37297758E-1, 2.65025407E-1, 3.17815512E-1},
+{1.89278707E-1, 2.58802205E-1, 3.04866165E-1},
+{2.97243059E-1, 3.17153066E-1, 3.56583923E-1},
+{1.58607468E-1, 1.78659767E-1, 2.41919369E-1},
+{1.94887385E-1, 2.41695851E-1, 2.62176663E-1},
+{1.58124432E-1, 2.11753070E-1, 3.11352164E-1},
+{2.16902718E-1, 2.98796803E-1, 3.20994049E-1},
+{1.49272785E-1, 1.74964130E-1, 3.15334409E-1},
+{2.21622273E-1, 2.56179065E-1, 3.03902954E-1},
+{1.75979599E-1, 2.43505448E-1, 2.85801739E-1},
+{2.64590383E-1, 2.85541564E-1, 3.45107764E-1},
+{1.80137083E-1, 2.05279350E-1, 2.22255990E-1},
+{2.10796222E-1, 2.26315439E-1, 3.14426929E-1},
+{1.79151163E-1, 2.09439725E-1, 2.93280870E-1},
+{2.49719024E-1, 2.91257650E-1, 3.27162296E-1},
+{1.98700234E-1, 2.15896755E-1, 2.49960214E-1},
+{2.40726396E-1, 2.64857739E-1, 2.99639553E-1},
+{1.71249732E-1, 2.68166155E-1, 3.03572744E-1},
+{2.69555569E-1, 3.16100627E-1, 3.56570691E-1},
+{1.50564745E-1, 1.84190869E-1, 2.68674821E-1},
+{2.16941193E-1, 2.40813971E-1, 2.78942198E-1},
+{1.35399476E-1, 2.60586530E-1, 3.32604855E-1},
+{2.56150961E-1, 2.87822872E-1, 3.06156367E-1},
+{1.66398838E-1, 1.88721806E-1, 2.93023735E-1},
+{2.29214087E-1, 2.61565417E-1, 3.27494055E-1},
+{1.98266640E-1, 2.32970506E-1, 2.99134284E-1},
+{2.87046254E-1, 3.07103783E-1, 3.27298075E-1},
+{1.75898686E-1, 2.11898595E-1, 2.51332909E-1},
+{2.32067421E-1, 2.44622201E-1, 2.99443692E-1},
+{1.90780059E-1, 2.12090015E-1, 3.25059265E-1},
+{2.31531218E-1, 3.14166099E-1, 3.42735857E-1},
+{1.95099846E-1, 2.09554315E-1, 2.79483467E-1},
+{2.40416065E-1, 2.69604772E-1, 3.28015476E-1},
+{1.71800867E-1, 2.82233089E-1, 3.14749271E-1},
+{2.69243777E-1, 3.38462502E-1, 3.79935652E-1},
+{1.59934625E-1, 1.77966774E-1, 2.00818628E-1},
+{2.01979712E-1, 2.30668545E-1, 2.56773323E-1},
+{1.34024277E-1, 2.10961610E-1, 2.84687728E-1},
+{2.03712896E-1, 2.83053070E-1, 3.03309411E-1},
+{1.44528881E-1, 1.64728075E-1, 2.85079390E-1},
+{2.06285611E-1, 2.48649031E-1, 2.96383053E-1},
+{1.58138171E-1, 2.34317720E-1, 2.79650003E-1},
+{2.64995635E-1, 2.79900700E-1, 3.18619400E-1},
+{1.66537479E-1, 1.84279412E-1, 2.14547485E-1},
+{2.03051880E-1, 2.35110492E-1, 2.88755983E-1},
+{1.68422714E-1, 2.03946173E-1, 2.87478894E-1},
+{2.31727019E-1, 2.74086386E-1, 3.24755162E-1},
+{1.85356215E-1, 2.14113116E-1, 2.29030401E-1},
+{2.42482558E-1, 2.60655493E-1, 2.83030301E-1},
+{1.67562261E-1, 2.42027491E-1, 2.99461991E-1},
+{2.38809898E-1, 3.19003850E-1, 3.58415872E-1},
+{1.37908265E-1, 1.54787809E-1, 2.65611202E-1},
+{2.11019263E-1, 2.24607319E-1, 2.79954702E-1},
+{1.37569889E-1, 2.25128531E-1, 3.09312850E-1},
+{2.29239866E-1, 2.76150972E-1, 3.15241843E-1},
+{1.60487458E-1, 1.95461214E-1, 2.83169478E-1},
+{2.18505666E-1, 2.38197207E-1, 3.30340117E-1},
+{1.81991324E-1, 2.33026952E-1, 2.93276042E-1},
+{2.54552305E-1, 3.14394146E-1, 3.36392254E-1},
+{1.44095764E-1, 2.26640165E-1, 2.50595063E-1},
+{2.15188012E-1, 2.51417249E-1, 2.85043985E-1},
+{1.87674388E-1, 2.04458863E-1, 2.94168979E-1},
+{2.30494842E-1, 2.68452436E-1, 3.52370054E-1},
+{1.85022101E-1, 1.99075252E-1, 2.71930546E-1},
+{2.42569372E-1, 2.55389154E-1, 3.11399311E-1},
+{1.95166096E-1, 2.49102056E-1, 2.98998445E-1},
+{2.83654153E-1, 3.14600259E-1, 3.55619401E-1},
+{1.51490018E-1, 1.97729796E-1, 2.32467473E-1},
+{2.00029895E-1, 2.30101258E-1, 2.81933933E-1},
+{1.38711318E-1, 1.91816628E-1, 3.45780402E-1},
+{1.96580395E-1, 3.04714769E-1, 3.40553433E-1},
+{1.38154253E-1, 1.88543141E-1, 2.99461216E-1},
+{2.05666468E-1, 2.68904895E-1, 3.05537194E-1},
+{1.72447845E-1, 2.33558387E-1, 2.93625206E-1},
+{2.70145416E-1, 2.98654765E-1, 3.28556389E-1},
+{1.75489411E-1, 1.91361547E-1, 2.35585332E-1},
+{2.20548794E-1, 2.34773993E-1, 2.95397669E-1},
+{1.85652360E-1, 2.22349137E-1, 2.79883891E-1},
+{2.29456946E-1, 3.04546326E-1, 3.24684292E-1},
+{1.86900780E-1, 2.15469390E-1, 2.51856804E-1},
+{2.34910533E-1, 2.71217376E-1, 2.99894661E-1},
+{1.85142443E-1, 2.56071001E-1, 2.93291301E-1},
+{2.63883710E-1, 3.07127446E-1, 3.62546653E-1},
+{1.60997644E-1, 1.78937852E-1, 2.55808324E-1},
+{2.25671068E-1, 2.43735075E-1, 2.68624991E-1},
+{1.55076161E-1, 2.30396181E-1, 3.21005553E-1},
+{2.51760483E-1, 2.79653400E-1, 3.14202160E-1},
+{1.56988814E-1, 2.07466930E-1, 2.89933950E-1},
+{2.17479482E-1, 2.59626418E-1, 3.40659052E-1},
+{1.76811531E-1, 2.31087089E-1, 3.17562491E-1},
+{2.82952607E-1, 2.99844354E-1, 3.36822897E-1},
+{1.82060316E-1, 1.98734730E-1, 2.51980305E-1},
+{2.25874200E-1, 2.52469152E-1, 2.93356389E-1},
+{2.00799957E-1, 2.17786849E-1, 3.02210063E-1},
+{2.47423753E-1, 2.86882848E-1, 3.47820610E-1},
+{2.01128140E-1, 2.14746892E-1, 2.62269646E-1},
+{2.53963351E-1, 2.69477993E-1, 3.12133819E-1},
+{1.91034868E-1, 2.55738169E-1, 3.32559615E-1},
+{2.91053712E-1, 3.31458420E-1, 3.68588477E-1},
+{1.57229915E-1, 1.85374141E-1, 2.25361317E-1},
+{2.08051339E-1, 2.38350868E-1, 2.64212936E-1},
+{1.46848336E-1, 2.13000089E-1, 3.00192565E-1},
+{2.18630567E-1, 2.90263802E-1, 3.09045762E-1},
+{1.43699184E-1, 1.87815160E-1, 2.83769876E-1},
+{2.07328036E-1, 2.45088696E-1, 3.08956414E-1},
+{1.64228097E-1, 2.27826655E-1, 3.08907896E-1},
+{2.61919737E-1, 2.91333705E-1, 3.31527978E-1},
+{1.70648888E-1, 2.02157527E-1, 2.17827827E-1},
+{2.07796112E-1, 2.34704822E-1, 3.06783766E-1},
+{1.72118798E-1, 2.14057386E-1, 3.10151786E-1},
+{2.29116157E-1, 2.80949861E-1, 3.33774298E-1},
+{1.96622208E-1, 2.16653049E-1, 2.33279720E-1},
+{2.37789229E-1, 2.58971304E-1, 3.04609209E-1},
+{1.55182019E-1, 2.63032585E-1, 3.18943053E-1},
+{2.49388829E-1, 3.16970855E-1, 3.77762467E-1},
+{1.51363596E-1, 1.75010651E-1, 2.78245836E-1},
+{2.19810233E-1, 2.32360214E-1, 2.85034925E-1},
+{1.42630622E-1, 2.40602851E-1, 3.04125100E-1},
+{2.42764875E-1, 2.83762127E-1, 3.15481216E-1},
+{1.57467470E-1, 2.07524061E-1, 2.75674909E-1},
+{2.28758618E-1, 2.49092206E-1, 3.28139395E-1},
+{1.90872714E-1, 2.38125205E-1, 2.94894546E-1},
+{2.66389251E-1, 3.14321429E-1, 3.38669509E-1},
+{1.70644209E-1, 2.25980043E-1, 2.47372389E-1},
+{2.36442789E-1, 2.53003448E-1, 2.88220435E-1},
+{1.85423777E-1, 2.04888850E-1, 3.14608842E-1},
+{2.17379019E-1, 2.94553548E-1, 3.67831022E-1},
+{1.88563988E-1, 2.15174288E-1, 2.72999734E-1},
+{2.45102122E-1, 2.59770364E-1, 3.21885556E-1},
+{1.98444173E-1, 2.61160702E-1, 3.17097872E-1},
+{2.99013853E-1, 3.28965336E-1, 3.56681198E-1},
+{1.58248767E-1, 1.92205697E-1, 2.46059090E-1},
+{2.02385351E-1, 2.47965842E-1, 2.71749645E-1},
+{1.61710784E-1, 2.13708103E-1, 3.27384740E-1},
+{2.14419708E-1, 3.05552453E-1, 3.33721548E-1},
+{1.61819980E-1, 1.89897299E-1, 3.10501546E-1},
+{2.19436333E-1, 2.65029579E-1, 3.09288830E-1},
+{1.88303933E-1, 2.49633163E-1, 2.85499543E-1},
+{2.69325376E-1, 2.99807042E-1, 3.41722459E-1},
+{1.72406003E-1, 2.10977256E-1, 2.27773219E-1},
+{2.20281526E-1, 2.34015763E-1, 3.12846094E-1},
+{1.83257267E-1, 2.22061962E-1, 2.91052371E-1},
+{2.42531225E-1, 3.09527606E-1, 3.30389649E-1},
+{2.07546696E-1, 2.24662632E-1, 2.44420141E-1},
+{2.45858207E-1, 2.70285994E-1, 3.05132121E-1},
+{1.84840545E-1, 2.72096783E-1, 3.12531084E-1},
+{2.74252594E-1, 3.21252435E-1, 3.74658197E-1},
+{1.66425839E-1, 1.84491634E-1, 2.68278092E-1},
+{2.28423670E-1, 2.43025422E-1, 2.81184882E-1},
+{1.60091296E-1, 2.52953321E-1, 3.35822314E-1},
+{2.62109995E-1, 2.95581907E-1, 3.13354105E-1},
+{1.67702749E-1, 2.01536924E-1, 3.01801592E-1},
+{2.37822965E-1, 2.59894758E-1, 3.38231117E-1},
+{1.97206214E-1, 2.45490909E-1, 3.17895442E-1},
+{2.98455298E-1, 3.19209784E-1, 3.40971738E-1},
+{1.71195343E-1, 2.24327832E-1, 2.62736112E-1},
+{2.30626896E-1, 2.53310233E-1, 3.01206797E-1},
+{2.04814211E-1, 2.21881568E-1, 3.25966567E-1},
+{2.22987518E-1, 3.06339115E-1, 3.50717157E-1},
+{2.00855389E-1, 2.15359926E-1, 2.84143478E-1},
+{2.50951648E-1, 2.66189247E-1, 3.33360583E-1},
+{1.75610259E-1, 2.93791324E-1, 3.40326935E-1},
+{2.91745067E-1, 3.40602487E-1, 3.81397158E-1}};
+
+static const float evrc_lspq_full_codebook4[128][3] = {
+{2.77461529E-1, 3.16972077E-1, 3.95498335E-1},
+{3.36560428E-1, 3.60156953E-1, 3.81473005E-1},
+{3.10509324E-1, 3.31732392E-1, 3.66864383E-1},
+{3.37470949E-1, 3.96795273E-1, 4.12356317E-1},
+{2.79660404E-1, 3.66520107E-1, 3.85313451E-1},
+{3.16038966E-1, 3.85609329E-1, 4.01304781E-1},
+{3.09960425E-1, 3.43410730E-1, 4.24745500E-1},
+{3.54243636E-1, 4.08699274E-1, 4.22167957E-1},
+{2.95587242E-1, 3.33741128E-1, 3.87421668E-1},
+{3.33446383E-1, 3.86974752E-1, 4.01353061E-1},
+{3.23412836E-1, 3.65269661E-1, 3.85193288E-1},
+{3.42731953E-1, 4.03192520E-1, 4.19920385E-1},
+{2.77681828E-1, 3.82494986E-1, 4.04274166E-1},
+{3.18247974E-1, 3.95985305E-1, 4.31353152E-1},
+{3.03711414E-1, 3.80319715E-1, 4.37173545E-1},
+{3.78288805E-1, 4.07077312E-1, 4.22679126E-1},
+{2.38116503E-1, 3.42454314E-1, 4.24624741E-1},
+{3.45615685E-1, 3.68681073E-1, 4.00817335E-1},
+{3.17688107E-1, 3.41902673E-1, 4.05601799E-1},
+{3.66368949E-1, 3.89039934E-1, 4.06154454E-1},
+{2.99398005E-1, 3.52021694E-1, 3.99955690E-1},
+{3.24991941E-1, 3.90028834E-1, 4.19478714E-1},
+{3.23025763E-1, 3.68114293E-1, 4.02087748E-1},
+{3.62326264E-1, 4.16927993E-1, 4.32773650E-1},
+{2.72696435E-1, 3.59205008E-1, 4.26880658E-1},
+{3.46539855E-1, 3.69616628E-1, 4.15621221E-1},
+{3.34109128E-1, 3.55736315E-1, 3.96749556E-1},
+{3.37468982E-1, 4.10392702E-1, 4.25986826E-1},
+{2.99468994E-1, 3.80648255E-1, 4.18284118E-1},
+{3.21378171E-1, 4.11198020E-1, 4.28792536E-1},
+{3.27841163E-1, 3.69345129E-1, 4.34395611E-1},
+{3.80669057E-1, 4.26086366E-1, 4.42754567E-1},
+{2.68943667E-1, 3.42942953E-1, 3.98681462E-1},
+{3.38102877E-1, 3.76338840E-1, 3.92043173E-1},
+{3.23593497E-1, 3.48742068E-1, 3.72551978E-1},
+{3.47550809E-1, 3.92885387E-1, 4.21169937E-1},
+{3.04182827E-1, 3.59816670E-1, 3.81633341E-1},
+{3.14221382E-1, 4.02108550E-1, 4.20085251E-1},
+{3.01306546E-1, 3.62662733E-1, 4.29262817E-1},
+{3.71770263E-1, 3.98696363E-1, 4.31438982E-1},
+{2.74591267E-1, 3.35595489E-1, 4.20079648E-1},
+{3.44540834E-1, 3.90451789E-1, 4.06412065E-1},
+{3.25239837E-1, 3.78344476E-1, 3.94673288E-1},
+{3.56683493E-1, 3.90574157E-1, 4.33851063E-1},
+{2.63501287E-1, 3.95260096E-1, 4.23116386E-1},
+{3.37520659E-1, 3.92563462E-1, 4.43415821E-1},
+{3.14522266E-1, 3.80968630E-1, 4.22676384E-1},
+{3.76235068E-1, 4.17298734E-1, 4.31451261E-1},
+{2.61855006E-1, 3.68646085E-1, 4.04260576E-1},
+{3.55580151E-1, 3.77994478E-1, 3.95868242E-1},
+{3.27742815E-1, 3.53872776E-1, 4.11040604E-1},
+{3.62960637E-1, 3.99466991E-1, 4.14690197E-1},
+{3.09410870E-1, 3.73796046E-1, 3.92672479E-1},
+{3.31016302E-1, 4.00801599E-1, 4.31759298E-1},
+{3.23573053E-1, 3.68619561E-1, 4.17455137E-1},
+{3.49115849E-1, 4.26840067E-1, 4.43913996E-1},
+{2.89738595E-1, 3.63759339E-1, 4.10511792E-1},
+{3.55286479E-1, 3.89331281E-1, 4.13432419E-1},
+{3.36565912E-1, 3.60222459E-1, 4.24179018E-1},
+{3.39932680E-1, 4.09228802E-1, 4.40184891E-1},
+{3.00889730E-1, 4.00081098E-1, 4.17955697E-1},
+{3.17052066E-1, 4.22288120E-1, 4.42229569E-1},
+{3.27336788E-1, 3.84311676E-1, 4.30288613E-1},
+{3.98990929E-1, 4.29498434E-1, 4.43475187E-1},
+{2.49110118E-1, 3.25696886E-1, 4.11728263E-1},
+{3.45929205E-1, 3.68577540E-1, 3.88473272E-1},
+{3.13219666E-1, 3.39229465E-1, 3.87597919E-1},
+{3.51453960E-1, 3.98730278E-1, 4.12656188E-1},
+{2.93487132E-1, 3.75763118E-1, 3.94488096E-1},
+{3.24470758E-1, 3.94202888E-1, 4.08882737E-1},
+{3.12710822E-1, 3.57720256E-1, 4.14061189E-1},
+{3.66507173E-1, 4.08171296E-1, 4.23891425E-1},
+{2.99965680E-1, 3.31993401E-1, 4.07860160E-1},
+{3.34925175E-1, 3.86143029E-1, 4.11538124E-1},
+{3.34788024E-1, 3.66196156E-1, 3.93347144E-1},
+{3.47847939E-1, 4.05926466E-1, 4.30507302E-1},
+{2.85952926E-1, 3.95283282E-1, 4.16119337E-1},
+{3.23867381E-1, 4.06476676E-1, 4.42482829E-1},
+{3.16716671E-1, 3.84451628E-1, 4.39411044E-1},
+{3.86772931E-1, 4.11824584E-1, 4.27831531E-1},
+{2.38072395E-1, 3.62342358E-1, 4.30931687E-1},
+{3.46450031E-1, 3.79082918E-1, 4.06567812E-1},
+{3.16576600E-1, 3.56468618E-1, 3.96218300E-1},
+{3.66539180E-1, 3.89590919E-1, 4.21055555E-1},
+{3.08291376E-1, 3.71324301E-1, 4.07867432E-1},
+{3.36435199E-1, 3.91514421E-1, 4.22977090E-1},
+{3.23035538E-1, 3.80447328E-1, 4.09550190E-1},
+{3.65228057E-1, 4.27910388E-1, 4.43691254E-1},
+{2.72038043E-1, 3.76596808E-1, 4.33685899E-1},
+{3.57665777E-1, 3.77761602E-1, 4.09178972E-1},
+{3.36498559E-1, 3.64215910E-1, 4.09255505E-1},
+{3.48082423E-1, 4.17631805E-1, 4.33284521E-1},
+{3.02754521E-1, 3.95974755E-1, 4.33717251E-1},
+{3.31676304E-1, 4.17587161E-1, 4.36239839E-1},
+{3.33287597E-1, 3.80799115E-1, 4.39620733E-1},
+{3.88112009E-1, 4.36933577E-1, 4.50829268E-1},
+{2.56026626E-1, 3.48015189E-1, 4.22922611E-1},
+{3.45773995E-1, 3.81725788E-1, 3.96794081E-1},
+{3.25623751E-1, 3.50391924E-1, 3.87330651E-1},
+{3.56868088E-1, 3.98574769E-1, 4.23177242E-1},
+{3.01226199E-1, 3.86906981E-1, 4.03335571E-1},
+{3.28178406E-1, 4.02090192E-1, 4.19389248E-1},
+{3.14385355E-1, 3.69043887E-1, 4.34375286E-1},
+{3.72321129E-1, 4.11672413E-1, 4.40518737E-1},
+{2.90479720E-1, 3.48121881E-1, 4.26216483E-1},
+{3.44438791E-1, 3.82666349E-1, 4.17321086E-1},
+{3.34866822E-1, 3.76235664E-1, 4.04475212E-1},
+{3.59025359E-1, 4.04721916E-1, 4.34838414E-1},
+{2.79127955E-1, 4.11106586E-1, 4.35360551E-1},
+{3.48125517E-1, 3.98732066E-1, 4.46927428E-1},
+{3.27018857E-1, 3.90107334E-1, 4.41707492E-1},
+{3.90858352E-1, 4.19813931E-1, 4.35153484E-1},
+{2.55319297E-1, 3.70405972E-1, 4.32188630E-1},
+{3.54651988E-1, 3.88332665E-1, 4.02956128E-1},
+{3.21608186E-1, 3.54489803E-1, 4.28299785E-1},
+{3.75163496E-1, 3.98833990E-1, 4.14177418E-1},
+{3.11953604E-1, 3.91430676E-1, 4.12552476E-1},
+{3.42528820E-1, 3.96365345E-1, 4.32497382E-1},
+{3.33744347E-1, 3.76422405E-1, 4.20536995E-1},
+{3.53529096E-1, 4.29231048E-1, 4.59699273E-1},
+{2.88017929E-1, 3.77999961E-1, 4.34011698E-1},
+{3.55683446E-1, 3.80780041E-1, 4.23145533E-1},
+{3.44358265E-1, 3.72184873E-1, 4.31265354E-1},
+{3.53966117E-1, 4.14166689E-1, 4.42941308E-1},
+{3.04770231E-1, 4.12517488E-1, 4.34183121E-1},
+{3.35913360E-1, 4.24590766E-1, 4.46378469E-1},
+{3.43738198E-1, 3.84766221E-1, 4.35271382E-1},
+{4.10941303E-1, 4.40662980E-1, 4.52113390E-1}};
+
+static const float evrc_lspq_half_codebook1[128][3] = {
+{1.35226343E-2, 1.82081293E-2, 3.93940695E-2},
+{2.29392890E-2, 3.57831158E-2, 1.05352886E-1},
+{2.09106486E-2, 3.04159056E-2, 8.93941075E-2},
+{1.88909005E-2, 3.82722206E-2, 1.37820408E-1},
+{2.05143820E-2, 2.85481159E-2, 7.39762187E-2},
+{4.69510332E-2, 6.84031919E-2, 1.09123811E-1},
+{3.15557197E-2, 5.69139980E-2, 8.57057571E-2},
+{3.81181911E-2, 7.77784660E-2, 1.92532852E-1},
+{2.16297153E-2, 2.92908940E-2, 6.25042021E-2},
+{3.11414022E-2, 5.99079318E-2, 1.02860682E-1},
+{3.02799307E-2, 5.35012372E-2, 7.80925751E-2},
+{6.50846213E-2, 9.06624720E-2, 1.42850950E-1},
+{3.27340364E-2, 5.04027791E-2, 6.26492277E-2},
+{5.27439862E-2, 6.22574277E-2, 1.22198336E-1},
+{3.48840356E-2, 6.42222390E-2, 9.16024595E-2},
+{4.88984436E-2, 1.05058022E-1, 1.68813452E-1},
+{2.35791076E-2, 3.21034677E-2, 5.60899563E-2},
+{2.77252812E-2, 4.87281792E-2, 1.01224191E-1},
+{2.74348017E-2, 4.04965915E-2, 9.34926122E-2},
+{4.38360050E-2, 6.03261292E-2, 1.52400866E-1},
+{2.68994924E-2, 4.52906378E-2, 6.49800375E-2},
+{5.16058952E-2, 6.08312152E-2, 1.08799636E-1},
+{4.20064926E-2, 6.11845106E-2, 8.54474008E-2},
+{7.13502690E-2, 1.01972111E-1, 1.74640998E-1},
+{2.88906675E-2, 4.13964354E-2, 5.25928028E-2},
+{3.16364467E-2, 6.63532093E-2, 1.24950245E-1},
+{4.30289507E-2, 5.14023267E-2, 7.96877742E-2},
+{5.70970774E-2, 1.08444504E-1, 1.44075617E-1},
+{3.38840261E-2, 5.04746847E-2, 7.29765445E-2},
+{6.54265657E-2, 7.90987685E-2, 1.15570590E-1},
+{3.85423526E-2, 7.33125433E-2, 1.02307513E-1},
+{6.57824501E-2, 1.02909811E-1, 2.11874440E-1},
+{1.54727865E-2, 2.04559695E-2, 5.46121262E-2},
+{2.27950197E-2, 3.90954204E-2, 1.19443826E-1},
+{3.06889173E-2, 4.54540215E-2, 8.20418894E-2},
+{2.25957241E-2, 4.79101725E-2, 1.71844408E-1},
+{2.71088015E-2, 4.01739590E-2, 7.01922849E-2},
+{4.95789349E-2, 7.92963281E-2, 1.04862511E-1},
+{3.06095853E-2, 5.64059429E-2, 9.49584097E-2},
+{6.34224564E-2, 9.11655501E-2, 1.84724405E-1},
+{2.43342388E-2, 3.91998328E-2, 6.31406233E-2},
+{3.38011980E-2, 6.60846457E-2, 1.11031540E-1},
+{3.51784080E-2, 5.79397269E-2, 7.20702857E-2},
+{6.49054050E-2, 8.65831897E-2, 1.54648736E-1},
+{2.91934665E-2, 5.16204573E-2, 6.94437325E-2},
+{5.94522804E-2, 7.19829276E-2, 1.27434507E-1},
+{5.31888530E-2, 6.38182089E-2, 9.88218486E-2},
+{8.68290961E-2, 1.41135350E-1, 1.91728458E-1},
+{2.49991138E-2, 3.62556018E-2, 5.03724031E-2},
+{2.82246377E-2, 5.44572286E-2, 1.12663500E-1},
+{3.62618119E-2, 4.59073223E-2, 9.43343639E-2},
+{5.70455343E-2, 7.46300444E-2, 1.59157172E-1},
+{2.72987466E-2, 4.56625856E-2, 7.52529651E-2},
+{5.12860194E-2, 8.51126984E-2, 1.23587973E-1},
+{4.91451994E-2, 5.93483113E-2, 9.22686011E-2},
+{7.06961900E-2, 1.05451979E-1, 1.92602143E-1},
+{2.80733760E-2, 4.18509208E-2, 5.87159805E-2},
+{4.64449003E-2, 7.06698820E-2, 1.26038432E-1},
+{4.18453738E-2, 6.30445331E-2, 7.66169876E-2},
+{8.42416435E-2, 1.13282882E-1, 1.43687114E-1},
+{4.17615622E-2, 5.59472926E-2, 7.09872842E-2},
+{5.55161387E-2, 9.50126722E-2, 1.27727196E-1},
+{5.90935498E-2, 7.36730024E-2, 9.65935886E-2},
+{7.84136653E-2, 1.41432360E-1, 2.17428640E-1},
+{2.10490543E-2, 2.91891042E-2, 4.60035764E-2},
+{3.64863276E-2, 4.62387018E-2, 1.07044168E-1},
+{2.68652122E-2, 3.92937548E-2, 8.41179937E-2},
+{2.72903945E-2, 5.53805046E-2, 1.41586170E-1},
+{2.48476695E-2, 3.63277681E-2, 7.62430876E-2},
+{5.25430813E-2, 7.75778666E-2, 1.14567965E-1},
+{4.07741442E-2, 5.39923795E-2, 9.07640457E-2},
+{5.73043302E-2, 7.65803084E-2, 1.79578975E-1},
+{2.46032421E-2, 3.41408364E-2, 6.78990781E-2},
+{4.08220068E-2, 6.29783794E-2, 9.95191261E-2},
+{3.83025035E-2, 5.52857481E-2, 7.90019333E-2},
+{7.24111274E-2, 1.01903863E-1, 1.46979645E-1},
+{3.73902172E-2, 4.70463894E-2, 6.54684529E-2},
+{5.27397543E-2, 6.72770366E-2, 1.39680430E-1},
+{4.05365378E-2, 7.05081299E-2, 9.25668627E-2},
+{4.43425253E-2, 1.10367171E-1, 1.99636266E-1},
+{2.54920740E-2, 3.47603969E-2, 6.05902039E-2},
+{4.35465500E-2, 5.32369502E-2, 1.08325966E-1},
+{2.79599819E-2, 4.91324775E-2, 8.84284526E-2},
+{4.98051867E-2, 8.81728902E-2, 1.52597323E-1},
+{3.19346264E-2, 4.62169312E-2, 6.85206428E-2},
+{5.80246300E-2, 6.84268698E-2, 1.15085281E-1},
+{4.33904678E-2, 6.90575615E-2, 8.44984353E-2},
+{7.39691556E-2, 1.19240515E-1, 1.77340195E-1},
+{3.18767503E-2, 4.59697433E-2, 5.72372638E-2},
+{4.50873822E-2, 5.66509366E-2, 1.32005826E-1},
+{4.59097028E-2, 5.45580424E-2, 8.61423314E-2},
+{7.44685754E-2, 1.13815404E-1, 1.61570594E-1},
+{3.97509560E-2, 4.95359488E-2, 7.22542256E-2},
+{6.76257759E-2, 8.31029043E-2, 1.27990112E-1},
+{5.76258078E-2, 6.95326403E-2, 1.05012968E-1},
+{6.85313493E-2, 1.21758826E-1, 2.20626548E-1},
+{2.18480472E-2, 2.99130920E-2, 5.16208000E-2},
+{3.64343151E-2, 4.91795056E-2, 1.23277210E-1},
+{3.89611274E-2, 4.76634987E-2, 8.61716568E-2},
+{4.14635167E-2, 6.88006952E-2, 1.69356152E-1},
+{3.35514620E-2, 4.17815186E-2, 7.37159401E-2},
+{5.80224693E-2, 8.70314166E-2, 1.12917498E-1},
+{4.80243117E-2, 5.69486506E-2, 1.00755706E-1},
+{5.98873124E-2, 8.57942328E-2, 2.01388851E-1},
+{2.99309995E-2, 3.94828431E-2, 6.46376088E-2},
+{3.88626605E-2, 8.07443634E-2, 1.15519784E-1},
+{3.49444002E-2, 6.28911033E-2, 8.04982036E-2},
+{6.88817874E-2, 9.92431119E-2, 1.60393253E-1},
+{3.64237651E-2, 5.34016453E-2, 6.70152009E-2},
+{5.83492741E-2, 7.85285756E-2, 1.41746715E-1},
+{4.86469641E-2, 7.26736858E-2, 9.48315859E-2},
+{5.85533604E-2, 1.36289746E-1, 1.98639736E-1},
+{2.60888506E-2, 3.73406820E-2, 5.57853170E-2},
+{4.58504409E-2, 5.60512505E-2, 1.17927872E-1},
+{4.28801328E-2, 5.14739119E-2, 9.75309014E-2},
+{6.37611598E-2, 8.73552933E-2, 1.68334916E-1},
+{3.76709923E-2, 4.58216034E-2, 7.86528140E-2},
+{6.75194561E-2, 8.98697898E-2, 1.19418114E-1},
+{5.46374246E-2, 6.66805878E-2, 8.93813819E-2},
+{7.73086548E-2, 1.21754415E-1, 1.99579224E-1},
+{3.15621309E-2, 4.51702215E-2, 6.25768527E-2},
+{3.78782675E-2, 8.03486481E-2, 1.38961688E-1},
+{5.08303270E-2, 6.18740581E-2, 8.31153840E-2},
+{8.96311402E-2, 1.28753766E-1, 1.64891586E-1},
+{4.73503470E-2, 5.75724356E-2, 7.65264630E-2},
+{7.16898590E-2, 9.89895687E-2, 1.30078360E-1},
+{6.29082546E-2, 7.90778771E-2, 1.05111063E-1},
+{8.80649835E-2, 1.65206164E-1, 2.13214174E-1}};
+
+static const float evrc_lspq_half_codebook2[128][3] = {
+{9.75915268E-2, 1.23701490E-1, 1.69437975E-1},
+{9.49536338E-2, 2.01081768E-1, 2.26855248E-1},
+{9.00496617E-2, 1.49164870E-1, 2.26532787E-1},
+{1.70302704E-1, 1.97222874E-1, 2.49974832E-1},
+{1.08773641E-1, 1.51972428E-1, 1.75123364E-1},
+{1.30278930E-1, 2.13229164E-1, 2.29646355E-1},
+{1.24917991E-1, 1.87347755E-1, 2.04712003E-1},
+{2.00670198E-1, 2.28963569E-1, 2.69420803E-1},
+{8.98375586E-2, 1.25332758E-1, 2.10539430E-1},
+{9.62376669E-2, 2.07185850E-1, 2.54174471E-1},
+{1.05694629E-1, 1.78856418E-1, 2.00121015E-1},
+{1.56048968E-1, 2.19573721E-1, 2.91079402E-1},
+{1.37392268E-1, 1.59993336E-1, 1.94698542E-1},
+{1.07262500E-1, 2.37790957E-1, 2.70740807E-1},
+{1.42976448E-1, 2.01550499E-1, 2.18468934E-1},
+{2.14270487E-1, 2.71881402E-1, 3.01200211E-1},
+{1.10729210E-1, 1.33688226E-1, 1.54877156E-1},
+{1.06667660E-1, 1.76678821E-1, 2.62798905E-1},
+{9.16352943E-2, 1.74592838E-1, 2.19329327E-1},
+{1.84038624E-1, 2.27964059E-1, 2.47762203E-1},
+{1.10572360E-1, 1.58207163E-1, 1.96013063E-1},
+{1.33543387E-1, 2.32269660E-1, 2.51828164E-1},
+{1.55922309E-1, 1.77941337E-1, 2.18096644E-1},
+{1.92260072E-1, 2.49512479E-1, 2.89911509E-1},
+{1.13708906E-1, 1.37872443E-1, 2.02929884E-1},
+{1.02557532E-1, 1.84820071E-1, 2.92164624E-1},
+{1.36595622E-1, 1.58687428E-1, 2.41399556E-1},
+{1.72813818E-1, 2.49303415E-1, 3.00458610E-1},
+{1.36871174E-1, 1.57249823E-1, 2.10913152E-1},
+{1.28974810E-1, 2.45167866E-1, 2.67653584E-1},
+{1.66812256E-1, 1.88998029E-1, 2.31345922E-1},
+{2.32248470E-1, 2.63196051E-1, 3.16754937E-1},
+{9.24560949E-2, 1.19977452E-1, 1.91262275E-1},
+{1.13085262E-1, 2.08461538E-1, 2.29368120E-1},
+{1.00716405E-1, 1.40670076E-1, 2.58062959E-1},
+{1.67010382E-1, 2.18105540E-1, 2.62592494E-1},
+{1.25487238E-1, 1.62686959E-1, 1.84409231E-1},
+{1.52406558E-1, 2.07131729E-1, 2.47582436E-1},
+{1.37441203E-1, 1.80262372E-1, 2.17698842E-1},
+{2.07853511E-1, 2.49209508E-1, 2.69830108E-1},
+{9.35257301E-2, 1.49197355E-1, 2.04652041E-1},
+{1.11997180E-1, 2.25233063E-1, 2.47003049E-1},
+{1.09315015E-1, 1.93811879E-1, 2.13802189E-1},
+{1.75118580E-1, 2.52520263E-1, 2.75082767E-1},
+{1.36918738E-1, 1.77440569E-1, 1.97931141E-1},
+{1.36811242E-1, 2.37426177E-1, 2.84737825E-1},
+{1.60759792E-1, 2.00833157E-1, 2.18084484E-1},
+{2.33710244E-1, 2.66372561E-1, 2.91802049E-1},
+{1.19171090E-1, 1.39703169E-1, 1.87723249E-1},
+{1.31049946E-1, 1.93696663E-1, 2.60426998E-1},
+{1.08267047E-1, 1.65194795E-1, 2.39523023E-1},
+{2.03195021E-1, 2.25942209E-1, 2.49403238E-1},
+{1.23842932E-1, 1.45794615E-1, 2.15635628E-1},
+{1.71226338E-1, 2.38054529E-1, 2.57975638E-1},
+{1.66923836E-1, 1.88604668E-1, 2.11124212E-1},
+{2.10620746E-1, 2.62442708E-1, 2.83127964E-1},
+{1.05748810E-1, 1.36286482E-1, 2.20050186E-1},
+{9.72945765E-2, 2.33471528E-1, 2.96113968E-1},
+{1.34298369E-1, 1.93955436E-1, 2.39148825E-1},
+{1.64229318E-1, 2.70067751E-1, 2.94142485E-1},
+{1.42760262E-1, 1.65033355E-1, 2.24100381E-1},
+{1.46414533E-1, 2.47942328E-1, 3.00708115E-1},
+{1.74778774E-1, 2.19349250E-1, 2.38162965E-1},
+{2.36311123E-1, 2.90669680E-1, 3.28010976E-1},
+{1.14076428E-1, 1.33071408E-1, 1.73181504E-1},
+{1.13575839E-1, 1.90307274E-1, 2.41681188E-1},
+{8.59165266E-2, 1.63920239E-1, 2.37934500E-1},
+{1.92916945E-1, 2.15082392E-1, 2.39128128E-1},
+{1.37291834E-1, 1.59423307E-1, 1.79722220E-1},
+{1.40435383E-1, 2.22092256E-1, 2.40960747E-1},
+{1.40387163E-1, 1.89601168E-1, 2.05635697E-1},
+{2.11695507E-1, 2.36578360E-1, 2.81248927E-1},
+{9.03010592E-2, 1.27157405E-1, 2.33567923E-1},
+{1.10118054E-1, 2.09328398E-1, 2.72836268E-1},
+{1.16710417E-1, 1.77853987E-1, 2.22808748E-1},
+{1.81691542E-1, 2.32265159E-1, 2.74991214E-1},
+{1.46553472E-1, 1.69474706E-1, 1.90245956E-1},
+{1.09213792E-1, 2.63291955E-1, 2.88490772E-1},
+{1.49815127E-1, 2.11342707E-1, 2.28899449E-1},
+{1.97645500E-1, 2.83229947E-1, 3.14882278E-1},
+{1.24495603E-1, 1.46097973E-1, 1.66125208E-1},
+{1.34878591E-1, 1.83030054E-1, 2.89288282E-1},
+{9.33032110E-2, 1.83962211E-1, 2.38543004E-1},
+{1.92844257E-1, 2.39588335E-1, 2.58421540E-1},
+{1.23796798E-1, 1.65556595E-1, 2.08408386E-1},
+{1.51144341E-1, 2.35801116E-1, 2.59280622E-1},
+{1.50657728E-1, 1.90052524E-1, 2.28362590E-1},
+{1.98180959E-1, 2.56794214E-1, 3.08975637E-1},
+{1.28490031E-1, 1.49084017E-1, 1.98376507E-1},
+{9.20595750E-2, 2.12231293E-1, 2.92948842E-1},
+{1.41698137E-1, 1.72356680E-1, 2.58454144E-1},
+{1.96733460E-1, 2.29709730E-1, 2.95780182E-1},
+{1.47062227E-1, 1.68918088E-1, 2.07363635E-1},
+{1.36309877E-1, 2.60373056E-1, 2.82607377E-1},
+{1.81041077E-1, 2.01826140E-1, 2.38867551E-1},
+{2.45326266E-1, 2.80183077E-1, 3.11954319E-1},
+{1.04131766E-1, 1.33040652E-1, 1.89834684E-1},
+{1.23298146E-1, 2.09621087E-1, 2.47813210E-1},
+{1.24040775E-1, 1.59827366E-1, 2.58856058E-1},
+{1.87048867E-1, 2.12488100E-1, 2.59629130E-1},
+{1.24255307E-1, 1.73768952E-1, 1.92850024E-1},
+{1.58917829E-1, 2.25389823E-1, 2.43284762E-1},
+{1.53421149E-1, 1.91807315E-1, 2.09249526E-1},
+{2.27154449E-1, 2.51181155E-1, 2.72600353E-1},
+{1.09922059E-1, 1.57100275E-1, 2.20024973E-1},
+{1.32782355E-1, 2.19485506E-1, 2.67028928E-1},
+{1.26857504E-1, 1.98836312E-1, 2.17928499E-1},
+{1.91415027E-1, 2.52424240E-1, 2.72652745E-1},
+{1.55277625E-1, 1.79573521E-1, 2.00773627E-1},
+{1.17547743E-1, 2.47869864E-1, 3.08279335E-1},
+{1.65706977E-1, 2.10339502E-1, 2.29199320E-1},
+{2.25694910E-1, 2.84438193E-1, 3.12106073E-1},
+{1.29503176E-1, 1.48420051E-1, 1.80180401E-1},
+{1.54752508E-1, 1.97748467E-1, 2.67275035E-1},
+{1.28590241E-1, 1.76178381E-1, 2.39905864E-1},
+{2.14926764E-1, 2.37634435E-1, 2.58794010E-1},
+{1.28322318E-1, 1.59338519E-1, 2.26626605E-1},
+{1.55747548E-1, 2.47740522E-1, 2.73726821E-1},
+{1.75741687E-1, 1.97952345E-1, 2.19115943E-1},
+{2.18626365E-1, 2.45809183E-1, 3.00479650E-1},
+{1.17709018E-1, 1.45512864E-1, 2.38044471E-1},
+{1.18006893E-1, 2.23775521E-1, 2.94175088E-1},
+{1.51349202E-1, 1.88157812E-1, 2.48743281E-1},
+{1.89312205E-1, 2.69580543E-1, 2.93785989E-1},
+{1.49895594E-1, 1.74537256E-1, 2.37430006E-1},
+{1.39775530E-1, 2.71709383E-1, 3.07839513E-1},
+{1.83945730E-1, 2.07717165E-1, 2.26722151E-1},
+{2.54552156E-1, 2.96640933E-1, 3.24801445E-1}};
+
+static const float evrc_lspq_half_codebook3[256][4] = {
+{2.36904725E-1, 2.56104350E-1, 3.16955745E-1, 4.07520533E-1},
+{2.97596931E-1, 3.23482454E-1, 3.47667515E-1, 3.74551237E-1},
+{2.73721159E-1, 2.98297524E-1, 3.29923928E-1, 3.83599102E-1},
+{3.07849586E-1, 3.32836270E-1, 3.89340341E-1, 4.05575991E-1},
+{2.33803615E-1, 2.60296524E-1, 3.67351949E-1, 4.04388249E-1},
+{2.97513664E-1, 3.15356553E-1, 3.85135233E-1, 4.02197123E-1},
+{2.85618782E-1, 3.10872793E-1, 3.65022361E-1, 3.84816766E-1},
+{3.35271597E-1, 3.55222225E-1, 3.81921113E-1, 3.98685753E-1},
+{2.00265601E-1, 2.50502288E-1, 3.70398223E-1, 4.32012677E-1},
+{3.07982087E-1, 3.33767712E-1, 3.58199060E-1, 3.78386796E-1},
+{2.60086119E-1, 3.25520277E-1, 3.56873333E-1, 3.84737790E-1},
+{3.01356375E-1, 3.41369390E-1, 4.00296748E-1, 4.17337179E-1},
+{2.67080963E-1, 2.97674358E-1, 3.69702041E-1, 3.89139235E-1},
+{2.72669852E-1, 3.49704087E-1, 3.91925275E-1, 4.06383276E-1},
+{2.52825916E-1, 3.49636555E-1, 3.84550989E-1, 4.05930996E-1},
+{3.42927098E-1, 3.74274015E-1, 4.05468166E-1, 4.20351923E-1},
+{2.52408743E-1, 2.80375838E-1, 3.21436584E-1, 3.88436913E-1},
+{2.96970189E-1, 3.17173600E-1, 3.65342557E-1, 4.02736843E-1},
+{2.81905174E-1, 3.01479161E-1, 3.34335625E-1, 4.07633483E-1},
+{3.26872945E-1, 3.47177684E-1, 3.75017703E-1, 4.05372381E-1},
+{2.36371145E-1, 3.16441059E-1, 3.48707020E-1, 3.82030427E-1},
+{2.87817597E-1, 3.13627005E-1, 4.05129731E-1, 4.23379660E-1},
+{2.77502477E-1, 3.01843822E-1, 3.72250855E-1, 4.19212818E-1},
+{3.28988850E-1, 3.61901104E-1, 4.02015507E-1, 4.19229805E-1},
+{2.24960461E-1, 2.74636388E-1, 3.77016127E-1, 3.94726515E-1},
+{3.01045477E-1, 3.40486169E-1, 3.74888122E-1, 4.02532160E-1},
+{2.59897947E-1, 3.30334961E-1, 3.57493818E-1, 4.08657968E-1},
+{3.00961852E-1, 3.56449068E-1, 4.04779494E-1, 4.22508955E-1},
+{2.20979586E-1, 3.16477656E-1, 4.01744068E-1, 4.20735776E-1},
+{2.79754996E-1, 3.30776095E-1, 4.11152899E-1, 4.32687044E-1},
+{2.64246881E-1, 3.16610634E-1, 3.83876741E-1, 4.36683774E-1},
+{3.44381154E-1, 3.85365665E-1, 4.24949467E-1, 4.41560209E-1},
+{2.19488308E-1, 2.36459881E-1, 3.42465997E-1, 4.24989998E-1},
+{2.91465104E-1, 3.22282016E-1, 3.72852802E-1, 3.91635895E-1},
+{2.74792433E-1, 3.16536307E-1, 3.45392585E-1, 3.74555230E-1},
+{3.10583472E-1, 3.35264921E-1, 3.87527227E-1, 4.23076212E-1},
+{2.23211512E-1, 2.98497617E-1, 3.68426204E-1, 3.90213728E-1},
+{2.89078832E-1, 3.26512754E-1, 3.76308680E-1, 4.09553707E-1},
+{2.63830125E-1, 3.08977246E-1, 3.81453037E-1, 4.04660761E-1},
+{3.47073615E-1, 3.64797831E-1, 3.86763453E-1, 4.04511690E-1},
+{2.18452707E-1, 2.75614083E-1, 3.62711072E-1, 4.18278992E-1},
+{3.15042794E-1, 3.40813220E-1, 3.78627181E-1, 3.96316767E-1},
+{2.79727697E-1, 3.31259727E-1, 3.60061288E-1, 3.81175518E-1},
+{3.18602443E-1, 3.38044286E-1, 4.09010768E-1, 4.30300415E-1},
+{2.64196932E-1, 2.90672481E-1, 3.68595004E-1, 4.31856751E-1},
+{2.72645593E-1, 3.63514841E-1, 3.96518826E-1, 4.20091212E-1},
+{2.26540968E-1, 3.50055099E-1, 3.93851519E-1, 4.12597001E-1},
+{3.53053868E-1, 3.69929552E-1, 4.09656048E-1, 4.26387310E-1},
+{2.60788381E-1, 2.85172462E-1, 3.45943332E-1, 3.97500694E-1},
+{3.01113129E-1, 3.28201890E-1, 3.56068015E-1, 4.10803795E-1},
+{2.88101614E-1, 3.09559643E-1, 3.43756795E-1, 4.24872875E-1},
+{3.10489357E-1, 3.51421893E-1, 3.93717408E-1, 4.15550530E-1},
+{2.22308263E-1, 3.26798201E-1, 3.77981663E-1, 3.98635030E-1},
+{3.02915514E-1, 3.22781920E-1, 3.98558855E-1, 4.25489604E-1},
+{2.77136803E-1, 3.19992602E-1, 3.77490878E-1, 4.29177463E-1},
+{3.38731766E-1, 3.58164370E-1, 4.08386350E-1, 4.25495386E-1},
+{2.18726233E-1, 2.84384966E-1, 3.94053698E-1, 4.16346967E-1},
+{3.01005960E-1, 3.44093680E-1, 3.69013667E-1, 4.15091276E-1},
+{2.80783713E-1, 3.33053648E-1, 3.76726151E-1, 3.97526860E-1},
+{3.14394057E-1, 3.62678826E-1, 4.23668981E-1, 4.41899240E-1},
+{2.66453624E-1, 3.08513761E-1, 3.97407174E-1, 4.17450190E-1},
+{2.94222653E-1, 3.41904402E-1, 4.12726879E-1, 4.34888899E-1},
+{2.87300706E-1, 3.32434595E-1, 3.78856659E-1, 4.38234031E-1},
+{3.57146621E-1, 3.98147047E-1, 4.29875731E-1, 4.44243908E-1},
+{2.29671344E-1, 2.51018614E-1, 3.41046572E-1, 4.04376328E-1},
+{2.94472575E-1, 3.34944606E-1, 3.60409737E-1, 3.83682847E-1},
+{2.88250983E-1, 3.11722696E-1, 3.31680059E-1, 3.65104675E-1},
+{3.24881613E-1, 3.45656693E-1, 3.88306379E-1, 4.05954897E-1},
+{2.50829220E-1, 2.77623534E-1, 3.70799541E-1, 3.90479207E-1},
+{2.93523371E-1, 3.28319192E-1, 3.92112255E-1, 4.09464061E-1},
+{2.83608794E-1, 3.03885639E-1, 3.78504395E-1, 3.97310555E-1},
+{3.34039807E-1, 3.52837384E-1, 3.97272944E-1, 4.14322019E-1},
+{2.21891895E-1, 2.51877457E-1, 3.71723533E-1, 4.31791008E-1},
+{3.13201427E-1, 3.41175437E-1, 3.65503550E-1, 3.88567209E-1},
+{2.71330535E-1, 3.39163721E-1, 3.62616420E-1, 3.95735979E-1},
+{3.07550132E-1, 3.47777665E-1, 4.01049614E-1, 4.32767451E-1},
+{2.59387434E-1, 2.87243843E-1, 3.86817336E-1, 4.06042695E-1},
+{2.85485208E-1, 3.44094992E-1, 4.02050495E-1, 4.19413745E-1},
+{2.65781403E-1, 3.40084374E-1, 3.69407654E-1, 4.27031696E-1},
+{3.53740931E-1, 3.84463251E-1, 4.11747813E-1, 4.26181793E-1},
+{2.43866488E-1, 2.68350184E-1, 3.42201948E-1, 3.98457229E-1},
+{2.93145239E-1, 3.34754169E-1, 3.61702800E-1, 3.98416638E-1},
+{2.91342974E-1, 3.13155174E-1, 3.36525917E-1, 3.87748599E-1},
+{3.05656791E-1, 3.62904549E-1, 3.88153434E-1, 4.05543149E-1},
+{2.17492327E-1, 3.11723530E-1, 3.75984788E-1, 4.28997755E-1},
+{2.91149259E-1, 3.29380929E-1, 4.03900385E-1, 4.22333181E-1},
+{2.90362060E-1, 3.09530973E-1, 3.78994226E-1, 4.13688362E-1},
+{3.29564869E-1, 3.77404690E-1, 4.06584859E-1, 4.24739718E-1},
+{2.46461585E-1, 2.71593273E-1, 3.66338253E-1, 4.30753767E-1},
+{3.14107716E-1, 3.37011874E-1, 3.80409718E-1, 4.11099434E-1},
+{2.76568413E-1, 3.27320695E-1, 3.58844280E-1, 4.28949475E-1},
+{3.17179084E-1, 3.58972430E-1, 4.04765844E-1, 4.40376341E-1},
+{2.42777750E-1, 3.34954798E-1, 3.96943450E-1, 4.13318396E-1},
+{2.88895488E-1, 3.25691164E-1, 4.22859550E-1, 4.43758667E-1},
+{2.77583301E-1, 3.25479031E-1, 3.89144659E-1, 4.41075861E-1},
+{3.59125674E-1, 3.90694141E-1, 4.21009541E-1, 4.35708523E-1},
+{2.20172390E-1, 2.47719273E-1, 3.54381859E-1, 4.25398111E-1},
+{3.06046784E-1, 3.27924728E-1, 3.66992772E-1, 3.93192589E-1},
+{2.70805597E-1, 3.16826642E-1, 3.45648706E-1, 4.11717594E-1},
+{3.23188901E-1, 3.45463097E-1, 3.89778793E-1, 4.21570778E-1},
+{2.46136114E-1, 3.12391996E-1, 3.72188628E-1, 3.95842731E-1},
+{3.03856730E-1, 3.24354768E-1, 3.85747254E-1, 4.14155006E-1},
+{2.81075418E-1, 3.18608463E-1, 3.85646880E-1, 4.02703643E-1},
+{3.53517115E-1, 3.72702539E-1, 3.96264613E-1, 4.13074911E-1},
+{2.09221140E-1, 2.95262218E-1, 3.80314291E-1, 4.31278229E-1},
+{3.25313628E-1, 3.46735477E-1, 3.70724022E-1, 3.91045630E-1},
+{2.86396503E-1, 3.43560040E-1, 3.69713604E-1, 3.89867842E-1},
+{3.27794671E-1, 3.47367823E-1, 4.05465066E-1, 4.24566150E-1},
+{2.53054976E-1, 3.02656293E-1, 3.82165134E-1, 4.29898322E-1},
+{2.94418454E-1, 3.70745420E-1, 3.95443261E-1, 4.19514775E-1},
+{2.62873113E-1, 3.45069230E-1, 4.04140890E-1, 4.21902061E-1},
+{3.65063488E-1, 3.82435143E-1, 4.13424790E-1, 4.31241691E-1},
+{2.48788506E-1, 2.82372773E-1, 3.65772307E-1, 4.10981059E-1},
+{3.07288766E-1, 3.27828944E-1, 3.77664983E-1, 4.36220944E-1},
+{2.98542321E-1, 3.20627332E-1, 3.50569665E-1, 4.27620232E-1},
+{3.16258013E-1, 3.62903833E-1, 3.88225138E-1, 4.25608873E-1},
+{2.39077866E-1, 3.31310451E-1, 3.70317876E-1, 4.15995896E-1},
+{3.03735793E-1, 3.32806051E-1, 4.10232842E-1, 4.27751064E-1},
+{2.96002507E-1, 3.19014788E-1, 3.81062448E-1, 4.26954985E-1},
+{3.32508922E-1, 3.62516999E-1, 4.23315108E-1, 4.40995157E-1},
+{2.35128701E-1, 2.74731100E-1, 4.12070572E-1, 4.35478806E-1},
+{2.98073769E-1, 3.55338752E-1, 3.79087746E-1, 4.15318787E-1},
+{2.83429801E-1, 3.45264912E-1, 3.70376289E-1, 4.09900844E-1},
+{3.23593080E-1, 3.65412831E-1, 4.12813127E-1, 4.31023479E-1},
+{2.76626348E-1, 3.00508440E-1, 4.02236879E-1, 4.26638782E-1},
+{2.94512928E-1, 3.61443222E-1, 4.19635236E-1, 4.36999202E-1},
+{2.90807247E-1, 3.41689348E-1, 3.92779291E-1, 4.43490267E-1},
+{3.59391451E-1, 4.03985143E-1, 4.40843761E-1, 4.53028619E-1},
+{2.23295465E-1, 2.39192486E-1, 3.23768020E-1, 4.21689451E-1},
+{2.94778049E-1, 3.18798721E-1, 3.53217840E-1, 3.91906381E-1},
+{2.59032130E-1, 3.10240507E-1, 3.43569040E-1, 3.95064235E-1},
+{3.16474676E-1, 3.38544369E-1, 3.93329024E-1, 4.12235558E-1},
+{2.40108207E-1, 2.84631193E-1, 3.60280991E-1, 3.79973769E-1},
+{2.96909094E-1, 3.15798342E-1, 3.94964337E-1, 4.15127575E-1},
+{2.85434067E-1, 3.04921508E-1, 3.61974716E-1, 4.05767262E-1},
+{3.37407053E-1, 3.56672168E-1, 3.85155082E-1, 4.11186695E-1},
+{2.24014923E-1, 2.60116160E-1, 3.94772530E-1, 4.19585884E-1},
+{3.00647914E-1, 3.41640651E-1, 3.70223522E-1, 3.89520049E-1},
+{2.65946031E-1, 3.25039148E-1, 3.74339938E-1, 3.92346144E-1},
+{3.16029310E-1, 3.40491295E-1, 4.02355313E-1, 4.20484245E-1},
+{2.69841492E-1, 2.94562399E-1, 3.62341762E-1, 4.06415462E-1},
+{2.78897285E-1, 3.59831035E-1, 3.82025838E-1, 4.10577476E-1},
+{2.60760844E-1, 3.31088543E-1, 3.88826251E-1, 4.05486643E-1},
+{3.43372285E-1, 3.82647038E-1, 4.14716601E-1, 4.31592941E-1},
+{2.47998103E-1, 2.73393154E-1, 3.31160426E-1, 4.18943226E-1},
+{3.03579569E-1, 3.25202465E-1, 3.70984435E-1, 4.14420485E-1},
+{2.76896894E-1, 3.00499499E-1, 3.54178190E-1, 4.28807020E-1},
+{3.23655546E-1, 3.59816968E-1, 3.89525414E-1, 4.09288704E-1},
+{2.38927796E-1, 3.09919238E-1, 3.53915572E-1, 4.16634321E-1},
+{2.81171739E-1, 3.07520270E-1, 4.16264892E-1, 4.38523829E-1},
+{2.88858652E-1, 3.09810817E-1, 3.67845178E-1, 4.36035573E-1},
+{3.38423491E-1, 3.70634377E-1, 4.15449977E-1, 4.31534529E-1},
+{2.41260394E-1, 2.73617864E-1, 3.89554620E-1, 4.12539542E-1},
+{2.98046708E-1, 3.40122104E-1, 3.86183739E-1, 4.13826346E-1},
+{2.82436430E-1, 3.31597507E-1, 3.57941389E-1, 4.12115216E-1},
+{3.03820193E-1, 3.70588601E-1, 4.05774951E-1, 4.31517065E-1},
+{2.39077732E-1, 3.11638474E-1, 4.13935781E-1, 4.35304046E-1},
+{2.67116845E-1, 3.41937900E-1, 4.17409420E-1, 4.39184844E-1},
+{2.67946839E-1, 3.33343923E-1, 3.86481404E-1, 4.37462509E-1},
+{3.40510964E-1, 3.90878022E-1, 4.35485125E-1, 4.49101925E-1},
+{2.10069850E-1, 2.32524484E-1, 3.61781418E-1, 4.31357861E-1},
+{2.94509888E-1, 3.33709776E-1, 3.82278621E-1, 3.98638904E-1},
+{2.80525148E-1, 3.25905204E-1, 3.50647032E-1, 3.92873943E-1},
+{3.19999635E-1, 3.43674660E-1, 3.91070545E-1, 4.37501073E-1},
+{2.20581010E-1, 3.03151906E-1, 3.81765544E-1, 4.04488146E-1},
+{2.86122739E-1, 3.29746544E-1, 3.88102829E-1, 4.24247742E-1},
+{2.69807100E-1, 3.25332284E-1, 3.79154503E-1, 4.15138245E-1},
+{3.34858894E-1, 3.69258404E-1, 3.94743145E-1, 4.11922157E-1},
+{2.07109794E-1, 2.72779524E-1, 3.78566444E-1, 4.34579968E-1},
+{3.06466222E-1, 3.46695721E-1, 3.87138307E-1, 4.03558314E-1},
+{2.70148575E-1, 3.46654534E-1, 3.77696693E-1, 3.96434486E-1},
+{3.18745911E-1, 3.40225697E-1, 4.14991558E-1, 4.41578746E-1},
+{2.58592844E-1, 3.14370096E-1, 3.65083754E-1, 4.21615183E-1},
+{2.82712996E-1, 3.54137123E-1, 4.06745970E-1, 4.29267883E-1},
+{2.52021760E-1, 3.59105110E-1, 3.95102918E-1, 4.18148398E-1},
+{3.54906201E-1, 3.74952912E-1, 4.18965995E-1, 4.36144412E-1},
+{2.64841139E-1, 2.92941809E-1, 3.27751458E-1, 4.08790469E-1},
+{3.07774246E-1, 3.35586190E-1, 3.62209618E-1, 4.25394237E-1},
+{2.88466334E-1, 3.16075742E-1, 3.60989630E-1, 4.19551432E-1},
+{3.17128420E-1, 3.55772197E-1, 4.05808747E-1, 4.23972964E-1},
+{2.47089684E-1, 3.38184595E-1, 3.71859610E-1, 3.95971477E-1},
+{3.07981730E-1, 3.32691789E-1, 4.00534213E-1, 4.38273668E-1},
+{2.79484808E-1, 3.16183507E-1, 3.97237718E-1, 4.34746623E-1},
+{3.44490469E-1, 3.66153181E-1, 4.10959423E-1, 4.41727102E-1},
+{2.35741779E-1, 2.94587255E-1, 3.98072541E-1, 4.16833401E-1},
+{3.14038455E-1, 3.52272034E-1, 3.79138887E-1, 4.10969079E-1},
+{2.83002496E-1, 3.38136256E-1, 3.88641894E-1, 4.06193316E-1},
+{3.23625326E-1, 3.50243390E-1, 4.28089559E-1, 4.46630359E-1},
+{2.61252105E-1, 3.24970961E-1, 4.00214493E-1, 4.25321758E-1},
+{3.05284500E-1, 3.42164159E-1, 4.24475133E-1, 4.43830967E-1},
+{2.87374794E-1, 3.32500637E-1, 3.94308269E-1, 4.42538500E-1},
+{3.74075353E-1, 4.02026355E-1, 4.30933535E-1, 4.44160044E-1},
+{2.34503999E-1, 2.56218612E-1, 3.41238797E-1, 4.23045278E-1},
+{3.05492580E-1, 3.29156995E-1, 3.52709830E-1, 3.92439067E-1},
+{2.81323552E-1, 3.03292334E-1, 3.48925412E-1, 3.93163860E-1},
+{3.21893454E-1, 3.50419939E-1, 3.97317469E-1, 4.14560318E-1},
+{2.39684582E-1, 2.92451501E-1, 3.78937423E-1, 3.96535456E-1},
+{3.07307243E-1, 3.29127908E-1, 3.98455560E-1, 4.16143298E-1},
+{2.85274565E-1, 3.08774531E-1, 3.92916501E-1, 4.14437652E-1},
+{3.44446361E-1, 3.62201869E-1, 3.97619784E-1, 4.17743623E-1},
+{2.32083067E-1, 2.67807961E-1, 3.78075659E-1, 4.34560895E-1},
+{3.04738700E-1, 3.51865292E-1, 3.75973165E-1, 3.95293653E-1},
+{2.61990905E-1, 3.46207321E-1, 3.71296942E-1, 4.12438929E-1},
+{3.11080933E-1, 3.51040900E-1, 4.16082799E-1, 4.34340119E-1},
+{2.74980426E-1, 2.96631455E-1, 3.87520492E-1, 4.09243762E-1},
+{2.90939093E-1, 3.54455590E-1, 3.93426955E-1, 4.08220291E-1},
+{2.71871865E-1, 3.45510781E-1, 3.87125313E-1, 4.22590613E-1},
+{3.63245904E-1, 3.81932199E-1, 4.04114902E-1, 4.18370664E-1},
+{2.45770738E-1, 2.72909343E-1, 3.48317921E-1, 4.25161839E-1},
+{3.14139009E-1, 3.37872326E-1, 3.65195215E-1, 4.04423416E-1},
+{2.94075787E-1, 3.16935539E-1, 3.43047202E-1, 4.06130373E-1},
+{3.14627469E-1, 3.72413397E-1, 4.00660694E-1, 4.17930841E-1},
+{2.34014243E-1, 3.14007223E-1, 3.83003533E-1, 4.34829175E-1},
+{2.93635666E-1, 3.20529997E-1, 4.10837352E-1, 4.36393142E-1},
+{2.89505839E-1, 3.11828852E-1, 3.86311471E-1, 4.38771248E-1},
+{3.26317430E-1, 3.80858183E-1, 4.19721425E-1, 4.38795507E-1},
+{2.50809520E-1, 2.83018053E-1, 3.82247388E-1, 4.34244394E-1},
+{3.18994045E-1, 3.44855130E-1, 3.72690141E-1, 4.23067033E-1},
+{2.88380086E-1, 3.36622238E-1, 3.69742334E-1, 4.25057590E-1},
+{3.06107700E-1, 3.81856918E-1, 4.18206155E-1, 4.32868361E-1},
+{2.33898312E-1, 3.44861805E-1, 4.12176549E-1, 4.29216206E-1},
+{2.85980880E-1, 3.42903793E-1, 4.25112903E-1, 4.44299698E-1},
+{2.79858828E-1, 3.38789344E-1, 3.92085373E-1, 4.40541029E-1},
+{3.64509344E-1, 3.82202744E-1, 4.29830611E-1, 4.45818365E-1},
+{2.34392300E-1, 2.57377386E-1, 3.59567046E-1, 4.30088580E-1},
+{3.05031896E-1, 3.27589393E-1, 3.78305554E-1, 4.01026130E-1},
+{2.77522624E-1, 3.18130314E-1, 3.67794275E-1, 4.01543021E-1},
+{3.33035767E-1, 3.55820954E-1, 3.87548923E-1, 4.24628675E-1},
+{2.45021001E-1, 3.12560678E-1, 3.91147614E-1, 4.08762813E-1},
+{2.97059119E-1, 3.40246916E-1, 3.92919302E-1, 4.28899705E-1},
+{2.77839303E-1, 3.25019777E-1, 3.97436380E-1, 4.15920913E-1},
+{3.49465251E-1, 3.70362461E-1, 3.95482540E-1, 4.31923389E-1},
+{2.31485590E-1, 2.91023374E-1, 3.77909541E-1, 4.32259738E-1},
+{3.19283485E-1, 3.53671074E-1, 3.80982876E-1, 3.97843361E-1},
+{2.89689243E-1, 3.50265682E-1, 3.80729675E-1, 3.97969365E-1},
+{3.28987300E-1, 3.52005422E-1, 4.12557244E-1, 4.37597930E-1},
+{2.76273251E-1, 3.02267194E-1, 3.81723404E-1, 4.34989095E-1},
+{2.79627264E-1, 3.73727322E-1, 4.12374616E-1, 4.30626333E-1},
+{2.53442764E-1, 3.65940034E-1, 4.14937019E-1, 4.32743609E-1},
+{3.76107216E-1, 3.95142019E-1, 4.16787744E-1, 4.33023572E-1},
+{2.62815833E-1, 2.88270533E-1, 3.47397208E-1, 4.24182594E-1},
+{3.01931322E-1, 3.43652546E-1, 3.77031326E-1, 4.34204459E-1},
+{2.97834277E-1, 3.23495388E-1, 3.64492416E-1, 4.33550835E-1},
+{3.31774473E-1, 3.64324927E-1, 3.98243546E-1, 4.35078323E-1},
+{2.49049723E-1, 3.27870786E-1, 3.83587003E-1, 4.35558081E-1},
+{3.04653406E-1, 3.27671230E-1, 4.18484688E-1, 4.41378772E-1},
+{2.96960890E-1, 3.23898911E-1, 3.90463710E-1, 4.39915955E-1},
+{3.43923748E-1, 3.67100477E-1, 4.29523230E-1, 4.45214987E-1},
+{2.59399652E-1, 2.91602671E-1, 4.04372454E-1, 4.31413233E-1},
+{2.97537506E-1, 3.57573807E-1, 3.88991833E-1, 4.30006981E-1},
+{2.84068942E-1, 3.49574566E-1, 3.81042838E-1, 4.29712772E-1},
+{3.25716257E-1, 3.74875903E-1, 4.31959271E-1, 4.47290838E-1},
+{2.65302956E-1, 3.14745963E-1, 4.16703463E-1, 4.37294722E-1},
+{3.00398588E-1, 3.54147255E-1, 4.28538084E-1, 4.60336387E-1},
+{2.98077166E-1, 3.49304914E-1, 4.00429249E-1, 4.48213518E-1},
+{3.75576198E-1, 4.16657329E-1, 4.42136765E-1, 4.52728629E-1}};
+
+static const float evrc_lspq_quant_codebook1[16][5] = {
+{0.42091064E-1, 0.69474973E-1, 0.11168948E+0, 0.14571965E+0, 0.20893581E+0},
+{0.54944664E-1, 0.98242261E-1, 0.11007882E+0, 0.15890779E+0, 0.20548241E+0},
+{0.45188572E-1, 0.75199433E-1, 0.11423391E+0, 0.15469728E+0, 0.19746706E+0},
+{0.49474996E-1, 0.79667501E-1, 0.12571351E+0, 0.16944779E+0, 0.20775315E+0},
+{0.41789379E-1, 0.63459560E-1, 0.12068028E+0, 0.15850765E+0, 0.20406815E+0},
+{0.47159236E-1, 0.79129547E-1, 0.12183110E+0, 0.15650047E+0, 0.22309226E+0},
+{0.54539919E-1, 0.80343045E-1, 0.12947764E+0, 0.15186153E+0, 0.20171718E+0},
+{0.55852082E-1, 0.94114847E-1, 0.14016025E+0, 0.17807084E+0, 0.22955489E+0},
+{0.45443531E-1, 0.73541410E-1, 0.11937657E+0, 0.15442030E+0, 0.21010752E+0},
+{0.63178010E-1, 0.95231488E-1, 0.12364983E+0, 0.17672543E+0, 0.21743731E+0},
+{0.52765369E-1, 0.84351443E-1, 0.11589085E+0, 0.15790924E+0, 0.20732352E+0},
+{0.51865745E-1, 0.81328541E-1, 0.13756232E+0, 0.18322878E+0, 0.21640070E+0},
+{0.44419531E-1, 0.68874463E-1, 0.13115251E+0, 0.16263582E+0, 0.21659100E+0},
+{0.49378436E-1, 0.81882551E-1, 0.13067168E+0, 0.16821896E+0, 0.23136081E+0},
+{0.55909779E-1, 0.90783298E-1, 0.13348848E+0, 0.16298474E+0, 0.20961523E+0},
+{0.61378211E-1, 0.98602772E-1, 0.14793332E+0, 0.19283190E+0, 0.23156509E+0}};
+
+static const float evrc_lspq_quant_codebook2[16][5] = {
+{0.26822963, 0.30585295, 0.31110349, 0.36823335, 0.40774474},
+{0.24418014, 0.28970167, 0.32573757, 0.39021483, 0.41345838},
+{0.23341830, 0.30078292, 0.32893899, 0.38557330, 0.41068462},
+{0.25905868, 0.29756859, 0.34196618, 0.38531172, 0.41295227},
+{0.24290450, 0.29223618, 0.32718554, 0.37788135, 0.40332928},
+{0.24674191, 0.29749370, 0.33631226, 0.39426059, 0.42258954},
+{0.21377595, 0.33140418, 0.34067687, 0.38222077, 0.40939021},
+{0.26673481, 0.30791649, 0.34419721, 0.39611506, 0.42387524},
+{0.26121426, 0.30492544, 0.32997236, 0.38486803, 0.42023736},
+{0.24954870, 0.29372856, 0.33382735, 0.37850669, 0.41714057},
+{0.24158891, 0.30173415, 0.34128246, 0.38428575, 0.41619650},
+{0.25818908, 0.31736413, 0.34904337, 0.38769925, 0.41551358},
+{0.24450587, 0.30673453, 0.33579323, 0.37844428, 0.40557048},
+{0.25164026, 0.31225079, 0.33847794, 0.39554194, 0.42396802},
+{0.22787990, 0.31779197, 0.33831909, 0.40044111, 0.41185561},
+{0.27896860, 0.32261974, 0.35658112, 0.40206763, 0.42370448}};
+
+static const float const *evrc_lspq_full_codebooks[] = {
+    evrc_lspq_full_codebook1[0], evrc_lspq_full_codebook2[0],
+    evrc_lspq_full_codebook3[0], evrc_lspq_full_codebook4[0],
+};
+
+static const float const *evrc_lspq_half_codebooks[] = {
+    evrc_lspq_half_codebook1[0], evrc_lspq_half_codebook2[0],
+    evrc_lspq_half_codebook3[0],
+};
+
+static const float const *evrc_lspq_quant_codebooks[] = {
+    evrc_lspq_quant_codebook1[0], evrc_lspq_quant_codebook2[0],
+};
+
+static const float const **evrc_lspq_codebooks[] = {
+    0,
+    evrc_lspq_quant_codebooks,
+    0,
+    evrc_lspq_half_codebooks,
+    evrc_lspq_full_codebooks,
+};
+
+static const uint8_t evrc_lspq_nb_codebooks[] = {
+    0,
+    FF_ARRAY_ELEMS(evrc_lspq_quant_codebooks),
+    0,
+    FF_ARRAY_ELEMS(evrc_lspq_half_codebooks),
+    FF_ARRAY_ELEMS(evrc_lspq_full_codebooks),
+};
+
+static const uint8_t evrc_lspq_full_codebooks_row_sizes[] = {
+    FF_ARRAY_ELEMS(evrc_lspq_full_codebook1[0]),
+    FF_ARRAY_ELEMS(evrc_lspq_full_codebook2[0]),
+    FF_ARRAY_ELEMS(evrc_lspq_full_codebook3[0]),
+    FF_ARRAY_ELEMS(evrc_lspq_full_codebook4[0]),
+};
+
+static const uint8_t evrc_lspq_half_codebooks_row_sizes[] = {
+    FF_ARRAY_ELEMS(evrc_lspq_half_codebook1[0]),
+    FF_ARRAY_ELEMS(evrc_lspq_half_codebook2[0]),
+    FF_ARRAY_ELEMS(evrc_lspq_half_codebook3[0]),
+};
+
+static const uint8_t evrc_lspq_quant_codebooks_row_sizes[] = {
+    FF_ARRAY_ELEMS(evrc_lspq_quant_codebook1[0]),
+    FF_ARRAY_ELEMS(evrc_lspq_quant_codebook2[0]),
+};
+
+static const uint8_t* const evrc_lspq_codebooks_row_sizes[] = {
+    NULL,
+    evrc_lspq_quant_codebooks_row_sizes,
+    NULL,
+    evrc_lspq_half_codebooks_row_sizes,
+    evrc_lspq_full_codebooks_row_sizes,
+};
+
+static const float pitch_gain_vq[] = { 0, 0.3, 0.55, 0.7, 0.8, 0.9, 1, 1.2 };
+static const float estimation_delay[] = { 55.0, 80.0, 39.0, 71.0, 33.0 }; // 5.2.3.4
+static const uint8_t subframe_sizes[] = { 53, 53, 54 };
+#endif /* AVCODEC_EVRCDATA_H */
diff --git a/libavcodec/evrcdec.c b/libavcodec/evrcdec.c
new file mode 100644
index 0000000..5569ca2
--- /dev/null
+++ b/libavcodec/evrcdec.c
@@ -0,0 +1,917 @@
+/*
+ * Enhanced Variable Rate Codec, Service Option 3 decoder
+ * 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
+ * Enhanced Variable Rate Codec, Service Option 3 decoder
+ * @author Paul B Mahol
+ */
+
+#include "libavutil/mathematics.h"
+#include "avcodec.h"
+#include "internal.h"
+#include "get_bits.h"
+#include "evrcdata.h"
+#include "acelp_vectors.h"
+#include "lsp.h"
+
+#define MIN_LSP_SEP (0.05 / (2.0 * M_PI))
+#define MIN_DELAY      20
+#define MAX_DELAY     120
+#define NB_SUBFRAMES    3
+#define SUBFRAME_SIZE  54
+#define FILTER_ORDER   10
+#define ACB_SIZE      128
+
+typedef enum {
+    RATE_ERRS = -1,
+    SILENCE,
+    RATE_QUANT,
+    RATE_QUARTER,
+    RATE_HALF,
+    RATE_FULL,
+} evrc_packet_rate;
+
+/**
+ * EVRC-A unpacked data frame
+ */
+typedef struct EVRCAFrame {
+    uint8_t  lpc_flag;        ///< spectral change indicator
+    uint16_t lsp[4];          ///< index into LSP codebook
+    uint8_t  pitch_delay;     ///< pitch delay for entire frame
+    uint8_t  delay_diff;      ///< delay difference for entire frame
+    uint8_t  acb_gain[3];     ///< adaptive codebook gain
+    uint16_t fcb_shape[3][4]; ///< fixed codebook shape
+    uint8_t  fcb_gain[3];     ///< fixed codebook gain index
+    uint8_t  energy_gain;     ///< frame energy gain index
+    uint8_t  tty;             ///< tty baud rate bit
+} EVRCAFrame;
+
+typedef struct EVRCContext {
+    GetBitContext    gb;
+    evrc_packet_rate bitrate;
+    evrc_packet_rate last_valid_bitrate;
+    EVRCAFrame       frame;
+
+    float            lspf[FILTER_ORDER];
+    float            prev_lspf[FILTER_ORDER];
+    float            synthesis[FILTER_ORDER];
+    float            postfilter_fir[FILTER_ORDER];
+    float            postfilter_iir[FILTER_ORDER];
+    float            postfilter_residual[ACB_SIZE + SUBFRAME_SIZE];
+    float            pitch_delay;
+    float            prev_pitch_delay;
+    float            avg_acb_gain;  ///< average adaptive codebook gain
+    float            avg_fcb_gain;  ///< average fixed codebook gain
+    float            pitch[ACB_SIZE + FILTER_ORDER + SUBFRAME_SIZE];
+    float            pitch_back[ACB_SIZE];
+    float            interpolation_coeffs[136];
+    float            energy_vector[NB_SUBFRAMES];
+    float            fade_scale;
+    float            last;
+
+    uint8_t          prev_energy_gain;
+    uint8_t          prev_error_flag;
+    uint8_t          warned_buf_mismatch_bitrate;
+} EVRCContext;
+
+/**
+ * Frame unpacking for RATE_FULL, RATE_HALF and RATE_QUANT
+ *
+ * @param e the context
+ *
+ * TIA/IS-127 Table 4.21-1
+ */
+static void unpack_frame(EVRCContext *e)
+{
+    EVRCAFrame *frame = &e->frame;
+    GetBitContext *gb = &e->gb;
+
+    switch (e->bitrate) {
+    case RATE_FULL:
+        frame->lpc_flag        = get_bits1(gb);
+        frame->lsp[0]          = get_bits(gb,  6);
+        frame->lsp[1]          = get_bits(gb,  6);
+        frame->lsp[2]          = get_bits(gb,  9);
+        frame->lsp[3]          = get_bits(gb,  7);
+        frame->pitch_delay     = get_bits(gb,  7);
+        frame->delay_diff      = get_bits(gb,  5);
+        frame->acb_gain[0]     = get_bits(gb,  3);
+        frame->fcb_shape[0][0] = get_bits(gb,  8);
+        frame->fcb_shape[0][1] = get_bits(gb,  8);
+        frame->fcb_shape[0][2] = get_bits(gb,  8);
+        frame->fcb_shape[0][3] = get_bits(gb, 11);
+        frame->fcb_gain[0]     = get_bits(gb,  5);
+        frame->acb_gain[1]     = get_bits(gb,  3);
+        frame->fcb_shape[1][0] = get_bits(gb,  8);
+        frame->fcb_shape[1][1] = get_bits(gb,  8);
+        frame->fcb_shape[1][2] = get_bits(gb,  8);
+        frame->fcb_shape[1][3] = get_bits(gb, 11);
+        frame->fcb_gain    [1] = get_bits(gb,  5);
+        frame->acb_gain    [2] = get_bits(gb,  3);
+        frame->fcb_shape[2][0] = get_bits(gb,  8);
+        frame->fcb_shape[2][1] = get_bits(gb,  8);
+        frame->fcb_shape[2][2] = get_bits(gb,  8);
+        frame->fcb_shape[2][3] = get_bits(gb, 11);
+        frame->fcb_gain    [2] = get_bits(gb,  5);
+        frame->tty             = get_bits1(gb);
+        break;
+    case RATE_HALF:
+        frame->lsp         [0] = get_bits(gb,  7);
+        frame->lsp         [1] = get_bits(gb,  7);
+        frame->lsp         [2] = get_bits(gb,  8);
+        frame->pitch_delay     = get_bits(gb,  7);
+        frame->acb_gain    [0] = get_bits(gb,  3);
+        frame->fcb_shape[0][0] = get_bits(gb, 10);
+        frame->fcb_gain    [0] = get_bits(gb,  4);
+        frame->acb_gain    [1] = get_bits(gb,  3);
+        frame->fcb_shape[1][0] = get_bits(gb, 10);
+        frame->fcb_gain    [1] = get_bits(gb,  4);
+        frame->acb_gain    [2] = get_bits(gb,  3);
+        frame->fcb_shape[2][0] = get_bits(gb, 10);
+        frame->fcb_gain    [2] = get_bits(gb,  4);
+        break;
+    case RATE_QUANT:
+        frame->lsp         [0] = get_bits(gb, 4);
+        frame->lsp         [1] = get_bits(gb, 4);
+        frame->energy_gain     = get_bits(gb, 8);
+        break;
+    }
+}
+
+static evrc_packet_rate buf_size2bitrate(const int buf_size)
+{
+    switch (buf_size) {
+    case 23: return RATE_FULL;
+    case 11: return RATE_HALF;
+    case  6: return RATE_QUARTER;
+    case  3: return RATE_QUANT;
+    case  1: return SILENCE;
+    }
+
+    return RATE_ERRS;
+}
+
+/**
+ * Determine the bitrate from the frame size and/or the first byte of the frame.
+ *
+ * @param avctx the AV codec context
+ * @param buf_size length of the buffer
+ * @param buf the bufffer
+ *
+ * @return the bitrate on success,
+ *         RATE_ERRS  if the bitrate cannot be satisfactorily determined
+ */
+static evrc_packet_rate determine_bitrate(AVCodecContext *avctx,
+                                          int *buf_size,
+                                          const uint8_t **buf)
+{
+    evrc_packet_rate bitrate;
+
+    if ((bitrate = buf_size2bitrate(*buf_size)) >= 0) {
+        if (bitrate > **buf) {
+            EVRCContext *e = avctx->priv_data;
+            if (!e->warned_buf_mismatch_bitrate) {
+                av_log(avctx, AV_LOG_WARNING,
+                       "Claimed bitrate and buffer size mismatch.\n");
+                e->warned_buf_mismatch_bitrate = 1;
+            }
+            bitrate = **buf;
+        } else if (bitrate < **buf) {
+            av_log(avctx, AV_LOG_ERROR,
+                   "Buffer is too small for the claimed bitrate.\n");
+            return RATE_ERRS;
+        }
+        (*buf)++;
+        *buf_size -= 1;
+    } else if ((bitrate = buf_size2bitrate(*buf_size + 1)) >= 0) {
+        av_log(avctx, AV_LOG_DEBUG,
+               "Bitrate byte is missing, guessing the bitrate from packet size.\n");
+    } else
+        return RATE_ERRS;
+
+    return bitrate;
+}
+
+static void warn_insufficient_frame_quality(AVCodecContext *avctx,
+                                            const char *message)
+{
+    av_log(avctx, AV_LOG_WARNING, "Frame #%d, %s\n",
+           avctx->frame_number, message);
+}
+
+/**
+ * Initialize the speech codec according to the specification.
+ *
+ * TIA/IS-127 5.2
+ */
+static av_cold int evrc_decode_init(AVCodecContext *avctx)
+{
+    EVRCContext *e = avctx->priv_data;
+    int i, n, idx = 0;
+    float denom = 2.0 / (2.0 * 8.0 + 1.0);
+
+    avctx->channels       = 1;
+    avctx->channel_layout = AV_CH_LAYOUT_MONO;
+    avctx->sample_fmt     = AV_SAMPLE_FMT_FLT;
+
+    for (i = 0; i < FILTER_ORDER; i++) {
+        e->prev_lspf[i] = (i + 1) * 0.048;
+        e->synthesis[i] = 0.0;
+    }
+
+    for (i = 0; i < ACB_SIZE; i++)
+        e->pitch[i] = e->pitch_back[i] = 0.0;
+
+    e->last_valid_bitrate = RATE_QUANT;
+    e->prev_pitch_delay   = 40.0;
+    e->fade_scale         = 1.0;
+    e->prev_error_flag    = 0;
+    e->avg_acb_gain = e->avg_fcb_gain = 0.0;
+
+    for (i = 0; i < 8; i++) {
+        float tt = ((float)i - 8.0 / 2.0) / 8.0;
+
+        for (n = -8; n <= 8; n++, idx++) {
+            float arg1 = M_PI * 0.9 * (tt - n);
+            float arg2 = M_PI * (tt - n);
+
+            e->interpolation_coeffs[idx] = 0.9;
+            if (arg1)
+                e->interpolation_coeffs[idx] *= (0.54 + 0.46 * cos(arg2 * denom)) *
+                                                 sin(arg1) / arg1;
+        }
+    }
+
+    return 0;
+}
+
+/**
+ * Decode the 10 vector quantized line spectral pair frequencies from the LSP
+ * transmission codes of any bitrate and check for badly received packets.
+ *
+ * @param e the context
+ *
+ * @return 0 on success, -1 if the packet is badly received
+ *
+ * TIA/IS-127 5.2.1, 5.7.1
+ */
+static int decode_lspf(EVRCContext *e)
+{
+    const float **codebooks = evrc_lspq_codebooks[e->bitrate];
+    int i, j, k = 0;
+
+    for (i = 0; i < evrc_lspq_nb_codebooks[e->bitrate]; i++) {
+        int row_size = evrc_lspq_codebooks_row_sizes[e->bitrate][i];
+        const float *codebook = codebooks[i];
+
+        for (j = 0; j < row_size; j++)
+            e->lspf[k++] = codebook[e->frame.lsp[i] * row_size + j];
+    }
+
+    // check for monotonic LSPs
+    for (i = 1; i < FILTER_ORDER; i++)
+        if (e->lspf[i] <= e->lspf[i - 1])
+            return -1;
+
+    // check for minimum separation of LSPs at the splits
+    for (i = 0, k = 0; i < evrc_lspq_nb_codebooks[e->bitrate] - 1; i++) {
+        k += evrc_lspq_codebooks_row_sizes[e->bitrate][i];
+        if (e->lspf[k] - e->lspf[k - 1] <= MIN_LSP_SEP)
+            return -1;
+    }
+
+    return 0;
+}
+
+/*
+ * Interpolation of LSP parameters.
+ *
+ * TIA/IS-127 5.2.3.1, 5.7.3.2
+ */
+static void interpolate_lsp(float *ilsp, const float *lsp,
+                            const float *prev, int index)
+{
+    static const float lsp_interpolation_factors[] = { 0.1667, 0.5, 0.8333 };
+    ff_weighted_vector_sumf(ilsp, prev, lsp,
+                            1.0 - lsp_interpolation_factors[index],
+                            lsp_interpolation_factors[index], FILTER_ORDER);
+}
+
+/*
+ * Reconstruction of the delay contour.
+ *
+ * TIA/IS-127 5.2.2.3.2
+ */
+static void interpolate_delay(float *dst, float current, float prev, int index)
+{
+    static const float d_interpolation_factors[] = { 0, 0.3313, 0.6625, 1, 1 };
+    dst[0] = (1.0 - d_interpolation_factors[index    ]) * prev
+                  + d_interpolation_factors[index    ]  * current;
+    dst[1] = (1.0 - d_interpolation_factors[index + 1]) * prev
+                  + d_interpolation_factors[index + 1]  * current;
+    dst[2] = (1.0 - d_interpolation_factors[index + 2]) * prev
+                  + d_interpolation_factors[index + 2]  * current;
+}
+
+/*
+ * Convert the quantized, interpolated line spectral frequencies,
+ * to prediction coefficients.
+ *
+ * TIA/IS-127 5.2.3.2, 4.7.2.2
+ */
+static void decode_predictor_coeffs(const float *ilspf, float *ilpc)
+{
+    double lsp[FILTER_ORDER];
+    float a[FILTER_ORDER / 2 + 1], b[FILTER_ORDER / 2 + 1];
+    float a1[FILTER_ORDER / 2] = { 0 };
+    float a2[FILTER_ORDER / 2] = { 0 };
+    float b1[FILTER_ORDER / 2] = { 0 };
+    float b2[FILTER_ORDER / 2] = { 0 };
+    int i, k;
+
+    ff_acelp_lsf2lspd(lsp, ilspf, FILTER_ORDER);
+
+    for (k = 0; k <= FILTER_ORDER; k++) {
+        a[0] = k < 2 ? 0.25 : 0;
+        b[0] = k < 2 ? k < 1 ? 0.25 : -0.25 : 0;
+
+        for (i = 0; i < FILTER_ORDER / 2; i++) {
+            a[i + 1] = a[i] - 2 * lsp[i * 2    ] * a1[i] + a2[i];
+            b[i + 1] = b[i] - 2 * lsp[i * 2 + 1] * b1[i] + b2[i];
+            a2[i] = a1[i];
+            a1[i] = a[i];
+            b2[i] = b1[i];
+            b1[i] = b[i];
+        }
+
+        if (k)
+            ilpc[k - 1] = 2.0 * (a[FILTER_ORDER / 2] + b[FILTER_ORDER / 2]);
+    }
+}
+
+static void bl_intrp(EVRCContext *e, float *ex, float delay)
+{
+    float *f;
+    int offset, i, coef_idx;
+    int16_t t;
+
+    offset = lrintf(fabs(delay));
+
+    t = (offset - delay + 0.5) * 8.0 + 0.5;
+    if (t == 8) {
+        t = 0;
+        offset--;
+    }
+
+    f = ex - offset - 8;
+
+    coef_idx = t * (2 * 8 + 1);
+
+    ex[0] = 0.0;
+    for (i = 0; i < 2 * 8 + 1; i++)
+        ex[0] += e->interpolation_coeffs[coef_idx + i] * f[i];
+}
+
+/*
+ * Adaptive codebook excitation.
+ *
+ * TIA/IS-127 5.2.2.3.3, 4.12.5.2
+ */
+static void acb_excitation(EVRCContext *e, float *excitation, float gain,
+                           const float delay[3], int length)
+{
+    float denom, locdelay, dpr, invl;
+    int i;
+
+    invl = 1.0 / ((float) length);
+    dpr = length;
+
+    /* first at-most extra samples */
+    denom = (delay[1] - delay[0]) * invl;
+    for (i = 0; i < dpr; i++) {
+        locdelay = delay[0] + i * denom;
+        bl_intrp(e, excitation + i, locdelay);
+    }
+
+    denom = (delay[2] - delay[1]) * invl;
+    /* interpolation */
+    for (i = dpr; i < dpr + 10; i++) {
+        locdelay = delay[1] + (i - dpr) * denom;
+        bl_intrp(e, excitation + i, locdelay);
+    }
+
+    for (i = 0; i < length; i++)
+        excitation[i] *= gain;
+}
+
+static void decode_8_pulses_35bits(const uint16_t *fixed_index, float *cod)
+{
+    int i, pos1, pos2, offset;
+
+    offset = (fixed_index[3] >> 9) & 3;
+
+    for (i = 0; i < 3; i++) {
+        pos1 = ((fixed_index[i] & 0x7f) / 11) * 5 + ((i + offset) % 5);
+        pos2 = ((fixed_index[i] & 0x7f) % 11) * 5 + ((i + offset) % 5);
+
+        cod[pos1] = (fixed_index[i] & 0x80) ? -1.0 : 1.0;
+
+        if (pos2 < pos1)
+            cod[pos2]  = -cod[pos1];
+        else
+            cod[pos2] +=  cod[pos1];
+    }
+
+    pos1 = ((fixed_index[3] & 0x7f) / 11) * 5 + ((3 + offset) % 5);
+    pos2 = ((fixed_index[3] & 0x7f) % 11) * 5 + ((4 + offset) % 5);
+
+    cod[pos1] = (fixed_index[3] & 0x100) ? -1.0 : 1.0;
+    cod[pos2] = (fixed_index[3] & 0x80 ) ? -1.0 : 1.0;
+}
+
+static void decode_3_pulses_10bits(uint16_t fixed_index, float *cod)
+{
+    float sign;
+    int pos;
+
+    sign = (fixed_index & 0x200) ? -1.0 : 1.0;
+
+    pos = ((fixed_index        & 0x7) * 7) + 4;
+    cod[pos] += sign;
+    pos = (((fixed_index >> 3) & 0x7) * 7) + 2;
+    cod[pos] -= sign;
+    pos = (((fixed_index >> 6) & 0x7) * 7);
+    cod[pos] += sign;
+}
+
+/*
+ * Reconstruction of ACELP fixed codebook excitation for full and half rate.
+ *
+ * TIA/IS-127 5.2.3.7
+ */
+static void fcb_excitation(EVRCContext *e, const uint16_t *codebook,
+                           float *excitation, float pitch_gain,
+                           int pitch_lag, int subframe_size)
+{
+    int i;
+
+    if (e->bitrate == RATE_FULL)
+        decode_8_pulses_35bits(codebook, excitation);
+    else
+        decode_3_pulses_10bits(*codebook, excitation);
+
+    pitch_gain = av_clipf(pitch_gain, 0.2, 0.9);
+
+    for (i = pitch_lag; i < subframe_size; i++)
+        excitation[i] += pitch_gain * excitation[i - pitch_lag];
+}
+
+/**
+ * Synthesis of the decoder output signal.
+ *
+ * param[in]     in              input signal
+ * param[in]     filter_coeffs   LPC coefficients
+ * param[in/out] memory          synthesis filter memory
+ * param         buffer_length   amount of data to process
+ * param[out]    samples         output samples
+ *
+ * TIA/IS-127 5.2.3.15, 5.7.3.4
+ */
+static void synthesis_filter(const float *in, const float *filter_coeffs,
+                             float *memory, int buffer_length, float *samples)
+{
+    int i, j;
+
+    for (i = 0; i < buffer_length; i++) {
+        samples[i] = in[i];
+        for (j = FILTER_ORDER - 1; j > 0; j--) {
+            samples[i] -= filter_coeffs[j] * memory[j];
+            memory[j]   = memory[j - 1];
+        }
+        samples[i] -= filter_coeffs[0] * memory[0];
+        memory[0]   = samples[i];
+    }
+}
+
+static void bandwidth_expansion(float *coeff, const float *inbuf, float gamma)
+{
+    double fac = gamma;
+    int i;
+
+    for (i = 0; i < FILTER_ORDER; i++) {
+        coeff[i] = inbuf[i] * fac;
+        fac *= gamma;
+    }
+}
+
+static void residual_filter(float *output, const float *input,
+                            const float *coef, float *memory, int length)
+{
+    float sum;
+    int i, j;
+
+    for (i = 0; i < length; i++) {
+        sum = input[i];
+
+        for (j = FILTER_ORDER - 1; j > 0; j--) {
+            sum      += coef[j] * memory[j];
+            memory[j] = memory[j - 1];
+        }
+        sum += coef[0] * memory[0];
+        memory[0] = input[i];
+        output[i] = sum;
+    }
+}
+
+/*
+ * TIA/IS-127 Table 5.9.1-1.
+ */
+static const struct PfCoeff {
+    float tilt;
+    float ltgain;
+    float p1;
+    float p2;
+} postfilter_coeffs[5] = {
+    { 0.0 , 0.0 , 0.0 , 0.0  },
+    { 0.0 , 0.0 , 0.57, 0.57 },
+    { 0.0 , 0.0 , 0.0 , 0.0  },
+    { 0.35, 0.50, 0.50, 0.75 },
+    { 0.20, 0.50, 0.57, 0.75 },
+};
+
+/*
+ * Adaptive postfilter.
+ *
+ * TIA/IS-127 5.9
+ */
+static void postfilter(EVRCContext *e, float *in, const float *coeff,
+                       float *out, int idx, const struct PfCoeff *pfc,
+                       int length)
+{
+    float wcoef1[FILTER_ORDER], wcoef2[FILTER_ORDER],
+          scratch[SUBFRAME_SIZE], temp[SUBFRAME_SIZE],
+          mem[SUBFRAME_SIZE];
+    float sum1 = 0.0, sum2 = 0.0, gamma, gain;
+    float tilt = pfc->tilt;
+    int i, n, best;
+
+    bandwidth_expansion(wcoef1, coeff, pfc->p1);
+    bandwidth_expansion(wcoef2, coeff, pfc->p2);
+
+    /* Tilt compensation filter, TIA/IS-127 5.9.1 */
+    for (i = 0; i < length - 1; i++)
+        sum2 += in[i] * in[i + 1];
+    if (sum2 < 0.0)
+        tilt = 0.0;
+
+    for (i = 0; i < length; i++) {
+        scratch[i] = in[i] - tilt * e->last;
+        e->last = in[i];
+    }
+
+    /* Short term residual filter, TIA/IS-127 5.9.2 */
+    residual_filter(&e->postfilter_residual[ACB_SIZE], scratch, wcoef1, e->postfilter_fir, length);
+
+    /* Long term postfilter */
+    best = idx;
+    for (i = FFMIN(MIN_DELAY, idx - 3); i <= FFMAX(MAX_DELAY, idx + 3); i++) {
+        for (n = ACB_SIZE, sum2 = 0; n < ACB_SIZE + length; n++)
+            sum2 += e->postfilter_residual[n] * e->postfilter_residual[n - i];
+        if (sum2 > sum1) {
+            sum1 = sum2;
+            best = i;
+        }
+    }
+
+    for (i = ACB_SIZE, sum1 = 0; i < ACB_SIZE + length; i++)
+        sum1 += e->postfilter_residual[i - best] * e->postfilter_residual[i - best];
+    for (i = ACB_SIZE, sum2 = 0; i < ACB_SIZE + length; i++)
+        sum2 += e->postfilter_residual[i] * e->postfilter_residual[i - best];
+
+    if (sum2 * sum1 == 0 || e->bitrate == RATE_QUANT) {
+        memcpy(temp, e->postfilter_residual + ACB_SIZE, length * sizeof(float));
+    } else {
+        gamma = sum2 / sum1;
+        if (gamma < 0.5)
+            memcpy(temp, e->postfilter_residual + ACB_SIZE, length * sizeof(float));
+        else {
+            gamma = FFMIN(gamma, 1.0);
+
+            for (i = 0; i < length; i++) {
+                temp[i] = e->postfilter_residual[ACB_SIZE + i] + gamma *
+                    pfc->ltgain * e->postfilter_residual[ACB_SIZE + i - best];
+            }
+        }
+    }
+
+    memcpy(scratch, temp, length * sizeof(float));
+    memcpy(mem, e->postfilter_iir, FILTER_ORDER * sizeof(float));
+    synthesis_filter(scratch, wcoef2, mem, length, scratch);
+
+    /* Gain computation, TIA/IS-127 5.9.4-2 */
+    for (i = 0, sum1 = 0, sum2 = 0; i < length; i++) {
+        sum1 += in[i] * in[i];
+        sum2 += scratch[i] * scratch[i];
+    }
+    gain = sum2 ? sqrt(sum1 / sum2) : 1.0;
+
+    for (i = 0; i < length; i++)
+        temp[i] *= gain;
+
+    /* Short term postfilter */
+    synthesis_filter(temp, wcoef2, e->postfilter_iir, length, out);
+
+    memcpy(e->postfilter_residual,
+           e->postfilter_residual + length, ACB_SIZE * sizeof(float));
+}
+
+static void frame_erasure(EVRCContext *e, float *samples)
+{
+    float ilspf[FILTER_ORDER], ilpc[FILTER_ORDER], idelay[NB_SUBFRAMES],
+          tmp[SUBFRAME_SIZE + 6], f;
+    int i, j;
+
+    for (i = 0; i < FILTER_ORDER; i++) {
+        if (e->bitrate != RATE_QUANT)
+            e->lspf[i] = e->prev_lspf[i] * 0.875 + 0.125 * (i + 1) * 0.048;
+        else
+            e->lspf[i] = e->prev_lspf[i];
+    }
+
+    if (e->prev_error_flag)
+        e->avg_acb_gain *= 0.75;
+    if (e->bitrate == RATE_FULL)
+        memcpy(e->pitch_back, e->pitch, ACB_SIZE * sizeof(float));
+    if (e->last_valid_bitrate == RATE_QUANT)
+        e->bitrate = RATE_QUANT;
+    else
+        e->bitrate = RATE_FULL;
+
+    if (e->bitrate == RATE_FULL || e->bitrate == RATE_HALF) {
+        e->pitch_delay = e->prev_pitch_delay;
+    } else {
+        float sum = 0;
+
+        idelay[0] = idelay[1] = idelay[2] = MIN_DELAY;
+
+        for (i = 0; i < NB_SUBFRAMES; i++)
+            sum += evrc_energy_quant[e->prev_energy_gain][i];
+        sum /= (float) NB_SUBFRAMES;
+        sum  = pow(10, sum);
+        for (i = 0; i < NB_SUBFRAMES; i++)
+            e->energy_vector[i] = sum;
+    }
+
+    if (fabs(e->pitch_delay - e->prev_pitch_delay) > 15)
+        e->prev_pitch_delay = e->pitch_delay;
+
+    for (i = 0; i < NB_SUBFRAMES; i++) {
+        int subframe_size = subframe_sizes[i];
+        int pitch_lag;
+
+        interpolate_lsp(ilspf, e->lspf, e->prev_lspf, i);
+
+        if (e->bitrate != RATE_QUANT) {
+            if (e->avg_acb_gain < 0.3) {
+                idelay[0] = estimation_delay[i];
+                idelay[1] = estimation_delay[i + 1];
+                idelay[2] = estimation_delay[i + 2];
+            } else {
+                interpolate_delay(idelay, e->pitch_delay, e->prev_pitch_delay, i);
+            }
+        }
+
+        pitch_lag = lrintf((idelay[1] + idelay[0]) / 2.0);
+        decode_predictor_coeffs(ilspf, ilpc);
+
+        if (e->bitrate != RATE_QUANT) {
+            acb_excitation(e, e->pitch + ACB_SIZE,
+                           e->avg_acb_gain, idelay, subframe_size);
+            for (j = 0; j < subframe_size; j++)
+                e->pitch[ACB_SIZE + j] *= e->fade_scale;
+            e->fade_scale = FFMAX(e->fade_scale - 0.05, 0.0);
+        } else {
+            for (j = 0; j < subframe_size; j++)
+                e->pitch[ACB_SIZE + j] = e->energy_vector[i];
+        }
+
+        memcpy(e->pitch, e->pitch + subframe_size, ACB_SIZE * sizeof(float));
+
+        if (e->bitrate != RATE_QUANT && e->avg_acb_gain < 0.4) {
+            f = 0.1 * e->avg_fcb_gain;
+            for (j = 0; j < subframe_size; j++)
+                e->pitch[ACB_SIZE + j] += f;
+        } else if (e->bitrate == RATE_QUANT) {
+            for (j = 0; j < subframe_size; j++)
+                e->pitch[ACB_SIZE + j] = e->energy_vector[i];
+        }
+
+        synthesis_filter(e->pitch + ACB_SIZE, ilpc,
+                         e->synthesis, subframe_size, tmp);
+        postfilter(e, tmp, ilpc, samples, pitch_lag,
+                   &postfilter_coeffs[e->bitrate], subframe_size);
+
+        samples += subframe_size;
+    }
+}
+
+static int evrc_decode_frame(AVCodecContext *avctx, void *data,
+                             int *got_frame_ptr, AVPacket *avpkt)
+{
+    const uint8_t *buf = avpkt->data;
+    AVFrame *frame     = data;
+    EVRCContext *e     = avctx->priv_data;
+    int buf_size       = avpkt->size;
+    float ilspf[FILTER_ORDER], ilpc[FILTER_ORDER], idelay[NB_SUBFRAMES];
+    float *samples;
+    int   i, j, ret, error_flag = 0;
+
+    frame->nb_samples = 160;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0)
+        return ret;
+    samples = (float *)frame->data[0];
+
+    if ((e->bitrate = determine_bitrate(avctx, &buf_size, &buf)) == RATE_ERRS) {
+        warn_insufficient_frame_quality(avctx, "bitrate cannot be determined.");
+        goto erasure;
+    }
+    if (e->bitrate <= SILENCE || e->bitrate == RATE_QUARTER)
+        goto erasure;
+    if (e->bitrate == RATE_QUANT && e->last_valid_bitrate == RATE_FULL
+                                 && !e->prev_error_flag)
+        goto erasure;
+
+    init_get_bits(&e->gb, buf, 8 * buf_size);
+    memset(&e->frame, 0, sizeof(EVRCAFrame));
+
+    unpack_frame(e);
+
+    if (e->bitrate != RATE_QUANT) {
+        uint8_t *p = (uint8_t *) &e->frame;
+        for (i = 0; i < sizeof(EVRCAFrame); i++) {
+            if (p[i])
+                break;
+        }
+        if (i == sizeof(EVRCAFrame))
+            goto erasure;
+    } else if (e->frame.lsp[0] == 0xf &&
+               e->frame.lsp[1] == 0xf &&
+               e->frame.energy_gain == 0xff) {
+        goto erasure;
+    }
+
+    if (decode_lspf(e) < 0)
+        goto erasure;
+
+    if (e->bitrate == RATE_FULL || e->bitrate == RATE_HALF) {
+        /* Pitch delay parameter checking as per TIA/IS-127 5.1.5.1 */
+        if (e->frame.pitch_delay > MAX_DELAY - MIN_DELAY)
+            goto erasure;
+
+        e->pitch_delay = e->frame.pitch_delay + MIN_DELAY;
+
+        /* Delay diff parameter checking as per TIA/IS-127 5.1.5.2 */
+        if (e->frame.delay_diff) {
+            int p = e->pitch_delay - e->frame.delay_diff + 16;
+            if (p < MIN_DELAY || p > MAX_DELAY)
+                goto erasure;
+        }
+
+        /* Delay contour reconstruction as per TIA/IS-127 5.2.2.2 */
+        if (e->frame.delay_diff &&
+            e->bitrate == RATE_FULL && e->prev_error_flag) {
+            float delay;
+
+            memcpy(e->pitch, e->pitch_back, ACB_SIZE * sizeof(float));
+
+            delay = e->prev_pitch_delay;
+            e->prev_pitch_delay = delay - e->frame.delay_diff + 16.0;
+
+            if (fabs(e->pitch_delay - delay) > 15)
+                delay = e->pitch_delay;
+
+            for (i = 0; i < NB_SUBFRAMES; i++) {
+                int subframe_size = subframe_sizes[i];
+
+                interpolate_delay(idelay, delay, e->prev_pitch_delay, i);
+                acb_excitation(e, e->pitch + ACB_SIZE, e->avg_acb_gain, idelay, subframe_size);
+                memcpy(e->pitch, e->pitch + subframe_size, ACB_SIZE * sizeof(float));
+            }
+        }
+
+        /* Smoothing of the decoded delay as per TIA/IS-127 5.2.2.5 */
+        if (fabs(e->pitch_delay - e->prev_pitch_delay) > 15)
+            e->prev_pitch_delay = e->pitch_delay;
+
+        e->avg_acb_gain = e->avg_fcb_gain = 0.0;
+    } else {
+        idelay[0] = idelay[1] = idelay[2] = MIN_DELAY;
+
+        /* Decode frame energy vectors as per TIA/IS-127 5.7.2 */
+        for (i = 0; i < NB_SUBFRAMES; i++)
+            e->energy_vector[i] = pow(10, evrc_energy_quant[e->frame.energy_gain][i]);
+        e->prev_energy_gain = e->frame.energy_gain;
+    }
+
+    for (i = 0; i < NB_SUBFRAMES; i++) {
+        float tmp[SUBFRAME_SIZE + 6] = { 0 };
+        int subframe_size = subframe_sizes[i];
+        int pitch_lag;
+
+        interpolate_lsp(ilspf, e->lspf, e->prev_lspf, i);
+
+        if (e->bitrate != RATE_QUANT)
+            interpolate_delay(idelay, e->pitch_delay, e->prev_pitch_delay, i);
+
+        pitch_lag = lrintf((idelay[1] + idelay[0]) / 2.0);
+        decode_predictor_coeffs(ilspf, ilpc);
+
+        /* Bandwidth expansion as per TIA/IS-127 5.2.3.3 */
+        if (e->frame.lpc_flag && e->prev_error_flag)
+            bandwidth_expansion(ilpc, ilpc, 0.75);
+
+        if (e->bitrate != RATE_QUANT) {
+            float acb_sum, f;
+
+            f = exp((e->bitrate == RATE_HALF ? 0.5 : 0.25)
+                         * (e->frame.fcb_gain[i] + 1));
+            acb_sum = pitch_gain_vq[e->frame.acb_gain[i]];
+            e->avg_acb_gain += acb_sum / NB_SUBFRAMES;
+            e->avg_fcb_gain += f / NB_SUBFRAMES;
+
+            acb_excitation(e, e->pitch + ACB_SIZE,
+                           acb_sum, idelay, subframe_size);
+            fcb_excitation(e, e->frame.fcb_shape[i], tmp,
+                           acb_sum, pitch_lag, subframe_size);
+
+            /* Total excitation generation as per TIA/IS-127 5.2.3.9 */
+            for (j = 0; j < subframe_size; j++)
+                e->pitch[ACB_SIZE + j] += f * tmp[j];
+            e->fade_scale = FFMIN(e->fade_scale + 0.2, 1.0);
+        } else {
+            for (j = 0; j < subframe_size; j++)
+                e->pitch[ACB_SIZE + j] = e->energy_vector[i];
+        }
+
+        memcpy(e->pitch, e->pitch + subframe_size, ACB_SIZE * sizeof(float));
+
+        synthesis_filter(e->pitch + ACB_SIZE, ilpc,
+                         e->synthesis, subframe_size, tmp);
+        postfilter(e, tmp, ilpc, samples, pitch_lag,
+                   &postfilter_coeffs[e->bitrate], subframe_size);
+
+        samples += subframe_size;
+    }
+
+    if (error_flag) {
+erasure:
+        error_flag = 1;
+        av_log(avctx, AV_LOG_WARNING, "frame erasure\n");
+        frame_erasure(e, samples);
+    }
+
+    memcpy(e->prev_lspf, e->lspf, sizeof(e->prev_lspf));
+    e->prev_error_flag    = error_flag;
+    e->last_valid_bitrate = e->bitrate;
+
+    if (e->bitrate != RATE_QUANT)
+        e->prev_pitch_delay = e->pitch_delay;
+
+    samples = (float *)frame->data[0];
+    for (i = 0; i < 160; i++)
+        samples[i] /= 32768;
+
+    *got_frame_ptr   = 1;
+
+    return avpkt->size;
+}
+
+AVCodec ff_evrc_decoder = {
+    .name           = "evrc",
+    .type           = AVMEDIA_TYPE_AUDIO,
+    .id             = AV_CODEC_ID_EVRC,
+    .init           = evrc_decode_init,
+    .decode         = evrc_decode_frame,
+    .capabilities   = CODEC_CAP_DR1,
+    .priv_data_size = sizeof(EVRCContext),
+    .long_name      = NULL_IF_CONFIG_SMALL("EVRC (Enhanced Variable Rate Codec)"),
+};
diff --git a/libavcodec/exr.c b/libavcodec/exr.c
index 6773d88..1432817 100644
--- a/libavcodec/exr.c
+++ b/libavcodec/exr.c
@@ -37,6 +37,7 @@
 #include "mathops.h"
 #include "thread.h"
 #include "libavutil/imgutils.h"
+#include "libavutil/avassert.h"
 
 enum ExrCompr {
     EXR_RAW   = 0,
@@ -44,21 +45,54 @@
     EXR_ZIP1  = 2,
     EXR_ZIP16 = 3,
     EXR_PIZ   = 4,
+    EXR_PXR24 = 5,
     EXR_B44   = 6,
     EXR_B44A  = 7,
 };
 
-typedef struct EXRContext {
-    AVFrame picture;
-    int compr;
-    int bits_per_color_id;
-    int channel_offsets[4]; // 0 = red, 1 = green, 2 = blue and 3 = alpha
+enum ExrPixelType {
+    EXR_UINT,
+    EXR_HALF,
+    EXR_FLOAT
+};
 
+typedef struct EXRChannel {
+    int               xsub, ysub;
+    enum ExrPixelType pixel_type;
+} EXRChannel;
+
+typedef struct EXRThreadData {
     uint8_t *uncompressed_data;
     int uncompressed_size;
 
     uint8_t *tmp;
     int tmp_size;
+} EXRThreadData;
+
+typedef struct EXRContext {
+    AVFrame picture;
+    int compr;
+    enum ExrPixelType pixel_type;
+    int channel_offsets[4]; // 0 = red, 1 = green, 2 = blue and 3 = alpha
+    const AVPixFmtDescriptor *desc;
+
+    uint32_t xmax, xmin;
+    uint32_t ymax, ymin;
+    uint32_t xdelta, ydelta;
+
+    int ysize;
+
+    uint64_t scan_line_size;
+    int scan_lines_per_block;
+
+    const uint8_t *buf, *table;
+    int buf_size;
+
+    EXRChannel *channels;
+    int nb_channels;
+
+    EXRThreadData *thread_data;
+    int thread_data_size;
 } EXRContext;
 
 /**
@@ -143,8 +177,6 @@
             *variable_buffer_data_size = get_header_variable_length(buf, buf_end);
             if (!*variable_buffer_data_size)
                 av_log(avctx, AV_LOG_ERROR, "Incomplete header\n");
-            if (*variable_buffer_data_size > buf_end - *buf)
-                return -1;
             return 1;
         }
         *buf -= strlen(value_name)+1;
@@ -185,10 +217,28 @@
     }
 }
 
-static int rle_uncompress(const uint8_t *src, int ssize, uint8_t *dst, int dsize)
+static int zip_uncompress(const uint8_t *src, int compressed_size,
+                          int uncompressed_size, EXRThreadData *td)
 {
-    int8_t *d = (int8_t *)dst;
-    int8_t *s = (int8_t *)src;
+    unsigned long dest_len = uncompressed_size;
+
+    if (uncompress(td->tmp, &dest_len, src, compressed_size) != Z_OK ||
+        dest_len != uncompressed_size)
+        return AVERROR(EINVAL);
+
+    predictor(td->tmp, uncompressed_size);
+    reorder_pixels(td->tmp, td->uncompressed_data, uncompressed_size);
+
+    return 0;
+}
+
+static int rle_uncompress(const uint8_t *src, int compressed_size,
+                          int uncompressed_size, EXRThreadData *td)
+{
+    int8_t *d = (int8_t *)td->tmp;
+    const int8_t *s = (const int8_t *)src;
+    int ssize = compressed_size;
+    int dsize = uncompressed_size;
     int8_t *dend = d + dsize;
     int count;
 
@@ -218,46 +268,224 @@
         }
     }
 
-    return dend != d;
+    if (dend != d)
+        return AVERROR_INVALIDDATA;
+
+    predictor(td->tmp, uncompressed_size);
+    reorder_pixels(td->tmp, td->uncompressed_data, uncompressed_size);
+
+    return 0;
+}
+
+static int pxr24_uncompress(EXRContext *s, const uint8_t *src,
+                            int compressed_size, int uncompressed_size,
+                            EXRThreadData *td)
+{
+    unsigned long dest_len = uncompressed_size;
+    const uint8_t *in = td->tmp;
+    uint8_t *out;
+    int c, i, j;
+
+    if (uncompress(td->tmp, &dest_len, src, compressed_size) != Z_OK ||
+        dest_len != uncompressed_size)
+        return AVERROR(EINVAL);
+
+    out = td->uncompressed_data;
+    for (i = 0; i < s->ysize; i++) {
+        for (c = 0; c < s->nb_channels; c++) {
+            EXRChannel *channel = &s->channels[c];
+            const uint8_t *ptr[4];
+            uint32_t pixel = 0;
+
+            switch (channel->pixel_type) {
+            case EXR_FLOAT:
+                ptr[0] = in;
+                ptr[1] = ptr[0] + s->xdelta;
+                ptr[2] = ptr[1] + s->xdelta;
+                in = ptr[2] + s->xdelta;
+
+                for (j = 0; j < s->xdelta; ++j) {
+                    uint32_t diff = (*(ptr[0]++) << 24) |
+                                    (*(ptr[1]++) << 16) |
+                                    (*(ptr[2]++) <<  8);
+                    pixel += diff;
+                    bytestream_put_le32(&out, pixel);
+                }
+                break;
+            case EXR_HALF:
+                ptr[0] = in;
+                ptr[1] = ptr[0] + s->xdelta;
+                in = ptr[1] + s->xdelta;
+                for (j = 0; j < s->xdelta; j++) {
+                    uint32_t diff = (*(ptr[0]++) << 8) | *(ptr[1]++);
+
+                    pixel += diff;
+                    bytestream_put_le16(&out, pixel);
+                }
+                break;
+            default:
+                av_assert1(0);
+            }
+        }
+    }
+
+    return 0;
+}
+
+static int decode_block(AVCodecContext *avctx, void *tdata,
+                        int jobnr, int threadnr)
+{
+    EXRContext *s = avctx->priv_data;
+    AVFrame *const p = &s->picture;
+    EXRThreadData *td = &s->thread_data[threadnr];
+    const uint8_t *channel_buffer[4] = { 0 };
+    const uint8_t *buf = s->buf;
+    uint64_t line_offset, uncompressed_size;
+    uint32_t xdelta = s->xdelta;
+    uint16_t *ptr_x;
+    uint8_t *ptr;
+    int32_t data_size, line;
+    const uint8_t *src;
+    int axmax = (avctx->width - (s->xmax + 1)) * 2 * s->desc->nb_components;
+    int bxmin = s->xmin * 2 * s->desc->nb_components;
+    int ret, i, x, buf_size = s->buf_size;
+
+    line_offset = AV_RL64(s->table + jobnr * 8);
+    // Check if the buffer has the required bytes needed from the offset
+    if (line_offset > buf_size - 8)
+        return AVERROR_INVALIDDATA;
+
+    src = buf + line_offset + 8;
+    line = AV_RL32(src - 8);
+    if (line < s->ymin || line > s->ymax)
+        return AVERROR_INVALIDDATA;
+
+    data_size = AV_RL32(src - 4);
+    if (data_size <= 0 || data_size > buf_size)
+        return AVERROR_INVALIDDATA;
+
+    s->ysize = FFMIN(s->scan_lines_per_block, s->ymax - line + 1);
+    uncompressed_size = s->scan_line_size * s->ysize;
+    if ((s->compr == EXR_RAW && (data_size != uncompressed_size ||
+                                 line_offset > buf_size - uncompressed_size)) ||
+        (s->compr != EXR_RAW && (data_size > uncompressed_size ||
+                                 line_offset > buf_size - data_size))) {
+        return AVERROR_INVALIDDATA;
+    }
+
+    if (data_size < uncompressed_size) {
+        av_fast_padded_malloc(&td->uncompressed_data, &td->uncompressed_size, uncompressed_size);
+        av_fast_padded_malloc(&td->tmp, &td->tmp_size, uncompressed_size);
+        if (!td->uncompressed_data || !td->tmp)
+            return AVERROR(ENOMEM);
+
+        switch (s->compr) {
+        case EXR_ZIP1:
+        case EXR_ZIP16:
+            ret = zip_uncompress(src, data_size, uncompressed_size, td);
+            break;
+        case EXR_PXR24:
+            ret = pxr24_uncompress(s, src, data_size, uncompressed_size, td);
+            break;
+        case EXR_RLE:
+            ret = rle_uncompress(src, data_size, uncompressed_size, td);
+        }
+
+        src = td->uncompressed_data;
+    }
+
+    channel_buffer[0] = src + xdelta * s->channel_offsets[0];
+    channel_buffer[1] = src + xdelta * s->channel_offsets[1];
+    channel_buffer[2] = src + xdelta * s->channel_offsets[2];
+    if (s->channel_offsets[3] >= 0)
+        channel_buffer[3] = src + xdelta * s->channel_offsets[3];
+
+    ptr = p->data[0] + line * p->linesize[0];
+    for (i = 0; i < s->scan_lines_per_block && line + i <= s->ymax; i++, ptr += p->linesize[0]) {
+        const uint8_t *r, *g, *b, *a;
+
+        r = channel_buffer[0];
+        g = channel_buffer[1];
+        b = channel_buffer[2];
+        if (channel_buffer[3])
+            a = channel_buffer[3];
+
+        ptr_x = (uint16_t *)ptr;
+
+        // Zero out the start if xmin is not 0
+        memset(ptr_x, 0, bxmin);
+        ptr_x += s->xmin * s->desc->nb_components;
+        if (s->pixel_type == EXR_FLOAT) {
+            // 32-bit
+            for (x = 0; x < xdelta; x++) {
+                *ptr_x++ = exr_flt2uint(bytestream_get_le32(&r));
+                *ptr_x++ = exr_flt2uint(bytestream_get_le32(&g));
+                *ptr_x++ = exr_flt2uint(bytestream_get_le32(&b));
+                if (channel_buffer[3])
+                    *ptr_x++ = exr_flt2uint(bytestream_get_le32(&a));
+            }
+        } else {
+            // 16-bit
+            for (x = 0; x < xdelta; x++) {
+                *ptr_x++ = exr_halflt2uint(bytestream_get_le16(&r));
+                *ptr_x++ = exr_halflt2uint(bytestream_get_le16(&g));
+                *ptr_x++ = exr_halflt2uint(bytestream_get_le16(&b));
+                if (channel_buffer[3])
+                    *ptr_x++ = exr_halflt2uint(bytestream_get_le16(&a));
+            }
+        }
+
+        // Zero out the end if xmax+1 is not w
+        memset(ptr_x, 0, axmax);
+
+        channel_buffer[0] += s->scan_line_size;
+        channel_buffer[1] += s->scan_line_size;
+        channel_buffer[2] += s->scan_line_size;
+        if (channel_buffer[3])
+            channel_buffer[3] += s->scan_line_size;
+    }
+
+    return 0;
 }
 
 static int decode_frame(AVCodecContext *avctx,
                         void *data,
-                        int *data_size,
+                        int *got_frame,
                         AVPacket *avpkt)
 {
     const uint8_t *buf      = avpkt->data;
     unsigned int   buf_size = avpkt->size;
     const uint8_t *buf_end  = buf + buf_size;
 
-    const AVPixFmtDescriptor *desc;
     EXRContext *const s = avctx->priv_data;
     AVFrame *picture  = data;
     AVFrame *const p = &s->picture;
     uint8_t *ptr;
 
-    int i, x, y, stride, magic_number, version_flag, ret;
+    int i, y, magic_number, version, flags, ret;
     int w = 0;
     int h = 0;
-    unsigned int xmin   = ~0;
-    unsigned int xmax   = ~0;
-    unsigned int ymin   = ~0;
-    unsigned int ymax   = ~0;
-    unsigned int xdelta = ~0;
 
     int out_line_size;
-    int bxmin, axmax;
-    int scan_lines_per_block;
-    unsigned long scan_line_size;
-    unsigned long uncompressed_size;
+    int scan_line_blocks;
 
     unsigned int current_channel_offset = 0;
 
+    s->xmin = ~0;
+    s->xmax = ~0;
+    s->ymin = ~0;
+    s->ymax = ~0;
+    s->xdelta = ~0;
+    s->ydelta = ~0;
     s->channel_offsets[0] = -1;
     s->channel_offsets[1] = -1;
     s->channel_offsets[2] = -1;
     s->channel_offsets[3] = -1;
-    s->bits_per_color_id = -1;
+    s->pixel_type = -1;
+    s->nb_channels = 0;
+    s->compr = -1;
+    s->buf = buf;
+    s->buf_size = buf_size;
 
     if (buf_size < 10) {
         av_log(avctx, AV_LOG_ERROR, "Too short header to parse\n");
@@ -270,8 +498,14 @@
         return AVERROR_INVALIDDATA;
     }
 
-    version_flag = bytestream_get_le32(&buf);
-    if ((version_flag & 0x200) == 0x200) {
+    version = bytestream_get_byte(&buf);
+    if (version != 2) {
+        av_log(avctx, AV_LOG_ERROR, "Unsupported version %d\n", version);
+        return AVERROR_PATCHWELCOME;
+    }
+
+    flags = bytestream_get_le24(&buf);
+    if (flags & 0x2) {
         av_log(avctx, AV_LOG_ERROR, "Tile based images are not supported\n");
         return AVERROR_PATCHWELCOME;
     }
@@ -287,8 +521,10 @@
 
             channel_list_end = buf + variable_buffer_data_size;
             while (channel_list_end - buf >= 19) {
-                int current_bits_per_color_id = -1;
+                EXRChannel *channel;
+                int current_pixel_type = -1;
                 int channel_index = -1;
+                int xsub, ysub;
 
                 if (!strcmp(buf, "R"))
                     channel_index = 0;
@@ -309,23 +545,38 @@
                     return AVERROR_INVALIDDATA;
                 }
 
-                current_bits_per_color_id = bytestream_get_le32(&buf);
-                if (current_bits_per_color_id > 2) {
-                    av_log(avctx, AV_LOG_ERROR, "Unknown color format\n");
+                current_pixel_type = bytestream_get_le32(&buf);
+                if (current_pixel_type > 2) {
+                    av_log(avctx, AV_LOG_ERROR, "Unknown pixel type\n");
                     return AVERROR_INVALIDDATA;
                 }
 
+                buf += 4;
+                xsub = bytestream_get_le32(&buf);
+                ysub = bytestream_get_le32(&buf);
+                if (xsub != 1 || ysub != 1) {
+                    av_log(avctx, AV_LOG_ERROR, "Unsupported subsampling %dx%d\n", xsub, ysub);
+                    return AVERROR_PATCHWELCOME;
+                }
+
                 if (channel_index >= 0) {
-                    if (s->bits_per_color_id != -1 && s->bits_per_color_id != current_bits_per_color_id) {
+                    if (s->pixel_type != -1 && s->pixel_type != current_pixel_type) {
                         av_log(avctx, AV_LOG_ERROR, "RGB channels not of the same depth\n");
                         return AVERROR_INVALIDDATA;
                     }
-                    s->bits_per_color_id  = current_bits_per_color_id;
+                    s->pixel_type = current_pixel_type;
                     s->channel_offsets[channel_index] = current_channel_offset;
                 }
 
-                current_channel_offset += 1 << current_bits_per_color_id;
-                buf += 12;
+                s->channels = av_realloc_f(s->channels, ++s->nb_channels, sizeof(EXRChannel));
+                if (!s->channels)
+                    return AVERROR(ENOMEM);
+                channel = &s->channels[s->nb_channels - 1];
+                channel->pixel_type = current_pixel_type;
+                channel->xsub = xsub;
+                channel->ysub = ysub;
+
+                current_channel_offset += 1 << current_pixel_type;
             }
 
             /* Check if all channels are set with an offset or if the channels
@@ -345,25 +596,20 @@
 
             buf = channel_list_end;
             continue;
-        }
-
-        // Process the dataWindow variable
-        if (check_header_variable(avctx, &buf, buf_end, "dataWindow", "box2i", 31, &variable_buffer_data_size) >= 0) {
+        } else if (check_header_variable(avctx, &buf, buf_end, "dataWindow", "box2i", 31, &variable_buffer_data_size) >= 0) {
             if (!variable_buffer_data_size)
                 return AVERROR_INVALIDDATA;
 
-            xmin = AV_RL32(buf);
-            ymin = AV_RL32(buf + 4);
-            xmax = AV_RL32(buf + 8);
-            ymax = AV_RL32(buf + 12);
-            xdelta = (xmax-xmin) + 1;
+            s->xmin = AV_RL32(buf);
+            s->ymin = AV_RL32(buf + 4);
+            s->xmax = AV_RL32(buf + 8);
+            s->ymax = AV_RL32(buf + 12);
+            s->xdelta = (s->xmax - s->xmin) + 1;
+            s->ydelta = (s->ymax - s->ymin) + 1;
 
             buf += variable_buffer_data_size;
             continue;
-        }
-
-        // Process the displayWindow variable
-        if (check_header_variable(avctx, &buf, buf_end, "displayWindow", "box2i", 34, &variable_buffer_data_size) >= 0) {
+        } else if (check_header_variable(avctx, &buf, buf_end, "displayWindow", "box2i", 34, &variable_buffer_data_size) >= 0) {
             if (!variable_buffer_data_size)
                 return AVERROR_INVALIDDATA;
 
@@ -372,24 +618,19 @@
 
             buf += variable_buffer_data_size;
             continue;
-        }
-
-        // Process the lineOrder variable
-        if (check_header_variable(avctx, &buf, buf_end, "lineOrder", "lineOrder", 25, &variable_buffer_data_size) >= 0) {
+        } else if (check_header_variable(avctx, &buf, buf_end, "lineOrder", "lineOrder", 25, &variable_buffer_data_size) >= 0) {
             if (!variable_buffer_data_size)
                 return AVERROR_INVALIDDATA;
 
-            if (*buf) {
-                av_log(avctx, AV_LOG_ERROR, "Doesn't support this line order : %d\n", *buf);
-                return AVERROR_PATCHWELCOME;
+            av_log(avctx, AV_LOG_DEBUG, "line order : %d\n", *buf);
+            if (*buf > 2) {
+                av_log(avctx, AV_LOG_ERROR, "Unknown line order\n");
+                return AVERROR_INVALIDDATA;
             }
 
             buf += variable_buffer_data_size;
             continue;
-        }
-
-        // Process the pixelAspectRatio variable
-        if (check_header_variable(avctx, &buf, buf_end, "pixelAspectRatio", "float", 31, &variable_buffer_data_size) >= 0) {
+        } else if (check_header_variable(avctx, &buf, buf_end, "pixelAspectRatio", "float", 31, &variable_buffer_data_size) >= 0) {
             if (!variable_buffer_data_size)
                 return AVERROR_INVALIDDATA;
 
@@ -397,10 +638,7 @@
 
             buf += variable_buffer_data_size;
             continue;
-        }
-
-        // Process the compression variable
-        if (check_header_variable(avctx, &buf, buf_end, "compression", "compression", 29, &variable_buffer_data_size) >= 0) {
+        } else if (check_header_variable(avctx, &buf, buf_end, "compression", "compression", 29, &variable_buffer_data_size) >= 0) {
             if (!variable_buffer_data_size)
                 return AVERROR_INVALIDDATA;
 
@@ -449,20 +687,19 @@
     }
     buf++;
 
-    switch (s->bits_per_color_id) {
-    case 2: // 32-bit
-    case 1: // 16-bit
+    switch (s->pixel_type) {
+    case EXR_FLOAT:
+    case EXR_HALF:
         if (s->channel_offsets[3] >= 0)
             avctx->pix_fmt = AV_PIX_FMT_RGBA64;
         else
             avctx->pix_fmt = AV_PIX_FMT_RGB48;
         break;
-    // 8-bit
-    case 0:
-        av_log_missing_feature(avctx, "8-bit OpenEXR", 1);
+    case EXR_UINT:
+        av_log_missing_feature(avctx, "32-bit unsigned int", 1);
         return AVERROR_PATCHWELCOME;
     default:
-        av_log(avctx, AV_LOG_ERROR, "Unknown color format : %d\n", s->bits_per_color_id);
+        av_log(avctx, AV_LOG_ERROR, "Missing channel list\n");
         return AVERROR_INVALIDDATA;
     }
 
@@ -470,10 +707,11 @@
     case EXR_RAW:
     case EXR_RLE:
     case EXR_ZIP1:
-        scan_lines_per_block = 1;
+        s->scan_lines_per_block = 1;
         break;
+    case EXR_PXR24:
     case EXR_ZIP16:
-        scan_lines_per_block = 16;
+        s->scan_lines_per_block = 16;
         break;
     default:
         av_log(avctx, AV_LOG_ERROR, "Compression type %d is not supported\n", s->compr);
@@ -486,7 +724,10 @@
         return AVERROR_INVALIDDATA;
 
     // Verify the xmin, xmax, ymin, ymax and xdelta before setting the actual image size
-    if (xmin > xmax || ymin > ymax || xdelta != xmax - xmin + 1 || xmax >= w || ymax >= h) {
+    if (s->xmin > s->xmax ||
+        s->ymin > s->ymax ||
+        s->xdelta != s->xmax - s->xmin + 1 ||
+        s->xmax >= w || s->ymax >= h) {
         av_log(avctx, AV_LOG_ERROR, "Wrong sizing or missing size information\n");
         return AVERROR_INVALIDDATA;
     }
@@ -495,18 +736,24 @@
         avcodec_set_dimensions(avctx, w, h);
     }
 
-    desc = av_pix_fmt_desc_get(avctx->pix_fmt);
-    bxmin = xmin * 2 * desc->nb_components;
-    axmax = (avctx->width - (xmax + 1)) * 2 * desc->nb_components;
-    out_line_size = avctx->width * 2 * desc->nb_components;
-    scan_line_size = xdelta * current_channel_offset;
-    uncompressed_size = scan_line_size * scan_lines_per_block;
+    s->desc = av_pix_fmt_desc_get(avctx->pix_fmt);
+    out_line_size = avctx->width * 2 * s->desc->nb_components;
+    s->scan_line_size = s->xdelta * current_channel_offset;
+    scan_line_blocks = (s->ydelta + s->scan_lines_per_block - 1) / s->scan_lines_per_block;
 
     if (s->compr != EXR_RAW) {
-        av_fast_padded_malloc(&s->uncompressed_data, &s->uncompressed_size, uncompressed_size);
-        av_fast_padded_malloc(&s->tmp, &s->tmp_size, uncompressed_size);
-        if (!s->uncompressed_data || !s->tmp)
+        size_t thread_data_size, prev_size;
+        EXRThreadData *m;
+
+        prev_size = s->thread_data_size;
+        if (av_size_mult(avctx->thread_count, sizeof(EXRThreadData), &thread_data_size))
+            return AVERROR(EINVAL);
+
+        m = av_fast_realloc(s->thread_data, &s->thread_data_size, thread_data_size);
+        if (!m)
             return AVERROR(ENOMEM);
+        s->thread_data = m;
+        memset(s->thread_data + prev_size, 0, s->thread_data_size - prev_size);
     }
 
     if ((ret = ff_thread_get_buffer(avctx, p)) < 0) {
@@ -514,126 +761,27 @@
         return ret;
     }
 
-    ptr    = p->data[0];
-    stride = p->linesize[0];
+    if (buf_end - buf < scan_line_blocks * 8)
+        return AVERROR_INVALIDDATA;
+    s->table = buf;
+    ptr = p->data[0];
 
     // Zero out the start if ymin is not 0
-    for (y = 0; y < ymin; y++) {
+    for (y = 0; y < s->ymin; y++) {
         memset(ptr, 0, out_line_size);
-        ptr += stride;
+        ptr += p->linesize[0];
     }
 
-    // Process the actual scan line blocks
-    for (y = ymin; y <= ymax; y += scan_lines_per_block) {
-        uint16_t *ptr_x = (uint16_t *)ptr;
-        if (buf_end - buf > 8) {
-            /* Read the lineoffset from the line offset table and add 8 bytes
-               to skip the coordinates and data size fields */
-            const uint64_t line_offset = bytestream_get_le64(&buf) + 8;
-            int32_t data_size;
-
-            // Check if the buffer has the required bytes needed from the offset
-            if ((line_offset > buf_size) ||
-                (s->compr == EXR_RAW && line_offset > avpkt->size - xdelta * current_channel_offset) ||
-                (s->compr != EXR_RAW && line_offset > buf_size - (data_size = AV_RL32(avpkt->data + line_offset - 4)))) {
-                // Line offset is probably wrong and not inside the buffer
-                av_log(avctx, AV_LOG_WARNING, "Line offset for line %d is out of reach setting it to black\n", y);
-                for (i = 0; i < scan_lines_per_block && y + i <= ymax; i++, ptr += stride) {
-                    ptr_x = (uint16_t *)ptr;
-                    memset(ptr_x, 0, out_line_size);
-                }
-            } else {
-                const uint8_t *red_channel_buffer, *green_channel_buffer, *blue_channel_buffer, *alpha_channel_buffer = 0;
-
-                if (scan_lines_per_block > 1)
-                    uncompressed_size = scan_line_size * FFMIN(scan_lines_per_block, ymax - y + 1);
-                if ((s->compr == EXR_ZIP1 || s->compr == EXR_ZIP16) && data_size < uncompressed_size) {
-                    unsigned long dest_len = uncompressed_size;
-
-                    if (uncompress(s->tmp, &dest_len, avpkt->data + line_offset, data_size) != Z_OK ||
-                        dest_len != uncompressed_size) {
-                        av_log(avctx, AV_LOG_ERROR, "error during zlib decompression\n");
-                        return AVERROR(EINVAL);
-                    }
-                } else if (s->compr == EXR_RLE && data_size < uncompressed_size) {
-                    if (rle_uncompress(avpkt->data + line_offset, data_size, s->tmp, uncompressed_size)) {
-                        av_log(avctx, AV_LOG_ERROR, "error during rle decompression\n");
-                        return AVERROR(EINVAL);
-                    }
-                }
-
-                if (s->compr != EXR_RAW && data_size < uncompressed_size) {
-                    predictor(s->tmp, uncompressed_size);
-                    reorder_pixels(s->tmp, s->uncompressed_data, uncompressed_size);
-
-                    red_channel_buffer   = s->uncompressed_data + xdelta * s->channel_offsets[0];
-                    green_channel_buffer = s->uncompressed_data + xdelta * s->channel_offsets[1];
-                    blue_channel_buffer  = s->uncompressed_data + xdelta * s->channel_offsets[2];
-                    if (s->channel_offsets[3] >= 0)
-                        alpha_channel_buffer = s->uncompressed_data + xdelta * s->channel_offsets[3];
-                } else {
-                    red_channel_buffer   = avpkt->data + line_offset + xdelta * s->channel_offsets[0];
-                    green_channel_buffer = avpkt->data + line_offset + xdelta * s->channel_offsets[1];
-                    blue_channel_buffer  = avpkt->data + line_offset + xdelta * s->channel_offsets[2];
-                    if (s->channel_offsets[3] >= 0)
-                        alpha_channel_buffer = avpkt->data + line_offset + xdelta * s->channel_offsets[3];
-                }
-
-                for (i = 0; i < scan_lines_per_block && y + i <= ymax; i++, ptr += stride) {
-                    const uint8_t *r, *g, *b, *a;
-
-                    r = red_channel_buffer;
-                    g = green_channel_buffer;
-                    b = blue_channel_buffer;
-                    if (alpha_channel_buffer)
-                        a = alpha_channel_buffer;
-
-                    ptr_x = (uint16_t *)ptr;
-
-                    // Zero out the start if xmin is not 0
-                    memset(ptr_x, 0, bxmin);
-                    ptr_x += xmin * desc->nb_components;
-                    if (s->bits_per_color_id == 2) {
-                        // 32-bit
-                        for (x = 0; x < xdelta; x++) {
-                            *ptr_x++ = exr_flt2uint(bytestream_get_le32(&r));
-                            *ptr_x++ = exr_flt2uint(bytestream_get_le32(&g));
-                            *ptr_x++ = exr_flt2uint(bytestream_get_le32(&b));
-                            if (alpha_channel_buffer)
-                                *ptr_x++ = exr_flt2uint(bytestream_get_le32(&a));
-                        }
-                    } else {
-                        // 16-bit
-                        for (x = 0; x < xdelta; x++) {
-                            *ptr_x++ = exr_halflt2uint(bytestream_get_le16(&r));
-                            *ptr_x++ = exr_halflt2uint(bytestream_get_le16(&g));
-                            *ptr_x++ = exr_halflt2uint(bytestream_get_le16(&b));
-                            if (alpha_channel_buffer)
-                                *ptr_x++ = exr_halflt2uint(bytestream_get_le16(&a));
-                        }
-                    }
-
-                    // Zero out the end if xmax+1 is not w
-                    memset(ptr_x, 0, axmax);
-
-                    red_channel_buffer   += scan_line_size;
-                    green_channel_buffer += scan_line_size;
-                    blue_channel_buffer  += scan_line_size;
-                    if (alpha_channel_buffer)
-                        alpha_channel_buffer += scan_line_size;
-                }
-            }
-        }
-    }
+    avctx->execute2(avctx, decode_block, s->thread_data, NULL, scan_line_blocks);
 
     // Zero out the end if ymax+1 is not h
-    for (y = ymax + 1; y < avctx->height; y++) {
+    for (y = s->ymax + 1; y < avctx->height; y++) {
         memset(ptr, 0, out_line_size);
-        ptr += stride;
+        ptr += p->linesize[0];
     }
 
     *picture   = s->picture;
-    *data_size = sizeof(AVPicture);
+    *got_frame = 1;
 
     return buf_size;
 }
@@ -645,20 +793,26 @@
     avcodec_get_frame_defaults(&s->picture);
     avctx->coded_frame = &s->picture;
 
-    s->compr = -1;
-
     return 0;
 }
 
 static av_cold int decode_end(AVCodecContext *avctx)
 {
     EXRContext *s = avctx->priv_data;
+    int i;
 
     if (s->picture.data[0])
         avctx->release_buffer(avctx, &s->picture);
 
-    av_freep(&s->uncompressed_data);
-    av_freep(&s->tmp);
+    for (i = 0; i < s->thread_data_size / sizeof(EXRThreadData); i++) {
+        EXRThreadData *td = &s->thread_data[i];
+        av_free(td->uncompressed_data);
+        av_free(td->tmp);
+    }
+
+    av_freep(&s->thread_data);
+    s->thread_data_size = 0;
+    av_freep(&s->channels);
 
     return 0;
 }
@@ -671,6 +825,6 @@
     .init               = decode_init,
     .close              = decode_end,
     .decode             = decode_frame,
-    .capabilities       = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
+    .capabilities       = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS | CODEC_CAP_SLICE_THREADS,
     .long_name          = NULL_IF_CONFIG_SMALL("OpenEXR image"),
 };
diff --git a/libavcodec/faandct.c b/libavcodec/faandct.c
index 1379394..b1d7a14 100644
--- a/libavcodec/faandct.c
+++ b/libavcodec/faandct.c
@@ -25,7 +25,6 @@
  * @author Michael Niedermayer <michaelni@gmx.at>
  */
 
-#include "dsputil.h"
 #include "faandct.h"
 #include "libavutil/internal.h"
 #include "libavutil/libm.h"
@@ -64,7 +63,7 @@
 B7*B0, B7*B1, B7*B2, B7*B3, B7*B4, B7*B5, B7*B6, B7*B7,
 };
 
-static av_always_inline void row_fdct(FLOAT temp[64], DCTELEM * data)
+static av_always_inline void row_fdct(FLOAT temp[64], int16_t *data)
 {
     FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
     FLOAT tmp10, tmp11, tmp12, tmp13;
@@ -119,7 +118,7 @@
     }
 }
 
-void ff_faandct(DCTELEM * data)
+void ff_faandct(int16_t *data)
 {
     FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
     FLOAT tmp10, tmp11, tmp12, tmp13;
@@ -179,7 +178,7 @@
     }
 }
 
-void ff_faandct248(DCTELEM * data)
+void ff_faandct248(int16_t *data)
 {
     FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
     FLOAT tmp10, tmp11, tmp12, tmp13;
diff --git a/libavcodec/faandct.h b/libavcodec/faandct.h
index a12dcaf..c5ef96d 100644
--- a/libavcodec/faandct.h
+++ b/libavcodec/faandct.h
@@ -29,9 +29,9 @@
 #ifndef AVCODEC_FAANDCT_H
 #define AVCODEC_FAANDCT_H
 
-#include "dsputil.h"
+#include <stdint.h>
 
-void ff_faandct(DCTELEM * data);
-void ff_faandct248(DCTELEM * data);
+void ff_faandct(int16_t *data);
+void ff_faandct248(int16_t *data);
 
 #endif /* AVCODEC_FAANDCT_H */
diff --git a/libavcodec/faanidct.c b/libavcodec/faanidct.c
index 1e9bfaf..5f34fa5 100644
--- a/libavcodec/faanidct.c
+++ b/libavcodec/faanidct.c
@@ -47,7 +47,7 @@
 B7*B0/8, B7*B1/8, B7*B2/8, B7*B3/8, B7*B4/8, B7*B5/8, B7*B6/8, B7*B7/8,
 };
 
-static inline void p8idct(DCTELEM data[64], FLOAT temp[64], uint8_t *dest, int stride, int x, int y, int type){
+static inline void p8idct(int16_t data[64], FLOAT temp[64], uint8_t *dest, int stride, int x, int y, int type){
     int i;
     FLOAT av_unused tmp0;
     FLOAT s04, d04, s17, d17, s26, d26, s53, d53;
@@ -129,7 +129,7 @@
     }
 }
 
-void ff_faanidct(DCTELEM block[64]){
+void ff_faanidct(int16_t block[64]){
     FLOAT temp[64];
     int i;
 
@@ -142,7 +142,7 @@
     p8idct(block, temp, NULL, 0, 8, 1, 1);
 }
 
-void ff_faanidct_add(uint8_t *dest, int line_size, DCTELEM block[64]){
+void ff_faanidct_add(uint8_t *dest, int line_size, int16_t block[64]){
     FLOAT temp[64];
     int i;
 
@@ -155,7 +155,7 @@
     p8idct(NULL , temp, dest, line_size, 8, 1, 2);
 }
 
-void ff_faanidct_put(uint8_t *dest, int line_size, DCTELEM block[64]){
+void ff_faanidct_put(uint8_t *dest, int line_size, int16_t block[64]){
     FLOAT temp[64];
     int i;
 
diff --git a/libavcodec/faanidct.h b/libavcodec/faanidct.h
index 4cf1189..4cd2c78 100644
--- a/libavcodec/faanidct.h
+++ b/libavcodec/faanidct.h
@@ -23,10 +23,9 @@
 #define AVCODEC_FAANIDCT_H
 
 #include <stdint.h>
-#include "dsputil.h"
 
-void ff_faanidct(DCTELEM block[64]);
-void ff_faanidct_add(uint8_t *dest, int line_size, DCTELEM block[64]);
-void ff_faanidct_put(uint8_t *dest, int line_size, DCTELEM block[64]);
+void ff_faanidct(int16_t block[64]);
+void ff_faanidct_add(uint8_t *dest, int line_size, int16_t block[64]);
+void ff_faanidct_put(uint8_t *dest, int line_size, int16_t block[64]);
 
 #endif /* AVCODEC_FAANIDCT_H */
diff --git a/libavcodec/faxcompr.c b/libavcodec/faxcompr.c
index e7f9d00..86be977 100644
--- a/libavcodec/faxcompr.c
+++ b/libavcodec/faxcompr.c
@@ -163,8 +163,6 @@
     int run_off = *ref++;
     unsigned int offs=0, run= 0;
 
-    runend--; // for the last written 0
-
     while(offs < width){
         int cmode = get_vlc2(gb, ccitt_group3_2d_vlc.table, 9, 1);
         if(cmode == -1){
@@ -172,10 +170,12 @@
             return -1;
         }
         if(!cmode){//pass mode
-            run_off += *ref++;
+            if(run_off < width)
+                run_off += *ref++;
             run = run_off - offs;
             offs= run_off;
-            run_off += *ref++;
+            if(run_off < width)
+                run_off += *ref++;
             if(offs > width){
                 av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n");
                 return -1;
@@ -234,7 +234,13 @@
         }
     }
     *runs++ = saved_run;
-    *runs++ = 0;
+    if (saved_run) {
+        if(runs >= runend){
+            av_log(avctx, AV_LOG_ERROR, "Run overrun\n");
+            return -1;
+        }
+        *runs++ = 0;
+    }
     return 0;
 }
 
diff --git a/libavcodec/fft-internal.h b/libavcodec/fft-internal.h
index 61066bb..d66731f 100644
--- a/libavcodec/fft-internal.h
+++ b/libavcodec/fft-internal.h
@@ -36,7 +36,7 @@
 
 #else
 
-#include "libavutil/intmath.h"
+#include "fft.h"
 #include "mathops.h"
 
 void ff_mdct_calcw_c(FFTContext *s, FFTDouble *output, const FFTSample *input);
diff --git a/libavcodec/ffv1.c b/libavcodec/ffv1.c
index 074be4c..c75f2aa 100644
--- a/libavcodec/ffv1.c
+++ b/libavcodec/ffv1.c
@@ -33,7 +33,6 @@
 #include "libavutil/timer.h"
 #include "avcodec.h"
 #include "internal.h"
-#include "dsputil.h"
 #include "rangecoder.h"
 #include "golomb.h"
 #include "mathops.h"
@@ -123,6 +122,10 @@
         int sxe         = f->avctx->width  * (sx + 1) / f->num_h_slices;
         int sys         = f->avctx->height *  sy      / f->num_v_slices;
         int sye         = f->avctx->height * (sy + 1) / f->num_v_slices;
+
+        if (!fs)
+            return AVERROR(ENOMEM);
+
         f->slice_context[i] = fs;
         memcpy(fs, f, sizeof(*fs));
         memset(fs->rc_stat2, 0, sizeof(fs->rc_stat2));
diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c
index da44b94..cb72203 100644
--- a/libavcodec/ffv1dec.c
+++ b/libavcodec/ffv1dec.c
@@ -35,7 +35,6 @@
 #include "internal.h"
 #include "get_bits.h"
 #include "put_bits.h"
-#include "dsputil.h"
 #include "rangecoder.h"
 #include "golomb.h"
 #include "mathops.h"
@@ -727,7 +726,7 @@
     return 0;
 }
 
-static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt)
+static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
 {
     const uint8_t *buf  = avpkt->data;
     int buf_size        = avpkt->size;
@@ -757,14 +756,14 @@
     } else {
         if (!f->key_frame_ok) {
             av_log(avctx, AV_LOG_ERROR,
-                   "Cant decode non keyframe without valid keyframe\n");
+                   "Cannot decode non-keyframe without valid keyframe\n");
             return AVERROR_INVALIDDATA;
         }
         p->key_frame = 0;
     }
 
     p->reference = 3; //for error concealment
-    if ((ret = avctx->get_buffer(avctx, p)) < 0) {
+    if ((ret = ff_get_buffer(avctx, p)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -843,7 +842,7 @@
     f->picture_number++;
 
     *picture   = *p;
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
 
     FFSWAP(AVFrame, f->picture, f->last_picture);
 
diff --git a/libavcodec/ffv1enc.c b/libavcodec/ffv1enc.c
index b3879fc..70fcd65 100644
--- a/libavcodec/ffv1enc.c
+++ b/libavcodec/ffv1enc.c
@@ -33,8 +33,7 @@
 #include "libavutil/timer.h"
 #include "avcodec.h"
 #include "internal.h"
-#include "get_bits.h"
-#include "dsputil.h"
+#include "put_bits.h"
 #include "rangecoder.h"
 #include "golomb.h"
 #include "mathops.h"
@@ -395,8 +394,8 @@
     int x, y, p, i;
     const int ring_size = s->avctx->context_model ? 3 : 2;
     int16_t *sample[4][3];
-    int lbd    = s->avctx->bits_per_raw_sample <= 8;
-    int bits   = s->avctx->bits_per_raw_sample > 0 ? s->avctx->bits_per_raw_sample : 8;
+    int lbd    = s->bits_per_raw_sample <= 8;
+    int bits   = s->bits_per_raw_sample > 0 ? s->bits_per_raw_sample : 8;
     int offset = 1 << bits;
 
     s->run_index = 0;
@@ -856,23 +855,35 @@
         find_best_state(best_state, s->state_transition);
 
         for (i = 0; i < s->quant_table_count; i++) {
-            for (j = 0; j < s->context_count[i]; j++)
-                for (k = 0; k < 32; k++) {
+            for (k = 0; k < 32; k++) {
+                double a=0, b=0;
+                int jp = 0;
+                for (j = 0; j < s->context_count[i]; j++) {
                     double p = 128;
-                    if (s->rc_stat2[i][j][k][0] + s->rc_stat2[i][j][k][1]) {
-                        p = 256.0 * s->rc_stat2[i][j][k][1] /
-                            (s->rc_stat2[i][j][k][0] + s->rc_stat2[i][j][k][1]);
+                    if (s->rc_stat2[i][j][k][0] + s->rc_stat2[i][j][k][1] > 200 && j || a+b > 200) {
+                        if (a+b)
+                            p = 256.0 * b / (a + b);
+                        s->initial_states[i][jp][k] =
+                            best_state[av_clip(round(p), 1, 255)][av_clip((a + b) / gob_count, 0, 255)];
+                        for(jp++; jp<j; jp++)
+                            s->initial_states[i][jp][k] = s->initial_states[i][jp-1][k];
+                        a=b=0;
+                    }
+                    a += s->rc_stat2[i][j][k][0];
+                    b += s->rc_stat2[i][j][k][1];
+                    if (a+b) {
+                        p = 256.0 * b / (a + b);
                     }
                     s->initial_states[i][j][k] =
-                        best_state[av_clip(round(p), 1, 255)][av_clip((s->rc_stat2[i][j][k][0] +
-                                                                       s->rc_stat2[i][j][k][1]) /
-                                                                      gob_count, 0, 255)];
+                        best_state[av_clip(round(p), 1, 255)][av_clip((a + b) / gob_count, 0, 255)];
                 }
+            }
         }
     }
 
     if (s->version > 1) {
-        for (s->num_v_slices = 2; s->num_v_slices < 9; s->num_v_slices++) {
+        s->num_v_slices = (avctx->width > 352 || avctx->height > 288 || !avctx->slices) ? 2 : 1;
+        for (; s->num_v_slices < 9; s->num_v_slices++) {
             for (s->num_h_slices = s->num_v_slices; s->num_h_slices < 2*s->num_v_slices; s->num_h_slices++) {
                 if (avctx->slices == s->num_h_slices * s->num_v_slices && avctx->slices <= 64 || !avctx->slices)
                     goto slices_ok;
@@ -895,6 +906,8 @@
 #define STATS_OUT_SIZE 1024 * 1024 * 6
     if (avctx->flags & CODEC_FLAG_PASS1) {
         avctx->stats_out = av_mallocz(STATS_OUT_SIZE);
+        if (!avctx->stats_out)
+            return AVERROR(ENOMEM);
         for (i = 0; i < s->quant_table_count; i++)
             for (j = 0; j < s->slice_count; j++) {
                 FFV1Context *sf = s->slice_context[j];
diff --git a/libavcodec/ffwavesynth.c b/libavcodec/ffwavesynth.c
index c63b90f..eb3b455 100644
--- a/libavcodec/ffwavesynth.c
+++ b/libavcodec/ffwavesynth.c
@@ -22,6 +22,8 @@
 #include "libavutil/intreadwrite.h"
 #include "libavutil/log.h"
 #include "avcodec.h"
+#include "internal.h"
+
 
 #define SIN_BITS 14
 #define WS_MAX_CHANNELS 32
@@ -442,7 +444,7 @@
     if (duration <= 0)
         return AVERROR(EINVAL);
     ws->frame.nb_samples = duration;
-    r = avc->get_buffer(avc, &ws->frame);
+    r = ff_get_buffer(avc, &ws->frame);
     if (r < 0)
         return r;
     pcm = (int16_t *)ws->frame.data[0];
diff --git a/libavcodec/flac.c b/libavcodec/flac.c
index 3b803fe..a79a809 100644
--- a/libavcodec/flac.c
+++ b/libavcodec/flac.c
@@ -29,13 +29,15 @@
 
 static const int8_t sample_size_table[] = { 0, 8, 12, 0, 16, 20, 24, 0 };
 
-static const int64_t flac_channel_layouts[6] = {
+static const uint64_t flac_channel_layouts[8] = {
     AV_CH_LAYOUT_MONO,
     AV_CH_LAYOUT_STEREO,
     AV_CH_LAYOUT_SURROUND,
     AV_CH_LAYOUT_QUAD,
     AV_CH_LAYOUT_5POINT0,
-    AV_CH_LAYOUT_5POINT1
+    AV_CH_LAYOUT_5POINT1,
+    AV_CH_LAYOUT_6POINT1,
+    AV_CH_LAYOUT_7POINT1
 };
 
 static int64_t get_utf8(GetBitContext *gb)
@@ -225,7 +227,7 @@
     avctx->bits_per_raw_sample = s->bps;
     ff_flac_set_channel_layout(avctx);
 
-    s->samples = get_bits_longlong(&gb, 36);
+    s->samples = get_bits64(&gb, 36);
 
     skip_bits_long(&gb, 64); /* md5 sum */
     skip_bits_long(&gb, 64); /* md5 sum */
diff --git a/libavcodec/flac_parser.c b/libavcodec/flac_parser.c
index 7d3c5c4..e2c6744 100644
--- a/libavcodec/flac_parser.c
+++ b/libavcodec/flac_parser.c
@@ -457,9 +457,12 @@
         check_header_mismatch(fpc, header, child, 0);
     }
 
+    if (header->fi.channels != fpc->avctx->channels ||
+        !fpc->avctx->channel_layout) {
+        fpc->avctx->channels = header->fi.channels;
+        ff_flac_set_channel_layout(fpc->avctx);
+    }
     fpc->avctx->sample_rate = header->fi.samplerate;
-    fpc->avctx->channels    = header->fi.channels;
-    ff_flac_set_channel_layout(fpc->avctx);
     fpc->pc->duration       = header->fi.blocksize;
     *poutbuf = flac_fifo_read_wrap(fpc, header->offset, *poutbuf_size,
                                         &fpc->wrap_buf,
diff --git a/libavcodec/flacdec.c b/libavcodec/flacdec.c
index 317d7fa..f264d20 100644
--- a/libavcodec/flacdec.c
+++ b/libavcodec/flacdec.c
@@ -49,7 +49,6 @@
     FLACSTREAMINFO
 
     AVCodecContext *avctx;                  ///< parent AVCodecContext
-    AVFrame frame;
     GetBitContext gb;                       ///< GetBitContext initialized to start at the current frame
 
     int blocksize;                          ///< number of samples in the current frame
@@ -113,9 +112,6 @@
     ff_flacdsp_init(&s->dsp, avctx->sample_fmt, s->bps);
     s->got_streaminfo = 1;
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     return 0;
 }
 
@@ -254,7 +250,7 @@
                                  int pred_order, int bps)
 {
     const int blocksize = s->blocksize;
-    int a, b, c, d, i;
+    int av_uninit(a), av_uninit(b), av_uninit(c), av_uninit(d), i;
 
     /* warm up samples */
     for (i = 0; i < pred_order; i++) {
@@ -424,7 +420,8 @@
             return ret;
     }
     s->channels = s->avctx->channels = fi.channels;
-    ff_flac_set_channel_layout(s->avctx);
+    if (!s->avctx->channel_layout)
+        ff_flac_set_channel_layout(s->avctx);
     s->ch_mode = fi.ch_mode;
 
     if (!s->bps && !fi.bps) {
@@ -490,6 +487,7 @@
 static int flac_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;
     FLACContext *s = avctx->priv_data;
@@ -504,6 +502,16 @@
                                        FLAC_MAX_CHANNELS, 32);
     }
 
+    if (buf_size > 5 && !memcmp(buf, "\177FLAC", 5)) {
+        av_log(s->avctx, AV_LOG_DEBUG, "skiping flac header packet 1\n");
+        return buf_size;
+    }
+
+    if (buf_size > 0 && (*buf & 0x7F) == FLAC_METADATA_TYPE_VORBIS_COMMENT) {
+        av_log(s->avctx, AV_LOG_DEBUG, "skiping vorbis comment\n");
+        return buf_size;
+    }
+
     /* check that there is at least the smallest decodable amount of data.
        this amount corresponds to the smallest valid FLAC frame possible.
        FF F8 69 02 00 00 9A 00 00 34 46 */
@@ -528,13 +536,13 @@
     bytes_read = (get_bits_count(&s->gb)+7)/8;
 
     /* get output buffer */
-    s->frame.nb_samples = s->blocksize;
-    if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = s->blocksize;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
 
-    s->dsp.decorrelate[s->ch_mode](s->frame.data, s->decoded, s->channels,
+    s->dsp.decorrelate[s->ch_mode](frame->data, s->decoded, s->channels,
                                    s->blocksize, s->sample_shift);
 
     if (bytes_read > buf_size) {
@@ -546,8 +554,7 @@
                buf_size - bytes_read, buf_size);
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
+    *got_frame_ptr = 1;
 
     return bytes_read;
 }
diff --git a/libavcodec/flacenc.c b/libavcodec/flacenc.c
index a3c4e64..bbdeaad2 100644
--- a/libavcodec/flacenc.c
+++ b/libavcodec/flacenc.c
@@ -26,7 +26,7 @@
 #include "libavutil/opt.h"
 #include "avcodec.h"
 #include "dsputil.h"
-#include "get_bits.h"
+#include "put_bits.h"
 #include "golomb.h"
 #include "internal.h"
 #include "lpc.h"
@@ -248,8 +248,11 @@
         break;
     }
 
-    if (channels < 1 || channels > FLAC_MAX_CHANNELS)
-        return -1;
+    if (channels < 1 || channels > FLAC_MAX_CHANNELS) {
+        av_log(avctx, AV_LOG_ERROR, "%d channels not supported (max %d)\n",
+               channels, FLAC_MAX_CHANNELS);
+        return AVERROR(EINVAL);
+    }
     s->channels = channels;
 
     /* find samplerate in table */
@@ -275,7 +278,8 @@
             s->sr_code[0] = 13;
             s->sr_code[1] = freq;
         } else {
-            return -1;
+            av_log(avctx, AV_LOG_ERROR, "%d Hz not supported\n", freq);
+            return AVERROR(EINVAL);
         }
         s->samplerate = freq;
     }
@@ -290,7 +294,7 @@
     if (level > 12) {
         av_log(avctx, AV_LOG_ERROR, "invalid compression level: %d\n",
                s->options.compression_level);
-        return -1;
+        return AVERROR(EINVAL);
     }
 
     s->options.block_time_ms = ((int[]){ 27, 27, 27,105,105,105,105,105,105,105,105,105,105})[level];
@@ -329,13 +333,13 @@
             if (avctx->min_prediction_order > MAX_FIXED_ORDER) {
                 av_log(avctx, AV_LOG_ERROR, "invalid min prediction order: %d\n",
                        avctx->min_prediction_order);
-                return -1;
+                return AVERROR(EINVAL);
             }
         } else if (avctx->min_prediction_order < MIN_LPC_ORDER ||
                    avctx->min_prediction_order > MAX_LPC_ORDER) {
             av_log(avctx, AV_LOG_ERROR, "invalid min prediction order: %d\n",
                    avctx->min_prediction_order);
-            return -1;
+            return AVERROR(EINVAL);
         }
         s->options.min_prediction_order = avctx->min_prediction_order;
     }
@@ -346,20 +350,20 @@
             if (avctx->max_prediction_order > MAX_FIXED_ORDER) {
                 av_log(avctx, AV_LOG_ERROR, "invalid max prediction order: %d\n",
                        avctx->max_prediction_order);
-                return -1;
+                return AVERROR(EINVAL);
             }
         } else if (avctx->max_prediction_order < MIN_LPC_ORDER ||
                    avctx->max_prediction_order > MAX_LPC_ORDER) {
             av_log(avctx, AV_LOG_ERROR, "invalid max prediction order: %d\n",
                    avctx->max_prediction_order);
-            return -1;
+            return AVERROR(EINVAL);
         }
         s->options.max_prediction_order = avctx->max_prediction_order;
     }
     if (s->options.max_prediction_order < s->options.min_prediction_order) {
         av_log(avctx, AV_LOG_ERROR, "invalid prediction orders: min=%d max=%d\n",
                s->options.min_prediction_order, s->options.max_prediction_order);
-        return -1;
+        return AVERROR(EINVAL);
     }
 
     if (avctx->frame_size > 0) {
@@ -367,7 +371,7 @@
                 avctx->frame_size > FLAC_MAX_BLOCKSIZE) {
             av_log(avctx, AV_LOG_ERROR, "invalid block size: %d\n",
                    avctx->frame_size);
-            return -1;
+            return AVERROR(EINVAL);
         }
     } else {
         s->avctx->frame_size = select_blocksize(s->samplerate, s->options.block_time_ms);
@@ -1320,7 +1324,7 @@
 { "fixed",    NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_LPC_TYPE_FIXED },    INT_MIN, INT_MAX, FLAGS, "lpc_type" },
 { "levinson", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_LPC_TYPE_LEVINSON }, INT_MIN, INT_MAX, FLAGS, "lpc_type" },
 { "cholesky", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_LPC_TYPE_CHOLESKY }, INT_MIN, INT_MAX, FLAGS, "lpc_type" },
-{ "lpc_passes", "Number of passes to use for Cholesky factorization during LPC analysis", offsetof(FlacEncodeContext, options.lpc_passes),  AV_OPT_TYPE_INT, {.i64 = -1 }, INT_MIN, INT_MAX, FLAGS },
+{ "lpc_passes", "Number of passes to use for Cholesky factorization during LPC analysis", offsetof(FlacEncodeContext, options.lpc_passes),  AV_OPT_TYPE_INT, {.i64 = 2 }, 1, INT_MAX, FLAGS },
 { "min_partition_order",  NULL, offsetof(FlacEncodeContext, options.min_partition_order),  AV_OPT_TYPE_INT, {.i64 = -1 },      -1, MAX_PARTITION_ORDER, FLAGS },
 { "max_partition_order",  NULL, offsetof(FlacEncodeContext, options.max_partition_order),  AV_OPT_TYPE_INT, {.i64 = -1 },      -1, MAX_PARTITION_ORDER, FLAGS },
 { "prediction_order_method", "Search method for selecting prediction order", offsetof(FlacEncodeContext, options.prediction_order_method), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, ORDER_METHOD_LOG, FLAGS, "predm" },
diff --git a/libavcodec/flashsv.c b/libavcodec/flashsv.c
index 533e9f0..21464ed 100644
--- a/libavcodec/flashsv.c
+++ b/libavcodec/flashsv.c
@@ -126,6 +126,9 @@
     z_stream zs;
     int zret; // Zlib return code
 
+    if (!src)
+        return AVERROR_INVALIDDATA;
+
     zs.zalloc = NULL;
     zs.zfree  = NULL;
     zs.opaque = NULL;
@@ -236,12 +239,14 @@
 }
 
 static int flashsv_decode_frame(AVCodecContext *avctx, void *data,
-                                int *data_size, AVPacket *avpkt)
+                                int *got_frame, AVPacket *avpkt)
 {
     int buf_size       = avpkt->size;
     FlashSVContext *s  = avctx->priv_data;
     int h_blocks, v_blocks, h_part, v_part, i, j;
     GetBitContext gb;
+    int last_blockwidth = s->block_width;
+    int last_blockheight= s->block_height;
 
     /* no supplementary picture */
     if (buf_size == 0)
@@ -257,6 +262,10 @@
     s->block_height = 16 * (get_bits(&gb,  4) + 1);
     s->image_height =       get_bits(&gb, 12);
 
+    if (   last_blockwidth != s->block_width
+        || last_blockheight!= s->block_height)
+        av_freep(&s->blocks);
+
     if (s->ver == 2) {
         skip_bits(&gb, 6);
         if (get_bits1(&gb)) {
@@ -320,9 +329,8 @@
         s->keyframedata = av_realloc(s->keyframedata, avpkt->size);
         memcpy(s->keyframedata, avpkt->data, avpkt->size);
     }
-    if(s->ver == 2)
-        s->blocks = av_realloc(s->blocks,
-                                (v_blocks + !!v_part) * (h_blocks + !!h_part)
+    if(s->ver == 2 && !s->blocks)
+        s->blocks = av_mallocz((v_blocks + !!v_part) * (h_blocks + !!h_part)
                                 * sizeof(s->blocks[0]));
 
     av_dlog(avctx, "image: %dx%d block: %dx%d num: %dx%d part: %dx%d\n",
@@ -443,7 +451,7 @@
         memcpy(s->keyframe, s->frame.data[0], s->frame.linesize[0] * avctx->height);
     }
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*)data = s->frame;
 
     if ((get_bits_count(&gb) / 8) != buf_size)
diff --git a/libavcodec/flicvideo.c b/libavcodec/flicvideo.c
index 7bba299..2f8cd33 100644
--- a/libavcodec/flicvideo.c
+++ b/libavcodec/flicvideo.c
@@ -148,7 +148,7 @@
 }
 
 static int flic_decode_frame_8BPP(AVCodecContext *avctx,
-                                  void *data, int *data_size,
+                                  void *data, int *got_frame,
                                   const uint8_t *buf, int buf_size)
 {
     FlicDecodeContext *s = avctx->priv_data;
@@ -387,6 +387,11 @@
                     if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
                         break;
                     byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
+                    if (!byte_run) {
+                        av_log(avctx, AV_LOG_ERROR, "Invalid byte run value.\n");
+                        return AVERROR_INVALIDDATA;
+                    }
+
                     if (byte_run > 0) {
                         palette_idx1 = bytestream2_get_byte(&g2);
                         CHECK_PIXEL_PTR(byte_run);
@@ -461,14 +466,14 @@
         s->new_palette = 0;
     }
 
-    *data_size=sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*)data = s->frame;
 
     return buf_size;
 }
 
 static int flic_decode_frame_15_16BPP(AVCodecContext *avctx,
-                                      void *data, int *data_size,
+                                      void *data, int *got_frame,
                                       const uint8_t *buf, int buf_size)
 {
     /* Note, the only difference between the 15Bpp and 16Bpp */
@@ -644,7 +649,7 @@
                 }
 
                 /* Now FLX is strange, in that it is "byte" as opposed to "pixel" run length compressed.
-                 * This does not give us any good oportunity to perform word endian conversion
+                 * This does not give us any good opportunity to perform word endian conversion
                  * during decompression. So if it is required (i.e., this is not a LE target, we do
                  * a second pass over the line here, swapping the bytes.
                  */
@@ -748,14 +753,14 @@
                "and final chunk ptr = %d\n", buf_size, bytestream2_tell(&g2));
 
 
-    *data_size=sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*)data = s->frame;
 
     return buf_size;
 }
 
 static int flic_decode_frame_24BPP(AVCodecContext *avctx,
-                                   void *data, int *data_size,
+                                   void *data, int *got_frame,
                                    const uint8_t *buf, int buf_size)
 {
   av_log(avctx, AV_LOG_ERROR, "24Bpp FLC Unsupported due to lack of test files.\n");
@@ -763,22 +768,22 @@
 }
 
 static int flic_decode_frame(AVCodecContext *avctx,
-                             void *data, int *data_size,
+                             void *data, int *got_frame,
                              AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
-      return flic_decode_frame_8BPP(avctx, data, data_size,
+      return flic_decode_frame_8BPP(avctx, data, got_frame,
                                     buf, buf_size);
     }
     else if ((avctx->pix_fmt == AV_PIX_FMT_RGB555) ||
              (avctx->pix_fmt == AV_PIX_FMT_RGB565)) {
-      return flic_decode_frame_15_16BPP(avctx, data, data_size,
+      return flic_decode_frame_15_16BPP(avctx, data, got_frame,
                                         buf, buf_size);
     }
     else if (avctx->pix_fmt == AV_PIX_FMT_BGR24) {
-      return flic_decode_frame_24BPP(avctx, data, data_size,
+      return flic_decode_frame_24BPP(avctx, data, got_frame,
                                      buf, buf_size);
     }
 
@@ -787,7 +792,7 @@
     /* the finite set of possibilites allowable by here. */
     /* But in case we do, just error out. */
     av_log(avctx, AV_LOG_ERROR, "Unknown FLC format, my science cannot explain how this happened.\n");
-    return AVERROR_INVALIDDATA;
+    return AVERROR_BUG;
 }
 
 
diff --git a/libavcodec/flvdec.c b/libavcodec/flvdec.c
index 774fde7..bb693d7 100644
--- a/libavcodec/flvdec.c
+++ b/libavcodec/flvdec.c
@@ -89,8 +89,8 @@
     s->height = height;
 
     s->pict_type = AV_PICTURE_TYPE_I + get_bits(&s->gb, 2);
-    s->dropable= s->pict_type > AV_PICTURE_TYPE_P;
-    if (s->dropable)
+    s->droppable = s->pict_type > AV_PICTURE_TYPE_P;
+    if (s->droppable)
         s->pict_type = AV_PICTURE_TYPE_P;
 
     skip_bits1(&s->gb); /* deblocking flag */
@@ -109,7 +109,8 @@
 
     if(s->avctx->debug & FF_DEBUG_PICT_INFO){
         av_log(s->avctx, AV_LOG_DEBUG, "%c esc_type:%d, qp:%d num:%d\n",
-               s->dropable ? 'D' : av_get_picture_type_char(s->pict_type), s->h263_flv-1, s->qscale, s->picture_number);
+               s->droppable ? 'D' : av_get_picture_type_char(s->pict_type),
+               s->h263_flv - 1, s->qscale, s->picture_number);
     }
 
     s->y_dc_scale_table=
diff --git a/libavcodec/fmtconvert.h b/libavcodec/fmtconvert.h
index ab2caa2..3fb9f4e 100644
--- a/libavcodec/fmtconvert.h
+++ b/libavcodec/fmtconvert.h
@@ -87,7 +87,7 @@
 void ff_float_interleave_c(float *dst, const float **src, unsigned int len,
                            int channels);
 
-av_cold void ff_fmt_convert_init(FmtConvertContext *c, AVCodecContext *avctx);
+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);
diff --git a/libavcodec/frame_thread_encoder.c b/libavcodec/frame_thread_encoder.c
index ab095dc..0ac018b 100644
--- a/libavcodec/frame_thread_encoder.c
+++ b/libavcodec/frame_thread_encoder.c
@@ -226,7 +226,7 @@
             if(!new)
                 return AVERROR(ENOMEM);
             pthread_mutex_lock(&c->buffer_mutex);
-            ret = c->parent_avctx->get_buffer(c->parent_avctx, new);
+            ret = ff_get_buffer(c->parent_avctx, new);
             pthread_mutex_unlock(&c->buffer_mutex);
             if(ret<0)
                 return ret;
diff --git a/libavcodec/fraps.c b/libavcodec/fraps.c
index b624e4b..5e2ba90 100644
--- a/libavcodec/fraps.c
+++ b/libavcodec/fraps.c
@@ -43,7 +43,7 @@
 /**
  * local variable storage
  */
-typedef struct FrapsContext{
+typedef struct FrapsContext {
     AVCodecContext *avctx;
     AVFrame frame;
     uint8_t *tmpbuf;
@@ -64,7 +64,7 @@
     avcodec_get_frame_defaults(&s->frame);
     avctx->coded_frame = &s->frame;
 
-    s->avctx = avctx;
+    s->avctx  = avctx;
     s->tmpbuf = NULL;
 
     ff_dsputil_init(&s->dsp, avctx);
@@ -76,7 +76,8 @@
  * Comparator - our nodes should ascend by count
  * but with preserved symbol order
  */
-static int huff_cmp(const void *va, const void *vb){
+static int huff_cmp(const void *va, const void *vb)
+{
     const Node *a = va, *b = vb;
     return (a->count - b->count)*256 + a->sym - b->sym;
 }
@@ -88,31 +89,33 @@
                                int h, const uint8_t *src, int size, int Uoff,
                                const int step)
 {
-    int i, j;
+    int i, j, ret;
     GetBitContext gb;
     VLC vlc;
     Node nodes[512];
 
-    for(i = 0; i < 256; i++)
+    for (i = 0; i < 256; i++)
         nodes[i].count = bytestream_get_le32(&src);
     size -= 1024;
-    if (ff_huff_build_tree(s->avctx, &vlc, 256, nodes, huff_cmp,
-                           FF_HUFFMAN_FLAG_ZERO_COUNT) < 0)
-        return -1;
+    if ((ret = ff_huff_build_tree(s->avctx, &vlc, 256, nodes, huff_cmp,
+                                  FF_HUFFMAN_FLAG_ZERO_COUNT)) < 0)
+        return ret;
     /* we have built Huffman table and are ready to decode plane */
 
     /* convert bits so they may be used by standard bitreader */
     s->dsp.bswap_buf((uint32_t *)s->tmpbuf, (const uint32_t *)src, size >> 2);
 
     init_get_bits(&gb, s->tmpbuf, size * 8);
-    for(j = 0; j < h; j++){
-        for(i = 0; i < w*step; i += step){
+    for (j = 0; j < h; j++) {
+        for (i = 0; i < w*step; i += step) {
             dst[i] = get_vlc2(&gb, vlc.table, 9, 3);
             /* lines are stored as deltas between previous lines
              * and we need to add 0x80 to the first lines of chroma planes
              */
-            if(j) dst[i] += dst[i - stride];
-            else if(Uoff) dst[i] += 0x80;
+            if (j)
+                dst[i] += dst[i - stride];
+            else if (Uoff)
+                dst[i] += 0x80;
             if (get_bits_left(&gb) < 0) {
                 ff_free_vlc(&vlc);
                 return AVERROR_INVALIDDATA;
@@ -125,28 +128,27 @@
 }
 
 static int decode_frame(AVCodecContext *avctx,
-                        void *data, int *data_size,
+                        void *data, int *got_frame,
                         AVPacket *avpkt)
 {
-    const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
     FrapsContext * const s = avctx->priv_data;
-    AVFrame *frame = data;
-    AVFrame * const f = &s->frame;
+    const uint8_t *buf     = avpkt->data;
+    int buf_size           = avpkt->size;
+    AVFrame *frame         = data;
+    AVFrame * const f      = &s->frame;
     uint32_t header;
     unsigned int version,header_size;
     unsigned int x, y;
     const uint32_t *buf32;
     uint32_t *luma1,*luma2,*cb,*cr;
     uint32_t offs[4];
-    int i, j, is_chroma;
+    int i, j, ret, is_chroma;
     const int planes = 3;
     uint8_t *out;
     enum AVPixelFormat pix_fmt;
-    int ret;
 
-    header = AV_RL32(buf);
-    version = header & 0xff;
+    header      = AV_RL32(buf);
+    version     = header & 0xff;
     header_size = (header & (1<<30))? 8 : 4; /* bit 30 means pad to 8 bytes */
 
     if (version > 5) {
@@ -159,12 +161,12 @@
     buf += header_size;
 
     if (version < 2) {
-        unsigned needed_size = avctx->width*avctx->height*3;
+        unsigned needed_size = avctx->width * avctx->height * 3;
         if (version == 0) needed_size /= 2;
         needed_size += header_size;
         /* bit 31 means same as previous pic */
         if (header & (1U<<31)) {
-            *data_size = 0;
+            *got_frame = 0;
             return buf_size;
         }
         if (buf_size != needed_size) {
@@ -176,22 +178,22 @@
     } else {
         /* skip frame */
         if (buf_size == 8) {
-            *data_size = 0;
+            *got_frame = 0;
             return buf_size;
         }
         if (AV_RL32(buf) != FPS_TAG || buf_size < planes*1024 + 24) {
             av_log(avctx, AV_LOG_ERROR, "Fraps: error in data stream\n");
             return AVERROR_INVALIDDATA;
         }
-        for(i = 0; i < planes; i++) {
+        for (i = 0; i < planes; i++) {
             offs[i] = AV_RL32(buf + 4 + i * 4);
-            if(offs[i] >= buf_size - header_size || (i && offs[i] <= offs[i - 1] + 1024)) {
+            if (offs[i] >= buf_size - header_size || (i && offs[i] <= offs[i - 1] + 1024)) {
                 av_log(avctx, AV_LOG_ERROR, "Fraps: plane %i offset is out of bounds\n", i);
                 return AVERROR_INVALIDDATA;
             }
         }
         offs[planes] = buf_size - header_size;
-        for(i = 0; i < planes; i++) {
+        for (i = 0; i < planes; i++) {
             av_fast_padded_malloc(&s->tmpbuf, &s->tmpbuf_size, offs[i + 1] - offs[i] - 1024);
             if (!s->tmpbuf)
                 return AVERROR(ENOMEM);
@@ -216,23 +218,23 @@
         return ret;
     }
 
-    switch(version) {
+    switch (version) {
     case 0:
     default:
         /* Fraps v0 is a reordered YUV420 */
-        if ( (avctx->width % 8) != 0 || (avctx->height % 2) != 0 ) {
+        if (((avctx->width % 8) != 0) || ((avctx->height % 2) != 0)) {
             av_log(avctx, AV_LOG_ERROR, "Invalid frame size %dx%d\n",
                    avctx->width, avctx->height);
             return AVERROR_INVALIDDATA;
         }
 
-        buf32=(const uint32_t*)buf;
-        for(y=0; y<avctx->height/2; y++){
-            luma1=(uint32_t*)&f->data[0][ y*2*f->linesize[0] ];
-            luma2=(uint32_t*)&f->data[0][ (y*2+1)*f->linesize[0] ];
-            cr=(uint32_t*)&f->data[1][ y*f->linesize[1] ];
-            cb=(uint32_t*)&f->data[2][ y*f->linesize[2] ];
-            for(x=0; x<avctx->width; x+=8){
+        buf32 = (const uint32_t*)buf;
+        for (y = 0; y < avctx->height / 2; y++) {
+            luma1 = (uint32_t*)&f->data[0][  y * 2      * f->linesize[0] ];
+            luma2 = (uint32_t*)&f->data[0][ (y * 2 + 1) * f->linesize[0] ];
+            cr    = (uint32_t*)&f->data[1][  y          * f->linesize[1] ];
+            cb    = (uint32_t*)&f->data[2][  y          * f->linesize[2] ];
+            for (x = 0; x < avctx->width; x += 8) {
                 *luma1++ = *buf32++;
                 *luma1++ = *buf32++;
                 *luma2++ = *buf32++;
@@ -245,10 +247,10 @@
 
     case 1:
         /* Fraps v1 is an upside-down BGR24 */
-        for(y=0; y<avctx->height; y++)
-            memcpy(&f->data[0][ (avctx->height-y)*f->linesize[0] ],
-                   &buf[y*avctx->width*3],
-                   3*avctx->width);
+            for (y = 0; y<avctx->height; y++)
+                memcpy(&f->data[0][(avctx->height - y - 1) * f->linesize[0]],
+                       &buf[y * avctx->width * 3],
+                       3 * avctx->width);
         break;
 
     case 2:
@@ -257,28 +259,32 @@
          * Fraps v2 is Huffman-coded YUV420 planes
          * Fraps v4 is virtually the same
          */
-        for(i = 0; i < planes; i++){
+        for (i = 0; i < planes; i++) {
             is_chroma = !!i;
-            if(fraps2_decode_plane(s, f->data[i], f->linesize[i], avctx->width >> is_chroma,
-                    avctx->height >> is_chroma, buf + offs[i], offs[i + 1] - offs[i], is_chroma, 1) < 0) {
+            if ((ret = fraps2_decode_plane(s, f->data[i], f->linesize[i],
+                                           avctx->width  >> is_chroma,
+                                           avctx->height >> is_chroma,
+                                           buf + offs[i], offs[i + 1] - offs[i],
+                                           is_chroma, 1)) < 0) {
                 av_log(avctx, AV_LOG_ERROR, "Error decoding plane %i\n", i);
-                return AVERROR_INVALIDDATA;
+                return ret;
             }
         }
         break;
     case 3:
     case 5:
         /* Virtually the same as version 4, but is for RGB24 */
-        for(i = 0; i < planes; i++){
-            if(fraps2_decode_plane(s, f->data[0] + i + (f->linesize[0] * (avctx->height - 1)), -f->linesize[0],
-                    avctx->width, avctx->height, buf + offs[i], offs[i + 1] - offs[i], 0, 3) < 0) {
+        for (i = 0; i < planes; i++) {
+            if ((ret = fraps2_decode_plane(s, f->data[0] + i + (f->linesize[0] * (avctx->height - 1)),
+                                           -f->linesize[0], avctx->width, avctx->height,
+                                           buf + offs[i], offs[i + 1] - offs[i], 0, 3)) < 0) {
                 av_log(avctx, AV_LOG_ERROR, "Error decoding plane %i\n", i);
-                return AVERROR_INVALIDDATA;
+                return ret;
             }
         }
         out = f->data[0];
         // convert pseudo-YUV into real RGB
-        for(j = 0; j < avctx->height; j++){
+        for (j = 0; j < avctx->height; j++) {
             uint8_t *line_end = out + 3*avctx->width;
             while (out < line_end) {
                 out[0]  += out[1];
@@ -291,7 +297,7 @@
     }
 
     *frame = *f;
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
 
     return buf_size;
 }
diff --git a/libavcodec/frwu.c b/libavcodec/frwu.c
index a0484d3..43feb01 100644
--- a/libavcodec/frwu.c
+++ b/libavcodec/frwu.c
@@ -22,6 +22,7 @@
 
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 #include "libavutil/opt.h"
 
 typedef struct {
@@ -44,7 +45,7 @@
     return 0;
 }
 
-static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         AVPacket *avpkt)
 {
     FRWUContext *s = avctx->priv_data;
@@ -66,7 +67,7 @@
     }
 
     pic->reference = 0;
-    if ((ret = avctx->get_buffer(avctx, pic)) < 0) {
+    if ((ret = ff_get_buffer(avctx, pic)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -106,7 +107,7 @@
         buf += field_size - min_field_size;
     }
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*)data = *pic;
 
     return avpkt->size;
diff --git a/libavcodec/g722.h b/libavcodec/g722.h
index bab1da4..71d03fc 100644
--- a/libavcodec/g722.h
+++ b/libavcodec/g722.h
@@ -32,7 +32,6 @@
 
 typedef struct G722Context {
     const AVClass *class;
-    AVFrame frame;
     int     bits_per_codeword;
     int16_t prev_samples[PREV_SAMPLES_BUF_SIZE]; ///< memory of past decoded samples
     int     prev_samples_pos;        ///< the number of values in prev_samples
diff --git a/libavcodec/g722dec.c b/libavcodec/g722dec.c
index f28c86b..b9c634b 100644
--- a/libavcodec/g722dec.c
+++ b/libavcodec/g722dec.c
@@ -39,6 +39,7 @@
 #include "avcodec.h"
 #include "get_bits.h"
 #include "g722.h"
+#include "internal.h"
 
 #define OFFSET(x) offsetof(G722Context, x)
 #define AD AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM
@@ -66,9 +67,6 @@
     c->band[1].scale_factor = 2;
     c->prev_samples_pos = 22;
 
-    avcodec_get_frame_defaults(&c->frame);
-    avctx->coded_frame = &c->frame;
-
     return 0;
 }
 
@@ -87,6 +85,7 @@
                              int *got_frame_ptr, AVPacket *avpkt)
 {
     G722Context *c = avctx->priv_data;
+    AVFrame *frame = data;
     int16_t *out_buf;
     int j, ret;
     const int skip = 8 - c->bits_per_codeword;
@@ -94,12 +93,12 @@
     GetBitContext gb;
 
     /* get output buffer */
-    c->frame.nb_samples = avpkt->size * 2;
-    if ((ret = avctx->get_buffer(avctx, &c->frame)) < 0) {
+    frame->nb_samples = avpkt->size * 2;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    out_buf = (int16_t *)c->frame.data[0];
+    out_buf = (int16_t *)frame->data[0];
 
     init_get_bits(&gb, avpkt->data, avpkt->size * 8);
 
@@ -134,8 +133,7 @@
         }
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = c->frame;
+    *got_frame_ptr = 1;
 
     return avpkt->size;
 }
diff --git a/libavcodec/g723_1.c b/libavcodec/g723_1.c
index fd6b558..1af2992 100644
--- a/libavcodec/g723_1.c
+++ b/libavcodec/g723_1.c
@@ -36,12 +36,12 @@
 #include "celp_filters.h"
 #include "celp_math.h"
 #include "g723_1_data.h"
+#include "internal.h"
 
 #define CNG_RANDOM_SEED 12345
 
 typedef struct g723_1_context {
     AVClass *class;
-    AVFrame frame;
 
     G723_1_Subframe subframe[4];
     enum FrameType cur_frame_type;
@@ -92,9 +92,6 @@
     avctx->channels       = 1;
     p->pf_gain            = 1 << 12;
 
-    avcodec_get_frame_defaults(&p->frame);
-    avctx->coded_frame    = &p->frame;
-
     memcpy(p->prev_lsp, dc_lsp, LPC_ORDER * sizeof(*p->prev_lsp));
     memcpy(p->sid_lsp,  dc_lsp, LPC_ORDER * sizeof(*p->sid_lsp));
 
@@ -1157,6 +1154,7 @@
                                int *got_frame_ptr, AVPacket *avpkt)
 {
     G723_1_Context *p  = avctx->priv_data;
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
     int dec_mode       = buf[0] & 3;
@@ -1186,13 +1184,13 @@
             p->cur_frame_type = UNTRANSMITTED_FRAME;
     }
 
-    p->frame.nb_samples = FRAME_LEN;
-    if ((ret = avctx->get_buffer(avctx, &p->frame)) < 0) {
+    frame->nb_samples = FRAME_LEN;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
 
-    out = (int16_t *)p->frame.data[0];
+    out = (int16_t *)frame->data[0];
 
     if (p->cur_frame_type == ACTIVE_FRAME) {
         if (!bad_frame)
@@ -1263,7 +1261,7 @@
                        (FRAME_LEN + PITCH_MAX) * sizeof(*p->excitation));
                 memset(p->prev_excitation, 0,
                        PITCH_MAX * sizeof(*p->excitation));
-                memset(p->frame.data[0], 0,
+                memset(frame->data[0], 0,
                        (FRAME_LEN + LPC_ORDER) * sizeof(int16_t));
             } else {
                 int16_t *buf = p->audio + LPC_ORDER;
@@ -1312,8 +1310,7 @@
             out[i] = av_clip_int16(p->audio[LPC_ORDER + i] << 1);
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = p->frame;
+    *got_frame_ptr = 1;
 
     return frame_size[dec_mode];
 }
diff --git a/libavcodec/g726.c b/libavcodec/g726.c
index e505d5d..638a737 100644
--- a/libavcodec/g726.c
+++ b/libavcodec/g726.c
@@ -77,7 +77,6 @@
 
 typedef struct G726Context {
     AVClass *class;
-    AVFrame frame;
     G726Tables tbls;    /**< static tables needed for computation */
 
     Float11 sr[2];      /**< prev. reconstructed samples */
@@ -432,15 +431,13 @@
 
     avctx->sample_fmt = AV_SAMPLE_FMT_S16;
 
-    avcodec_get_frame_defaults(&c->frame);
-    avctx->coded_frame = &c->frame;
-
     return 0;
 }
 
 static int g726_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;
     G726Context *c = avctx->priv_data;
@@ -451,12 +448,12 @@
     out_samples = buf_size * 8 / c->code_size;
 
     /* get output buffer */
-    c->frame.nb_samples = out_samples;
-    if ((ret = avctx->get_buffer(avctx, &c->frame)) < 0) {
+    frame->nb_samples = out_samples;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    samples = (int16_t *)c->frame.data[0];
+    samples = (int16_t *)frame->data[0];
 
     init_get_bits(&gb, buf, buf_size * 8);
 
@@ -466,8 +463,7 @@
     if (get_bits_left(&gb) > 0)
         av_log(avctx, AV_LOG_ERROR, "Frame invalidly split, missing parser?\n");
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = c->frame;
+    *got_frame_ptr = 1;
 
     return buf_size;
 }
diff --git a/libavcodec/g729dec.c b/libavcodec/g729dec.c
index 036614d..db3f013 100644
--- a/libavcodec/g729dec.c
+++ b/libavcodec/g729dec.c
@@ -26,6 +26,8 @@
 #include "libavutil/avutil.h"
 #include "get_bits.h"
 #include "dsputil.h"
+#include "internal.h"
+
 
 #include "g729.h"
 #include "lsp.h"
@@ -418,7 +420,7 @@
     int is_periodic = 0;         // whether one of the subframes is declared as periodic or not
 
     ctx->frame.nb_samples = SUBFRAME_SIZE<<1;
-    if ((ret = avctx->get_buffer(avctx, &ctx->frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, &ctx->frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -508,6 +510,10 @@
 
         /* Round pitch delay to nearest (used everywhere except ff_acelp_interpolate). */
         pitch_delay_int[i]  = (pitch_delay_3x + 1) / 3;
+        if (pitch_delay_int[i] > PITCH_DELAY_MAX) {
+            av_log(avctx, AV_LOG_WARNING, "pitch_delay_int %d is too large\n", pitch_delay_int[i]);
+            pitch_delay_int[i] = PITCH_DELAY_MAX;
+        }
 
         if (frame_erasure) {
             ctx->rand_value = g729_prng(ctx->rand_value);
diff --git a/libavcodec/get_bits.h b/libavcodec/get_bits.h
index a1a48ab..f16a508 100644
--- a/libavcodec/get_bits.h
+++ b/libavcodec/get_bits.h
@@ -27,6 +27,7 @@
 #define AVCODEC_GET_BITS_H
 
 #include <stdint.h>
+
 #include "libavutil/common.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/log.h"
@@ -72,46 +73,48 @@
 } RL_VLC_ELEM;
 
 /* Bitstream reader API docs:
-name
-    arbitrary name which is used as prefix for the internal variables
-
-gb
-    getbitcontext
-
-OPEN_READER(name, gb)
-    load gb into local variables
-
-CLOSE_READER(name, gb)
-    store local vars in gb
-
-UPDATE_CACHE(name, gb)
-    refill the internal cache from the bitstream
-    after this call at least MIN_CACHE_BITS will be available,
-
-GET_CACHE(name, gb)
-    will output the contents of the internal cache, next bit is MSB of 32 or 64 bit (FIXME 64bit)
-
-SHOW_UBITS(name, gb, num)
-    will return the next num bits
-
-SHOW_SBITS(name, gb, num)
-    will return the next num bits and do sign extension
-
-SKIP_BITS(name, gb, num)
-    will skip over the next num bits
-    note, this is equivalent to SKIP_CACHE; SKIP_COUNTER
-
-SKIP_CACHE(name, gb, num)
-    will remove the next num bits from the cache (note SKIP_COUNTER MUST be called before UPDATE_CACHE / CLOSE_READER)
-
-SKIP_COUNTER(name, gb, num)
-    will increment the internal bit counter (see SKIP_CACHE & SKIP_BITS)
-
-LAST_SKIP_BITS(name, gb, num)
-    like SKIP_BITS, to be used if next call is UPDATE_CACHE or CLOSE_READER
-
-for examples see get_bits, show_bits, skip_bits, get_vlc
-*/
+ * name
+ *   arbitrary name which is used as prefix for the internal variables
+ *
+ * gb
+ *   getbitcontext
+ *
+ * OPEN_READER(name, gb)
+ *   load gb into local variables
+ *
+ * CLOSE_READER(name, gb)
+ *   store local vars in gb
+ *
+ * UPDATE_CACHE(name, gb)
+ *   Refill the internal cache from the bitstream.
+ *   After this call at least MIN_CACHE_BITS will be available.
+ *
+ * GET_CACHE(name, gb)
+ *   Will output the contents of the internal cache,
+ *   next bit is MSB of 32 or 64 bit (FIXME 64bit).
+ *
+ * SHOW_UBITS(name, gb, num)
+ *   Will return the next num bits.
+ *
+ * SHOW_SBITS(name, gb, num)
+ *   Will return the next num bits and do sign extension.
+ *
+ * SKIP_BITS(name, gb, num)
+ *   Will skip over the next num bits.
+ *   Note, this is equivalent to SKIP_CACHE; SKIP_COUNTER.
+ *
+ * SKIP_CACHE(name, gb, num)
+ *   Will remove the next num bits from the cache (note SKIP_COUNTER
+ *   MUST be called before UPDATE_CACHE / CLOSE_READER).
+ *
+ * SKIP_COUNTER(name, gb, num)
+ *   Will increment the internal bit counter (see SKIP_CACHE & SKIP_BITS).
+ *
+ * LAST_SKIP_BITS(name, gb, num)
+ *   Like SKIP_BITS, to be used if next call is UPDATE_CACHE or CLOSE_READER.
+ *
+ * For examples see get_bits, show_bits, skip_bits, get_vlc.
+ */
 
 #ifdef LONG_BITSTREAM_READER
 #   define MIN_CACHE_BITS 32
@@ -121,57 +124,56 @@
 
 #if UNCHECKED_BITSTREAM_READER
 #define OPEN_READER(name, gb)                   \
-    unsigned int name##_index = (gb)->index;    \
-    av_unused unsigned int name##_cache
+    unsigned int name ## _index = (gb)->index;  \
+    unsigned int av_unused name ## _cache
 
 #define HAVE_BITS_REMAINING(name, gb) 1
 #else
 #define OPEN_READER(name, gb)                   \
-    unsigned int name##_index = (gb)->index;    \
-    unsigned int av_unused name##_cache = 0;    \
-    unsigned int av_unused name##_size_plus8 =  \
-                (gb)->size_in_bits_plus8
+    unsigned int name ## _index = (gb)->index;  \
+    unsigned int av_unused name ## _cache = 0;  \
+    unsigned int av_unused name ## _size_plus8 = (gb)->size_in_bits_plus8
 
-#define HAVE_BITS_REMAINING(name, gb)           \
-    name##_index < name##_size_plus8
+#define HAVE_BITS_REMAINING(name, gb) name ## _index < name ## _size_plus8
 #endif
 
-#define CLOSE_READER(name, gb) (gb)->index = name##_index
+#define CLOSE_READER(name, gb) (gb)->index = name ## _index
 
 #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)
+#   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)
+#   define UPDATE_CACHE(name, gb) name ## _cache = \
+        AV_RL32((gb)->buffer + (name ## _index >> 3)) >> (name ## _index & 7)
 # endif
 
-# define SKIP_CACHE(name, gb, num) name##_cache >>= (num)
+# 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))
+#   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)
+#   define UPDATE_CACHE(name, gb) name ## _cache = \
+        AV_RB32((gb)->buffer + (name ## _index >> 3)) << (name ## _index & 7)
 # endif
 
-# define SKIP_CACHE(name, gb, num) name##_cache <<= (num)
+# define SKIP_CACHE(name, gb, num) name ## _cache <<= (num)
 
 #endif
 
 #if UNCHECKED_BITSTREAM_READER
-#   define SKIP_COUNTER(name, gb, num) name##_index += (num)
+#   define SKIP_COUNTER(name, gb, num) name ## _index += (num)
 #else
 #   define SKIP_COUNTER(name, gb, num) \
-    name##_index = FFMIN(name##_size_plus8, name##_index + (num))
+    name ## _index = FFMIN(name ## _size_plus8, name ## _index + (num))
 #endif
 
-#define SKIP_BITS(name, gb, num) do {           \
+#define SKIP_BITS(name, gb, num)                \
+    do {                                        \
         SKIP_CACHE(name, gb, num);              \
         SKIP_COUNTER(name, gb, num);            \
     } while (0)
@@ -179,21 +181,22 @@
 #define LAST_SKIP_BITS(name, gb, num) SKIP_COUNTER(name, gb, 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) zero_extend(name ## _cache, num)
+#   define SHOW_SBITS(name, gb, num) sign_extend(name ## _cache, 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) NEG_USR32(name ## _cache, num)
+#   define SHOW_SBITS(name, gb, num) NEG_SSR32(name ## _cache, num)
 #endif
 
-#define GET_CACHE(name, gb) ((uint32_t)name##_cache)
+#define GET_CACHE(name, gb) ((uint32_t) name ## _cache)
 
 static inline int get_bits_count(const GetBitContext *s)
 {
     return s->index;
 }
 
-static inline void skip_bits_long(GetBitContext *s, int n){
+static inline void skip_bits_long(GetBitContext *s, int n)
+{
 #if UNCHECKED_BITSTREAM_READER
     s->index += n;
 #else
@@ -213,7 +216,7 @@
     OPEN_READER(re, s);
     UPDATE_CACHE(re, s);
     cache = GET_CACHE(re, s);
-    sign = ~cache >> 31;
+    sign  = ~cache >> 31;
     LAST_SKIP_BITS(re, s, n);
     CLOSE_READER(re, s);
     return (NEG_USR32(sign ^ cache, n) ^ sign) - sign;
@@ -270,10 +273,10 @@
 static inline unsigned int get_bits1(GetBitContext *s)
 {
     unsigned int index = s->index;
-    uint8_t result = s->buffer[index>>3];
+    uint8_t result     = s->buffer[index >> 3];
 #ifdef BITSTREAM_READER_LE
     result >>= index & 7;
-    result &= 1;
+    result  &= 1;
 #else
     result <<= index & 7;
     result >>= 8 - 1;
@@ -304,15 +307,15 @@
 {
     if (!n) {
         return 0;
-    } else if (n <= MIN_CACHE_BITS)
+    } else if (n <= MIN_CACHE_BITS) {
         return get_bits(s, n);
-    else {
+    } else {
 #ifdef BITSTREAM_READER_LE
         unsigned ret = get_bits(s, 16);
-        return ret | (get_bits(s, n-16) << 16);
+        return ret | (get_bits(s, n - 16) << 16);
 #else
-        unsigned ret = get_bits(s, 16) << (n-16);
-        return ret | get_bits(s, n-16);
+        unsigned ret = get_bits(s, 16) << (n - 16);
+        return ret | get_bits(s, n - 16);
 #endif
     }
 }
@@ -320,17 +323,17 @@
 /**
  * Read 0-64 bits.
  */
-static inline uint64_t get_bits_longlong(GetBitContext *s, int n)
+static inline uint64_t get_bits64(GetBitContext *s, int n)
 {
-    if (n <= 32)
+    if (n <= 32) {
         return get_bits_long(s, n);
-    else {
+    } else {
 #ifdef BITSTREAM_READER_LE
         uint64_t ret = get_bits_long(s, 32);
-        return ret | (((uint64_t)get_bits_long(s, n-32)) << 32);
+        return ret | (uint64_t) get_bits_long(s, n - 32) << 32;
 #else
-        uint64_t ret = ((uint64_t)get_bits_long(s, 32)) << (n-32);
-        return ret | get_bits_long(s, n-32);
+        uint64_t ret = (uint64_t) get_bits_long(s, n - 32) << 32;
+        return ret | get_bits_long(s, 32);
 #endif
     }
 }
@@ -348,9 +351,9 @@
  */
 static inline unsigned int show_bits_long(GetBitContext *s, int n)
 {
-    if (n <= MIN_CACHE_BITS)
+    if (n <= MIN_CACHE_BITS) {
         return show_bits(s, n);
-    else {
+    } else {
         GetBitContext gb = *s;
         return get_bits_long(&gb, n);
     }
@@ -366,58 +369,86 @@
 }
 
 /**
- * Inititalize GetBitContext.
- * @param buffer bitstream buffer, must be FF_INPUT_BUFFER_PADDING_SIZE bytes larger than the actual read bits
- * because some optimized bitstream readers read 32 or 64 bit at once and could read over the end
+ * Initialize GetBitContext.
+ * @param buffer bitstream buffer, must be FF_INPUT_BUFFER_PADDING_SIZE bytes
+ *        larger than the actual read bits because some optimized bitstream
+ *        readers read 32 or 64 bit at once and could read over the end
  * @param bit_size the size of the buffer in bits
+ * @return 0 on success, AVERROR_INVALIDDATA if the buffer_size would overflow.
  */
-static inline void init_get_bits(GetBitContext *s, const uint8_t *buffer,
-                                 int bit_size)
+static inline int init_get_bits(GetBitContext *s, const uint8_t *buffer,
+                                int bit_size)
 {
-    int buffer_size = (bit_size+7)>>3;
-    if (buffer_size < 0 || bit_size < 0) {
+    int buffer_size;
+    int ret = 0;
+
+    if (bit_size >= INT_MAX - 7 || bit_size < 0 || !buffer) {
         buffer_size = bit_size = 0;
-        buffer = NULL;
+        buffer      = NULL;
+        ret         = AVERROR_INVALIDDATA;
     }
 
-    s->buffer       = buffer;
-    s->size_in_bits = bit_size;
+    buffer_size = (bit_size + 7) >> 3;
+
+    s->buffer             = buffer;
+    s->size_in_bits       = bit_size;
     s->size_in_bits_plus8 = bit_size + 8;
-    s->buffer_end   = buffer + buffer_size;
-    s->index        = 0;
+    s->buffer_end         = buffer + buffer_size;
+    s->index              = 0;
+
+    return ret;
 }
 
-static inline void align_get_bits(GetBitContext *s)
+/**
+ * Initialize GetBitContext.
+ * @param buffer bitstream buffer, must be FF_INPUT_BUFFER_PADDING_SIZE bytes
+ *        larger than the actual read bits because some optimized bitstream
+ *        readers read 32 or 64 bit at once and could read over the end
+ * @param byte_size the size of the buffer in bytes
+ * @return 0 on success, AVERROR_INVALIDDATA if the buffer_size would overflow.
+ */
+static inline int init_get_bits8(GetBitContext *s, const uint8_t *buffer,
+                                 int byte_size)
+{
+    if (byte_size > INT_MAX / 8 || byte_size < 0)
+        byte_size = -1;
+    return init_get_bits(s, buffer, byte_size * 8);
+}
+
+static inline const uint8_t *align_get_bits(GetBitContext *s)
 {
     int n = -get_bits_count(s) & 7;
-    if (n) skip_bits(s, n);
+    if (n)
+        skip_bits(s, n);
+    return s->buffer + (s->index >> 3);
 }
 
 #define init_vlc(vlc, nb_bits, nb_codes,                \
                  bits, bits_wrap, bits_size,            \
                  codes, codes_wrap, codes_size,         \
                  flags)                                 \
-        ff_init_vlc_sparse(vlc, nb_bits, nb_codes,         \
-                           bits, bits_wrap, bits_size,     \
-                           codes, codes_wrap, codes_size,  \
-                           NULL, 0, 0, flags)
+    ff_init_vlc_sparse(vlc, nb_bits, nb_codes,          \
+                       bits, bits_wrap, bits_size,      \
+                       codes, codes_wrap, codes_size,   \
+                       NULL, 0, 0, flags)
 
 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);
-#define INIT_VLC_LE         2
-#define INIT_VLC_USE_NEW_STATIC 4
+                       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);
 void ff_free_vlc(VLC *vlc);
 
-#define INIT_VLC_STATIC(vlc, bits, a,b,c,d,e,f,g, static_size) do {     \
-        static VLC_TYPE table[static_size][2];                          \
-        (vlc)->table = table;                                           \
-        (vlc)->table_allocated = static_size;                           \
-        init_vlc(vlc, bits, a,b,c,d,e,f,g, INIT_VLC_USE_NEW_STATIC);    \
-    } while (0)
+#define INIT_VLC_LE             2
+#define INIT_VLC_USE_NEW_STATIC 4
 
+#define INIT_VLC_STATIC(vlc, bits, a, b, c, d, e, f, g, static_size)       \
+    do {                                                                   \
+        static VLC_TYPE table[static_size][2];                             \
+        (vlc)->table           = table;                                    \
+        (vlc)->table_allocated = static_size;                              \
+        init_vlc(vlc, bits, a, b, c, d, e, f, g, INIT_VLC_USE_NEW_STATIC); \
+    } while (0)
 
 /**
  * If the vlc code is invalid and max_depth=1, then no bits will be removed.
@@ -456,32 +487,32 @@
         SKIP_BITS(name, gb, n);                                 \
     } while (0)
 
-#define GET_RL_VLC(level, run, name, gb, table, bits, max_depth, need_update) \
-    do {                                                                \
-        int n, nb_bits;                                                 \
-        unsigned int index;                                             \
-                                                                        \
-        index = SHOW_UBITS(name, gb, bits);                             \
-        level = table[index].level;                                     \
-        n     = table[index].len;                                       \
-                                                                        \
-        if (max_depth > 1 && n < 0) {                                   \
-            SKIP_BITS(name, gb, bits);                                  \
-            if (need_update) {                                          \
-                UPDATE_CACHE(name, gb);                                 \
-            }                                                           \
-                                                                        \
-            nb_bits = -n;                                               \
-                                                                        \
-            index = SHOW_UBITS(name, gb, nb_bits) + level;              \
-            level = table[index].level;                                 \
-            n     = table[index].len;                                   \
-        }                                                               \
-        run = table[index].run;                                         \
-        SKIP_BITS(name, gb, n);                                         \
+#define GET_RL_VLC(level, run, name, gb, table, bits,           \
+                   max_depth, need_update)                      \
+    do {                                                        \
+        int n, nb_bits;                                         \
+        unsigned int index;                                     \
+                                                                \
+        index = SHOW_UBITS(name, gb, bits);                     \
+        level = table[index].level;                             \
+        n     = table[index].len;                               \
+                                                                \
+        if (max_depth > 1 && n < 0) {                           \
+            SKIP_BITS(name, gb, bits);                          \
+            if (need_update) {                                  \
+                UPDATE_CACHE(name, gb);                         \
+            }                                                   \
+                                                                \
+            nb_bits = -n;                                       \
+                                                                \
+            index = SHOW_UBITS(name, gb, nb_bits) + level;      \
+            level = table[index].level;                         \
+            n     = table[index].len;                           \
+        }                                                       \
+        run = table[index].run;                                 \
+        SKIP_BITS(name, gb, n);                                 \
     } while (0)
 
-
 /**
  * Parse a vlc code.
  * @param bits is the number of bits which will be read at once, must be
@@ -501,6 +532,7 @@
     GET_VLC(code, re, s, table, bits, max_depth);
 
     CLOSE_READER(re, s);
+
     return code;
 }
 
@@ -534,9 +566,8 @@
 {
     int i;
 
-    for (i = n-1; i >= 0; i--) {
-        av_log(NULL, AV_LOG_DEBUG, "%d", (bits>>i)&1);
-    }
+    for (i = n - 1; i >= 0; i--)
+        av_log(NULL, AV_LOG_DEBUG, "%d", (bits >> i) & 1);
     for (i = n; i < 24; i++)
         av_log(NULL, AV_LOG_DEBUG, " ");
 }
@@ -548,9 +579,11 @@
 
     print_bin(r, n);
     av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d bit @%5d in %s %s:%d\n",
-           r, n, r, get_bits_count(s)-n, file, func, line);
+           r, n, r, get_bits_count(s) - n, file, func, line);
+
     return r;
 }
+
 static inline int get_vlc_trace(GetBitContext *s, VLC_TYPE (*table)[2],
                                 int bits, int max_depth, const char *file,
                                 const char *func, int line)
@@ -559,14 +592,16 @@
     int pos   = get_bits_count(s);
     int r     = get_vlc2(s, table, bits, max_depth);
     int len   = get_bits_count(s) - pos;
-    int bits2 = show >> (24-len);
+    int bits2 = show >> (24 - len);
 
     print_bin(bits2, len);
 
     av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d vlc @%5d in %s %s:%d\n",
            bits2, len, r, pos, file, func, line);
+
     return r;
 }
+
 static inline int get_xbits_trace(GetBitContext *s, int n, const char *file,
                                   const char *func, int line)
 {
@@ -575,20 +610,22 @@
 
     print_bin(show, n);
     av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d xbt @%5d in %s %s:%d\n",
-           show, n, r, get_bits_count(s)-n, file, func, line);
+           show, n, r, get_bits_count(s) - n, file, func, line);
+
     return r;
 }
 
-#define get_bits(s, n)  get_bits_trace(s, n, __FILE__, __PRETTY_FUNCTION__, __LINE__)
-#define get_bits1(s)    get_bits_trace(s, 1, __FILE__, __PRETTY_FUNCTION__, __LINE__)
+#define get_bits(s, n)  get_bits_trace(s , n, __FILE__, __PRETTY_FUNCTION__, __LINE__)
+#define get_bits1(s)    get_bits_trace(s,  1, __FILE__, __PRETTY_FUNCTION__, __LINE__)
 #define get_xbits(s, n) get_xbits_trace(s, n, __FILE__, __PRETTY_FUNCTION__, __LINE__)
-#define get_vlc(s, vlc)            get_vlc_trace(s, (vlc)->table, (vlc)->bits, 3, __FILE__, __PRETTY_FUNCTION__, __LINE__)
-#define get_vlc2(s, tab, bits, max) get_vlc_trace(s, tab, bits, max, __FILE__, __PRETTY_FUNCTION__, __LINE__)
+
+#define get_vlc(s, vlc)             get_vlc_trace(s, (vlc)->table, (vlc)->bits,   3, __FILE__, __PRETTY_FUNCTION__, __LINE__)
+#define get_vlc2(s, tab, bits, max) get_vlc_trace(s,          tab,        bits, max, __FILE__, __PRETTY_FUNCTION__, __LINE__)
 
 #define tprintf(p, ...) av_log(p, AV_LOG_DEBUG, __VA_ARGS__)
 
 #else //TRACE
-#define tprintf(p, ...) {}
+#define tprintf(p, ...) { }
 #endif
 
 #endif /* AVCODEC_GET_BITS_H */
diff --git a/libavcodec/gif.c b/libavcodec/gif.c
index 1ae4661..de3e576 100644
--- a/libavcodec/gif.c
+++ b/libavcodec/gif.c
@@ -25,8 +25,6 @@
  * First version by Francois Revol revol@free.fr
  *
  * Features and limitations:
- * - currently no compression is performed,
- *   in fact the size of the data is 9/8 the size of the image in 8bpp
  * - uses only a global standard palette
  * - tested with IE 5.0, Opera for BeOS, NetPositive (BeOS), and Mozilla (BeOS).
  *
@@ -34,11 +32,6 @@
  * http://www.goice.co.jp/member/mo/formats/gif.html
  * http://astronomy.swin.edu.au/pbourke/dataformats/gif/
  * http://www.dcs.ed.ac.uk/home/mxr/gfx/2d/GIF89a.txt
- *
- * this url claims to have an LZW algorithm not covered by Unisys patent:
- * http://www.msg.net/utility/whirlgif/gifencod.html
- * could help reduce the size of the files _a lot_...
- * some sites mentions an RLE type compression also.
  */
 
 #include "avcodec.h"
diff --git a/libavcodec/gifdec.c b/libavcodec/gifdec.c
index 3e3c9a5..71d3d70 100644
--- a/libavcodec/gifdec.c
+++ b/libavcodec/gifdec.c
@@ -27,6 +27,7 @@
 #include "libavutil/opt.h"
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 #include "lzw.h"
 #include "gif.h"
 
@@ -64,9 +65,8 @@
     int stored_img_size;
     int stored_bg_color;
 
+    GetByteContext gb;
     /* LZW compatible decoder */
-    const uint8_t *bytestream;
-    const uint8_t *bytestream_end;
     LZWState *lzw;
 
     /* aux buffers */
@@ -75,15 +75,16 @@
 
     AVCodecContext *avctx;
     int keyframe;
+    int keyframe_ok;
     int trans_color;    /**< color value that is used instead of transparent color */
 } GifState;
 
-static void gif_read_palette(const uint8_t **buf, uint32_t *pal, int nb)
+static void gif_read_palette(GifState *s, uint32_t *pal, int nb)
 {
-    const uint8_t *pal_end = *buf + nb * 3;
+    int i;
 
-    for (; *buf < pal_end; *buf += 3, pal++)
-        *pal = (0xffu << 24) | AV_RB24(*buf);
+    for (i = 0; i < nb; i++, pal++)
+        *pal = (0xffu << 24) | bytestream2_get_be24u(&s->gb);
 }
 
 static void gif_fill(AVFrame *picture, uint32_t color)
@@ -99,7 +100,7 @@
 {
     const int linesize = picture->linesize[0] / sizeof(uint32_t);
     const uint32_t *py = (uint32_t *)picture->data[0] + t * linesize;
-    const uint32_t *pr, *pb = py + (t + h) * linesize;
+    const uint32_t *pr, *pb = py + h * linesize;
     uint32_t *px;
 
     for (; py < pb; py += linesize) {
@@ -115,19 +116,17 @@
                               int linesize, int l, int t, int w, int h)
 {
     const int y_start = t * linesize;
-    const uint32_t *src_px, *src_pr,
+    const uint32_t *src_px,
                    *src_py = src + y_start,
                    *dst_py = dst + y_start;
-    const uint32_t *src_pb = src_py + (t + h) * linesize;
+    const uint32_t *src_pb = src_py + h * linesize;
     uint32_t *dst_px;
 
     for (; src_py < src_pb; src_py += linesize, dst_py += linesize) {
         src_px = src_py + l;
         dst_px = (uint32_t *)dst_py + l;
-        src_pr = src_px + w;
 
-        for (; src_px < src_pr; src_px++, dst_px++)
-            *dst_px = *src_px;
+        memcpy(dst_px, src_px, w * sizeof(uint32_t));
     }
 }
 
@@ -140,14 +139,14 @@
     uint8_t *idx;
 
     /* At least 9 bytes of Image Descriptor. */
-    if (s->bytestream_end < s->bytestream + 9)
+    if (bytestream2_get_bytes_left(&s->gb) < 9)
         return AVERROR_INVALIDDATA;
 
-    left = bytestream_get_le16(&s->bytestream);
-    top = bytestream_get_le16(&s->bytestream);
-    width = bytestream_get_le16(&s->bytestream);
-    height = bytestream_get_le16(&s->bytestream);
-    flags = bytestream_get_byte(&s->bytestream);
+    left = bytestream2_get_le16u(&s->gb);
+    top = bytestream2_get_le16u(&s->gb);
+    width = bytestream2_get_le16u(&s->gb);
+    height = bytestream2_get_le16u(&s->gb);
+    flags = bytestream2_get_byteu(&s->gb);
     is_interleaved = flags & 0x40;
     has_local_palette = flags & 0x80;
     bits_per_pixel = (flags & 0x07) + 1;
@@ -157,14 +156,14 @@
     if (has_local_palette) {
         pal_size = 1 << bits_per_pixel;
 
-        if (s->bytestream_end < s->bytestream + pal_size * 3)
+        if (bytestream2_get_bytes_left(&s->gb) < pal_size * 3)
             return AVERROR_INVALIDDATA;
 
-        gif_read_palette(&s->bytestream, s->local_palette, pal_size);
+        gif_read_palette(s, s->local_palette, pal_size);
         pal = s->local_palette;
     } else {
         if (!s->has_global_palette) {
-            av_log(s->avctx, AV_LOG_FATAL, "picture doesn't have either global or local palette.\n");
+            av_log(s->avctx, AV_LOG_ERROR, "picture doesn't have either global or local palette.\n");
             return AVERROR_INVALIDDATA;
         }
 
@@ -185,7 +184,9 @@
     /* verify that all the image is inside the screen dimensions */
     if (left + width > s->screen_width ||
         top + height > s->screen_height)
-        return AVERROR(EINVAL);
+        return AVERROR_INVALIDDATA;
+    if (width <= 0 || height <= 0)
+        return AVERROR_INVALIDDATA;
 
     /* process disposal method */
     if (s->gce_prev_disposal == GCE_DISPOSAL_BACKGROUND) {
@@ -202,7 +203,7 @@
         s->gce_w = width; s->gce_h = height;
 
         if (s->gce_disposal == GCE_DISPOSAL_BACKGROUND) {
-            if (s->background_color_index == s->transparent_color_index)
+            if (s->transparent_color_index >= 0)
                 s->stored_bg_color = s->trans_color;
             else
                 s->stored_bg_color = s->bg_color;
@@ -217,13 +218,13 @@
     }
 
     /* Expect at least 2 bytes: 1 for lzw code size and 1 for block size. */
-    if (s->bytestream_end < s->bytestream + 2)
+    if (bytestream2_get_bytes_left(&s->gb) < 2)
         return AVERROR_INVALIDDATA;
 
     /* now get the image data */
-    code_size = bytestream_get_byte(&s->bytestream);
-    if ((ret = ff_lzw_decode_init(s->lzw, code_size, s->bytestream,
-                       s->bytestream_end - s->bytestream, FF_LZW_GIF)) < 0) {
+    code_size = bytestream2_get_byteu(&s->gb);
+    if ((ret = ff_lzw_decode_init(s->lzw, code_size, s->gb.buffer,
+                                  bytestream2_get_bytes_left(&s->gb), FF_LZW_GIF)) < 0) {
         av_log(s->avctx, AV_LOG_ERROR, "LZW init failed\n");
         return ret;
     }
@@ -280,7 +281,6 @@
  decode_tail:
     /* read the garbage data until end marker is found */
     ff_lzw_decode_tail(s->lzw);
-    s->bytestream = ff_lzw_cur_ptr(s->lzw);
 
     /* Graphic Control Extension's scope is single frame.
      * Remove its influence. */
@@ -292,15 +292,15 @@
 
 static int gif_read_extension(GifState *s)
 {
-    int ext_code, ext_len, i, gce_flags, gce_transparent_index;
+    int ext_code, ext_len, gce_flags, gce_transparent_index;
 
     /* There must be at least 2 bytes:
      * 1 for extension label and 1 for extension length. */
-    if (s->bytestream_end < s->bytestream + 2)
+    if (bytestream2_get_bytes_left(&s->gb) < 2)
         return AVERROR_INVALIDDATA;
 
-    ext_code = bytestream_get_byte(&s->bytestream);
-    ext_len = bytestream_get_byte(&s->bytestream);
+    ext_code = bytestream2_get_byteu(&s->gb);
+    ext_len = bytestream2_get_byteu(&s->gb);
 
     av_dlog(s->avctx, "ext_code=0x%x len=%d\n", ext_code, ext_len);
 
@@ -311,13 +311,12 @@
 
         /* We need at least 5 bytes more: 4 is for extension body
          * and 1 for next block size. */
-        if (s->bytestream_end < s->bytestream + 5)
+        if (bytestream2_get_bytes_left(&s->gb) < 5)
             return AVERROR_INVALIDDATA;
 
-        s->transparent_color_index = -1;
-        gce_flags = bytestream_get_byte(&s->bytestream);
-        bytestream_get_le16(&s->bytestream);    // delay during which the frame is shown
-        gce_transparent_index = bytestream_get_byte(&s->bytestream);
+        gce_flags = bytestream2_get_byteu(&s->gb);
+        bytestream2_skipu(&s->gb, 2);    // delay during which the frame is shown
+        gce_transparent_index = bytestream2_get_byteu(&s->gb);
         if (gce_flags & 0x01)
             s->transparent_color_index = gce_transparent_index;
         else
@@ -333,20 +332,19 @@
             av_dlog(s->avctx, "invalid value in gce_disposal (%d). Using default value of 0.\n", ext_len);
         }
 
-        ext_len = bytestream_get_byte(&s->bytestream);
+        ext_len = bytestream2_get_byteu(&s->gb);
         break;
     }
 
     /* NOTE: many extension blocks can come after */
  discard_ext:
-    while (ext_len != 0) {
+    while (ext_len) {
         /* There must be at least ext_len bytes and 1 for next block size byte. */
-        if (s->bytestream_end < s->bytestream + ext_len + 1)
+        if (bytestream2_get_bytes_left(&s->gb) < ext_len + 1)
             return AVERROR_INVALIDDATA;
 
-        for (i = 0; i < ext_len; i++)
-            bytestream_get_byte(&s->bytestream);
-        ext_len = bytestream_get_byte(&s->bytestream);
+        bytestream2_skipu(&s->gb, ext_len);
+        ext_len = bytestream2_get_byteu(&s->gb);
 
         av_dlog(s->avctx, "ext_len1=%d\n", ext_len);
     }
@@ -359,35 +357,26 @@
     int v, n;
     int background_color_index;
 
-    if (s->bytestream_end < s->bytestream + 13)
+    if (bytestream2_get_bytes_left(&s->gb) < 13)
         return AVERROR_INVALIDDATA;
 
     /* read gif signature */
-    bytestream_get_buffer(&s->bytestream, sig, 6);
-    if (memcmp(sig, gif87a_sig, 6) != 0 &&
-        memcmp(sig, gif89a_sig, 6) != 0)
+    bytestream2_get_bufferu(&s->gb, sig, 6);
+    if (memcmp(sig, gif87a_sig, 6) &&
+        memcmp(sig, gif89a_sig, 6))
         return AVERROR_INVALIDDATA;
 
     /* read screen header */
     s->transparent_color_index = -1;
-    s->screen_width = bytestream_get_le16(&s->bytestream);
-    s->screen_height = bytestream_get_le16(&s->bytestream);
-    if(   (unsigned)s->screen_width  > 32767
-       || (unsigned)s->screen_height > 32767){
-        av_log(s->avctx, AV_LOG_ERROR, "picture size too large\n");
-        return AVERROR_INVALIDDATA;
-    }
+    s->screen_width = bytestream2_get_le16u(&s->gb);
+    s->screen_height = bytestream2_get_le16u(&s->gb);
 
-    av_fast_malloc(&s->idx_line, &s->idx_line_size, s->screen_width);
-    if (!s->idx_line)
-        return AVERROR(ENOMEM);
-
-    v = bytestream_get_byte(&s->bytestream);
+    v = bytestream2_get_byteu(&s->gb);
     s->color_resolution = ((v & 0x70) >> 4) + 1;
     s->has_global_palette = (v & 0x80);
     s->bits_per_pixel = (v & 0x07) + 1;
-    background_color_index = bytestream_get_byte(&s->bytestream);
-    n = bytestream_get_byte(&s->bytestream);
+    background_color_index = bytestream2_get_byteu(&s->gb);
+    n = bytestream2_get_byteu(&s->gb);
     if (n) {
         s->avctx->sample_aspect_ratio.num = n + 15;
         s->avctx->sample_aspect_ratio.den = 64;
@@ -400,10 +389,10 @@
     if (s->has_global_palette) {
         s->background_color_index = background_color_index;
         n = 1 << s->bits_per_pixel;
-        if (s->bytestream_end < s->bytestream + n * 3)
+        if (bytestream2_get_bytes_left(&s->gb) < n * 3)
             return AVERROR_INVALIDDATA;
 
-        gif_read_palette(&s->bytestream, s->global_palette, n);
+        gif_read_palette(s, s->global_palette, n);
         s->bg_color = s->global_palette[s->background_color_index];
     } else
         s->background_color_index = -1;
@@ -411,12 +400,11 @@
     return 0;
 }
 
-static int gif_parse_next_image(GifState *s, int *got_picture)
+static int gif_parse_next_image(GifState *s)
 {
-    int ret;
-    *got_picture = sizeof(AVPicture);
-    while (s->bytestream < s->bytestream_end) {
-        int code = bytestream_get_byte(&s->bytestream);
+    while (bytestream2_get_bytes_left(&s->gb)) {
+        int code = bytestream2_get_byte(&s->gb);
+        int ret;
 
         av_dlog(s->avctx, "code=%02x '%c'\n", code, code);
 
@@ -429,8 +417,7 @@
             break;
         case GIF_TRAILER:
             /* end of image */
-            *got_picture = 0;
-            return 0;
+            return AVERROR_EOF;
         default:
             /* erroneous block label */
             return AVERROR_INVALIDDATA;
@@ -453,30 +440,28 @@
     return 0;
 }
 
-static int gif_decode_frame(AVCodecContext *avctx, void *data, int *got_picture, AVPacket *avpkt)
+static int gif_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
 {
-    const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
     GifState *s = avctx->priv_data;
     AVFrame *picture = data;
     int ret;
 
+    bytestream2_init(&s->gb, avpkt->data, avpkt->size);
+
     s->picture.pts          = avpkt->pts;
     s->picture.pkt_pts      = avpkt->pts;
     s->picture.pkt_dts      = avpkt->dts;
     s->picture.pkt_duration = avpkt->duration;
 
-    s->bytestream = buf;
-    s->bytestream_end = buf + buf_size;
-
-    if (buf_size >= 6) {
-        s->keyframe = memcmp(s->bytestream, gif87a_sig, 6) == 0 ||
-                      memcmp(s->bytestream, gif89a_sig, 6) == 0;
+    if (avpkt->size >= 6) {
+        s->keyframe = memcmp(avpkt->data, gif87a_sig, 6) == 0 ||
+                      memcmp(avpkt->data, gif89a_sig, 6) == 0;
     } else {
         s->keyframe = 0;
     }
 
     if (s->keyframe) {
+        s->keyframe_ok = 0;
         if ((ret = gif_read_header1(s)) < 0)
             return ret;
 
@@ -487,14 +472,24 @@
         if (s->picture.data[0])
             avctx->release_buffer(avctx, &s->picture);
 
-        if ((ret = avctx->get_buffer(avctx, &s->picture)) < 0) {
+        if ((ret = ff_get_buffer(avctx, &s->picture)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
             return ret;
         }
 
+        av_fast_malloc(&s->idx_line, &s->idx_line_size, s->screen_width);
+        if (!s->idx_line)
+            return AVERROR(ENOMEM);
+
         s->picture.pict_type = AV_PICTURE_TYPE_I;
         s->picture.key_frame = 1;
+        s->keyframe_ok = 1;
     } else {
+        if (!s->keyframe_ok) {
+            av_log(avctx, AV_LOG_ERROR, "cannot decode frame without keyframe\n");
+            return AVERROR_INVALIDDATA;
+        }
+
         if ((ret = avctx->reget_buffer(avctx, &s->picture)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
             return ret;
@@ -504,13 +499,14 @@
         s->picture.key_frame = 0;
     }
 
-    ret = gif_parse_next_image(s, got_picture);
+    ret = gif_parse_next_image(s);
     if (ret < 0)
         return ret;
-    else if (*got_picture)
-        *picture = s->picture;
 
-    return s->bytestream - buf;
+    *picture = s->picture;
+    *got_frame = 1;
+
+    return avpkt->size;
 }
 
 static av_cold int gif_decode_close(AVCodecContext *avctx)
diff --git a/libavcodec/golomb-test.c b/libavcodec/golomb-test.c
index 54644ad..8adcdf6 100644
--- a/libavcodec/golomb-test.c
+++ b/libavcodec/golomb-test.c
@@ -27,7 +27,6 @@
 #include "golomb.h"
 #include "put_bits.h"
 
-#undef fprintf
 #define COUNT 8191
 #define SIZE (COUNT * 4)
 
diff --git a/libavcodec/golomb.h b/libavcodec/golomb.h
index 0ce1b34..66607ad 100644
--- a/libavcodec/golomb.h
+++ b/libavcodec/golomb.h
@@ -66,10 +66,14 @@
         return ff_ue_golomb_vlc_code[buf];
     }else{
         log= 2*av_log2(buf) - 31;
-        buf>>= log;
-        buf--;
         LAST_SKIP_BITS(re, gb, 32 - log);
         CLOSE_READER(re, gb);
+        if (CONFIG_FTRAPV && log < 0) {
+            av_log(0, AV_LOG_ERROR, "Invalid UE golomb code\n");
+            return AVERROR_INVALIDDATA;
+        }
+        buf>>= log;
+        buf--;
 
         return buf;
     }
@@ -107,7 +111,8 @@
     return ff_ue_golomb_vlc_code[buf];
 }
 
-static inline int svq3_get_ue_golomb(GetBitContext *gb){
+static inline unsigned svq3_get_ue_golomb(GetBitContext *gb)
+{
     uint32_t buf;
 
     OPEN_READER(re, gb);
@@ -121,7 +126,7 @@
 
         return ff_interleaved_ue_golomb_vlc_code[buf];
     }else{
-        int ret = 1;
+        unsigned ret = 1;
 
         do {
             buf >>= 32 - 8;
@@ -182,7 +187,11 @@
 
         return ff_se_golomb_vlc_code[buf];
     }else{
-        log= 2*av_log2(buf) - 31;
+        log = av_log2(buf);
+        LAST_SKIP_BITS(re, gb, 31 - log);
+        UPDATE_CACHE(re, gb);
+        buf = GET_CACHE(re, gb);
+
         buf>>= log;
 
         LAST_SKIP_BITS(re, gb, 32 - log);
diff --git a/libavcodec/gsmdec.c b/libavcodec/gsmdec.c
index f6f99bd..f20ef9a 100644
--- a/libavcodec/gsmdec.c
+++ b/libavcodec/gsmdec.c
@@ -27,14 +27,13 @@
 #include "libavutil/channel_layout.h"
 #include "avcodec.h"
 #include "get_bits.h"
+#include "internal.h"
 #include "msgsmdec.h"
 
 #include "gsmdec_template.c"
 
 static av_cold int gsm_init(AVCodecContext *avctx)
 {
-    GSMContext *s = avctx->priv_data;
-
     avctx->channels       = 1;
     avctx->channel_layout = AV_CH_LAYOUT_MONO;
     if (!avctx->sample_rate)
@@ -51,16 +50,13 @@
         avctx->block_align = GSM_MS_BLOCK_SIZE;
     }
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     return 0;
 }
 
 static int gsm_decode_frame(AVCodecContext *avctx, void *data,
                             int *got_frame_ptr, AVPacket *avpkt)
 {
-    GSMContext *s = avctx->priv_data;
+    AVFrame *frame = data;
     int res;
     GetBitContext gb;
     const uint8_t *buf = avpkt->data;
@@ -73,12 +69,12 @@
     }
 
     /* get output buffer */
-    s->frame.nb_samples = avctx->frame_size;
-    if ((res = avctx->get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = avctx->frame_size;
+    if ((res = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return res;
     }
-    samples = (int16_t *)s->frame.data[0];
+    samples = (int16_t *)frame->data[0];
 
     switch (avctx->codec_id) {
     case AV_CODEC_ID_GSM:
@@ -95,8 +91,7 @@
             return res;
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
+    *got_frame_ptr = 1;
 
     return avctx->block_align;
 }
diff --git a/libavcodec/gsmdec_data.h b/libavcodec/gsmdec_data.h
index 6abe2b4..fd89ed6 100644
--- a/libavcodec/gsmdec_data.h
+++ b/libavcodec/gsmdec_data.h
@@ -19,14 +19,13 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#ifndef AVCODEC_GSMDEC_DATA
-#define AVCODEC_GSMDEC_DATA
+#ifndef AVCODEC_GSMDEC_DATA_H
+#define AVCODEC_GSMDEC_DATA_H
 
 #include <stdint.h>
 #include "avcodec.h"
 
 typedef struct GSMContext {
-    AVFrame frame;
     // Contains first 120 elements from the previous frame
     // (used by long_term_synth according to the "lag"),
     // then in the following 160 elements the current
@@ -41,4 +40,4 @@
 extern const uint16_t ff_gsm_long_term_gain_tab[4];
 extern const int16_t ff_gsm_dequant_tab[64][8];
 
-#endif /* AVCODEC_GSMDEC_DATA */
+#endif /* AVCODEC_GSMDEC_DATA_H */
diff --git a/libavcodec/h261.c b/libavcodec/h261.c
index 951997d..f89d5c7 100644
--- a/libavcodec/h261.c
+++ b/libavcodec/h261.c
@@ -25,7 +25,6 @@
  * h261codec.
  */
 
-#include "dsputil.h"
 #include "avcodec.h"
 #include "h261.h"
 
diff --git a/libavcodec/h261dec.c b/libavcodec/h261dec.c
index 9bd6b20..eebfd02 100644
--- a/libavcodec/h261dec.c
+++ b/libavcodec/h261dec.c
@@ -26,7 +26,6 @@
  */
 
 #include "libavutil/avassert.h"
-#include "dsputil.h"
 #include "avcodec.h"
 #include "mpegvideo.h"
 #include "h263.h"
@@ -48,7 +47,7 @@
 static VLC h261_mv_vlc;
 static VLC h261_cbp_vlc;
 
-static int h261_decode_block(H261Context * h, DCTELEM * block, int n, int coded);
+static int h261_decode_block(H261Context * h, int16_t * block, int n, int coded);
 
 static av_cold void h261_decode_init_vlc(H261Context *h){
     static int done = 0;
@@ -366,7 +365,7 @@
  * Decode a macroblock.
  * @return <0 if an error occurred
  */
-static int h261_decode_block(H261Context * h, DCTELEM * block,
+static int h261_decode_block(H261Context * h, int16_t * block,
                              int n, int coded)
 {
     MpegEncContext * const s = &h->s;
@@ -551,7 +550,7 @@
 }
 
 static int h261_decode_frame(AVCodecContext *avctx,
-                             void *data, int *data_size,
+                             void *data, int *got_frame,
                              AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
@@ -617,7 +616,7 @@
     if(ff_MPV_frame_start(s, avctx) < 0)
         return -1;
 
-    ff_er_frame_start(s);
+    ff_mpeg_er_frame_start(s);
 
     /* decode each macroblock */
     s->mb_x=0;
@@ -636,7 +635,7 @@
     *pict = s->current_picture_ptr->f;
     ff_print_debug_info(s, pict);
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
 
     return get_consumed_bytes(s, buf_size);
 }
diff --git a/libavcodec/h261enc.c b/libavcodec/h261enc.c
index 29bee5d..c22100c 100644
--- a/libavcodec/h261enc.c
+++ b/libavcodec/h261enc.c
@@ -26,7 +26,6 @@
  */
 
 #include "libavutil/avassert.h"
-#include "dsputil.h"
 #include "avcodec.h"
 #include "mpegvideo.h"
 #include "h263.h"
@@ -35,7 +34,7 @@
 
 extern uint8_t ff_h261_rl_table_store[2][2*MAX_RUN + MAX_LEVEL + 3];
 
-static void h261_encode_block(H261Context * h, DCTELEM * block,
+static void h261_encode_block(H261Context * h, int16_t * block,
                               int n);
 
 int ff_h261_get_picture_format(int width, int height){
@@ -144,7 +143,7 @@
 }
 
 static inline int get_cbp(MpegEncContext * s,
-                      DCTELEM block[6][64])
+                      int16_t block[6][64])
 {
     int i, cbp;
     cbp= 0;
@@ -155,7 +154,7 @@
     return cbp;
 }
 void ff_h261_encode_mb(MpegEncContext * s,
-         DCTELEM block[6][64],
+         int16_t block[6][64],
          int motion_x, int motion_y)
 {
     H261Context * h = (H261Context *)s;
@@ -256,7 +255,7 @@
  * @param block the 8x8 block
  * @param n block index (0-3 are luma, 4-5 are chroma)
  */
-static void h261_encode_block(H261Context * h, DCTELEM * block, int n){
+static void h261_encode_block(H261Context * h, int16_t * block, int n){
     MpegEncContext * const s = &h->s;
     int level, run, i, j, last_index, last_non_zero, sign, slevel, code;
     RLTable *rl;
diff --git a/libavcodec/h263.c b/libavcodec/h263.c
index 5b77106..a7e60ea 100644
--- a/libavcodec/h263.c
+++ b/libavcodec/h263.c
@@ -30,7 +30,6 @@
 //#define DEBUG
 #include <limits.h>
 
-#include "dsputil.h"
 #include "avcodec.h"
 #include "mpegvideo.h"
 #include "h263.h"
@@ -226,7 +225,7 @@
     }
 }
 
-void ff_h263_pred_acdc(MpegEncContext * s, DCTELEM *block, int n)
+void ff_h263_pred_acdc(MpegEncContext * s, int16_t *block, int n)
 {
     int x, y, wrap, a, c, pred_dc, scale, i;
     int16_t *dc_val, *ac_val, *ac_val1;
diff --git a/libavcodec/h263.h b/libavcodec/h263.h
index a8d266d..a95cfb0 100644
--- a/libavcodec/h263.h
+++ b/libavcodec/h263.h
@@ -64,23 +64,25 @@
 
 extern uint8_t ff_h263_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3];
 
+extern const enum AVPixelFormat ff_h263_hwaccel_pixfmt_list_420[];
+
 
 int ff_h263_decode_motion(MpegEncContext * s, int pred, int f_code);
 av_const int ff_h263_aspect_to_info(AVRational aspect);
 int ff_h263_decode_init(AVCodecContext *avctx);
 int ff_h263_decode_frame(AVCodecContext *avctx,
-                             void *data, int *data_size,
+                             void *data, int *got_frame,
                              AVPacket *avpkt);
 int ff_h263_decode_end(AVCodecContext *avctx);
 void ff_h263_encode_mb(MpegEncContext *s,
-                       DCTELEM block[6][64],
+                       int16_t block[6][64],
                        int motion_x, int motion_y);
 void ff_h263_encode_picture_header(MpegEncContext *s, int picture_number);
 void ff_h263_encode_gob_header(MpegEncContext * s, int mb_line);
 int16_t *ff_h263_pred_motion(MpegEncContext * s, int block, int dir,
                              int *px, int *py);
 void ff_h263_encode_init(MpegEncContext *s);
-void ff_h263_decode_init_vlc(MpegEncContext *s);
+void ff_h263_decode_init_vlc(void);
 int ff_h263_decode_picture_header(MpegEncContext *s);
 int ff_h263_decode_gob_header(MpegEncContext *s);
 void ff_h263_update_motion_val(MpegEncContext * s);
@@ -89,7 +91,7 @@
 void ff_h263_encode_mba(MpegEncContext *s);
 void ff_init_qscale_tab(MpegEncContext *s);
 int ff_h263_pred_dc(MpegEncContext * s, int n, int16_t **dc_val_ptr);
-void ff_h263_pred_acdc(MpegEncContext * s, DCTELEM *block, int n);
+void ff_h263_pred_acdc(MpegEncContext * s, int16_t *block, int n);
 
 
 /**
@@ -99,7 +101,7 @@
 
 int ff_intel_h263_decode_picture_header(MpegEncContext *s);
 int ff_h263_decode_mb(MpegEncContext *s,
-                      DCTELEM block[6][64]);
+                      int16_t block[6][64]);
 
 /**
  * Return the value of the 3bit "source format" syntax element.
@@ -144,7 +146,7 @@
 }
 
 static inline int get_p_cbp(MpegEncContext * s,
-                      DCTELEM block[6][64],
+                      int16_t block[6][64],
                       int motion_x, int motion_y){
     int cbp, i;
 
diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c
index 3fff1d6..72138e1 100644
--- a/libavcodec/h263dec.c
+++ b/libavcodec/h263dec.c
@@ -28,7 +28,6 @@
 #include "libavutil/cpu.h"
 #include "internal.h"
 #include "avcodec.h"
-#include "dsputil.h"
 #include "mpegvideo.h"
 #include "h263.h"
 #include "h263_parser.h"
@@ -119,7 +118,7 @@
         if ((ret = ff_MPV_common_init(s)) < 0)
             return ret;
 
-        ff_h263_decode_init_vlc(s);
+        ff_h263_decode_init_vlc();
 
     return 0;
 }
@@ -192,7 +191,7 @@
         /* per-row end of slice checks */
         if(s->msmpeg4_version){
             if(s->resync_mb_y + s->slice_height == s->mb_y){
-                ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_END);
+                ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_END);
 
                 return 0;
             }
@@ -233,24 +232,24 @@
                     if(s->loop_filter)
                         ff_h263_loop_filter(s);
 
-                    ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_MB_END&part_mask);
+                    ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_MB_END&part_mask);
 
                     s->padding_bug_score--;
 
                     if(++s->mb_x >= s->mb_width){
                         s->mb_x=0;
-                        ff_draw_horiz_band(s, s->mb_y*mb_size, mb_size);
+                        ff_mpeg_draw_horiz_band(s, s->mb_y*mb_size, mb_size);
                         ff_MPV_report_decode_progress(s);
                         s->mb_y++;
                     }
                     return 0;
                 }else if(ret==SLICE_NOEND){
                     av_log(s->avctx, AV_LOG_ERROR, "Slice mismatch at MB: %d\n", xy);
-                    ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x+1, s->mb_y, ER_MB_END&part_mask);
+                    ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x+1, s->mb_y, ER_MB_END&part_mask);
                     return AVERROR_INVALIDDATA;
                 }
                 av_log(s->avctx, AV_LOG_ERROR, "Error at MB: %d\n", xy);
-                ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR&part_mask);
+                ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR&part_mask);
 
                 return AVERROR_INVALIDDATA;
             }
@@ -260,7 +259,7 @@
                 ff_h263_loop_filter(s);
         }
 
-        ff_draw_horiz_band(s, s->mb_y*mb_size, mb_size);
+        ff_mpeg_draw_horiz_band(s, s->mb_y*mb_size, mb_size);
         ff_MPV_report_decode_progress(s);
 
         s->mb_x= 0;
@@ -329,7 +328,7 @@
         else if(left<0){
             av_log(s->avctx, AV_LOG_ERROR, "overreading %d bits\n", -left);
         }else
-            ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_END);
+            ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_END);
 
         return 0;
     }
@@ -338,13 +337,13 @@
             get_bits_left(&s->gb),
             show_bits(&s->gb, 24), s->padding_bug_score);
 
-    ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_MB_END&part_mask);
+    ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_MB_END&part_mask);
 
     return AVERROR_INVALIDDATA;
 }
 
 int ff_h263_decode_frame(AVCodecContext *avctx,
-                             void *data, int *data_size,
+                             void *data, int *got_frame,
                              AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
@@ -366,7 +365,7 @@
             *pict = s->next_picture_ptr->f;
             s->next_picture_ptr= NULL;
 
-            *data_size = sizeof(AVFrame);
+            *got_frame = 1;
         }
 
         return 0;
@@ -467,7 +466,7 @@
     if(s->xvid_build==-1 && s->divx_version==-1 && s->lavc_build==-1){
         if(s->stream_codec_tag == AV_RL32("XVID") ||
            s->codec_tag == AV_RL32("XVID") || s->codec_tag == AV_RL32("XVIX") ||
-           s->codec_tag == AV_RL32("RMP4") ||
+           s->codec_tag == AV_RL32("RMP4") || s->codec_tag == AV_RL32("ZMP4") ||
            s->codec_tag == AV_RL32("SIPP")
            )
             s->xvid_build= 0;
@@ -626,7 +625,9 @@
     s->current_picture.f.key_frame = s->pict_type == AV_PICTURE_TYPE_I;
 
     /* skip B-frames if we don't have reference frames */
-    if(s->last_picture_ptr==NULL && (s->pict_type==AV_PICTURE_TYPE_B || s->dropable)) return get_consumed_bytes(s, buf_size);
+    if (s->last_picture_ptr == NULL &&
+        (s->pict_type == AV_PICTURE_TYPE_B || s->droppable))
+        return get_consumed_bytes(s, buf_size);
     if(   (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type==AV_PICTURE_TYPE_B)
        || (avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type!=AV_PICTURE_TYPE_I)
        ||  avctx->skip_frame >= AVDISCARD_ALL)
@@ -639,10 +640,7 @@
             s->next_p_frame_damaged=0;
     }
 
-    if((s->avctx->flags2 & CODEC_FLAG2_FAST) && s->pict_type==AV_PICTURE_TYPE_B){
-        s->me.qpel_put= s->dsp.put_2tap_qpel_pixels_tab;
-        s->me.qpel_avg= s->dsp.avg_2tap_qpel_pixels_tab;
-    }else if((!s->no_rounding) || s->pict_type==AV_PICTURE_TYPE_B){
+    if((!s->no_rounding) || s->pict_type==AV_PICTURE_TYPE_B){
         s->me.qpel_put= s->dsp.put_qpel_pixels_tab;
         s->me.qpel_avg= s->dsp.avg_qpel_pixels_tab;
     }else{
@@ -665,7 +663,7 @@
             return ret;
     }
 
-    ff_er_frame_start(s);
+    ff_mpeg_er_frame_start(s);
 
     //the second part of the wmv2 header contains the MB skip bits which are stored in current_picture->mb_type
     //which is not available before ff_MPV_frame_start()
@@ -689,7 +687,7 @@
             if(ff_h263_resync(s)<0)
                 break;
             if (prev_y * s->mb_width + prev_x < s->mb_y * s->mb_width + s->mb_x)
-                s->error_occurred = 1;
+                s->er.error_occurred = 1;
         }
 
         if(s->msmpeg4_version<4 && s->h263_pred)
@@ -700,12 +698,12 @@
 
     if (s->msmpeg4_version && s->msmpeg4_version<4 && s->pict_type==AV_PICTURE_TYPE_I)
         if(!CONFIG_MSMPEG4_DECODER || ff_msmpeg4_decode_ext_header(s, buf_size) < 0){
-            s->error_status_table[s->mb_num-1]= ER_MB_ERROR;
+            s->er.error_status_table[s->mb_num - 1] = ER_MB_ERROR;
         }
 
     av_assert1(s->bitstream_buffer_size==0);
 frame_end:
-    /* divx 5.01+ bistream reorder stuff */
+    /* divx 5.01+ bitstream reorder stuff */
     if(s->codec_id==AV_CODEC_ID_MPEG4 && s->divx_packed){
         int current_pos= s->gb.buffer == s->bitstream_buffer ? 0 : (get_bits_count(&s->gb)>>3);
         int startcode_found=0;
@@ -733,7 +731,7 @@
     }
 
 intrax8_decoded:
-    ff_er_frame_end(s);
+    ff_er_frame_end(&s->er);
 
     if (avctx->hwaccel) {
         if ((ret = avctx->hwaccel->end_frame(avctx)) < 0)
@@ -751,7 +749,7 @@
     }
 
     if(s->last_picture_ptr || s->low_delay){
-        *data_size = sizeof(AVFrame);
+        *got_frame = 1;
         ff_print_debug_info(s, pict);
     }
 
@@ -762,6 +760,17 @@
     return (ret && (avctx->err_recognition & AV_EF_EXPLODE))?ret:get_consumed_bytes(s, buf_size);
 }
 
+const enum AVPixelFormat ff_h263_hwaccel_pixfmt_list_420[] = {
+#if CONFIG_VAAPI
+    AV_PIX_FMT_VAAPI_VLD,
+#endif
+#if CONFIG_VDPAU
+    AV_PIX_FMT_VDPAU,
+#endif
+    AV_PIX_FMT_YUV420P,
+    AV_PIX_FMT_NONE
+};
+
 AVCodec ff_h263_decoder = {
     .name           = "h263",
     .type           = AVMEDIA_TYPE_VIDEO,
@@ -775,7 +784,7 @@
     .flush          = ff_mpeg_flush,
     .max_lowres     = 3,
     .long_name      = NULL_IF_CONFIG_SMALL("H.263 / H.263-1996, H.263+ / H.263-1998 / H.263 version 2"),
-    .pix_fmts       = ff_hwaccel_pixfmt_list_420,
+    .pix_fmts       = ff_h263_hwaccel_pixfmt_list_420,
 };
 
 AVCodec ff_h263p_decoder = {
@@ -791,5 +800,5 @@
     .flush          = ff_mpeg_flush,
     .max_lowres     = 3,
     .long_name      = NULL_IF_CONFIG_SMALL("H.263 / H.263-1996, H.263+ / H.263-1998 / H.263 version 2"),
-    .pix_fmts       = ff_hwaccel_pixfmt_list_420,
+    .pix_fmts       = ff_h263_hwaccel_pixfmt_list_420,
 };
diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index f9b8fc1..f88b5a8 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -35,10 +35,12 @@
 #include "mpegvideo.h"
 #include "h264.h"
 #include "h264data.h"
+#include "h264chroma.h"
 #include "h264_mvpred.h"
 #include "golomb.h"
 #include "mathops.h"
 #include "rectangle.h"
+#include "svq3.h"
 #include "thread.h"
 #include "vdpau_internal.h"
 #include "libavutil/avassert.h"
@@ -64,10 +66,36 @@
    14,14,14,14,
 };
 
-static const enum AVPixelFormat hwaccel_pixfmt_list_h264_jpeg_420[] = {
+static const enum AVPixelFormat hwaccel_pixfmt_list_h264_420[] = {
+#if CONFIG_H264_DXVA2_HWACCEL
     AV_PIX_FMT_DXVA2_VLD,
+#endif
+#if CONFIG_H264_VAAPI_HWACCEL
     AV_PIX_FMT_VAAPI_VLD,
+#endif
+#if CONFIG_H264_VDA_HWACCEL
     AV_PIX_FMT_VDA_VLD,
+#endif
+#if CONFIG_H264_VDPAU_HWACCEL
+    AV_PIX_FMT_VDPAU,
+#endif
+    AV_PIX_FMT_YUV420P,
+    AV_PIX_FMT_NONE
+};
+
+static const enum AVPixelFormat hwaccel_pixfmt_list_h264_jpeg_420[] = {
+#if CONFIG_H264_DXVA2_HWACCEL
+    AV_PIX_FMT_DXVA2_VLD,
+#endif
+#if CONFIG_H264_VAAPI_HWACCEL
+    AV_PIX_FMT_VAAPI_VLD,
+#endif
+#if CONFIG_H264_VDA_HWACCEL
+    AV_PIX_FMT_VDA_VLD,
+#endif
+#if CONFIG_H264_VDPAU_HWACCEL
+    AV_PIX_FMT_VDPAU,
+#endif
     AV_PIX_FMT_YUVJ420P,
     AV_PIX_FMT_NONE
 };
@@ -78,13 +106,210 @@
     return h ? h->sps.num_reorder_frames : 0;
 }
 
+static void h264_er_decode_mb(void *opaque, int ref, int mv_dir, int mv_type,
+                              int (*mv)[2][4][2],
+                              int mb_x, int mb_y, int mb_intra, int mb_skipped)
+{
+    H264Context    *h = opaque;
+
+    h->mb_x  = mb_x;
+    h->mb_y  = mb_y;
+    h->mb_xy = mb_x + mb_y * h->mb_stride;
+    memset(h->non_zero_count_cache, 0, sizeof(h->non_zero_count_cache));
+    av_assert1(ref >= 0);
+    /* FIXME: It is possible albeit uncommon that slice references
+     * differ between slices. We take the easy approach and ignore
+     * it for now. If this turns out to have any relevance in
+     * practice then correct remapping should be added. */
+    if (ref >= h->ref_count[0])
+        ref = 0;
+    if (!h->ref_list[0][ref].f.data[0]) {
+        av_log(h->avctx, AV_LOG_DEBUG, "Reference not available for error concealing\n");
+        ref = 0;
+    }
+    if ((h->ref_list[0][ref].f.reference&3) != 3) {
+        av_log(h->avctx, AV_LOG_DEBUG, "Reference invalid\n");
+        return;
+    }
+    fill_rectangle(&h->cur_pic.f.ref_index[0][4 * h->mb_xy],
+                   2, 2, 2, ref, 1);
+    fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, ref, 1);
+    fill_rectangle(h->mv_cache[0][scan8[0]], 4, 4, 8,
+                   pack16to32((*mv)[0][0][0], (*mv)[0][0][1]), 4);
+    h->mb_mbaff =
+    h->mb_field_decoding_flag = 0;
+    ff_h264_hl_decode_mb(h);
+}
+
+void ff_h264_draw_horiz_band(H264Context *h, int y, int height)
+{
+    ff_draw_horiz_band(h->avctx, NULL, &h->cur_pic,
+                       h->ref_list[0][0].f.data[0] ? &h->ref_list[0][0] : NULL,
+                       y, height, h->picture_structure, h->first_field, 0,
+                       h->low_delay, h->mb_height * 16, h->mb_width * 16);
+}
+
+static void free_frame_buffer(H264Context *h, Picture *pic)
+{
+    pic->period_since_free = 0;
+    ff_thread_release_buffer(h->avctx, &pic->f);
+    av_freep(&pic->f.hwaccel_picture_private);
+}
+
+static void free_picture(H264Context *h, Picture *pic)
+{
+    int i;
+
+    if (pic->f.data[0])
+        free_frame_buffer(h, pic);
+
+    av_freep(&pic->qscale_table_base);
+    pic->f.qscale_table = NULL;
+    av_freep(&pic->mb_type_base);
+    pic->f.mb_type = NULL;
+    for (i = 0; i < 2; i++) {
+        av_freep(&pic->motion_val_base[i]);
+        av_freep(&pic->f.ref_index[i]);
+        pic->f.motion_val[i] = NULL;
+    }
+}
+
+static void release_unused_pictures(H264Context *h, int remove_current)
+{
+    int i;
+
+    /* release non reference frames */
+    for (i = 0; i < h->picture_count; i++) {
+        if (h->DPB[i].f.data[0] && !h->DPB[i].f.reference &&
+            (!h->DPB[i].owner2 || h->DPB[i].owner2 == h) &&
+            (remove_current || &h->DPB[i] != h->cur_pic_ptr)) {
+            free_frame_buffer(h, &h->DPB[i]);
+        }
+    }
+}
+
+static int alloc_scratch_buffers(H264Context *h, int linesize)
+{
+    int alloc_size = FFALIGN(FFABS(linesize) + 32, 32);
+
+    if (h->bipred_scratchpad)
+        return 0;
+
+    h->bipred_scratchpad = av_malloc(16 * 6 * alloc_size);
+    // edge emu needs blocksize + filter length - 1
+    // (= 21x21 for  h264)
+    h->edge_emu_buffer = av_mallocz(alloc_size * 2 * 21);
+    h->me.scratchpad   = av_mallocz(alloc_size * 2 * 16 * 2);
+
+    if (!h->bipred_scratchpad || !h->edge_emu_buffer || !h->me.scratchpad) {
+        av_freep(&h->bipred_scratchpad);
+        av_freep(&h->edge_emu_buffer);
+        av_freep(&h->me.scratchpad);
+        return AVERROR(ENOMEM);
+    }
+
+    h->me.temp = h->me.scratchpad;
+
+    return 0;
+}
+
+static int alloc_picture(H264Context *h, Picture *pic)
+{
+    const int big_mb_num    = h->mb_stride * (h->mb_height + 1) + 1;
+    const int mb_array_size = h->mb_stride * h->mb_height;
+    const int b4_stride     = h->mb_width * 4 + 1;
+    const int b4_array_size = b4_stride * h->mb_height * 4;
+    int i, ret = 0;
+
+    av_assert0(!pic->f.data[0]);
+
+    if (h->avctx->hwaccel) {
+        const AVHWAccel *hwaccel = h->avctx->hwaccel;
+        av_assert0(!pic->f.hwaccel_picture_private);
+        if (hwaccel->priv_data_size) {
+            pic->f.hwaccel_picture_private = av_mallocz(hwaccel->priv_data_size);
+            if (!pic->f.hwaccel_picture_private)
+                return AVERROR(ENOMEM);
+        }
+    }
+    ret = ff_thread_get_buffer(h->avctx, &pic->f);
+    if (ret < 0)
+        goto fail;
+
+    h->linesize   = pic->f.linesize[0];
+    h->uvlinesize = pic->f.linesize[1];
+
+    if (pic->f.qscale_table == NULL) {
+        FF_ALLOCZ_OR_GOTO(h->avctx, pic->qscale_table_base,
+                          (big_mb_num + h->mb_stride) * sizeof(uint8_t),
+                          fail)
+        FF_ALLOCZ_OR_GOTO(h->avctx, pic->mb_type_base,
+                          (big_mb_num + h->mb_stride) * sizeof(uint32_t),
+                          fail)
+        pic->f.mb_type = pic->mb_type_base + 2 * h->mb_stride + 1;
+        pic->f.qscale_table = pic->qscale_table_base + 2 * h->mb_stride + 1;
+
+        for (i = 0; i < 2; i++) {
+            FF_ALLOCZ_OR_GOTO(h->avctx, pic->motion_val_base[i],
+                              2 * (b4_array_size + 4) * sizeof(int16_t),
+                              fail)
+            pic->f.motion_val[i] = pic->motion_val_base[i] + 4;
+            FF_ALLOCZ_OR_GOTO(h->avctx, pic->f.ref_index[i],
+                              4 * mb_array_size * sizeof(uint8_t), fail)
+        }
+        pic->f.motion_subsample_log2 = 2;
+
+        pic->f.qstride = h->mb_stride;
+    }
+
+    pic->owner2 = h;
+
+    return 0;
+fail:
+    free_frame_buffer(h, pic);
+    return (ret < 0) ? ret : AVERROR(ENOMEM);
+}
+
+static inline int pic_is_unused(H264Context *h, Picture *pic)
+{
+    if (   (h->avctx->active_thread_type & FF_THREAD_FRAME)
+        && pic->f.qscale_table //check if the frame has anything allocated
+        && pic->period_since_free < h->avctx->thread_count)
+        return 0;
+    if (pic->f.data[0] == NULL)
+        return 1;
+    if (pic->needs_realloc && !(pic->f.reference & DELAYED_PIC_REF))
+        if (!pic->owner2 || pic->owner2 == h)
+            return 1;
+    return 0;
+}
+
+static int find_unused_picture(H264Context *h)
+{
+    int i;
+
+    for (i = h->picture_range_start; i < h->picture_range_end; i++) {
+        if (pic_is_unused(h, &h->DPB[i]))
+            break;
+    }
+    if (i == h->picture_range_end)
+        return AVERROR_INVALIDDATA;
+
+    if (h->DPB[i].needs_realloc) {
+        h->DPB[i].needs_realloc = 0;
+        free_picture(h, &h->DPB[i]);
+        avcodec_get_frame_defaults(&h->DPB[i].f);
+    }
+
+    return i;
+}
+
 /**
  * Check if the top & left blocks are available if needed and
  * change the dc mode so it only uses the available blocks.
  */
 int ff_h264_check_intra4x4_pred_mode(H264Context *h)
 {
-    MpegEncContext *const s     = &h->s;
     static const int8_t top[12] = {
         -1, 0, LEFT_DC_PRED, -1, -1, -1, -1, -1, 0
     };
@@ -97,9 +322,9 @@
         for (i = 0; i < 4; i++) {
             int status = top[h->intra4x4_pred_mode_cache[scan8[0] + i]];
             if (status < 0) {
-                av_log(h->s.avctx, AV_LOG_ERROR,
+                av_log(h->avctx, AV_LOG_ERROR,
                        "top block unavailable for requested intra4x4 mode %d at %d %d\n",
-                       status, s->mb_x, s->mb_y);
+                       status, h->mb_x, h->mb_y);
                 return -1;
             } else if (status) {
                 h->intra4x4_pred_mode_cache[scan8[0] + i] = status;
@@ -113,9 +338,9 @@
             if (!(h->left_samples_available & mask[i])) {
                 int status = left[h->intra4x4_pred_mode_cache[scan8[0] + 8 * i]];
                 if (status < 0) {
-                    av_log(h->s.avctx, AV_LOG_ERROR,
+                    av_log(h->avctx, AV_LOG_ERROR,
                            "left block unavailable for requested intra4x4 mode %d at %d %d\n",
-                           status, s->mb_x, s->mb_y);
+                           status, h->mb_x, h->mb_y);
                     return -1;
                 } else if (status) {
                     h->intra4x4_pred_mode_cache[scan8[0] + 8 * i] = status;
@@ -132,23 +357,22 @@
  */
 int ff_h264_check_intra_pred_mode(H264Context *h, int mode, int is_chroma)
 {
-    MpegEncContext *const s     = &h->s;
     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 };
 
     if (mode > 6U) {
-        av_log(h->s.avctx, AV_LOG_ERROR,
+        av_log(h->avctx, AV_LOG_ERROR,
                "out of range intra chroma pred mode at %d %d\n",
-               s->mb_x, s->mb_y);
+               h->mb_x, h->mb_y);
         return -1;
     }
 
     if (!(h->top_samples_available & 0x8000)) {
         mode = top[mode];
         if (mode < 0) {
-            av_log(h->s.avctx, AV_LOG_ERROR,
+            av_log(h->avctx, AV_LOG_ERROR,
                    "top block unavailable for requested intra mode at %d %d\n",
-                   s->mb_x, s->mb_y);
+                   h->mb_x, h->mb_y);
             return -1;
         }
     }
@@ -162,9 +386,9 @@
                    2 * (mode == DC_128_PRED8x8);
         }
         if (mode < 0) {
-            av_log(h->s.avctx, AV_LOG_ERROR,
+            av_log(h->avctx, AV_LOG_ERROR,
                    "left block unavailable for requested intra mode at %d %d\n",
-                   s->mb_x, s->mb_y);
+                   h->mb_x, h->mb_y);
             return -1;
         }
     }
@@ -244,7 +468,7 @@
     if(i>=length-1){ //no escaped 0
         *dst_length= length;
         *consumed= length+1; //+1 for the header
-        if(h->s.avctx->flags2 & CODEC_FLAG2_FAST){
+        if(h->avctx->flags2 & CODEC_FLAG2_FAST){
             return src;
         }else{
             memcpy(dst, src, length);
@@ -293,7 +517,7 @@
     int v = *src;
     int r;
 
-    tprintf(h->s.avctx, "rbsp trailing %X\n", v);
+    tprintf(h->avctx, "rbsp trailing %X\n", v);
 
     for (r = 1; r < 9; r++) {
         if (v & 1)
@@ -307,22 +531,22 @@
                                          int height, int y_offset, int list)
 {
     int raw_my        = h->mv_cache[list][scan8[n]][1];
-    int filter_height = (raw_my & 3) ? 2 : 0;
+    int filter_height_down = (raw_my & 3) ? 3 : 0;
     int full_my       = (raw_my >> 2) + y_offset;
-    int top           = full_my - filter_height;
-    int bottom        = full_my + filter_height + height;
+    int bottom        = full_my + filter_height_down + height;
 
-    return FFMAX(abs(top), bottom);
+    av_assert2(height >= 0);
+
+    return FFMAX(0, bottom);
 }
 
 static inline void get_lowest_part_y(H264Context *h, int refs[2][48], int n,
                                      int height, int y_offset, int list0,
                                      int list1, int *nrefs)
 {
-    MpegEncContext *const s = &h->s;
     int my;
 
-    y_offset += 16 * (s->mb_y >> MB_FIELD);
+    y_offset += 16 * (h->mb_y >> MB_FIELD);
 
     if (list0) {
         int ref_n    = h->ref_cache[0][scan8[n]];
@@ -331,8 +555,8 @@
         // 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->f.thread_opaque   != s->current_picture.f.thread_opaque ||
-            (ref->f.reference & 3) != s->picture_structure) {
+        if (ref->f.thread_opaque   != h->cur_pic.f.thread_opaque ||
+            (ref->f.reference & 3) != h->picture_structure) {
             my = get_lowest_part_list_y(h, ref, n, height, y_offset, 0);
             if (refs[0][ref_n] < 0)
                 nrefs[0] += 1;
@@ -344,8 +568,8 @@
         int ref_n    = h->ref_cache[1][scan8[n]];
         Picture *ref = &h->ref_list[1][ref_n];
 
-        if (ref->f.thread_opaque   != s->current_picture.f.thread_opaque ||
-            (ref->f.reference & 3) != s->picture_structure) {
+        if (ref->f.thread_opaque   != h->cur_pic.f.thread_opaque ||
+            (ref->f.reference & 3) != h->picture_structure) {
             my = get_lowest_part_list_y(h, ref, n, height, y_offset, 1);
             if (refs[1][ref_n] < 0)
                 nrefs[1] += 1;
@@ -361,9 +585,8 @@
  */
 static void await_references(H264Context *h)
 {
-    MpegEncContext *const s = &h->s;
     const int mb_xy   = h->mb_xy;
-    const int mb_type = s->current_picture.f.mb_type[mb_xy];
+    const int mb_type = h->cur_pic.f.mb_type[mb_xy];
     int refs[2][48];
     int nrefs[2] = { 0 };
     int ref, list;
@@ -437,7 +660,7 @@
                 Picture *ref_pic      = &h->ref_list[list][ref];
                 int ref_field         = ref_pic->f.reference - 1;
                 int ref_field_picture = ref_pic->field_picture;
-                int pic_height        = 16 * s->mb_height >> ref_field_picture;
+                int pic_height        = 16 * h->mb_height >> ref_field_picture;
 
                 row <<= MB_MBAFF;
                 nrefs[list]--;
@@ -478,20 +701,19 @@
                                          h264_chroma_mc_func chroma_op,
                                          int pixel_shift, int chroma_idc)
 {
-    MpegEncContext *const s = &h->s;
     const int mx      = h->mv_cache[list][scan8[n]][0] + src_x_offset * 8;
     int my            = h->mv_cache[list][scan8[n]][1] + src_y_offset * 8;
     const int luma_xy = (mx & 3) + ((my & 3) << 2);
     int offset        = ((mx >> 2) << pixel_shift) + (my >> 2) * h->mb_linesize;
     uint8_t *src_y    = pic->f.data[0] + offset;
     uint8_t *src_cb, *src_cr;
-    int extra_width  = h->emu_edge_width;
-    int extra_height = h->emu_edge_height;
+    int extra_width  = 0;
+    int extra_height = 0;
     int emu = 0;
     const int full_mx    = mx >> 2;
     const int full_my    = my >> 2;
-    const int pic_width  = 16 * s->mb_width;
-    const int pic_height = 16 * s->mb_height >> MB_FIELD;
+    const int pic_width  = 16 * h->mb_width;
+    const int pic_height = 16 * h->mb_height >> MB_FIELD;
     int ysh;
 
     if (mx & 7)
@@ -503,12 +725,12 @@
         full_my                <          0 - extra_height ||
         full_mx + 16 /*FIXME*/ > pic_width  + extra_width  ||
         full_my + 16 /*FIXME*/ > pic_height + extra_height) {
-        s->dsp.emulated_edge_mc(s->edge_emu_buffer,
-                                src_y - (2 << pixel_shift) - 2 * h->mb_linesize,
-                                h->mb_linesize,
-                                16 + 5, 16 + 5 /*FIXME*/, full_mx - 2,
-                                full_my - 2, pic_width, pic_height);
-        src_y = s->edge_emu_buffer + (2 << pixel_shift) + 2 * h->mb_linesize;
+        h->vdsp.emulated_edge_mc(h->edge_emu_buffer,
+                                 src_y - (2 << pixel_shift) - 2 * h->mb_linesize,
+                                 h->mb_linesize,
+                                 16 + 5, 16 + 5 /*FIXME*/, full_mx - 2,
+                                 full_my - 2, pic_width, pic_height);
+        src_y = h->edge_emu_buffer + (2 << pixel_shift) + 2 * h->mb_linesize;
         emu   = 1;
     }
 
@@ -516,19 +738,19 @@
     if (!square)
         qpix_op[luma_xy](dest_y + delta, src_y + delta, h->mb_linesize);
 
-    if (CONFIG_GRAY && s->flags & CODEC_FLAG_GRAY)
+    if (CONFIG_GRAY && h->flags & CODEC_FLAG_GRAY)
         return;
 
     if (chroma_idc == 3 /* yuv444 */) {
         src_cb = pic->f.data[1] + offset;
         if (emu) {
-            s->dsp.emulated_edge_mc(s->edge_emu_buffer,
-                                    src_cb - (2 << pixel_shift) - 2 * h->mb_linesize,
-                                    h->mb_linesize,
-                                    16 + 5, 16 + 5 /*FIXME*/,
-                                    full_mx - 2, full_my - 2,
-                                    pic_width, pic_height);
-            src_cb = s->edge_emu_buffer + (2 << pixel_shift) + 2 * h->mb_linesize;
+            h->vdsp.emulated_edge_mc(h->edge_emu_buffer,
+                                     src_cb - (2 << pixel_shift) - 2 * h->mb_linesize,
+                                     h->mb_linesize,
+                                     16 + 5, 16 + 5 /*FIXME*/,
+                                     full_mx - 2, full_my - 2,
+                                     pic_width, pic_height);
+            src_cb = h->edge_emu_buffer + (2 << pixel_shift) + 2 * h->mb_linesize;
         }
         qpix_op[luma_xy](dest_cb, src_cb, h->mb_linesize); // FIXME try variable height perhaps?
         if (!square)
@@ -536,13 +758,13 @@
 
         src_cr = pic->f.data[2] + offset;
         if (emu) {
-            s->dsp.emulated_edge_mc(s->edge_emu_buffer,
-                                    src_cr - (2 << pixel_shift) - 2 * h->mb_linesize,
-                                    h->mb_linesize,
-                                    16 + 5, 16 + 5 /*FIXME*/,
-                                    full_mx - 2, full_my - 2,
-                                    pic_width, pic_height);
-            src_cr = s->edge_emu_buffer + (2 << pixel_shift) + 2 * h->mb_linesize;
+            h->vdsp.emulated_edge_mc(h->edge_emu_buffer,
+                                     src_cr - (2 << pixel_shift) - 2 * h->mb_linesize,
+                                     h->mb_linesize,
+                                     16 + 5, 16 + 5 /*FIXME*/,
+                                     full_mx - 2, full_my - 2,
+                                     pic_width, pic_height);
+            src_cr = h->edge_emu_buffer + (2 << pixel_shift) + 2 * h->mb_linesize;
         }
         qpix_op[luma_xy](dest_cr, src_cr, h->mb_linesize); // FIXME try variable height perhaps?
         if (!square)
@@ -553,7 +775,7 @@
     ysh = 3 - (chroma_idc == 2 /* yuv422 */);
     if (chroma_idc == 1 /* yuv420 */ && MB_FIELD) {
         // chroma offset when predicting from a field of opposite parity
-        my  += 2 * ((s->mb_y & 1) - (pic->f.reference - 1));
+        my  += 2 * ((h->mb_y & 1) - (pic->f.reference - 1));
         emu |= (my >> 3) < 0 || (my >> 3) + 8 >= (pic_height >> 1);
     }
 
@@ -563,20 +785,20 @@
              (my >> ysh) * h->mb_uvlinesize;
 
     if (emu) {
-        s->dsp.emulated_edge_mc(s->edge_emu_buffer, src_cb, h->mb_uvlinesize,
-                                9, 8 * chroma_idc + 1, (mx >> 3), (my >> ysh),
-                                pic_width >> 1, pic_height >> (chroma_idc == 1 /* yuv420 */));
-        src_cb = s->edge_emu_buffer;
+        h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cb, h->mb_uvlinesize,
+                                 9, 8 * chroma_idc + 1, (mx >> 3), (my >> ysh),
+                                 pic_width >> 1, pic_height >> (chroma_idc == 1 /* yuv420 */));
+        src_cb = h->edge_emu_buffer;
     }
     chroma_op(dest_cb, src_cb, h->mb_uvlinesize,
               height >> (chroma_idc == 1 /* yuv420 */),
               mx & 7, (my << (chroma_idc == 2 /* yuv422 */)) & 7);
 
     if (emu) {
-        s->dsp.emulated_edge_mc(s->edge_emu_buffer, src_cr, h->mb_uvlinesize,
-                                9, 8 * chroma_idc + 1, (mx >> 3), (my >> ysh),
-                                pic_width >> 1, pic_height >> (chroma_idc == 1 /* yuv420 */));
-        src_cr = s->edge_emu_buffer;
+        h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cr, h->mb_uvlinesize,
+                                 9, 8 * chroma_idc + 1, (mx >> 3), (my >> ysh),
+                                 pic_width >> 1, pic_height >> (chroma_idc == 1 /* yuv420 */));
+        src_cr = h->edge_emu_buffer;
     }
     chroma_op(dest_cr, src_cr, h->mb_uvlinesize, height >> (chroma_idc == 1 /* yuv420 */),
               mx & 7, (my << (chroma_idc == 2 /* yuv422 */)) & 7);
@@ -594,7 +816,6 @@
                                          int list0, int list1,
                                          int pixel_shift, int chroma_idc)
 {
-    MpegEncContext *const s       = &h->s;
     qpel_mc_func *qpix_op         = qpix_put;
     h264_chroma_mc_func chroma_op = chroma_put;
 
@@ -609,8 +830,8 @@
         dest_cb += (x_offset << pixel_shift) + y_offset * h->mb_uvlinesize;
         dest_cr += (x_offset << pixel_shift) + y_offset * h->mb_uvlinesize;
     }
-    x_offset += 8 * s->mb_x;
-    y_offset += 8 * (s->mb_y >> MB_FIELD);
+    x_offset += 8 * h->mb_x;
+    y_offset += 8 * (h->mb_y >> MB_FIELD);
 
     if (list0) {
         Picture *ref = &h->ref_list[0][h->ref_cache[0][scan8[n]]];
@@ -644,7 +865,6 @@
                                               int list0, int list1,
                                               int pixel_shift, int chroma_idc)
 {
-    MpegEncContext *const s = &h->s;
     int chroma_height;
 
     dest_y += (2 * x_offset << pixel_shift) + 2 * y_offset * h->mb_linesize;
@@ -663,15 +883,15 @@
         dest_cb      += (x_offset << pixel_shift) + y_offset * h->mb_uvlinesize;
         dest_cr      += (x_offset << pixel_shift) + y_offset * h->mb_uvlinesize;
     }
-    x_offset += 8 * s->mb_x;
-    y_offset += 8 * (s->mb_y >> MB_FIELD);
+    x_offset += 8 * h->mb_x;
+    y_offset += 8 * (h->mb_y >> MB_FIELD);
 
     if (list0 && list1) {
         /* don't optimize for luma-only case, since B-frames usually
          * use implicit weights => chroma too. */
-        uint8_t *tmp_cb = s->obmc_scratchpad;
-        uint8_t *tmp_cr = s->obmc_scratchpad + (16 << pixel_shift);
-        uint8_t *tmp_y  = s->obmc_scratchpad + 16 * h->mb_uvlinesize;
+        uint8_t *tmp_cb = h->bipred_scratchpad;
+        uint8_t *tmp_cr = h->bipred_scratchpad + (16 << pixel_shift);
+        uint8_t *tmp_y  = h->bipred_scratchpad + 16 * h->mb_uvlinesize;
         int refn0       = h->ref_cache[0][scan8[n]];
         int refn1       = h->ref_cache[1][scan8[n]];
 
@@ -685,7 +905,7 @@
                     pixel_shift, chroma_idc);
 
         if (h->use_weight == 2) {
-            int weight0 = h->implicit_weight[refn0][refn1][s->mb_y & 1];
+            int weight0 = h->implicit_weight[refn0][refn1][h->mb_y & 1];
             int weight1 = 64 - weight0;
             luma_weight_avg(dest_y, tmp_y, h->mb_linesize,
                             height, 5, weight0, weight1, 0);
@@ -743,22 +963,21 @@
 {
     /* fetch pixels for estimated mv 4 macroblocks ahead
      * optimized for 64byte cache lines */
-    MpegEncContext *const s = &h->s;
     const int refn = h->ref_cache[list][scan8[0]];
     if (refn >= 0) {
-        const int mx  = (h->mv_cache[list][scan8[0]][0] >> 2) + 16 * s->mb_x + 8;
-        const int my  = (h->mv_cache[list][scan8[0]][1] >> 2) + 16 * s->mb_y;
+        const int mx  = (h->mv_cache[list][scan8[0]][0] >> 2) + 16 * h->mb_x + 8;
+        const int my  = (h->mv_cache[list][scan8[0]][1] >> 2) + 16 * h->mb_y;
         uint8_t **src = h->ref_list[list][refn].f.data;
         int off       = (mx << pixel_shift) +
-                        (my + (s->mb_x & 3) * 4) * h->mb_linesize +
+                        (my + (h->mb_x & 3) * 4) * h->mb_linesize +
                         (64 << pixel_shift);
-        s->dsp.prefetch(src[0] + off, s->linesize, 4);
+        h->vdsp.prefetch(src[0] + off, h->linesize, 4);
         if (chroma_idc == 3 /* yuv444 */) {
-            s->dsp.prefetch(src[1] + off, s->linesize, 4);
-            s->dsp.prefetch(src[2] + off, s->linesize, 4);
+            h->vdsp.prefetch(src[1] + off, h->linesize, 4);
+            h->vdsp.prefetch(src[2] + off, h->linesize, 4);
         } else {
-            off= (((mx>>1)+64)<<pixel_shift) + ((my>>1) + (s->mb_x&7))*s->uvlinesize;
-            s->dsp.prefetch(src[1] + off, src[2] - src[1], 2);
+            off= (((mx>>1)+64)<<pixel_shift) + ((my>>1) + (h->mb_x&7))*h->uvlinesize;
+            h->vdsp.prefetch(src[1] + off, src[2] - src[1], 2);
         }
     }
 }
@@ -782,13 +1001,37 @@
     av_freep(&h->mb2b_xy);
     av_freep(&h->mb2br_xy);
 
+    for (i = 0; i < 3; i++)
+        av_freep(&h->visualization_buffer[i]);
+
+    if (free_rbsp) {
+        for (i = 0; i < h->picture_count && !h->avctx->internal->is_copy; i++)
+            free_picture(h, &h->DPB[i]);
+        av_freep(&h->DPB);
+        h->picture_count = 0;
+    } else if (h->DPB) {
+        for (i = 0; i < h->picture_count; i++)
+            h->DPB[i].needs_realloc = 1;
+    }
+
+    h->cur_pic_ptr = NULL;
+
     for (i = 0; i < MAX_THREADS; i++) {
         hx = h->thread_context[i];
         if (!hx)
             continue;
         av_freep(&hx->top_borders[1]);
         av_freep(&hx->top_borders[0]);
-        av_freep(&hx->s.obmc_scratchpad);
+        av_freep(&hx->bipred_scratchpad);
+        av_freep(&hx->edge_emu_buffer);
+        av_freep(&hx->dc_val_base);
+        av_freep(&hx->me.scratchpad);
+        av_freep(&hx->er.mb_index2xy);
+        av_freep(&hx->er.error_status_table);
+        av_freep(&hx->er.er_temp_buffer);
+        av_freep(&hx->er.mbintra_table);
+        av_freep(&hx->er.mbskip_table);
+
         if (free_rbsp) {
             av_freep(&hx->rbsp_buffer[1]);
             av_freep(&hx->rbsp_buffer[0]);
@@ -872,52 +1115,59 @@
 
 int ff_h264_alloc_tables(H264Context *h)
 {
-    MpegEncContext *const s = &h->s;
-    const int big_mb_num    = s->mb_stride * (s->mb_height + 1);
-    const int row_mb_num    = 2*s->mb_stride*FFMAX(s->avctx->thread_count, 1);
-    int x, y;
+    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->s.avctx, h->intra4x4_pred_mode,
+    FF_ALLOCZ_OR_GOTO(h->avctx, h->intra4x4_pred_mode,
                       row_mb_num * 8 * sizeof(uint8_t), fail)
-    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->non_zero_count,
+    FF_ALLOCZ_OR_GOTO(h->avctx, h->non_zero_count,
                       big_mb_num * 48 * sizeof(uint8_t), fail)
-    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->slice_table_base,
-                      (big_mb_num + s->mb_stride) * sizeof(*h->slice_table_base), fail)
-    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->cbp_table,
+    FF_ALLOCZ_OR_GOTO(h->avctx, h->slice_table_base,
+                      (big_mb_num + h->mb_stride) * sizeof(*h->slice_table_base), fail)
+    FF_ALLOCZ_OR_GOTO(h->avctx, h->cbp_table,
                       big_mb_num * sizeof(uint16_t), fail)
-    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->chroma_pred_mode_table,
+    FF_ALLOCZ_OR_GOTO(h->avctx, h->chroma_pred_mode_table,
                       big_mb_num * sizeof(uint8_t), fail)
-    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->mvd_table[0],
+    FF_ALLOCZ_OR_GOTO(h->avctx, h->mvd_table[0],
                       16 * row_mb_num * sizeof(uint8_t), fail);
-    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->mvd_table[1],
+    FF_ALLOCZ_OR_GOTO(h->avctx, h->mvd_table[1],
                       16 * row_mb_num * sizeof(uint8_t), fail);
-    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->direct_table,
+    FF_ALLOCZ_OR_GOTO(h->avctx, h->direct_table,
                       4 * big_mb_num * sizeof(uint8_t), fail);
-    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->list_counts,
+    FF_ALLOCZ_OR_GOTO(h->avctx, h->list_counts,
                       big_mb_num * sizeof(uint8_t), fail)
 
     memset(h->slice_table_base, -1,
-           (big_mb_num + s->mb_stride) * sizeof(*h->slice_table_base));
-    h->slice_table = h->slice_table_base + s->mb_stride * 2 + 1;
+           (big_mb_num + h->mb_stride) * sizeof(*h->slice_table_base));
+    h->slice_table = h->slice_table_base + h->mb_stride * 2 + 1;
 
-    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->mb2b_xy,
+    FF_ALLOCZ_OR_GOTO(h->avctx, h->mb2b_xy,
                       big_mb_num * sizeof(uint32_t), fail);
-    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->mb2br_xy,
+    FF_ALLOCZ_OR_GOTO(h->avctx, h->mb2br_xy,
                       big_mb_num * sizeof(uint32_t), fail);
-    for (y = 0; y < s->mb_height; y++)
-        for (x = 0; x < s->mb_width; x++) {
-            const int mb_xy = x + y * s->mb_stride;
+    for (y = 0; y < h->mb_height; y++)
+        for (x = 0; x < h->mb_width; x++) {
+            const int mb_xy = x + y * h->mb_stride;
             const int b_xy  = 4 * x + 4 * y * h->b_stride;
 
             h->mb2b_xy[mb_xy]  = b_xy;
-            h->mb2br_xy[mb_xy] = 8 * (FMO ? mb_xy : (mb_xy % (2 * s->mb_stride)));
+            h->mb2br_xy[mb_xy] = 8 * (FMO ? mb_xy : (mb_xy % (2 * h->mb_stride)));
         }
 
-    s->obmc_scratchpad = NULL;
-
     if (!h->dequant4_coeff[0])
         init_dequant_tables(h);
 
+    if (!h->DPB) {
+        h->picture_count = MAX_PICTURE_COUNT * FFMAX(1, h->avctx->thread_count);
+        h->DPB = av_mallocz_array(h->picture_count, sizeof(*h->DPB));
+        if (!h->DPB)
+            return AVERROR(ENOMEM);
+        for (i = 0; i < h->picture_count; i++)
+            avcodec_get_frame_defaults(&h->DPB[i].f);
+        avcodec_get_frame_defaults(&h->cur_pic.f);
+    }
+
     return 0;
 
 fail:
@@ -930,20 +1180,24 @@
  */
 static void clone_tables(H264Context *dst, H264Context *src, int i)
 {
-    MpegEncContext *const s     = &src->s;
-    dst->intra4x4_pred_mode     = src->intra4x4_pred_mode + i * 8 * 2 * s->mb_stride;
+    dst->intra4x4_pred_mode     = src->intra4x4_pred_mode + i * 8 * 2 * src->mb_stride;
     dst->non_zero_count         = src->non_zero_count;
     dst->slice_table            = src->slice_table;
     dst->cbp_table              = src->cbp_table;
     dst->mb2b_xy                = src->mb2b_xy;
     dst->mb2br_xy               = src->mb2br_xy;
     dst->chroma_pred_mode_table = src->chroma_pred_mode_table;
-    dst->mvd_table[0]           = src->mvd_table[0] + i * 8 * 2 * s->mb_stride;
-    dst->mvd_table[1]           = src->mvd_table[1] + i * 8 * 2 * s->mb_stride;
+    dst->mvd_table[0]           = src->mvd_table[0] + i * 8 * 2 * src->mb_stride;
+    dst->mvd_table[1]           = src->mvd_table[1] + i * 8 * 2 * src->mb_stride;
     dst->direct_table           = src->direct_table;
     dst->list_counts            = src->list_counts;
-    dst->s.obmc_scratchpad      = NULL;
-    ff_h264_pred_init(&dst->hpc, src->s.codec_id, src->sps.bit_depth_luma,
+    dst->DPB                    = src->DPB;
+    dst->cur_pic_ptr            = src->cur_pic_ptr;
+    dst->cur_pic                = src->cur_pic;
+    dst->bipred_scratchpad      = NULL;
+    dst->edge_emu_buffer        = NULL;
+    dst->me.scratchpad          = NULL;
+    ff_h264_pred_init(&dst->hpc, src->avctx->codec_id, src->sps.bit_depth_luma,
                       src->sps.chroma_format_idc);
 }
 
@@ -953,10 +1207,17 @@
  */
 static int context_init(H264Context *h)
 {
-    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->top_borders[0],
-                      h->s.mb_width * 16 * 3 * sizeof(uint8_t) * 2, fail)
-    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->top_borders[1],
-                      h->s.mb_width * 16 * 3 * sizeof(uint8_t) * 2, fail)
+    ERContext *er = &h->er;
+    int mb_array_size = h->mb_height * h->mb_stride;
+    int y_size  = (2 * h->mb_width + 1) * (2 * h->mb_height + 1);
+    int c_size  = h->mb_stride * (h->mb_height + 1);
+    int yc_size = y_size + 2   * c_size;
+    int x, y, i;
+
+    FF_ALLOCZ_OR_GOTO(h->avctx, h->top_borders[0],
+                      h->mb_width * 16 * 3 * sizeof(uint8_t) * 2, fail)
+    FF_ALLOCZ_OR_GOTO(h->avctx, h->top_borders[1],
+                      h->mb_width * 16 * 3 * sizeof(uint8_t) * 2, fail)
 
     h->ref_cache[0][scan8[5]  + 1] =
     h->ref_cache[0][scan8[7]  + 1] =
@@ -965,44 +1226,87 @@
     h->ref_cache[1][scan8[7]  + 1] =
     h->ref_cache[1][scan8[13] + 1] = PART_NOT_AVAILABLE;
 
+    /* init ER */
+    er->avctx          = h->avctx;
+    er->dsp            = &h->dsp;
+    er->decode_mb      = h264_er_decode_mb;
+    er->opaque         = h;
+    er->quarter_sample = 1;
+
+    er->mb_num      = h->mb_num;
+    er->mb_width    = h->mb_width;
+    er->mb_height   = h->mb_height;
+    er->mb_stride   = h->mb_stride;
+    er->b8_stride   = h->mb_width * 2 + 1;
+
+    FF_ALLOCZ_OR_GOTO(h->avctx, er->mb_index2xy, (h->mb_num + 1) * sizeof(int),
+                      fail); // error ressilience code looks cleaner with this
+    for (y = 0; y < h->mb_height; y++)
+        for (x = 0; x < h->mb_width; x++)
+            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;
+
+    FF_ALLOCZ_OR_GOTO(h->avctx, er->error_status_table,
+                      mb_array_size * sizeof(uint8_t), fail);
+
+    FF_ALLOC_OR_GOTO(h->avctx, er->mbintra_table, mb_array_size, fail);
+    memset(er->mbintra_table, 1, mb_array_size);
+
+    FF_ALLOCZ_OR_GOTO(h->avctx, er->mbskip_table, mb_array_size + 2, fail);
+
+    FF_ALLOC_OR_GOTO(h->avctx, er->er_temp_buffer, h->mb_height * h->mb_stride,
+                     fail);
+
+    FF_ALLOCZ_OR_GOTO(h->avctx, h->dc_val_base, yc_size * sizeof(int16_t), fail);
+    er->dc_val[0] = h->dc_val_base + h->mb_width * 2 + 2;
+    er->dc_val[1] = h->dc_val_base + y_size + h->mb_stride + 1;
+    er->dc_val[2] = er->dc_val[1] + c_size;
+    for (i = 0; i < yc_size; i++)
+        h->dc_val_base[i] = 1024;
+
     return 0;
 
 fail:
     return -1; // free_tables will clean up for us
 }
 
-static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size);
+static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size,
+                            int parse_extradata);
 
 static av_cold void common_init(H264Context *h)
 {
-    MpegEncContext *const s = &h->s;
 
-    s->width    = s->avctx->width;
-    s->height   = s->avctx->height;
-    s->codec_id = s->avctx->codec->id;
+    h->width    = h->avctx->width;
+    h->height   = h->avctx->height;
 
-    s->avctx->bits_per_raw_sample = 8;
+    h->bit_depth_luma    = 8;
+    h->chroma_format_idc = 1;
+
+    h->avctx->bits_per_raw_sample = 8;
     h->cur_chroma_format_idc = 1;
 
-    ff_h264dsp_init(&h->h264dsp,
-                    s->avctx->bits_per_raw_sample, h->cur_chroma_format_idc);
-    ff_h264_pred_init(&h->hpc, s->codec_id,
-                      s->avctx->bits_per_raw_sample, h->cur_chroma_format_idc);
+    ff_h264dsp_init(&h->h264dsp, 8, 1);
+    av_assert0(h->sps.bit_depth_chroma == 0);
+    ff_h264chroma_init(&h->h264chroma, h->sps.bit_depth_chroma);
+    ff_h264qpel_init(&h->h264qpel, 8);
+    ff_h264_pred_init(&h->hpc, h->avctx->codec_id, 8, 1);
 
     h->dequant_coeff_pps = -1;
-    s->unrestricted_mv   = 1;
 
-    s->dsp.dct_bits = 16;
+    h->dsp.dct_bits = 16;
     /* needed so that IDCT permutation is known early */
-    ff_dsputil_init(&s->dsp, s->avctx);
+    ff_dsputil_init(&h->dsp, h->avctx);
+    ff_videodsp_init(&h->vdsp, 8);
 
     memset(h->pps.scaling_matrix4, 16, 6 * 16 * sizeof(uint8_t));
     memset(h->pps.scaling_matrix8, 16, 2 * 64 * sizeof(uint8_t));
 }
 
-static int ff_h264_decode_extradata_internal(H264Context *h, const uint8_t *buf, int size)
+int ff_h264_decode_extradata(H264Context *h, const uint8_t *buf, int size)
 {
-    AVCodecContext *avctx = h->s.avctx;
+    AVCodecContext *avctx = h->avctx;
 
     if (!buf || size <= 0)
         return -1;
@@ -1027,7 +1331,7 @@
             nalsize = AV_RB16(p) + 2;
             if(nalsize > size - (p-buf))
                 return -1;
-            if (decode_nal_units(h, p, nalsize) < 0) {
+            if (decode_nal_units(h, p, nalsize, 1) < 0) {
                 av_log(avctx, AV_LOG_ERROR,
                        "Decoding sps %d from avcC failed\n", i);
                 return -1;
@@ -1040,7 +1344,7 @@
             nalsize = AV_RB16(p) + 2;
             if(nalsize > size - (p-buf))
                 return -1;
-            if (decode_nal_units(h, p, nalsize) < 0) {
+            if (decode_nal_units(h, p, nalsize, 1) < 0) {
                 av_log(avctx, AV_LOG_ERROR,
                        "Decoding pps %d from avcC failed\n", i);
                 return -1;
@@ -1051,40 +1355,31 @@
         h->nal_length_size = (buf[4] & 0x03) + 1;
     } else {
         h->is_avc = 0;
-        if (decode_nal_units(h, buf, size) < 0)
+        if (decode_nal_units(h, buf, size, 1) < 0)
             return -1;
     }
     return size;
 }
 
-int ff_h264_decode_extradata(H264Context *h, const uint8_t *buf, int size)
-{
-    int ret;
-    h->decoding_extradata = 1;
-    ret = ff_h264_decode_extradata_internal(h, buf, size);
-    h->decoding_extradata = 0;
-    return ret;
-}
-
 av_cold int ff_h264_decode_init(AVCodecContext *avctx)
 {
     H264Context *h = avctx->priv_data;
-    MpegEncContext *const s = &h->s;
     int i;
 
-    ff_MPV_decode_defaults(s);
-
-    s->avctx = avctx;
+    h->avctx = avctx;
     common_init(h);
 
-    s->out_format      = FMT_H264;
-    s->workaround_bugs = avctx->workaround_bugs;
+    h->picture_structure   = PICT_FRAME;
+    h->picture_range_start = 0;
+    h->picture_range_end   = MAX_PICTURE_COUNT;
+    h->slice_context_count = 1;
+    h->workaround_bugs     = avctx->workaround_bugs;
+    h->flags               = avctx->flags;
 
     /* set defaults */
     // s->decode_mb = ff_h263_decode_mb;
-    s->quarter_sample = 1;
     if (!avctx->has_b_frames)
-        s->low_delay = 1;
+        h->low_delay = 1;
 
     avctx->chroma_sample_location = AVCHROMA_LOC_LEFT;
 
@@ -1103,10 +1398,10 @@
     ff_h264_reset_sei(h);
     if (avctx->codec_id == AV_CODEC_ID_H264) {
         if (avctx->ticks_per_frame == 1) {
-            if(s->avctx->time_base.den < INT_MAX/2) {
-                s->avctx->time_base.den *= 2;
+            if(h->avctx->time_base.den < INT_MAX/2) {
+                h->avctx->time_base.den *= 2;
             } else
-                s->avctx->time_base.num /= 2;
+                h->avctx->time_base.num /= 2;
         }
         avctx->ticks_per_frame = 2;
     }
@@ -1118,9 +1413,9 @@
     }
 
     if (h->sps.bitstream_restriction_flag &&
-        s->avctx->has_b_frames < h->sps.num_reorder_frames) {
-        s->avctx->has_b_frames = h->sps.num_reorder_frames;
-        s->low_delay           = 0;
+        h->avctx->has_b_frames < h->sps.num_reorder_frames) {
+        h->avctx->has_b_frames = h->sps.num_reorder_frames;
+        h->low_delay           = 0;
     }
 
     ff_init_cabac_states();
@@ -1129,16 +1424,21 @@
 }
 
 #define IN_RANGE(a, b, size) (((a) >= (b)) && ((a) < ((b) + (size))))
+#undef REBASE_PICTURE
+#define REBASE_PICTURE(pic, new_ctx, old_ctx)             \
+    ((pic && pic >= old_ctx->DPB &&                       \
+      pic < old_ctx->DPB + old_ctx->picture_count) ?      \
+        &new_ctx->DPB[pic - old_ctx->DPB] : NULL)
 
 static void copy_picture_range(Picture **to, Picture **from, int count,
-                               MpegEncContext *new_base,
-                               MpegEncContext *old_base)
+                               H264Context *new_base,
+                               H264Context *old_base)
 {
     int i;
 
     for (i = 0; i < count; i++) {
         assert((IN_RANGE(from[i], old_base, sizeof(*old_base)) ||
-                IN_RANGE(from[i], old_base->picture,
+                IN_RANGE(from[i], old_base->DPB,
                          sizeof(Picture) * old_base->picture_count) ||
                 !from[i]));
         to[i] = REBASE_PICTURE(from[i], new_base, old_base);
@@ -1169,6 +1469,8 @@
     memset(h->sps_buffers, 0, sizeof(h->sps_buffers));
     memset(h->pps_buffers, 0, sizeof(h->pps_buffers));
 
+    h->context_initialized = 0;
+
     return 0;
 }
 
@@ -1176,22 +1478,67 @@
     memcpy(&to->start_field, &from->start_field,                        \
            (char *)&to->end_field - (char *)&to->start_field)
 
+static int h264_slice_header_init(H264Context *, int);
+
+static int h264_set_parameter_from_sps(H264Context *h);
+
 static int decode_update_thread_context(AVCodecContext *dst,
                                         const AVCodecContext *src)
 {
     H264Context *h = dst->priv_data, *h1 = src->priv_data;
-    MpegEncContext *const s = &h->s, *const s1 = &h1->s;
-    int inited = s->context_initialized, err;
+    int inited = h->context_initialized, err = 0;
+    int context_reinitialized = 0;
     int i;
 
     if (dst == src)
         return 0;
 
-    err = ff_mpeg_update_thread_context(dst, src);
-    if (err)
-        return err;
+    if (inited &&
+        (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)) {
 
-    // FIXME handle width/height changing
+        av_freep(&h->bipred_scratchpad);
+
+        h->width     = h1->width;
+        h->height    = h1->height;
+        h->mb_height = h1->mb_height;
+        h->mb_width  = h1->mb_width;
+        h->mb_num    = h1->mb_num;
+        h->mb_stride = h1->mb_stride;
+        h->b_stride  = h1->b_stride;
+        // SPS/PPS
+        copy_parameter_set((void **)h->sps_buffers, (void **)h1->sps_buffers,
+                        MAX_SPS_COUNT, sizeof(SPS));
+        h->sps = h1->sps;
+        copy_parameter_set((void **)h->pps_buffers, (void **)h1->pps_buffers,
+                        MAX_PPS_COUNT, sizeof(PPS));
+        h->pps = h1->pps;
+
+        if ((err = h264_slice_header_init(h, 1)) < 0) {
+            av_log(h->avctx, AV_LOG_ERROR, "h264_slice_header_init() failed");
+            return err;
+        }
+        context_reinitialized = 1;
+
+#if 0
+        h264_set_parameter_from_sps(h);
+        //Note we set context_reinitialized which will cause h264_set_parameter_from_sps to be reexecuted
+        h->cur_chroma_format_idc = h1->cur_chroma_format_idc;
+#endif
+    }
+    /* update linesize on resize for h264. The h264 decoder doesn't
+     * necessarily call ff_MPV_frame_start in the new thread */
+    h->linesize   = h1->linesize;
+    h->uvlinesize = h1->uvlinesize;
+
+    /* copy block_offset since frame_start may not be called */
+    memcpy(h->block_offset, h1->block_offset, sizeof(h->block_offset));
+
     if (!inited) {
         for (i = 0; i < MAX_SPS_COUNT; i++)
             av_freep(h->sps_buffers + i);
@@ -1199,35 +1546,73 @@
         for (i = 0; i < MAX_PPS_COUNT; i++)
             av_freep(h->pps_buffers + i);
 
-        // copy all fields after MpegEnc
-        memcpy(&h->s + 1, &h1->s + 1,
-               sizeof(H264Context) - sizeof(MpegEncContext));
+        memcpy(h, h1, offsetof(H264Context, intra_pcm_ptr));
+        memcpy(&h->cabac, &h1->cabac,
+               sizeof(H264Context) - offsetof(H264Context, cabac));
+        av_assert0((void*)&h->cabac == &h->mb_padding + 1);
+
         memset(h->sps_buffers, 0, sizeof(h->sps_buffers));
         memset(h->pps_buffers, 0, sizeof(h->pps_buffers));
 
-        if (s1->context_initialized) {
+        memset(&h->er, 0, sizeof(h->er));
+        memset(&h->me, 0, sizeof(h->me));
+        h->avctx = dst;
+        h->DPB   = NULL;
+
+        if (h1->context_initialized) {
+        h->context_initialized = 0;
+
+        h->picture_range_start  += MAX_PICTURE_COUNT;
+        h->picture_range_end    += MAX_PICTURE_COUNT;
+
+        h->cur_pic.f.extended_data = h->cur_pic.f.data;
+
         if (ff_h264_alloc_tables(h) < 0) {
             av_log(dst, AV_LOG_ERROR, "Could not allocate memory for h264\n");
             return AVERROR(ENOMEM);
         }
         context_init(h);
-
-        /* frame_start may not be called for the next thread (if it's decoding
-         * a bottom field) so this has to be allocated here */
-        h->s.obmc_scratchpad = av_malloc(16 * 6 * s->linesize);
         }
 
         for (i = 0; i < 2; i++) {
             h->rbsp_buffer[i]      = NULL;
             h->rbsp_buffer_size[i] = 0;
         }
+        h->bipred_scratchpad = NULL;
+        h->edge_emu_buffer   = NULL;
 
         h->thread_context[0] = h;
-
-        s->dsp.clear_blocks(h->mb);
-        s->dsp.clear_blocks(h->mb + (24 * 16 << h->pixel_shift));
+        h->context_initialized = h1->context_initialized;
     }
 
+    h->avctx->coded_height  = h1->avctx->coded_height;
+    h->avctx->coded_width   = h1->avctx->coded_width;
+    h->avctx->width         = h1->avctx->width;
+    h->avctx->height        = h1->avctx->height;
+    h->coded_picture_number = h1->coded_picture_number;
+    h->first_field          = h1->first_field;
+    h->picture_structure    = h1->picture_structure;
+    h->qscale               = h1->qscale;
+    h->droppable            = h1->droppable;
+    h->data_partitioning    = h1->data_partitioning;
+    h->low_delay            = h1->low_delay;
+
+    memcpy(h->DPB, h1->DPB, h1->picture_count * sizeof(*h1->DPB));
+
+    // reset s->picture[].f.extended_data to s->picture[].f.data
+    for (i = 0; i < h->picture_count; i++) {
+        h->DPB[i].f.extended_data = h->DPB[i].f.data;
+        h->DPB[i].period_since_free ++;
+    }
+
+    h->cur_pic_ptr     = REBASE_PICTURE(h1->cur_pic_ptr, h, h1);
+    h->cur_pic = h1->cur_pic;
+    h->cur_pic.f.extended_data = h->cur_pic.f.data;
+
+    h->workaround_bugs = h1->workaround_bugs;
+    h->low_delay       = h1->low_delay;
+    h->droppable       = h1->droppable;
+
     // extradata/NAL handling
     h->is_avc = h1->is_avc;
 
@@ -1258,21 +1643,25 @@
 
     // reference lists
     copy_fields(h, h1, ref_count, list_count);
-    copy_fields(h, h1, ref_list, intra_gb);
+    copy_fields(h, h1, ref2frm, intra_gb);
     copy_fields(h, h1, short_ref, cabac_init_idc);
 
-    copy_picture_range(h->short_ref, h1->short_ref, 32, s, s1);
-    copy_picture_range(h->long_ref, h1->long_ref, 32, s, s1);
+    copy_picture_range(h->short_ref, h1->short_ref, 32, h, h1);
+    copy_picture_range(h->long_ref, h1->long_ref, 32, h, h1);
     copy_picture_range(h->delayed_pic, h1->delayed_pic,
-                       MAX_DELAYED_PIC_COUNT + 2, s, s1);
+                       MAX_DELAYED_PIC_COUNT + 2, h, h1);
 
     h->last_slice_type = h1->last_slice_type;
     h->sync            = h1->sync;
+    memcpy(h->last_ref_count, h1->last_ref_count, sizeof(h->last_ref_count));
 
-    if (!s->current_picture_ptr)
+    if (context_reinitialized)
+        h264_set_parameter_from_sps(h);
+
+    if (!h->cur_pic_ptr)
         return 0;
 
-    if (!s->dropable) {
+    if (!h->droppable) {
         err = ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index);
         h->prev_poc_msb = h->poc_msb;
         h->prev_poc_lsb = h->poc_lsb;
@@ -1286,49 +1675,78 @@
 
 int ff_h264_frame_start(H264Context *h)
 {
-    MpegEncContext *const s = &h->s;
-    int i;
+    Picture *pic;
+    int i, ret;
     const int pixel_shift = h->pixel_shift;
+    int c[4] = {
+        1<<(h->sps.bit_depth_luma-1),
+        1<<(h->sps.bit_depth_chroma-1),
+        1<<(h->sps.bit_depth_chroma-1),
+        -1
+    };
 
-    if (ff_MPV_frame_start(s, s->avctx) < 0)
+    if (!ff_thread_can_start_frame(h->avctx)) {
+        av_log(h->avctx, AV_LOG_ERROR, "Attempt to start a frame outside SETUP state\n");
         return -1;
-    ff_er_frame_start(s);
+    }
+
+    release_unused_pictures(h, 1);
+    h->cur_pic_ptr = NULL;
+
+    i = find_unused_picture(h);
+    if (i < 0) {
+        av_log(h->avctx, AV_LOG_ERROR, "no frame buffer available\n");
+        return i;
+    }
+    pic = &h->DPB[i];
+
+    pic->f.reference            = h->droppable ? 0 : h->picture_structure;
+    pic->f.coded_picture_number = h->coded_picture_number++;
+    pic->field_picture          = h->picture_structure != PICT_FRAME;
+
     /*
-     * ff_MPV_frame_start uses pict_type to derive key_frame.
-     * This is incorrect for H.264; IDR markings must be used.
-     * Zero here; IDR markings per slice in frame or fields are ORed in later.
+     * Zero key_frame here; IDR markings per slice in frame or fields are ORed
+     * in later.
      * See decode_nal_units().
      */
-    s->current_picture_ptr->f.key_frame = 0;
-    s->current_picture_ptr->sync        = 0;
-    s->current_picture_ptr->mmco_reset  = 0;
+    pic->f.key_frame = 0;
+    pic->sync        = 0;
+    pic->mmco_reset  = 0;
 
-    assert(s->linesize && s->uvlinesize);
+    if ((ret = alloc_picture(h, pic)) < 0)
+        return ret;
+    if(!h->sync && !h->avctx->hwaccel &&
+       !(h->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU))
+        avpriv_color_frame(&pic->f, c);
+
+    h->cur_pic_ptr = pic;
+    h->cur_pic     = *h->cur_pic_ptr;
+    h->cur_pic.f.extended_data = h->cur_pic.f.data;
+
+    ff_er_frame_start(&h->er);
+    h->er.last_pic =
+    h->er.next_pic = NULL;
+
+    assert(h->linesize && h->uvlinesize);
 
     for (i = 0; i < 16; i++) {
-        h->block_offset[i]           = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 4 * s->linesize * ((scan8[i] - scan8[0]) >> 3);
-        h->block_offset[48 + i]      = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 8 * s->linesize * ((scan8[i] - scan8[0]) >> 3);
+        h->block_offset[i]           = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 4 * h->linesize * ((scan8[i] - scan8[0]) >> 3);
+        h->block_offset[48 + i]      = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 8 * h->linesize * ((scan8[i] - scan8[0]) >> 3);
     }
     for (i = 0; i < 16; i++) {
         h->block_offset[16 + i]      =
-        h->block_offset[32 + i]      = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 4 * s->uvlinesize * ((scan8[i] - scan8[0]) >> 3);
+        h->block_offset[32 + i]      = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 4 * h->uvlinesize * ((scan8[i] - scan8[0]) >> 3);
         h->block_offset[48 + 16 + i] =
-        h->block_offset[48 + 32 + i] = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 8 * s->uvlinesize * ((scan8[i] - scan8[0]) >> 3);
+        h->block_offset[48 + 32 + i] = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 8 * h->uvlinesize * ((scan8[i] - scan8[0]) >> 3);
     }
 
-    /* can't be in alloc_tables because linesize isn't known there.
-     * FIXME: redo bipred weight to not require extra buffer? */
-    for (i = 0; i < s->slice_context_count; i++)
-        if (h->thread_context[i] && !h->thread_context[i]->s.obmc_scratchpad)
-            h->thread_context[i]->s.obmc_scratchpad = av_malloc(16 * 6 * s->linesize);
-
     /* Some macroblocks can be accessed before they're available in case
      * of lost slices, MBAFF or threading. */
     memset(h->slice_table, -1,
-           (s->mb_height * s->mb_stride - 1) * sizeof(*h->slice_table));
+           (h->mb_height * h->mb_stride - 1) * sizeof(*h->slice_table));
 
-    // s->decode = (s->flags & CODEC_FLAG_PSNR) || !s->encoding ||
-    //             s->current_picture.f.reference /* || h->contains_intra */ || 1;
+    // s->decode = (h->flags & CODEC_FLAG_PSNR) || !s->encoding ||
+    //             h->cur_pic.f.reference /* || h->contains_intra */ || 1;
 
     /* We mark the current picture as non-reference after allocating it, so
      * that if we break out due to an error it can be released automatically
@@ -1336,15 +1754,14 @@
      * SVQ3 as well as most other codecs have only last/next/current and thus
      * get released even with set reference, besides SVQ3 and others do not
      * mark frames as reference later "naturally". */
-    if (s->codec_id != AV_CODEC_ID_SVQ3)
-        s->current_picture_ptr->f.reference = 0;
+    if (h->avctx->codec_id != AV_CODEC_ID_SVQ3)
+        h->cur_pic_ptr->f.reference = 0;
 
-    s->current_picture_ptr->field_poc[0]     =
-        s->current_picture_ptr->field_poc[1] = INT_MAX;
+    h->cur_pic_ptr->field_poc[0] = h->cur_pic_ptr->field_poc[1] = INT_MAX;
 
     h->next_output_pic = NULL;
 
-    assert(s->current_picture_ptr->long_ref == 0);
+    assert(h->cur_pic_ptr->long_ref == 0);
 
     return 0;
 }
@@ -1359,13 +1776,12 @@
  */
 static void decode_postinit(H264Context *h, int setup_finished)
 {
-    MpegEncContext *const s = &h->s;
-    Picture *out = s->current_picture_ptr;
-    Picture *cur = s->current_picture_ptr;
+    Picture *out = h->cur_pic_ptr;
+    Picture *cur = h->cur_pic_ptr;
     int i, pics, out_of_order, out_idx;
 
-    s->current_picture_ptr->f.qscale_type = FF_QSCALE_TYPE_H264;
-    s->current_picture_ptr->f.pict_type   = s->pict_type;
+    h->cur_pic_ptr->f.qscale_type = FF_QSCALE_TYPE_H264;
+    h->cur_pic_ptr->f.pict_type   = h->pict_type;
 
     if (h->next_output_pic)
         return;
@@ -1376,7 +1792,7 @@
          * The check in decode_nal_units() is not good enough to find this
          * yet, so we assume the worst for now. */
         // if (setup_finished)
-        //    ff_thread_finish_setup(s->avctx);
+        //    ff_thread_finish_setup(h->avctx);
         return;
     }
 
@@ -1411,7 +1827,6 @@
             cur->f.repeat_pict = 1;
             break;
         case SEI_PIC_STRUCT_FRAME_DOUBLING:
-            // Force progressive here, doubling interlaced frame is a bad idea.
             cur->f.repeat_pict = 2;
             break;
         case SEI_PIC_STRUCT_FRAME_TRIPLING:
@@ -1453,15 +1868,15 @@
     /* Sort B-frames into display order */
 
     if (h->sps.bitstream_restriction_flag &&
-        s->avctx->has_b_frames < h->sps.num_reorder_frames) {
-        s->avctx->has_b_frames = h->sps.num_reorder_frames;
-        s->low_delay           = 0;
+        h->avctx->has_b_frames < h->sps.num_reorder_frames) {
+        h->avctx->has_b_frames = h->sps.num_reorder_frames;
+        h->low_delay           = 0;
     }
 
-    if (s->avctx->strict_std_compliance >= FF_COMPLIANCE_STRICT &&
+    if (h->avctx->strict_std_compliance >= FF_COMPLIANCE_STRICT &&
         !h->sps.bitstream_restriction_flag) {
-        s->avctx->has_b_frames = MAX_DELAYED_PIC_COUNT - 1;
-        s->low_delay           = 0;
+        h->avctx->has_b_frames = MAX_DELAYED_PIC_COUNT - 1;
+        h->low_delay           = 0;
     }
 
     for (i = 0; 1; i++) {
@@ -1477,10 +1892,16 @@
     if(   cur->f.pict_type == AV_PICTURE_TYPE_B
        || (h->last_pocs[MAX_DELAYED_PIC_COUNT-2] > INT_MIN && h->last_pocs[MAX_DELAYED_PIC_COUNT-1] - h->last_pocs[MAX_DELAYED_PIC_COUNT-2] > 2))
         out_of_order = FFMAX(out_of_order, 1);
-    if(s->avctx->has_b_frames < out_of_order && !h->sps.bitstream_restriction_flag){
-        av_log(s->avctx, AV_LOG_VERBOSE, "Increasing reorder buffer to %d\n", out_of_order);
-        s->avctx->has_b_frames = out_of_order;
-        s->low_delay = 0;
+    if (out_of_order == MAX_DELAYED_PIC_COUNT) {
+        av_log(h->avctx, AV_LOG_VERBOSE, "Invalid POC %d<%d\n", cur->poc, h->last_pocs[0]);
+        for (i = 1; i < MAX_DELAYED_PIC_COUNT; i++)
+            h->last_pocs[i] = INT_MIN;
+        h->last_pocs[0] = cur->poc;
+        cur->mmco_reset = 1;
+    } else if(h->avctx->has_b_frames < out_of_order && !h->sps.bitstream_restriction_flag){
+        av_log(h->avctx, AV_LOG_VERBOSE, "Increasing reorder buffer to %d\n", out_of_order);
+        h->avctx->has_b_frames = out_of_order;
+        h->low_delay = 0;
     }
 
     pics = 0;
@@ -1503,27 +1924,27 @@
             out     = h->delayed_pic[i];
             out_idx = i;
         }
-    if (s->avctx->has_b_frames == 0 &&
+    if (h->avctx->has_b_frames == 0 &&
         (h->delayed_pic[0]->f.key_frame || h->delayed_pic[0]->mmco_reset))
         h->next_outputed_poc = INT_MIN;
     out_of_order = out->poc < h->next_outputed_poc;
 
-    if (out_of_order || pics > s->avctx->has_b_frames) {
+    if (out_of_order || pics > h->avctx->has_b_frames) {
         out->f.reference &= ~DELAYED_PIC_REF;
         // for frame threading, the owner must be the second field's thread or
         // else the first thread can release the picture and reuse it unsafely
-        out->owner2       = s;
+        out->owner2       = h;
         for (i = out_idx; h->delayed_pic[i]; i++)
             h->delayed_pic[i] = h->delayed_pic[i + 1];
     }
-    if (!out_of_order && pics > s->avctx->has_b_frames) {
+    if (!out_of_order && pics > h->avctx->has_b_frames) {
         h->next_output_pic = out;
         if (out_idx == 0 && h->delayed_pic[0] && (h->delayed_pic[0]->f.key_frame || h->delayed_pic[0]->mmco_reset)) {
             h->next_outputed_poc = INT_MIN;
         } else
             h->next_outputed_poc = out->poc;
     } else {
-        av_log(s->avctx, AV_LOG_DEBUG, "no picture %s\n", out_of_order ? "ooo" : "");
+        av_log(h->avctx, AV_LOG_DEBUG, "no picture %s\n", out_of_order ? "ooo" : "");
     }
 
     if (h->next_output_pic && h->next_output_pic->sync) {
@@ -1531,7 +1952,7 @@
     }
 
     if (setup_finished)
-        ff_thread_finish_setup(s->avctx);
+        ff_thread_finish_setup(h->avctx);
 }
 
 static av_always_inline void backup_mb_border(H264Context *h, uint8_t *src_y,
@@ -1539,7 +1960,6 @@
                                               int linesize, int uvlinesize,
                                               int simple)
 {
-    MpegEncContext *const s = &h->s;
     uint8_t *top_border;
     int top_idx = 1;
     const int pixel_shift = h->pixel_shift;
@@ -1551,13 +1971,13 @@
     src_cr -= uvlinesize;
 
     if (!simple && FRAME_MBAFF) {
-        if (s->mb_y & 1) {
+        if (h->mb_y & 1) {
             if (!MB_MBAFF) {
-                top_border = h->top_borders[0][s->mb_x];
+                top_border = h->top_borders[0][h->mb_x];
                 AV_COPY128(top_border, src_y + 15 * linesize);
                 if (pixel_shift)
                     AV_COPY128(top_border + 16, src_y + 15 * linesize + 16);
-                if (simple || !CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) {
+                if (simple || !CONFIG_GRAY || !(h->flags & CODEC_FLAG_GRAY)) {
                     if (chroma444) {
                         if (pixel_shift) {
                             AV_COPY128(top_border + 32, src_cb + 15 * uvlinesize);
@@ -1593,14 +2013,14 @@
             return;
     }
 
-    top_border = h->top_borders[top_idx][s->mb_x];
+    top_border = h->top_borders[top_idx][h->mb_x];
     /* There are two lines saved, the line above the top macroblock
      * of a pair, and the line above the bottom macroblock. */
     AV_COPY128(top_border, src_y + 16 * linesize);
     if (pixel_shift)
         AV_COPY128(top_border + 16, src_y + 16 * linesize + 16);
 
-    if (simple || !CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) {
+    if (simple || !CONFIG_GRAY || !(h->flags & CODEC_FLAG_GRAY)) {
         if (chroma444) {
             if (pixel_shift) {
                 AV_COPY128(top_border + 32, src_cb + 16 * linesize);
@@ -1637,7 +2057,6 @@
                                             int xchg, int chroma444,
                                             int simple, int pixel_shift)
 {
-    MpegEncContext *const s = &h->s;
     int deblock_topleft;
     int deblock_top;
     int top_idx = 1;
@@ -1645,7 +2064,7 @@
     uint8_t *top_border;
 
     if (!simple && FRAME_MBAFF) {
-        if (s->mb_y & 1) {
+        if (h->mb_y & 1) {
             if (!MB_MBAFF)
                 return;
         } else {
@@ -1654,19 +2073,19 @@
     }
 
     if (h->deblocking_filter == 2) {
-        deblock_topleft = h->slice_table[h->mb_xy - 1 - s->mb_stride] == h->slice_num;
+        deblock_topleft = h->slice_table[h->mb_xy - 1 - h->mb_stride] == h->slice_num;
         deblock_top     = h->top_type;
     } else {
-        deblock_topleft = (s->mb_x > 0);
-        deblock_top     = (s->mb_y > !!MB_FIELD);
+        deblock_topleft = (h->mb_x > 0);
+        deblock_top     = (h->mb_y > !!MB_FIELD);
     }
 
     src_y  -= linesize   + 1 + pixel_shift;
     src_cb -= uvlinesize + 1 + pixel_shift;
     src_cr -= uvlinesize + 1 + pixel_shift;
 
-    top_border_m1 = h->top_borders[top_idx][s->mb_x - 1];
-    top_border    = h->top_borders[top_idx][s->mb_x];
+    top_border_m1 = h->top_borders[top_idx][h->mb_x - 1];
+    top_border    = h->top_borders[top_idx][h->mb_x];
 
 #define XCHG(a, b, xchg)                        \
     if (pixel_shift) {                          \
@@ -1688,12 +2107,12 @@
         }
         XCHG(top_border + (0 << pixel_shift), src_y + (1 << pixel_shift), xchg);
         XCHG(top_border + (8 << pixel_shift), src_y + (9 << pixel_shift), 1);
-        if (s->mb_x + 1 < s->mb_width) {
-            XCHG(h->top_borders[top_idx][s->mb_x + 1],
+        if (h->mb_x + 1 < h->mb_width) {
+            XCHG(h->top_borders[top_idx][h->mb_x + 1],
                  src_y + (17 << pixel_shift), 1);
         }
     }
-    if (simple || !CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) {
+    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);
@@ -1703,9 +2122,9 @@
             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 (s->mb_x + 1 < s->mb_width) {
-                XCHG(h->top_borders[top_idx][s->mb_x + 1] + (16 << pixel_shift), src_cb + (17 << pixel_shift), 1);
-                XCHG(h->top_borders[top_idx][s->mb_x + 1] + (32 << pixel_shift), src_cr + (17 << 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) {
@@ -1720,7 +2139,7 @@
     }
 }
 
-static av_always_inline int dctcoef_get(DCTELEM *mb, int high_bit_depth,
+static av_always_inline int dctcoef_get(int16_t *mb, int high_bit_depth,
                                         int index)
 {
     if (high_bit_depth) {
@@ -1729,7 +2148,7 @@
         return AV_RN16A(mb + index);
 }
 
-static av_always_inline void dctcoef_set(DCTELEM *mb, int high_bit_depth,
+static av_always_inline void dctcoef_set(int16_t *mb, int high_bit_depth,
                                          int index, int value)
 {
     if (high_bit_depth) {
@@ -1747,84 +2166,81 @@
                                                        int linesize,
                                                        uint8_t *dest_y, int p)
 {
-    MpegEncContext *const s = &h->s;
-    void (*idct_add)(uint8_t *dst, DCTELEM *block, int stride);
-    void (*idct_dc_add)(uint8_t *dst, DCTELEM *block, int stride);
+    void (*idct_add)(uint8_t *dst, int16_t *block, int stride);
+    void (*idct_dc_add)(uint8_t *dst, int16_t *block, int stride);
     int i;
-    int qscale = p == 0 ? s->qscale : h->chroma_qp[p - 1];
+    int qscale = p == 0 ? h->qscale : h->chroma_qp[p - 1];
     block_offset += 16 * p;
     if (IS_INTRA4x4(mb_type)) {
-        if (simple || !s->encoding) {
-            if (IS_8x8DCT(mb_type)) {
-                if (transform_bypass) {
-                    idct_dc_add  =
-                    idct_add     = s->dsp.add_pixels8;
+        if (IS_8x8DCT(mb_type)) {
+            if (transform_bypass) {
+                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;
+            }
+            for (i = 0; i < 16; i += 4) {
+                uint8_t *const ptr = dest_y + block_offset[i];
+                const int dir      = h->intra4x4_pred_mode_cache[scan8[i]];
+                if (transform_bypass && h->sps.profile_idc == 244 && dir <= 1) {
+                    h->hpc.pred8x8l_add[dir](ptr, h->mb + (i * 16 + p * 256 << pixel_shift), linesize);
                 } else {
-                    idct_dc_add = h->h264dsp.h264_idct8_dc_add;
-                    idct_add    = h->h264dsp.h264_idct8_add;
+                    const int nnz = h->non_zero_count_cache[scan8[i + p * 16]];
+                    h->hpc.pred8x8l[dir](ptr, (h->topleft_samples_available << i) & 0x8000,
+                                         (h->topright_samples_available << i) & 0x4000, linesize);
+                    if (nnz) {
+                        if (nnz == 1 && dctcoef_get(h->mb, pixel_shift, i * 16 + p * 256))
+                            idct_dc_add(ptr, h->mb + (i * 16 + p * 256 << pixel_shift), linesize);
+                        else
+                            idct_add(ptr, h->mb + (i * 16 + p * 256 << pixel_shift), linesize);
+                    }
                 }
-                for (i = 0; i < 16; i += 4) {
-                    uint8_t *const ptr = dest_y + block_offset[i];
-                    const int dir      = h->intra4x4_pred_mode_cache[scan8[i]];
-                    if (transform_bypass && h->sps.profile_idc == 244 && dir <= 1) {
-                        h->hpc.pred8x8l_add[dir](ptr, h->mb + (i * 16 + p * 256 << pixel_shift), linesize);
-                    } else {
-                        const int nnz = h->non_zero_count_cache[scan8[i + p * 16]];
-                        h->hpc.pred8x8l[dir](ptr, (h->topleft_samples_available << i) & 0x8000,
-                                             (h->topright_samples_available << i) & 0x4000, linesize);
-                        if (nnz) {
+            }
+        } else {
+            if (transform_bypass) {
+                idct_dc_add  =
+                idct_add     = h->h264dsp.h264_add_pixels4_clear;
+            } else {
+                idct_dc_add = h->h264dsp.h264_idct_dc_add;
+                idct_add    = h->h264dsp.h264_idct_add;
+            }
+            for (i = 0; i < 16; i++) {
+                uint8_t *const ptr = dest_y + block_offset[i];
+                const int dir      = h->intra4x4_pred_mode_cache[scan8[i]];
+
+                if (transform_bypass && h->sps.profile_idc == 244 && dir <= 1) {
+                    h->hpc.pred4x4_add[dir](ptr, h->mb + (i * 16 + p * 256 << pixel_shift), linesize);
+                } else {
+                    uint8_t *topright;
+                    int nnz, tr;
+                    uint64_t tr_high;
+                    if (dir == DIAG_DOWN_LEFT_PRED || dir == VERT_LEFT_PRED) {
+                        const int topright_avail = (h->topright_samples_available << i) & 0x8000;
+                        av_assert2(h->mb_y || linesize <= block_offset[i]);
+                        if (!topright_avail) {
+                            if (pixel_shift) {
+                                tr_high  = ((uint16_t *)ptr)[3 - linesize / 2] * 0x0001000100010001ULL;
+                                topright = (uint8_t *)&tr_high;
+                            } else {
+                                tr       = ptr[3 - linesize] * 0x01010101u;
+                                topright = (uint8_t *)&tr;
+                            }
+                        } else
+                            topright = ptr + (4 << pixel_shift) - linesize;
+                    } else
+                        topright = NULL;
+
+                    h->hpc.pred4x4[dir](ptr, topright, linesize);
+                    nnz = h->non_zero_count_cache[scan8[i + p * 16]];
+                    if (nnz) {
+                        if (is_h264) {
                             if (nnz == 1 && dctcoef_get(h->mb, pixel_shift, i * 16 + p * 256))
                                 idct_dc_add(ptr, h->mb + (i * 16 + p * 256 << pixel_shift), linesize);
                             else
                                 idct_add(ptr, h->mb + (i * 16 + p * 256 << pixel_shift), linesize);
-                        }
-                    }
-                }
-            } else {
-                if (transform_bypass) {
-                    idct_dc_add  =
-                        idct_add = s->dsp.add_pixels4;
-                } else {
-                    idct_dc_add = h->h264dsp.h264_idct_dc_add;
-                    idct_add    = h->h264dsp.h264_idct_add;
-                }
-                for (i = 0; i < 16; i++) {
-                    uint8_t *const ptr = dest_y + block_offset[i];
-                    const int dir      = h->intra4x4_pred_mode_cache[scan8[i]];
-
-                    if (transform_bypass && h->sps.profile_idc == 244 && dir <= 1) {
-                        h->hpc.pred4x4_add[dir](ptr, h->mb + (i * 16 + p * 256 << pixel_shift), linesize);
-                    } else {
-                        uint8_t *topright;
-                        int nnz, tr;
-                        uint64_t tr_high;
-                        if (dir == DIAG_DOWN_LEFT_PRED || dir == VERT_LEFT_PRED) {
-                            const int topright_avail = (h->topright_samples_available << i) & 0x8000;
-                            av_assert2(s->mb_y || linesize <= block_offset[i]);
-                            if (!topright_avail) {
-                                if (pixel_shift) {
-                                    tr_high  = ((uint16_t *)ptr)[3 - linesize / 2] * 0x0001000100010001ULL;
-                                    topright = (uint8_t *)&tr_high;
-                                } else {
-                                    tr       = ptr[3 - linesize] * 0x01010101u;
-                                    topright = (uint8_t *)&tr;
-                                }
-                            } else
-                                topright = ptr + (4 << pixel_shift) - linesize;
-                        } else
-                            topright = NULL;
-
-                        h->hpc.pred4x4[dir](ptr, topright, linesize);
-                        nnz = h->non_zero_count_cache[scan8[i + p * 16]];
-                        if (nnz) {
-                            if (is_h264) {
-                                if (nnz == 1 && dctcoef_get(h->mb, pixel_shift, i * 16 + p * 256))
-                                    idct_dc_add(ptr, h->mb + (i * 16 + p * 256 << pixel_shift), linesize);
-                                else
-                                    idct_add(ptr, h->mb + (i * 16 + p * 256 << pixel_shift), linesize);
-                            } else if (CONFIG_SVQ3_DECODER)
-                                ff_svq3_add_idct_c(ptr, h->mb + i * 16 + p * 256, linesize, qscale, 0);
-                        }
+                        } else if (CONFIG_SVQ3_DECODER)
+                            ff_svq3_add_idct_c(ptr, h->mb + i * 16 + p * 256, linesize, qscale, 0);
                     }
                 }
             }
@@ -1864,8 +2280,7 @@
                                                     int linesize,
                                                     uint8_t *dest_y, int p)
 {
-    MpegEncContext *const s = &h->s;
-    void (*idct_add)(uint8_t *dst, DCTELEM *block, int stride);
+    void (*idct_add)(uint8_t *dst, int16_t *block, int stride);
     int i;
     block_offset += 16 * p;
     if (!IS_INTRA4x4(mb_type)) {
@@ -1882,9 +2297,9 @@
                         for (i = 0; i < 16; i++)
                             if (h->non_zero_count_cache[scan8[i + p * 16]] ||
                                 dctcoef_get(h->mb, pixel_shift, i * 16 + p * 256))
-                                s->dsp.add_pixels4(dest_y + block_offset[i],
-                                                   h->mb + (i * 16 + p * 256 << pixel_shift),
-                                                   linesize);
+                                h->h264dsp.h264_add_pixels4_clear(dest_y + block_offset[i],
+                                                                  h->mb + (i * 16 + p * 256 << pixel_shift),
+                                                                  linesize);
                     }
                 } else {
                     h->h264dsp.h264_idct_add16intra(dest_y, block_offset,
@@ -1895,8 +2310,8 @@
             } else if (h->cbp & 15) {
                 if (transform_bypass) {
                     const int di = IS_8x8DCT(mb_type) ? 4 : 1;
-                    idct_add = IS_8x8DCT(mb_type) ? s->dsp.add_pixels8
-                                                  : s->dsp.add_pixels4;
+                    idct_add = IS_8x8DCT(mb_type) ? h->h264dsp.h264_add_pixels8_clear
+                                                  : h->h264dsp.h264_add_pixels4_clear;
                     for (i = 0; i < 16; i += di)
                         if (h->non_zero_count_cache[scan8[i + p * 16]])
                             idct_add(dest_y + block_offset[i],
@@ -1921,7 +2336,7 @@
                     // FIXME benchmark weird rule, & below
                     uint8_t *const ptr = dest_y + block_offset[i];
                     ff_svq3_add_idct_c(ptr, h->mb + i * 16 + p * 256, linesize,
-                                       s->qscale, IS_INTRA(mb_type) ? 1 : 0);
+                                       h->qscale, IS_INTRA(mb_type) ? 1 : 0);
                 }
         }
     }
@@ -1941,10 +2356,9 @@
 
 void ff_h264_hl_decode_mb(H264Context *h)
 {
-    MpegEncContext *const s = &h->s;
     const int mb_xy   = h->mb_xy;
-    const int mb_type = s->current_picture.f.mb_type[mb_xy];
-    int is_complex    = CONFIG_SMALL || h->is_complex || IS_INTRA_PCM(mb_type) || s->qscale == 0;
+    const int mb_type = h->cur_pic.f.mb_type[mb_xy];
+    int is_complex    = CONFIG_SMALL || h->is_complex || IS_INTRA_PCM(mb_type) || h->qscale == 0;
 
     if (CHROMA444) {
         if (is_complex || h->pixel_shift)
@@ -1961,15 +2375,14 @@
 
 static int pred_weight_table(H264Context *h)
 {
-    MpegEncContext *const s = &h->s;
     int list, i;
     int luma_def, chroma_def;
 
     h->use_weight             = 0;
     h->use_weight_chroma      = 0;
-    h->luma_log2_weight_denom = get_ue_golomb(&s->gb);
+    h->luma_log2_weight_denom = get_ue_golomb(&h->gb);
     if (h->sps.chroma_format_idc)
-        h->chroma_log2_weight_denom = get_ue_golomb(&s->gb);
+        h->chroma_log2_weight_denom = get_ue_golomb(&h->gb);
     luma_def   = 1 << h->luma_log2_weight_denom;
     chroma_def = 1 << h->chroma_log2_weight_denom;
 
@@ -1979,10 +2392,10 @@
         for (i = 0; i < h->ref_count[list]; i++) {
             int luma_weight_flag, chroma_weight_flag;
 
-            luma_weight_flag = get_bits1(&s->gb);
+            luma_weight_flag = get_bits1(&h->gb);
             if (luma_weight_flag) {
-                h->luma_weight[i][list][0] = get_se_golomb(&s->gb);
-                h->luma_weight[i][list][1] = get_se_golomb(&s->gb);
+                h->luma_weight[i][list][0] = get_se_golomb(&h->gb);
+                h->luma_weight[i][list][1] = get_se_golomb(&h->gb);
                 if (h->luma_weight[i][list][0] != luma_def ||
                     h->luma_weight[i][list][1] != 0) {
                     h->use_weight             = 1;
@@ -1994,12 +2407,12 @@
             }
 
             if (h->sps.chroma_format_idc) {
-                chroma_weight_flag = get_bits1(&s->gb);
+                chroma_weight_flag = get_bits1(&h->gb);
                 if (chroma_weight_flag) {
                     int j;
                     for (j = 0; j < 2; j++) {
-                        h->chroma_weight[i][list][j][0] = get_se_golomb(&s->gb);
-                        h->chroma_weight[i][list][j][1] = get_se_golomb(&s->gb);
+                        h->chroma_weight[i][list][j][0] = get_se_golomb(&h->gb);
+                        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;
@@ -2029,7 +2442,6 @@
  */
 static void implicit_weight_table(H264Context *h, int field)
 {
-    MpegEncContext *const s = &h->s;
     int ref0, ref1, i, cur_poc, ref_start, ref_count0, ref_count1;
 
     for (i = 0; i < 2; i++) {
@@ -2038,10 +2450,10 @@
     }
 
     if (field < 0) {
-        if (s->picture_structure == PICT_FRAME) {
-            cur_poc = s->current_picture_ptr->poc;
+        if (h->picture_structure == PICT_FRAME) {
+            cur_poc = h->cur_pic_ptr->poc;
         } else {
-            cur_poc = s->current_picture_ptr->field_poc[s->picture_structure - 1];
+            cur_poc = h->cur_pic_ptr->field_poc[h->picture_structure - 1];
         }
         if (h->ref_count[0] == 1 && h->ref_count[1] == 1 && !FRAME_MBAFF &&
             h->ref_list[0][0].poc + h->ref_list[1][0].poc == 2 * cur_poc) {
@@ -2053,7 +2465,7 @@
         ref_count0 = h->ref_count[0];
         ref_count1 = h->ref_count[1];
     } else {
-        cur_poc    = s->current_picture_ptr->field_poc[field];
+        cur_poc    = h->cur_pic_ptr->field_poc[field];
         ref_start  = 16;
         ref_count0 = 16 + 2 * h->ref_count[0];
         ref_count1 = 16 + 2 * h->ref_count[1];
@@ -2105,34 +2517,68 @@
 }
 
 /* forget old pics after a seek */
-static void flush_dpb(AVCodecContext *avctx)
+static void flush_change(H264Context *h)
 {
-    H264Context *h = avctx->priv_data;
-    int i;
-    for (i=0; i<=MAX_DELAYED_PIC_COUNT; i++) {
-        if (h->delayed_pic[i])
-            h->delayed_pic[i]->f.reference = 0;
-        h->delayed_pic[i] = NULL;
-    }
+    int i, j;
+
     h->outputed_poc = h->next_outputed_poc = INT_MIN;
     h->prev_interlaced_frame = 1;
     idr(h);
     h->prev_frame_num = -1;
-    if (h->s.current_picture_ptr)
-        h->s.current_picture_ptr->f.reference = 0;
-    h->s.first_field = 0;
+    if (h->cur_pic_ptr) {
+        h->cur_pic_ptr->f.reference = 0;
+        for (j=i=0; h->delayed_pic[i]; i++)
+            if (h->delayed_pic[i] != h->cur_pic_ptr)
+                h->delayed_pic[j++] = h->delayed_pic[i];
+        h->delayed_pic[j] = NULL;
+    }
+    h->first_field = 0;
+    memset(h->ref_list[0], 0, sizeof(h->ref_list[0]));
+    memset(h->ref_list[1], 0, sizeof(h->ref_list[1]));
+    memset(h->default_ref_list[0], 0, sizeof(h->default_ref_list[0]));
+    memset(h->default_ref_list[1], 0, sizeof(h->default_ref_list[1]));
     ff_h264_reset_sei(h);
-    ff_mpeg_flush(avctx);
     h->recovery_frame= -1;
     h->sync= 0;
+    h->list_count = 0;
+    h->current_slice = 0;
+}
+
+/* forget old pics after a seek */
+static void flush_dpb(AVCodecContext *avctx)
+{
+    H264Context *h = avctx->priv_data;
+    int i;
+
+    for (i = 0; i <= MAX_DELAYED_PIC_COUNT; i++) {
+        if (h->delayed_pic[i])
+            h->delayed_pic[i]->f.reference = 0;
+        h->delayed_pic[i] = NULL;
+    }
+
+    flush_change(h);
+
+    for (i = 0; i < h->picture_count; i++) {
+        if (h->DPB[i].f.data[0])
+            free_frame_buffer(h, &h->DPB[i]);
+    }
+    h->cur_pic_ptr = NULL;
+
+    h->mb_x = h->mb_y = 0;
+
+    h->parse_context.state             = -1;
+    h->parse_context.frame_start_found = 0;
+    h->parse_context.overread          = 0;
+    h->parse_context.overread_index    = 0;
+    h->parse_context.index             = 0;
+    h->parse_context.last_index        = 0;
 }
 
 static int init_poc(H264Context *h)
 {
-    MpegEncContext *const s = &h->s;
     const int max_frame_num = 1 << h->sps.log2_max_frame_num;
     int field_poc[2];
-    Picture *cur = s->current_picture_ptr;
+    Picture *cur = h->cur_pic_ptr;
 
     h->frame_num_offset = h->prev_frame_num_offset;
     if (h->frame_num < h->prev_frame_num)
@@ -2149,7 +2595,7 @@
             h->poc_msb = h->prev_poc_msb;
         field_poc[0] =
         field_poc[1] = h->poc_msb + h->poc_lsb;
-        if (s->picture_structure == PICT_FRAME)
+        if (h->picture_structure == PICT_FRAME)
             field_poc[1] += h->delta_poc_bottom;
     } else if (h->sps.poc_type == 1) {
         int abs_frame_num, expected_delta_per_poc_cycle, expectedpoc;
@@ -2184,7 +2630,7 @@
         field_poc[0] = expectedpoc + h->delta_poc[0];
         field_poc[1] = field_poc[0] + h->sps.offset_for_top_to_bottom_field;
 
-        if (s->picture_structure == PICT_FRAME)
+        if (h->picture_structure == PICT_FRAME)
             field_poc[1] += h->delta_poc[1];
     } else {
         int poc = 2 * (h->frame_num_offset + h->frame_num);
@@ -2196,10 +2642,10 @@
         field_poc[1] = poc;
     }
 
-    if (s->picture_structure != PICT_BOTTOM_FIELD)
-        s->current_picture_ptr->field_poc[0] = field_poc[0];
-    if (s->picture_structure != PICT_TOP_FIELD)
-        s->current_picture_ptr->field_poc[1] = field_poc[1];
+    if (h->picture_structure != PICT_BOTTOM_FIELD)
+        h->cur_pic_ptr->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]);
 
     return 0;
@@ -2244,21 +2690,20 @@
 
 static int field_end(H264Context *h, int in_setup)
 {
-    MpegEncContext *const s     = &h->s;
-    AVCodecContext *const avctx = s->avctx;
+    AVCodecContext *const avctx = h->avctx;
     int err = 0;
-    s->mb_y = 0;
+    h->mb_y = 0;
 
-    if (!in_setup && !s->dropable)
-        ff_thread_report_progress(&s->current_picture_ptr->f, INT_MAX,
-                                  s->picture_structure == PICT_BOTTOM_FIELD);
+    if (!in_setup && !h->droppable)
+        ff_thread_report_progress(&h->cur_pic_ptr->f, INT_MAX,
+                                  h->picture_structure == PICT_BOTTOM_FIELD);
 
     if (CONFIG_H264_VDPAU_DECODER &&
-        s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)
-        ff_vdpau_h264_set_reference_frames(s);
+        h->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)
+        ff_vdpau_h264_set_reference_frames(h);
 
     if (in_setup || !(avctx->active_thread_type & FF_THREAD_FRAME)) {
-        if (!s->dropable) {
+        if (!h->droppable) {
             err = ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index);
             h->prev_poc_msb = h->poc_msb;
             h->prev_poc_lsb = h->poc_lsb;
@@ -2275,8 +2720,8 @@
     }
 
     if (CONFIG_H264_VDPAU_DECODER &&
-        s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)
-        ff_vdpau_h264_picture_complete(s);
+        h->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)
+        ff_vdpau_h264_picture_complete(h);
 
     /*
      * FIXME: Error handling code does not seem to support interlaced
@@ -2290,10 +2735,11 @@
      * past end by one (callers fault) and resync_mb_y != 0
      * causes problems for the first MB line, too.
      */
-    if (!FIELD_PICTURE)
-        ff_er_frame_end(s);
-
-    ff_MPV_frame_end(s);
+    if (!FIELD_PICTURE && h->current_slice && !h->sps.new) {
+        h->er.cur_pic  = h->cur_pic_ptr;
+        ff_er_frame_end(&h->er);
+    }
+    emms_c();
 
     h->current_slice = 0;
 
@@ -2303,14 +2749,14 @@
 /**
  * Replicate H264 "master" context to thread contexts.
  */
-static void clone_slice(H264Context *dst, H264Context *src)
+static int clone_slice(H264Context *dst, H264Context *src)
 {
     memcpy(dst->block_offset, src->block_offset, sizeof(dst->block_offset));
-    dst->s.current_picture_ptr = src->s.current_picture_ptr;
-    dst->s.current_picture     = src->s.current_picture;
-    dst->s.linesize            = src->s.linesize;
-    dst->s.uvlinesize          = src->s.uvlinesize;
-    dst->s.first_field         = src->s.first_field;
+    dst->cur_pic_ptr = src->cur_pic_ptr;
+    dst->cur_pic     = src->cur_pic;
+    dst->linesize    = src->linesize;
+    dst->uvlinesize  = src->uvlinesize;
+    dst->first_field = src->first_field;
 
     dst->prev_poc_msb          = src->prev_poc_msb;
     dst->prev_poc_lsb          = src->prev_poc_lsb;
@@ -2321,10 +2767,11 @@
     memcpy(dst->short_ref,        src->short_ref,        sizeof(dst->short_ref));
     memcpy(dst->long_ref,         src->long_ref,         sizeof(dst->long_ref));
     memcpy(dst->default_ref_list, src->default_ref_list, sizeof(dst->default_ref_list));
-    memcpy(dst->ref_list,         src->ref_list,         sizeof(dst->ref_list));
 
     memcpy(dst->dequant4_coeff,   src->dequant4_coeff,   sizeof(src->dequant4_coeff));
     memcpy(dst->dequant8_coeff,   src->dequant8_coeff,   sizeof(src->dequant8_coeff));
+
+    return 0;
 }
 
 /**
@@ -2354,6 +2801,250 @@
     return profile;
 }
 
+static int h264_set_parameter_from_sps(H264Context *h)
+{
+    if (h->flags & CODEC_FLAG_LOW_DELAY ||
+        (h->sps.bitstream_restriction_flag &&
+         !h->sps.num_reorder_frames)) {
+        if (h->avctx->has_b_frames > 1 || h->delayed_pic[0])
+            av_log(h->avctx, AV_LOG_WARNING, "Delayed frames seen. "
+                   "Reenabling low delay requires a codec flush.\n");
+        else
+            h->low_delay = 1;
+    }
+
+    if (h->avctx->has_b_frames < 2)
+        h->avctx->has_b_frames = !h->low_delay;
+
+    if (h->avctx->bits_per_raw_sample != h->sps.bit_depth_luma ||
+        h->cur_chroma_format_idc      != h->sps.chroma_format_idc) {
+        if (h->avctx->codec &&
+            h->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU &&
+            (h->sps.bit_depth_luma != 8 || h->sps.chroma_format_idc > 1)) {
+            av_log(h->avctx, AV_LOG_ERROR,
+                   "VDPAU decoding does not support video colorspace.\n");
+            return AVERROR_INVALIDDATA;
+        }
+        if (h->sps.bit_depth_luma >= 8 && h->sps.bit_depth_luma <= 14 &&
+            h->sps.bit_depth_luma != 11 && h->sps.bit_depth_luma != 13 &&
+                (h->sps.bit_depth_luma != 9 || !CHROMA422)) {
+            h->avctx->bits_per_raw_sample = h->sps.bit_depth_luma;
+            h->cur_chroma_format_idc      = h->sps.chroma_format_idc;
+            h->pixel_shift                = h->sps.bit_depth_luma > 8;
+
+            ff_h264dsp_init(&h->h264dsp, h->sps.bit_depth_luma,
+                            h->sps.chroma_format_idc);
+            ff_h264chroma_init(&h->h264chroma, h->sps.bit_depth_chroma);
+            ff_h264qpel_init(&h->h264qpel, h->sps.bit_depth_luma);
+            ff_h264_pred_init(&h->hpc, h->avctx->codec_id, h->sps.bit_depth_luma,
+                              h->sps.chroma_format_idc);
+            h->dsp.dct_bits = h->sps.bit_depth_luma > 8 ? 32 : 16;
+            ff_dsputil_init(&h->dsp, h->avctx);
+            ff_videodsp_init(&h->vdsp, h->sps.bit_depth_luma);
+        } else {
+            av_log(h->avctx, AV_LOG_ERROR, "Unsupported bit depth: %d\n",
+                   h->sps.bit_depth_luma);
+            return AVERROR_INVALIDDATA;
+        }
+    }
+    return 0;
+}
+
+static enum PixelFormat get_pixel_format(H264Context *h, int force_callback)
+{
+    switch (h->sps.bit_depth_luma) {
+    case 9:
+        if (CHROMA444) {
+            if (h->avctx->colorspace == AVCOL_SPC_RGB) {
+                return AV_PIX_FMT_GBRP9;
+            } else
+                return AV_PIX_FMT_YUV444P9;
+        } else if (CHROMA422)
+            return AV_PIX_FMT_YUV422P9;
+        else
+            return AV_PIX_FMT_YUV420P9;
+        break;
+    case 10:
+        if (CHROMA444) {
+            if (h->avctx->colorspace == AVCOL_SPC_RGB) {
+                return AV_PIX_FMT_GBRP10;
+            } else
+                return AV_PIX_FMT_YUV444P10;
+        } else if (CHROMA422)
+            return AV_PIX_FMT_YUV422P10;
+        else
+            return AV_PIX_FMT_YUV420P10;
+        break;
+    case 12:
+        if (CHROMA444) {
+            if (h->avctx->colorspace == AVCOL_SPC_RGB) {
+                return AV_PIX_FMT_GBRP12;
+            } else
+                return AV_PIX_FMT_YUV444P12;
+        } else if (CHROMA422)
+            return AV_PIX_FMT_YUV422P12;
+        else
+            return AV_PIX_FMT_YUV420P12;
+        break;
+    case 14:
+        if (CHROMA444) {
+            if (h->avctx->colorspace == AVCOL_SPC_RGB) {
+                return AV_PIX_FMT_GBRP14;
+            } else
+                return AV_PIX_FMT_YUV444P14;
+        } else if (CHROMA422)
+            return AV_PIX_FMT_YUV422P14;
+        else
+            return AV_PIX_FMT_YUV420P14;
+        break;
+    case 8:
+        if (CHROMA444) {
+            if (h->avctx->colorspace == AVCOL_SPC_RGB) {
+                av_log(h->avctx, AV_LOG_DEBUG, "Detected GBR colorspace.\n");
+                return AV_PIX_FMT_GBR24P;
+            } else if (h->avctx->colorspace == AVCOL_SPC_YCGCO) {
+                av_log(h->avctx, AV_LOG_WARNING, "Detected unsupported YCgCo colorspace.\n");
+            }
+            return h->avctx->color_range == AVCOL_RANGE_JPEG ? AV_PIX_FMT_YUVJ444P
+                                                                : AV_PIX_FMT_YUV444P;
+        } else if (CHROMA422) {
+            return h->avctx->color_range == AVCOL_RANGE_JPEG ? AV_PIX_FMT_YUVJ422P
+                                                             : AV_PIX_FMT_YUV422P;
+        } else {
+            int i;
+            const enum AVPixelFormat * fmt = h->avctx->codec->pix_fmts ?
+                                        h->avctx->codec->pix_fmts :
+                                        h->avctx->color_range == AVCOL_RANGE_JPEG ?
+                                        hwaccel_pixfmt_list_h264_jpeg_420 :
+                                        hwaccel_pixfmt_list_h264_420;
+
+            for (i=0; fmt[i] != AV_PIX_FMT_NONE; i++)
+                if (fmt[i] == h->avctx->pix_fmt && !force_callback)
+                    return fmt[i];
+            return h->avctx->get_format(h->avctx, fmt);
+        }
+        break;
+    default:
+        av_log(h->avctx, AV_LOG_ERROR,
+               "Unsupported bit depth: %d\n", h->sps.bit_depth_luma);
+        return AVERROR_INVALIDDATA;
+    }
+}
+
+static int h264_slice_header_init(H264Context *h, int reinit)
+{
+    int nb_slices = (HAVE_THREADS &&
+                     h->avctx->active_thread_type & FF_THREAD_SLICE) ?
+                    h->avctx->thread_count : 1;
+    int i;
+
+    if(    FFALIGN(h->avctx->width , 16                                 ) == h->width
+        && FFALIGN(h->avctx->height, 16*(2 - h->sps.frame_mbs_only_flag)) == h->height
+        && !h->sps.crop_right && !h->sps.crop_bottom
+        && (h->avctx->width != h->width || h->avctx->height && h->height)
+    ) {
+        av_log(h->avctx, AV_LOG_DEBUG, "Using externally provided dimensions\n");
+        h->avctx->coded_width  = h->width;
+        h->avctx->coded_height = h->height;
+    } else{
+        avcodec_set_dimensions(h->avctx, h->width, h->height);
+        h->avctx->width  -= (2>>CHROMA444)*FFMIN(h->sps.crop_right, (8<<CHROMA444)-1);
+        h->avctx->height -= (1<<h->chroma_y_shift)*FFMIN(h->sps.crop_bottom, (16>>h->chroma_y_shift)-1) * (2 - h->sps.frame_mbs_only_flag);
+    }
+
+    h->avctx->sample_aspect_ratio = h->sps.sar;
+    av_assert0(h->avctx->sample_aspect_ratio.den);
+    av_pix_fmt_get_chroma_sub_sample(h->avctx->pix_fmt,
+                                     &h->chroma_x_shift, &h->chroma_y_shift);
+
+    if (h->sps.timing_info_present_flag) {
+        int64_t den = h->sps.time_scale;
+        if (h->x264_build < 44U)
+            den *= 2;
+        av_reduce(&h->avctx->time_base.num, &h->avctx->time_base.den,
+                  h->sps.num_units_in_tick, den, 1 << 30);
+    }
+
+    h->avctx->hwaccel = ff_find_hwaccel(h->avctx->codec->id, h->avctx->pix_fmt);
+
+    if (reinit)
+        free_tables(h, 0);
+    h->first_field = 0;
+    h->prev_interlaced_frame = 1;
+
+    init_scan_tables(h);
+    if (ff_h264_alloc_tables(h) < 0) {
+        av_log(h->avctx, AV_LOG_ERROR,
+               "Could not allocate memory for h264\n");
+        return AVERROR(ENOMEM);
+    }
+
+    if (nb_slices > MAX_THREADS || (nb_slices > h->mb_height && h->mb_height)) {
+        int max_slices;
+        if (h->mb_height)
+            max_slices = FFMIN(MAX_THREADS, h->mb_height);
+        else
+            max_slices = MAX_THREADS;
+        av_log(h->avctx, AV_LOG_WARNING, "too many threads/slices (%d),"
+               " reducing to %d\n", nb_slices, max_slices);
+        nb_slices = max_slices;
+    }
+    h->slice_context_count = nb_slices;
+
+    if (!HAVE_THREADS || !(h->avctx->active_thread_type & FF_THREAD_SLICE)) {
+        if (context_init(h) < 0) {
+            av_log(h->avctx, AV_LOG_ERROR, "context_init() failed.\n");
+            return -1;
+        }
+    } 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->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->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->chroma_x_shift = h->chroma_x_shift;
+            c->chroma_y_shift = h->chroma_y_shift;
+            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;
+
+            init_scan_tables(c);
+            clone_tables(c, h, i);
+            c->context_initialized = 1;
+        }
+
+        for (i = 0; i < h->slice_context_count; i++)
+            if (context_init(h->thread_context[i]) < 0) {
+                av_log(h->avctx, AV_LOG_ERROR, "context_init() failed.\n");
+                return -1;
+            }
+    }
+
+    h->context_initialized = 1;
+
+    return 0;
+}
+
 /**
  * Decode a slice header.
  * This will also call ff_MPV_common_init() and frame_start() as needed.
@@ -2366,27 +3057,19 @@
  */
 static int decode_slice_header(H264Context *h, H264Context *h0)
 {
-    MpegEncContext *const s  = &h->s;
-    MpegEncContext *const s0 = &h0->s;
     unsigned int first_mb_in_slice;
     unsigned int pps_id;
-    int num_ref_idx_active_override_flag;
+    int num_ref_idx_active_override_flag, ret;
     unsigned int slice_type, tmp, i, j;
     int default_ref_list_done = 0;
-    int last_pic_structure, last_pic_dropable;
+    int last_pic_structure, last_pic_droppable;
     int must_reinit;
+    int needs_reinit = 0;
 
-    /* FIXME: 2tap qpel isn't implemented for high bit depth. */
-    if ((s->avctx->flags2 & CODEC_FLAG2_FAST) &&
-        !h->nal_ref_idc && !h->pixel_shift) {
-        s->me.qpel_put = s->dsp.put_2tap_qpel_pixels_tab;
-        s->me.qpel_avg = s->dsp.avg_2tap_qpel_pixels_tab;
-    } else {
-        s->me.qpel_put = s->dsp.put_h264_qpel_pixels_tab;
-        s->me.qpel_avg = s->dsp.avg_h264_qpel_pixels_tab;
-    }
+    h->me.qpel_put = h->h264qpel.put_h264_qpel_pixels_tab;
+    h->me.qpel_avg = h->h264qpel.avg_h264_qpel_pixels_tab;
 
-    first_mb_in_slice = get_ue_golomb_long(&s->gb);
+    first_mb_in_slice = get_ue_golomb_long(&h->gb);
 
     if (first_mb_in_slice == 0) { // FIXME better field boundary detection
         if (h0->current_slice && FIELD_PICTURE) {
@@ -2394,21 +3077,21 @@
         }
 
         h0->current_slice = 0;
-        if (!s0->first_field) {
-            if (s->current_picture_ptr && !s->dropable &&
-                s->current_picture_ptr->owner2 == s) {
-                ff_thread_report_progress(&s->current_picture_ptr->f, INT_MAX,
-                                          s->picture_structure == PICT_BOTTOM_FIELD);
+        if (!h0->first_field) {
+            if (h->cur_pic_ptr && !h->droppable &&
+                h->cur_pic_ptr->owner2 == h) {
+                ff_thread_report_progress(&h->cur_pic_ptr->f, INT_MAX,
+                                          h->picture_structure == PICT_BOTTOM_FIELD);
             }
-            s->current_picture_ptr = NULL;
+            h->cur_pic_ptr = NULL;
         }
     }
 
-    slice_type = get_ue_golomb_31(&s->gb);
+    slice_type = get_ue_golomb_31(&h->gb);
     if (slice_type > 9) {
-        av_log(h->s.avctx, AV_LOG_ERROR,
+        av_log(h->avctx, AV_LOG_ERROR,
                "slice type too large (%d) at %d %d\n",
-               slice_type, s->mb_x, s->mb_y);
+               slice_type, h->mb_x, h->mb_y);
         return -1;
     }
     if (slice_type > 4) {
@@ -2419,22 +3102,24 @@
 
     slice_type = golomb_to_pict_type[slice_type];
     if (slice_type == AV_PICTURE_TYPE_I ||
-        (h0->current_slice != 0 && slice_type == h0->last_slice_type)) {
+        (h0->current_slice != 0 &&
+         slice_type == h0->last_slice_type &&
+         !memcmp(h0->last_ref_count, h0->ref_count, sizeof(h0->ref_count)))) {
         default_ref_list_done = 1;
     }
     h->slice_type     = slice_type;
     h->slice_type_nos = slice_type & 3;
 
     // to make a few old functions happy, it's wrong though
-    s->pict_type = h->slice_type;
+    h->pict_type = h->slice_type;
 
-    pps_id = get_ue_golomb(&s->gb);
+    pps_id = get_ue_golomb(&h->gb);
     if (pps_id >= MAX_PPS_COUNT) {
-        av_log(h->s.avctx, AV_LOG_ERROR, "pps_id %d out of range\n", pps_id);
+        av_log(h->avctx, AV_LOG_ERROR, "pps_id %d out of range\n", pps_id);
         return -1;
     }
     if (!h0->pps_buffers[pps_id]) {
-        av_log(h->s.avctx, AV_LOG_ERROR,
+        av_log(h->avctx, AV_LOG_ERROR,
                "non-existing PPS %u referenced\n",
                pps_id);
         return -1;
@@ -2442,231 +3127,114 @@
     h->pps = *h0->pps_buffers[pps_id];
 
     if (!h0->sps_buffers[h->pps.sps_id]) {
-        av_log(h->s.avctx, AV_LOG_ERROR,
+        av_log(h->avctx, AV_LOG_ERROR,
                "non-existing SPS %u referenced\n",
                h->pps.sps_id);
         return -1;
     }
-    h->sps = *h0->sps_buffers[h->pps.sps_id];
 
-    s->avctx->profile = ff_h264_get_profile(&h->sps);
-    s->avctx->level   = h->sps.level_idc;
-    s->avctx->refs    = h->sps.ref_frame_count;
+    if (h->pps.sps_id != h->current_sps_id ||
+        h0->sps_buffers[h->pps.sps_id]->new) {
+        h0->sps_buffers[h->pps.sps_id]->new = 0;
 
-    must_reinit = (s->context_initialized &&
-                    (   16*h->sps.mb_width != s->avctx->coded_width
-                     || 16*h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag) != s->avctx->coded_height
-                     || s->avctx->bits_per_raw_sample != h->sps.bit_depth_luma
+        h->current_sps_id = h->pps.sps_id;
+        h->sps            = *h0->sps_buffers[h->pps.sps_id];
+
+        if (h->mb_width  != h->sps.mb_width ||
+            h->mb_height != h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag) ||
+            h->avctx->bits_per_raw_sample != h->sps.bit_depth_luma ||
+            h->cur_chroma_format_idc != h->sps.chroma_format_idc
+        )
+            needs_reinit = 1;
+
+        if (h->bit_depth_luma    != h->sps.bit_depth_luma ||
+            h->chroma_format_idc != h->sps.chroma_format_idc) {
+            h->bit_depth_luma    = h->sps.bit_depth_luma;
+            h->chroma_format_idc = h->sps.chroma_format_idc;
+            needs_reinit         = 1;
+        }
+        if ((ret = h264_set_parameter_from_sps(h)) < 0)
+            return ret;
+    }
+
+    h->avctx->profile = ff_h264_get_profile(&h->sps);
+    h->avctx->level   = h->sps.level_idc;
+    h->avctx->refs    = h->sps.ref_frame_count;
+
+    must_reinit = (h->context_initialized &&
+                    (   16*h->sps.mb_width != h->avctx->coded_width
+                     || 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, s->avctx->sample_aspect_ratio)));
+                     || av_cmp_q(h->sps.sar, h->avctx->sample_aspect_ratio)));
+    if (h0->avctx->pix_fmt != get_pixel_format(h0, 0))
+        must_reinit = 1;
 
-    if(must_reinit && (h != h0 || (s->avctx->active_thread_type & FF_THREAD_FRAME))) {
-        av_log_missing_feature(s->avctx,
-                                "Width/height/bit depth/chroma idc changing with threads", 0);
-        return AVERROR_PATCHWELCOME;   // width / height changed during parallelized decoding
+    h->mb_width  = h->sps.mb_width;
+    h->mb_height = h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag);
+    h->mb_num    = h->mb_width * h->mb_height;
+    h->mb_stride = h->mb_width + 1;
+
+    h->b_stride = h->mb_width * 4;
+
+    h->chroma_y_shift = h->sps.chroma_format_idc <= 1; // 400 uses yuv420p
+
+    h->width  = 16 * h->mb_width;
+    h->height = 16 * h->mb_height;
+
+    if (h->sps.video_signal_type_present_flag) {
+        h->avctx->color_range = h->sps.full_range>0 ? AVCOL_RANGE_JPEG
+                                                    : AVCOL_RANGE_MPEG;
+        if (h->sps.colour_description_present_flag) {
+            if (h->avctx->colorspace != h->sps.colorspace)
+                needs_reinit = 1;
+            h->avctx->color_primaries = h->sps.color_primaries;
+            h->avctx->color_trc       = h->sps.color_trc;
+            h->avctx->colorspace      = h->sps.colorspace;
+        }
     }
 
-    s->mb_width  = h->sps.mb_width;
-    s->mb_height = h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag);
+    if (h->context_initialized &&
+        (
+         needs_reinit                   ||
+         must_reinit)) {
 
-    h->b_stride = s->mb_width * 4;
-
-    s->chroma_y_shift = h->sps.chroma_format_idc <= 1; // 400 uses yuv420p
-
-    s->width  = 16 * s->mb_width;
-    s->height = 16 * s->mb_height;
-
-    if(must_reinit) {
-        free_tables(h, 0);
-        flush_dpb(s->avctx);
-        ff_MPV_common_end(s);
-        h->list_count = 0;
-        h->current_slice = 0;
-    }
-    if (!s->context_initialized) {
         if (h != h0) {
-            av_log(h->s.avctx, AV_LOG_ERROR,
-                   "Cannot (re-)initialize context during parallel decoding.\n");
-            return -1;
-        }
-        if(   FFALIGN(s->avctx->width , 16                                 ) == s->width
-           && FFALIGN(s->avctx->height, 16*(2 - h->sps.frame_mbs_only_flag)) == s->height
-           && !h->sps.crop_right && !h->sps.crop_bottom
-           && (s->avctx->width != s->width || s->avctx->height && s->height)
-        ) {
-            av_log(h->s.avctx, AV_LOG_DEBUG, "Using externally provided dimensions\n");
-            s->avctx->coded_width  = s->width;
-            s->avctx->coded_height = s->height;
-        } else{
-            avcodec_set_dimensions(s->avctx, s->width, s->height);
-            s->avctx->width  -= (2>>CHROMA444)*FFMIN(h->sps.crop_right, (8<<CHROMA444)-1);
-            s->avctx->height -= (1<<s->chroma_y_shift)*FFMIN(h->sps.crop_bottom, (16>>s->chroma_y_shift)-1) * (2 - h->sps.frame_mbs_only_flag);
-        }
-        s->avctx->sample_aspect_ratio = h->sps.sar;
-        av_assert0(s->avctx->sample_aspect_ratio.den);
-
-        if (s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU
-            && (h->sps.bit_depth_luma != 8 ||
-                h->sps.chroma_format_idc > 1)) {
-            av_log(s->avctx, AV_LOG_ERROR,
-                   "VDPAU decoding does not support video "
-                   "colorspace\n");
-            return -1;
-        }
-
-        if (s->avctx->bits_per_raw_sample != h->sps.bit_depth_luma ||
-            h->cur_chroma_format_idc != h->sps.chroma_format_idc) {
-            if (h->sps.bit_depth_luma >= 8 && h->sps.bit_depth_luma <= 14 && h->sps.bit_depth_luma != 11 && h->sps.bit_depth_luma != 13 &&
-                (h->sps.bit_depth_luma != 9 || !CHROMA422)) {
-                s->avctx->bits_per_raw_sample = h->sps.bit_depth_luma;
-                h->cur_chroma_format_idc = h->sps.chroma_format_idc;
-                h->pixel_shift = h->sps.bit_depth_luma > 8;
-
-                ff_h264dsp_init(&h->h264dsp, h->sps.bit_depth_luma, h->sps.chroma_format_idc);
-                ff_h264_pred_init(&h->hpc, s->codec_id, h->sps.bit_depth_luma, h->sps.chroma_format_idc);
-                s->dsp.dct_bits = h->sps.bit_depth_luma > 8 ? 32 : 16;
-                ff_dsputil_init(&s->dsp, s->avctx);
-            } else {
-                av_log(s->avctx, AV_LOG_ERROR, "Unsupported bit depth: %d chroma_idc: %d\n",
-                       h->sps.bit_depth_luma, h->sps.chroma_format_idc);
-                return -1;
-            }
-        }
-
-        if (h->sps.video_signal_type_present_flag) {
-            s->avctx->color_range = h->sps.full_range>0 ? AVCOL_RANGE_JPEG
-                                                      : AVCOL_RANGE_MPEG;
-            if (h->sps.colour_description_present_flag) {
-                s->avctx->color_primaries = h->sps.color_primaries;
-                s->avctx->color_trc       = h->sps.color_trc;
-                s->avctx->colorspace      = h->sps.colorspace;
-            }
-        }
-
-        if (h->sps.timing_info_present_flag) {
-            int64_t den = h->sps.time_scale;
-            if (h->x264_build < 44U)
-                den *= 2;
-            av_reduce(&s->avctx->time_base.num, &s->avctx->time_base.den,
-                      h->sps.num_units_in_tick, den, 1 << 30);
-        }
-
-        switch (h->sps.bit_depth_luma) {
-        case 9:
-            if (CHROMA444) {
-                if (s->avctx->colorspace == AVCOL_SPC_RGB) {
-                    s->avctx->pix_fmt = AV_PIX_FMT_GBRP9;
-                } else
-                    s->avctx->pix_fmt = AV_PIX_FMT_YUV444P9;
-            } else if (CHROMA422)
-                s->avctx->pix_fmt = AV_PIX_FMT_YUV422P9;
-            else
-                s->avctx->pix_fmt = AV_PIX_FMT_YUV420P9;
-            break;
-        case 10:
-            if (CHROMA444) {
-                if (s->avctx->colorspace == AVCOL_SPC_RGB) {
-                    s->avctx->pix_fmt = AV_PIX_FMT_GBRP10;
-                } else
-                    s->avctx->pix_fmt = AV_PIX_FMT_YUV444P10;
-            } else if (CHROMA422)
-                s->avctx->pix_fmt = AV_PIX_FMT_YUV422P10;
-            else
-                s->avctx->pix_fmt = AV_PIX_FMT_YUV420P10;
-            break;
-        case 12:
-            if (CHROMA444) {
-                if (s->avctx->colorspace == AVCOL_SPC_RGB) {
-                    s->avctx->pix_fmt = AV_PIX_FMT_GBRP12;
-                } else
-                    s->avctx->pix_fmt = AV_PIX_FMT_YUV444P12;
-            } else if (CHROMA422)
-                s->avctx->pix_fmt = AV_PIX_FMT_YUV422P12;
-            else
-                s->avctx->pix_fmt = AV_PIX_FMT_YUV420P12;
-            break;
-        case 14:
-            if (CHROMA444) {
-                if (s->avctx->colorspace == AVCOL_SPC_RGB) {
-                    s->avctx->pix_fmt = AV_PIX_FMT_GBRP14;
-                } else
-                    s->avctx->pix_fmt = AV_PIX_FMT_YUV444P14;
-            } else if (CHROMA422)
-                s->avctx->pix_fmt = AV_PIX_FMT_YUV422P14;
-            else
-                s->avctx->pix_fmt = AV_PIX_FMT_YUV420P14;
-            break;
-        case 8:
-            if (CHROMA444) {
-                    s->avctx->pix_fmt = s->avctx->color_range == AVCOL_RANGE_JPEG ? AV_PIX_FMT_YUVJ444P
-                                                                                  : AV_PIX_FMT_YUV444P;
-                    if (s->avctx->colorspace == AVCOL_SPC_RGB) {
-                        s->avctx->pix_fmt = AV_PIX_FMT_GBR24P;
-                        av_log(h->s.avctx, AV_LOG_DEBUG, "Detected GBR colorspace.\n");
-                    } else if (s->avctx->colorspace == AVCOL_SPC_YCGCO) {
-                        av_log(h->s.avctx, AV_LOG_WARNING, "Detected unsupported YCgCo colorspace.\n");
-                    }
-            } else if (CHROMA422) {
-                s->avctx->pix_fmt = s->avctx->color_range == AVCOL_RANGE_JPEG ? AV_PIX_FMT_YUVJ422P
-                                                                              : AV_PIX_FMT_YUV422P;
-            } else {
-                s->avctx->pix_fmt = s->avctx->get_format(s->avctx,
-                                                         s->avctx->codec->pix_fmts ?
-                                                         s->avctx->codec->pix_fmts :
-                                                         s->avctx->color_range == AVCOL_RANGE_JPEG ?
-                                                         hwaccel_pixfmt_list_h264_jpeg_420 :
-                                                         ff_hwaccel_pixfmt_list_420);
-            }
-            break;
-        default:
-            av_log(s->avctx, AV_LOG_ERROR,
-                   "Unsupported bit depth: %d\n", h->sps.bit_depth_luma);
+            av_log(h->avctx, AV_LOG_ERROR, "changing width/height on "
+                   "slice %d\n", h0->current_slice + 1);
             return AVERROR_INVALIDDATA;
         }
 
-        s->avctx->hwaccel = ff_find_hwaccel(s->avctx->codec->id,
-                                            s->avctx->pix_fmt);
+        flush_change(h);
 
-        if (ff_MPV_common_init(s) < 0) {
-            av_log(h->s.avctx, AV_LOG_ERROR, "ff_MPV_common_init() failed.\n");
+        if ((ret = get_pixel_format(h, 1)) < 0)
+            return ret;
+        h->avctx->pix_fmt = ret;
+
+        av_log(h->avctx, AV_LOG_INFO, "Reinit context to %dx%d, "
+               "pix_fmt: %d\n", h->width, h->height, h->avctx->pix_fmt);
+
+        if ((ret = h264_slice_header_init(h, 1)) < 0) {
+            av_log(h->avctx, AV_LOG_ERROR,
+                   "h264_slice_header_init() failed\n");
+            return ret;
+        }
+    }
+    if (!h->context_initialized) {
+        if (h != h0) {
+            av_log(h->avctx, AV_LOG_ERROR,
+                   "Cannot (re-)initialize context during parallel decoding.\n");
             return -1;
         }
-        s->first_field = 0;
-        h->prev_interlaced_frame = 1;
 
-        init_scan_tables(h);
-        if (ff_h264_alloc_tables(h) < 0) {
-            av_log(h->s.avctx, AV_LOG_ERROR,
-                   "Could not allocate memory for h264\n");
-            return AVERROR(ENOMEM);
-        }
+        if ((ret = get_pixel_format(h, 1)) < 0)
+            return ret;
+        h->avctx->pix_fmt = ret;
 
-        if (!HAVE_THREADS || !(s->avctx->active_thread_type & FF_THREAD_SLICE)) {
-            if (context_init(h) < 0) {
-                av_log(h->s.avctx, AV_LOG_ERROR, "context_init() failed.\n");
-                return -1;
-            }
-        } else {
-            for (i = 1; i < s->slice_context_count; i++) {
-                H264Context *c;
-                c = h->thread_context[i] = av_malloc(sizeof(H264Context));
-                memcpy(c, h->s.thread_context[i], sizeof(MpegEncContext));
-                memset(&c->s + 1, 0, sizeof(H264Context) - sizeof(MpegEncContext));
-                c->h264dsp     = h->h264dsp;
-                c->sps         = h->sps;
-                c->pps         = h->pps;
-                c->pixel_shift = h->pixel_shift;
-                c->cur_chroma_format_idc = h->cur_chroma_format_idc;
-                init_scan_tables(c);
-                clone_tables(c, h, i);
-            }
-
-            for (i = 0; i < s->slice_context_count; i++)
-                if (context_init(h->thread_context[i]) < 0) {
-                    av_log(h->s.avctx, AV_LOG_ERROR,
-                           "context_init() failed.\n");
-                    return -1;
-                }
+        if ((ret = h264_slice_header_init(h, 0)) < 0) {
+            av_log(h->avctx, AV_LOG_ERROR,
+                   "h264_slice_header_init() failed\n");
+            return ret;
         }
     }
 
@@ -2675,41 +3243,41 @@
         init_dequant_tables(h);
     }
 
-    h->frame_num = get_bits(&s->gb, h->sps.log2_max_frame_num);
+    h->frame_num = get_bits(&h->gb, h->sps.log2_max_frame_num);
 
     h->mb_mbaff        = 0;
     h->mb_aff_frame    = 0;
-    last_pic_structure = s0->picture_structure;
-    last_pic_dropable  = s->dropable;
-    s->dropable        = h->nal_ref_idc == 0;
+    last_pic_structure = h0->picture_structure;
+    last_pic_droppable = h0->droppable;
+    h->droppable       = h->nal_ref_idc == 0;
     if (h->sps.frame_mbs_only_flag) {
-        s->picture_structure = PICT_FRAME;
+        h->picture_structure = PICT_FRAME;
     } else {
         if (!h->sps.direct_8x8_inference_flag && slice_type == AV_PICTURE_TYPE_B) {
-            av_log(h->s.avctx, AV_LOG_ERROR, "This stream was generated by a broken encoder, invalid 8x8 inference\n");
+            av_log(h->avctx, AV_LOG_ERROR, "This stream was generated by a broken encoder, invalid 8x8 inference\n");
             return -1;
         }
-        if (get_bits1(&s->gb)) { // field_pic_flag
-            s->picture_structure = PICT_TOP_FIELD + get_bits1(&s->gb); // bottom_field_flag
+        if (get_bits1(&h->gb)) { // field_pic_flag
+            h->picture_structure = PICT_TOP_FIELD + get_bits1(&h->gb); // bottom_field_flag
         } else {
-            s->picture_structure = PICT_FRAME;
+            h->picture_structure = PICT_FRAME;
             h->mb_aff_frame      = h->sps.mb_aff;
         }
     }
-    h->mb_field_decoding_flag = s->picture_structure != PICT_FRAME;
+    h->mb_field_decoding_flag = h->picture_structure != PICT_FRAME;
 
     if (h0->current_slice != 0) {
-        if (last_pic_structure != s->picture_structure ||
-            last_pic_dropable  != s->dropable) {
-            av_log(h->s.avctx, AV_LOG_ERROR,
+        if (last_pic_structure != h->picture_structure ||
+            last_pic_droppable != h->droppable) {
+            av_log(h->avctx, AV_LOG_ERROR,
                    "Changing field mode (%d -> %d) between slices is not allowed\n",
-                   last_pic_structure, s->picture_structure);
-            s->picture_structure = last_pic_structure;
-            s->dropable          = last_pic_dropable;
+                   last_pic_structure, h->picture_structure);
+            h->picture_structure = last_pic_structure;
+            h->droppable         = last_pic_droppable;
             return AVERROR_INVALIDDATA;
-        } else if (!s->current_picture_ptr) {
-            av_log(s->avctx, AV_LOG_ERROR,
-                   "unset current_picture_ptr on %d. slice\n",
+        } else if (!h0->cur_pic_ptr) {
+            av_log(h->avctx, AV_LOG_ERROR,
+                   "unset cur_pic_ptr on %d. slice\n",
                    h0->current_slice + 1);
             return AVERROR_INVALIDDATA;
         }
@@ -2736,55 +3304,55 @@
          * Here, we're using that to see if we should mark previously
          * decode frames as "finished".
          * We have to do that before the "dummy" in-between frame allocation,
-         * since that can modify s->current_picture_ptr. */
-        if (s0->first_field) {
-            assert(s0->current_picture_ptr);
-            assert(s0->current_picture_ptr->f.data[0]);
-            assert(s0->current_picture_ptr->f.reference != DELAYED_PIC_REF);
+         * since that can modify h->cur_pic_ptr. */
+        if (h0->first_field) {
+            assert(h0->cur_pic_ptr);
+            assert(h0->cur_pic_ptr->f.data[0]);
+            assert(h0->cur_pic_ptr->f.reference != DELAYED_PIC_REF);
 
             /* Mark old field/frame as completed */
-            if (!last_pic_dropable && s0->current_picture_ptr->owner2 == s0) {
-                ff_thread_report_progress(&s0->current_picture_ptr->f, INT_MAX,
+            if (!last_pic_droppable && h0->cur_pic_ptr->owner2 == h0) {
+                ff_thread_report_progress(&h0->cur_pic_ptr->f, INT_MAX,
                                           last_pic_structure == PICT_BOTTOM_FIELD);
             }
 
             /* figure out if we have a complementary field pair */
-            if (!FIELD_PICTURE || s->picture_structure == last_pic_structure) {
+            if (!FIELD_PICTURE || h->picture_structure == last_pic_structure) {
                 /* Previous field is unmatched. Don't display it, but let it
                  * remain for reference if marked as such. */
-                if (!last_pic_dropable && last_pic_structure != PICT_FRAME) {
-                    ff_thread_report_progress(&s0->current_picture_ptr->f, INT_MAX,
+                if (!last_pic_droppable && last_pic_structure != PICT_FRAME) {
+                    ff_thread_report_progress(&h0->cur_pic_ptr->f, INT_MAX,
                                               last_pic_structure == PICT_TOP_FIELD);
                 }
             } else {
-                if (s0->current_picture_ptr->frame_num != h->frame_num) {
+                if (h0->cur_pic_ptr->frame_num != h->frame_num) {
                     /* This and previous field were reference, but had
                      * different frame_nums. Consider this field first in
                      * pair. Throw away previous field except for reference
                      * purposes. */
-                    if (!last_pic_dropable && last_pic_structure != PICT_FRAME) {
-                        ff_thread_report_progress(&s0->current_picture_ptr->f, INT_MAX,
+                    if (!last_pic_droppable && last_pic_structure != PICT_FRAME) {
+                        ff_thread_report_progress(&h0->cur_pic_ptr->f, INT_MAX,
                                                   last_pic_structure == PICT_TOP_FIELD);
                     }
                 } else {
                     /* Second field in complementary pair */
                     if (!((last_pic_structure   == PICT_TOP_FIELD &&
-                           s->picture_structure == PICT_BOTTOM_FIELD) ||
+                           h->picture_structure == PICT_BOTTOM_FIELD) ||
                           (last_pic_structure   == PICT_BOTTOM_FIELD &&
-                           s->picture_structure == PICT_TOP_FIELD))) {
-                        av_log(s->avctx, AV_LOG_ERROR,
+                           h->picture_structure == PICT_TOP_FIELD))) {
+                        av_log(h->avctx, AV_LOG_ERROR,
                                "Invalid field mode combination %d/%d\n",
-                               last_pic_structure, s->picture_structure);
-                        s->picture_structure = last_pic_structure;
-                        s->dropable          = last_pic_dropable;
+                               last_pic_structure, h->picture_structure);
+                        h->picture_structure = last_pic_structure;
+                        h->droppable         = last_pic_droppable;
                         return AVERROR_INVALIDDATA;
-                    } else if (last_pic_dropable != s->dropable) {
-                        av_log(s->avctx, AV_LOG_ERROR,
+                    } else if (last_pic_droppable != h->droppable) {
+                        av_log(h->avctx, AV_LOG_ERROR,
                                "Cannot combine reference and non-reference fields in the same frame\n");
-                        av_log_ask_for_sample(s->avctx, NULL);
-                        s->picture_structure = last_pic_structure;
-                        s->dropable          = last_pic_dropable;
-                        return AVERROR_INVALIDDATA;
+                        av_log_ask_for_sample(h->avctx, NULL);
+                        h->picture_structure = last_pic_structure;
+                        h->droppable         = last_pic_droppable;
+                        return AVERROR_PATCHWELCOME;
                     }
 
                     /* Take ownership of this buffer. Note that if another thread owned
@@ -2793,26 +3361,31 @@
                      * on that first field (or if that was us, we just did that above).
                      * By taking ownership, we assign responsibility to ourselves to
                      * report progress on the second field. */
-                    s0->current_picture_ptr->owner2 = s0;
+                    h0->cur_pic_ptr->owner2 = h0;
                 }
             }
         }
 
-        while (h->frame_num != h->prev_frame_num && h->prev_frame_num >= 0 &&
+        while (h->frame_num != h->prev_frame_num && h->prev_frame_num >= 0 && !h0->first_field &&
                h->frame_num != (h->prev_frame_num + 1) % (1 << h->sps.log2_max_frame_num)) {
             Picture *prev = h->short_ref_count ? h->short_ref[0] : NULL;
-            av_log(h->s.avctx, AV_LOG_DEBUG, "Frame num gap %d %d\n",
+            av_log(h->avctx, AV_LOG_DEBUG, "Frame num gap %d %d\n",
                    h->frame_num, h->prev_frame_num);
+            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 (ff_h264_frame_start(h) < 0)
                 return -1;
             h->prev_frame_num++;
             h->prev_frame_num %= 1 << h->sps.log2_max_frame_num;
-            s->current_picture_ptr->frame_num = h->prev_frame_num;
-            ff_thread_report_progress(&s->current_picture_ptr->f, INT_MAX, 0);
-            ff_thread_report_progress(&s->current_picture_ptr->f, INT_MAX, 1);
-            ff_generate_sliding_window_mmcos(h);
+            h->cur_pic_ptr->frame_num = h->prev_frame_num;
+            ff_thread_report_progress(&h->cur_pic_ptr->f, INT_MAX, 0);
+            ff_thread_report_progress(&h->cur_pic_ptr->f, INT_MAX, 1);
+            if ((ret = ff_generate_sliding_window_mmcos(h, 1)) < 0 &&
+                h->avctx->err_recognition & AV_EF_EXPLODE)
+                return ret;
             if (ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index) < 0 &&
-                (s->avctx->err_recognition & AV_EF_EXPLODE))
+                (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
@@ -2824,7 +3397,7 @@
                 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,
-                                  s->avctx->pix_fmt, s->mb_width * 16, s->mb_height * 16);
+                                  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;
@@ -2834,63 +3407,72 @@
         /* See if we have a decoded first field looking for a pair...
          * We're using that to see whether to continue decoding in that
          * frame, or to allocate a new one. */
-        if (s0->first_field) {
-            assert(s0->current_picture_ptr);
-            assert(s0->current_picture_ptr->f.data[0]);
-            assert(s0->current_picture_ptr->f.reference != DELAYED_PIC_REF);
+        if (h0->first_field) {
+            assert(h0->cur_pic_ptr);
+            assert(h0->cur_pic_ptr->f.data[0]);
+            assert(h0->cur_pic_ptr->f.reference != DELAYED_PIC_REF);
 
             /* figure out if we have a complementary field pair */
-            if (!FIELD_PICTURE || s->picture_structure == last_pic_structure) {
+            if (!FIELD_PICTURE || h->picture_structure == last_pic_structure) {
                 /* Previous field is unmatched. Don't display it, but let it
                  * remain for reference if marked as such. */
-                s0->current_picture_ptr = NULL;
-                s0->first_field         = FIELD_PICTURE;
+                h0->cur_pic_ptr = NULL;
+                h0->first_field = FIELD_PICTURE;
             } else {
-                if (s0->current_picture_ptr->frame_num != h->frame_num) {
-                    ff_thread_report_progress((AVFrame*)s0->current_picture_ptr, INT_MAX,
-                                              s0->picture_structure==PICT_BOTTOM_FIELD);
+                if (h0->cur_pic_ptr->frame_num != h->frame_num) {
+                    ff_thread_report_progress((AVFrame*)h0->cur_pic_ptr, INT_MAX,
+                                              h0->picture_structure==PICT_BOTTOM_FIELD);
                     /* This and the previous field had different frame_nums.
                      * Consider this field first in pair. Throw away previous
                      * one except for reference purposes. */
-                    s0->first_field         = 1;
-                    s0->current_picture_ptr = NULL;
+                    h0->first_field = 1;
+                    h0->cur_pic_ptr = NULL;
                 } else {
                     /* Second field in complementary pair */
-                    s0->first_field = 0;
+                    h0->first_field = 0;
                 }
             }
         } else {
             /* Frame or first field in a potentially complementary pair */
-            s0->first_field = FIELD_PICTURE;
+            h0->first_field = FIELD_PICTURE;
         }
 
-        if (!FIELD_PICTURE || s0->first_field) {
+        if (!FIELD_PICTURE || h0->first_field) {
             if (ff_h264_frame_start(h) < 0) {
-                s0->first_field = 0;
+                h0->first_field = 0;
                 return -1;
             }
         } else {
-            ff_release_unused_pictures(s, 0);
+            release_unused_pictures(h, 0);
         }
     }
-    if (h != h0)
-        clone_slice(h, h0);
+    if (h != h0 && (ret = clone_slice(h, h0)) < 0)
+        return ret;
 
-    s->current_picture_ptr->frame_num = h->frame_num; // FIXME frame_num cleanup
+    /* can't be in alloc_tables because linesize isn't known there.
+     * FIXME: redo bipred weight to not require extra buffer? */
+    for (i = 0; i < h->slice_context_count; i++)
+        if (h->thread_context[i]) {
+            ret = alloc_scratch_buffers(h->thread_context[i], h->linesize);
+            if (ret < 0)
+                return ret;
+        }
 
-    av_assert1(s->mb_num == s->mb_width * s->mb_height);
-    if (first_mb_in_slice << FIELD_OR_MBAFF_PICTURE >= s->mb_num ||
-        first_mb_in_slice >= s->mb_num) {
-        av_log(h->s.avctx, AV_LOG_ERROR, "first_mb_in_slice overflow\n");
+    h->cur_pic_ptr->frame_num = h->frame_num; // FIXME frame_num cleanup
+
+    av_assert1(h->mb_num == h->mb_width * h->mb_height);
+    if (first_mb_in_slice << FIELD_OR_MBAFF_PICTURE >= 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;
     }
-    s->resync_mb_x = s->mb_x =  first_mb_in_slice % s->mb_width;
-    s->resync_mb_y = s->mb_y = (first_mb_in_slice / s->mb_width) << FIELD_OR_MBAFF_PICTURE;
-    if (s->picture_structure == PICT_BOTTOM_FIELD)
-        s->resync_mb_y = s->mb_y = s->mb_y + 1;
-    av_assert1(s->mb_y < s->mb_height);
+    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;
+    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);
 
-    if (s->picture_structure == PICT_FRAME) {
+    if (h->picture_structure == PICT_FRAME) {
         h->curr_pic_num = h->frame_num;
         h->max_pic_num  = 1 << h->sps.log2_max_frame_num;
     } else {
@@ -2899,26 +3481,26 @@
     }
 
     if (h->nal_unit_type == NAL_IDR_SLICE)
-        get_ue_golomb(&s->gb); /* idr_pic_id */
+        get_ue_golomb(&h->gb); /* idr_pic_id */
 
     if (h->sps.poc_type == 0) {
-        h->poc_lsb = get_bits(&s->gb, h->sps.log2_max_poc_lsb);
+        h->poc_lsb = get_bits(&h->gb, h->sps.log2_max_poc_lsb);
 
-        if (h->pps.pic_order_present == 1 && s->picture_structure == PICT_FRAME)
-            h->delta_poc_bottom = get_se_golomb(&s->gb);
+        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(&s->gb);
+        h->delta_poc[0] = get_se_golomb(&h->gb);
 
-        if (h->pps.pic_order_present == 1 && s->picture_structure == PICT_FRAME)
-            h->delta_poc[1] = get_se_golomb(&s->gb);
+        if (h->pps.pic_order_present == 1 && h->picture_structure == PICT_FRAME)
+            h->delta_poc[1] = get_se_golomb(&h->gb);
     }
 
     init_poc(h);
 
     if (h->pps.redundant_pic_cnt_present)
-        h->redundant_pic_count = get_ue_golomb(&s->gb);
+        h->redundant_pic_count = get_ue_golomb(&h->gb);
 
     // set defaults, might be overridden a few lines later
     h->ref_count[0] = h->pps.ref_count[0];
@@ -2926,23 +3508,23 @@
 
     if (h->slice_type_nos != AV_PICTURE_TYPE_I) {
         unsigned max[2];
-        max[0] = max[1] = s->picture_structure == PICT_FRAME ? 15 : 31;
+        max[0] = max[1] = h->picture_structure == PICT_FRAME ? 15 : 31;
 
         if (h->slice_type_nos == AV_PICTURE_TYPE_B)
-            h->direct_spatial_mv_pred = get_bits1(&s->gb);
-        num_ref_idx_active_override_flag = get_bits1(&s->gb);
+            h->direct_spatial_mv_pred = get_bits1(&h->gb);
+        num_ref_idx_active_override_flag = get_bits1(&h->gb);
 
         if (num_ref_idx_active_override_flag) {
-            h->ref_count[0] = get_ue_golomb(&s->gb) + 1;
+            h->ref_count[0] = get_ue_golomb(&h->gb) + 1;
             if (h->slice_type_nos == AV_PICTURE_TYPE_B) {
-                h->ref_count[1] = get_ue_golomb(&s->gb) + 1;
+                h->ref_count[1] = get_ue_golomb(&h->gb) + 1;
             } else
                 // full range is spec-ok in this case, even for frames
                 h->ref_count[1] = 1;
         }
 
         if (h->ref_count[0]-1 > max[0] || h->ref_count[1]-1 > max[1]){
-            av_log(h->s.avctx, AV_LOG_ERROR, "reference overflow %u > %u or %u > %u\n", h->ref_count[0]-1, max[0], h->ref_count[1]-1, max[1]);
+            av_log(h->avctx, AV_LOG_ERROR, "reference overflow %u > %u or %u > %u\n", h->ref_count[0]-1, max[0], h->ref_count[1]-1, max[1]);
             h->ref_count[0] = h->ref_count[1] = 1;
             return AVERROR_INVALIDDATA;
         }
@@ -2963,17 +3545,6 @@
         return -1;
     }
 
-    if (h->slice_type_nos != AV_PICTURE_TYPE_I) {
-        s->last_picture_ptr = &h->ref_list[0][0];
-        s->last_picture_ptr->owner2 = s;
-        ff_copy_picture(&s->last_picture, s->last_picture_ptr);
-    }
-    if (h->slice_type_nos == AV_PICTURE_TYPE_B) {
-        s->next_picture_ptr = &h->ref_list[1][0];
-        s->next_picture_ptr->owner2 = s;
-        ff_copy_picture(&s->next_picture, s->next_picture_ptr);
-    }
-
     if ((h->pps.weighted_pred && h->slice_type_nos == AV_PICTURE_TYPE_P) ||
         (h->pps.weighted_bipred_idc == 1 &&
          h->slice_type_nos == AV_PICTURE_TYPE_B))
@@ -2989,8 +3560,16 @@
         }
     }
 
-    if (h->nal_ref_idc && ff_h264_decode_ref_pic_marking(h0, &s->gb) < 0 &&
-        (s->avctx->err_recognition & AV_EF_EXPLODE))
+    // If frame-mt is enabled, only update mmco tables for the first slice
+    // in a field. Subsequent slices can temporarily clobber h->mmco_index
+    // 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 (FRAME_MBAFF) {
@@ -3007,37 +3586,37 @@
     ff_h264_direct_ref_list_init(h);
 
     if (h->slice_type_nos != AV_PICTURE_TYPE_I && h->pps.cabac) {
-        tmp = get_ue_golomb_31(&s->gb);
+        tmp = get_ue_golomb_31(&h->gb);
         if (tmp > 2) {
-            av_log(s->avctx, AV_LOG_ERROR, "cabac_init_idc overflow\n");
+            av_log(h->avctx, AV_LOG_ERROR, "cabac_init_idc overflow\n");
             return -1;
         }
         h->cabac_init_idc = tmp;
     }
 
     h->last_qscale_diff = 0;
-    tmp = h->pps.init_qp + get_se_golomb(&s->gb);
+    tmp = h->pps.init_qp + get_se_golomb(&h->gb);
     if (tmp > 51 + 6 * (h->sps.bit_depth_luma - 8)) {
-        av_log(s->avctx, AV_LOG_ERROR, "QP %u out of range\n", tmp);
+        av_log(h->avctx, AV_LOG_ERROR, "QP %u out of range\n", tmp);
         return -1;
     }
-    s->qscale       = tmp;
-    h->chroma_qp[0] = get_chroma_qp(h, 0, s->qscale);
-    h->chroma_qp[1] = get_chroma_qp(h, 1, s->qscale);
+    h->qscale       = tmp;
+    h->chroma_qp[0] = get_chroma_qp(h, 0, h->qscale);
+    h->chroma_qp[1] = get_chroma_qp(h, 1, h->qscale);
     // FIXME qscale / qp ... stuff
     if (h->slice_type == AV_PICTURE_TYPE_SP)
-        get_bits1(&s->gb); /* sp_for_switch_flag */
+        get_bits1(&h->gb); /* sp_for_switch_flag */
     if (h->slice_type == AV_PICTURE_TYPE_SP ||
         h->slice_type == AV_PICTURE_TYPE_SI)
-        get_se_golomb(&s->gb); /* slice_qs_delta */
+        get_se_golomb(&h->gb); /* slice_qs_delta */
 
     h->deblocking_filter     = 1;
     h->slice_alpha_c0_offset = 52;
     h->slice_beta_offset     = 52;
     if (h->pps.deblocking_filter_parameters_present) {
-        tmp = get_ue_golomb_31(&s->gb);
+        tmp = get_ue_golomb_31(&h->gb);
         if (tmp > 2) {
-            av_log(s->avctx, AV_LOG_ERROR,
+            av_log(h->avctx, AV_LOG_ERROR,
                    "deblocking_filter_idc %u out of range\n", tmp);
             return -1;
         }
@@ -3046,11 +3625,11 @@
             h->deblocking_filter ^= 1;  // 1<->0
 
         if (h->deblocking_filter) {
-            h->slice_alpha_c0_offset += get_se_golomb(&s->gb) << 1;
-            h->slice_beta_offset     += get_se_golomb(&s->gb) << 1;
+            h->slice_alpha_c0_offset += get_se_golomb(&h->gb) << 1;
+            h->slice_beta_offset     += get_se_golomb(&h->gb) << 1;
             if (h->slice_alpha_c0_offset > 104U ||
                 h->slice_beta_offset     > 104U) {
-                av_log(s->avctx, AV_LOG_ERROR,
+                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;
@@ -3058,29 +3637,29 @@
         }
     }
 
-    if (s->avctx->skip_loop_filter >= AVDISCARD_ALL ||
-        (s->avctx->skip_loop_filter >= AVDISCARD_NONKEY &&
+    if (h->avctx->skip_loop_filter >= AVDISCARD_ALL ||
+        (h->avctx->skip_loop_filter >= AVDISCARD_NONKEY &&
          h->slice_type_nos != AV_PICTURE_TYPE_I) ||
-        (s->avctx->skip_loop_filter >= AVDISCARD_BIDIR  &&
+        (h->avctx->skip_loop_filter >= AVDISCARD_BIDIR  &&
          h->slice_type_nos == AV_PICTURE_TYPE_B) ||
-        (s->avctx->skip_loop_filter >= AVDISCARD_NONREF &&
+        (h->avctx->skip_loop_filter >= AVDISCARD_NONREF &&
          h->nal_ref_idc == 0))
         h->deblocking_filter = 0;
 
     if (h->deblocking_filter == 1 && h0->max_contexts > 1) {
-        if (s->avctx->flags2 & CODEC_FLAG2_FAST) {
+        if (h->avctx->flags2 & CODEC_FLAG2_FAST) {
             /* Cheat slightly for speed:
              * Do not bother to deblock across slices. */
             h->deblocking_filter = 2;
         } else {
             h0->max_contexts = 1;
             if (!h0->single_decode_warning) {
-                av_log(s->avctx, AV_LOG_INFO,
+                av_log(h->avctx, AV_LOG_INFO,
                        "Cannot parallelize deblocking type 1, decoding such frames in sequential order\n");
                 h0->single_decode_warning = 1;
             }
             if (h != h0) {
-                av_log(h->s.avctx, AV_LOG_ERROR,
+                av_log(h->avctx, AV_LOG_ERROR,
                        "Deblocking switched inside frame.\n");
                 return 1;
             }
@@ -3094,15 +3673,16 @@
                    6 * (h->sps.bit_depth_luma - 8);
 
     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;
 
     if (h->slice_num)
-        h0->slice_row[(h->slice_num-1)&(MAX_SLICES-1)]= s->resync_mb_y;
-    if (   h0->slice_row[h->slice_num&(MAX_SLICES-1)] + 3 >= s->resync_mb_y
-        && h0->slice_row[h->slice_num&(MAX_SLICES-1)] <= s->resync_mb_y
+        h0->slice_row[(h->slice_num-1)&(MAX_SLICES-1)]= h->resync_mb_y;
+    if (   h0->slice_row[h->slice_num&(MAX_SLICES-1)] + 3 >= h->resync_mb_y
+        && h0->slice_row[h->slice_num&(MAX_SLICES-1)] <= h->resync_mb_y
         && h->slice_num >= MAX_SLICES) {
         //in case of ASO this check needs to be updated depending on how we decide to assign slice numbers in this case
-        av_log(s->avctx, AV_LOG_WARNING, "Possibly too many slices (%d >= %d), increase MAX_SLICES and recompile if there are artifacts\n", h->slice_num, MAX_SLICES);
+        av_log(h->avctx, AV_LOG_WARNING, "Possibly too many slices (%d >= %d), increase MAX_SLICES and recompile if there are artifacts\n", h->slice_num, MAX_SLICES);
     }
 
     for (j = 0; j < 2; j++) {
@@ -3138,27 +3718,23 @@
                              (h->ref_list[j][i].f.reference & 3);
     }
 
-    // FIXME: fix draw_edges + PAFF + frame threads
-    h->emu_edge_width  = (s->flags & CODEC_FLAG_EMU_EDGE ||
-                          (!h->sps.frame_mbs_only_flag &&
-                           s->avctx->active_thread_type))
-                         ? 0 : 16;
-    h->emu_edge_height = (FRAME_MBAFF || FIELD_PICTURE) ? 0 : h->emu_edge_width;
+    if (h->ref_count[0]) h->er.last_pic = &h->ref_list[0][0];
+    if (h->ref_count[1]) h->er.next_pic = &h->ref_list[1][0];
 
-    if (s->avctx->debug & FF_DEBUG_PICT_INFO) {
-        av_log(h->s.avctx, AV_LOG_DEBUG,
+    if (h->avctx->debug & FF_DEBUG_PICT_INFO) {
+        av_log(h->avctx, AV_LOG_DEBUG,
                "slice:%d %s mb:%d %c%s%s pps:%u frame:%d poc:%d/%d ref:%d/%d qp:%d loop:%d:%d:%d weight:%d%s %s\n",
                h->slice_num,
-               (s->picture_structure == PICT_FRAME ? "F" : s->picture_structure == PICT_TOP_FIELD ? "T" : "B"),
+               (h->picture_structure == PICT_FRAME ? "F" : h->picture_structure == PICT_TOP_FIELD ? "T" : "B"),
                first_mb_in_slice,
                av_get_picture_type_char(h->slice_type),
                h->slice_type_fixed ? " fix" : "",
                h->nal_unit_type == NAL_IDR_SLICE ? " IDR" : "",
                pps_id, h->frame_num,
-               s->current_picture_ptr->field_poc[0],
-               s->current_picture_ptr->field_poc[1],
+               h->cur_pic_ptr->field_poc[0],
+               h->cur_pic_ptr->field_poc[1],
                h->ref_count[0], h->ref_count[1],
-               s->qscale,
+               h->qscale,
                h->deblocking_filter,
                h->slice_alpha_c0_offset / 2 - 26, h->slice_beta_offset / 2 - 26,
                h->use_weight,
@@ -3188,7 +3764,6 @@
 }
 
 static av_always_inline void fill_filter_caches_inter(H264Context *h,
-                                                      MpegEncContext *const s,
                                                       int mb_type, int top_xy,
                                                       int left_xy[LEFT_MBS],
                                                       int top_type,
@@ -3203,11 +3778,11 @@
             const int b_xy  = h->mb2b_xy[top_xy] + 3 * b_stride;
             const int b8_xy = 4 * top_xy + 2;
             int (*ref2frm)[64] = (void*)(h->ref2frm[h->slice_table[top_xy] & (MAX_SLICES - 1)][0] + (MB_MBAFF ? 20 : 2));
-            AV_COPY128(mv_dst - 1 * 8, s->current_picture.f.motion_val[list][b_xy + 0]);
+            AV_COPY128(mv_dst - 1 * 8, h->cur_pic.f.motion_val[list][b_xy + 0]);
             ref_cache[0 - 1 * 8] =
-            ref_cache[1 - 1 * 8] = ref2frm[list][s->current_picture.f.ref_index[list][b8_xy + 0]];
+            ref_cache[1 - 1 * 8] = ref2frm[list][h->cur_pic.f.ref_index[list][b8_xy + 0]];
             ref_cache[2 - 1 * 8] =
-            ref_cache[3 - 1 * 8] = ref2frm[list][s->current_picture.f.ref_index[list][b8_xy + 1]];
+            ref_cache[3 - 1 * 8] = ref2frm[list][h->cur_pic.f.ref_index[list][b8_xy + 1]];
         } else {
             AV_ZERO128(mv_dst - 1 * 8);
             AV_WN32A(&ref_cache[0 - 1 * 8], ((LIST_NOT_USED) & 0xFF) * 0x01010101u);
@@ -3218,14 +3793,14 @@
                 const int b_xy  = h->mb2b_xy[left_xy[LTOP]] + 3;
                 const int b8_xy = 4 * left_xy[LTOP] + 1;
                 int (*ref2frm)[64] =(void*)( h->ref2frm[h->slice_table[left_xy[LTOP]] & (MAX_SLICES - 1)][0] + (MB_MBAFF ? 20 : 2));
-                AV_COPY32(mv_dst - 1 +  0, s->current_picture.f.motion_val[list][b_xy + b_stride * 0]);
-                AV_COPY32(mv_dst - 1 +  8, s->current_picture.f.motion_val[list][b_xy + b_stride * 1]);
-                AV_COPY32(mv_dst - 1 + 16, s->current_picture.f.motion_val[list][b_xy + b_stride * 2]);
-                AV_COPY32(mv_dst - 1 + 24, s->current_picture.f.motion_val[list][b_xy + b_stride * 3]);
+                AV_COPY32(mv_dst - 1 +  0, h->cur_pic.f.motion_val[list][b_xy + b_stride * 0]);
+                AV_COPY32(mv_dst - 1 +  8, h->cur_pic.f.motion_val[list][b_xy + b_stride * 1]);
+                AV_COPY32(mv_dst - 1 + 16, h->cur_pic.f.motion_val[list][b_xy + b_stride * 2]);
+                AV_COPY32(mv_dst - 1 + 24, h->cur_pic.f.motion_val[list][b_xy + b_stride * 3]);
                 ref_cache[-1 +  0] =
-                ref_cache[-1 +  8] = ref2frm[list][s->current_picture.f.ref_index[list][b8_xy + 2 * 0]];
+                ref_cache[-1 +  8] = ref2frm[list][h->cur_pic.f.ref_index[list][b8_xy + 2 * 0]];
                 ref_cache[-1 + 16] =
-                ref_cache[-1 + 24] = ref2frm[list][s->current_picture.f.ref_index[list][b8_xy + 2 * 1]];
+                ref_cache[-1 + 24] = ref2frm[list][h->cur_pic.f.ref_index[list][b8_xy + 2 * 1]];
             } else {
                 AV_ZERO32(mv_dst - 1 +  0);
                 AV_ZERO32(mv_dst - 1 +  8);
@@ -3249,7 +3824,7 @@
     }
 
     {
-        int8_t *ref = &s->current_picture.f.ref_index[list][4 * mb_xy];
+        int8_t *ref = &h->cur_pic.f.ref_index[list][4 * mb_xy];
         int (*ref2frm)[64] = (void*)(h->ref2frm[h->slice_num & (MAX_SLICES - 1)][0] + (MB_MBAFF ? 20 : 2));
         uint32_t ref01 = (pack16to32(ref2frm[list][ref[0]], ref2frm[list][ref[1]]) & 0x00FF00FF) * 0x0101;
         uint32_t ref23 = (pack16to32(ref2frm[list][ref[2]], ref2frm[list][ref[3]]) & 0x00FF00FF) * 0x0101;
@@ -3260,7 +3835,7 @@
     }
 
     {
-        int16_t(*mv_src)[2] = &s->current_picture.f.motion_val[list][4 * s->mb_x + 4 * s->mb_y * b_stride];
+        int16_t(*mv_src)[2] = &h->cur_pic.f.motion_val[list][4 * h->mb_x + 4 * h->mb_y * b_stride];
         AV_COPY128(mv_dst + 8 * 0, mv_src + 0 * b_stride);
         AV_COPY128(mv_dst + 8 * 1, mv_src + 1 * b_stride);
         AV_COPY128(mv_dst + 8 * 2, mv_src + 2 * b_stride);
@@ -3274,31 +3849,30 @@
  */
 static int fill_filter_caches(H264Context *h, int mb_type)
 {
-    MpegEncContext *const s = &h->s;
     const int mb_xy = h->mb_xy;
     int top_xy, left_xy[LEFT_MBS];
     int top_type, left_type[LEFT_MBS];
     uint8_t *nnz;
     uint8_t *nnz_cache;
 
-    top_xy = mb_xy - (s->mb_stride << MB_FIELD);
+    top_xy = mb_xy - (h->mb_stride << MB_FIELD);
 
     /* Wow, what a mess, why didn't they simplify the interlacing & intra
      * stuff, I can't imagine that these complex rules are worth it. */
 
     left_xy[LBOT] = left_xy[LTOP] = mb_xy - 1;
     if (FRAME_MBAFF) {
-        const int left_mb_field_flag = IS_INTERLACED(s->current_picture.f.mb_type[mb_xy - 1]);
+        const int left_mb_field_flag = IS_INTERLACED(h->cur_pic.f.mb_type[mb_xy - 1]);
         const int curr_mb_field_flag = IS_INTERLACED(mb_type);
-        if (s->mb_y & 1) {
+        if (h->mb_y & 1) {
             if (left_mb_field_flag != curr_mb_field_flag)
-                left_xy[LTOP] -= s->mb_stride;
+                left_xy[LTOP] -= h->mb_stride;
         } else {
             if (curr_mb_field_flag)
-                top_xy += s->mb_stride &
-                    (((s->current_picture.f.mb_type[top_xy] >> 7) & 1) - 1);
+                top_xy += h->mb_stride &
+                    (((h->cur_pic.f.mb_type[top_xy] >> 7) & 1) - 1);
             if (left_mb_field_flag != curr_mb_field_flag)
-                left_xy[LBOT] += s->mb_stride;
+                left_xy[LBOT] += h->mb_stride;
         }
     }
 
@@ -3310,25 +3884,25 @@
          * This is a conservative estimate: could also check beta_offset
          * and more accurate chroma_qp. */
         int qp_thresh = h->qp_thresh; // FIXME strictly we should store qp_thresh for each mb of a slice
-        int qp        = s->current_picture.f.qscale_table[mb_xy];
+        int qp        = h->cur_pic.f.qscale_table[mb_xy];
         if (qp <= qp_thresh &&
             (left_xy[LTOP] < 0 ||
-             ((qp + s->current_picture.f.qscale_table[left_xy[LTOP]] + 1) >> 1) <= qp_thresh) &&
+             ((qp + h->cur_pic.f.qscale_table[left_xy[LTOP]] + 1) >> 1) <= qp_thresh) &&
             (top_xy < 0 ||
-             ((qp + s->current_picture.f.qscale_table[top_xy] + 1) >> 1) <= qp_thresh)) {
+             ((qp + h->cur_pic.f.qscale_table[top_xy] + 1) >> 1) <= qp_thresh)) {
             if (!FRAME_MBAFF)
                 return 1;
             if ((left_xy[LTOP] < 0 ||
-                 ((qp + s->current_picture.f.qscale_table[left_xy[LBOT]] + 1) >> 1) <= qp_thresh) &&
-                (top_xy < s->mb_stride ||
-                 ((qp + s->current_picture.f.qscale_table[top_xy - s->mb_stride] + 1) >> 1) <= qp_thresh))
+                 ((qp + h->cur_pic.f.qscale_table[left_xy[LBOT]] + 1) >> 1) <= qp_thresh) &&
+                (top_xy < h->mb_stride ||
+                 ((qp + h->cur_pic.f.qscale_table[top_xy - h->mb_stride] + 1) >> 1) <= qp_thresh))
                 return 1;
         }
     }
 
-    top_type        = s->current_picture.f.mb_type[top_xy];
-    left_type[LTOP] = s->current_picture.f.mb_type[left_xy[LTOP]];
-    left_type[LBOT] = s->current_picture.f.mb_type[left_xy[LBOT]];
+    top_type        = h->cur_pic.f.mb_type[top_xy];
+    left_type[LTOP] = h->cur_pic.f.mb_type[left_xy[LTOP]];
+    left_type[LBOT] = h->cur_pic.f.mb_type[left_xy[LBOT]];
     if (h->deblocking_filter == 2) {
         if (h->slice_table[top_xy] != h->slice_num)
             top_type = 0;
@@ -3347,10 +3921,10 @@
     if (IS_INTRA(mb_type))
         return 0;
 
-    fill_filter_caches_inter(h, s, mb_type, top_xy, left_xy,
+    fill_filter_caches_inter(h, mb_type, top_xy, left_xy,
                              top_type, left_type, mb_xy, 0);
     if (h->list_count == 2)
-        fill_filter_caches_inter(h, s, mb_type, top_xy, left_xy,
+        fill_filter_caches_inter(h, mb_type, top_xy, left_xy,
                                  top_type, left_type, mb_xy, 1);
 
     nnz       = h->non_zero_count[mb_xy];
@@ -3420,57 +3994,56 @@
 
 static void loop_filter(H264Context *h, int start_x, int end_x)
 {
-    MpegEncContext *const s = &h->s;
     uint8_t *dest_y, *dest_cb, *dest_cr;
     int linesize, uvlinesize, mb_x, mb_y;
-    const int end_mb_y       = s->mb_y + FRAME_MBAFF;
+    const int end_mb_y       = h->mb_y + FRAME_MBAFF;
     const int old_slice_type = h->slice_type;
     const int pixel_shift    = h->pixel_shift;
-    const int block_h        = 16 >> s->chroma_y_shift;
+    const int block_h        = 16 >> h->chroma_y_shift;
 
     if (h->deblocking_filter) {
         for (mb_x = start_x; mb_x < end_x; mb_x++)
             for (mb_y = end_mb_y - FRAME_MBAFF; mb_y <= end_mb_y; mb_y++) {
                 int mb_xy, mb_type;
-                mb_xy         = h->mb_xy = mb_x + mb_y * s->mb_stride;
+                mb_xy         = h->mb_xy = mb_x + mb_y * h->mb_stride;
                 h->slice_num  = h->slice_table[mb_xy];
-                mb_type       = s->current_picture.f.mb_type[mb_xy];
+                mb_type       = h->cur_pic.f.mb_type[mb_xy];
                 h->list_count = h->list_counts[mb_xy];
 
                 if (FRAME_MBAFF)
                     h->mb_mbaff               =
                     h->mb_field_decoding_flag = !!IS_INTERLACED(mb_type);
 
-                s->mb_x = mb_x;
-                s->mb_y = mb_y;
-                dest_y  = s->current_picture.f.data[0] +
-                          ((mb_x << pixel_shift) + mb_y * s->linesize) * 16;
-                dest_cb = s->current_picture.f.data[1] +
+                h->mb_x = mb_x;
+                h->mb_y = mb_y;
+                dest_y  = h->cur_pic.f.data[0] +
+                          ((mb_x << pixel_shift) + mb_y * h->linesize) * 16;
+                dest_cb = h->cur_pic.f.data[1] +
                           (mb_x << pixel_shift) * (8 << CHROMA444) +
-                          mb_y * s->uvlinesize * block_h;
-                dest_cr = s->current_picture.f.data[2] +
+                          mb_y * h->uvlinesize * block_h;
+                dest_cr = h->cur_pic.f.data[2] +
                           (mb_x << pixel_shift) * (8 << CHROMA444) +
-                          mb_y * s->uvlinesize * block_h;
+                          mb_y * h->uvlinesize * block_h;
                 // FIXME simplify above
 
                 if (MB_FIELD) {
-                    linesize   = h->mb_linesize   = s->linesize   * 2;
-                    uvlinesize = h->mb_uvlinesize = s->uvlinesize * 2;
+                    linesize   = h->mb_linesize   = h->linesize   * 2;
+                    uvlinesize = h->mb_uvlinesize = h->uvlinesize * 2;
                     if (mb_y & 1) { // FIXME move out of this function?
-                        dest_y  -= s->linesize   * 15;
-                        dest_cb -= s->uvlinesize * (block_h - 1);
-                        dest_cr -= s->uvlinesize * (block_h - 1);
+                        dest_y  -= h->linesize   * 15;
+                        dest_cb -= h->uvlinesize * (block_h - 1);
+                        dest_cr -= h->uvlinesize * (block_h - 1);
                     }
                 } else {
-                    linesize   = h->mb_linesize   = s->linesize;
-                    uvlinesize = h->mb_uvlinesize = s->uvlinesize;
+                    linesize   = h->mb_linesize   = h->linesize;
+                    uvlinesize = h->mb_uvlinesize = h->uvlinesize;
                 }
                 backup_mb_border(h, dest_y, dest_cb, dest_cr, linesize,
                                  uvlinesize, 0);
                 if (fill_filter_caches(h, mb_type))
                     continue;
-                h->chroma_qp[0] = get_chroma_qp(h, 0, s->current_picture.f.qscale_table[mb_xy]);
-                h->chroma_qp[1] = get_chroma_qp(h, 1, s->current_picture.f.qscale_table[mb_xy]);
+                h->chroma_qp[0] = get_chroma_qp(h, 0, h->cur_pic.f.qscale_table[mb_xy]);
+                h->chroma_qp[1] = get_chroma_qp(h, 1, h->cur_pic.f.qscale_table[mb_xy]);
 
                 if (FRAME_MBAFF) {
                     ff_h264_filter_mb(h, mb_x, mb_y, dest_y, dest_cb, dest_cr,
@@ -3482,20 +4055,19 @@
             }
     }
     h->slice_type   = old_slice_type;
-    s->mb_x         = end_x;
-    s->mb_y         = end_mb_y - FRAME_MBAFF;
-    h->chroma_qp[0] = get_chroma_qp(h, 0, s->qscale);
-    h->chroma_qp[1] = get_chroma_qp(h, 1, s->qscale);
+    h->mb_x         = end_x;
+    h->mb_y         = end_mb_y - FRAME_MBAFF;
+    h->chroma_qp[0] = get_chroma_qp(h, 0, h->qscale);
+    h->chroma_qp[1] = get_chroma_qp(h, 1, h->qscale);
 }
 
 static void predict_field_decoding_flag(H264Context *h)
 {
-    MpegEncContext *const s = &h->s;
-    const int mb_xy = s->mb_x + s->mb_y * s->mb_stride;
+    const int mb_xy = h->mb_x + h->mb_y * h->mb_stride;
     int mb_type     = (h->slice_table[mb_xy - 1] == h->slice_num) ?
-                      s->current_picture.f.mb_type[mb_xy - 1] :
-                      (h->slice_table[mb_xy - s->mb_stride] == h->slice_num) ?
-                      s->current_picture.f.mb_type[mb_xy - s->mb_stride] : 0;
+                      h->cur_pic.f.mb_type[mb_xy - 1] :
+                      (h->slice_table[mb_xy - h->mb_stride] == h->slice_num) ?
+                      h->cur_pic.f.mb_type[mb_xy - h->mb_stride] : 0;
     h->mb_mbaff     = h->mb_field_decoding_flag = IS_INTERLACED(mb_type) ? 1 : 0;
 }
 
@@ -3504,9 +4076,8 @@
  */
 static void decode_finish_row(H264Context *h)
 {
-    MpegEncContext *const s = &h->s;
-    int top            = 16 * (s->mb_y      >> FIELD_PICTURE);
-    int pic_height     = 16 *  s->mb_height >> FIELD_PICTURE;
+    int top            = 16 * (h->mb_y      >> FIELD_PICTURE);
+    int pic_height     = 16 *  h->mb_height >> FIELD_PICTURE;
     int height         =  16      << FRAME_MBAFF;
     int deblock_border = (16 + 4) << FRAME_MBAFF;
 
@@ -3516,46 +4087,54 @@
         top -= deblock_border;
     }
 
-    if (top >= pic_height || (top + height) < h->emu_edge_height)
+    if (top >= pic_height || (top + height) < 0)
         return;
 
     height = FFMIN(height, pic_height - top);
-    if (top < h->emu_edge_height) {
+    if (top < 0) {
         height = top + height;
         top    = 0;
     }
 
-    ff_draw_horiz_band(s, top, height);
+    ff_h264_draw_horiz_band(h, top, height);
 
-    if (s->dropable)
+    if (h->droppable)
         return;
 
-    ff_thread_report_progress(&s->current_picture_ptr->f, top + height - 1,
-                              s->picture_structure == PICT_BOTTOM_FIELD);
+    ff_thread_report_progress(&h->cur_pic_ptr->f, top + height - 1,
+                              h->picture_structure == PICT_BOTTOM_FIELD);
+}
+
+static void er_add_slice(H264Context *h, int startx, int starty,
+                         int endx, int endy, int status)
+{
+    ERContext *er = &h->er;
+
+    er->ref_count = h->ref_count[0];
+    ff_er_add_slice(er, startx, starty, endx, endy, status);
 }
 
 static int decode_slice(struct AVCodecContext *avctx, void *arg)
 {
     H264Context *h = *(void **)arg;
-    MpegEncContext *const s = &h->s;
-    const int part_mask     = s->partitioned_frame ? (ER_AC_END | ER_AC_ERROR)
-                                                   : 0x7F;
-    int lf_x_start = s->mb_x;
+    int lf_x_start = h->mb_x;
 
-    s->mb_skip_run = -1;
+    h->mb_skip_run = -1;
 
-    h->is_complex = FRAME_MBAFF || s->picture_structure != PICT_FRAME ||
-                    s->codec_id != AV_CODEC_ID_H264 ||
-                    (CONFIG_GRAY && (s->flags & CODEC_FLAG_GRAY));
+    av_assert0(h->block_offset[15] == (4 * ((scan8[15] - scan8[0]) & 7) << h->pixel_shift) + 4 * h->linesize * ((scan8[15] - scan8[0]) >> 3));
+
+    h->is_complex = FRAME_MBAFF || h->picture_structure != PICT_FRAME ||
+                    avctx->codec_id != AV_CODEC_ID_H264 ||
+                    (CONFIG_GRAY && (h->flags & CODEC_FLAG_GRAY));
 
     if (h->pps.cabac) {
         /* realign */
-        align_get_bits(&s->gb);
+        align_get_bits(&h->gb);
 
         /* init cabac */
         ff_init_cabac_decoder(&h->cabac,
-                              s->gb.buffer + get_bits_count(&s->gb) / 8,
-                              (get_bits_left(&s->gb) + 7) / 8);
+                              h->gb.buffer + get_bits_count(&h->gb) / 8,
+                              (get_bits_left(&h->gb) + 7) / 8);
 
         ff_h264_init_cabac_states(h);
 
@@ -3570,55 +4149,55 @@
 
             // FIXME optimal? or let mb_decode decode 16x32 ?
             if (ret >= 0 && FRAME_MBAFF) {
-                s->mb_y++;
+                h->mb_y++;
 
                 ret = ff_h264_decode_mb_cabac(h);
 
                 if (ret >= 0)
                     ff_h264_hl_decode_mb(h);
-                s->mb_y--;
+                h->mb_y--;
             }
             eos = get_cabac_terminate(&h->cabac);
 
-            if ((s->workaround_bugs & FF_BUG_TRUNCATED) &&
+            if ((h->workaround_bugs & FF_BUG_TRUNCATED) &&
                 h->cabac.bytestream > h->cabac.bytestream_end + 2) {
-                ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x - 1,
-                                s->mb_y, ER_MB_END & part_mask);
-                if (s->mb_x >= lf_x_start)
-                    loop_filter(h, lf_x_start, s->mb_x + 1);
+                er_add_slice(h, h->resync_mb_x, h->resync_mb_y, 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 + 1);
                 return 0;
             }
             if (h->cabac.bytestream > h->cabac.bytestream_end + 2 )
-                av_log(h->s.avctx, AV_LOG_DEBUG, "bytestream overread %td\n", h->cabac.bytestream_end - h->cabac.bytestream);
+                av_log(h->avctx, AV_LOG_DEBUG, "bytestream overread %td\n", h->cabac.bytestream_end - h->cabac.bytestream);
             if (ret < 0 || h->cabac.bytestream > h->cabac.bytestream_end + 4) {
-                av_log(h->s.avctx, AV_LOG_ERROR,
+                av_log(h->avctx, AV_LOG_ERROR,
                        "error while decoding MB %d %d, bytestream (%td)\n",
-                       s->mb_x, s->mb_y,
+                       h->mb_x, h->mb_y,
                        h->cabac.bytestream_end - h->cabac.bytestream);
-                ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x,
-                                s->mb_y, ER_MB_ERROR & part_mask);
+                er_add_slice(h, h->resync_mb_x, h->resync_mb_y, h->mb_x,
+                                h->mb_y, ER_MB_ERROR);
                 return -1;
             }
 
-            if (++s->mb_x >= s->mb_width) {
-                loop_filter(h, lf_x_start, s->mb_x);
-                s->mb_x = lf_x_start = 0;
+            if (++h->mb_x >= h->mb_width) {
+                loop_filter(h, lf_x_start, h->mb_x);
+                h->mb_x = lf_x_start = 0;
                 decode_finish_row(h);
-                ++s->mb_y;
+                ++h->mb_y;
                 if (FIELD_OR_MBAFF_PICTURE) {
-                    ++s->mb_y;
-                    if (FRAME_MBAFF && s->mb_y < s->mb_height)
+                    ++h->mb_y;
+                    if (FRAME_MBAFF && h->mb_y < h->mb_height)
                         predict_field_decoding_flag(h);
                 }
             }
 
-            if (eos || s->mb_y >= s->mb_height) {
-                tprintf(s->avctx, "slice end %d %d\n",
-                        get_bits_count(&s->gb), s->gb.size_in_bits);
-                ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x - 1,
-                                s->mb_y, ER_MB_END & part_mask);
-                if (s->mb_x > lf_x_start)
-                    loop_filter(h, lf_x_start, s->mb_x);
+            if (eos || h->mb_y >= h->mb_height) {
+                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);
+                if (h->mb_x > lf_x_start)
+                    loop_filter(h, lf_x_start, h->mb_x);
                 return 0;
             }
         }
@@ -3631,67 +4210,67 @@
 
             // FIXME optimal? or let mb_decode decode 16x32 ?
             if (ret >= 0 && FRAME_MBAFF) {
-                s->mb_y++;
+                h->mb_y++;
                 ret = ff_h264_decode_mb_cavlc(h);
 
                 if (ret >= 0)
                     ff_h264_hl_decode_mb(h);
-                s->mb_y--;
+                h->mb_y--;
             }
 
             if (ret < 0) {
-                av_log(h->s.avctx, AV_LOG_ERROR,
-                       "error while decoding MB %d %d\n", s->mb_x, s->mb_y);
-                ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x,
-                                s->mb_y, ER_MB_ERROR & part_mask);
+                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;
             }
 
-            if (++s->mb_x >= s->mb_width) {
-                loop_filter(h, lf_x_start, s->mb_x);
-                s->mb_x = lf_x_start = 0;
+            if (++h->mb_x >= h->mb_width) {
+                loop_filter(h, lf_x_start, h->mb_x);
+                h->mb_x = lf_x_start = 0;
                 decode_finish_row(h);
-                ++s->mb_y;
+                ++h->mb_y;
                 if (FIELD_OR_MBAFF_PICTURE) {
-                    ++s->mb_y;
-                    if (FRAME_MBAFF && s->mb_y < s->mb_height)
+                    ++h->mb_y;
+                    if (FRAME_MBAFF && h->mb_y < h->mb_height)
                         predict_field_decoding_flag(h);
                 }
-                if (s->mb_y >= s->mb_height) {
-                    tprintf(s->avctx, "slice end %d %d\n",
-                            get_bits_count(&s->gb), s->gb.size_in_bits);
+                if (h->mb_y >= h->mb_height) {
+                    tprintf(h->avctx, "slice end %d %d\n",
+                            get_bits_count(&h->gb), h->gb.size_in_bits);
 
-                    if (   get_bits_left(&s->gb) == 0
-                        || get_bits_left(&s->gb) > 0 && !(s->avctx->err_recognition & AV_EF_AGGRESSIVE)) {
-                        ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y,
-                                        s->mb_x - 1, s->mb_y,
-                                        ER_MB_END & part_mask);
+                    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);
 
                         return 0;
                     } else {
-                        ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y,
-                                        s->mb_x, s->mb_y,
-                                        ER_MB_END & part_mask);
+                        er_add_slice(h, h->resync_mb_x, h->resync_mb_y,
+                                        h->mb_x, h->mb_y,
+                                        ER_MB_END);
 
                         return -1;
                     }
                 }
             }
 
-            if (get_bits_left(&s->gb) <= 0 && s->mb_skip_run <= 0) {
-                tprintf(s->avctx, "slice end %d %d\n",
-                        get_bits_count(&s->gb), s->gb.size_in_bits);
-                if (get_bits_left(&s->gb) == 0) {
-                    ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y,
-                                    s->mb_x - 1, s->mb_y,
-                                    ER_MB_END & part_mask);
-                    if (s->mb_x > lf_x_start)
-                        loop_filter(h, lf_x_start, s->mb_x);
+            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);
+                    if (h->mb_x > lf_x_start)
+                        loop_filter(h, lf_x_start, h->mb_x);
 
                     return 0;
                 } else {
-                    ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x,
-                                    s->mb_y, ER_MB_ERROR & part_mask);
+                    er_add_slice(h, h->resync_mb_x, h->resync_mb_y, h->mb_x,
+                                    h->mb_y, ER_MB_ERROR);
 
                     return -1;
                 }
@@ -3708,21 +4287,20 @@
  */
 static int execute_decode_slices(H264Context *h, int context_count)
 {
-    MpegEncContext *const s     = &h->s;
-    AVCodecContext *const avctx = s->avctx;
+    AVCodecContext *const avctx = h->avctx;
     H264Context *hx;
     int i;
 
-    if (s->avctx->hwaccel ||
-        s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)
+    if (h->avctx->hwaccel ||
+        h->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)
         return 0;
     if (context_count == 1) {
         return decode_slice(avctx, &h);
     } else {
+        av_assert0(context_count > 0);
         for (i = 1; i < context_count; i++) {
             hx                    = h->thread_context[i];
-            hx->s.err_recognition = avctx->err_recognition;
-            hx->s.error_count     = 0;
+            hx->er.error_count  = 0;
             hx->x264_build        = h->x264_build;
         }
 
@@ -3731,21 +4309,21 @@
 
         /* pull back stuff from slices to master context */
         hx                   = h->thread_context[context_count - 1];
-        s->mb_x              = hx->s.mb_x;
-        s->mb_y              = hx->s.mb_y;
-        s->dropable          = hx->s.dropable;
-        s->picture_structure = hx->s.picture_structure;
+        h->mb_x              = hx->mb_x;
+        h->mb_y              = hx->mb_y;
+        h->droppable         = hx->droppable;
+        h->picture_structure = hx->picture_structure;
         for (i = 1; i < context_count; i++)
-            h->s.error_count += h->thread_context[i]->s.error_count;
+            h->er.error_count += h->thread_context[i]->er.error_count;
     }
 
     return 0;
 }
 
-static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size)
+static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size,
+                            int parse_extradata)
 {
-    MpegEncContext *const s     = &h->s;
-    AVCodecContext *const avctx = s->avctx;
+    AVCodecContext *const avctx = h->avctx;
     H264Context *hx; ///< thread context
     int buf_index;
     int context_count;
@@ -3753,16 +4331,18 @@
     int pass = !(avctx->active_thread_type & FF_THREAD_FRAME);
     int nals_needed = 0; ///< number of NALs that need decoding before the next frame thread starts
     int nal_index;
+    int idr_cleared=0;
+    int first_slice = 0;
 
     h->nal_unit_type= 0;
 
-    if(!s->slice_context_count)
-         s->slice_context_count= 1;
-    h->max_contexts = s->slice_context_count;
-    if (!(s->flags2 & CODEC_FLAG2_CHUNKS)) {
+    if(!h->slice_context_count)
+         h->slice_context_count= 1;
+    h->max_contexts = h->slice_context_count;
+    if (!(avctx->flags2 & CODEC_FLAG2_CHUNKS)) {
         h->current_slice = 0;
-        if (!s->first_field)
-            s->current_picture_ptr = NULL;
+        if (!h->first_field)
+            h->cur_pic_ptr = NULL;
         ff_h264_reset_sei(h);
     }
 
@@ -3793,7 +4373,7 @@
                 for (i = 0; i < h->nal_length_size; i++)
                     nalsize = (nalsize << 8) | buf[buf_index++];
                 if (nalsize <= 0 || nalsize > buf_size - buf_index) {
-                    av_log(h->s.avctx, AV_LOG_ERROR,
+                    av_log(h->avctx, AV_LOG_ERROR,
                            "AVC: nal size %d\n", nalsize);
                     break;
                 }
@@ -3826,23 +4406,23 @@
                 goto end;
             }
             i = buf_index + consumed;
-            if ((s->workaround_bugs & FF_BUG_AUTODETECT) && i + 3 < next_avc &&
+            if ((h->workaround_bugs & FF_BUG_AUTODETECT) && i + 3 < next_avc &&
                 buf[i]     == 0x00 && buf[i + 1] == 0x00 &&
                 buf[i + 2] == 0x01 && buf[i + 3] == 0xE0)
-                s->workaround_bugs |= FF_BUG_TRUNCATED;
+                h->workaround_bugs |= FF_BUG_TRUNCATED;
 
-            if (!(s->workaround_bugs & FF_BUG_TRUNCATED))
+            if (!(h->workaround_bugs & FF_BUG_TRUNCATED))
                 while(dst_length > 0 && ptr[dst_length - 1] == 0)
                     dst_length--;
             bit_length = !dst_length ? 0
                                      : (8 * dst_length -
                                         decode_rbsp_trailing(h, ptr + dst_length - 1));
 
-            if (s->avctx->debug & FF_DEBUG_STARTCODE)
-                av_log(h->s.avctx, AV_LOG_DEBUG, "NAL %d/%d at %d/%d length %d pass %d\n", hx->nal_unit_type, hx->nal_ref_idc, buf_index, buf_size, dst_length, pass);
+            if (h->avctx->debug & FF_DEBUG_STARTCODE)
+                av_log(h->avctx, AV_LOG_DEBUG, "NAL %d/%d at %d/%d length %d pass %d\n", hx->nal_unit_type, hx->nal_ref_idc, buf_index, buf_size, dst_length, pass);
 
             if (h->is_avc && (nalsize != consumed) && nalsize)
-                av_log(h->s.avctx, AV_LOG_DEBUG,
+                av_log(h->avctx, AV_LOG_DEBUG,
                        "AVC: Consumed only %d bytes instead of %d\n",
                        consumed, nalsize);
 
@@ -3859,23 +4439,35 @@
                 case NAL_PPS:
                     nals_needed = nal_index;
                     break;
+                case NAL_DPA:
                 case NAL_IDR_SLICE:
                 case NAL_SLICE:
-                    init_get_bits(&hx->s.gb, ptr, bit_length);
-                    if (!get_ue_golomb(&hx->s.gb))
+                    init_get_bits(&hx->gb, ptr, bit_length);
+                    if (!get_ue_golomb(&hx->gb) || !first_slice)
                         nals_needed = nal_index;
+                    if (!first_slice)
+                        first_slice = hx->nal_unit_type;
                 }
                 continue;
             }
 
+            if (!first_slice)
+                switch (hx->nal_unit_type) {
+                case NAL_DPA:
+                case NAL_IDR_SLICE:
+                case NAL_SLICE:
+                    first_slice = hx->nal_unit_type;
+                }
+
             // FIXME do not discard SEI id
             if (avctx->skip_frame >= AVDISCARD_NONREF && h->nal_ref_idc == 0)
                 continue;
 
 again:
-            err = 0;
-
-            if (h->decoding_extradata) {
+            /* Ignore per frame NAL unit type during extradata
+             * parsing. Decoding slices is not possible in codec init
+             * with frame-mt */
+            if (parse_extradata) {
                 switch (hx->nal_unit_type) {
                 case NAL_IDR_SLICE:
                 case NAL_SLICE:
@@ -3883,25 +4475,29 @@
                 case NAL_DPB:
                 case NAL_DPC:
                 case NAL_AUXILIARY_SLICE:
-                    av_log(h->s.avctx, AV_LOG_WARNING, "Ignoring NAL %d in global header\n", hx->nal_unit_type);
-                    hx->nal_unit_type = NAL_FILLER_DATA;
+                    av_log(h->avctx, AV_LOG_WARNING, "Ignoring NAL %d in global header/extradata\n", hx->nal_unit_type);
+                    hx->nal_unit_type = NAL_FF_IGNORE;
                 }
             }
 
+            err = 0;
+
             switch (hx->nal_unit_type) {
             case NAL_IDR_SLICE:
-                if (h->nal_unit_type != NAL_IDR_SLICE) {
-                    av_log(h->s.avctx, AV_LOG_ERROR,
+                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;
                     goto end;
                 }
-                idr(h); // FIXME ensure we don't lose some frames if there is reordering
+                if(!idr_cleared)
+                    idr(h); // FIXME ensure we don't lose some frames if there is reordering
+                idr_cleared = 1;
             case NAL_SLICE:
-                init_get_bits(&hx->s.gb, ptr, bit_length);
+                init_get_bits(&hx->gb, ptr, bit_length);
                 hx->intra_gb_ptr        =
-                    hx->inter_gb_ptr    = &hx->s.gb;
-                hx->s.data_partitioning = 0;
+                    hx->inter_gb_ptr    = &hx->gb;
+                hx->data_partitioning = 0;
 
                 if ((err = decode_slice_header(hx, h)))
                     break;
@@ -3919,28 +4515,28 @@
                         h->recovery_frame = h->frame_num;
                 }
 
-                s->current_picture_ptr->f.key_frame |=
+                h->cur_pic_ptr->f.key_frame |=
                         (hx->nal_unit_type == NAL_IDR_SLICE);
 
                 if (h->recovery_frame == h->frame_num) {
-                    s->current_picture_ptr->sync |= 1;
+                    h->cur_pic_ptr->sync |= 1;
                     h->recovery_frame = -1;
                 }
 
-                h->sync |= !!s->current_picture_ptr->f.key_frame;
-                h->sync |= 3*!!(s->flags2 & CODEC_FLAG2_SHOW_ALL);
-                s->current_picture_ptr->sync |= h->sync;
+                h->sync |= !!h->cur_pic_ptr->f.key_frame;
+                h->sync |= 3*!!(avctx->flags2 & CODEC_FLAG2_SHOW_ALL);
+                h->cur_pic_ptr->sync |= h->sync;
 
                 if (h->current_slice == 1) {
-                    if (!(s->flags2 & CODEC_FLAG2_CHUNKS))
+                    if (!(avctx->flags2 & CODEC_FLAG2_CHUNKS))
                         decode_postinit(h, nal_index >= nals_needed);
 
-                    if (s->avctx->hwaccel &&
-                        s->avctx->hwaccel->start_frame(s->avctx, NULL, 0) < 0)
+                    if (h->avctx->hwaccel &&
+                        h->avctx->hwaccel->start_frame(h->avctx, NULL, 0) < 0)
                         return -1;
                     if (CONFIG_H264_VDPAU_DECODER &&
-                        s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)
-                        ff_vdpau_h264_picture_start(s);
+                        h->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)
+                        ff_vdpau_h264_picture_start(h);
                 }
 
                 if (hx->redundant_pic_count == 0 &&
@@ -3957,26 +4553,26 @@
                                                          consumed) < 0)
                             return -1;
                     } else if (CONFIG_H264_VDPAU_DECODER &&
-                               s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) {
+                               h->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) {
                         static const uint8_t start_code[] = {
                             0x00, 0x00, 0x01 };
-                        ff_vdpau_add_data_chunk(s, start_code,
+                        ff_vdpau_add_data_chunk(h->cur_pic_ptr->f.data[0], start_code,
                                                 sizeof(start_code));
-                        ff_vdpau_add_data_chunk(s, &buf[buf_index - consumed],
+                        ff_vdpau_add_data_chunk(h->cur_pic_ptr->f.data[0], &buf[buf_index - consumed],
                                                 consumed);
                     } else
                         context_count++;
                 }
                 break;
             case NAL_DPA:
-                init_get_bits(&hx->s.gb, ptr, bit_length);
+                init_get_bits(&hx->gb, ptr, bit_length);
                 hx->intra_gb_ptr =
                 hx->inter_gb_ptr = NULL;
 
                 if ((err = decode_slice_header(hx, h)) < 0)
                     break;
 
-                hx->s.data_partitioning = 1;
+                hx->data_partitioning = 1;
                 break;
             case NAL_DPB:
                 init_get_bits(&hx->intra_gb, ptr, bit_length);
@@ -3986,14 +4582,13 @@
                 init_get_bits(&hx->inter_gb, ptr, bit_length);
                 hx->inter_gb_ptr = &hx->inter_gb;
 
-                av_log(h->s.avctx, AV_LOG_ERROR, "Partitioned H.264 support is incomplete\n");
+                av_log(h->avctx, AV_LOG_ERROR, "Partitioned H.264 support is incomplete\n");
                 break;
 
                 if (hx->redundant_pic_count == 0 &&
                     hx->intra_gb_ptr &&
-                    hx->s.data_partitioning &&
-                    s->current_picture_ptr &&
-                    s->context_initialized &&
+                    hx->data_partitioning &&
+                    h->cur_pic_ptr && h->context_initialized &&
                     (avctx->skip_frame < AVDISCARD_NONREF || hx->nal_ref_idc) &&
                     (avctx->skip_frame < AVDISCARD_BIDIR  ||
                      hx->slice_type_nos != AV_PICTURE_TYPE_B) &&
@@ -4003,39 +4598,26 @@
                     context_count++;
                 break;
             case NAL_SEI:
-                init_get_bits(&s->gb, ptr, bit_length);
+                init_get_bits(&h->gb, ptr, bit_length);
                 ff_h264_decode_sei(h);
                 break;
             case NAL_SPS:
-                init_get_bits(&s->gb, ptr, bit_length);
+                init_get_bits(&h->gb, ptr, bit_length);
                 if (ff_h264_decode_seq_parameter_set(h) < 0 && (h->is_avc ? (nalsize != consumed) && nalsize : 1)) {
-                    av_log(h->s.avctx, AV_LOG_DEBUG,
+                    av_log(h->avctx, AV_LOG_DEBUG,
                            "SPS decoding failure, trying again with the complete NAL\n");
                     if (h->is_avc)
                         av_assert0(next_avc - buf_index + consumed == nalsize);
                     if ((next_avc - buf_index + consumed - 1) >= INT_MAX/8)
                         break;
-                    init_get_bits(&s->gb, &buf[buf_index + 1 - consumed],
+                    init_get_bits(&h->gb, &buf[buf_index + 1 - consumed],
                                   8*(next_avc - buf_index + consumed - 1));
                     ff_h264_decode_seq_parameter_set(h);
                 }
 
-                if (s->flags & CODEC_FLAG_LOW_DELAY ||
-                    (h->sps.bitstream_restriction_flag &&
-                     !h->sps.num_reorder_frames)) {
-                    if (s->avctx->has_b_frames > 1 || h->delayed_pic[0])
-                        av_log(avctx, AV_LOG_WARNING, "Delayed frames seen "
-                               "reenabling low delay requires a codec "
-                               "flush.\n");
-                        else
-                            s->low_delay = 1;
-                }
-
-                if (avctx->has_b_frames < 2)
-                    avctx->has_b_frames = !s->low_delay;
                 break;
             case NAL_PPS:
-                init_get_bits(&s->gb, ptr, bit_length);
+                init_get_bits(&h->gb, ptr, bit_length);
                 ff_h264_decode_picture_parameter_set(h, bit_length);
                 break;
             case NAL_AUD:
@@ -4045,6 +4627,8 @@
             case NAL_SPS_EXT:
             case NAL_AUXILIARY_SLICE:
                 break;
+            case NAL_FF_IGNORE:
+                break;
             default:
                 av_log(avctx, AV_LOG_DEBUG, "Unknown NAL code: %d (%d bits)\n",
                        hx->nal_unit_type, bit_length);
@@ -4056,7 +4640,7 @@
             }
 
             if (err < 0)
-                av_log(h->s.avctx, AV_LOG_ERROR, "decode_slice_header error\n");
+                av_log(h->avctx, AV_LOG_ERROR, "decode_slice_header error\n");
             else if (err == 1) {
                 /* Slice could not be decoded in parallel mode, copy down
                  * NAL unit stuff to context 0 and restart. Note that
@@ -4074,10 +4658,10 @@
 
 end:
     /* clean up */
-    if (s->current_picture_ptr && s->current_picture_ptr->owner2 == s &&
-        !s->dropable) {
-        ff_thread_report_progress(&s->current_picture_ptr->f, INT_MAX,
-                                  s->picture_structure == PICT_BOTTOM_FIELD);
+    if (h->cur_pic_ptr && h->cur_pic_ptr->owner2 == h &&
+        !h->droppable) {
+        ff_thread_report_progress(&h->cur_pic_ptr->f, INT_MAX,
+                                  h->picture_structure == PICT_BOTTOM_FIELD);
     }
 
     return buf_index;
@@ -4086,7 +4670,7 @@
 /**
  * Return the number of bytes consumed for building the current frame.
  */
-static int get_consumed_bytes(MpegEncContext *s, int pos, int buf_size)
+static int get_consumed_bytes(int pos, int buf_size)
 {
     if (pos == 0)
         pos = 1;          // avoid infinite loops (i doubt that is needed but ...)
@@ -4097,25 +4681,24 @@
 }
 
 static int decode_frame(AVCodecContext *avctx, void *data,
-                        int *data_size, AVPacket *avpkt)
+                        int *got_frame, AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
     H264Context *h     = avctx->priv_data;
-    MpegEncContext *s  = &h->s;
     AVFrame *pict      = data;
     int buf_index      = 0;
     Picture *out;
     int i, out_idx;
 
-    s->flags  = avctx->flags;
-    s->flags2 = avctx->flags2;
+    h->flags  = avctx->flags;
 
     /* end of stream, output what is still in the buffers */
     if (buf_size == 0) {
  out:
 
-        s->current_picture_ptr = NULL;
+        h->cur_pic_ptr = NULL;
+        h->first_field = 0;
 
         // FIXME factorize this with the output code below
         out     = h->delayed_pic[0];
@@ -4134,7 +4717,8 @@
             h->delayed_pic[i] = h->delayed_pic[i + 1];
 
         if (out) {
-            *data_size = sizeof(AVFrame);
+            out->f.reference &= ~DELAYED_PIC_REF;
+            *got_frame = 1;
             *pict      = out->f;
         }
 
@@ -4163,16 +4747,16 @@
     }
 not_extra:
 
-    buf_index = decode_nal_units(h, buf, buf_size);
+    buf_index = decode_nal_units(h, buf, buf_size, 0);
     if (buf_index < 0)
         return -1;
 
-    if (!s->current_picture_ptr && h->nal_unit_type == NAL_END_SEQUENCE) {
+    if (!h->cur_pic_ptr && h->nal_unit_type == NAL_END_SEQUENCE) {
         av_assert0(buf_index <= buf_size);
         goto out;
     }
 
-    if (!(s->flags2 & CODEC_FLAG2_CHUNKS) && !s->current_picture_ptr) {
+    if (!(avctx->flags2 & CODEC_FLAG2_CHUNKS) && !h->cur_pic_ptr) {
         if (avctx->skip_frame >= AVDISCARD_NONREF ||
             buf_size >= 4 && !memcmp("Q264", buf, 4))
             return buf_size;
@@ -4180,25 +4764,27 @@
         return -1;
     }
 
-    if (!(s->flags2 & CODEC_FLAG2_CHUNKS) ||
-        (s->mb_y >= s->mb_height && s->mb_height)) {
-        if (s->flags2 & CODEC_FLAG2_CHUNKS)
+    if (!(avctx->flags2 & CODEC_FLAG2_CHUNKS) ||
+        (h->mb_y >= h->mb_height && h->mb_height)) {
+        if (avctx->flags2 & CODEC_FLAG2_CHUNKS)
             decode_postinit(h, 1);
 
         field_end(h, 0);
 
         /* Wait for second field. */
-        *data_size = 0;
+        *got_frame = 0;
         if (h->next_output_pic && (h->next_output_pic->sync || h->sync>1)) {
-            *data_size = sizeof(AVFrame);
+            *got_frame = 1;
             *pict      = h->next_output_pic->f;
         }
     }
 
-    assert(pict->data[0] || !*data_size);
-    ff_print_debug_info(s, pict);
+    assert(pict->data[0] || !*got_frame);
 
-    return get_consumed_bytes(s, buf_index, buf_size);
+    ff_print_debug_info2(h->avctx, pict, h->er.mbskip_table, h->visualization_buffer, &h->low_delay,
+                         h->mb_width, h->mb_height, h->mb_stride, 1);
+
+    return get_consumed_bytes(buf_index, buf_size);
 }
 
 av_cold void ff_h264_free_context(H264Context *h)
@@ -4217,14 +4803,17 @@
 static av_cold int h264_decode_end(AVCodecContext *avctx)
 {
     H264Context *h    = avctx->priv_data;
-    MpegEncContext *s = &h->s;
+    int i;
 
     ff_h264_remove_all_refs(h);
     ff_h264_free_context(h);
 
-    ff_MPV_common_end(s);
-
-    // memset(h, 0, sizeof(H264Context));
+    if (h->DPB && !h->avctx->internal->is_copy) {
+        for (i = 0; i < h->picture_count; i++) {
+            free_picture(h, &h->DPB[i]);
+        }
+    }
+    av_freep(&h->DPB);
 
     return 0;
 }
diff --git a/libavcodec/h264.h b/libavcodec/h264.h
index 00a1fc3..d391b22 100644
--- a/libavcodec/h264.h
+++ b/libavcodec/h264.h
@@ -29,16 +29,15 @@
 #define AVCODEC_H264_H
 
 #include "libavutil/intreadwrite.h"
-#include "dsputil.h"
 #include "cabac.h"
+#include "get_bits.h"
 #include "mpegvideo.h"
+#include "h264chroma.h"
 #include "h264dsp.h"
 #include "h264pred.h"
+#include "h264qpel.h"
 #include "rectangle.h"
 
-#define interlaced_dct interlaced_dct_is_a_bad_name
-#define mb_intra       mb_intra_is_not_initialized_see_mb_type
-
 #define MAX_SPS_COUNT          32
 #define MAX_PPS_COUNT         256
 
@@ -64,7 +63,7 @@
 #define MB_MBAFF    h->mb_mbaff
 #define MB_FIELD    h->mb_field_decoding_flag
 #define FRAME_MBAFF h->mb_aff_frame
-#define FIELD_PICTURE (s->picture_structure != PICT_FRAME)
+#define FIELD_PICTURE (h->picture_structure != PICT_FRAME)
 #define LEFT_MBS 2
 #define LTOP     0
 #define LBOT     1
@@ -98,12 +97,6 @@
 #define IS_REF0(a)         ((a) & MB_TYPE_REF0)
 #define IS_8x8DCT(a)       ((a) & MB_TYPE_8x8DCT)
 
-/**
- * Value of Picture.reference when Picture is not a reference picture, but
- * is held for delayed output.
- */
-#define DELAYED_PIC_REF 4
-
 #define QP_MAX_NUM (51 + 6*6)           // The maximum supported qp
 
 /* NAL unit types */
@@ -121,7 +114,8 @@
     NAL_END_STREAM,
     NAL_FILLER_DATA,
     NAL_SPS_EXT,
-    NAL_AUXILIARY_SLICE = 19
+    NAL_AUXILIARY_SLICE = 19,
+    NAL_FF_IGNORE       = 0xff0f001,
 };
 
 /**
@@ -207,6 +201,7 @@
     int bit_depth_chroma;                 ///< bit_depth_chroma_minus8 + 8
     int residual_color_transform_flag;    ///< residual_colour_transform_flag
     int constraint_set_flags;             ///< constraint_set[0-3]_flag
+    int new;                              ///< flag to keep track if the decoder context needs re-init due to changed SPS
 } SPS;
 
 /**
@@ -260,13 +255,42 @@
  * H264Context
  */
 typedef struct H264Context {
-    MpegEncContext s;
+    AVCodecContext *avctx;
+    DSPContext       dsp;
+    VideoDSPContext vdsp;
     H264DSPContext h264dsp;
+    H264ChromaContext h264chroma;
+    H264QpelContext h264qpel;
+    MotionEstContext me;
+    ParseContext parse_context;
+    GetBitContext gb;
+    ERContext er;
+
+    Picture *DPB;
+    Picture *cur_pic_ptr;
+    Picture cur_pic;
+    int picture_count;
+    int picture_range_start, picture_range_end;
+
     int pixel_shift;    ///< 0 for 8-bit H264, 1 for high-bit-depth H264
     int chroma_qp[2];   // QPc
 
     int qp_thresh;      ///< QP threshold to skip loopfilter
 
+    int width, height;
+    int linesize, uvlinesize;
+    int chroma_x_shift, chroma_y_shift;
+
+    int qscale;
+    int droppable;
+    int data_partitioning;
+    int coded_picture_number;
+    int low_delay;
+
+    int context_initialized;
+    int flags;
+    int workaround_bugs;
+
     int prev_mb_skipped;
     int next_mb_skipped;
 
@@ -330,9 +354,7 @@
     int mb_linesize;    ///< may be equal to s->linesize or s->linesize * 2, for mbaff
     int mb_uvlinesize;
 
-    int emu_edge_width;
-    int emu_edge_height;
-
+    unsigned current_sps_id; ///< id of the current SPS
     SPS sps; ///< current sps
 
     /**
@@ -355,6 +377,8 @@
     int mb_aff_frame;
     int mb_field_decoding_flag;
     int mb_mbaff;               ///< mb_aff_frame && mb_field_decoding_flag
+    int picture_structure;
+    int first_field;
 
     DECLARE_ALIGNED(8, uint16_t, sub_mb_type)[4];
 
@@ -371,7 +395,7 @@
     int direct_spatial_mv_pred;
     int col_parity;
     int col_fieldoff;
-    int dist_scale_factor[16];
+    int dist_scale_factor[32];
     int dist_scale_factor_field[2][32];
     int map_col_to_list0[2][16 + 32];
     int map_col_to_list0_field[2][2][16 + 32];
@@ -393,9 +417,10 @@
     GetBitContext *intra_gb_ptr;
     GetBitContext *inter_gb_ptr;
 
-    DECLARE_ALIGNED(16, DCTELEM, mb)[16 * 48 * 2]; ///< as a dct coeffecient is int32_t in high depth, we need to reserve twice the space.
-    DECLARE_ALIGNED(16, DCTELEM, mb_luma_dc)[3][16 * 2];
-    DCTELEM mb_padding[256 * 2];        ///< as mb is addressed by scantable[i] and scantable is uint8_t we can either check that i is not too large or ensure that there is some unused stuff after mb
+    const uint8_t *intra_pcm_ptr;
+    DECLARE_ALIGNED(16, int16_t, mb)[16 * 48 * 2]; ///< as a dct coeffecient is int32_t in high depth, we need to reserve twice the space.
+    DECLARE_ALIGNED(16, int16_t, mb_luma_dc)[3][16 * 2];
+    int16_t mb_padding[256 * 2];        ///< as mb is addressed by scantable[i] and scantable is uint8_t we can either check that i is not too large or ensure that there is some unused stuff after mb
 
     /**
      * Cabac
@@ -431,6 +456,13 @@
 
     int x264_build;
 
+    int mb_x, mb_y;
+    int resync_mb_x;
+    int resync_mb_y;
+    int mb_skip_run;
+    int mb_height, mb_width;
+    int mb_stride;
+    int mb_num;
     int mb_xy;
 
     int is_complex;
@@ -447,7 +479,6 @@
     int nal_unit_type;
     uint8_t *rbsp_buffer[2];
     unsigned int rbsp_buffer_size[2];
-    int decoding_extradata;
 
     /**
      * Used to parse AVC variant of h264
@@ -456,6 +487,9 @@
     int nal_length_size;  ///< Number of bytes used for nal length (1, 2 or 4)
     int got_first;        ///< this flag is != 0 if we've parsed a frame
 
+    int bit_depth_luma;         ///< luma bit depth from sps to detect changes
+    int chroma_format_idc;      ///< chroma format from sps to detect changes
+
     SPS *sps_buffers[MAX_SPS_COUNT];
     PPS *pps_buffers[MAX_PPS_COUNT];
 
@@ -487,9 +521,9 @@
 
     int redundant_pic_count;
 
+    Picture default_ref_list[2][32]; ///< base reference list for all slices of a coded picture
     Picture *short_ref[32];
     Picture *long_ref[32];
-    Picture default_ref_list[2][32]; ///< base reference list for all slices of a coded picture
     Picture *delayed_pic[MAX_DELAYED_PIC_COUNT + 2]; // FIXME size?
     int last_pocs[MAX_DELAYED_PIC_COUNT];
     Picture *next_output_pic;
@@ -527,13 +561,18 @@
      */
     int max_contexts;
 
+    int slice_context_count;
+
     /**
      *  1 if the single thread fallback warning has already been
      *  displayed, 0 otherwise.
      */
     int single_decode_warning;
 
+    enum AVPictureType pict_type;
+
     int last_slice_type;
+    unsigned int last_ref_count[2];
     /** @} */
 
     /**
@@ -595,6 +634,7 @@
     int initial_cpb_removal_delay[32];  ///< Initial timestamps for CPBs
 
     int cur_chroma_format_idc;
+    uint8_t *bipred_scratchpad;
 
     int16_t slice_row[MAX_SLICES]; ///< to detect when MAX_SLICES is too low
 
@@ -603,6 +643,10 @@
     uint8_t parse_history[4];
     int parse_history_count;
     int parse_last_mb;
+    uint8_t *edge_emu_buffer;
+    int16_t *dc_val_base;
+
+    uint8_t *visualization_buffer[3]; ///< temporary buffer vor MV visualization
 } H264Context;
 
 extern const uint8_t ff_h264_chroma_qp[7][QP_MAX_NUM + 1]; ///< One chroma qp table for each possible bit depth (8-14).
@@ -643,7 +687,7 @@
  * Free any data that may have been allocated in the H264 context
  * like SPS, PPS etc.
  */
-av_cold void ff_h264_free_context(H264Context *h);
+void ff_h264_free_context(H264Context *h);
 
 /**
  * Reconstruct bitstream slice_type.
@@ -670,9 +714,10 @@
  */
 int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count);
 
-int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb);
+int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb,
+                                   int first_slice);
 
-void ff_generate_sliding_window_mmcos(H264Context *h);
+int ff_generate_sliding_window_mmcos(H264Context *h, int first_slice);
 
 /**
  * Check if the top & left blocks are available if needed & change the
@@ -689,8 +734,8 @@
 void ff_h264_hl_decode_mb(H264Context *h);
 int ff_h264_frame_start(H264Context *h);
 int ff_h264_decode_extradata(H264Context *h, const uint8_t *buf, int size);
-av_cold int ff_h264_decode_init(AVCodecContext *avctx);
-av_cold void ff_h264_decode_init_vlc(void);
+int ff_h264_decode_init(AVCodecContext *avctx);
+void ff_h264_decode_init_vlc(void);
 
 /**
  * Decode a macroblock
@@ -810,7 +855,7 @@
     const int top    = h->intra4x4_pred_mode_cache[index8 - 8];
     const int min    = FFMIN(left, top);
 
-    tprintf(h->s.avctx, "mode:%d %d min:%d\n", left, top, min);
+    tprintf(h->avctx, "mode:%d %d min:%d\n", left, top, min);
 
     if (min < 0)
         return DC_PRED;
@@ -844,7 +889,7 @@
     AV_COPY32(&nnz[32], &nnz_cache[4 + 8 * 11]);
     AV_COPY32(&nnz[36], &nnz_cache[4 + 8 * 12]);
 
-    if (!h->s.chroma_y_shift) {
+    if (!h->chroma_y_shift) {
         AV_COPY32(&nnz[24], &nnz_cache[4 + 8 * 8]);
         AV_COPY32(&nnz[28], &nnz_cache[4 + 8 * 9]);
         AV_COPY32(&nnz[40], &nnz_cache[4 + 8 * 13]);
@@ -853,12 +898,11 @@
 }
 
 static av_always_inline void write_back_motion_list(H264Context *h,
-                                                    MpegEncContext *const s,
                                                     int b_stride,
                                                     int b_xy, int b8_xy,
                                                     int mb_type, int list)
 {
-    int16_t(*mv_dst)[2] = &s->current_picture.f.motion_val[list][b_xy];
+    int16_t(*mv_dst)[2] = &h->cur_pic.f.motion_val[list][b_xy];
     int16_t(*mv_src)[2] = &h->mv_cache[list][scan8[0]];
     AV_COPY128(mv_dst + 0 * b_stride, mv_src + 8 * 0);
     AV_COPY128(mv_dst + 1 * b_stride, mv_src + 8 * 1);
@@ -879,7 +923,7 @@
     }
 
     {
-        int8_t *ref_index = &s->current_picture.f.ref_index[list][b8_xy];
+        int8_t *ref_index = &h->cur_pic.f.ref_index[list][b8_xy];
         int8_t *ref_cache = h->ref_cache[list];
         ref_index[0 + 0 * 2] = ref_cache[scan8[0]];
         ref_index[1 + 0 * 2] = ref_cache[scan8[4]];
@@ -890,19 +934,18 @@
 
 static av_always_inline void write_back_motion(H264Context *h, int mb_type)
 {
-    MpegEncContext *const s = &h->s;
     const int b_stride      = h->b_stride;
-    const int b_xy  = 4 * s->mb_x + 4 * s->mb_y * h->b_stride; // try mb2b(8)_xy
+    const int b_xy  = 4 * h->mb_x + 4 * h->mb_y * h->b_stride; // try mb2b(8)_xy
     const int b8_xy = 4 * h->mb_xy;
 
     if (USES_LIST(mb_type, 0)) {
-        write_back_motion_list(h, s, b_stride, b_xy, b8_xy, mb_type, 0);
+        write_back_motion_list(h, b_stride, b_xy, b8_xy, mb_type, 0);
     } else {
-        fill_rectangle(&s->current_picture.f.ref_index[0][b8_xy],
+        fill_rectangle(&h->cur_pic.f.ref_index[0][b8_xy],
                        2, 2, 2, (uint8_t)LIST_NOT_USED, 1);
     }
     if (USES_LIST(mb_type, 1))
-        write_back_motion_list(h, s, b_stride, b_xy, b8_xy, mb_type, 1);
+        write_back_motion_list(h, b_stride, b_xy, b8_xy, mb_type, 1);
 
     if (h->slice_type_nos == AV_PICTURE_TYPE_B && CABAC) {
         if (IS_8X8(mb_type)) {
@@ -926,4 +969,6 @@
                   0x0001000100010001ULL));
 }
 
+void ff_h264_draw_horiz_band(H264Context *h, int y, int height);
+
 #endif /* AVCODEC_H264_H */
diff --git a/libavcodec/h264_cabac.c b/libavcodec/h264_cabac.c
index 015b02e..bf9cf15 100644
--- a/libavcodec/h264_cabac.c
+++ b/libavcodec/h264_cabac.c
@@ -31,7 +31,6 @@
 #include "cabac.h"
 #include "cabac_functions.h"
 #include "internal.h"
-#include "dsputil.h"
 #include "avcodec.h"
 #include "h264.h"
 #include "h264data.h"
@@ -1258,10 +1257,9 @@
 };
 
 void ff_h264_init_cabac_states(H264Context *h) {
-    MpegEncContext * const s = &h->s;
     int i;
     const int8_t (*tab)[2];
-    const int slice_qp = av_clip(s->qscale - 6*(h->sps.bit_depth_luma-8), 0, 51);
+    const int slice_qp = av_clip(h->qscale - 6*(h->sps.bit_depth_luma-8), 0, 51);
 
     if( h->slice_type_nos == AV_PICTURE_TYPE_I ) tab = cabac_context_init_I;
     else                                 tab = cabac_context_init_PB[h->cabac_init_idc];
@@ -1279,13 +1277,12 @@
 }
 
 static int decode_cabac_field_decoding_flag(H264Context *h) {
-    MpegEncContext * const s = &h->s;
-    const long mbb_xy = h->mb_xy - 2L*s->mb_stride;
+    const long mbb_xy = h->mb_xy - 2L*h->mb_stride;
 
     unsigned long ctx = 0;
 
-    ctx += h->mb_field_decoding_flag & !!s->mb_x; //for FMO:(s->current_picture.f.mb_type[mba_xy] >> 7) & (h->slice_table[mba_xy] == h->slice_num);
-    ctx += (s->current_picture.f.mb_type[mbb_xy] >> 7) & (h->slice_table[mbb_xy] == h->slice_num);
+    ctx += h->mb_field_decoding_flag & !!h->mb_x; //for FMO:(s->current_picture.f.mb_type[mba_xy] >> 7) & (h->slice_table[mba_xy] == h->slice_num);
+    ctx += (h->cur_pic.f.mb_type[mbb_xy] >> 7) & (h->slice_table[mbb_xy] == h->slice_num);
 
     return get_cabac_noinline( &h->cabac, &(h->cabac_state+70)[ctx] );
 }
@@ -1321,34 +1318,33 @@
 }
 
 static int decode_cabac_mb_skip( H264Context *h, int mb_x, int mb_y ) {
-    MpegEncContext * const s = &h->s;
     int mba_xy, mbb_xy;
     int ctx = 0;
 
     if(FRAME_MBAFF){ //FIXME merge with the stuff in fill_caches?
-        int mb_xy = mb_x + (mb_y&~1)*s->mb_stride;
+        int mb_xy = mb_x + (mb_y&~1)*h->mb_stride;
         mba_xy = mb_xy - 1;
         if( (mb_y&1)
             && h->slice_table[mba_xy] == h->slice_num
-            && MB_FIELD == !!IS_INTERLACED( s->current_picture.f.mb_type[mba_xy] ) )
-            mba_xy += s->mb_stride;
+            && MB_FIELD == !!IS_INTERLACED( h->cur_pic.f.mb_type[mba_xy] ) )
+            mba_xy += h->mb_stride;
         if( MB_FIELD ){
-            mbb_xy = mb_xy - s->mb_stride;
+            mbb_xy = mb_xy - h->mb_stride;
             if( !(mb_y&1)
                 && h->slice_table[mbb_xy] == h->slice_num
-                && IS_INTERLACED( s->current_picture.f.mb_type[mbb_xy] ) )
-                mbb_xy -= s->mb_stride;
+                && IS_INTERLACED( h->cur_pic.f.mb_type[mbb_xy] ) )
+                mbb_xy -= h->mb_stride;
         }else
-            mbb_xy = mb_x + (mb_y-1)*s->mb_stride;
+            mbb_xy = mb_x + (mb_y-1)*h->mb_stride;
     }else{
         int mb_xy = h->mb_xy;
         mba_xy = mb_xy - 1;
-        mbb_xy = mb_xy - (s->mb_stride << FIELD_PICTURE);
+        mbb_xy = mb_xy - (h->mb_stride << FIELD_PICTURE);
     }
 
-    if( h->slice_table[mba_xy] == h->slice_num && !IS_SKIP( s->current_picture.f.mb_type[mba_xy] ))
+    if( h->slice_table[mba_xy] == h->slice_num && !IS_SKIP(h->cur_pic.f.mb_type[mba_xy] ))
         ctx++;
-    if( h->slice_table[mbb_xy] == h->slice_num && !IS_SKIP( s->current_picture.f.mb_type[mbb_xy] ))
+    if( h->slice_table[mbb_xy] == h->slice_num && !IS_SKIP(h->cur_pic.f.mb_type[mbb_xy] ))
         ctx++;
 
     if( h->slice_type_nos == AV_PICTURE_TYPE_B )
@@ -1505,7 +1501,7 @@
             mvd += 1 << k;
             k++;
             if(k>24){
-                av_log(h->s.avctx, AV_LOG_ERROR, "overflow in decode_cabac_mb_mvd\n");
+                av_log(h->avctx, AV_LOG_ERROR, "overflow in decode_cabac_mb_mvd\n");
                 return INT_MIN;
             }
         }
@@ -1559,7 +1555,7 @@
 }
 
 static av_always_inline void
-decode_cabac_residual_internal(H264Context *h, DCTELEM *block,
+decode_cabac_residual_internal(H264Context *h, int16_t *block,
                                int cat, int n, const uint8_t *scantable,
                                const uint32_t *qmul, int max_coeff,
                                int is_dc, int chroma422)
@@ -1711,7 +1707,7 @@
 \
             if( coeff_abs >= 15 ) { \
                 int j = 0; \
-                while( get_cabac_bypass( CC ) ) { \
+                while(get_cabac_bypass( CC ) && j<30) { \
                     j++; \
                 } \
 \
@@ -1743,18 +1739,27 @@
 
 }
 
-static void decode_cabac_residual_dc_internal( H264Context *h, DCTELEM *block, int cat, int n, const uint8_t *scantable, int max_coeff ) {
+static void decode_cabac_residual_dc_internal(H264Context *h, int16_t *block,
+                                              int cat, int n,
+                                              const uint8_t *scantable,
+                                              int max_coeff)
+{
     decode_cabac_residual_internal(h, block, cat, n, scantable, NULL, max_coeff, 1, 0);
 }
 
-static void decode_cabac_residual_dc_internal_422(H264Context *h, DCTELEM *block,
+static void decode_cabac_residual_dc_internal_422(H264Context *h, int16_t *block,
                                                   int cat, int n, const uint8_t *scantable,
                                                   int max_coeff)
 {
     decode_cabac_residual_internal(h, block, cat, n, scantable, NULL, max_coeff, 1, 1);
 }
 
-static void decode_cabac_residual_nondc_internal( H264Context *h, DCTELEM *block, int cat, int n, const uint8_t *scantable, const uint32_t *qmul, int max_coeff ) {
+static void decode_cabac_residual_nondc_internal(H264Context *h, int16_t *block,
+                                                 int cat, int n,
+                                                 const uint8_t *scantable,
+                                                 const uint32_t *qmul,
+                                                 int max_coeff)
+{
     decode_cabac_residual_internal(h, block, cat, n, scantable, qmul, max_coeff, 0, 0);
 }
 
@@ -1770,7 +1775,12 @@
  * because it allows improved constant propagation into get_cabac_cbf_ctx,
  * as well as because most blocks have zero CBFs. */
 
-static av_always_inline void decode_cabac_residual_dc( H264Context *h, DCTELEM *block, int cat, int n, const uint8_t *scantable, int max_coeff ) {
+static av_always_inline void decode_cabac_residual_dc(H264Context *h,
+                                                      int16_t *block,
+                                                      int cat, int n,
+                                                      const uint8_t *scantable,
+                                                      int max_coeff)
+{
     /* read coded block flag */
     if( get_cabac( &h->cabac, &h->cabac_state[get_cabac_cbf_ctx( h, cat, n, max_coeff, 1 ) ] ) == 0 ) {
         h->non_zero_count_cache[scan8[n]] = 0;
@@ -1780,7 +1790,7 @@
 }
 
 static av_always_inline void
-decode_cabac_residual_dc_422(H264Context *h, DCTELEM *block,
+decode_cabac_residual_dc_422(H264Context *h, int16_t *block,
                              int cat, int n, const uint8_t *scantable,
                              int max_coeff)
 {
@@ -1792,7 +1802,13 @@
     decode_cabac_residual_dc_internal_422(h, block, cat, n, scantable, max_coeff);
 }
 
-static av_always_inline void decode_cabac_residual_nondc( H264Context *h, DCTELEM *block, int cat, int n, const uint8_t *scantable, const uint32_t *qmul, int max_coeff ) {
+static av_always_inline void decode_cabac_residual_nondc(H264Context *h,
+                                                         int16_t *block,
+                                                         int cat, int n,
+                                                         const uint8_t *scantable,
+                                                         const uint32_t *qmul,
+                                                         int max_coeff)
+{
     /* read coded block flag */
     if( (cat != 5 || CHROMA444) && get_cabac( &h->cabac, &h->cabac_state[get_cabac_cbf_ctx( h, cat, n, max_coeff, 0 ) ] ) == 0 ) {
         if( max_coeff == 64 ) {
@@ -1810,8 +1826,7 @@
     static const uint8_t ctx_cat[4][3] = {{0,6,10},{1,7,11},{2,8,12},{5,9,13}};
     const uint32_t *qmul;
     int i8x8, i4x4;
-    MpegEncContext * const s = &h->s;
-    int qscale = p == 0 ? s->qscale : h->chroma_qp[p-1];
+    int qscale = p == 0 ? h->qscale : h->chroma_qp[p-1];
     if( IS_INTRA16x16( mb_type ) ) {
         AV_ZERO128(h->mb_luma_dc[p]+0);
         AV_ZERO128(h->mb_luma_dc[p]+8);
@@ -1857,7 +1872,6 @@
  * @return 0 if OK, ER_AC_ERROR / ER_DC_ERROR / ER_MV_ERROR if an error is noticed
  */
 int ff_h264_decode_mb_cabac(H264Context *h) {
-    MpegEncContext * const s = &h->s;
     int mb_xy;
     int mb_type, partition_count, cbp = 0;
     int dct8x8_allowed= h->pps.transform_8x8_mode;
@@ -1865,21 +1879,21 @@
     const int pixel_shift = h->pixel_shift;
     unsigned local_ref_count[2];
 
-    mb_xy = h->mb_xy = s->mb_x + s->mb_y*s->mb_stride;
+    mb_xy = h->mb_xy = h->mb_x + h->mb_y*h->mb_stride;
 
-    tprintf(s->avctx, "pic:%d mb:%d/%d\n", h->frame_num, s->mb_x, s->mb_y);
+    tprintf(h->avctx, "pic:%d mb:%d/%d\n", h->frame_num, h->mb_x, h->mb_y);
     if( h->slice_type_nos != AV_PICTURE_TYPE_I ) {
         int skip;
         /* a skipped mb needs the aff flag from the following mb */
-        if( FRAME_MBAFF && (s->mb_y&1)==1 && h->prev_mb_skipped )
+        if( FRAME_MBAFF && (h->mb_y&1)==1 && h->prev_mb_skipped )
             skip = h->next_mb_skipped;
         else
-            skip = decode_cabac_mb_skip( h, s->mb_x, s->mb_y );
+            skip = decode_cabac_mb_skip( h, h->mb_x, h->mb_y );
         /* read skip flags */
         if( skip ) {
-            if( FRAME_MBAFF && (s->mb_y&1)==0 ){
-                s->current_picture.f.mb_type[mb_xy] = MB_TYPE_SKIP;
-                h->next_mb_skipped = decode_cabac_mb_skip( h, s->mb_x, s->mb_y+1 );
+            if( FRAME_MBAFF && (h->mb_y&1)==0 ){
+                h->cur_pic.f.mb_type[mb_xy] = MB_TYPE_SKIP;
+                h->next_mb_skipped = decode_cabac_mb_skip( h, h->mb_x, h->mb_y+1 );
                 if(!h->next_mb_skipped)
                     h->mb_mbaff = h->mb_field_decoding_flag = decode_cabac_field_decoding_flag(h);
             }
@@ -1895,7 +1909,7 @@
         }
     }
     if(FRAME_MBAFF){
-        if( (s->mb_y&1) == 0 )
+        if( (h->mb_y&1) == 0 )
             h->mb_mbaff =
             h->mb_field_decoding_flag = decode_cabac_field_decoding_flag(h);
     }
@@ -1988,7 +2002,8 @@
         // The pixels are stored in the same order as levels in h->mb array.
         if ((int) (h->cabac.bytestream_end - ptr) < mb_size)
             return -1;
-        memcpy(h->mb, ptr, mb_size); ptr+=mb_size;
+        h->intra_pcm_ptr = ptr;
+        ptr += mb_size;
 
         ff_init_cabac_decoder(&h->cabac, ptr, h->cabac.bytestream_end - ptr);
 
@@ -1996,10 +2011,10 @@
         h->cbp_table[mb_xy] = 0xf7ef;
         h->chroma_pred_mode_table[mb_xy] = 0;
         // In deblocking, the quantizer is 0
-        s->current_picture.f.qscale_table[mb_xy] = 0;
+        h->cur_pic.f.qscale_table[mb_xy] = 0;
         // All coeffs are present
         memset(h->non_zero_count[mb_xy], 16, 48);
-        s->current_picture.f.mb_type[mb_xy] = mb_type;
+        h->cur_pic.f.mb_type[mb_xy] = mb_type;
         h->last_qscale_diff = 0;
         return 0;
     }
@@ -2024,7 +2039,7 @@
                     int pred = pred_intra_mode( h, i );
                     h->intra4x4_pred_mode_cache[ scan8[i] ] = decode_cabac_mb_intra4x4_pred_mode( h, pred );
 
-                    av_dlog(s->avctx, "i4x4 pred=%d mode=%d\n", pred,
+                    av_dlog(h->avctx, "i4x4 pred=%d mode=%d\n", pred,
                             h->intra4x4_pred_mode_cache[scan8[i]]);
                 }
             }
@@ -2078,7 +2093,7 @@
                         if (local_ref_count[list] > 1) {
                             ref[list][i] = decode_cabac_mb_ref( h, list, 4*i );
                             if (ref[list][i] >= (unsigned)local_ref_count[list]) {
-                                av_log(s->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref[list][i], local_ref_count[list]);
+                                av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref[list][i], local_ref_count[list]);
                                 return -1;
                             }
                         }else
@@ -2113,7 +2128,7 @@
                         uint8_t (* mvd_cache)[2]= &h->mvd_cache[list][ scan8[index] ];
                         pred_motion(h, index, block_width, list, h->ref_cache[list][ scan8[index] ], &mx, &my);
                         DECODE_CABAC_MB_MVD( h, list, index)
-                        tprintf(s->avctx, "final mv:%d %d\n", mx, my);
+                        tprintf(h->avctx, "final mv:%d %d\n", mx, my);
 
                         if(IS_SUB_8X8(sub_mb_type)){
                             mv_cache[ 1 ][0]=
@@ -2164,7 +2179,7 @@
                     if (local_ref_count[list] > 1) {
                         ref= decode_cabac_mb_ref(h, list, 0);
                         if (ref >= (unsigned)local_ref_count[list]) {
-                            av_log(s->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, local_ref_count[list]);
+                            av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, local_ref_count[list]);
                             return -1;
                         }
                     }else
@@ -2177,7 +2192,7 @@
                     int mx,my,mpx,mpy;
                     pred_motion(h, 0, 4, list, h->ref_cache[list][ scan8[0] ], &mx, &my);
                     DECODE_CABAC_MB_MVD( h, list, 0)
-                    tprintf(s->avctx, "final mv:%d %d\n", mx, my);
+                    tprintf(h->avctx, "final mv:%d %d\n", mx, my);
 
                     fill_rectangle(h->mvd_cache[list][ scan8[0] ], 4, 4, 8, pack8to16(mpx,mpy), 2);
                     fill_rectangle(h->mv_cache[list][ scan8[0] ], 4, 4, 8, pack16to32(mx,my), 4);
@@ -2192,7 +2207,7 @@
                             if (local_ref_count[list] > 1) {
                                 ref= decode_cabac_mb_ref( h, list, 8*i );
                                 if (ref >= (unsigned)local_ref_count[list]) {
-                                    av_log(s->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, local_ref_count[list]);
+                                    av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, local_ref_count[list]);
                                     return -1;
                                 }
                             }else
@@ -2208,7 +2223,7 @@
                         int mx,my,mpx,mpy;
                         pred_16x8_motion(h, 8*i, list, h->ref_cache[list][scan8[0] + 16*i], &mx, &my);
                         DECODE_CABAC_MB_MVD( h, list, 8*i)
-                        tprintf(s->avctx, "final mv:%d %d\n", mx, my);
+                        tprintf(h->avctx, "final mv:%d %d\n", mx, my);
 
                         fill_rectangle(h->mvd_cache[list][ scan8[0] + 16*i ], 4, 2, 8, pack8to16(mpx,mpy), 2);
                         fill_rectangle(h->mv_cache[list][ scan8[0] + 16*i ], 4, 2, 8, pack16to32(mx,my), 4);
@@ -2227,7 +2242,7 @@
                             if (local_ref_count[list] > 1) {
                                 ref= decode_cabac_mb_ref( h, list, 4*i );
                                 if (ref >= (unsigned)local_ref_count[list]) {
-                                    av_log(s->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, local_ref_count[list]);
+                                    av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, local_ref_count[list]);
                                     return -1;
                                 }
                             }else
@@ -2244,7 +2259,7 @@
                         pred_8x16_motion(h, i*4, list, h->ref_cache[list][ scan8[0] + 2*i ], &mx, &my);
                         DECODE_CABAC_MB_MVD( h, list, 4*i)
 
-                        tprintf(s->avctx, "final mv:%d %d\n", mx, my);
+                        tprintf(h->avctx, "final mv:%d %d\n", mx, my);
                         fill_rectangle(h->mvd_cache[list][ scan8[0] + 2*i ], 2, 4, 8, pack8to16(mpx,mpy), 2);
                         fill_rectangle(h->mv_cache[list][ scan8[0] + 2*i ], 2, 4, 8, pack16to32(mx,my), 4);
                     }else{
@@ -2267,7 +2282,7 @@
             cbp |= decode_cabac_mb_cbp_chroma( h ) << 4;
     } else {
         if (!decode_chroma && cbp>15) {
-            av_log(s->avctx, AV_LOG_ERROR, "gray chroma\n");
+            av_log(h->avctx, AV_LOG_ERROR, "gray chroma\n");
             return AVERROR_INVALIDDATA;
         }
     }
@@ -2300,18 +2315,18 @@
             AV_WN32A(&nnz_cache[4+8*10], top_empty);
         }
     }
-    s->current_picture.f.mb_type[mb_xy] = mb_type;
+    h->cur_pic.f.mb_type[mb_xy] = mb_type;
 
     if( cbp || IS_INTRA16x16( mb_type ) ) {
         const uint8_t *scan, *scan8x8;
         const uint32_t *qmul;
 
         if(IS_INTERLACED(mb_type)){
-            scan8x8= s->qscale ? h->field_scan8x8 : h->field_scan8x8_q0;
-            scan= s->qscale ? h->field_scan : h->field_scan_q0;
+            scan8x8= h->qscale ? h->field_scan8x8 : h->field_scan8x8_q0;
+            scan= h->qscale ? h->field_scan : h->field_scan_q0;
         }else{
-            scan8x8= s->qscale ? h->zigzag_scan8x8 : h->zigzag_scan8x8_q0;
-            scan= s->qscale ? h->zigzag_scan : h->zigzag_scan_q0;
+            scan8x8= h->qscale ? h->zigzag_scan8x8 : h->zigzag_scan8x8_q0;
+            scan= h->qscale ? h->zigzag_scan : h->zigzag_scan_q0;
         }
 
         // decode_cabac_mb_dqp
@@ -2324,7 +2339,7 @@
                 ctx= 3;
                 val++;
                 if(val > 2*max_qp){ //prevent infinite loop
-                    av_log(h->s.avctx, AV_LOG_ERROR, "cabac decode of qscale diff failed at %d %d\n", s->mb_x, s->mb_y);
+                    av_log(h->avctx, AV_LOG_ERROR, "cabac decode of qscale diff failed at %d %d\n", h->mb_x, h->mb_y);
                     return -1;
                 }
             }
@@ -2334,13 +2349,13 @@
             else
                 val= -((val + 1)>>1);
             h->last_qscale_diff = val;
-            s->qscale += val;
-            if(((unsigned)s->qscale) > max_qp){
-                if(s->qscale<0) s->qscale+= max_qp+1;
-                else            s->qscale-= max_qp+1;
+            h->qscale += val;
+            if(((unsigned)h->qscale) > max_qp){
+                if(h->qscale<0) h->qscale+= max_qp+1;
+                else            h->qscale-= max_qp+1;
             }
-            h->chroma_qp[0] = get_chroma_qp(h, 0, s->qscale);
-            h->chroma_qp[1] = get_chroma_qp(h, 1, s->qscale);
+            h->chroma_qp[0] = get_chroma_qp(h, 0, h->qscale);
+            h->chroma_qp[1] = get_chroma_qp(h, 1, h->qscale);
         }else
             h->last_qscale_diff=0;
 
@@ -2360,7 +2375,7 @@
             if( cbp&0x20 ) {
                 int c, i, i8x8;
                 for( c = 0; c < 2; c++ ) {
-                    DCTELEM *mb = h->mb + (16*(16 + 16*c) << pixel_shift);
+                    int16_t *mb = h->mb + (16*(16 + 16*c) << pixel_shift);
                     qmul = h->dequant4_coeff[c+1+(IS_INTRA( mb_type ) ? 0:3)][h->chroma_qp[c]];
                     for (i8x8 = 0; i8x8 < 2; i8x8++) {
                         for (i = 0; i < 4; i++) {
@@ -2402,7 +2417,7 @@
         h->last_qscale_diff = 0;
     }
 
-    s->current_picture.f.qscale_table[mb_xy] = s->qscale;
+    h->cur_pic.f.qscale_table[mb_xy] = h->qscale;
     write_back_non_zero_count(h);
 
     return 0;
diff --git a/libavcodec/h264_cavlc.c b/libavcodec/h264_cavlc.c
index 2c75d8c..0701a3c 100644
--- a/libavcodec/h264_cavlc.c
+++ b/libavcodec/h264_cavlc.c
@@ -291,7 +291,7 @@
 
     if(i<64) i= (i+1)>>1;
 
-    tprintf(h->s.avctx, "pred_nnz L%X T%X n%d s%d P%X\n", left, top, n, scan8[n], i&31);
+    tprintf(h->avctx, "pred_nnz L%X T%X n%d s%d P%X\n", left, top, n, scan8[n], i&31);
 
     return i&31;
 }
@@ -441,8 +441,7 @@
  * @param max_coeff number of coefficients in the block
  * @return <0 if an error occurred
  */
-static int decode_residual(H264Context *h, GetBitContext *gb, DCTELEM *block, int n, const uint8_t *scantable, const uint32_t *qmul, int max_coeff){
-    MpegEncContext * const s = &h->s;
+static int decode_residual(H264Context *h, GetBitContext *gb, int16_t *block, int n, const uint8_t *scantable, const uint32_t *qmul, int max_coeff){
     static const int coeff_token_table_index[17]= {0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3};
     int level[16];
     int zeros_left, coeff_token, total_coeff, i, trailing_ones, run_before;
@@ -473,12 +472,12 @@
     if(total_coeff==0)
         return 0;
     if(total_coeff > (unsigned)max_coeff) {
-        av_log(h->s.avctx, AV_LOG_ERROR, "corrupted macroblock %d %d (total_coeff=%d)\n", s->mb_x, s->mb_y, total_coeff);
+        av_log(h->avctx, AV_LOG_ERROR, "corrupted macroblock %d %d (total_coeff=%d)\n", h->mb_x, h->mb_y, total_coeff);
         return -1;
     }
 
     trailing_ones= coeff_token&3;
-    tprintf(h->s.avctx, "trailing:%d, total:%d\n", trailing_ones, total_coeff);
+    tprintf(h->avctx, "trailing:%d, total:%d\n", trailing_ones, total_coeff);
     av_assert2(total_coeff<=16);
 
     i = show_bits(gb, 3);
@@ -514,7 +513,7 @@
                 level_code= 30;
                 if(prefix>=16){
                     if(prefix > 25+3){
-                        av_log(h->s.avctx, AV_LOG_ERROR, "Invalid level prefix\n");
+                        av_log(h->avctx, AV_LOG_ERROR, "Invalid level prefix\n");
                         return -1;
                     }
                     level_code += (1<<(prefix-3))-4096;
@@ -611,7 +610,7 @@
     }
 
     if(zeros_left<0){
-        av_log(h->s.avctx, AV_LOG_ERROR, "negative number of zero coeffs at %d %d\n", s->mb_x, s->mb_y);
+        av_log(h->avctx, AV_LOG_ERROR, "negative number of zero coeffs at %d %d\n", h->mb_x, h->mb_y);
         return -1;
     }
 
@@ -626,8 +625,7 @@
 
 static av_always_inline int decode_luma_residual(H264Context *h, GetBitContext *gb, const uint8_t *scan, const uint8_t *scan8x8, int pixel_shift, int mb_type, int cbp, int p){
     int i4x4, i8x8;
-    MpegEncContext * const s = &h->s;
-    int qscale = p == 0 ? s->qscale : h->chroma_qp[p-1];
+    int qscale = p == 0 ? h->qscale : h->chroma_qp[p-1];
     if(IS_INTRA16x16(mb_type)){
         AV_ZERO128(h->mb_luma_dc[p]+0);
         AV_ZERO128(h->mb_luma_dc[p]+8);
@@ -661,7 +659,7 @@
         for(i8x8=0; i8x8<4; i8x8++){
             if(cbp & (1<<i8x8)){
                 if(IS_8x8DCT(mb_type)){
-                    DCTELEM *buf = &h->mb[64*i8x8+256*p << pixel_shift];
+                    int16_t *buf = &h->mb[64*i8x8+256*p << pixel_shift];
                     uint8_t *nnz;
                     for(i4x4=0; i4x4<4; i4x4++){
                         const int index= i4x4 + 4*i8x8 + p*16;
@@ -692,7 +690,6 @@
 }
 
 int ff_h264_decode_mb_cavlc(H264Context *h){
-    MpegEncContext * const s = &h->s;
     int mb_xy;
     int partition_count;
     unsigned int mb_type, cbp;
@@ -701,32 +698,32 @@
     const int pixel_shift = h->pixel_shift;
     unsigned local_ref_count[2];
 
-    mb_xy = h->mb_xy = s->mb_x + s->mb_y*s->mb_stride;
+    mb_xy = h->mb_xy = h->mb_x + h->mb_y*h->mb_stride;
 
-    tprintf(s->avctx, "pic:%d mb:%d/%d\n", h->frame_num, s->mb_x, s->mb_y);
+    tprintf(h->avctx, "pic:%d mb:%d/%d\n", h->frame_num, h->mb_x, h->mb_y);
     cbp = 0; /* avoid warning. FIXME: find a solution without slowing
                 down the code */
     if(h->slice_type_nos != AV_PICTURE_TYPE_I){
-        if(s->mb_skip_run==-1)
-            s->mb_skip_run= get_ue_golomb(&s->gb);
+        if(h->mb_skip_run==-1)
+            h->mb_skip_run= get_ue_golomb(&h->gb);
 
-        if (s->mb_skip_run--) {
-            if(FRAME_MBAFF && (s->mb_y&1) == 0){
-                if(s->mb_skip_run==0)
-                    h->mb_mbaff = h->mb_field_decoding_flag = get_bits1(&s->gb);
+        if (h->mb_skip_run--) {
+            if(FRAME_MBAFF && (h->mb_y&1) == 0){
+                if(h->mb_skip_run==0)
+                    h->mb_mbaff = h->mb_field_decoding_flag = get_bits1(&h->gb);
             }
             decode_mb_skip(h);
             return 0;
         }
     }
     if(FRAME_MBAFF){
-        if( (s->mb_y&1) == 0 )
-            h->mb_mbaff = h->mb_field_decoding_flag = get_bits1(&s->gb);
+        if( (h->mb_y&1) == 0 )
+            h->mb_mbaff = h->mb_field_decoding_flag = get_bits1(&h->gb);
     }
 
     h->prev_mb_skipped= 0;
 
-    mb_type= get_ue_golomb(&s->gb);
+    mb_type= get_ue_golomb(&h->gb);
     if(h->slice_type_nos == AV_PICTURE_TYPE_B){
         if(mb_type < 23){
             partition_count= b_mb_type_info[mb_type].partition_count;
@@ -749,7 +746,7 @@
             mb_type--;
 decode_intra_mb:
         if(mb_type > 25){
-            av_log(h->s.avctx, AV_LOG_ERROR, "mb_type %d in %c slice too large at %d %d\n", mb_type, av_get_picture_type_char(h->slice_type), s->mb_x, s->mb_y);
+            av_log(h->avctx, AV_LOG_ERROR, "mb_type %d in %c slice too large at %d %d\n", mb_type, av_get_picture_type_char(h->slice_type), h->mb_x, h->mb_y);
             return -1;
         }
         partition_count=0;
@@ -764,24 +761,19 @@
     h->slice_table[ mb_xy ]= h->slice_num;
 
     if(IS_INTRA_PCM(mb_type)){
-        unsigned int x;
         const int mb_size = ff_h264_mb_sizes[h->sps.chroma_format_idc] *
-                            h->sps.bit_depth_luma >> 3;
+                            h->sps.bit_depth_luma;
 
         // We assume these blocks are very rare so we do not optimize it.
-        align_get_bits(&s->gb);
-
-        // The pixels are stored in the same order as levels in h->mb array.
-        for(x=0; x < mb_size; x++){
-            ((uint8_t*)h->mb)[x]= get_bits(&s->gb, 8);
-        }
+        h->intra_pcm_ptr = align_get_bits(&h->gb);
+        skip_bits_long(&h->gb, mb_size);
 
         // In deblocking, the quantizer is 0
-        s->current_picture.f.qscale_table[mb_xy] = 0;
+        h->cur_pic.f.qscale_table[mb_xy] = 0;
         // All coeffs are present
         memset(h->non_zero_count[mb_xy], 16, 48);
 
-        s->current_picture.f.mb_type[mb_xy] = mb_type;
+        h->cur_pic.f.mb_type[mb_xy] = mb_type;
         return 0;
     }
 
@@ -798,7 +790,7 @@
         if(IS_INTRA4x4(mb_type)){
             int i;
             int di = 1;
-            if(dct8x8_allowed && get_bits1(&s->gb)){
+            if(dct8x8_allowed && get_bits1(&h->gb)){
                 mb_type |= MB_TYPE_8x8DCT;
                 di = 4;
             }
@@ -807,8 +799,8 @@
             for(i=0; i<16; i+=di){
                 int mode= pred_intra_mode(h, i);
 
-                if(!get_bits1(&s->gb)){
-                    const int rem_mode= get_bits(&s->gb, 3);
+                if(!get_bits1(&h->gb)){
+                    const int rem_mode= get_bits(&h->gb, 3);
                     mode = rem_mode + (rem_mode >= mode);
                 }
 
@@ -826,7 +818,7 @@
                 return -1;
         }
         if(decode_chroma){
-            pred_mode= ff_h264_check_intra_pred_mode(h, get_ue_golomb_31(&s->gb), 1);
+            pred_mode= ff_h264_check_intra_pred_mode(h, get_ue_golomb_31(&h->gb), 1);
             if(pred_mode < 0)
                 return -1;
             h->chroma_pred_mode= pred_mode;
@@ -838,9 +830,9 @@
 
         if(h->slice_type_nos == AV_PICTURE_TYPE_B){
             for(i=0; i<4; i++){
-                h->sub_mb_type[i]= get_ue_golomb_31(&s->gb);
+                h->sub_mb_type[i]= get_ue_golomb_31(&h->gb);
                 if(h->sub_mb_type[i] >=13){
-                    av_log(h->s.avctx, AV_LOG_ERROR, "B sub_mb_type %u out of range at %d %d\n", h->sub_mb_type[i], s->mb_x, s->mb_y);
+                    av_log(h->avctx, AV_LOG_ERROR, "B sub_mb_type %u out of range at %d %d\n", h->sub_mb_type[i], h->mb_x, h->mb_y);
                     return -1;
                 }
                 sub_partition_count[i]= b_sub_mb_type_info[ h->sub_mb_type[i] ].partition_count;
@@ -856,9 +848,9 @@
         }else{
             av_assert2(h->slice_type_nos == AV_PICTURE_TYPE_P); //FIXME SP correct ?
             for(i=0; i<4; i++){
-                h->sub_mb_type[i]= get_ue_golomb_31(&s->gb);
+                h->sub_mb_type[i]= get_ue_golomb_31(&h->gb);
                 if(h->sub_mb_type[i] >=4){
-                    av_log(h->s.avctx, AV_LOG_ERROR, "P sub_mb_type %u out of range at %d %d\n", h->sub_mb_type[i], s->mb_x, s->mb_y);
+                    av_log(h->avctx, AV_LOG_ERROR, "P sub_mb_type %u out of range at %d %d\n", h->sub_mb_type[i], h->mb_x, h->mb_y);
                     return -1;
                 }
                 sub_partition_count[i]= p_sub_mb_type_info[ h->sub_mb_type[i] ].partition_count;
@@ -875,11 +867,11 @@
                     if(ref_count == 1){
                         tmp= 0;
                     }else if(ref_count == 2){
-                        tmp= get_bits1(&s->gb)^1;
+                        tmp= get_bits1(&h->gb)^1;
                     }else{
-                        tmp= get_ue_golomb_31(&s->gb);
+                        tmp= get_ue_golomb_31(&h->gb);
                         if(tmp>=ref_count){
-                            av_log(h->s.avctx, AV_LOG_ERROR, "ref %u overflow\n", tmp);
+                            av_log(h->avctx, AV_LOG_ERROR, "ref %u overflow\n", tmp);
                             return -1;
                         }
                     }
@@ -911,9 +903,9 @@
                         const int index= 4*i + block_width*j;
                         int16_t (* mv_cache)[2]= &h->mv_cache[list][ scan8[index] ];
                         pred_motion(h, index, block_width, list, h->ref_cache[list][ scan8[index] ], &mx, &my);
-                        mx += get_se_golomb(&s->gb);
-                        my += get_se_golomb(&s->gb);
-                        tprintf(s->avctx, "final mv:%d %d\n", mx, my);
+                        mx += get_se_golomb(&h->gb);
+                        my += get_se_golomb(&h->gb);
+                        tprintf(h->avctx, "final mv:%d %d\n", mx, my);
 
                         if(IS_SUB_8X8(sub_mb_type)){
                             mv_cache[ 1 ][0]=
@@ -950,11 +942,11 @@
                         if(local_ref_count[list]==1){
                             val= 0;
                         }else if(local_ref_count[list]==2){
-                            val= get_bits1(&s->gb)^1;
+                            val= get_bits1(&h->gb)^1;
                         }else{
-                            val= get_ue_golomb_31(&s->gb);
+                            val= get_ue_golomb_31(&h->gb);
                             if(val >= local_ref_count[list]){
-                                av_log(h->s.avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
+                                av_log(h->avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
                                 return -1;
                             }
                         }
@@ -964,9 +956,9 @@
             for(list=0; list<h->list_count; list++){
                 if(IS_DIR(mb_type, 0, list)){
                     pred_motion(h, 0, 4, list, h->ref_cache[list][ scan8[0] ], &mx, &my);
-                    mx += get_se_golomb(&s->gb);
-                    my += get_se_golomb(&s->gb);
-                    tprintf(s->avctx, "final mv:%d %d\n", mx, my);
+                    mx += get_se_golomb(&h->gb);
+                    my += get_se_golomb(&h->gb);
+                    tprintf(h->avctx, "final mv:%d %d\n", mx, my);
 
                     fill_rectangle(h->mv_cache[list][ scan8[0] ], 4, 4, 8, pack16to32(mx,my), 4);
                 }
@@ -980,11 +972,11 @@
                             if(local_ref_count[list] == 1){
                                 val= 0;
                             }else if(local_ref_count[list] == 2){
-                                val= get_bits1(&s->gb)^1;
+                                val= get_bits1(&h->gb)^1;
                             }else{
-                                val= get_ue_golomb_31(&s->gb);
+                                val= get_ue_golomb_31(&h->gb);
                                 if(val >= local_ref_count[list]){
-                                    av_log(h->s.avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
+                                    av_log(h->avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
                                     return -1;
                                 }
                             }
@@ -998,9 +990,9 @@
                     unsigned int val;
                     if(IS_DIR(mb_type, i, list)){
                         pred_16x8_motion(h, 8*i, list, h->ref_cache[list][scan8[0] + 16*i], &mx, &my);
-                        mx += get_se_golomb(&s->gb);
-                        my += get_se_golomb(&s->gb);
-                        tprintf(s->avctx, "final mv:%d %d\n", mx, my);
+                        mx += get_se_golomb(&h->gb);
+                        my += get_se_golomb(&h->gb);
+                        tprintf(h->avctx, "final mv:%d %d\n", mx, my);
 
                         val= pack16to32(mx,my);
                     }else
@@ -1017,11 +1009,11 @@
                             if(local_ref_count[list]==1){
                                 val= 0;
                             }else if(local_ref_count[list]==2){
-                                val= get_bits1(&s->gb)^1;
+                                val= get_bits1(&h->gb)^1;
                             }else{
-                                val= get_ue_golomb_31(&s->gb);
+                                val= get_ue_golomb_31(&h->gb);
                                 if(val >= local_ref_count[list]){
-                                    av_log(h->s.avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
+                                    av_log(h->avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
                                     return -1;
                                 }
                             }
@@ -1035,9 +1027,9 @@
                     unsigned int val;
                     if(IS_DIR(mb_type, i, list)){
                         pred_8x16_motion(h, i*4, list, h->ref_cache[list][ scan8[0] + 2*i ], &mx, &my);
-                        mx += get_se_golomb(&s->gb);
-                        my += get_se_golomb(&s->gb);
-                        tprintf(s->avctx, "final mv:%d %d\n", mx, my);
+                        mx += get_se_golomb(&h->gb);
+                        my += get_se_golomb(&h->gb);
+                        tprintf(h->avctx, "final mv:%d %d\n", mx, my);
 
                         val= pack16to32(mx,my);
                     }else
@@ -1052,18 +1044,18 @@
         write_back_motion(h, mb_type);
 
     if(!IS_INTRA16x16(mb_type)){
-        cbp= get_ue_golomb(&s->gb);
+        cbp= get_ue_golomb(&h->gb);
 
         if(decode_chroma){
             if(cbp > 47){
-                av_log(h->s.avctx, AV_LOG_ERROR, "cbp too large (%u) at %d %d\n", cbp, s->mb_x, s->mb_y);
+                av_log(h->avctx, AV_LOG_ERROR, "cbp too large (%u) at %d %d\n", cbp, h->mb_x, h->mb_y);
                 return -1;
             }
             if(IS_INTRA4x4(mb_type)) cbp= golomb_to_intra4x4_cbp[cbp];
             else                     cbp= golomb_to_inter_cbp   [cbp];
         }else{
             if(cbp > 15){
-                av_log(h->s.avctx, AV_LOG_ERROR, "cbp too large (%u) at %d %d\n", cbp, s->mb_x, s->mb_y);
+                av_log(h->avctx, AV_LOG_ERROR, "cbp too large (%u) at %d %d\n", cbp, h->mb_x, h->mb_y);
                 return -1;
             }
             if(IS_INTRA4x4(mb_type)) cbp= golomb_to_intra4x4_cbp_gray[cbp];
@@ -1071,17 +1063,17 @@
         }
     } else {
         if (!decode_chroma && cbp>15) {
-            av_log(s->avctx, AV_LOG_ERROR, "gray chroma\n");
+            av_log(h->avctx, AV_LOG_ERROR, "gray chroma\n");
             return AVERROR_INVALIDDATA;
         }
     }
 
     if(dct8x8_allowed && (cbp&15) && !IS_INTRA(mb_type)){
-        mb_type |= MB_TYPE_8x8DCT*get_bits1(&s->gb);
+        mb_type |= MB_TYPE_8x8DCT*get_bits1(&h->gb);
     }
     h->cbp=
     h->cbp_table[mb_xy]= cbp;
-    s->current_picture.f.mb_type[mb_xy] = mb_type;
+    h->cur_pic.f.mb_type[mb_xy] = mb_type;
 
     if(cbp || IS_INTRA16x16(mb_type)){
         int i4x4, i8x8, chroma_idx;
@@ -1092,28 +1084,28 @@
         const int max_qp = 51 + 6*(h->sps.bit_depth_luma-8);
 
         if(IS_INTERLACED(mb_type)){
-            scan8x8= s->qscale ? h->field_scan8x8_cavlc : h->field_scan8x8_cavlc_q0;
-            scan= s->qscale ? h->field_scan : h->field_scan_q0;
+            scan8x8= h->qscale ? h->field_scan8x8_cavlc : h->field_scan8x8_cavlc_q0;
+            scan= h->qscale ? h->field_scan : h->field_scan_q0;
         }else{
-            scan8x8= s->qscale ? h->zigzag_scan8x8_cavlc : h->zigzag_scan8x8_cavlc_q0;
-            scan= s->qscale ? h->zigzag_scan : h->zigzag_scan_q0;
+            scan8x8= h->qscale ? h->zigzag_scan8x8_cavlc : h->zigzag_scan8x8_cavlc_q0;
+            scan= h->qscale ? h->zigzag_scan : h->zigzag_scan_q0;
         }
 
-        dquant= get_se_golomb(&s->gb);
+        dquant= get_se_golomb(&h->gb);
 
-        s->qscale += dquant;
+        h->qscale += dquant;
 
-        if(((unsigned)s->qscale) > max_qp){
-            if(s->qscale<0) s->qscale+= max_qp+1;
-            else            s->qscale-= max_qp+1;
-            if(((unsigned)s->qscale) > max_qp){
-                av_log(h->s.avctx, AV_LOG_ERROR, "dquant out of range (%d) at %d %d\n", dquant, s->mb_x, s->mb_y);
+        if(((unsigned)h->qscale) > max_qp){
+            if(h->qscale<0) h->qscale+= max_qp+1;
+            else            h->qscale-= max_qp+1;
+            if(((unsigned)h->qscale) > max_qp){
+                av_log(h->avctx, AV_LOG_ERROR, "dquant out of range (%d) at %d %d\n", dquant, h->mb_x, h->mb_y);
                 return -1;
             }
         }
 
-        h->chroma_qp[0]= get_chroma_qp(h, 0, s->qscale);
-        h->chroma_qp[1]= get_chroma_qp(h, 1, s->qscale);
+        h->chroma_qp[0]= get_chroma_qp(h, 0, h->qscale);
+        h->chroma_qp[1]= get_chroma_qp(h, 1, h->qscale);
 
         if( (ret = decode_luma_residual(h, gb, scan, scan8x8, pixel_shift, mb_type, cbp, 0)) < 0 ){
             return -1;
@@ -1142,7 +1134,7 @@
             if(cbp&0x20){
                 for(chroma_idx=0; chroma_idx<2; chroma_idx++){
                     const uint32_t *qmul = h->dequant4_coeff[chroma_idx+1+(IS_INTRA( mb_type ) ? 0:3)][h->chroma_qp[chroma_idx]];
-                    DCTELEM *mb = h->mb + (16*(16 + 16*chroma_idx) << pixel_shift);
+                    int16_t *mb = h->mb + (16*(16 + 16*chroma_idx) << pixel_shift);
                     for (i8x8=0; i8x8<num_c8x8; i8x8++) {
                         for (i4x4=0; i4x4<4; i4x4++) {
                             const int index= 16 + 16*chroma_idx + 8*i8x8 + i4x4;
@@ -1162,7 +1154,7 @@
         fill_rectangle(&h->non_zero_count_cache[scan8[16]], 4, 4, 8, 0, 1);
         fill_rectangle(&h->non_zero_count_cache[scan8[32]], 4, 4, 8, 0, 1);
     }
-    s->current_picture.f.qscale_table[mb_xy] = s->qscale;
+    h->cur_pic.f.qscale_table[mb_xy] = h->qscale;
     write_back_non_zero_count(h);
 
     return 0;
diff --git a/libavcodec/h264_direct.c b/libavcodec/h264_direct.c
index 9ef5862..c6be455 100644
--- a/libavcodec/h264_direct.c
+++ b/libavcodec/h264_direct.c
@@ -26,7 +26,6 @@
  */
 
 #include "internal.h"
-#include "dsputil.h"
 #include "avcodec.h"
 #include "mpegvideo.h"
 #include "h264.h"
@@ -50,29 +49,30 @@
 }
 
 void ff_h264_direct_dist_scale_factor(H264Context * const h){
-    MpegEncContext * const s = &h->s;
-    const int poc = h->s.current_picture_ptr->field_poc[ s->picture_structure == PICT_BOTTOM_FIELD ];
+    const int poc = h->cur_pic_ptr->field_poc[h->picture_structure == PICT_BOTTOM_FIELD];
     const int poc1 = h->ref_list[1][0].poc;
     int i, field;
-    for(field=0; field<2; field++){
-        const int poc  = h->s.current_picture_ptr->field_poc[field];
-        const int poc1 = h->ref_list[1][0].field_poc[field];
-        for(i=0; i < 2*h->ref_count[0]; i++)
-            h->dist_scale_factor_field[field][i^field] = get_scale_factor(h, poc, poc1, i+16);
-    }
 
-    for(i=0; i<h->ref_count[0]; i++){
+    if (FRAME_MBAFF)
+        for (field = 0; field < 2; field++){
+            const int poc  = h->cur_pic_ptr->field_poc[field];
+            const int poc1 = h->ref_list[1][0].field_poc[field];
+            for (i = 0; i < 2 * h->ref_count[0]; i++)
+                h->dist_scale_factor_field[field][i^field] =
+                    get_scale_factor(h, poc, poc1, i+16);
+        }
+
+    for (i = 0; i < h->ref_count[0]; i++){
         h->dist_scale_factor[i] = get_scale_factor(h, poc, poc1, i);
     }
 }
 
 static void fill_colmap(H264Context *h, int map[2][16+32], int list, int field, int colfield, int mbafi){
-    MpegEncContext * const s = &h->s;
     Picture * const ref1 = &h->ref_list[1][0];
     int j, old_ref, rfield;
     int start= mbafi ? 16                      : 0;
     int end  = mbafi ? 16+2*h->ref_count[0]    : h->ref_count[0];
-    int interl= mbafi || s->picture_structure != PICT_FRAME;
+    int interl= mbafi || h->picture_structure != PICT_FRAME;
 
     /* bogus; fills in for missing frames */
     memset(map[list], 0, sizeof(map[list]));
@@ -83,14 +83,14 @@
 
             if     (!interl)
                 poc |= 3;
-            else if( interl && (poc&3) == 3) //FIXME store all MBAFF references so this isnt needed
+            else if( interl && (poc&3) == 3) // FIXME: store all MBAFF references so this is not needed
                 poc= (poc&~3) + rfield + 1;
 
             for(j=start; j<end; j++){
                 if (4 * h->ref_list[0][j].frame_num + (h->ref_list[0][j].f.reference & 3) == poc) {
                     int cur_ref= mbafi ? (j-16)^field : j;
-                    if(ref1->mbaff)
-                        map[list][2*old_ref + (rfield^field) + 16] = cur_ref;
+                    if (ref1->mbaff)
+                        map[list][2 * old_ref + (rfield^field) + 16] = cur_ref;
                     if(rfield == field || !interl)
                         map[list][old_ref] = cur_ref;
                     break;
@@ -101,11 +101,10 @@
 }
 
 void ff_h264_direct_ref_list_init(H264Context * const h){
-    MpegEncContext * const s = &h->s;
     Picture * const ref1 = &h->ref_list[1][0];
-    Picture * const cur = s->current_picture_ptr;
+    Picture * const cur = h->cur_pic_ptr;
     int list, j, field;
-    int sidx= (s->picture_structure&1)^1;
+    int sidx= (h->picture_structure&1)^1;
     int ref1sidx = (ref1->f.reference&1)^1;
 
     for(list=0; list<2; list++){
@@ -114,7 +113,7 @@
             cur->ref_poc[sidx][list][j] = 4 * h->ref_list[list][j].frame_num + (h->ref_list[list][j].f.reference & 3);
     }
 
-    if(s->picture_structure == PICT_FRAME){
+    if(h->picture_structure == PICT_FRAME){
         memcpy(cur->ref_count[1], cur->ref_count[0], sizeof(cur->ref_count[0]));
         memcpy(cur->ref_poc  [1], cur->ref_poc  [0], sizeof(cur->ref_poc  [0]));
     }
@@ -122,12 +121,12 @@
     cur->mbaff= FRAME_MBAFF;
 
     h->col_fieldoff= 0;
-    if(s->picture_structure == PICT_FRAME){
-        int cur_poc = s->current_picture_ptr->poc;
+    if(h->picture_structure == PICT_FRAME){
+        int cur_poc = h->cur_pic_ptr->poc;
         int *col_poc = h->ref_list[1]->field_poc;
         h->col_parity= (FFABS(col_poc[0] - cur_poc) >= FFABS(col_poc[1] - cur_poc));
         ref1sidx=sidx= h->col_parity;
-    } else if (!(s->picture_structure & h->ref_list[1][0].f.reference) && !h->ref_list[1][0].mbaff) { // FL -> FL & differ parity
+    } else if (!(h->picture_structure & h->ref_list[1][0].f.reference) && !h->ref_list[1][0].mbaff) { // FL -> FL & differ parity
         h->col_fieldoff = 2 * h->ref_list[1][0].f.reference - 3;
     }
 
@@ -146,9 +145,9 @@
 {
     int ref_field = ref->f.reference - 1;
     int ref_field_picture = ref->field_picture;
-    int ref_height = 16*h->s.mb_height >> ref_field_picture;
+    int ref_height = 16*h->mb_height >> ref_field_picture;
 
-    if(!HAVE_THREADS || !(h->s.avctx->active_thread_type&FF_THREAD_FRAME))
+    if(!HAVE_THREADS || !(h->avctx->active_thread_type&FF_THREAD_FRAME))
         return;
 
     //FIXME it can be safe to access mb stuff
@@ -160,10 +159,9 @@
 }
 
 static void pred_spatial_direct_motion(H264Context * const h, int *mb_type){
-    MpegEncContext * const s = &h->s;
     int b8_stride = 2;
     int b4_stride = h->b_stride;
-    int mb_xy = h->mb_xy, mb_y = s->mb_y;
+    int mb_xy = h->mb_xy, mb_y = h->mb_y;
     int mb_type_col[2];
     const int16_t (*l1mv0)[2], (*l1mv1)[2];
     const int8_t *l1ref0, *l1ref1;
@@ -176,7 +174,7 @@
 
     assert(h->ref_list[1][0].f.reference & 3);
 
-    await_reference_mb_row(h, &h->ref_list[1][0], s->mb_y + !!IS_INTERLACED(*mb_type));
+    await_reference_mb_row(h, &h->ref_list[1][0], h->mb_y + !!IS_INTERLACED(*mb_type));
 
 #define MB_TYPE_16x16_OR_INTRA (MB_TYPE_16x16|MB_TYPE_INTRA4x4|MB_TYPE_INTRA16x16|MB_TYPE_INTRA_PCM)
 
@@ -238,21 +236,21 @@
 
     if (IS_INTERLACED(h->ref_list[1][0].f.mb_type[mb_xy])) { // AFL/AFR/FR/FL -> AFL/FL
         if (!IS_INTERLACED(*mb_type)) {                          //     AFR/FR    -> AFL/FL
-            mb_y = (s->mb_y&~1) + h->col_parity;
-            mb_xy= s->mb_x + ((s->mb_y&~1) + h->col_parity)*s->mb_stride;
+            mb_y = (h->mb_y&~1) + h->col_parity;
+            mb_xy= h->mb_x + ((h->mb_y&~1) + h->col_parity)*h->mb_stride;
             b8_stride = 0;
         }else{
             mb_y  += h->col_fieldoff;
-            mb_xy += s->mb_stride*h->col_fieldoff; // non zero for FL -> FL & differ parity
+            mb_xy += h->mb_stride*h->col_fieldoff; // non zero for FL -> FL & differ parity
         }
         goto single_col;
     }else{                                               // AFL/AFR/FR/FL -> AFR/FR
         if(IS_INTERLACED(*mb_type)){                     // AFL       /FL -> AFR/FR
-            mb_y = s->mb_y&~1;
-            mb_xy= s->mb_x + (s->mb_y&~1)*s->mb_stride;
+            mb_y = h->mb_y&~1;
+            mb_xy= h->mb_x + (h->mb_y&~1)*h->mb_stride;
             mb_type_col[0] = h->ref_list[1][0].f.mb_type[mb_xy];
-            mb_type_col[1] = h->ref_list[1][0].f.mb_type[mb_xy + s->mb_stride];
-            b8_stride = 2+4*s->mb_stride;
+            mb_type_col[1] = h->ref_list[1][0].f.mb_type[mb_xy + h->mb_stride];
+            b8_stride = 2+4*h->mb_stride;
             b4_stride *= 6;
             if (IS_INTERLACED(mb_type_col[0]) != IS_INTERLACED(mb_type_col[1])) {
                 mb_type_col[0] &= ~MB_TYPE_INTERLACED;
@@ -290,12 +288,12 @@
 
     await_reference_mb_row(h, &h->ref_list[1][0], mb_y);
 
-    l1mv0  = &h->ref_list[1][0].f.motion_val[0][h->mb2b_xy [mb_xy]];
-    l1mv1  = &h->ref_list[1][0].f.motion_val[1][h->mb2b_xy [mb_xy]];
+    l1mv0  = (void*)&h->ref_list[1][0].f.motion_val[0][h->mb2b_xy [mb_xy]];
+    l1mv1  = (void*)&h->ref_list[1][0].f.motion_val[1][h->mb2b_xy [mb_xy]];
     l1ref0 = &h->ref_list[1][0].f.ref_index [0][4 * mb_xy];
     l1ref1 = &h->ref_list[1][0].f.ref_index [1][4 * mb_xy];
     if(!b8_stride){
-        if(s->mb_y&1){
+        if(h->mb_y&1){
             l1ref0 += 2;
             l1ref1 += 2;
             l1mv0  +=  2*b4_stride;
@@ -411,10 +409,9 @@
 }
 
 static void pred_temp_direct_motion(H264Context * const h, int *mb_type){
-    MpegEncContext * const s = &h->s;
     int b8_stride = 2;
     int b4_stride = h->b_stride;
-    int mb_xy = h->mb_xy, mb_y = s->mb_y;
+    int mb_xy = h->mb_xy, mb_y = h->mb_y;
     int mb_type_col[2];
     const int16_t (*l1mv0)[2], (*l1mv1)[2];
     const int8_t *l1ref0, *l1ref1;
@@ -424,25 +421,25 @@
 
     assert(h->ref_list[1][0].f.reference & 3);
 
-    await_reference_mb_row(h, &h->ref_list[1][0], s->mb_y + !!IS_INTERLACED(*mb_type));
+    await_reference_mb_row(h, &h->ref_list[1][0], h->mb_y + !!IS_INTERLACED(*mb_type));
 
     if (IS_INTERLACED(h->ref_list[1][0].f.mb_type[mb_xy])) { // AFL/AFR/FR/FL -> AFL/FL
         if (!IS_INTERLACED(*mb_type)) {                          //     AFR/FR    -> AFL/FL
-            mb_y = (s->mb_y&~1) + h->col_parity;
-            mb_xy= s->mb_x + ((s->mb_y&~1) + h->col_parity)*s->mb_stride;
+            mb_y = (h->mb_y&~1) + h->col_parity;
+            mb_xy= h->mb_x + ((h->mb_y&~1) + h->col_parity)*h->mb_stride;
             b8_stride = 0;
         }else{
             mb_y  += h->col_fieldoff;
-            mb_xy += s->mb_stride*h->col_fieldoff; // non zero for FL -> FL & differ parity
+            mb_xy += h->mb_stride*h->col_fieldoff; // non zero for FL -> FL & differ parity
         }
         goto single_col;
     }else{                                               // AFL/AFR/FR/FL -> AFR/FR
         if(IS_INTERLACED(*mb_type)){                     // AFL       /FL -> AFR/FR
-            mb_y = s->mb_y&~1;
-            mb_xy= s->mb_x + (s->mb_y&~1)*s->mb_stride;
+            mb_y = h->mb_y&~1;
+            mb_xy= h->mb_x + (h->mb_y&~1)*h->mb_stride;
             mb_type_col[0] = h->ref_list[1][0].f.mb_type[mb_xy];
-            mb_type_col[1] = h->ref_list[1][0].f.mb_type[mb_xy + s->mb_stride];
-            b8_stride = 2+4*s->mb_stride;
+            mb_type_col[1] = h->ref_list[1][0].f.mb_type[mb_xy + h->mb_stride];
+            b8_stride = 2+4*h->mb_stride;
             b4_stride *= 6;
             if (IS_INTERLACED(mb_type_col[0]) != IS_INTERLACED(mb_type_col[1])) {
                 mb_type_col[0] &= ~MB_TYPE_INTERLACED;
@@ -481,12 +478,12 @@
 
     await_reference_mb_row(h, &h->ref_list[1][0], mb_y);
 
-    l1mv0  = &h->ref_list[1][0].f.motion_val[0][h->mb2b_xy [mb_xy]];
-    l1mv1  = &h->ref_list[1][0].f.motion_val[1][h->mb2b_xy [mb_xy]];
+    l1mv0  = (void*)&h->ref_list[1][0].f.motion_val[0][h->mb2b_xy [mb_xy]];
+    l1mv1  = (void*)&h->ref_list[1][0].f.motion_val[1][h->mb2b_xy [mb_xy]];
     l1ref0 = &h->ref_list[1][0].f.ref_index [0][4 * mb_xy];
     l1ref1 = &h->ref_list[1][0].f.ref_index [1][4 * mb_xy];
     if(!b8_stride){
-        if(s->mb_y&1){
+        if(h->mb_y&1){
             l1ref0 += 2;
             l1ref1 += 2;
             l1mv0  +=  2*b4_stride;
@@ -500,9 +497,9 @@
         int ref_offset;
 
         if(FRAME_MBAFF && IS_INTERLACED(*mb_type)){
-            map_col_to_list0[0] = h->map_col_to_list0_field[s->mb_y&1][0];
-            map_col_to_list0[1] = h->map_col_to_list0_field[s->mb_y&1][1];
-            dist_scale_factor   =h->dist_scale_factor_field[s->mb_y&1];
+            map_col_to_list0[0] = h->map_col_to_list0_field[h->mb_y&1][0];
+            map_col_to_list0[1] = h->map_col_to_list0_field[h->mb_y&1][1];
+            dist_scale_factor   =h->dist_scale_factor_field[h->mb_y&1];
         }
         ref_offset = (h->ref_list[1][0].mbaff<<4) & (mb_type_col[0]>>3); //if(h->ref_list[1][0].mbaff && IS_INTERLACED(mb_type_col[0])) ref_offset=16 else 0
 
diff --git a/libavcodec/h264_loopfilter.c b/libavcodec/h264_loopfilter.c
index 7cd9f69..13d99f2 100644
--- a/libavcodec/h264_loopfilter.c
+++ b/libavcodec/h264_loopfilter.c
@@ -25,9 +25,9 @@
  * @author Michael Niedermayer <michaelni@gmx.at>
  */
 
+#include "libavutil/internal.h"
 #include "libavutil/intreadwrite.h"
 #include "internal.h"
-#include "dsputil.h"
 #include "avcodec.h"
 #include "mpegvideo.h"
 #include "h264.h"
@@ -241,8 +241,7 @@
                                                           unsigned int uvlinesize,
                                                           int pixel_shift)
 {
-    MpegEncContext * const s = &h->s;
-    int chroma = CHROMA && !(CONFIG_GRAY && (s->flags&CODEC_FLAG_GRAY));
+    int chroma = CHROMA && !(CONFIG_GRAY && (h->flags&CODEC_FLAG_GRAY));
     int chroma444 = CHROMA444;
     int chroma422 = CHROMA422;
 
@@ -254,10 +253,10 @@
     int a = h->slice_alpha_c0_offset - qp_bd_offset;
     int b = h->slice_beta_offset - qp_bd_offset;
 
-    int mb_type = s->current_picture.f.mb_type[mb_xy];
-    int qp      = s->current_picture.f.qscale_table[mb_xy];
-    int qp0     = s->current_picture.f.qscale_table[mb_xy - 1];
-    int qp1     = s->current_picture.f.qscale_table[h->top_mb_xy];
+    int mb_type = h->cur_pic.f.mb_type[mb_xy];
+    int qp      = h->cur_pic.f.qscale_table[mb_xy];
+    int qp0     = h->cur_pic.f.qscale_table[mb_xy - 1];
+    int qp1     = h->cur_pic.f.qscale_table[h->top_mb_xy];
     int qpc = get_chroma_qp( h, 0, qp );
     int qpc0 = get_chroma_qp( h, 0, qp0 );
     int qpc1 = get_chroma_qp( h, 0, qp1 );
@@ -462,7 +461,6 @@
 }
 
 static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr, unsigned int linesize, unsigned int uvlinesize, int mb_xy, int mb_type, int mvy_limit, int first_vertical_edge_done, int a, int b, int chroma, int dir) {
-    MpegEncContext * const s = &h->s;
     int edge;
     int chroma_qp_avg[2];
     int chroma444 = CHROMA444;
@@ -490,16 +488,16 @@
             //
             unsigned int tmp_linesize   = 2 *   linesize;
             unsigned int tmp_uvlinesize = 2 * uvlinesize;
-            int mbn_xy = mb_xy - 2 * s->mb_stride;
+            int mbn_xy = mb_xy - 2 * h->mb_stride;
             int j;
 
-            for(j=0; j<2; j++, mbn_xy += s->mb_stride){
+            for(j=0; j<2; j++, mbn_xy += h->mb_stride){
                 DECLARE_ALIGNED(8, int16_t, bS)[4];
                 int qp;
-                if (IS_INTRA(mb_type | s->current_picture.f.mb_type[mbn_xy])) {
+                if (IS_INTRA(mb_type | h->cur_pic.f.mb_type[mbn_xy])) {
                     AV_WN64A(bS, 0x0003000300030003ULL);
                 } else {
-                    if (!CABAC && IS_8x8DCT(s->current_picture.f.mb_type[mbn_xy])) {
+                    if (!CABAC && IS_8x8DCT(h->cur_pic.f.mb_type[mbn_xy])) {
                         bS[0]= 1+((h->cbp_table[mbn_xy] & 0x4000)||h->non_zero_count_cache[scan8[0]+0]);
                         bS[1]= 1+((h->cbp_table[mbn_xy] & 0x4000)||h->non_zero_count_cache[scan8[0]+1]);
                         bS[2]= 1+((h->cbp_table[mbn_xy] & 0x8000)||h->non_zero_count_cache[scan8[0]+2]);
@@ -514,12 +512,12 @@
                 }
                 // Do not use s->qscale as luma quantizer because it has not the same
                 // value in IPCM macroblocks.
-                qp = (s->current_picture.f.qscale_table[mb_xy] + s->current_picture.f.qscale_table[mbn_xy] + 1) >> 1;
-                tprintf(s->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, tmp_linesize, tmp_uvlinesize);
-                { int i; for (i = 0; i < 4; i++) tprintf(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "\n"); }
+                qp = (h->cur_pic.f.qscale_table[mb_xy] + h->cur_pic.f.qscale_table[mbn_xy] + 1) >> 1;
+                tprintf(h->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, tmp_linesize, tmp_uvlinesize);
+                { int i; for (i = 0; i < 4; i++) tprintf(h->avctx, " bS[%d]:%d", i, bS[i]); tprintf(h->avctx, "\n"); }
                 filter_mb_edgeh( &img_y[j*linesize], tmp_linesize, bS, qp, a, b, h, 0 );
-                chroma_qp_avg[0] = (h->chroma_qp[0] + get_chroma_qp(h, 0, s->current_picture.f.qscale_table[mbn_xy]) + 1) >> 1;
-                chroma_qp_avg[1] = (h->chroma_qp[1] + get_chroma_qp(h, 1, s->current_picture.f.qscale_table[mbn_xy]) + 1) >> 1;
+                chroma_qp_avg[0] = (h->chroma_qp[0] + get_chroma_qp(h, 0, h->cur_pic.f.qscale_table[mbn_xy]) + 1) >> 1;
+                chroma_qp_avg[1] = (h->chroma_qp[1] + get_chroma_qp(h, 1, h->cur_pic.f.qscale_table[mbn_xy]) + 1) >> 1;
                 if (chroma) {
                     if (chroma444) {
                         filter_mb_edgeh (&img_cb[j*uvlinesize], tmp_uvlinesize, bS, chroma_qp_avg[0], a, b, h, 0);
@@ -537,7 +535,7 @@
             if( IS_INTRA(mb_type|mbm_type)) {
                 AV_WN64A(bS, 0x0003000300030003ULL);
                 if (   (!IS_INTERLACED(mb_type|mbm_type))
-                    || ((FRAME_MBAFF || (s->picture_structure != PICT_FRAME)) && (dir == 0))
+                    || ((FRAME_MBAFF || (h->picture_structure != PICT_FRAME)) && (dir == 0))
                 )
                     AV_WN64A(bS, 0x0004000400040004ULL);
             } else {
@@ -579,12 +577,12 @@
             // Do not use s->qscale as luma quantizer because it has not the same
             // value in IPCM macroblocks.
             if(bS[0]+bS[1]+bS[2]+bS[3]){
-                qp = (s->current_picture.f.qscale_table[mb_xy] + s->current_picture.f.qscale_table[mbm_xy] + 1) >> 1;
-                //tprintf(s->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d, QPc:%d, QPcn:%d\n", mb_x, mb_y, dir, edge, qp, h->chroma_qp[0], s->current_picture.qscale_table[mbn_xy]);
-                tprintf(s->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, linesize, uvlinesize);
-                //{ int i; for (i = 0; i < 4; i++) tprintf(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "\n"); }
-                chroma_qp_avg[0] = (h->chroma_qp[0] + get_chroma_qp(h, 0, s->current_picture.f.qscale_table[mbm_xy]) + 1) >> 1;
-                chroma_qp_avg[1] = (h->chroma_qp[1] + get_chroma_qp(h, 1, s->current_picture.f.qscale_table[mbm_xy]) + 1) >> 1;
+                qp = (h->cur_pic.f.qscale_table[mb_xy] + h->cur_pic.f.qscale_table[mbm_xy] + 1) >> 1;
+                //tprintf(h->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d, QPc:%d, QPcn:%d\n", mb_x, mb_y, dir, edge, qp, h->chroma_qp[0], h->cur_pic.qscale_table[mbn_xy]);
+                tprintf(h->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, linesize, uvlinesize);
+                //{ int i; for (i = 0; i < 4; i++) tprintf(h->avctx, " bS[%d]:%d", i, bS[i]); tprintf(h->avctx, "\n"); }
+                chroma_qp_avg[0] = (h->chroma_qp[0] + get_chroma_qp(h, 0, h->cur_pic.f.qscale_table[mbm_xy]) + 1) >> 1;
+                chroma_qp_avg[1] = (h->chroma_qp[1] + get_chroma_qp(h, 1, h->cur_pic.f.qscale_table[mbm_xy]) + 1) >> 1;
                 if( dir == 0 ) {
                     filter_mb_edgev( &img_y[0], linesize, bS, qp, a, b, h, 1 );
                     if (chroma) {
@@ -664,10 +662,10 @@
         /* Filter edge */
         // Do not use s->qscale as luma quantizer because it has not the same
         // value in IPCM macroblocks.
-        qp = s->current_picture.f.qscale_table[mb_xy];
-        //tprintf(s->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d, QPc:%d, QPcn:%d\n", mb_x, mb_y, dir, edge, qp, h->chroma_qp[0], s->current_picture.qscale_table[mbn_xy]);
-        tprintf(s->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, linesize, uvlinesize);
-        //{ int i; for (i = 0; i < 4; i++) tprintf(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "\n"); }
+        qp = h->cur_pic.f.qscale_table[mb_xy];
+        //tprintf(h->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d, QPc:%d, QPcn:%d\n", mb_x, mb_y, dir, edge, qp, h->chroma_qp[0], h->cur_pic.qscale_table[mbn_xy]);
+        tprintf(h->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, linesize, uvlinesize);
+        //{ int i; for (i = 0; i < 4; i++) tprintf(h->avctx, " bS[%d]:%d", i, bS[i]); tprintf(h->avctx, "\n"); }
         if( dir == 0 ) {
             filter_mb_edgev( &img_y[4*edge << h->pixel_shift], linesize, bS, qp, a, b, h, 0 );
             if (chroma) {
@@ -704,13 +702,12 @@
 }
 
 void ff_h264_filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr, unsigned int linesize, unsigned int uvlinesize) {
-    MpegEncContext * const s = &h->s;
-    const int mb_xy= mb_x + mb_y*s->mb_stride;
-    const int mb_type = s->current_picture.f.mb_type[mb_xy];
+    const int mb_xy= mb_x + mb_y*h->mb_stride;
+    const int mb_type = h->cur_pic.f.mb_type[mb_xy];
     const int mvy_limit = IS_INTERLACED(mb_type) ? 2 : 4;
     int first_vertical_edge_done = 0;
     av_unused int dir;
-    int chroma = CHROMA && !(CONFIG_GRAY && (s->flags&CODEC_FLAG_GRAY));
+    int chroma = CHROMA && !(CONFIG_GRAY && (h->flags&CODEC_FLAG_GRAY));
     int qp_bd_offset = 6 * (h->sps.bit_depth_luma - 8);
     int a = h->slice_alpha_c0_offset - qp_bd_offset;
     int b = h->slice_beta_offset - qp_bd_offset;
@@ -762,9 +759,9 @@
             }
         }
 
-        mb_qp   = s->current_picture.f.qscale_table[mb_xy];
-        mbn0_qp = s->current_picture.f.qscale_table[h->left_mb_xy[0]];
-        mbn1_qp = s->current_picture.f.qscale_table[h->left_mb_xy[1]];
+        mb_qp   = h->cur_pic.f.qscale_table[mb_xy];
+        mbn0_qp = h->cur_pic.f.qscale_table[h->left_mb_xy[0]];
+        mbn1_qp = h->cur_pic.f.qscale_table[h->left_mb_xy[1]];
         qp[0] = ( mb_qp + mbn0_qp + 1 ) >> 1;
         bqp[0] = ( get_chroma_qp( h, 0, mb_qp ) +
                    get_chroma_qp( h, 0, mbn0_qp ) + 1 ) >> 1;
@@ -777,8 +774,8 @@
                    get_chroma_qp( h, 1, mbn1_qp ) + 1 ) >> 1;
 
         /* Filter edge */
-        tprintf(s->avctx, "filter mb:%d/%d MBAFF, QPy:%d/%d, QPb:%d/%d QPr:%d/%d ls:%d uvls:%d", mb_x, mb_y, qp[0], qp[1], bqp[0], bqp[1], rqp[0], rqp[1], linesize, uvlinesize);
-        { int i; for (i = 0; i < 8; i++) tprintf(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "\n"); }
+        tprintf(h->avctx, "filter mb:%d/%d MBAFF, QPy:%d/%d, QPb:%d/%d QPr:%d/%d ls:%d uvls:%d", mb_x, mb_y, qp[0], qp[1], bqp[0], bqp[1], rqp[0], rqp[1], linesize, uvlinesize);
+        { int i; for (i = 0; i < 8; i++) tprintf(h->avctx, " bS[%d]:%d", i, bS[i]); tprintf(h->avctx, "\n"); }
         if(MB_FIELD){
             filter_mb_mbaff_edgev ( h, img_y                ,   linesize, bS  , 1, qp [0], a, b, 1 );
             filter_mb_mbaff_edgev ( h, img_y  + 8*  linesize,   linesize, bS+4, 1, qp [1], a, b, 1 );
diff --git a/libavcodec/h264_mb_template.c b/libavcodec/h264_mb_template.c
index b02f566..8830d34 100644
--- a/libavcodec/h264_mb_template.c
+++ b/libavcodec/h264_mb_template.c
@@ -40,39 +40,38 @@
 
 static av_noinline void FUNC(hl_decode_mb)(H264Context *h)
 {
-    MpegEncContext *const s = &h->s;
-    const int mb_x    = s->mb_x;
-    const int mb_y    = s->mb_y;
+    const int mb_x    = h->mb_x;
+    const int mb_y    = h->mb_y;
     const int mb_xy   = h->mb_xy;
-    const int mb_type = s->current_picture.f.mb_type[mb_xy];
+    const int mb_type = h->cur_pic.f.mb_type[mb_xy];
     uint8_t *dest_y, *dest_cb, *dest_cr;
     int linesize, uvlinesize /*dct_offset*/;
     int i, j;
     int *block_offset = &h->block_offset[0];
-    const int transform_bypass = !SIMPLE && (s->qscale == 0 && h->sps.transform_bypass);
+    const int transform_bypass = !SIMPLE && (h->qscale == 0 && h->sps.transform_bypass);
     /* is_h264 should always be true if SVQ3 is disabled. */
-    const int is_h264 = !CONFIG_SVQ3_DECODER || SIMPLE || s->codec_id == AV_CODEC_ID_H264;
-    void (*idct_add)(uint8_t *dst, DCTELEM *block, int stride);
-    const int block_h   = 16 >> s->chroma_y_shift;
+    const int is_h264 = !CONFIG_SVQ3_DECODER || SIMPLE || h->avctx->codec_id == AV_CODEC_ID_H264;
+    void (*idct_add)(uint8_t *dst, int16_t *block, int stride);
+    const int block_h   = 16 >> h->chroma_y_shift;
     const int chroma422 = CHROMA422;
 
-    dest_y  = s->current_picture.f.data[0] + ((mb_x << PIXEL_SHIFT)     + mb_y * s->linesize)  * 16;
-    dest_cb = s->current_picture.f.data[1] +  (mb_x << PIXEL_SHIFT) * 8 + mb_y * s->uvlinesize * block_h;
-    dest_cr = s->current_picture.f.data[2] +  (mb_x << PIXEL_SHIFT) * 8 + mb_y * s->uvlinesize * block_h;
+    dest_y  = h->cur_pic.f.data[0] + ((mb_x << PIXEL_SHIFT)     + mb_y * h->linesize)  * 16;
+    dest_cb = h->cur_pic.f.data[1] +  (mb_x << PIXEL_SHIFT) * 8 + mb_y * h->uvlinesize * block_h;
+    dest_cr = h->cur_pic.f.data[2] +  (mb_x << PIXEL_SHIFT) * 8 + mb_y * h->uvlinesize * block_h;
 
-    s->dsp.prefetch(dest_y  + (s->mb_x & 3) * 4 * s->linesize   + (64 << PIXEL_SHIFT), s->linesize,       4);
-    s->dsp.prefetch(dest_cb + (s->mb_x & 7)     * s->uvlinesize + (64 << PIXEL_SHIFT), dest_cr - dest_cb, 2);
+    h->vdsp.prefetch(dest_y  + (h->mb_x & 3) * 4 * h->linesize   + (64 << PIXEL_SHIFT), h->linesize,       4);
+    h->vdsp.prefetch(dest_cb + (h->mb_x & 7)     * h->uvlinesize + (64 << PIXEL_SHIFT), dest_cr - dest_cb, 2);
 
     h->list_counts[mb_xy] = h->list_count;
 
     if (!SIMPLE && MB_FIELD) {
-        linesize     = h->mb_linesize = s->linesize * 2;
-        uvlinesize   = h->mb_uvlinesize = s->uvlinesize * 2;
+        linesize     = h->mb_linesize = h->linesize * 2;
+        uvlinesize   = h->mb_uvlinesize = h->uvlinesize * 2;
         block_offset = &h->block_offset[48];
         if (mb_y & 1) { // FIXME move out of this function?
-            dest_y  -= s->linesize * 15;
-            dest_cb -= s->uvlinesize * (block_h - 1);
-            dest_cr -= s->uvlinesize * (block_h - 1);
+            dest_y  -= h->linesize * 15;
+            dest_cb -= h->uvlinesize * (block_h - 1);
+            dest_cr -= h->uvlinesize * (block_h - 1);
         }
         if (FRAME_MBAFF) {
             int list;
@@ -81,20 +80,20 @@
                     continue;
                 if (IS_16X16(mb_type)) {
                     int8_t *ref = &h->ref_cache[list][scan8[0]];
-                    fill_rectangle(ref, 4, 4, 8, (16 + *ref) ^ (s->mb_y & 1), 1);
+                    fill_rectangle(ref, 4, 4, 8, (16 + *ref) ^ (h->mb_y & 1), 1);
                 } else {
                     for (i = 0; i < 16; i += 4) {
                         int ref = h->ref_cache[list][scan8[i]];
                         if (ref >= 0)
                             fill_rectangle(&h->ref_cache[list][scan8[i]], 2, 2,
-                                           8, (16 + ref) ^ (s->mb_y & 1), 1);
+                                           8, (16 + ref) ^ (h->mb_y & 1), 1);
                     }
                 }
             }
         }
     } else {
-        linesize   = h->mb_linesize   = s->linesize;
-        uvlinesize = h->mb_uvlinesize = s->uvlinesize;
+        linesize   = h->mb_linesize   = h->linesize;
+        uvlinesize = h->mb_uvlinesize = h->uvlinesize;
         // dct_offset = s->linesize * 16;
     }
 
@@ -103,7 +102,7 @@
         if (PIXEL_SHIFT) {
             int j;
             GetBitContext gb;
-            init_get_bits(&gb, (uint8_t *)h->mb,
+            init_get_bits(&gb, h->intra_pcm_ptr,
                           ff_h264_mb_sizes[h->sps.chroma_format_idc] * bit_depth);
 
             for (i = 0; i < 16; i++) {
@@ -111,7 +110,7 @@
                 for (j = 0; j < 16; j++)
                     tmp_y[j] = get_bits(&gb, bit_depth);
             }
-            if (SIMPLE || !CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) {
+            if (SIMPLE || !CONFIG_GRAY || !(h->flags & CODEC_FLAG_GRAY)) {
                 if (!h->sps.chroma_format_idc) {
                     for (i = 0; i < block_h; i++) {
                         uint16_t *tmp_cb = (uint16_t *)(dest_cb + i * uvlinesize);
@@ -135,16 +134,16 @@
             }
         } else {
             for (i = 0; i < 16; i++)
-                memcpy(dest_y + i * linesize, (uint8_t *)h->mb + i * 16, 16);
-            if (SIMPLE || !CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) {
+                memcpy(dest_y + i * linesize, h->intra_pcm_ptr + i * 16, 16);
+            if (SIMPLE || !CONFIG_GRAY || !(h->flags & CODEC_FLAG_GRAY)) {
                 if (!h->sps.chroma_format_idc) {
                     for (i = 0; i < 8; i++) {
                         memset(dest_cb + i*uvlinesize, 1 << (bit_depth - 1), 8);
                         memset(dest_cr + i*uvlinesize, 1 << (bit_depth - 1), 8);
                     }
                 } else {
-                    uint8_t *src_cb = (uint8_t *)h->mb + 256;
-                    uint8_t *src_cr = (uint8_t *)h->mb + 256 + block_h * 8;
+                    const uint8_t *src_cb = h->intra_pcm_ptr + 256;
+                    const uint8_t *src_cr = h->intra_pcm_ptr + 256 + block_h * 8;
                     for (i = 0; i < block_h; i++) {
                         memcpy(dest_cb + i * uvlinesize, src_cb + i * 8, 8);
                         memcpy(dest_cr + i * uvlinesize, src_cr + i * 8, 8);
@@ -158,11 +157,9 @@
                 xchg_mb_border(h, dest_y, dest_cb, dest_cr, linesize,
                                uvlinesize, 1, 0, SIMPLE, PIXEL_SHIFT);
 
-            if (SIMPLE || !CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) {
-                if (CHROMA) {
+            if (SIMPLE || !CONFIG_GRAY || !(h->flags & CODEC_FLAG_GRAY)) {
                 h->hpc.pred8x8[h->chroma_pred_mode](dest_cb, uvlinesize);
                 h->hpc.pred8x8[h->chroma_pred_mode](dest_cr, uvlinesize);
-                }
             }
 
             hl_decode_mb_predict_luma(h, mb_type, is_h264, SIMPLE,
@@ -175,14 +172,14 @@
         } else if (is_h264) {
             if (chroma422) {
                 FUNC(hl_motion_422)(h, dest_y, dest_cb, dest_cr,
-                              s->me.qpel_put, s->dsp.put_h264_chroma_pixels_tab,
-                              s->me.qpel_avg, s->dsp.avg_h264_chroma_pixels_tab,
+                              h->me.qpel_put, h->h264chroma.put_h264_chroma_pixels_tab,
+                              h->me.qpel_avg, h->h264chroma.avg_h264_chroma_pixels_tab,
                               h->h264dsp.weight_h264_pixels_tab,
                               h->h264dsp.biweight_h264_pixels_tab);
             } else {
                 FUNC(hl_motion_420)(h, dest_y, dest_cb, dest_cr,
-                              s->me.qpel_put, s->dsp.put_h264_chroma_pixels_tab,
-                              s->me.qpel_avg, s->dsp.avg_h264_chroma_pixels_tab,
+                              h->me.qpel_put, h->h264chroma.put_h264_chroma_pixels_tab,
+                              h->me.qpel_avg, h->h264chroma.avg_h264_chroma_pixels_tab,
                               h->h264dsp.weight_h264_pixels_tab,
                               h->h264dsp.biweight_h264_pixels_tab);
             }
@@ -191,7 +188,7 @@
         hl_decode_mb_idct_luma(h, mb_type, is_h264, SIMPLE, transform_bypass,
                                PIXEL_SHIFT, block_offset, linesize, dest_y, 0);
 
-        if ((SIMPLE || !CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) &&
+        if ((SIMPLE || !CONFIG_GRAY || !(h->flags & CODEC_FLAG_GRAY)) &&
             (h->cbp & 0x30)) {
             uint8_t *dest[2] = { dest_cb, dest_cr };
             if (transform_bypass) {
@@ -207,7 +204,7 @@
                                                             h->mb + (16 * 16 * 2 << PIXEL_SHIFT),
                                                             uvlinesize);
                 } else {
-                    idct_add = s->dsp.add_pixels4;
+                    idct_add = h->h264dsp.h264_add_pixels4_clear;
                     for (j = 1; j < 3; j++) {
                         for (i = j * 16; i < j * 16 + 4; i++)
                             if (h->non_zero_count_cache[scan8[i]] ||
@@ -255,17 +252,13 @@
                                 uint8_t *const ptr = dest[j - 1] + block_offset[i];
                                 ff_svq3_add_idct_c(ptr, h->mb + i * 16,
                                                    uvlinesize,
-                                                   ff_h264_chroma_qp[0][s->qscale + 12] - 12, 2);
+                                                   ff_h264_chroma_qp[0][h->qscale + 12] - 12, 2);
                             }
                     }
                 }
             }
         }
     }
-    if (h->cbp || IS_INTRA(mb_type)) {
-        s->dsp.clear_blocks(h->mb);
-        s->dsp.clear_blocks(h->mb + (24 * 16 << PIXEL_SHIFT));
-    }
 }
 
 #if !SIMPLE || BITS == 8
@@ -276,33 +269,32 @@
 
 static av_noinline void FUNC(hl_decode_mb_444)(H264Context *h)
 {
-    MpegEncContext *const s = &h->s;
-    const int mb_x    = s->mb_x;
-    const int mb_y    = s->mb_y;
+    const int mb_x    = h->mb_x;
+    const int mb_y    = h->mb_y;
     const int mb_xy   = h->mb_xy;
-    const int mb_type = s->current_picture.f.mb_type[mb_xy];
+    const int mb_type = h->cur_pic.f.mb_type[mb_xy];
     uint8_t *dest[3];
     int linesize;
     int i, j, p;
     int *block_offset = &h->block_offset[0];
-    const int transform_bypass = !SIMPLE && (s->qscale == 0 && h->sps.transform_bypass);
-    const int plane_count      = (SIMPLE || !CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) ? 3 : 1;
+    const int transform_bypass = !SIMPLE && (h->qscale == 0 && h->sps.transform_bypass);
+    const int plane_count      = (SIMPLE || !CONFIG_GRAY || !(h->flags & CODEC_FLAG_GRAY)) ? 3 : 1;
 
     for (p = 0; p < plane_count; p++) {
-        dest[p] = s->current_picture.f.data[p] +
-                  ((mb_x << PIXEL_SHIFT) + mb_y * s->linesize) * 16;
-        s->dsp.prefetch(dest[p] + (s->mb_x & 3) * 4 * s->linesize + (64 << PIXEL_SHIFT),
-                        s->linesize, 4);
+        dest[p] = h->cur_pic.f.data[p] +
+                  ((mb_x << PIXEL_SHIFT) + mb_y * h->linesize) * 16;
+        h->vdsp.prefetch(dest[p] + (h->mb_x & 3) * 4 * h->linesize + (64 << PIXEL_SHIFT),
+                         h->linesize, 4);
     }
 
     h->list_counts[mb_xy] = h->list_count;
 
     if (!SIMPLE && MB_FIELD) {
-        linesize     = h->mb_linesize = h->mb_uvlinesize = s->linesize * 2;
+        linesize     = h->mb_linesize = h->mb_uvlinesize = h->linesize * 2;
         block_offset = &h->block_offset[48];
         if (mb_y & 1) // FIXME move out of this function?
             for (p = 0; p < 3; p++)
-                dest[p] -= s->linesize * 15;
+                dest[p] -= h->linesize * 15;
         if (FRAME_MBAFF) {
             int list;
             for (list = 0; list < h->list_count; list++) {
@@ -310,26 +302,26 @@
                     continue;
                 if (IS_16X16(mb_type)) {
                     int8_t *ref = &h->ref_cache[list][scan8[0]];
-                    fill_rectangle(ref, 4, 4, 8, (16 + *ref) ^ (s->mb_y & 1), 1);
+                    fill_rectangle(ref, 4, 4, 8, (16 + *ref) ^ (h->mb_y & 1), 1);
                 } else {
                     for (i = 0; i < 16; i += 4) {
                         int ref = h->ref_cache[list][scan8[i]];
                         if (ref >= 0)
                             fill_rectangle(&h->ref_cache[list][scan8[i]], 2, 2,
-                                           8, (16 + ref) ^ (s->mb_y & 1), 1);
+                                           8, (16 + ref) ^ (h->mb_y & 1), 1);
                     }
                 }
             }
         }
     } else {
-        linesize = h->mb_linesize = h->mb_uvlinesize = s->linesize;
+        linesize = h->mb_linesize = h->mb_uvlinesize = h->linesize;
     }
 
     if (!SIMPLE && IS_INTRA_PCM(mb_type)) {
         if (PIXEL_SHIFT) {
             const int bit_depth = h->sps.bit_depth_luma;
             GetBitContext gb;
-            init_get_bits(&gb, (uint8_t *)h->mb, 768 * bit_depth);
+            init_get_bits(&gb, h->intra_pcm_ptr, 768 * bit_depth);
 
             for (p = 0; p < plane_count; p++)
                 for (i = 0; i < 16; i++) {
@@ -341,7 +333,7 @@
             for (p = 0; p < plane_count; p++)
                 for (i = 0; i < 16; i++)
                     memcpy(dest[p] + i * linesize,
-                           (uint8_t *)h->mb + p * 256 + i * 16, 16);
+                           h->intra_pcm_ptr + p * 256 + i * 16, 16);
         }
     } else {
         if (IS_INTRA(mb_type)) {
@@ -359,8 +351,8 @@
                                linesize, 0, 1, SIMPLE, PIXEL_SHIFT);
         } else {
             FUNC(hl_motion_444)(h, dest[0], dest[1], dest[2],
-                      s->me.qpel_put, s->dsp.put_h264_chroma_pixels_tab,
-                      s->me.qpel_avg, s->dsp.avg_h264_chroma_pixels_tab,
+                      h->me.qpel_put, h->h264chroma.put_h264_chroma_pixels_tab,
+                      h->me.qpel_avg, h->h264chroma.avg_h264_chroma_pixels_tab,
                       h->h264dsp.weight_h264_pixels_tab,
                       h->h264dsp.biweight_h264_pixels_tab);
         }
@@ -370,10 +362,6 @@
                                    PIXEL_SHIFT, block_offset, linesize,
                                    dest[p], p);
     }
-    if (h->cbp || IS_INTRA(mb_type)) {
-        s->dsp.clear_blocks(h->mb);
-        s->dsp.clear_blocks(h->mb + (24 * 16 << PIXEL_SHIFT));
-    }
 }
 
 #endif
diff --git a/libavcodec/h264_mc_template.c b/libavcodec/h264_mc_template.c
index a59d6a2..2a035af 100644
--- a/libavcodec/h264_mc_template.c
+++ b/libavcodec/h264_mc_template.c
@@ -46,7 +46,7 @@
                     int list0, int list1)
 {
     if ((h->use_weight == 2 && list0 && list1 &&
-         (h->implicit_weight[h->ref_cache[0][scan8[n]]][h->ref_cache[1][scan8[n]]][h->s.mb_y & 1] != 32)) ||
+         (h->implicit_weight[h->ref_cache[0][scan8[n]]][h->ref_cache[1][scan8[n]]][h->mb_y & 1] != 32)) ||
         h->use_weight == 1)
         mc_part_weighted(h, n, square, height, delta, dest_y, dest_cb, dest_cr,
                          x_offset, y_offset, qpix_put, chroma_put,
@@ -67,13 +67,12 @@
                               h264_weight_func *weight_op,
                               h264_biweight_func *weight_avg)
 {
-    MpegEncContext *const s = &h->s;
     const int mb_xy   = h->mb_xy;
-    const int mb_type = s->current_picture.f.mb_type[mb_xy];
+    const int mb_type = h->cur_pic.f.mb_type[mb_xy];
 
     av_assert2(IS_INTER(mb_type));
 
-    if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME))
+    if (HAVE_THREADS && (h->avctx->active_thread_type & FF_THREAD_FRAME))
         await_references(h);
     prefetch_motion(h, 0, PIXEL_SHIFT, CHROMA_IDC);
 
diff --git a/libavcodec/h264_mvpred.h b/libavcodec/h264_mvpred.h
index 0a405f7..41670fc 100644
--- a/libavcodec/h264_mvpred.h
+++ b/libavcodec/h264_mvpred.h
@@ -38,32 +38,31 @@
                                               int i, int list, int part_width)
 {
     const int topright_ref = h->ref_cache[list][i - 8 + part_width];
-    MpegEncContext *s      = &h->s;
 
     /* there is no consistent mapping of mvs to neighboring locations that will
      * make mbaff happy, so we can't move all this logic to fill_caches */
     if (FRAME_MBAFF) {
 #define SET_DIAG_MV(MV_OP, REF_OP, XY, Y4)                              \
         const int xy = XY, y4 = Y4;                                     \
-        const int mb_type = mb_types[xy + (y4 >> 2) * s->mb_stride];    \
+        const int mb_type = mb_types[xy + (y4 >> 2) * h->mb_stride];    \
         if (!USES_LIST(mb_type, list))                                  \
             return LIST_NOT_USED;                                       \
-        mv = s->current_picture_ptr->f.motion_val[list][h->mb2b_xy[xy] + 3 + y4 * h->b_stride]; \
+        mv = h->cur_pic_ptr->f.motion_val[list][h->mb2b_xy[xy] + 3 + y4 * h->b_stride]; \
         h->mv_cache[list][scan8[0] - 2][0] = mv[0];                     \
         h->mv_cache[list][scan8[0] - 2][1] = mv[1] MV_OP;               \
-        return s->current_picture_ptr->f.ref_index[list][4 * xy + 1 + (y4 & ~1)] REF_OP;
+        return h->cur_pic_ptr->f.ref_index[list][4 * xy + 1 + (y4 & ~1)] REF_OP;
 
         if (topright_ref == PART_NOT_AVAILABLE
             && i >= scan8[0] + 8 && (i & 7) == 4
             && h->ref_cache[list][scan8[0] - 1] != PART_NOT_AVAILABLE) {
-            const uint32_t *mb_types = s->current_picture_ptr->f.mb_type;
+            const uint32_t *mb_types = h->cur_pic_ptr->f.mb_type;
             const int16_t *mv;
             AV_ZERO32(h->mv_cache[list][scan8[0] - 2]);
             *C = h->mv_cache[list][scan8[0] - 2];
 
             if (!MB_FIELD && IS_INTERLACED(h->left_type[0])) {
-                SET_DIAG_MV(* 2, >> 1, h->left_mb_xy[0] + s->mb_stride,
-                            (s->mb_y & 1) * 2 + (i >> 5));
+                SET_DIAG_MV(* 2, >> 1, h->left_mb_xy[0] + h->mb_stride,
+                            (h->mb_y & 1) * 2 + (i >> 5));
             }
             if (MB_FIELD && !IS_INTERLACED(h->left_type[0])) {
                 // left shift will turn LIST_NOT_USED into PART_NOT_AVAILABLE, but that's OK.
@@ -77,7 +76,7 @@
         *C = h->mv_cache[list][i - 8 + part_width];
         return topright_ref;
     } else {
-        tprintf(s->avctx, "topright MV not available\n");
+        tprintf(h->avctx, "topright MV not available\n");
 
         *C = h->mv_cache[list][i - 8 - 1];
         return h->ref_cache[list][i - 8 - 1];
@@ -115,7 +114,7 @@
 
     diagonal_ref = fetch_diagonal_mv(h, &C, index8, list, part_width);
     match_count  = (diagonal_ref == ref) + (top_ref == ref) + (left_ref == ref);
-    tprintf(h->s.avctx, "pred_motion match_count=%d\n", match_count);
+    tprintf(h->avctx, "pred_motion match_count=%d\n", match_count);
     if (match_count > 1) { //most common
         *mx = mid_pred(A[0], B[0], C[0]);
         *my = mid_pred(A[1], B[1], C[1]);
@@ -142,10 +141,10 @@
         }
     }
 
-    tprintf(h->s.avctx,
+    tprintf(h->avctx,
             "pred_motion (%2d %2d %2d) (%2d %2d %2d) (%2d %2d %2d) -> (%2d %2d %2d) at %2d %2d %d list %d\n",
             top_ref, B[0], B[1], diagonal_ref, C[0], C[1], left_ref,
-            A[0], A[1], ref, *mx, *my, h->s.mb_x, h->s.mb_y, n, list);
+            A[0], A[1], ref, *mx, *my, h->mb_x, h->mb_y, n, list);
 }
 
 /**
@@ -162,8 +161,8 @@
         const int top_ref      = h->ref_cache[list][scan8[0] - 8];
         const int16_t *const B = h->mv_cache[list][scan8[0] - 8];
 
-        tprintf(h->s.avctx, "pred_16x8: (%2d %2d %2d) at %2d %2d %d list %d\n",
-                top_ref, B[0], B[1], h->s.mb_x, h->s.mb_y, n, list);
+        tprintf(h->avctx, "pred_16x8: (%2d %2d %2d) at %2d %2d %d list %d\n",
+                top_ref, B[0], B[1], h->mb_x, h->mb_y, n, list);
 
         if (top_ref == ref) {
             *mx = B[0];
@@ -174,8 +173,8 @@
         const int left_ref     = h->ref_cache[list][scan8[8] - 1];
         const int16_t *const A = h->mv_cache[list][scan8[8] - 1];
 
-        tprintf(h->s.avctx, "pred_16x8: (%2d %2d %2d) at %2d %2d %d list %d\n",
-                left_ref, A[0], A[1], h->s.mb_x, h->s.mb_y, n, list);
+        tprintf(h->avctx, "pred_16x8: (%2d %2d %2d) at %2d %2d %d list %d\n",
+                left_ref, A[0], A[1], h->mb_x, h->mb_y, n, list);
 
         if (left_ref == ref) {
             *mx = A[0];
@@ -202,8 +201,8 @@
         const int left_ref     = h->ref_cache[list][scan8[0] - 1];
         const int16_t *const A = h->mv_cache[list][scan8[0] - 1];
 
-        tprintf(h->s.avctx, "pred_8x16: (%2d %2d %2d) at %2d %2d %d list %d\n",
-                left_ref, A[0], A[1], h->s.mb_x, h->s.mb_y, n, list);
+        tprintf(h->avctx, "pred_8x16: (%2d %2d %2d) at %2d %2d %d list %d\n",
+                left_ref, A[0], A[1], h->mb_x, h->mb_y, n, list);
 
         if (left_ref == ref) {
             *mx = A[0];
@@ -216,8 +215,8 @@
 
         diagonal_ref = fetch_diagonal_mv(h, &C, scan8[4], list, 2);
 
-        tprintf(h->s.avctx, "pred_8x16: (%2d %2d %2d) at %2d %2d %d list %d\n",
-                diagonal_ref, C[0], C[1], h->s.mb_x, h->s.mb_y, n, list);
+        tprintf(h->avctx, "pred_8x16: (%2d %2d %2d) at %2d %2d %d list %d\n",
+                diagonal_ref, C[0], C[1], h->mb_x, h->mb_y, n, list);
 
         if (diagonal_ref == ref) {
             *mx = C[0];
@@ -253,9 +252,8 @@
 {
     DECLARE_ALIGNED(4, static const int16_t, zeromv)[2] = { 0 };
     DECLARE_ALIGNED(4, int16_t, mvbuf)[3][2];
-    MpegEncContext *const s = &h->s;
-    int8_t *ref     = s->current_picture.f.ref_index[0];
-    int16_t(*mv)[2] = s->current_picture.f.motion_val[0];
+    int8_t *ref     = h->cur_pic.f.ref_index[0];
+    int16_t(*mv)[2] = h->cur_pic.f.motion_val[0];
     int top_ref, left_ref, diagonal_ref, match_count, mx, my;
     const int16_t *A, *B, *C;
     int b_stride = h->b_stride;
@@ -293,8 +291,8 @@
         goto zeromv;
     }
 
-    tprintf(h->s.avctx, "pred_pskip: (%d) (%d) at %2d %2d\n",
-            top_ref, left_ref, h->s.mb_x, h->s.mb_y);
+    tprintf(h->avctx, "pred_pskip: (%d) (%d) at %2d %2d\n",
+            top_ref, left_ref, h->mb_x, h->mb_y);
 
     if (USES_LIST(h->topright_type, 0)) {
         diagonal_ref = ref[4 * h->topright_mb_xy + 2];
@@ -320,7 +318,7 @@
     }
 
     match_count = !diagonal_ref + !top_ref + !left_ref;
-    tprintf(h->s.avctx, "pred_pskip_motion match_count=%d\n", match_count);
+    tprintf(h->avctx, "pred_pskip_motion match_count=%d\n", match_count);
     if (match_count > 1) {
         mx = mid_pred(A[0], B[0], C[0]);
         my = mid_pred(A[1], B[1], C[1]);
@@ -350,7 +348,6 @@
 
 static void fill_decode_neighbors(H264Context *h, int mb_type)
 {
-    MpegEncContext *const s = &h->s;
     const int mb_xy = h->mb_xy;
     int topleft_xy, top_xy, topright_xy, left_xy[LEFT_MBS];
     static const uint8_t left_block_options[4][32] = {
@@ -362,7 +359,7 @@
 
     h->topleft_partition = -1;
 
-    top_xy = mb_xy - (s->mb_stride << MB_FIELD);
+    top_xy = mb_xy - (h->mb_stride << MB_FIELD);
 
     /* Wow, what a mess, why didn't they simplify the interlacing & intra
      * stuff, I can't imagine that these complex rules are worth it. */
@@ -372,16 +369,16 @@
     left_xy[LBOT] = left_xy[LTOP] = mb_xy - 1;
     h->left_block = left_block_options[0];
     if (FRAME_MBAFF) {
-        const int left_mb_field_flag = IS_INTERLACED(s->current_picture.f.mb_type[mb_xy - 1]);
+        const int left_mb_field_flag = IS_INTERLACED(h->cur_pic.f.mb_type[mb_xy - 1]);
         const int curr_mb_field_flag = IS_INTERLACED(mb_type);
-        if (s->mb_y & 1) {
+        if (h->mb_y & 1) {
             if (left_mb_field_flag != curr_mb_field_flag) {
-                left_xy[LBOT] = left_xy[LTOP] = mb_xy - s->mb_stride - 1;
+                left_xy[LBOT] = left_xy[LTOP] = mb_xy - h->mb_stride - 1;
                 if (curr_mb_field_flag) {
-                    left_xy[LBOT] += s->mb_stride;
+                    left_xy[LBOT] += h->mb_stride;
                     h->left_block  = left_block_options[3];
                 } else {
-                    topleft_xy += s->mb_stride;
+                    topleft_xy += h->mb_stride;
                     /* take top left mv from the middle of the mb, as opposed
                      * to all other modes which use the bottom right partition */
                     h->topleft_partition = 0;
@@ -390,13 +387,13 @@
             }
         } else {
             if (curr_mb_field_flag) {
-                topleft_xy  += s->mb_stride & (((s->current_picture.f.mb_type[top_xy - 1] >> 7) & 1) - 1);
-                topright_xy += s->mb_stride & (((s->current_picture.f.mb_type[top_xy + 1] >> 7) & 1) - 1);
-                top_xy      += s->mb_stride & (((s->current_picture.f.mb_type[top_xy]     >> 7) & 1) - 1);
+                topleft_xy  += h->mb_stride & (((h->cur_pic.f.mb_type[top_xy - 1] >> 7) & 1) - 1);
+                topright_xy += h->mb_stride & (((h->cur_pic.f.mb_type[top_xy + 1] >> 7) & 1) - 1);
+                top_xy      += h->mb_stride & (((h->cur_pic.f.mb_type[top_xy]     >> 7) & 1) - 1);
             }
             if (left_mb_field_flag != curr_mb_field_flag) {
                 if (curr_mb_field_flag) {
-                    left_xy[LBOT] += s->mb_stride;
+                    left_xy[LBOT] += h->mb_stride;
                     h->left_block  = left_block_options[3];
                 } else {
                     h->left_block = left_block_options[2];
@@ -412,11 +409,11 @@
     h->left_mb_xy[LBOT] = left_xy[LBOT];
     //FIXME do we need all in the context?
 
-    h->topleft_type    = s->current_picture.f.mb_type[topleft_xy];
-    h->top_type        = s->current_picture.f.mb_type[top_xy];
-    h->topright_type   = s->current_picture.f.mb_type[topright_xy];
-    h->left_type[LTOP] = s->current_picture.f.mb_type[left_xy[LTOP]];
-    h->left_type[LBOT] = s->current_picture.f.mb_type[left_xy[LBOT]];
+    h->topleft_type    = h->cur_pic.f.mb_type[topleft_xy];
+    h->top_type        = h->cur_pic.f.mb_type[top_xy];
+    h->topright_type   = h->cur_pic.f.mb_type[topright_xy];
+    h->left_type[LTOP] = h->cur_pic.f.mb_type[left_xy[LTOP]];
+    h->left_type[LBOT] = h->cur_pic.f.mb_type[left_xy[LBOT]];
 
     if (FMO) {
         if (h->slice_table[topleft_xy] != h->slice_num)
@@ -440,7 +437,6 @@
 
 static void fill_decode_caches(H264Context *h, int mb_type)
 {
-    MpegEncContext *const s = &h->s;
     int topleft_xy, top_xy, topright_xy, left_xy[LEFT_MBS];
     int topleft_type, top_type, topright_type, left_type[LEFT_MBS];
     const uint8_t *left_block = h->left_block;
@@ -483,7 +479,7 @@
                         h->left_samples_available    &= 0xFF5F;
                     }
                 } else {
-                    int left_typei = s->current_picture.f.mb_type[left_xy[LTOP] + s->mb_stride];
+                    int left_typei = h->cur_pic.f.mb_type[left_xy[LTOP] + h->mb_stride];
 
                     av_assert2(left_xy[LTOP] == left_xy[LBOT]);
                     if (!((left_typei & type_mask) && (left_type[LTOP] & type_mask))) {
@@ -540,7 +536,7 @@
         if (top_type) {
             nnz = h->non_zero_count[top_xy];
             AV_COPY32(&nnz_cache[4 + 8 * 0], &nnz[4 * 3]);
-            if (!s->chroma_y_shift) {
+            if (!h->chroma_y_shift) {
                 AV_COPY32(&nnz_cache[4 + 8 *  5], &nnz[4 *  7]);
                 AV_COPY32(&nnz_cache[4 + 8 * 10], &nnz[4 * 11]);
             } else {
@@ -605,9 +601,9 @@
         int b_stride = h->b_stride;
         for (list = 0; list < h->list_count; list++) {
             int8_t *ref_cache = &h->ref_cache[list][scan8[0]];
-            int8_t *ref       = s->current_picture.f.ref_index[list];
+            int8_t *ref       = h->cur_pic.f.ref_index[list];
             int16_t(*mv_cache)[2] = &h->mv_cache[list][scan8[0]];
-            int16_t(*mv)[2]       = s->current_picture.f.motion_val[list];
+            int16_t(*mv)[2]       = h->cur_pic.f.motion_val[list];
             if (!USES_LIST(mb_type, list))
                 continue;
             av_assert2(!(IS_DIRECT(mb_type) && !h->direct_spatial_mv_pred));
@@ -799,7 +795,6 @@
  */
 static void av_unused decode_mb_skip(H264Context *h)
 {
-    MpegEncContext *const s = &h->s;
     const int mb_xy = h->mb_xy;
     int mb_type     = 0;
 
@@ -825,10 +820,10 @@
     }
 
     write_back_motion(h, mb_type);
-    s->current_picture.f.mb_type[mb_xy]      = mb_type;
-    s->current_picture.f.qscale_table[mb_xy] = s->qscale;
-    h->slice_table[mb_xy]                    = h->slice_num;
-    h->prev_mb_skipped                       = 1;
+    h->cur_pic.f.mb_type[mb_xy]      = mb_type;
+    h->cur_pic.f.qscale_table[mb_xy] = h->qscale;
+    h->slice_table[mb_xy]            = h->slice_num;
+    h->prev_mb_skipped               = 1;
 }
 
 #endif /* AVCODEC_H264_MVPRED_H */
diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c
index f33e885..14ae67b 100644
--- a/libavcodec/h264_parser.c
+++ b/libavcodec/h264_parser.c
@@ -34,7 +34,7 @@
 {
     int i, j;
     uint32_t state;
-    ParseContext *pc = &(h->s.parse_context);
+    ParseContext *pc = &h->parse_context;
     int next_avc= h->is_avc ? 0 : buf_size;
 
 //    mb_addr= pc->mb_addr - 1;
@@ -43,7 +43,7 @@
         state= 7;
 
     if(h->is_avc && !h->nal_length_size)
-        av_log(h->s.avctx, AV_LOG_ERROR, "AVC-parser: nal length size invalid\n");
+        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) {
@@ -52,7 +52,7 @@
             for(j = 0; j < h->nal_length_size; j++)
                 nalsize = (nalsize << 8) | buf[i++];
             if(nalsize <= 0 || nalsize > buf_size - i){
-                av_log(h->s.avctx, AV_LOG_ERROR, "AVC-parser: nal size %d remaining %d\n", 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;
@@ -151,7 +151,7 @@
     s->pict_type = AV_PICTURE_TYPE_I;
     s->key_frame = 0;
 
-    h->s.avctx= avctx;
+    h->avctx= avctx;
     h->sei_recovery_frame_cnt = -1;
     h->sei_dpb_output_delay         =  0;
     h->sei_cpb_removal_delay        = -1;
@@ -169,7 +169,7 @@
             for (i = 0; i < h->nal_length_size; i++)
                 nalsize = (nalsize << 8) | *buf++;
             if (nalsize <= 0 || nalsize > buf_end - buf) {
-                av_log(h->s.avctx, AV_LOG_ERROR, "AVC: nal size %d\n", nalsize);
+                av_log(h->avctx, AV_LOG_ERROR, "AVC: nal size %d\n", nalsize);
                 break;
             }
             src_length = nalsize;
@@ -192,13 +192,13 @@
         if (ptr==NULL || dst_length < 0)
             break;
 
-        init_get_bits(&h->s.gb, ptr, 8*dst_length);
+        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;
         case NAL_PPS:
-            ff_h264_decode_picture_parameter_set(h, h->s.gb.size_in_bits);
+            ff_h264_decode_picture_parameter_set(h, h->gb.size_in_bits);
             break;
         case NAL_SEI:
             ff_h264_decode_sei(h);
@@ -207,40 +207,40 @@
             s->key_frame = 1;
             /* fall through */
         case NAL_SLICE:
-            get_ue_golomb_long(&h->s.gb);  // skip first_mb_in_slice
-            slice_type = get_ue_golomb_31(&h->s.gb);
+            get_ue_golomb_long(&h->gb);  // skip first_mb_in_slice
+            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->s.gb);
+            pps_id= get_ue_golomb(&h->gb);
             if(pps_id>=MAX_PPS_COUNT) {
-                av_log(h->s.avctx, AV_LOG_ERROR, "pps_id out of range\n");
+                av_log(h->avctx, AV_LOG_ERROR, "pps_id out of range\n");
                 return -1;
             }
             if(!h->pps_buffers[pps_id]) {
-                av_log(h->s.avctx, AV_LOG_ERROR, "non-existing PPS referenced\n");
+                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->s.avctx, AV_LOG_ERROR, "non-existing SPS referenced\n");
+                av_log(h->avctx, AV_LOG_ERROR, "non-existing SPS referenced\n");
                 return -1;
             }
             h->sps = *h->sps_buffers[h->pps.sps_id];
-            h->frame_num = get_bits(&h->s.gb, h->sps.log2_max_frame_num);
+            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->s.picture_structure= PICT_FRAME;
+                h->picture_structure= PICT_FRAME;
             }else{
-                if(get_bits1(&h->s.gb)) { //field_pic_flag
-                    h->s.picture_structure= PICT_TOP_FIELD + get_bits1(&h->s.gb); //bottom_field_flag
+                if(get_bits1(&h->gb)) { //field_pic_flag
+                    h->picture_structure= PICT_TOP_FIELD + get_bits1(&h->gb); //bottom_field_flag
                 } else {
-                    h->s.picture_structure= PICT_FRAME;
+                    h->picture_structure= PICT_FRAME;
                 }
             }
 
@@ -266,11 +266,11 @@
                         s->repeat_pict = 5;
                         break;
                     default:
-                        s->repeat_pict = h->s.picture_structure == PICT_FRAME ? 1 : 0;
+                        s->repeat_pict = h->picture_structure == PICT_FRAME ? 1 : 0;
                         break;
                 }
             } else {
-                s->repeat_pict = h->s.picture_structure == PICT_FRAME ? 1 : 0;
+                s->repeat_pict = h->picture_structure == PICT_FRAME ? 1 : 0;
             }
 
             return 0; /* no need to evaluate the rest */
@@ -280,7 +280,7 @@
     if (q264)
         return 0;
     /* didn't find a picture! */
-    av_log(h->s.avctx, AV_LOG_ERROR, "missing picture in access unit with size %d\n", buf_size);
+    av_log(h->avctx, AV_LOG_ERROR, "missing picture in access unit with size %d\n", buf_size);
     return -1;
 }
 
@@ -290,19 +290,19 @@
                       const uint8_t *buf, int buf_size)
 {
     H264Context *h = s->priv_data;
-    ParseContext *pc = &h->s.parse_context;
+    ParseContext *pc = &h->parse_context;
     int next;
 
     if (!h->got_first) {
         h->got_first = 1;
         if (avctx->extradata_size) {
-            h->s.avctx = avctx;
+            h->avctx = avctx;
             // must be done like in decoder, otherwise opening the parser,
             // letting it create extradata and then closing and opening again
             // will cause has_b_frames to be always set.
             // Note that estimate_timings_from_pts does exactly this.
             if (!avctx->has_b_frames)
-                h->s.low_delay = 1;
+                h->low_delay = 1;
             ff_h264_decode_extradata(h, avctx->extradata, avctx->extradata_size);
         }
     }
@@ -372,7 +372,7 @@
 static void close(AVCodecParserContext *s)
 {
     H264Context *h = s->priv_data;
-    ParseContext *pc = &h->s.parse_context;
+    ParseContext *pc = &h->parse_context;
 
     av_free(pc->buffer);
     ff_h264_free_context(h);
@@ -382,7 +382,7 @@
 {
     H264Context *h = s->priv_data;
     h->thread_context[0] = h;
-    h->s.slice_context_count = 1;
+    h->slice_context_count = 1;
     return 0;
 }
 
diff --git a/libavcodec/h264_ps.c b/libavcodec/h264_ps.c
index 28d3cbc..8638ce2 100644
--- a/libavcodec/h264_ps.c
+++ b/libavcodec/h264_ps.c
@@ -27,7 +27,6 @@
 
 #include "libavutil/imgutils.h"
 #include "internal.h"
-#include "dsputil.h"
 #include "avcodec.h"
 #include "h264.h"
 #include "h264data.h" //FIXME FIXME FIXME (just for zigzag_scan)
@@ -37,6 +36,9 @@
 //#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},
@@ -148,46 +150,44 @@
 }};
 
 static inline int decode_hrd_parameters(H264Context *h, SPS *sps){
-    MpegEncContext * const s = &h->s;
     int cpb_count, i;
-    cpb_count = get_ue_golomb_31(&s->gb) + 1;
+    cpb_count = get_ue_golomb_31(&h->gb) + 1;
 
     if(cpb_count > 32U){
-        av_log(h->s.avctx, AV_LOG_ERROR, "cpb_count %d invalid\n", cpb_count);
+        av_log(h->avctx, AV_LOG_ERROR, "cpb_count %d invalid\n", cpb_count);
         return -1;
     }
 
-    get_bits(&s->gb, 4); /* bit_rate_scale */
-    get_bits(&s->gb, 4); /* cpb_size_scale */
+    get_bits(&h->gb, 4); /* bit_rate_scale */
+    get_bits(&h->gb, 4); /* cpb_size_scale */
     for(i=0; i<cpb_count; i++){
-        get_ue_golomb_long(&s->gb); /* bit_rate_value_minus1 */
-        get_ue_golomb_long(&s->gb); /* cpb_size_value_minus1 */
-        get_bits1(&s->gb);     /* cbr_flag */
+        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 */
     }
-    sps->initial_cpb_removal_delay_length = get_bits(&s->gb, 5) + 1;
-    sps->cpb_removal_delay_length = get_bits(&s->gb, 5) + 1;
-    sps->dpb_output_delay_length = get_bits(&s->gb, 5) + 1;
-    sps->time_offset_length = get_bits(&s->gb, 5);
+    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;
     return 0;
 }
 
 static inline int decode_vui_parameters(H264Context *h, SPS *sps){
-    MpegEncContext * const s = &h->s;
     int aspect_ratio_info_present_flag;
     unsigned int aspect_ratio_idc;
 
-    aspect_ratio_info_present_flag= get_bits1(&s->gb);
+    aspect_ratio_info_present_flag= get_bits1(&h->gb);
 
     if( aspect_ratio_info_present_flag ) {
-        aspect_ratio_idc= get_bits(&s->gb, 8);
+        aspect_ratio_idc= get_bits(&h->gb, 8);
         if( aspect_ratio_idc == EXTENDED_SAR ) {
-            sps->sar.num= get_bits(&s->gb, 16);
-            sps->sar.den= get_bits(&s->gb, 16);
+            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->s.avctx, AV_LOG_ERROR, "illegal aspect ratio\n");
+            av_log(h->avctx, AV_LOG_ERROR, "illegal aspect ratio\n");
             return -1;
         }
     }else{
@@ -196,20 +196,20 @@
     }
 //            s->avctx->aspect_ratio= sar_width*s->width / (float)(s->height*sar_height);
 
-    if(get_bits1(&s->gb)){      /* overscan_info_present_flag */
-        get_bits1(&s->gb);      /* overscan_appropriate_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(&s->gb);
+    sps->video_signal_type_present_flag = get_bits1(&h->gb);
     if(sps->video_signal_type_present_flag){
-        get_bits(&s->gb, 3);    /* video_format */
-        sps->full_range = get_bits1(&s->gb); /* video_full_range_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(&s->gb);
+        sps->colour_description_present_flag = get_bits1(&h->gb);
         if(sps->colour_description_present_flag){
-            sps->color_primaries = get_bits(&s->gb, 8); /* colour_primaries */
-            sps->color_trc       = get_bits(&s->gb, 8); /* transfer_characteristics */
-            sps->colorspace      = get_bits(&s->gb, 8); /* matrix_coefficients */
+            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;
             if (sps->color_trc >= AVCOL_TRC_NB)
@@ -219,58 +219,58 @@
         }
     }
 
-    if(get_bits1(&s->gb)){      /* chroma_location_info_present_flag */
-        s->avctx->chroma_sample_location = get_ue_golomb(&s->gb)+1;  /* chroma_sample_location_type_top_field */
-        get_ue_golomb(&s->gb);  /* chroma_sample_location_type_bottom_field */
+    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 */
+        get_ue_golomb(&h->gb);  /* chroma_sample_location_type_bottom_field */
     }
 
-    sps->timing_info_present_flag = get_bits1(&s->gb);
+    sps->timing_info_present_flag = get_bits1(&h->gb);
     if(sps->timing_info_present_flag){
-        sps->num_units_in_tick = get_bits_long(&s->gb, 32);
-        sps->time_scale = get_bits_long(&s->gb, 32);
+        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->s.avctx, AV_LOG_ERROR, "time_scale/num_units_in_tick invalid or unsupported (%d/%d)\n", sps->time_scale, sps->num_units_in_tick);
+            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->fixed_frame_rate_flag = get_bits1(&s->gb);
+        sps->fixed_frame_rate_flag = get_bits1(&h->gb);
     }
 
-    sps->nal_hrd_parameters_present_flag = get_bits1(&s->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;
-    sps->vcl_hrd_parameters_present_flag = get_bits1(&s->gb);
+    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)
-        get_bits1(&s->gb);     /* low_delay_hrd_flag */
-    sps->pic_struct_present_flag = get_bits1(&s->gb);
-    if(!get_bits_left(&s->gb))
+        get_bits1(&h->gb);     /* low_delay_hrd_flag */
+    sps->pic_struct_present_flag = get_bits1(&h->gb);
+    if(!get_bits_left(&h->gb))
         return 0;
-    sps->bitstream_restriction_flag = get_bits1(&s->gb);
+    sps->bitstream_restriction_flag = get_bits1(&h->gb);
     if(sps->bitstream_restriction_flag){
-        get_bits1(&s->gb);     /* motion_vectors_over_pic_boundaries_flag */
-        get_ue_golomb(&s->gb); /* max_bytes_per_pic_denom */
-        get_ue_golomb(&s->gb); /* max_bits_per_mb_denom */
-        get_ue_golomb(&s->gb); /* log2_max_mv_length_horizontal */
-        get_ue_golomb(&s->gb); /* log2_max_mv_length_vertical */
-        sps->num_reorder_frames= get_ue_golomb(&s->gb);
-        get_ue_golomb(&s->gb); /*max_dec_frame_buffering*/
+        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);
+        get_ue_golomb(&h->gb); /*max_dec_frame_buffering*/
 
-        if (get_bits_left(&s->gb) < 0) {
+        if (get_bits_left(&h->gb) < 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->s.avctx, AV_LOG_ERROR, "illegal num_reorder_frames %d\n", sps->num_reorder_frames);
+            av_log(h->avctx, AV_LOG_ERROR, "illegal num_reorder_frames %d\n", sps->num_reorder_frames);
             return -1;
         }
     }
 
-    if (get_bits_left(&s->gb) < 0) {
-        av_log(h->s.avctx, AV_LOG_ERROR, "Overread VUI by %d bits\n", -get_bits_left(&s->gb));
+    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));
         return AVERROR_INVALIDDATA;
     }
 
@@ -279,15 +279,14 @@
 
 static void decode_scaling_list(H264Context *h, uint8_t *factors, int size,
                                 const uint8_t *jvt_list, const uint8_t *fallback_list){
-    MpegEncContext * const s = &h->s;
     int i, last = 8, next = 8;
     const uint8_t *scan = size == 16 ? zigzag_scan : ff_zigzag_direct;
-    if(!get_bits1(&s->gb)) /* matrix not written, we use the predicted one */
+    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(&s->gb)) & 0xff;
+            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;
@@ -298,7 +297,6 @@
 
 static void decode_scaling_matrices(H264Context *h, SPS *sps, PPS *pps, int is_sps,
                                    uint8_t (*scaling_matrix4)[16], uint8_t (*scaling_matrix8)[64]){
-    MpegEncContext * const s = &h->s;
     int fallback_sps = !is_sps && sps->scaling_matrix_present;
     const uint8_t *fallback[4] = {
         fallback_sps ? sps->scaling_matrix4[0] : default_scaling4[0],
@@ -306,7 +304,7 @@
         fallback_sps ? sps->scaling_matrix8[0] : default_scaling8[0],
         fallback_sps ? sps->scaling_matrix8[3] : default_scaling8[1]
     };
-    if(get_bits1(&s->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
@@ -328,25 +326,24 @@
 }
 
 int ff_h264_decode_seq_parameter_set(H264Context *h){
-    MpegEncContext * const s = &h->s;
     int profile_idc, level_idc, constraint_set_flags = 0;
     unsigned int sps_id;
-    int i;
+    int i, log2_max_frame_num_minus4;
     SPS *sps;
 
-    profile_idc= get_bits(&s->gb, 8);
-    constraint_set_flags |= get_bits1(&s->gb) << 0;   //constraint_set0_flag
-    constraint_set_flags |= get_bits1(&s->gb) << 1;   //constraint_set1_flag
-    constraint_set_flags |= get_bits1(&s->gb) << 2;   //constraint_set2_flag
-    constraint_set_flags |= get_bits1(&s->gb) << 3;   //constraint_set3_flag
-    constraint_set_flags |= get_bits1(&s->gb) << 4;   //constraint_set4_flag
-    constraint_set_flags |= get_bits1(&s->gb) << 5;   //constraint_set5_flag
-    get_bits(&s->gb, 2); // reserved
-    level_idc= get_bits(&s->gb, 8);
-    sps_id= get_ue_golomb_31(&s->gb);
+    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);
 
     if(sps_id >= MAX_SPS_COUNT) {
-        av_log(h->s.avctx, AV_LOG_ERROR, "sps_id (%d) out of range\n", sps_id);
+        av_log(h->avctx, AV_LOG_ERROR, "sps_id (%d) out of range\n", sps_id);
         return -1;
     }
     sps= av_mallocz(sizeof(SPS));
@@ -364,29 +361,30 @@
     sps->scaling_matrix_present = 0;
     sps->colorspace = 2; //AVCOL_SPC_UNSPECIFIED
 
-    if(sps->profile_idc == 100 || sps->profile_idc == 110 ||
-       sps->profile_idc == 122 || sps->profile_idc == 244 || 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(&s->gb);
+    if (sps->profile_idc == 100 || sps->profile_idc == 110 ||
+        sps->profile_idc == 122 || sps->profile_idc == 244 ||
+        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);
         if (sps->chroma_format_idc > 3U) {
-            av_log(h->s.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) {
-            sps->residual_color_transform_flag = get_bits1(&s->gb);
+            sps->residual_color_transform_flag = get_bits1(&h->gb);
             if(sps->residual_color_transform_flag) {
-                av_log(h->s.avctx, AV_LOG_ERROR, "separate color planes are not supported\n");
+                av_log(h->avctx, AV_LOG_ERROR, "separate color planes are not supported\n");
                 goto fail;
             }
         }
-        sps->bit_depth_luma   = get_ue_golomb(&s->gb) + 8;
-        sps->bit_depth_chroma = get_ue_golomb(&s->gb) + 8;
-        if (sps->bit_depth_luma > 14U || sps->bit_depth_chroma > 14U) {
-            av_log(h->s.avctx, AV_LOG_ERROR, "illegal bit depth value (%d, %d)\n",
+        sps->bit_depth_luma   = get_ue_golomb(&h->gb) + 8;
+        sps->bit_depth_chroma = get_ue_golomb(&h->gb) + 8;
+        if (sps->bit_depth_luma > 14U || sps->bit_depth_chroma > 14U || sps->bit_depth_luma != sps->bit_depth_chroma) {
+            av_log(h->avctx, AV_LOG_ERROR, "illegal bit depth value (%d, %d)\n",
                    sps->bit_depth_luma, sps->bit_depth_chroma);
             goto fail;
         }
-        sps->transform_bypass = get_bits1(&s->gb);
+        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;
@@ -394,81 +392,98 @@
         sps->bit_depth_chroma = 8;
     }
 
-    sps->log2_max_frame_num= get_ue_golomb(&s->gb) + 4;
-    if (sps->log2_max_frame_num < 4 || sps->log2_max_frame_num > 16) {
-        av_log(h->s.avctx, AV_LOG_ERROR, "illegal log2_max_frame_num %d\n",
-               sps->log2_max_frame_num);
+    log2_max_frame_num_minus4 = get_ue_golomb(&h->gb);
+    if (log2_max_frame_num_minus4 < MIN_LOG2_MAX_FRAME_NUM - 4 ||
+        log2_max_frame_num_minus4 > MAX_LOG2_MAX_FRAME_NUM - 4) {
+        av_log(h->avctx, AV_LOG_ERROR,
+               "log2_max_frame_num_minus4 out of range (0-12): %d\n",
+               log2_max_frame_num_minus4);
         goto fail;
     }
+    sps->log2_max_frame_num = log2_max_frame_num_minus4 + 4;
 
-    sps->poc_type= get_ue_golomb_31(&s->gb);
+    sps->poc_type= get_ue_golomb_31(&h->gb);
 
     if(sps->poc_type == 0){ //FIXME #define
-        unsigned t = get_ue_golomb(&s->gb);
+        unsigned t = get_ue_golomb(&h->gb);
         if(t>12){
-            av_log(h->s.avctx, AV_LOG_ERROR, "log2_max_poc_lsb (%d) is out of range\n", t);
+            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(&s->gb);
-        sps->offset_for_non_ref_pic= get_se_golomb(&s->gb);
-        sps->offset_for_top_to_bottom_field= get_se_golomb(&s->gb);
-        sps->poc_cycle_length                = get_ue_golomb(&s->gb);
+        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->s.avctx, AV_LOG_ERROR, "poc_cycle_length overflow %u\n", sps->poc_cycle_length);
+            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(&s->gb);
+            sps->offset_for_ref_frame[i]= get_se_golomb(&h->gb);
     }else if(sps->poc_type != 2){
-        av_log(h->s.avctx, AV_LOG_ERROR, "illegal POC type %d\n", sps->poc_type);
+        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(&s->gb);
-    if (h->s.avctx->codec_tag == MKTAG('S', 'M', 'V', '2'))
+    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){
-        av_log(h->s.avctx, AV_LOG_ERROR, "too many reference frames\n");
+        av_log(h->avctx, AV_LOG_ERROR, "too many reference frames\n");
         goto fail;
     }
-    sps->gaps_in_frame_num_allowed_flag= get_bits1(&s->gb);
-    sps->mb_width = get_ue_golomb(&s->gb) + 1;
-    sps->mb_height= get_ue_golomb(&s->gb) + 1;
+    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->s.avctx)){
-        av_log(h->s.avctx, AV_LOG_ERROR, "mb_width/height overflow\n");
+       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(&s->gb);
+    sps->frame_mbs_only_flag= get_bits1(&h->gb);
     if(!sps->frame_mbs_only_flag)
-        sps->mb_aff= get_bits1(&s->gb);
+        sps->mb_aff= get_bits1(&h->gb);
     else
         sps->mb_aff= 0;
 
-    sps->direct_8x8_inference_flag= get_bits1(&s->gb);
+    sps->direct_8x8_inference_flag= get_bits1(&h->gb);
 
 #ifndef ALLOW_INTERLACE
     if(sps->mb_aff)
-        av_log(h->s.avctx, AV_LOG_ERROR, "MBAFF support not included; enable it at compile-time.\n");
+        av_log(h->avctx, AV_LOG_ERROR, "MBAFF support not included; enable it at compile-time.\n");
 #endif
-    sps->crop= get_bits1(&s->gb);
+    sps->crop= get_bits1(&h->gb);
     if(sps->crop){
         int crop_vertical_limit   = sps->chroma_format_idc  & 2 ? 16 : 8;
         int crop_horizontal_limit = sps->chroma_format_idc == 3 ? 16 : 8;
-        sps->crop_left  = get_ue_golomb(&s->gb);
-        sps->crop_right = get_ue_golomb(&s->gb);
-        sps->crop_top   = get_ue_golomb(&s->gb);
-        sps->crop_bottom= get_ue_golomb(&s->gb);
+        sps->crop_left  = get_ue_golomb(&h->gb);
+        sps->crop_right = get_ue_golomb(&h->gb);
+        sps->crop_top   = get_ue_golomb(&h->gb);
+        sps->crop_bottom= get_ue_golomb(&h->gb);
+        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",
+                   sps->crop_left,
+                   sps->crop_right,
+                   sps->crop_top,
+                   sps->crop_bottom);
+
+            sps->crop_left   =
+            sps->crop_right  =
+            sps->crop_top    =
+            sps->crop_bottom = 0;
+        }
         if(sps->crop_left || sps->crop_top){
-            av_log(h->s.avctx, AV_LOG_ERROR, "insane cropping not completely supported, this could look slightly wrong ... (left: %d, top: %d)\n", sps->crop_left, sps->crop_top);
+            av_log(h->avctx, AV_LOG_ERROR, "insane cropping not completely supported, this could look slightly wrong ... (left: %d, top: %d)\n", sps->crop_left, sps->crop_top);
         }
         if(sps->crop_right >= crop_horizontal_limit || sps->crop_bottom >= crop_vertical_limit){
-            av_log(h->s.avctx, AV_LOG_ERROR, "brainfart cropping not supported, cropping disabled (right: %d, bottom: %d)\n", sps->crop_right, sps->crop_bottom);
+            av_log(h->avctx, AV_LOG_ERROR, "brainfart cropping not supported, cropping disabled (right: %d, bottom: %d)\n", sps->crop_right, sps->crop_bottom);
         /* It is very unlikely that partial cropping will make anybody happy.
          * Not cropping at all fixes for example playback of Sisvel 3D streams
          * in applications supporting Sisvel 3D. */
@@ -484,7 +499,7 @@
         sps->crop_bottom= 0;
     }
 
-    sps->vui_parameters_present_flag= get_bits1(&s->gb);
+    sps->vui_parameters_present_flag= get_bits1(&h->gb);
     if( sps->vui_parameters_present_flag )
         if (decode_vui_parameters(h, sps) < 0)
             goto fail;
@@ -492,9 +507,9 @@
     if(!sps->sar.den)
         sps->sar.den= 1;
 
-    if(s->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->s.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,
@@ -511,10 +526,13 @@
                h->sps.bitstream_restriction_flag ? sps->num_reorder_frames : -1
                );
     }
+    sps->new = 1;
 
     av_free(h->sps_buffers[sps_id]);
-    h->sps_buffers[sps_id]= sps;
-    h->sps = *sps;
+    h->sps_buffers[sps_id] = sps;
+    h->sps                 = *sps;
+    h->current_sps_id      = sps_id;
+
     return 0;
 fail:
     av_free(sps);
@@ -537,7 +555,7 @@
 
     if ((profile_idc == 66 || profile_idc == 77 ||
          profile_idc == 88) && (sps->constraint_set_flags & 7)) {
-        av_log(h->s.avctx, AV_LOG_VERBOSE,
+        av_log(h->avctx, AV_LOG_VERBOSE,
                "Current profile doesn't provide more RBSP data in PPS, skipping\n");
         return 0;
     }
@@ -546,38 +564,37 @@
 }
 
 int ff_h264_decode_picture_parameter_set(H264Context *h, int bit_length){
-    MpegEncContext * const s = &h->s;
-    unsigned int pps_id= get_ue_golomb(&s->gb);
+    unsigned int pps_id= get_ue_golomb(&h->gb);
     PPS *pps;
     const int qp_bd_offset = 6*(h->sps.bit_depth_luma-8);
     int bits_left;
 
     if(pps_id >= MAX_PPS_COUNT) {
-        av_log(h->s.avctx, AV_LOG_ERROR, "pps_id (%d) out of range\n", pps_id);
+        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->s.avctx, AV_LOG_ERROR, "Invalid luma bit depth=%d\n", h->sps.bit_depth_luma);
+        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->s.avctx, AV_LOG_ERROR, "Unimplemented luma bit depth=%d\n", h->sps.bit_depth_luma);
+        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(&s->gb);
+    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->s.avctx, AV_LOG_ERROR, "sps_id out of range\n");
+        av_log(h->avctx, AV_LOG_ERROR, "sps_id out of range\n");
         goto fail;
     }
 
-    pps->cabac= get_bits1(&s->gb);
-    pps->pic_order_present= get_bits1(&s->gb);
-    pps->slice_group_count= get_ue_golomb(&s->gb) + 1;
+    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(&s->gb);
-        av_log(h->s.avctx, AV_LOG_ERROR, "FMO not supported\n");
+        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){
         case 0:
 #if 0
@@ -612,32 +629,32 @@
             break;
         }
     }
-    pps->ref_count[0]= get_ue_golomb(&s->gb) + 1;
-    pps->ref_count[1]= get_ue_golomb(&s->gb) + 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->s.avctx, AV_LOG_ERROR, "reference overflow (pps)\n");
+        av_log(h->avctx, AV_LOG_ERROR, "reference overflow (pps)\n");
         goto fail;
     }
 
-    pps->weighted_pred= get_bits1(&s->gb);
-    pps->weighted_bipred_idc= get_bits(&s->gb, 2);
-    pps->init_qp= get_se_golomb(&s->gb) + 26 + qp_bd_offset;
-    pps->init_qs= get_se_golomb(&s->gb) + 26 + qp_bd_offset;
-    pps->chroma_qp_index_offset[0]= get_se_golomb(&s->gb);
-    pps->deblocking_filter_parameters_present= get_bits1(&s->gb);
-    pps->constrained_intra_pred= get_bits1(&s->gb);
-    pps->redundant_pic_cnt_present = get_bits1(&s->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));
 
-    bits_left = bit_length - get_bits_count(&s->gb);
+    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(&s->gb);
+        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(&s->gb); //second_chroma_qp_index_offset
+        pps->chroma_qp_index_offset[1]= get_se_golomb(&h->gb); //second_chroma_qp_index_offset
     } else {
         pps->chroma_qp_index_offset[1]= pps->chroma_qp_index_offset[0];
     }
@@ -647,8 +664,8 @@
     if(pps->chroma_qp_index_offset[0] != pps->chroma_qp_index_offset[1])
         pps->chroma_qp_diff= 1;
 
-    if(s->avctx->debug&FF_DEBUG_PICT_INFO){
-        av_log(h->s.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,
diff --git a/libavcodec/h264_refs.c b/libavcodec/h264_refs.c
index 812913a..d87106e 100644
--- a/libavcodec/h264_refs.c
+++ b/libavcodec/h264_refs.c
@@ -27,7 +27,6 @@
 
 #include "libavutil/avassert.h"
 #include "internal.h"
-#include "dsputil.h"
 #include "avcodec.h"
 #include "h264.h"
 #include "golomb.h"
@@ -107,7 +106,6 @@
 }
 
 int ff_h264_fill_default_ref_list(H264Context *h){
-    MpegEncContext * const s = &h->s;
     int i, len;
 
     if(h->slice_type_nos==AV_PICTURE_TYPE_B){
@@ -116,16 +114,16 @@
         int lens[2];
 
         if(FIELD_PICTURE)
-            cur_poc= s->current_picture_ptr->field_poc[ s->picture_structure == PICT_BOTTOM_FIELD ];
+            cur_poc= h->cur_pic_ptr->field_poc[h->picture_structure == PICT_BOTTOM_FIELD];
         else
-            cur_poc= s->current_picture_ptr->poc;
+            cur_poc= h->cur_pic_ptr->poc;
 
         for(list= 0; list<2; list++){
             len= add_sorted(sorted    , h->short_ref, h->short_ref_count, cur_poc, 1^list);
             len+=add_sorted(sorted+len, h->short_ref, h->short_ref_count, cur_poc, 0^list);
             av_assert0(len<=32);
-            len= build_def_list(h->default_ref_list[list]    , sorted     , len, 0, s->picture_structure);
-            len+=build_def_list(h->default_ref_list[list]+len, h->long_ref, 16 , 1, s->picture_structure);
+            len= build_def_list(h->default_ref_list[list]    , sorted     , len, 0, h->picture_structure);
+            len+=build_def_list(h->default_ref_list[list]+len, h->long_ref, 16 , 1, h->picture_structure);
             av_assert0(len<=32);
 
             if(len < h->ref_count[list])
@@ -139,19 +137,19 @@
                 FFSWAP(Picture, h->default_ref_list[1][0], h->default_ref_list[1][1]);
         }
     }else{
-        len = build_def_list(h->default_ref_list[0]    , h->short_ref, h->short_ref_count, 0, s->picture_structure);
-        len+= build_def_list(h->default_ref_list[0]+len, h-> long_ref, 16                , 1, s->picture_structure);
+        len = build_def_list(h->default_ref_list[0]    , h->short_ref, h->short_ref_count, 0, h->picture_structure);
+        len+= build_def_list(h->default_ref_list[0]+len, h-> long_ref, 16                , 1, h->picture_structure);
         av_assert0(len<=32);
         if(len < h->ref_count[0])
             memset(&h->default_ref_list[0][len], 0, sizeof(Picture)*(h->ref_count[0] - len));
     }
 #ifdef TRACE
     for (i=0; i<h->ref_count[0]; i++) {
-        tprintf(h->s.avctx, "List0: %s fn:%d 0x%p\n", (h->default_ref_list[0][i].long_ref ? "LT" : "ST"), h->default_ref_list[0][i].pic_id, h->default_ref_list[0][i].f.data[0]);
+        tprintf(h->avctx, "List0: %s fn:%d 0x%p\n", (h->default_ref_list[0][i].long_ref ? "LT" : "ST"), h->default_ref_list[0][i].pic_id, h->default_ref_list[0][i].f.data[0]);
     }
     if(h->slice_type_nos==AV_PICTURE_TYPE_B){
         for (i=0; i<h->ref_count[1]; i++) {
-            tprintf(h->s.avctx, "List1: %s fn:%d 0x%p\n", (h->default_ref_list[1][i].long_ref ? "LT" : "ST"), h->default_ref_list[1][i].pic_id, h->default_ref_list[1][i].f.data[0]);
+            tprintf(h->avctx, "List1: %s fn:%d 0x%p\n", (h->default_ref_list[1][i].long_ref ? "LT" : "ST"), h->default_ref_list[1][i].pic_id, h->default_ref_list[1][i].f.data[0]);
         }
     }
 #endif
@@ -172,9 +170,7 @@
  *         described by pic_num
  */
 static int pic_num_extract(H264Context *h, int pic_num, int *structure){
-    MpegEncContext * const s = &h->s;
-
-    *structure = s->picture_structure;
+    *structure = h->picture_structure;
     if(FIELD_PICTURE){
         if (!(pic_num & 1))
             /* opposite field */
@@ -186,7 +182,6 @@
 }
 
 int ff_h264_decode_ref_pic_list_reordering(H264Context *h){
-    MpegEncContext * const s = &h->s;
     int list, index, pic_structure;
 
     print_short_term(h);
@@ -195,11 +190,11 @@
     for(list=0; list<h->list_count; list++){
         memcpy(h->ref_list[list], h->default_ref_list[list], sizeof(Picture)*h->ref_count[list]);
 
-        if(get_bits1(&s->gb)){
+        if(get_bits1(&h->gb)){
             int pred= h->curr_pic_num;
 
             for(index=0; ; index++){
-                unsigned int reordering_of_pic_nums_idc= get_ue_golomb_31(&s->gb);
+                unsigned int reordering_of_pic_nums_idc= get_ue_golomb_31(&h->gb);
                 unsigned int pic_id;
                 int i;
                 Picture *ref = NULL;
@@ -208,17 +203,17 @@
                     break;
 
                 if(index >= h->ref_count[list]){
-                    av_log(h->s.avctx, AV_LOG_ERROR, "reference count overflow\n");
+                    av_log(h->avctx, AV_LOG_ERROR, "reference count overflow\n");
                     return -1;
                 }
 
                 if(reordering_of_pic_nums_idc<3){
                     if(reordering_of_pic_nums_idc<2){
-                        const unsigned int abs_diff_pic_num= get_ue_golomb(&s->gb) + 1;
+                        const unsigned int abs_diff_pic_num= get_ue_golomb(&h->gb) + 1;
                         int frame_num;
 
                         if(abs_diff_pic_num > h->max_pic_num){
-                            av_log(h->s.avctx, AV_LOG_ERROR, "abs_diff_pic_num overflow\n");
+                            av_log(h->avctx, AV_LOG_ERROR, "abs_diff_pic_num overflow\n");
                             return -1;
                         }
 
@@ -242,12 +237,12 @@
                             ref->pic_id= pred;
                     }else{
                         int long_idx;
-                        pic_id= get_ue_golomb(&s->gb); //long_term_pic_idx
+                        pic_id= get_ue_golomb(&h->gb); //long_term_pic_idx
 
                         long_idx= pic_num_extract(h, pic_id, &pic_structure);
 
                         if(long_idx>31){
-                            av_log(h->s.avctx, AV_LOG_ERROR, "long_term_pic_idx overflow\n");
+                            av_log(h->avctx, AV_LOG_ERROR, "long_term_pic_idx overflow\n");
                             return -1;
                         }
                         ref = h->long_ref[long_idx];
@@ -262,7 +257,7 @@
                     }
 
                     if (i < 0) {
-                        av_log(h->s.avctx, AV_LOG_ERROR, "reference picture missing during reorder\n");
+                        av_log(h->avctx, AV_LOG_ERROR, "reference picture missing during reorder\n");
                         memset(&h->ref_list[list][index], 0, sizeof(Picture)); //FIXME
                     } else {
                         for(i=index; i+1<h->ref_count[list]; i++){
@@ -278,7 +273,7 @@
                         }
                     }
                 }else{
-                    av_log(h->s.avctx, AV_LOG_ERROR, "illegal reordering_of_pic_nums_idc\n");
+                    av_log(h->avctx, AV_LOG_ERROR, "illegal reordering_of_pic_nums_idc\n");
                     return -1;
                 }
             }
@@ -287,7 +282,10 @@
     for(list=0; list<h->list_count; list++){
         for(index= 0; index < h->ref_count[list]; index++){
             if (!h->ref_list[list][index].f.data[0]) {
-                av_log(h->s.avctx, AV_LOG_ERROR, "Missing reference picture, default is %d\n", h->default_ref_list[list][0].poc);
+                int i;
+                av_log(h->avctx, AV_LOG_ERROR, "Missing reference picture, default is %d\n", h->default_ref_list[list][0].poc);
+                for (i=0; i<FF_ARRAY_ELEMS(h->last_pocs); i++)
+                    h->last_pocs[i] = INT_MIN;
                 if (h->default_ref_list[list][0].f.data[0])
                     h->ref_list[list][index]= h->default_ref_list[list][0];
                 else
@@ -360,13 +358,12 @@
  *                 frame number is found
  */
 static Picture * find_short(H264Context *h, int frame_num, int *idx){
-    MpegEncContext * const s = &h->s;
     int i;
 
     for(i=0; i<h->short_ref_count; i++){
         Picture *pic= h->short_ref[i];
-        if(s->avctx->debug&FF_DEBUG_MMCO)
-            av_log(h->s.avctx, AV_LOG_DEBUG, "%d %d %p\n", i, pic->frame_num, pic);
+        if(h->avctx->debug&FF_DEBUG_MMCO)
+            av_log(h->avctx, AV_LOG_DEBUG, "%d %d %p\n", i, pic->frame_num, pic);
         if(pic->frame_num == frame_num) {
             *idx = i;
             return pic;
@@ -393,12 +390,11 @@
  * @return the removed picture or NULL if an error occurs
  */
 static Picture * remove_short(H264Context *h, int frame_num, int ref_mask){
-    MpegEncContext * const s = &h->s;
     Picture *pic;
     int i;
 
-    if(s->avctx->debug&FF_DEBUG_MMCO)
-        av_log(h->s.avctx, AV_LOG_DEBUG, "remove short %d count %d\n", frame_num, h->short_ref_count);
+    if(h->avctx->debug&FF_DEBUG_MMCO)
+        av_log(h->avctx, AV_LOG_DEBUG, "remove short %d count %d\n", frame_num, h->short_ref_count);
 
     pic = find_short(h, frame_num, &i);
     if (pic){
@@ -453,11 +449,11 @@
  */
 static void print_short_term(H264Context *h) {
     uint32_t i;
-    if(h->s.avctx->debug&FF_DEBUG_MMCO) {
-        av_log(h->s.avctx, AV_LOG_DEBUG, "short term list:\n");
+    if(h->avctx->debug&FF_DEBUG_MMCO) {
+        av_log(h->avctx, AV_LOG_DEBUG, "short term list:\n");
         for(i=0; i<h->short_ref_count; i++){
             Picture *pic= h->short_ref[i];
-            av_log(h->s.avctx, AV_LOG_DEBUG, "%d fn:%d poc:%d %p\n",
+            av_log(h->avctx, AV_LOG_DEBUG, "%d fn:%d poc:%d %p\n",
                    i, pic->frame_num, pic->poc, pic->f.data[0]);
         }
     }
@@ -468,49 +464,77 @@
  */
 static void print_long_term(H264Context *h) {
     uint32_t i;
-    if(h->s.avctx->debug&FF_DEBUG_MMCO) {
-        av_log(h->s.avctx, AV_LOG_DEBUG, "long term list:\n");
+    if(h->avctx->debug&FF_DEBUG_MMCO) {
+        av_log(h->avctx, AV_LOG_DEBUG, "long term list:\n");
         for(i = 0; i < 16; i++){
             Picture *pic= h->long_ref[i];
             if (pic) {
-                av_log(h->s.avctx, AV_LOG_DEBUG, "%d fn:%d poc:%d %p\n",
+                av_log(h->avctx, AV_LOG_DEBUG, "%d fn:%d poc:%d %p\n",
                        i, pic->frame_num, pic->poc, pic->f.data[0]);
             }
         }
     }
 }
 
-void ff_generate_sliding_window_mmcos(H264Context *h) {
-    MpegEncContext * const s = &h->s;
+static int check_opcodes(MMCO *mmco1, MMCO *mmco2, int n_mmcos)
+{
+    int i;
 
-    h->mmco_index= 0;
-    if(h->short_ref_count && h->long_ref_count + h->short_ref_count >= h->sps.ref_frame_count &&
-            !(FIELD_PICTURE && !s->first_field && s->current_picture_ptr->f.reference)) {
-        h->mmco[0].opcode= MMCO_SHORT2UNUSED;
-        h->mmco[0].short_pic_num= h->short_ref[ h->short_ref_count - 1 ]->frame_num;
-        h->mmco_index= 1;
-        if (FIELD_PICTURE) {
-            h->mmco[0].short_pic_num *= 2;
-            h->mmco[1].opcode= MMCO_SHORT2UNUSED;
-            h->mmco[1].short_pic_num= h->mmco[0].short_pic_num + 1;
-            h->mmco_index= 2;
+    for (i = 0; i < n_mmcos; i++) {
+        if (mmco1[i].opcode != mmco2[i].opcode) {
+            av_log(NULL, AV_LOG_ERROR, "MMCO opcode [%d, %d] at %d mismatches between slices\n",
+                   mmco1[i].opcode, mmco2[i].opcode, i);
+            return -1;
         }
     }
+
+    return 0;
+}
+
+int ff_generate_sliding_window_mmcos(H264Context *h, int first_slice)
+{
+    MMCO mmco_temp[MAX_MMCO_COUNT], *mmco = first_slice ? h->mmco : mmco_temp;
+    int mmco_index = 0, i;
+
+    if (h->short_ref_count &&
+        h->long_ref_count + h->short_ref_count >= h->sps.ref_frame_count &&
+        !(FIELD_PICTURE && !h->first_field && h->cur_pic_ptr->f.reference)) {
+        mmco[0].opcode = MMCO_SHORT2UNUSED;
+        mmco[0].short_pic_num = h->short_ref[h->short_ref_count - 1]->frame_num;
+        mmco_index = 1;
+        if (FIELD_PICTURE) {
+            mmco[0].short_pic_num *= 2;
+            mmco[1].opcode = MMCO_SHORT2UNUSED;
+            mmco[1].short_pic_num = mmco[0].short_pic_num + 1;
+            mmco_index = 2;
+        }
+    }
+
+    if (first_slice) {
+        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)))) {
+        av_log(h->avctx, AV_LOG_ERROR,
+               "Inconsistent MMCO state between slices [%d, %d]\n",
+               mmco_index, h->mmco_index);
+        return AVERROR_INVALIDDATA;
+    }
+    return 0;
 }
 
 int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){
-    MpegEncContext * const s = &h->s;
     int i, av_uninit(j);
     int current_ref_assigned=0, err=0;
     Picture *av_uninit(pic);
 
-    if((s->avctx->debug&FF_DEBUG_MMCO) && mmco_count==0)
-        av_log(h->s.avctx, AV_LOG_DEBUG, "no mmco here\n");
+    if((h->avctx->debug&FF_DEBUG_MMCO) && mmco_count==0)
+        av_log(h->avctx, AV_LOG_DEBUG, "no mmco here\n");
 
     for(i=0; i<mmco_count; i++){
         int av_uninit(structure), av_uninit(frame_num);
-        if(s->avctx->debug&FF_DEBUG_MMCO)
-            av_log(h->s.avctx, AV_LOG_DEBUG, "mmco:%d %d %d\n", h->mmco[i].opcode, h->mmco[i].short_pic_num, h->mmco[i].long_arg);
+        if(h->avctx->debug&FF_DEBUG_MMCO)
+            av_log(h->avctx, AV_LOG_DEBUG, "mmco:%d %d %d\n", h->mmco[i].opcode, h->mmco[i].short_pic_num, h->mmco[i].long_arg);
 
         if(   mmco[i].opcode == MMCO_SHORT2UNUSED
            || mmco[i].opcode == MMCO_SHORT2LONG){
@@ -519,7 +543,7 @@
             if(!pic){
                 if(mmco[i].opcode != MMCO_SHORT2LONG || !h->long_ref[mmco[i].long_arg]
                    || h->long_ref[mmco[i].long_arg]->frame_num != frame_num) {
-                    av_log(h->s.avctx, AV_LOG_ERROR, "mmco: unref short failure\n");
+                    av_log(h->avctx, AV_LOG_ERROR, "mmco: unref short failure\n");
                     err = AVERROR_INVALIDDATA;
                 }
                 continue;
@@ -528,8 +552,8 @@
 
         switch(mmco[i].opcode){
         case MMCO_SHORT2UNUSED:
-            if(s->avctx->debug&FF_DEBUG_MMCO)
-                av_log(h->s.avctx, AV_LOG_DEBUG, "mmco: unref short %d count %d\n", h->mmco[i].short_pic_num, h->short_ref_count);
+            if(h->avctx->debug&FF_DEBUG_MMCO)
+                av_log(h->avctx, AV_LOG_DEBUG, "mmco: unref short %d count %d\n", h->mmco[i].short_pic_num, h->short_ref_count);
             remove_short(h, frame_num, structure ^ PICT_FRAME);
             break;
         case MMCO_SHORT2LONG:
@@ -548,8 +572,8 @@
             pic = h->long_ref[j];
             if (pic) {
                 remove_long(h, j, structure ^ PICT_FRAME);
-            } else if(s->avctx->debug&FF_DEBUG_MMCO)
-                av_log(h->s.avctx, AV_LOG_DEBUG, "mmco: unref long failure\n");
+            } else if(h->avctx->debug&FF_DEBUG_MMCO)
+                av_log(h->avctx, AV_LOG_DEBUG, "mmco: unref long failure\n");
             break;
         case MMCO_LONG:
                     // Comment below left from previous code as it is an interresting note.
@@ -560,15 +584,15 @@
                      * and mark this field valid.
                      */
 
-            if (h->long_ref[mmco[i].long_arg] != s->current_picture_ptr) {
+            if (h->long_ref[mmco[i].long_arg] != h->cur_pic_ptr) {
                 remove_long(h, mmco[i].long_arg, 0);
 
-                h->long_ref[ mmco[i].long_arg ]= s->current_picture_ptr;
+                h->long_ref[ mmco[i].long_arg ]= h->cur_pic_ptr;
                 h->long_ref[ mmco[i].long_arg ]->long_ref=1;
                 h->long_ref_count++;
             }
 
-            s->current_picture_ptr->f.reference |= s->picture_structure;
+            h->cur_pic_ptr->f.reference |= h->picture_structure;
             current_ref_assigned=1;
             break;
         case MMCO_SET_MAX_LONG:
@@ -586,9 +610,9 @@
                 remove_long(h, j, 0);
             }
             h->frame_num=
-            s->current_picture_ptr->frame_num= 0;
+            h->cur_pic_ptr->frame_num= 0;
             h->mmco_reset = 1;
-            s->current_picture_ptr->mmco_reset=1;
+            h->cur_pic_ptr->mmco_reset=1;
             for (j = 0; j < MAX_DELAYED_PIC_COUNT; j++)
                 h->last_pocs[j] = INT_MIN;
             break;
@@ -603,28 +627,28 @@
          * in long_ref; trying to put it on the short list here is an
          * error in the encoded bit stream (ref: 7.4.3.3, NOTE 2 and 3).
          */
-        if (h->short_ref_count && h->short_ref[0] == s->current_picture_ptr) {
+        if (h->short_ref_count && h->short_ref[0] == h->cur_pic_ptr) {
             /* Just mark the second field valid */
-            s->current_picture_ptr->f.reference = PICT_FRAME;
-        } else if (s->current_picture_ptr->long_ref) {
-            av_log(h->s.avctx, AV_LOG_ERROR, "illegal short term reference "
-                                             "assignment for second field "
-                                             "in complementary field pair "
-                                             "(first field is long term)\n");
+            h->cur_pic_ptr->f.reference = PICT_FRAME;
+        } else if (h->cur_pic_ptr->long_ref) {
+            av_log(h->avctx, AV_LOG_ERROR, "illegal short term reference "
+                                           "assignment for second field "
+                                           "in complementary field pair "
+                                           "(first field is long term)\n");
             err = AVERROR_INVALIDDATA;
         } else {
-            pic= remove_short(h, s->current_picture_ptr->frame_num, 0);
+            pic= remove_short(h, h->cur_pic_ptr->frame_num, 0);
             if(pic){
-                av_log(h->s.avctx, AV_LOG_ERROR, "illegal short term buffer state detected\n");
+                av_log(h->avctx, AV_LOG_ERROR, "illegal short term buffer state detected\n");
                 err = AVERROR_INVALIDDATA;
             }
 
             if(h->short_ref_count)
                 memmove(&h->short_ref[1], &h->short_ref[0], h->short_ref_count*sizeof(Picture*));
 
-            h->short_ref[0]= s->current_picture_ptr;
+            h->short_ref[0]= h->cur_pic_ptr;
             h->short_ref_count++;
-            s->current_picture_ptr->f.reference |= s->picture_structure;
+            h->cur_pic_ptr->f.reference |= h->picture_structure;
         }
     }
 
@@ -634,7 +658,7 @@
          * stream. Need to discard one frame. Prevents overrun of the
          * short_ref and long_ref buffers.
          */
-        av_log(h->s.avctx, AV_LOG_ERROR,
+        av_log(h->avctx, AV_LOG_ERROR,
                "number of reference frames (%d+%d) exceeds max (%d; probably "
                "corrupt input), discarding one\n",
                h->long_ref_count, h->short_ref_count, h->sps.ref_frame_count);
@@ -656,61 +680,94 @@
     print_short_term(h);
     print_long_term(h);
 
-    if(err >= 0 && h->long_ref_count==0 && h->short_ref_count<=2 && h->pps.ref_count[0]<=1 + (s->picture_structure != PICT_FRAME) && s->current_picture_ptr->f.pict_type == AV_PICTURE_TYPE_I){
-        s->current_picture_ptr->sync |= 1;
-        if(!h->s.avctx->has_b_frames)
+    if(err >= 0 && h->long_ref_count==0 && h->short_ref_count<=2 && h->pps.ref_count[0]<=1 + (h->picture_structure != PICT_FRAME) && h->cur_pic_ptr->f.pict_type == AV_PICTURE_TYPE_I){
+        h->cur_pic_ptr->sync |= 1;
+        if(!h->avctx->has_b_frames)
             h->sync = 2;
     }
 
-    return (h->s.avctx->err_recognition & AV_EF_EXPLODE) ? err : 0;
+    return (h->avctx->err_recognition & AV_EF_EXPLODE) ? err : 0;
 }
 
-int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb){
-    MpegEncContext * const s = &h->s;
-    int i;
+int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb,
+                                   int first_slice)
+{
+    int i, ret;
+    MMCO mmco_temp[MAX_MMCO_COUNT], *mmco = first_slice ? h->mmco : mmco_temp;
+    int mmco_index = 0;
 
-    h->mmco_index= 0;
-    if(h->nal_unit_type == NAL_IDR_SLICE){ //FIXME fields
-        s->broken_link= get_bits1(gb) -1;
-        if(get_bits1(gb)){
-            h->mmco[0].opcode= MMCO_LONG;
-            h->mmco[0].long_arg= 0;
-            h->mmco_index= 1;
+    if (h->nal_unit_type == NAL_IDR_SLICE){ // FIXME fields
+        skip_bits1(gb); // broken_link
+        if (get_bits1(gb)){
+            mmco[0].opcode = MMCO_LONG;
+            mmco[0].long_arg = 0;
+            mmco_index = 1;
         }
-    }else{
-        if(get_bits1(gb)){ // adaptive_ref_pic_marking_mode_flag
-            for(i= 0; i<MAX_MMCO_COUNT; i++) {
-                MMCOOpcode opcode= get_ue_golomb_31(gb);
+    } else {
+        if (get_bits1(gb)) { // adaptive_ref_pic_marking_mode_flag
+            for (i = 0; i < MAX_MMCO_COUNT; i++) {
+                MMCOOpcode opcode = get_ue_golomb_31(gb);
 
-                h->mmco[i].opcode= opcode;
-                if(opcode==MMCO_SHORT2UNUSED || opcode==MMCO_SHORT2LONG){
-                    h->mmco[i].short_pic_num= (h->curr_pic_num - get_ue_golomb(gb) - 1) & (h->max_pic_num - 1);
-/*                    if(h->mmco[i].short_pic_num >= h->short_ref_count || h->short_ref[ h->mmco[i].short_pic_num ] == NULL){
-                        av_log(s->avctx, AV_LOG_ERROR, "illegal short ref in memory management control operation %d\n", mmco);
-                        return -1;
-                    }*/
-                }
-                if(opcode==MMCO_SHORT2LONG || opcode==MMCO_LONG2UNUSED || opcode==MMCO_LONG || opcode==MMCO_SET_MAX_LONG){
-                    unsigned int long_arg= get_ue_golomb_31(gb);
-                    if(long_arg >= 32 || (long_arg >= 16 && !(opcode == MMCO_SET_MAX_LONG && long_arg == 16) && !(opcode == MMCO_LONG2UNUSED && FIELD_PICTURE))){
-                        av_log(h->s.avctx, AV_LOG_ERROR, "illegal long ref in memory management control operation %d\n", opcode);
+                mmco[i].opcode = opcode;
+                if (opcode == MMCO_SHORT2UNUSED || opcode == MMCO_SHORT2LONG){
+                    mmco[i].short_pic_num =
+                        (h->curr_pic_num - get_ue_golomb(gb) - 1) &
+                            (h->max_pic_num - 1);
+#if 0
+                    if (mmco[i].short_pic_num >= h->short_ref_count ||
+                        h->short_ref[ mmco[i].short_pic_num ] == NULL){
+                        av_log(s->avctx, AV_LOG_ERROR,
+                               "illegal short ref in memory management control "
+                               "operation %d\n", mmco);
                         return -1;
                     }
-                    h->mmco[i].long_arg= long_arg;
+#endif
+                }
+                if (opcode == MMCO_SHORT2LONG || opcode == MMCO_LONG2UNUSED ||
+                    opcode == MMCO_LONG || opcode == MMCO_SET_MAX_LONG) {
+                    unsigned int long_arg = get_ue_golomb_31(gb);
+                    if (long_arg >= 32 ||
+                        (long_arg >= 16 && !(opcode == MMCO_SET_MAX_LONG &&
+                                             long_arg == 16) &&
+                         !(opcode == MMCO_LONG2UNUSED && FIELD_PICTURE))){
+                        av_log(h->avctx, AV_LOG_ERROR,
+                               "illegal long ref in memory management control "
+                               "operation %d\n", opcode);
+                        return -1;
+                    }
+                    mmco[i].long_arg = long_arg;
                 }
 
-                if(opcode > (unsigned)MMCO_LONG){
-                    av_log(h->s.avctx, AV_LOG_ERROR, "illegal memory management control operation %d\n", opcode);
+                if (opcode > (unsigned) MMCO_LONG){
+                    av_log(h->avctx, AV_LOG_ERROR,
+                           "illegal memory management control operation %d\n",
+                           opcode);
                     return -1;
                 }
-                if(opcode == MMCO_END)
+                if (opcode == MMCO_END)
                     break;
             }
-            h->mmco_index= i;
-        }else{
-            ff_generate_sliding_window_mmcos(h);
+            mmco_index = i;
+        } else {
+            if (first_slice) {
+                ret = ff_generate_sliding_window_mmcos(h, first_slice);
+                if (ret < 0 && h->avctx->err_recognition & AV_EF_EXPLODE)
+                    return ret;
+            }
+            mmco_index = -1;
         }
     }
 
+    if (first_slice && mmco_index != -1) {
+        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)))) {
+        av_log(h->avctx, AV_LOG_ERROR,
+               "Inconsistent MMCO state between slices [%d, %d]\n",
+               mmco_index, h->mmco_index);
+        return AVERROR_INVALIDDATA;
+    }
+
     return 0;
 }
diff --git a/libavcodec/h264_sei.c b/libavcodec/h264_sei.c
index 62320e2..ece54f1 100644
--- a/libavcodec/h264_sei.c
+++ b/libavcodec/h264_sei.c
@@ -45,14 +45,13 @@
 }
 
 static int decode_picture_timing(H264Context *h){
-    MpegEncContext * const s = &h->s;
     if(h->sps.nal_hrd_parameters_present_flag || h->sps.vcl_hrd_parameters_present_flag){
-        h->sei_cpb_removal_delay = get_bits_long(&s->gb, h->sps.cpb_removal_delay_length);
-        h->sei_dpb_output_delay = get_bits_long(&s->gb, h->sps.dpb_output_delay_length);
+        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);
     }
     if(h->sps.pic_struct_present_flag){
         unsigned int i, num_clock_ts;
-        h->sei_pic_struct = get_bits(&s->gb, 4);
+        h->sei_pic_struct = get_bits(&h->gb, 4);
         h->sei_ct_type    = 0;
 
         if (h->sei_pic_struct > SEI_PIC_STRUCT_FRAME_TRIPLING)
@@ -61,42 +60,41 @@
         num_clock_ts = sei_num_clock_ts_table[h->sei_pic_struct];
 
         for (i = 0 ; i < num_clock_ts ; i++){
-            if(get_bits(&s->gb, 1)){                  /* clock_timestamp_flag */
+            if(get_bits(&h->gb, 1)){                  /* clock_timestamp_flag */
                 unsigned int full_timestamp_flag;
-                h->sei_ct_type |= 1<<get_bits(&s->gb, 2);
-                skip_bits(&s->gb, 1);                 /* nuit_field_based_flag */
-                skip_bits(&s->gb, 5);                 /* counting_type */
-                full_timestamp_flag = get_bits(&s->gb, 1);
-                skip_bits(&s->gb, 1);                 /* discontinuity_flag */
-                skip_bits(&s->gb, 1);                 /* cnt_dropped_flag */
-                skip_bits(&s->gb, 8);                 /* n_frames */
+                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){
-                    skip_bits(&s->gb, 6);             /* seconds_value 0..59 */
-                    skip_bits(&s->gb, 6);             /* minutes_value 0..59 */
-                    skip_bits(&s->gb, 5);             /* hours_value 0..23 */
+                    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(&s->gb, 1)){          /* seconds_flag */
-                        skip_bits(&s->gb, 6);         /* seconds_value range 0..59 */
-                        if(get_bits(&s->gb, 1)){      /* minutes_flag */
-                            skip_bits(&s->gb, 6);     /* minutes_value 0..59 */
-                            if(get_bits(&s->gb, 1))   /* hours_flag */
-                                skip_bits(&s->gb, 5); /* hours_value 0..23 */
+                    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 */
+                            skip_bits(&h->gb, 6);     /* minutes_value 0..59 */
+                            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(&s->gb, h->sps.time_offset_length); /* time_offset */
+                    skip_bits(&h->gb, h->sps.time_offset_length); /* time_offset */
             }
         }
 
-        if(s->avctx->debug & FF_DEBUG_PICT_INFO)
-            av_log(s->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) {
-    MpegEncContext * const s = &h->s;
     uint32_t user_identifier;
     int dtg_active_format;
 
@@ -104,28 +102,28 @@
         return -1;
     size -= 7;
 
-    skip_bits(&s->gb, 8);   // country_code
-    skip_bits(&s->gb, 16);  // provider_code
-    user_identifier = get_bits_long(&s->gb, 32);
+    skip_bits(&h->gb, 8);   // country_code
+    skip_bits(&h->gb, 16);  // provider_code
+    user_identifier = get_bits_long(&h->gb, 32);
 
     switch (user_identifier) {
         case 0x44544731:    // "DTG1" - AFD_data
             if (size < 1)
                 return -1;
-            skip_bits(&s->gb, 1);
-            if (get_bits(&s->gb, 1)) {
-                skip_bits(&s->gb, 6);
+            skip_bits(&h->gb, 1);
+            if (get_bits(&h->gb, 1)) {
+                skip_bits(&h->gb, 6);
                 if (size < 2)
                     return -1;
-                skip_bits(&s->gb, 4);
-                dtg_active_format = get_bits(&s->gb, 4);
-                s->avctx->dtg_active_format = dtg_active_format;
+                skip_bits(&h->gb, 4);
+                dtg_active_format = get_bits(&h->gb, 4);
+                h->avctx->dtg_active_format = dtg_active_format;
             } else {
-                skip_bits(&s->gb, 6);
+                skip_bits(&h->gb, 6);
             }
             break;
         default:
-            skip_bits(&s->gb, size * 8);
+            skip_bits(&h->gb, size * 8);
             break;
     }
 
@@ -133,7 +131,6 @@
 }
 
 static int decode_unregistered_user_data(H264Context *h, int size){
-    MpegEncContext * const s = &h->s;
     uint8_t user_data[16+256];
     int e, build, i;
 
@@ -141,7 +138,7 @@
         return -1;
 
     for(i=0; i<sizeof(user_data)-1 && i<size; i++){
-        user_data[i]= get_bits(&s->gb, 8);
+        user_data[i]= get_bits(&h->gb, 8);
     }
 
     user_data[i]= 0;
@@ -151,33 +148,30 @@
     if(e==1 && build==1 && !strncmp(user_data+16, "x264 - core 0000", 16))
         h->x264_build = 67;
 
-    if(s->avctx->debug & FF_DEBUG_BUGS)
-        av_log(s->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++)
-        skip_bits(&s->gb, 8);
+        skip_bits(&h->gb, 8);
 
     return 0;
 }
 
 static int decode_recovery_point(H264Context *h){
-    MpegEncContext * const s = &h->s;
-
-    h->sei_recovery_frame_cnt = get_ue_golomb(&s->gb);
-    skip_bits(&s->gb, 4);       /* 1b exact_match_flag, 1b broken_link_flag, 2b changing_slice_group_idc */
+    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 */
 
     return 0;
 }
 
 static int decode_buffering_period(H264Context *h){
-    MpegEncContext * const s = &h->s;
     unsigned int sps_id;
     int sched_sel_idx;
     SPS *sps;
 
-    sps_id = get_ue_golomb_31(&s->gb);
+    sps_id = get_ue_golomb_31(&h->gb);
     if(sps_id > 31 || !h->sps_buffers[sps_id]) {
-        av_log(h->s.avctx, AV_LOG_ERROR, "non-existing SPS %d referenced in buffering period\n", sps_id);
+        av_log(h->avctx, AV_LOG_ERROR, "non-existing SPS %d referenced in buffering period\n", sps_id);
         return -1;
     }
     sps = h->sps_buffers[sps_id];
@@ -185,14 +179,14 @@
     // 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(&s->gb, sps->initial_cpb_removal_delay_length);
-            skip_bits(&s->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);
+            skip_bits(&h->gb, sps->initial_cpb_removal_delay_length); // initial_cpb_removal_delay_offset
         }
     }
     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(&s->gb, sps->initial_cpb_removal_delay_length);
-            skip_bits(&s->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);
+            skip_bits(&h->gb, sps->initial_cpb_removal_delay_length); // initial_cpb_removal_delay_offset
         }
     }
 
@@ -201,27 +195,25 @@
 }
 
 int ff_h264_decode_sei(H264Context *h){
-    MpegEncContext * const s = &h->s;
-
-    while (get_bits_left(&s->gb) > 16) {
+    while (get_bits_left(&h->gb) > 16) {
         int size, type;
 
         type=0;
         do{
-            if (get_bits_left(&s->gb) < 8)
+            if (get_bits_left(&h->gb) < 8)
                 return -1;
-            type+= show_bits(&s->gb, 8);
-        }while(get_bits(&s->gb, 8) == 255);
+            type+= show_bits(&h->gb, 8);
+        }while(get_bits(&h->gb, 8) == 255);
 
         size=0;
         do{
-            if (get_bits_left(&s->gb) < 8)
+            if (get_bits_left(&h->gb) < 8)
                 return -1;
-            size+= show_bits(&s->gb, 8);
-        }while(get_bits(&s->gb, 8) == 255);
+            size+= show_bits(&h->gb, 8);
+        }while(get_bits(&h->gb, 8) == 255);
 
-        if(s->avctx->debug&FF_DEBUG_STARTCODE)
-            av_log(h->s.avctx, AV_LOG_DEBUG, "SEI %d len:%d\n", type, size);
+        if(h->avctx->debug&FF_DEBUG_STARTCODE)
+            av_log(h->avctx, AV_LOG_DEBUG, "SEI %d len:%d\n", type, size);
 
         switch(type){
         case SEI_TYPE_PIC_TIMING: // Picture timing SEI
@@ -245,11 +237,11 @@
                 return -1;
             break;
         default:
-            skip_bits(&s->gb, 8*size);
+            skip_bits(&h->gb, 8*size);
         }
 
         //FIXME check bits here
-        align_get_bits(&s->gb);
+        align_get_bits(&h->gb);
     }
 
     return 0;
diff --git a/libavcodec/h264addpx_template.c b/libavcodec/h264addpx_template.c
new file mode 100644
index 0000000..046b6c2
--- /dev/null
+++ b/libavcodec/h264addpx_template.c
@@ -0,0 +1,72 @@
+/*
+ * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder
+ * Copyright (c) 2003-2011 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
+ * H.264 / AVC / MPEG4 part10 DSP functions.
+ * @author Michael Niedermayer <michaelni@gmx.at>
+ */
+
+#include "bit_depth_template.c"
+
+static void FUNCC(ff_h264_add_pixels4)(uint8_t *_dst, int16_t *_src, int stride)
+{
+    int i;
+    pixel *dst = (pixel *) _dst;
+    dctcoef *src = (dctcoef *) _src;
+    stride /= sizeof(pixel);
+
+    for (i = 0; i < 4; i++) {
+        dst[0] += src[0];
+        dst[1] += src[1];
+        dst[2] += src[2];
+        dst[3] += src[3];
+
+        dst += stride;
+        src += 4;
+    }
+
+    memset(_src, 0, sizeof(dctcoef) * 16);
+}
+
+static void FUNCC(ff_h264_add_pixels8)(uint8_t *_dst, int16_t *_src, int stride)
+{
+    int i;
+    pixel *dst = (pixel *) _dst;
+    dctcoef *src = (dctcoef *) _src;
+    stride /= sizeof(pixel);
+
+    for (i = 0; i < 8; i++) {
+        dst[0] += src[0];
+        dst[1] += src[1];
+        dst[2] += src[2];
+        dst[3] += src[3];
+        dst[4] += src[4];
+        dst[5] += src[5];
+        dst[6] += src[6];
+        dst[7] += src[7];
+
+        dst += stride;
+        src += 8;
+    }
+
+    memset(_src, 0, sizeof(dctcoef) * 64);
+}
diff --git a/libavcodec/h264chroma.c b/libavcodec/h264chroma.c
new file mode 100644
index 0000000..3b780a0
--- /dev/null
+++ b/libavcodec/h264chroma.c
@@ -0,0 +1,54 @@
+/*
+ * 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 "h264chroma.h"
+
+#define BIT_DEPTH 8
+#include "h264chroma_template.c"
+#undef BIT_DEPTH
+
+#define BIT_DEPTH 16
+#include "h264chroma_template.c"
+#undef BIT_DEPTH
+
+#define SET_CHROMA(depth)                                                   \
+    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->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; \
+
+void ff_h264chroma_init(H264ChromaContext *c, int bit_depth)
+{
+    if (bit_depth > 8 && bit_depth <= 16) {
+        SET_CHROMA(16);
+    } else {
+        SET_CHROMA(8);
+    }
+
+    if (ARCH_ARM)
+        ff_h264chroma_init_arm(c, bit_depth);
+    if (ARCH_PPC)
+        ff_h264chroma_init_ppc(c, bit_depth);
+    if (ARCH_SH4)
+        ff_h264chroma_init_sh4(c, bit_depth);
+    if (ARCH_X86)
+        ff_h264chroma_init_x86(c, bit_depth);
+}
diff --git a/libavcodec/h264chroma.h b/libavcodec/h264chroma.h
new file mode 100644
index 0000000..4e035b0
--- /dev/null
+++ b/libavcodec/h264chroma.h
@@ -0,0 +1,38 @@
+/*
+ * 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_H264CHROMA_H
+#define AVCODEC_H264CHROMA_H
+
+#include <stdint.h>
+
+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];
+} H264ChromaContext;
+
+void ff_h264chroma_init(H264ChromaContext *c, int bit_depth);
+
+void ff_h264chroma_init_arm(H264ChromaContext *c, int bit_depth);
+void ff_h264chroma_init_ppc(H264ChromaContext *c, int bit_depth);
+void ff_h264chroma_init_sh4(H264ChromaContext *c, int bit_depth);
+void ff_h264chroma_init_x86(H264ChromaContext *c, int bit_depth);
+
+#endif /* AVCODEC_H264CHROMA_H */
diff --git a/libavcodec/h264chroma_template.c b/libavcodec/h264chroma_template.c
new file mode 100644
index 0000000..93559d7
--- /dev/null
+++ b/libavcodec/h264chroma_template.c
@@ -0,0 +1,142 @@
+/*
+ * 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 "libavutil/avassert.h"
+
+#include "bit_depth_template.c"
+
+#define H264_CHROMA_MC(OPNAME, OP)\
+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;\
+    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]));\
+            OP(dst[1], (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2]));\
+            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]));\
+            OP(dst[1], (A*src[1] + E*src[step+1]));\
+            dst+= stride;\
+            src+= stride;\
+        }\
+    }\
+}\
+\
+static void FUNCC(OPNAME ## h264_chroma_mc4)(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]));\
+            OP(dst[1], (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2]));\
+            OP(dst[2], (A*src[2] + B*src[3] + C*src[stride+2] + D*src[stride+3]));\
+            OP(dst[3], (A*src[3] + B*src[4] + C*src[stride+3] + D*src[stride+4]));\
+            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]));\
+            OP(dst[1], (A*src[1] + E*src[step+1]));\
+            OP(dst[2], (A*src[2] + E*src[step+2]));\
+            OP(dst[3], (A*src[3] + E*src[step+3]));\
+            dst+= stride;\
+            src+= stride;\
+        }\
+    }\
+}\
+\
+static void FUNCC(OPNAME ## h264_chroma_mc8)(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]));\
+            OP(dst[1], (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2]));\
+            OP(dst[2], (A*src[2] + B*src[3] + C*src[stride+2] + D*src[stride+3]));\
+            OP(dst[3], (A*src[3] + B*src[4] + C*src[stride+3] + D*src[stride+4]));\
+            OP(dst[4], (A*src[4] + B*src[5] + C*src[stride+4] + D*src[stride+5]));\
+            OP(dst[5], (A*src[5] + B*src[6] + C*src[stride+5] + D*src[stride+6]));\
+            OP(dst[6], (A*src[6] + B*src[7] + C*src[stride+6] + D*src[stride+7]));\
+            OP(dst[7], (A*src[7] + B*src[8] + C*src[stride+7] + D*src[stride+8]));\
+            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]));\
+            OP(dst[1], (A*src[1] + E*src[step+1]));\
+            OP(dst[2], (A*src[2] + E*src[step+2]));\
+            OP(dst[3], (A*src[3] + E*src[step+3]));\
+            OP(dst[4], (A*src[4] + E*src[step+4]));\
+            OP(dst[5], (A*src[5] + E*src[step+5]));\
+            OP(dst[6], (A*src[6] + E*src[step+6]));\
+            OP(dst[7], (A*src[7] + E*src[step+7]));\
+            dst+= stride;\
+            src+= stride;\
+        }\
+    }\
+}
+
+#define op_avg(a, b) a = (((a)+(((b) + 32)>>6)+1)>>1)
+#define op_put(a, b) a = (((b) + 32)>>6)
+
+H264_CHROMA_MC(put_       , op_put)
+H264_CHROMA_MC(avg_       , op_avg)
+#undef op_avg
+#undef op_put
diff --git a/libavcodec/h264dsp.c b/libavcodec/h264dsp.c
index 69d0536..da9e417 100644
--- a/libavcodec/h264dsp.c
+++ b/libavcodec/h264dsp.c
@@ -29,6 +29,7 @@
 #include "libavutil/avassert.h"
 #include "avcodec.h"
 #include "h264dsp.h"
+#include "h264idct.h"
 #include "libavutil/common.h"
 
 #define BIT_DEPTH 8
@@ -51,11 +52,29 @@
 #include "h264dsp_template.c"
 #undef BIT_DEPTH
 
+#define BIT_DEPTH 8
+#include "h264addpx_template.c"
+#undef BIT_DEPTH
+
+#define BIT_DEPTH 16
+#include "h264addpx_template.c"
+#undef BIT_DEPTH
+
 void ff_h264dsp_init(H264DSPContext *c, const int bit_depth, const int chroma_format_idc)
 {
 #undef FUNC
 #define FUNC(a, depth) a ## _ ## depth ## _c
 
+#define ADDPX_DSP(depth) \
+    c->h264_add_pixels4_clear = FUNC(ff_h264_add_pixels4, depth);\
+    c->h264_add_pixels8_clear = FUNC(ff_h264_add_pixels8, depth)
+
+    if (bit_depth > 8 && bit_depth <= 16) {
+        ADDPX_DSP(16);
+    } else {
+        ADDPX_DSP(8);
+    }
+
 #define H264_DSP(depth) \
     c->h264_idct_add= FUNC(ff_h264_idct_add, depth);\
     c->h264_idct8_add= FUNC(ff_h264_idct8_add, depth);\
diff --git a/libavcodec/h264dsp.h b/libavcodec/h264dsp.h
index 45f81a0..98ea15c 100644
--- a/libavcodec/h264dsp.h
+++ b/libavcodec/h264dsp.h
@@ -29,8 +29,6 @@
 
 #include <stdint.h>
 
-#include "dsputil.h"
-
 typedef void (*h264_weight_func)(uint8_t *block, int stride, int height,
                                  int log2_denom, int weight, int offset);
 typedef void (*h264_biweight_func)(uint8_t *dst, uint8_t *src,
@@ -80,29 +78,33 @@
 
     /* IDCT */
     void (*h264_idct_add)(uint8_t *dst /*align 4*/,
-                          DCTELEM *block /*align 16*/, int stride);
+                          int16_t *block /*align 16*/, int stride);
     void (*h264_idct8_add)(uint8_t *dst /*align 8*/,
-                           DCTELEM *block /*align 16*/, int stride);
+                           int16_t *block /*align 16*/, int stride);
     void (*h264_idct_dc_add)(uint8_t *dst /*align 4*/,
-                             DCTELEM *block /*align 16*/, int stride);
+                             int16_t *block /*align 16*/, int stride);
     void (*h264_idct8_dc_add)(uint8_t *dst /*align 8*/,
-                              DCTELEM *block /*align 16*/, int stride);
+                              int16_t *block /*align 16*/, int stride);
 
     void (*h264_idct_add16)(uint8_t *dst /*align 16*/, const int *blockoffset,
-                            DCTELEM *block /*align 16*/, int stride,
+                            int16_t *block /*align 16*/, int stride,
                             const uint8_t nnzc[15 * 8]);
     void (*h264_idct8_add4)(uint8_t *dst /*align 16*/, const int *blockoffset,
-                            DCTELEM *block /*align 16*/, int stride,
+                            int16_t *block /*align 16*/, int stride,
                             const uint8_t nnzc[15 * 8]);
     void (*h264_idct_add8)(uint8_t **dst /*align 16*/, const int *blockoffset,
-                           DCTELEM *block /*align 16*/, int stride,
+                           int16_t *block /*align 16*/, int stride,
                            const uint8_t nnzc[15 * 8]);
     void (*h264_idct_add16intra)(uint8_t *dst /*align 16*/, const int *blockoffset,
-                                 DCTELEM *block /*align 16*/,
+                                 int16_t *block /*align 16*/,
                                  int stride, const uint8_t nnzc[15 * 8]);
-    void (*h264_luma_dc_dequant_idct)(DCTELEM *output,
-                                      DCTELEM *input /*align 16*/, int qmul);
-    void (*h264_chroma_dc_dequant_idct)(DCTELEM *block, int qmul);
+    void (*h264_luma_dc_dequant_idct)(int16_t *output,
+                                      int16_t *input /*align 16*/, int qmul);
+    void (*h264_chroma_dc_dequant_idct)(int16_t *block, int qmul);
+
+    /* 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);
 } H264DSPContext;
 
 void ff_h264dsp_init(H264DSPContext *c, const int bit_depth,
diff --git a/libavcodec/h264idct.c b/libavcodec/h264idct.c
index d92025c..6a771af 100644
--- a/libavcodec/h264idct.c
+++ b/libavcodec/h264idct.c
@@ -25,6 +25,8 @@
  * @author Michael Niedermayer <michaelni@gmx.at>
  */
 
+#include "h264idct.h"
+
 #define BIT_DEPTH 8
 #include "h264idct_template.c"
 #undef BIT_DEPTH
diff --git a/libavcodec/h264idct.h b/libavcodec/h264idct.h
new file mode 100644
index 0000000..17e0051
--- /dev/null
+++ b/libavcodec/h264idct.h
@@ -0,0 +1,44 @@
+/*
+ * 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_H264IDCT_H
+#define AVCODEC_H264IDCT_H
+
+#include <stdint.h>
+
+#define H264_IDCT(depth) \
+void ff_h264_idct8_add_ ## depth ## _c(uint8_t *dst, int16_t *block, int stride);\
+void ff_h264_idct_add_ ## depth ## _c(uint8_t *dst, int16_t *block, int stride);\
+void ff_h264_idct8_dc_add_ ## depth ## _c(uint8_t *dst, int16_t *block, int stride);\
+void ff_h264_idct_dc_add_ ## depth ## _c(uint8_t *dst, int16_t *block, int stride);\
+void ff_h264_idct_add16_ ## depth ## _c(uint8_t *dst, const int *blockoffset, int16_t *block, int stride, const uint8_t nnzc[6*8]);\
+void ff_h264_idct_add16intra_ ## depth ## _c(uint8_t *dst, const int *blockoffset, int16_t *block, int stride, const uint8_t nnzc[6*8]);\
+void ff_h264_idct8_add4_ ## depth ## _c(uint8_t *dst, const int *blockoffset, int16_t *block, int stride, const uint8_t nnzc[6*8]);\
+void ff_h264_idct_add8_422_ ## depth ## _c(uint8_t **dest, const int *blockoffset, int16_t *block, int stride, const uint8_t nnzc[6*8]);\
+void ff_h264_idct_add8_ ## depth ## _c(uint8_t **dest, const int *blockoffset, int16_t *block, int stride, const uint8_t nnzc[6*8]);\
+void ff_h264_luma_dc_dequant_idct_ ## depth ## _c(int16_t *output, int16_t *input, int qmul);\
+void ff_h264_chroma422_dc_dequant_idct_ ## depth ## _c(int16_t *block, int qmul);\
+void ff_h264_chroma_dc_dequant_idct_ ## depth ## _c(int16_t *block, int qmul);
+
+H264_IDCT( 8)
+H264_IDCT( 9)
+H264_IDCT(10)
+H264_IDCT(12)
+H264_IDCT(14)
+
+#endif /* AVCODEC_H264IDCT_H */
diff --git a/libavcodec/h264idct_template.c b/libavcodec/h264idct_template.c
index 313732b..9f16e1d 100644
--- a/libavcodec/h264idct_template.c
+++ b/libavcodec/h264idct_template.c
@@ -27,27 +27,9 @@
 
 #include "bit_depth_template.c"
 #include "libavutil/common.h"
+#include "h264.h"
 
-#ifndef AVCODEC_H264IDCT_INTERNAL_H
-#define AVCODEC_H264IDCT_INTERNAL_H
-//FIXME this table is a duplicate from h264data.h, and will be removed once the tables from, h264 have been split
-static const uint8_t scan8[16*3]={
- 4+ 1*8, 5+ 1*8, 4+ 2*8, 5+ 2*8,
- 6+ 1*8, 7+ 1*8, 6+ 2*8, 7+ 2*8,
- 4+ 3*8, 5+ 3*8, 4+ 4*8, 5+ 4*8,
- 6+ 3*8, 7+ 3*8, 6+ 4*8, 7+ 4*8,
- 4+ 6*8, 5+ 6*8, 4+ 7*8, 5+ 7*8,
- 6+ 6*8, 7+ 6*8, 6+ 7*8, 7+ 7*8,
- 4+ 8*8, 5+ 8*8, 4+ 9*8, 5+ 9*8,
- 6+ 8*8, 7+ 8*8, 6+ 9*8, 7+ 9*8,
- 4+11*8, 5+11*8, 4+12*8, 5+12*8,
- 6+11*8, 7+11*8, 6+12*8, 7+12*8,
- 4+13*8, 5+13*8, 4+14*8, 5+14*8,
- 6+13*8, 7+13*8, 6+14*8, 7+14*8
-};
-#endif
-
-void FUNCC(ff_h264_idct_add)(uint8_t *_dst, DCTELEM *_block, int stride)
+void FUNCC(ff_h264_idct_add)(uint8_t *_dst, int16_t *_block, int stride)
 {
     int i;
     pixel *dst = (pixel*)_dst;
@@ -79,9 +61,11 @@
         dst[i + 2*stride]= av_clip_pixel(dst[i + 2*stride] + ((z1 - z2) >> 6));
         dst[i + 3*stride]= av_clip_pixel(dst[i + 3*stride] + ((z0 - z3) >> 6));
     }
+
+    memset(block, 0, 16 * sizeof(dctcoef));
 }
 
-void FUNCC(ff_h264_idct8_add)(uint8_t *_dst, DCTELEM *_block, int stride){
+void FUNCC(ff_h264_idct8_add)(uint8_t *_dst, int16_t *_block, int stride){
     int i;
     pixel *dst = (pixel*)_dst;
     dctcoef *block = (dctcoef*)_block;
@@ -151,14 +135,18 @@
         dst[i + 6*stride] = av_clip_pixel( dst[i + 6*stride] + ((b2 - b5) >> 6) );
         dst[i + 7*stride] = av_clip_pixel( dst[i + 7*stride] + ((b0 - b7) >> 6) );
     }
+
+    memset(block, 0, 64 * sizeof(dctcoef));
 }
 
 // assumes all AC coefs are 0
-void FUNCC(ff_h264_idct_dc_add)(uint8_t *p_dst, DCTELEM *block, int stride){
+void FUNCC(ff_h264_idct_dc_add)(uint8_t *_dst, int16_t *_block, int stride){
     int i, j;
-    int dc = (((dctcoef*)block)[0] + 32) >> 6;
-    pixel *dst = (pixel*)p_dst;
+    pixel *dst = (pixel*)_dst;
+    dctcoef *block = (dctcoef*)_block;
+    int dc = (block[0] + 32) >> 6;
     stride >>= sizeof(pixel)-1;
+    block[0] = 0;
     for( j = 0; j < 4; j++ )
     {
         for( i = 0; i < 4; i++ )
@@ -167,10 +155,12 @@
     }
 }
 
-void FUNCC(ff_h264_idct8_dc_add)(uint8_t *p_dst, DCTELEM *block, int stride){
+void FUNCC(ff_h264_idct8_dc_add)(uint8_t *_dst, int16_t *_block, int stride){
     int i, j;
-    int dc = (((dctcoef*)block)[0] + 32) >> 6;
-    pixel *dst = (pixel*)p_dst;
+    pixel *dst = (pixel*)_dst;
+    dctcoef *block = (dctcoef*)_block;
+    int dc = (block[0] + 32) >> 6;
+    block[0] = 0;
     stride >>= sizeof(pixel)-1;
     for( j = 0; j < 8; j++ )
     {
@@ -180,7 +170,7 @@
     }
 }
 
-void FUNCC(ff_h264_idct_add16)(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[15*8]){
+void FUNCC(ff_h264_idct_add16)(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] ];
@@ -191,7 +181,7 @@
     }
 }
 
-void FUNCC(ff_h264_idct_add16intra)(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[15*8]){
+void FUNCC(ff_h264_idct_add16intra)(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] ])             FUNCC(ff_h264_idct_add   )(dst + block_offset[i], block + i*16*sizeof(pixel), stride);
@@ -199,7 +189,7 @@
     }
 }
 
-void FUNCC(ff_h264_idct8_add4)(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[15*8]){
+void FUNCC(ff_h264_idct8_add4)(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] ];
@@ -210,7 +200,7 @@
     }
 }
 
-void FUNCC(ff_h264_idct_add8)(uint8_t **dest, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[15*8]){
+void FUNCC(ff_h264_idct_add8)(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++){
@@ -222,7 +212,7 @@
     }
 }
 
-void FUNCC(ff_h264_idct_add8_422)(uint8_t **dest, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[15*8]){
+void FUNCC(ff_h264_idct_add8_422)(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++){
@@ -248,13 +238,13 @@
  * IDCT transforms the 16 dc values and dequantizes them.
  * @param qmul quantization parameter
  */
-void FUNCC(ff_h264_luma_dc_dequant_idct)(DCTELEM *p_output, DCTELEM *p_input, int qmul){
+void FUNCC(ff_h264_luma_dc_dequant_idct)(int16_t *_output, int16_t *_input, int qmul){
 #define stride 16
     int i;
     int temp[16];
     static const uint8_t x_offset[4]={0, 2*stride, 8*stride, 10*stride};
-    dctcoef *input = (dctcoef*)p_input;
-    dctcoef *output = (dctcoef*)p_output;
+    dctcoef *input = (dctcoef*)_input;
+    dctcoef *output = (dctcoef*)_output;
 
     for(i=0; i<4; i++){
         const int z0= input[4*i+0] + input[4*i+1];
@@ -283,7 +273,7 @@
 #undef stride
 }
 
-void FUNCC(ff_h264_chroma422_dc_dequant_idct)(DCTELEM *_block, int qmul){
+void FUNCC(ff_h264_chroma422_dc_dequant_idct)(int16_t *_block, int qmul){
     const int stride= 16*2;
     const int xStride= 16;
     int i;
@@ -310,7 +300,7 @@
     }
 }
 
-void FUNCC(ff_h264_chroma_dc_dequant_idct)(DCTELEM *_block, int qmul){
+void FUNCC(ff_h264_chroma_dc_dequant_idct)(int16_t *_block, int qmul){
     const int stride= 16*2;
     const int xStride= 16;
     int a,b,c,d,e;
diff --git a/libavcodec/h264pred.c b/libavcodec/h264pred.c
index f83924d..e5f1f5a 100644
--- a/libavcodec/h264pred.c
+++ b/libavcodec/h264pred.c
@@ -26,7 +26,9 @@
  */
 
 #include "libavutil/avassert.h"
+#include "dsputil.h"
 #include "h264pred.h"
+#include "avcodec.h" // for AV_CODEC_ID_*
 
 #define BIT_DEPTH 8
 #include "h264pred_template.c"
@@ -406,10 +408,8 @@
  * Set the intra prediction function pointers.
  */
 void ff_h264_pred_init(H264PredContext *h, int codec_id, const int bit_depth,
-                       const int chroma_format_idc)
+                       int chroma_format_idc)
 {
-//    MpegEncContext * const s = &h->s;
-
 #undef FUNC
 #undef FUNCC
 #define FUNC(a, depth) a ## _ ## depth
@@ -566,6 +566,9 @@
     h->pred16x16_add[VERT_PRED8x8]= FUNCC(pred16x16_vertical_add          , depth);\
     h->pred16x16_add[ HOR_PRED8x8]= FUNCC(pred16x16_horizontal_add        , depth);\
 
+    if(!chroma_format_idc)
+        chroma_format_idc = 1;
+
     switch (bit_depth) {
         case 9:
             H264_PRED(9)
diff --git a/libavcodec/h264pred.h b/libavcodec/h264pred.h
index 33f3944..ed67d2e 100644
--- a/libavcodec/h264pred.h
+++ b/libavcodec/h264pred.h
@@ -28,8 +28,8 @@
 #ifndef AVCODEC_H264PRED_H
 #define AVCODEC_H264PRED_H
 
-#include "libavutil/common.h"
-#include "dsputil.h"
+#include <stddef.h>
+#include <stdint.h>
 
 /**
  * Prediction types
@@ -98,15 +98,15 @@
     void(*pred16x16[4 + 3 + 2])(uint8_t *src, ptrdiff_t stride);
 
     void(*pred4x4_add[2])(uint8_t *pix /*align  4*/,
-                          const DCTELEM *block /*align 16*/, ptrdiff_t stride);
+                          int16_t *block /*align 16*/, ptrdiff_t stride);
     void(*pred8x8l_add[2])(uint8_t *pix /*align  8*/,
-                           const DCTELEM *block /*align 16*/, ptrdiff_t stride);
+                           int16_t *block /*align 16*/, ptrdiff_t stride);
     void(*pred8x8_add[3])(uint8_t *pix /*align  8*/,
                           const int *block_offset,
-                          const DCTELEM *block /*align 16*/, ptrdiff_t stride);
+                          int16_t *block /*align 16*/, ptrdiff_t stride);
     void(*pred16x16_add[3])(uint8_t *pix /*align 16*/,
                             const int *block_offset,
-                            const DCTELEM *block /*align 16*/, ptrdiff_t stride);
+                            int16_t *block /*align 16*/, ptrdiff_t stride);
 } H264PredContext;
 
 void ff_h264_pred_init(H264PredContext *h, int codec_id,
diff --git a/libavcodec/h264pred_template.c b/libavcodec/h264pred_template.c
index f08fdf4..8d8d62e 100644
--- a/libavcodec/h264pred_template.c
+++ b/libavcodec/h264pred_template.c
@@ -1132,7 +1132,7 @@
 #undef PL
 #undef SRC
 
-static void FUNCC(pred4x4_vertical_add)(uint8_t *_pix, const DCTELEM *_block,
+static void FUNCC(pred4x4_vertical_add)(uint8_t *_pix, int16_t *_block,
                                         ptrdiff_t stride)
 {
     int i;
@@ -1149,9 +1149,11 @@
         pix++;
         block++;
     }
+
+    memset(_block, 0, sizeof(dctcoef) * 16);
 }
 
-static void FUNCC(pred4x4_horizontal_add)(uint8_t *_pix, const DCTELEM *_block,
+static void FUNCC(pred4x4_horizontal_add)(uint8_t *_pix, int16_t *_block,
                                           ptrdiff_t stride)
 {
     int i;
@@ -1167,9 +1169,11 @@
         pix+= stride;
         block+= 4;
     }
+
+    memset(_block, 0, sizeof(dctcoef) * 16);
 }
 
-static void FUNCC(pred8x8l_vertical_add)(uint8_t *_pix, const DCTELEM *_block,
+static void FUNCC(pred8x8l_vertical_add)(uint8_t *_pix, int16_t *_block,
                                          ptrdiff_t stride)
 {
     int i;
@@ -1190,9 +1194,11 @@
         pix++;
         block++;
     }
+
+    memset(_block, 0, sizeof(dctcoef) * 64);
 }
 
-static void FUNCC(pred8x8l_horizontal_add)(uint8_t *_pix, const DCTELEM *_block,
+static void FUNCC(pred8x8l_horizontal_add)(uint8_t *_pix, int16_t *_block,
                                            ptrdiff_t stride)
 {
     int i;
@@ -1212,10 +1218,12 @@
         pix+= stride;
         block+= 8;
     }
+
+    memset(_block, 0, sizeof(dctcoef) * 64);
 }
 
 static void FUNCC(pred16x16_vertical_add)(uint8_t *pix, const int *block_offset,
-                                          const DCTELEM *block,
+                                          int16_t *block,
                                           ptrdiff_t stride)
 {
     int i;
@@ -1225,7 +1233,7 @@
 
 static void FUNCC(pred16x16_horizontal_add)(uint8_t *pix,
                                             const int *block_offset,
-                                            const DCTELEM *block,
+                                            int16_t *block,
                                             ptrdiff_t stride)
 {
     int i;
@@ -1234,7 +1242,7 @@
 }
 
 static void FUNCC(pred8x8_vertical_add)(uint8_t *pix, const int *block_offset,
-                                        const DCTELEM *block, ptrdiff_t stride)
+                                        int16_t *block, ptrdiff_t stride)
 {
     int i;
     for(i=0; i<4; i++)
@@ -1242,7 +1250,7 @@
 }
 
 static void FUNCC(pred8x16_vertical_add)(uint8_t *pix, const int *block_offset,
-                                         const DCTELEM *block, ptrdiff_t stride)
+                                         int16_t *block, ptrdiff_t stride)
 {
     int i;
     for(i=0; i<4; i++)
@@ -1252,7 +1260,7 @@
 }
 
 static void FUNCC(pred8x8_horizontal_add)(uint8_t *pix, const int *block_offset,
-                                          const DCTELEM *block,
+                                          int16_t *block,
                                           ptrdiff_t stride)
 {
     int i;
@@ -1262,7 +1270,7 @@
 
 static void FUNCC(pred8x16_horizontal_add)(uint8_t *pix,
                                            const int *block_offset,
-                                           const DCTELEM *block, ptrdiff_t stride)
+                                           int16_t *block, ptrdiff_t stride)
 {
     int i;
     for(i=0; i<4; i++)
diff --git a/libavcodec/h264qpel.c b/libavcodec/h264qpel.c
new file mode 100644
index 0000000..f46da8f
--- /dev/null
+++ b/libavcodec/h264qpel.c
@@ -0,0 +1,104 @@
+/*
+ * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder
+ * Copyright (c) 2003-2010 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 "h264qpel.h"
+
+#define pixeltmp int16_t
+#define BIT_DEPTH 8
+#include "h264qpel_template.c"
+#undef BIT_DEPTH
+
+#define BIT_DEPTH 9
+#include "h264qpel_template.c"
+#undef BIT_DEPTH
+
+#define BIT_DEPTH 10
+#include "h264qpel_template.c"
+#undef BIT_DEPTH
+#undef pixeltmp
+
+#define pixeltmp int32_t
+#define BIT_DEPTH 12
+#include "h264qpel_template.c"
+#undef BIT_DEPTH
+
+#define BIT_DEPTH 14
+#include "h264qpel_template.c"
+#undef BIT_DEPTH
+
+
+void ff_h264qpel_init(H264QpelContext *c, int bit_depth)
+{
+#undef FUNCC
+#define FUNCC(f, depth) f ## _ ## depth ## _c
+
+#define dspfunc2(PFX, IDX, NUM, depth)                                  \
+    c->PFX ## _pixels_tab[IDX][ 0] = FUNCC(PFX ## NUM ## _mc00, depth); \
+    c->PFX ## _pixels_tab[IDX][ 1] = FUNCC(PFX ## NUM ## _mc10, depth); \
+    c->PFX ## _pixels_tab[IDX][ 2] = FUNCC(PFX ## NUM ## _mc20, depth); \
+    c->PFX ## _pixels_tab[IDX][ 3] = FUNCC(PFX ## NUM ## _mc30, depth); \
+    c->PFX ## _pixels_tab[IDX][ 4] = FUNCC(PFX ## NUM ## _mc01, depth); \
+    c->PFX ## _pixels_tab[IDX][ 5] = FUNCC(PFX ## NUM ## _mc11, depth); \
+    c->PFX ## _pixels_tab[IDX][ 6] = FUNCC(PFX ## NUM ## _mc21, depth); \
+    c->PFX ## _pixels_tab[IDX][ 7] = FUNCC(PFX ## NUM ## _mc31, depth); \
+    c->PFX ## _pixels_tab[IDX][ 8] = FUNCC(PFX ## NUM ## _mc02, depth); \
+    c->PFX ## _pixels_tab[IDX][ 9] = FUNCC(PFX ## NUM ## _mc12, depth); \
+    c->PFX ## _pixels_tab[IDX][10] = FUNCC(PFX ## NUM ## _mc22, depth); \
+    c->PFX ## _pixels_tab[IDX][11] = FUNCC(PFX ## NUM ## _mc32, depth); \
+    c->PFX ## _pixels_tab[IDX][12] = FUNCC(PFX ## NUM ## _mc03, depth); \
+    c->PFX ## _pixels_tab[IDX][13] = FUNCC(PFX ## NUM ## _mc13, depth); \
+    c->PFX ## _pixels_tab[IDX][14] = FUNCC(PFX ## NUM ## _mc23, depth); \
+    c->PFX ## _pixels_tab[IDX][15] = FUNCC(PFX ## NUM ## _mc33, depth)
+
+#define SET_QPEL(depth)                         \
+    dspfunc2(put_h264_qpel, 0, 16, depth);      \
+    dspfunc2(put_h264_qpel, 1,  8, depth);      \
+    dspfunc2(put_h264_qpel, 2,  4, depth);      \
+    dspfunc2(put_h264_qpel, 3,  2, depth);      \
+    dspfunc2(avg_h264_qpel, 0, 16, depth);      \
+    dspfunc2(avg_h264_qpel, 1,  8, depth);      \
+    dspfunc2(avg_h264_qpel, 2,  4, depth)
+
+    switch (bit_depth) {
+    default:
+        SET_QPEL(8);
+        break;
+    case 9:
+        SET_QPEL(9);
+        break;
+    case 10:
+        SET_QPEL(10);
+        break;
+    case 12:
+        SET_QPEL(12);
+        break;
+    case 14:
+        SET_QPEL(14);
+        break;
+    }
+
+    if (ARCH_ARM)
+        ff_h264qpel_init_arm(c, bit_depth);
+    if (ARCH_PPC)
+        ff_h264qpel_init_ppc(c, bit_depth);
+    if (ARCH_X86)
+        ff_h264qpel_init_x86(c, bit_depth);
+}
diff --git a/libavcodec/h264qpel.h b/libavcodec/h264qpel.h
new file mode 100644
index 0000000..6abfac0
--- /dev/null
+++ b/libavcodec/h264qpel.h
@@ -0,0 +1,38 @@
+/*
+ * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder
+ * Copyright (c) 2003-2010 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
+ */
+
+#ifndef AVCODEC_H264QPEL_H
+#define AVCODEC_H264QPEL_H
+
+#include "dsputil.h"
+
+typedef struct H264QpelContext {
+    qpel_mc_func put_h264_qpel_pixels_tab[4][16];
+    qpel_mc_func avg_h264_qpel_pixels_tab[4][16];
+} H264QpelContext;
+
+void ff_h264qpel_init(H264QpelContext *c, int bit_depth);
+
+void ff_h264qpel_init_arm(H264QpelContext *c, int bit_depth);
+void ff_h264qpel_init_ppc(H264QpelContext *c, int bit_depth);
+void ff_h264qpel_init_x86(H264QpelContext *c, int bit_depth);
+
+#endif /* AVCODEC_H264QPEL_H */
diff --git a/libavcodec/h264qpel_template.c b/libavcodec/h264qpel_template.c
new file mode 100644
index 0000000..95950f4
--- /dev/null
+++ b/libavcodec/h264qpel_template.c
@@ -0,0 +1,560 @@
+/*
+ * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder
+ * Copyright (c) 2003-2010 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 "libavutil/common.h"
+#include "bit_depth_template.c"
+#include "hpel_template.c"
+
+static inline void FUNC(copy_block2)(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
+{
+    int i;
+    for(i=0; i<h; i++)
+    {
+        AV_WN2P(dst   , AV_RN2P(src   ));
+        dst+=dstStride;
+        src+=srcStride;
+    }
+}
+
+static inline void FUNC(copy_block4)(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
+{
+    int i;
+    for(i=0; i<h; i++)
+    {
+        AV_WN4P(dst   , AV_RN4P(src   ));
+        dst+=dstStride;
+        src+=srcStride;
+    }
+}
+
+static inline void FUNC(copy_block8)(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
+{
+    int i;
+    for(i=0; i<h; i++)
+    {
+        AV_WN4P(dst                , AV_RN4P(src                ));
+        AV_WN4P(dst+4*sizeof(pixel), AV_RN4P(src+4*sizeof(pixel)));
+        dst+=dstStride;
+        src+=srcStride;
+    }
+}
+
+static inline void FUNC(copy_block16)(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
+{
+    int i;
+    for(i=0; i<h; i++)
+    {
+        AV_WN4P(dst                 , AV_RN4P(src                 ));
+        AV_WN4P(dst+ 4*sizeof(pixel), AV_RN4P(src+ 4*sizeof(pixel)));
+        AV_WN4P(dst+ 8*sizeof(pixel), AV_RN4P(src+ 8*sizeof(pixel)));
+        AV_WN4P(dst+12*sizeof(pixel), AV_RN4P(src+12*sizeof(pixel)));
+        dst+=dstStride;
+        src+=srcStride;
+    }
+}
+
+#define H264_LOWPASS(OPNAME, OP, OP2) \
+static av_unused void FUNC(OPNAME ## h264_qpel2_h_lowpass)(uint8_t *p_dst, uint8_t *p_src, int dstStride, int srcStride){\
+    const int h=2;\
+    INIT_CLIP\
+    int i;\
+    pixel *dst = (pixel*)p_dst;\
+    pixel *src = (pixel*)p_src;\
+    dstStride >>= sizeof(pixel)-1;\
+    srcStride >>= sizeof(pixel)-1;\
+    for(i=0; i<h; i++)\
+    {\
+        OP(dst[0], (src[0]+src[1])*20 - (src[-1]+src[2])*5 + (src[-2]+src[3]));\
+        OP(dst[1], (src[1]+src[2])*20 - (src[0 ]+src[3])*5 + (src[-1]+src[4]));\
+        dst+=dstStride;\
+        src+=srcStride;\
+    }\
+}\
+\
+static av_unused void FUNC(OPNAME ## h264_qpel2_v_lowpass)(uint8_t *p_dst, uint8_t *p_src, int dstStride, int srcStride){\
+    const int w=2;\
+    INIT_CLIP\
+    int i;\
+    pixel *dst = (pixel*)p_dst;\
+    pixel *src = (pixel*)p_src;\
+    dstStride >>= sizeof(pixel)-1;\
+    srcStride >>= sizeof(pixel)-1;\
+    for(i=0; i<w; i++)\
+    {\
+        const int srcB= src[-2*srcStride];\
+        const int srcA= src[-1*srcStride];\
+        const int src0= src[0 *srcStride];\
+        const int src1= src[1 *srcStride];\
+        const int src2= src[2 *srcStride];\
+        const int src3= src[3 *srcStride];\
+        const int src4= src[4 *srcStride];\
+        OP(dst[0*dstStride], (src0+src1)*20 - (srcA+src2)*5 + (srcB+src3));\
+        OP(dst[1*dstStride], (src1+src2)*20 - (src0+src3)*5 + (srcA+src4));\
+        dst++;\
+        src++;\
+    }\
+}\
+\
+static av_unused void FUNC(OPNAME ## h264_qpel2_hv_lowpass)(uint8_t *p_dst, pixeltmp *tmp, uint8_t *p_src, int dstStride, int tmpStride, int srcStride){\
+    const int h=2;\
+    const int w=2;\
+    const int pad = (BIT_DEPTH == 10) ? (-10 * ((1<<BIT_DEPTH)-1)) : 0;\
+    INIT_CLIP\
+    int i;\
+    pixel *dst = (pixel*)p_dst;\
+    pixel *src = (pixel*)p_src;\
+    dstStride >>= sizeof(pixel)-1;\
+    srcStride >>= sizeof(pixel)-1;\
+    src -= 2*srcStride;\
+    for(i=0; i<h+5; i++)\
+    {\
+        tmp[0]= (src[0]+src[1])*20 - (src[-1]+src[2])*5 + (src[-2]+src[3]) + pad;\
+        tmp[1]= (src[1]+src[2])*20 - (src[0 ]+src[3])*5 + (src[-1]+src[4]) + pad;\
+        tmp+=tmpStride;\
+        src+=srcStride;\
+    }\
+    tmp -= tmpStride*(h+5-2);\
+    for(i=0; i<w; i++)\
+    {\
+        const int tmpB= tmp[-2*tmpStride] - pad;\
+        const int tmpA= tmp[-1*tmpStride] - pad;\
+        const int tmp0= tmp[0 *tmpStride] - pad;\
+        const int tmp1= tmp[1 *tmpStride] - pad;\
+        const int tmp2= tmp[2 *tmpStride] - pad;\
+        const int tmp3= tmp[3 *tmpStride] - pad;\
+        const int tmp4= tmp[4 *tmpStride] - pad;\
+        OP2(dst[0*dstStride], (tmp0+tmp1)*20 - (tmpA+tmp2)*5 + (tmpB+tmp3));\
+        OP2(dst[1*dstStride], (tmp1+tmp2)*20 - (tmp0+tmp3)*5 + (tmpA+tmp4));\
+        dst++;\
+        tmp++;\
+    }\
+}\
+static void FUNC(OPNAME ## h264_qpel4_h_lowpass)(uint8_t *p_dst, uint8_t *p_src, int dstStride, int srcStride){\
+    const int h=4;\
+    INIT_CLIP\
+    int i;\
+    pixel *dst = (pixel*)p_dst;\
+    pixel *src = (pixel*)p_src;\
+    dstStride >>= sizeof(pixel)-1;\
+    srcStride >>= sizeof(pixel)-1;\
+    for(i=0; i<h; i++)\
+    {\
+        OP(dst[0], (src[0]+src[1])*20 - (src[-1]+src[2])*5 + (src[-2]+src[3]));\
+        OP(dst[1], (src[1]+src[2])*20 - (src[0 ]+src[3])*5 + (src[-1]+src[4]));\
+        OP(dst[2], (src[2]+src[3])*20 - (src[1 ]+src[4])*5 + (src[0 ]+src[5]));\
+        OP(dst[3], (src[3]+src[4])*20 - (src[2 ]+src[5])*5 + (src[1 ]+src[6]));\
+        dst+=dstStride;\
+        src+=srcStride;\
+    }\
+}\
+\
+static void FUNC(OPNAME ## h264_qpel4_v_lowpass)(uint8_t *p_dst, uint8_t *p_src, int dstStride, int srcStride){\
+    const int w=4;\
+    INIT_CLIP\
+    int i;\
+    pixel *dst = (pixel*)p_dst;\
+    pixel *src = (pixel*)p_src;\
+    dstStride >>= sizeof(pixel)-1;\
+    srcStride >>= sizeof(pixel)-1;\
+    for(i=0; i<w; i++)\
+    {\
+        const int srcB= src[-2*srcStride];\
+        const int srcA= src[-1*srcStride];\
+        const int src0= src[0 *srcStride];\
+        const int src1= src[1 *srcStride];\
+        const int src2= src[2 *srcStride];\
+        const int src3= src[3 *srcStride];\
+        const int src4= src[4 *srcStride];\
+        const int src5= src[5 *srcStride];\
+        const int src6= src[6 *srcStride];\
+        OP(dst[0*dstStride], (src0+src1)*20 - (srcA+src2)*5 + (srcB+src3));\
+        OP(dst[1*dstStride], (src1+src2)*20 - (src0+src3)*5 + (srcA+src4));\
+        OP(dst[2*dstStride], (src2+src3)*20 - (src1+src4)*5 + (src0+src5));\
+        OP(dst[3*dstStride], (src3+src4)*20 - (src2+src5)*5 + (src1+src6));\
+        dst++;\
+        src++;\
+    }\
+}\
+\
+static void FUNC(OPNAME ## h264_qpel4_hv_lowpass)(uint8_t *p_dst, pixeltmp *tmp, uint8_t *p_src, int dstStride, int tmpStride, int srcStride){\
+    const int h=4;\
+    const int w=4;\
+    const int pad = (BIT_DEPTH == 10) ? (-10 * ((1<<BIT_DEPTH)-1)) : 0;\
+    INIT_CLIP\
+    int i;\
+    pixel *dst = (pixel*)p_dst;\
+    pixel *src = (pixel*)p_src;\
+    dstStride >>= sizeof(pixel)-1;\
+    srcStride >>= sizeof(pixel)-1;\
+    src -= 2*srcStride;\
+    for(i=0; i<h+5; i++)\
+    {\
+        tmp[0]= (src[0]+src[1])*20 - (src[-1]+src[2])*5 + (src[-2]+src[3]) + pad;\
+        tmp[1]= (src[1]+src[2])*20 - (src[0 ]+src[3])*5 + (src[-1]+src[4]) + pad;\
+        tmp[2]= (src[2]+src[3])*20 - (src[1 ]+src[4])*5 + (src[0 ]+src[5]) + pad;\
+        tmp[3]= (src[3]+src[4])*20 - (src[2 ]+src[5])*5 + (src[1 ]+src[6]) + pad;\
+        tmp+=tmpStride;\
+        src+=srcStride;\
+    }\
+    tmp -= tmpStride*(h+5-2);\
+    for(i=0; i<w; i++)\
+    {\
+        const int tmpB= tmp[-2*tmpStride] - pad;\
+        const int tmpA= tmp[-1*tmpStride] - pad;\
+        const int tmp0= tmp[0 *tmpStride] - pad;\
+        const int tmp1= tmp[1 *tmpStride] - pad;\
+        const int tmp2= tmp[2 *tmpStride] - pad;\
+        const int tmp3= tmp[3 *tmpStride] - pad;\
+        const int tmp4= tmp[4 *tmpStride] - pad;\
+        const int tmp5= tmp[5 *tmpStride] - pad;\
+        const int tmp6= tmp[6 *tmpStride] - pad;\
+        OP2(dst[0*dstStride], (tmp0+tmp1)*20 - (tmpA+tmp2)*5 + (tmpB+tmp3));\
+        OP2(dst[1*dstStride], (tmp1+tmp2)*20 - (tmp0+tmp3)*5 + (tmpA+tmp4));\
+        OP2(dst[2*dstStride], (tmp2+tmp3)*20 - (tmp1+tmp4)*5 + (tmp0+tmp5));\
+        OP2(dst[3*dstStride], (tmp3+tmp4)*20 - (tmp2+tmp5)*5 + (tmp1+tmp6));\
+        dst++;\
+        tmp++;\
+    }\
+}\
+\
+static void FUNC(OPNAME ## h264_qpel8_h_lowpass)(uint8_t *p_dst, uint8_t *p_src, int dstStride, int srcStride){\
+    const int h=8;\
+    INIT_CLIP\
+    int i;\
+    pixel *dst = (pixel*)p_dst;\
+    pixel *src = (pixel*)p_src;\
+    dstStride >>= sizeof(pixel)-1;\
+    srcStride >>= sizeof(pixel)-1;\
+    for(i=0; i<h; i++)\
+    {\
+        OP(dst[0], (src[0]+src[1])*20 - (src[-1]+src[2])*5 + (src[-2]+src[3 ]));\
+        OP(dst[1], (src[1]+src[2])*20 - (src[0 ]+src[3])*5 + (src[-1]+src[4 ]));\
+        OP(dst[2], (src[2]+src[3])*20 - (src[1 ]+src[4])*5 + (src[0 ]+src[5 ]));\
+        OP(dst[3], (src[3]+src[4])*20 - (src[2 ]+src[5])*5 + (src[1 ]+src[6 ]));\
+        OP(dst[4], (src[4]+src[5])*20 - (src[3 ]+src[6])*5 + (src[2 ]+src[7 ]));\
+        OP(dst[5], (src[5]+src[6])*20 - (src[4 ]+src[7])*5 + (src[3 ]+src[8 ]));\
+        OP(dst[6], (src[6]+src[7])*20 - (src[5 ]+src[8])*5 + (src[4 ]+src[9 ]));\
+        OP(dst[7], (src[7]+src[8])*20 - (src[6 ]+src[9])*5 + (src[5 ]+src[10]));\
+        dst+=dstStride;\
+        src+=srcStride;\
+    }\
+}\
+\
+static void FUNC(OPNAME ## h264_qpel8_v_lowpass)(uint8_t *p_dst, uint8_t *p_src, int dstStride, int srcStride){\
+    const int w=8;\
+    INIT_CLIP\
+    int i;\
+    pixel *dst = (pixel*)p_dst;\
+    pixel *src = (pixel*)p_src;\
+    dstStride >>= sizeof(pixel)-1;\
+    srcStride >>= sizeof(pixel)-1;\
+    for(i=0; i<w; i++)\
+    {\
+        const int srcB= src[-2*srcStride];\
+        const int srcA= src[-1*srcStride];\
+        const int src0= src[0 *srcStride];\
+        const int src1= src[1 *srcStride];\
+        const int src2= src[2 *srcStride];\
+        const int src3= src[3 *srcStride];\
+        const int src4= src[4 *srcStride];\
+        const int src5= src[5 *srcStride];\
+        const int src6= src[6 *srcStride];\
+        const int src7= src[7 *srcStride];\
+        const int src8= src[8 *srcStride];\
+        const int src9= src[9 *srcStride];\
+        const int src10=src[10*srcStride];\
+        OP(dst[0*dstStride], (src0+src1)*20 - (srcA+src2)*5 + (srcB+src3));\
+        OP(dst[1*dstStride], (src1+src2)*20 - (src0+src3)*5 + (srcA+src4));\
+        OP(dst[2*dstStride], (src2+src3)*20 - (src1+src4)*5 + (src0+src5));\
+        OP(dst[3*dstStride], (src3+src4)*20 - (src2+src5)*5 + (src1+src6));\
+        OP(dst[4*dstStride], (src4+src5)*20 - (src3+src6)*5 + (src2+src7));\
+        OP(dst[5*dstStride], (src5+src6)*20 - (src4+src7)*5 + (src3+src8));\
+        OP(dst[6*dstStride], (src6+src7)*20 - (src5+src8)*5 + (src4+src9));\
+        OP(dst[7*dstStride], (src7+src8)*20 - (src6+src9)*5 + (src5+src10));\
+        dst++;\
+        src++;\
+    }\
+}\
+\
+static void FUNC(OPNAME ## h264_qpel8_hv_lowpass)(uint8_t *p_dst, pixeltmp *tmp, uint8_t *p_src, int dstStride, int tmpStride, int srcStride){\
+    const int h=8;\
+    const int w=8;\
+    const int pad = (BIT_DEPTH == 10) ? (-10 * ((1<<BIT_DEPTH)-1)) : 0;\
+    INIT_CLIP\
+    int i;\
+    pixel *dst = (pixel*)p_dst;\
+    pixel *src = (pixel*)p_src;\
+    dstStride >>= sizeof(pixel)-1;\
+    srcStride >>= sizeof(pixel)-1;\
+    src -= 2*srcStride;\
+    for(i=0; i<h+5; i++)\
+    {\
+        tmp[0]= (src[0]+src[1])*20 - (src[-1]+src[2])*5 + (src[-2]+src[3 ]) + pad;\
+        tmp[1]= (src[1]+src[2])*20 - (src[0 ]+src[3])*5 + (src[-1]+src[4 ]) + pad;\
+        tmp[2]= (src[2]+src[3])*20 - (src[1 ]+src[4])*5 + (src[0 ]+src[5 ]) + pad;\
+        tmp[3]= (src[3]+src[4])*20 - (src[2 ]+src[5])*5 + (src[1 ]+src[6 ]) + pad;\
+        tmp[4]= (src[4]+src[5])*20 - (src[3 ]+src[6])*5 + (src[2 ]+src[7 ]) + pad;\
+        tmp[5]= (src[5]+src[6])*20 - (src[4 ]+src[7])*5 + (src[3 ]+src[8 ]) + pad;\
+        tmp[6]= (src[6]+src[7])*20 - (src[5 ]+src[8])*5 + (src[4 ]+src[9 ]) + pad;\
+        tmp[7]= (src[7]+src[8])*20 - (src[6 ]+src[9])*5 + (src[5 ]+src[10]) + pad;\
+        tmp+=tmpStride;\
+        src+=srcStride;\
+    }\
+    tmp -= tmpStride*(h+5-2);\
+    for(i=0; i<w; i++)\
+    {\
+        const int tmpB= tmp[-2*tmpStride] - pad;\
+        const int tmpA= tmp[-1*tmpStride] - pad;\
+        const int tmp0= tmp[0 *tmpStride] - pad;\
+        const int tmp1= tmp[1 *tmpStride] - pad;\
+        const int tmp2= tmp[2 *tmpStride] - pad;\
+        const int tmp3= tmp[3 *tmpStride] - pad;\
+        const int tmp4= tmp[4 *tmpStride] - pad;\
+        const int tmp5= tmp[5 *tmpStride] - pad;\
+        const int tmp6= tmp[6 *tmpStride] - pad;\
+        const int tmp7= tmp[7 *tmpStride] - pad;\
+        const int tmp8= tmp[8 *tmpStride] - pad;\
+        const int tmp9= tmp[9 *tmpStride] - pad;\
+        const int tmp10=tmp[10*tmpStride] - pad;\
+        OP2(dst[0*dstStride], (tmp0+tmp1)*20 - (tmpA+tmp2)*5 + (tmpB+tmp3));\
+        OP2(dst[1*dstStride], (tmp1+tmp2)*20 - (tmp0+tmp3)*5 + (tmpA+tmp4));\
+        OP2(dst[2*dstStride], (tmp2+tmp3)*20 - (tmp1+tmp4)*5 + (tmp0+tmp5));\
+        OP2(dst[3*dstStride], (tmp3+tmp4)*20 - (tmp2+tmp5)*5 + (tmp1+tmp6));\
+        OP2(dst[4*dstStride], (tmp4+tmp5)*20 - (tmp3+tmp6)*5 + (tmp2+tmp7));\
+        OP2(dst[5*dstStride], (tmp5+tmp6)*20 - (tmp4+tmp7)*5 + (tmp3+tmp8));\
+        OP2(dst[6*dstStride], (tmp6+tmp7)*20 - (tmp5+tmp8)*5 + (tmp4+tmp9));\
+        OP2(dst[7*dstStride], (tmp7+tmp8)*20 - (tmp6+tmp9)*5 + (tmp5+tmp10));\
+        dst++;\
+        tmp++;\
+    }\
+}\
+\
+static void FUNC(OPNAME ## h264_qpel16_v_lowpass)(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\
+    FUNC(OPNAME ## h264_qpel8_v_lowpass)(dst                , src                , dstStride, srcStride);\
+    FUNC(OPNAME ## h264_qpel8_v_lowpass)(dst+8*sizeof(pixel), src+8*sizeof(pixel), dstStride, srcStride);\
+    src += 8*srcStride;\
+    dst += 8*dstStride;\
+    FUNC(OPNAME ## h264_qpel8_v_lowpass)(dst                , src                , dstStride, srcStride);\
+    FUNC(OPNAME ## h264_qpel8_v_lowpass)(dst+8*sizeof(pixel), src+8*sizeof(pixel), dstStride, srcStride);\
+}\
+\
+static void FUNC(OPNAME ## h264_qpel16_h_lowpass)(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\
+    FUNC(OPNAME ## h264_qpel8_h_lowpass)(dst                , src                , dstStride, srcStride);\
+    FUNC(OPNAME ## h264_qpel8_h_lowpass)(dst+8*sizeof(pixel), src+8*sizeof(pixel), dstStride, srcStride);\
+    src += 8*srcStride;\
+    dst += 8*dstStride;\
+    FUNC(OPNAME ## h264_qpel8_h_lowpass)(dst                , src                , dstStride, srcStride);\
+    FUNC(OPNAME ## h264_qpel8_h_lowpass)(dst+8*sizeof(pixel), src+8*sizeof(pixel), dstStride, srcStride);\
+}\
+\
+static void FUNC(OPNAME ## h264_qpel16_hv_lowpass)(uint8_t *dst, pixeltmp *tmp, uint8_t *src, int dstStride, int tmpStride, int srcStride){\
+    FUNC(OPNAME ## h264_qpel8_hv_lowpass)(dst                , tmp  , src                , dstStride, tmpStride, srcStride);\
+    FUNC(OPNAME ## h264_qpel8_hv_lowpass)(dst+8*sizeof(pixel), tmp+8, src+8*sizeof(pixel), dstStride, tmpStride, srcStride);\
+    src += 8*srcStride;\
+    dst += 8*dstStride;\
+    FUNC(OPNAME ## h264_qpel8_hv_lowpass)(dst                , tmp  , src                , dstStride, tmpStride, srcStride);\
+    FUNC(OPNAME ## h264_qpel8_hv_lowpass)(dst+8*sizeof(pixel), tmp+8, src+8*sizeof(pixel), dstStride, tmpStride, srcStride);\
+}\
+
+#define H264_MC(OPNAME, SIZE) \
+static av_unused void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc00)(uint8_t *dst, uint8_t *src, int stride){\
+    FUNCC(OPNAME ## pixels ## SIZE)(dst, src, stride, SIZE);\
+}\
+\
+static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc10)(uint8_t *dst, uint8_t *src, int stride){\
+    uint8_t half[SIZE*SIZE*sizeof(pixel)];\
+    FUNC(put_h264_qpel ## SIZE ## _h_lowpass)(half, src, SIZE*sizeof(pixel), stride);\
+    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, src, half, stride, stride, SIZE*sizeof(pixel), SIZE);\
+}\
+\
+static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc20)(uint8_t *dst, uint8_t *src, int stride){\
+    FUNC(OPNAME ## h264_qpel ## SIZE ## _h_lowpass)(dst, src, stride, stride);\
+}\
+\
+static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc30)(uint8_t *dst, uint8_t *src, int stride){\
+    uint8_t half[SIZE*SIZE*sizeof(pixel)];\
+    FUNC(put_h264_qpel ## SIZE ## _h_lowpass)(half, src, SIZE*sizeof(pixel), stride);\
+    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, src+sizeof(pixel), half, stride, stride, SIZE*sizeof(pixel), SIZE);\
+}\
+\
+static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc01)(uint8_t *dst, uint8_t *src, int stride){\
+    uint8_t full[SIZE*(SIZE+5)*sizeof(pixel)];\
+    uint8_t * const full_mid= full + SIZE*2*sizeof(pixel);\
+    uint8_t half[SIZE*SIZE*sizeof(pixel)];\
+    FUNC(copy_block ## SIZE )(full, src - stride*2, SIZE*sizeof(pixel),  stride, SIZE + 5);\
+    FUNC(put_h264_qpel ## SIZE ## _v_lowpass)(half, full_mid, SIZE*sizeof(pixel), SIZE*sizeof(pixel));\
+    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, full_mid, half, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\
+}\
+\
+static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc02)(uint8_t *dst, uint8_t *src, int stride){\
+    uint8_t full[SIZE*(SIZE+5)*sizeof(pixel)];\
+    uint8_t * const full_mid= full + SIZE*2*sizeof(pixel);\
+    FUNC(copy_block ## SIZE )(full, src - stride*2, SIZE*sizeof(pixel),  stride, SIZE + 5);\
+    FUNC(OPNAME ## h264_qpel ## SIZE ## _v_lowpass)(dst, full_mid, stride, SIZE*sizeof(pixel));\
+}\
+\
+static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc03)(uint8_t *dst, uint8_t *src, int stride){\
+    uint8_t full[SIZE*(SIZE+5)*sizeof(pixel)];\
+    uint8_t * const full_mid= full + SIZE*2*sizeof(pixel);\
+    uint8_t half[SIZE*SIZE*sizeof(pixel)];\
+    FUNC(copy_block ## SIZE )(full, src - stride*2, SIZE*sizeof(pixel),  stride, SIZE + 5);\
+    FUNC(put_h264_qpel ## SIZE ## _v_lowpass)(half, full_mid, SIZE*sizeof(pixel), SIZE*sizeof(pixel));\
+    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, full_mid+SIZE*sizeof(pixel), half, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\
+}\
+\
+static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc11)(uint8_t *dst, uint8_t *src, int stride){\
+    uint8_t full[SIZE*(SIZE+5)*sizeof(pixel)];\
+    uint8_t * const full_mid= full + SIZE*2*sizeof(pixel);\
+    uint8_t halfH[SIZE*SIZE*sizeof(pixel)];\
+    uint8_t halfV[SIZE*SIZE*sizeof(pixel)];\
+    FUNC(put_h264_qpel ## SIZE ## _h_lowpass)(halfH, src, SIZE*sizeof(pixel), stride);\
+    FUNC(copy_block ## SIZE )(full, src - stride*2, SIZE*sizeof(pixel),  stride, SIZE + 5);\
+    FUNC(put_h264_qpel ## SIZE ## _v_lowpass)(halfV, full_mid, SIZE*sizeof(pixel), SIZE*sizeof(pixel));\
+    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, halfH, halfV, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\
+}\
+\
+static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc31)(uint8_t *dst, uint8_t *src, int stride){\
+    uint8_t full[SIZE*(SIZE+5)*sizeof(pixel)];\
+    uint8_t * const full_mid= full + SIZE*2*sizeof(pixel);\
+    uint8_t halfH[SIZE*SIZE*sizeof(pixel)];\
+    uint8_t halfV[SIZE*SIZE*sizeof(pixel)];\
+    FUNC(put_h264_qpel ## SIZE ## _h_lowpass)(halfH, src, SIZE*sizeof(pixel), stride);\
+    FUNC(copy_block ## SIZE )(full, src - stride*2 + sizeof(pixel), SIZE*sizeof(pixel),  stride, SIZE + 5);\
+    FUNC(put_h264_qpel ## SIZE ## _v_lowpass)(halfV, full_mid, SIZE*sizeof(pixel), SIZE*sizeof(pixel));\
+    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, halfH, halfV, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\
+}\
+\
+static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc13)(uint8_t *dst, uint8_t *src, int stride){\
+    uint8_t full[SIZE*(SIZE+5)*sizeof(pixel)];\
+    uint8_t * const full_mid= full + SIZE*2*sizeof(pixel);\
+    uint8_t halfH[SIZE*SIZE*sizeof(pixel)];\
+    uint8_t halfV[SIZE*SIZE*sizeof(pixel)];\
+    FUNC(put_h264_qpel ## SIZE ## _h_lowpass)(halfH, src + stride, SIZE*sizeof(pixel), stride);\
+    FUNC(copy_block ## SIZE )(full, src - stride*2, SIZE*sizeof(pixel),  stride, SIZE + 5);\
+    FUNC(put_h264_qpel ## SIZE ## _v_lowpass)(halfV, full_mid, SIZE*sizeof(pixel), SIZE*sizeof(pixel));\
+    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, halfH, halfV, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\
+}\
+\
+static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc33)(uint8_t *dst, uint8_t *src, int stride){\
+    uint8_t full[SIZE*(SIZE+5)*sizeof(pixel)];\
+    uint8_t * const full_mid= full + SIZE*2*sizeof(pixel);\
+    uint8_t halfH[SIZE*SIZE*sizeof(pixel)];\
+    uint8_t halfV[SIZE*SIZE*sizeof(pixel)];\
+    FUNC(put_h264_qpel ## SIZE ## _h_lowpass)(halfH, src + stride, SIZE*sizeof(pixel), stride);\
+    FUNC(copy_block ## SIZE )(full, src - stride*2 + sizeof(pixel), SIZE*sizeof(pixel),  stride, SIZE + 5);\
+    FUNC(put_h264_qpel ## SIZE ## _v_lowpass)(halfV, full_mid, SIZE*sizeof(pixel), SIZE*sizeof(pixel));\
+    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, halfH, halfV, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\
+}\
+\
+static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc22)(uint8_t *dst, uint8_t *src, int stride){\
+    pixeltmp tmp[SIZE*(SIZE+5)*sizeof(pixel)];\
+    FUNC(OPNAME ## h264_qpel ## SIZE ## _hv_lowpass)(dst, tmp, src, stride, SIZE*sizeof(pixel), stride);\
+}\
+\
+static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc21)(uint8_t *dst, uint8_t *src, int stride){\
+    pixeltmp tmp[SIZE*(SIZE+5)*sizeof(pixel)];\
+    uint8_t halfH[SIZE*SIZE*sizeof(pixel)];\
+    uint8_t halfHV[SIZE*SIZE*sizeof(pixel)];\
+    FUNC(put_h264_qpel ## SIZE ## _h_lowpass)(halfH, src, SIZE*sizeof(pixel), stride);\
+    FUNC(put_h264_qpel ## SIZE ## _hv_lowpass)(halfHV, tmp, src, SIZE*sizeof(pixel), SIZE*sizeof(pixel), stride);\
+    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, halfH, halfHV, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\
+}\
+\
+static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc23)(uint8_t *dst, uint8_t *src, int stride){\
+    pixeltmp tmp[SIZE*(SIZE+5)*sizeof(pixel)];\
+    uint8_t halfH[SIZE*SIZE*sizeof(pixel)];\
+    uint8_t halfHV[SIZE*SIZE*sizeof(pixel)];\
+    FUNC(put_h264_qpel ## SIZE ## _h_lowpass)(halfH, src + stride, SIZE*sizeof(pixel), stride);\
+    FUNC(put_h264_qpel ## SIZE ## _hv_lowpass)(halfHV, tmp, src, SIZE*sizeof(pixel), SIZE*sizeof(pixel), stride);\
+    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, halfH, halfHV, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\
+}\
+\
+static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc12)(uint8_t *dst, uint8_t *src, int stride){\
+    uint8_t full[SIZE*(SIZE+5)*sizeof(pixel)];\
+    uint8_t * const full_mid= full + SIZE*2*sizeof(pixel);\
+    pixeltmp tmp[SIZE*(SIZE+5)*sizeof(pixel)];\
+    uint8_t halfV[SIZE*SIZE*sizeof(pixel)];\
+    uint8_t halfHV[SIZE*SIZE*sizeof(pixel)];\
+    FUNC(copy_block ## SIZE )(full, src - stride*2, SIZE*sizeof(pixel),  stride, SIZE + 5);\
+    FUNC(put_h264_qpel ## SIZE ## _v_lowpass)(halfV, full_mid, SIZE*sizeof(pixel), SIZE*sizeof(pixel));\
+    FUNC(put_h264_qpel ## SIZE ## _hv_lowpass)(halfHV, tmp, src, SIZE*sizeof(pixel), SIZE*sizeof(pixel), stride);\
+    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, halfV, halfHV, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\
+}\
+\
+static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc32)(uint8_t *dst, uint8_t *src, int stride){\
+    uint8_t full[SIZE*(SIZE+5)*sizeof(pixel)];\
+    uint8_t * const full_mid= full + SIZE*2*sizeof(pixel);\
+    pixeltmp tmp[SIZE*(SIZE+5)*sizeof(pixel)];\
+    uint8_t halfV[SIZE*SIZE*sizeof(pixel)];\
+    uint8_t halfHV[SIZE*SIZE*sizeof(pixel)];\
+    FUNC(copy_block ## SIZE )(full, src - stride*2 + sizeof(pixel), SIZE*sizeof(pixel),  stride, SIZE + 5);\
+    FUNC(put_h264_qpel ## SIZE ## _v_lowpass)(halfV, full_mid, SIZE*sizeof(pixel), SIZE*sizeof(pixel));\
+    FUNC(put_h264_qpel ## SIZE ## _hv_lowpass)(halfHV, tmp, src, SIZE*sizeof(pixel), SIZE*sizeof(pixel), stride);\
+    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, halfV, halfHV, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\
+}\
+
+#define op_avg(a, b)  a = (((a)+CLIP(((b) + 16)>>5)+1)>>1)
+//#define op_avg2(a, b) a = (((a)*w1+cm[((b) + 16)>>5]*w2 + o + 64)>>7)
+#define op_put(a, b)  a = CLIP(((b) + 16)>>5)
+#define op2_avg(a, b)  a = (((a)+CLIP(((b) + 512)>>10)+1)>>1)
+#define op2_put(a, b)  a = CLIP(((b) + 512)>>10)
+
+H264_LOWPASS(put_       , op_put, op2_put)
+H264_LOWPASS(avg_       , op_avg, op2_avg)
+H264_MC(put_, 2)
+H264_MC(put_, 4)
+H264_MC(put_, 8)
+H264_MC(put_, 16)
+H264_MC(avg_, 4)
+H264_MC(avg_, 8)
+H264_MC(avg_, 16)
+
+#undef op_avg
+#undef op_put
+#undef op2_avg
+#undef op2_put
+
+#if BIT_DEPTH == 8
+#   define put_h264_qpel8_mc00_8_c  ff_put_pixels8x8_8_c
+#   define avg_h264_qpel8_mc00_8_c  ff_avg_pixels8x8_8_c
+#   define put_h264_qpel16_mc00_8_c ff_put_pixels16x16_8_c
+#   define avg_h264_qpel16_mc00_8_c ff_avg_pixels16x16_8_c
+#elif BIT_DEPTH == 9
+#   define put_h264_qpel8_mc00_9_c  ff_put_pixels8x8_9_c
+#   define avg_h264_qpel8_mc00_9_c  ff_avg_pixels8x8_9_c
+#   define put_h264_qpel16_mc00_9_c ff_put_pixels16x16_9_c
+#   define avg_h264_qpel16_mc00_9_c ff_avg_pixels16x16_9_c
+#elif BIT_DEPTH == 10
+#   define put_h264_qpel8_mc00_10_c  ff_put_pixels8x8_10_c
+#   define avg_h264_qpel8_mc00_10_c  ff_avg_pixels8x8_10_c
+#   define put_h264_qpel16_mc00_10_c ff_put_pixels16x16_10_c
+#   define avg_h264_qpel16_mc00_10_c ff_avg_pixels16x16_10_c
+#elif BIT_DEPTH == 12
+#   define put_h264_qpel8_mc00_12_c  ff_put_pixels8x8_12_c
+#   define avg_h264_qpel8_mc00_12_c  ff_avg_pixels8x8_12_c
+#   define put_h264_qpel16_mc00_12_c ff_put_pixels16x16_12_c
+#   define avg_h264_qpel16_mc00_12_c ff_avg_pixels16x16_12_c
+#elif BIT_DEPTH == 14
+#   define put_h264_qpel8_mc00_14_c  ff_put_pixels8x8_14_c
+#   define avg_h264_qpel8_mc00_14_c  ff_avg_pixels8x8_14_c
+#   define put_h264_qpel16_mc00_14_c ff_put_pixels16x16_14_c
+#   define avg_h264_qpel16_mc00_14_c ff_avg_pixels16x16_14_c
+#endif
diff --git a/libavcodec/hpel_template.c b/libavcodec/hpel_template.c
new file mode 100644
index 0000000..3b46999
--- /dev/null
+++ b/libavcodec/hpel_template.c
@@ -0,0 +1,100 @@
+/*
+ * 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
+ */
+
+#define DEF_HPEL(OPNAME, OP) \
+static inline void FUNCC(OPNAME ## _pixels2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){\
+    int i;\
+    for(i=0; i<h; i++){\
+        OP(*((pixel2*)(block  )), AV_RN2P(pixels  ));\
+        pixels+=line_size;\
+        block +=line_size;\
+    }\
+}\
+static inline void FUNCC(OPNAME ## _pixels4)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){\
+    int i;\
+    for(i=0; i<h; i++){\
+        OP(*((pixel4*)(block  )), AV_RN4P(pixels  ));\
+        pixels+=line_size;\
+        block +=line_size;\
+    }\
+}\
+static inline void FUNCC(OPNAME ## _pixels8)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){\
+    int i;\
+    for(i=0; i<h; i++){\
+        OP(*((pixel4*)(block                )), AV_RN4P(pixels                ));\
+        OP(*((pixel4*)(block+4*sizeof(pixel))), AV_RN4P(pixels+4*sizeof(pixel)));\
+        pixels+=line_size;\
+        block +=line_size;\
+    }\
+}\
+\
+static inline void FUNC(OPNAME ## _pixels8_l2)(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, \
+                                                int src_stride1, int src_stride2, int h){\
+    int i;\
+    for(i=0; i<h; i++){\
+        pixel4 a,b;\
+        a= AV_RN4P(&src1[i*src_stride1  ]);\
+        b= AV_RN4P(&src2[i*src_stride2  ]);\
+        OP(*((pixel4*)&dst[i*dst_stride  ]), rnd_avg_pixel4(a, b));\
+        a= AV_RN4P(&src1[i*src_stride1+4*sizeof(pixel)]);\
+        b= AV_RN4P(&src2[i*src_stride2+4*sizeof(pixel)]);\
+        OP(*((pixel4*)&dst[i*dst_stride+4*sizeof(pixel)]), rnd_avg_pixel4(a, b));\
+    }\
+}\
+\
+static inline void FUNC(OPNAME ## _pixels4_l2)(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, \
+                                                int src_stride1, int src_stride2, int h){\
+    int i;\
+    for(i=0; i<h; i++){\
+        pixel4 a,b;\
+        a= AV_RN4P(&src1[i*src_stride1  ]);\
+        b= AV_RN4P(&src2[i*src_stride2  ]);\
+        OP(*((pixel4*)&dst[i*dst_stride  ]), rnd_avg_pixel4(a, b));\
+    }\
+}\
+\
+static inline void FUNC(OPNAME ## _pixels2_l2)(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, \
+                                                int src_stride1, int src_stride2, int h){\
+    int i;\
+    for(i=0; i<h; i++){\
+        pixel4 a,b;\
+        a= AV_RN2P(&src1[i*src_stride1  ]);\
+        b= AV_RN2P(&src2[i*src_stride2  ]);\
+        OP(*((pixel2*)&dst[i*dst_stride  ]), rnd_avg_pixel4(a, b));\
+    }\
+}\
+\
+static inline void FUNC(OPNAME ## _pixels16_l2)(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, \
+                                                int src_stride1, int src_stride2, int h){\
+    FUNC(OPNAME ## _pixels8_l2)(dst  , src1  , src2  , dst_stride, src_stride1, src_stride2, h);\
+    FUNC(OPNAME ## _pixels8_l2)(dst+8*sizeof(pixel), src1+8*sizeof(pixel), src2+8*sizeof(pixel), dst_stride, src_stride1, src_stride2, h);\
+}\
+\
+CALL_2X_PIXELS(FUNCC(OPNAME ## _pixels16)    , FUNCC(OPNAME ## _pixels8)    , 8*sizeof(pixel))
+
+
+#define op_avg(a, b) a = rnd_avg_pixel4(a, b)
+#define op_put(a, b) a = b
+
+DEF_HPEL(avg, op_avg)
+DEF_HPEL(put, op_put)
+#undef op_avg
+#undef op_put
diff --git a/libavcodec/huffyuv.c b/libavcodec/huffyuv.c
index ca5bcd8..b4ef76f 100644
--- a/libavcodec/huffyuv.c
+++ b/libavcodec/huffyuv.c
@@ -28,216 +28,14 @@
  * huffyuv codec for libavcodec.
  */
 
+#include <stdint.h>
+
+#include "libavutil/mem.h"
+
 #include "avcodec.h"
-#include "internal.h"
-#include "get_bits.h"
-#include "put_bits.h"
-#include "dsputil.h"
-#include "thread.h"
-#include "huffman.h"
+#include "huffyuv.h"
 
-#define VLC_BITS 11
-
-#if HAVE_BIGENDIAN
-#define B 3
-#define G 2
-#define R 1
-#define A 0
-#else
-#define B 0
-#define G 1
-#define R 2
-#define A 3
-#endif
-
-typedef enum Predictor {
-    LEFT= 0,
-    PLANE,
-    MEDIAN,
-} Predictor;
-
-typedef struct HYuvContext {
-    AVCodecContext *avctx;
-    Predictor predictor;
-    GetBitContext gb;
-    PutBitContext pb;
-    int interlaced;
-    int decorrelate;
-    int bitstream_bpp;
-    int version;
-    int yuy2;                               //use yuy2 instead of 422P
-    int bgr32;                              //use bgr32 instead of bgr24
-    int width, height;
-    int flags;
-    int context;
-    int picture_number;
-    int last_slice_end;
-    uint8_t *temp[3];
-    uint64_t stats[3][256];
-    uint8_t len[3][256];
-    uint32_t bits[3][256];
-    uint32_t pix_bgr_map[1<<VLC_BITS];
-    VLC vlc[6];                             //Y,U,V,YY,YU,YV
-    AVFrame picture;
-    uint8_t *bitstream_buffer;
-    unsigned int bitstream_buffer_size;
-    DSPContext dsp;
-} HYuvContext;
-
-#define classic_shift_luma_table_size 42
-static const unsigned char classic_shift_luma[classic_shift_luma_table_size + FF_INPUT_BUFFER_PADDING_SIZE] = {
-  34,36,35,69,135,232,9,16,10,24,11,23,12,16,13,10,14,8,15,8,
-  16,8,17,20,16,10,207,206,205,236,11,8,10,21,9,23,8,8,199,70,
-  69,68, 0,
-  0,0,0,0,0,0,0,0,
-};
-
-#define classic_shift_chroma_table_size 59
-static const unsigned char classic_shift_chroma[classic_shift_chroma_table_size + FF_INPUT_BUFFER_PADDING_SIZE] = {
-  66,36,37,38,39,40,41,75,76,77,110,239,144,81,82,83,84,85,118,183,
-  56,57,88,89,56,89,154,57,58,57,26,141,57,56,58,57,58,57,184,119,
-  214,245,116,83,82,49,80,79,78,77,44,75,41,40,39,38,37,36,34, 0,
-  0,0,0,0,0,0,0,0,
-};
-
-static const unsigned char classic_add_luma[256] = {
-    3,  9,  5, 12, 10, 35, 32, 29, 27, 50, 48, 45, 44, 41, 39, 37,
-   73, 70, 68, 65, 64, 61, 58, 56, 53, 50, 49, 46, 44, 41, 38, 36,
-   68, 65, 63, 61, 58, 55, 53, 51, 48, 46, 45, 43, 41, 39, 38, 36,
-   35, 33, 32, 30, 29, 27, 26, 25, 48, 47, 46, 44, 43, 41, 40, 39,
-   37, 36, 35, 34, 32, 31, 30, 28, 27, 26, 24, 23, 22, 20, 19, 37,
-   35, 34, 33, 31, 30, 29, 27, 26, 24, 23, 21, 20, 18, 17, 15, 29,
-   27, 26, 24, 22, 21, 19, 17, 16, 14, 26, 25, 23, 21, 19, 18, 16,
-   15, 27, 25, 23, 21, 19, 17, 16, 14, 26, 25, 23, 21, 18, 17, 14,
-   12, 17, 19, 13,  4,  9,  2, 11,  1,  7,  8,  0, 16,  3, 14,  6,
-   12, 10,  5, 15, 18, 11, 10, 13, 15, 16, 19, 20, 22, 24, 27, 15,
-   18, 20, 22, 24, 26, 14, 17, 20, 22, 24, 27, 15, 18, 20, 23, 25,
-   28, 16, 19, 22, 25, 28, 32, 36, 21, 25, 29, 33, 38, 42, 45, 49,
-   28, 31, 34, 37, 40, 42, 44, 47, 49, 50, 52, 54, 56, 57, 59, 60,
-   62, 64, 66, 67, 69, 35, 37, 39, 40, 42, 43, 45, 47, 48, 51, 52,
-   54, 55, 57, 59, 60, 62, 63, 66, 67, 69, 71, 72, 38, 40, 42, 43,
-   46, 47, 49, 51, 26, 28, 30, 31, 33, 34, 18, 19, 11, 13,  7,  8,
-};
-
-static const unsigned char classic_add_chroma[256] = {
-    3,  1,  2,  2,  2,  2,  3,  3,  7,  5,  7,  5,  8,  6, 11,  9,
-    7, 13, 11, 10,  9,  8,  7,  5,  9,  7,  6,  4,  7,  5,  8,  7,
-   11,  8, 13, 11, 19, 15, 22, 23, 20, 33, 32, 28, 27, 29, 51, 77,
-   43, 45, 76, 81, 46, 82, 75, 55, 56,144, 58, 80, 60, 74,147, 63,
-  143, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
-   80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 27, 30, 21, 22,
-   17, 14,  5,  6,100, 54, 47, 50, 51, 53,106,107,108,109,110,111,
-  112,113,114,115,  4,117,118, 92, 94,121,122,  3,124,103,  2,  1,
-    0,129,130,131,120,119,126,125,136,137,138,139,140,141,142,134,
-  135,132,133,104, 64,101, 62, 57,102, 95, 93, 59, 61, 28, 97, 96,
-   52, 49, 48, 29, 32, 25, 24, 46, 23, 98, 45, 44, 43, 20, 42, 41,
-   19, 18, 99, 40, 15, 39, 38, 16, 13, 12, 11, 37, 10,  9,  8, 36,
-    7,128,127,105,123,116, 35, 34, 33,145, 31, 79, 42,146, 78, 26,
-   83, 48, 49, 50, 44, 47, 26, 31, 30, 18, 17, 19, 21, 24, 25, 13,
-   14, 16, 17, 18, 20, 21, 12, 14, 15,  9, 10,  6,  9,  6,  5,  8,
-    6, 12,  8, 10,  7,  9,  6,  4,  6,  2,  2,  3,  3,  3,  3,  2,
-};
-
-static inline int sub_left_prediction(HYuvContext *s, uint8_t *dst,
-                                      const uint8_t *src, int w, int left)
-{
-    int i;
-    if (w < 32) {
-        for (i = 0; i < w; i++) {
-            const int temp = src[i];
-            dst[i] = temp - left;
-            left   = temp;
-        }
-        return left;
-    } else {
-        for (i = 0; i < 16; i++) {
-            const int temp = src[i];
-            dst[i] = temp - left;
-            left   = temp;
-        }
-        s->dsp.diff_bytes(dst + 16, src + 16, src + 15, w - 16);
-        return src[w-1];
-    }
-}
-
-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 i;
-    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];
-        const int bt = src[i * 4 + B];
-        const int at = src[i * 4 + A];
-        dst[i * 4 + R] = rt - r;
-        dst[i * 4 + G] = gt - g;
-        dst[i * 4 + B] = bt - b;
-        dst[i * 4 + A] = at - a;
-        r = rt;
-        g = gt;
-        b = bt;
-        a = at;
-    }
-
-    s->dsp.diff_bytes(dst + 16, src + 16, src + 12, w * 4 - 16);
-
-    *red   = src[(w - 1) * 4 + R];
-    *green = src[(w - 1) * 4 + G];
-    *blue  = src[(w - 1) * 4 + B];
-    *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){
-    int i;
-    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;
-        r = rt;
-        g = gt;
-        b = bt;
-    }
-
-    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];
-}
-
-static int read_len_table(uint8_t *dst, GetBitContext *gb)
-{
-    int i, val, repeat;
-
-    for (i = 0; i < 256;) {
-        repeat = get_bits(gb, 3);
-        val    = get_bits(gb, 5);
-        if (repeat == 0)
-            repeat = get_bits(gb, 8);
-        if (i + repeat > 256 || get_bits_left(gb) < 0) {
-            av_log(NULL, AV_LOG_ERROR, "Error reading huffman table\n");
-            return -1;
-        }
-        while (repeat--)
-            dst[i++] = val;
-    }
-    return 0;
-}
-
-static int generate_bits_table(uint32_t *dst, const uint8_t *len_table)
+int ff_huffyuv_generate_bits_table(uint32_t *dst, const uint8_t *len_table)
 {
     int len, index;
     uint32_t bits = 0;
@@ -256,150 +54,25 @@
     return 0;
 }
 
-static void generate_joint_tables(HYuvContext *s)
-{
-    uint16_t symbols[1 << VLC_BITS];
-    uint16_t bits[1 << VLC_BITS];
-    uint8_t len[1 << VLC_BITS];
-    if (s->bitstream_bpp < 24) {
-        int p, i, y, u;
-        for (p = 0; p < 3; p++) {
-            for (i = y = 0; y < 256; y++) {
-                int len0 = s->len[0][y];
-                int limit = VLC_BITS - len0;
-                if(limit <= 0)
-                    continue;
-                for (u = 0; u < 256; u++) {
-                    int len1 = s->len[p][u];
-                    if (len1 > limit)
-                        continue;
-                    len[i] = len0 + len1;
-                    bits[i] = (s->bits[0][y] << len1) + s->bits[p][u];
-                    symbols[i] = (y << 8) + u;
-                    if(symbols[i] != 0xffff) // reserved to mean "invalid"
-                        i++;
-                }
-            }
-            ff_free_vlc(&s->vlc[3 + p]);
-            ff_init_vlc_sparse(&s->vlc[3 + p], VLC_BITS, i, len, 1, 1,
-                               bits, 2, 2, symbols, 2, 2, 0);
-        }
-    } else {
-        uint8_t (*map)[4] = (uint8_t(*)[4])s->pix_bgr_map;
-        int i, b, g, r, code;
-        int p0 = s->decorrelate;
-        int p1 = !s->decorrelate;
-        // restrict the range to +/-16 because that's pretty much guaranteed to
-        // cover all the combinations that fit in 11 bits total, and it doesn't
-        // matter if we miss a few rare codes.
-        for (i = 0, g = -16; g < 16; g++) {
-            int len0 = s->len[p0][g & 255];
-            int limit0 = VLC_BITS - len0;
-            if (limit0 < 2)
-                continue;
-            for (b = -16; b < 16; b++) {
-                int len1 = s->len[p1][b & 255];
-                int limit1 = limit0 - len1;
-                if (limit1 < 1)
-                    continue;
-                code = (s->bits[p0][g & 255] << len1) + s->bits[p1][b & 255];
-                for (r = -16; r < 16; r++) {
-                    int len2 = s->len[2][r & 255];
-                    if (len2 > limit1)
-                        continue;
-                    len[i] = len0 + len1 + len2;
-                    bits[i] = (code << len2) + s->bits[2][r & 255];
-                    if (s->decorrelate) {
-                        map[i][G] = g;
-                        map[i][B] = g + b;
-                        map[i][R] = g + r;
-                    } else {
-                        map[i][B] = g;
-                        map[i][G] = b;
-                        map[i][R] = r;
-                    }
-                    i++;
-                }
-            }
-        }
-        ff_free_vlc(&s->vlc[3]);
-        init_vlc(&s->vlc[3], VLC_BITS, i, len, 1, 1, bits, 2, 2, 0);
-    }
-}
-
-static int read_huffman_tables(HYuvContext *s, const uint8_t *src, int length)
-{
-    GetBitContext gb;
-    int i;
-
-    init_get_bits(&gb, src, length * 8);
-
-    for (i = 0; i < 3; i++) {
-        if (read_len_table(s->len[i], &gb) < 0)
-            return -1;
-        if (generate_bits_table(s->bits[i], s->len[i]) < 0) {
-            return -1;
-        }
-        ff_free_vlc(&s->vlc[i]);
-        init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1,
-                 s->bits[i], 4, 4, 0);
-    }
-
-    generate_joint_tables(s);
-
-    return (get_bits_count(&gb) + 7) / 8;
-}
-
-static int read_old_huffman_tables(HYuvContext *s)
-{
-    GetBitContext gb;
-    int i;
-
-    init_get_bits(&gb, classic_shift_luma,
-                  classic_shift_luma_table_size * 8);
-    if (read_len_table(s->len[0], &gb) < 0)
-        return -1;
-
-    init_get_bits(&gb, classic_shift_chroma,
-                  classic_shift_chroma_table_size * 8);
-    if (read_len_table(s->len[1], &gb) < 0)
-        return -1;
-
-    for(i=0; i<256; i++) s->bits[0][i] = classic_add_luma  [i];
-    for(i=0; i<256; i++) s->bits[1][i] = classic_add_chroma[i];
-
-    if (s->bitstream_bpp >= 24) {
-        memcpy(s->bits[1], s->bits[0], 256 * sizeof(uint32_t));
-        memcpy(s->len[1] , s->len [0], 256 * sizeof(uint8_t));
-    }
-    memcpy(s->bits[2], s->bits[1], 256 * sizeof(uint32_t));
-    memcpy(s->len[2] , s->len [1], 256 * sizeof(uint8_t));
-
-    for (i = 0; i < 3; i++) {
-        ff_free_vlc(&s->vlc[i]);
-        init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1,
-                 s->bits[i], 4, 4, 0);
-    }
-
-    generate_joint_tables(s);
-
-    return 0;
-}
-
-static av_cold void alloc_temp(HYuvContext *s)
+av_cold int ff_huffyuv_alloc_temp(HYuvContext *s)
 {
     int i;
 
     if (s->bitstream_bpp<24) {
         for (i=0; i<3; i++) {
             s->temp[i]= av_malloc(s->width + 16);
+            if (!s->temp[i])
+                return AVERROR(ENOMEM);
         }
     } else {
         s->temp[0]= av_mallocz(4*s->width + 16);
+        if (!s->temp[0])
+            return AVERROR(ENOMEM);
     }
+    return 0;
 }
 
-static av_cold int common_init(AVCodecContext *avctx)
+av_cold void ff_huffyuv_common_init(AVCodecContext *avctx)
 {
     HYuvContext *s = avctx->priv_data;
 
@@ -410,1165 +83,15 @@
 
     s->width = avctx->width;
     s->height = avctx->height;
+
     av_assert1(s->width > 0 && s->height > 0);
-
-    return 0;
 }
 
-#if CONFIG_HUFFYUV_DECODER || CONFIG_FFVHUFF_DECODER
-static av_cold int decode_init(AVCodecContext *avctx)
-{
-    HYuvContext *s = avctx->priv_data;
-
-    common_init(avctx);
-    memset(s->vlc, 0, 3 * sizeof(VLC));
-
-    avctx->coded_frame = &s->picture;
-    avcodec_get_frame_defaults(&s->picture);
-    s->interlaced = s->height > 288;
-
-    s->bgr32 = 1;
-
-    if (avctx->extradata_size) {
-        if ((avctx->bits_per_coded_sample & 7) &&
-            avctx->bits_per_coded_sample != 12)
-            s->version = 1; // do such files exist at all?
-        else
-            s->version = 2;
-    } else
-        s->version = 0;
-
-    if (s->version == 2) {
-        int method, interlace;
-
-        if (avctx->extradata_size < 4)
-            return -1;
-
-        method = ((uint8_t*)avctx->extradata)[0];
-        s->decorrelate = method & 64 ? 1 : 0;
-        s->predictor = method & 63;
-        s->bitstream_bpp = ((uint8_t*)avctx->extradata)[1];
-        if (s->bitstream_bpp == 0)
-            s->bitstream_bpp = avctx->bits_per_coded_sample & ~7;
-        interlace = (((uint8_t*)avctx->extradata)[2] & 0x30) >> 4;
-        s->interlaced = (interlace == 1) ? 1 : (interlace == 2) ? 0 : s->interlaced;
-        s->context = ((uint8_t*)avctx->extradata)[2] & 0x40 ? 1 : 0;
-
-        if ( read_huffman_tables(s, ((uint8_t*)avctx->extradata) + 4,
-                                 avctx->extradata_size - 4) < 0)
-            return -1;
-    }else{
-        switch (avctx->bits_per_coded_sample & 7) {
-        case 1:
-            s->predictor = LEFT;
-            s->decorrelate = 0;
-            break;
-        case 2:
-            s->predictor = LEFT;
-            s->decorrelate = 1;
-            break;
-        case 3:
-            s->predictor = PLANE;
-            s->decorrelate = avctx->bits_per_coded_sample >= 24;
-            break;
-        case 4:
-            s->predictor = MEDIAN;
-            s->decorrelate = 0;
-            break;
-        default:
-            s->predictor = LEFT; //OLD
-            s->decorrelate = 0;
-            break;
-        }
-        s->bitstream_bpp = avctx->bits_per_coded_sample & ~7;
-        s->context = 0;
-
-        if (read_old_huffman_tables(s) < 0)
-            return -1;
-    }
-
-    switch (s->bitstream_bpp) {
-    case 12:
-        avctx->pix_fmt = AV_PIX_FMT_YUV420P;
-        break;
-    case 16:
-        if (s->yuy2) {
-            avctx->pix_fmt = AV_PIX_FMT_YUYV422;
-        } else {
-            avctx->pix_fmt = AV_PIX_FMT_YUV422P;
-        }
-        break;
-    case 24:
-    case 32:
-        if (s->bgr32) {
-            avctx->pix_fmt = AV_PIX_FMT_RGB32;
-        } else {
-            avctx->pix_fmt = AV_PIX_FMT_BGR24;
-        }
-        break;
-    default:
-        return AVERROR_INVALIDDATA;
-    }
-
-    if ((avctx->pix_fmt == AV_PIX_FMT_YUV422P || avctx->pix_fmt == AV_PIX_FMT_YUV420P) && avctx->width & 1) {
-        av_log(avctx, AV_LOG_ERROR, "width must be even for this colorspace\n");
-        return AVERROR_INVALIDDATA;
-    }
-    if (s->predictor == MEDIAN && avctx->pix_fmt == AV_PIX_FMT_YUV422P && avctx->width%4) {
-        av_log(avctx, AV_LOG_ERROR, "width must be a multiple of 4 this colorspace and predictor\n");
-        return AVERROR_INVALIDDATA;
-    }
-    alloc_temp(s);
-
-    return 0;
-}
-
-static av_cold int decode_init_thread_copy(AVCodecContext *avctx)
-{
-    HYuvContext *s = avctx->priv_data;
-    int i;
-
-    avctx->coded_frame= &s->picture;
-    alloc_temp(s);
-
-    for (i = 0; i < 6; i++)
-        s->vlc[i].table = NULL;
-
-    if (s->version == 2) {
-        if (read_huffman_tables(s, ((uint8_t*)avctx->extradata) + 4,
-                                avctx->extradata_size) < 0)
-            return -1;
-    } else {
-        if (read_old_huffman_tables(s) < 0)
-            return -1;
-    }
-
-    return 0;
-}
-#endif /* CONFIG_HUFFYUV_DECODER || CONFIG_FFVHUFF_DECODER */
-
-#if CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER
-static int store_table(HYuvContext *s, const uint8_t *len, uint8_t *buf)
-{
-    int i;
-    int index = 0;
-
-    for (i = 0; i < 256;) {
-        int val = len[i];
-        int repeat = 0;
-
-        for (; i < 256 && len[i] == val && repeat < 255; i++)
-            repeat++;
-
-        av_assert0(val < 32 && val >0 && repeat<256 && repeat>0);
-        if (repeat > 7) {
-            buf[index++] = val;
-            buf[index++] = repeat;
-        } else {
-            buf[index++] = val | (repeat << 5);
-        }
-    }
-
-    return index;
-}
-
-static av_cold int encode_init(AVCodecContext *avctx)
-{
-    HYuvContext *s = avctx->priv_data;
-    int i, j;
-
-    common_init(avctx);
-
-    avctx->extradata = av_mallocz(1024*30); // 256*3+4 == 772
-    avctx->stats_out = av_mallocz(1024*30); // 21*256*3(%llu ) + 3(\n) + 1(0) = 16132
-    s->version = 2;
-
-    avctx->coded_frame = &s->picture;
-
-    switch (avctx->pix_fmt) {
-    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");
-            return AVERROR(EINVAL);
-        }
-        s->bitstream_bpp = avctx->pix_fmt == AV_PIX_FMT_YUV420P ? 12 : 16;
-        break;
-    case AV_PIX_FMT_RGB32:
-        s->bitstream_bpp = 32;
-        break;
-    case AV_PIX_FMT_RGB24:
-        s->bitstream_bpp = 24;
-        break;
-    default:
-        av_log(avctx, AV_LOG_ERROR, "format not supported\n");
-        return -1;
-    }
-    avctx->bits_per_coded_sample = s->bitstream_bpp;
-    s->decorrelate = s->bitstream_bpp >= 24;
-    s->predictor = avctx->prediction_method;
-    s->interlaced = avctx->flags&CODEC_FLAG_INTERLACED_ME ? 1 : 0;
-    if (avctx->context_model == 1) {
-        s->context = avctx->context_model;
-        if (s->flags & (CODEC_FLAG_PASS1|CODEC_FLAG_PASS2)) {
-            av_log(avctx, AV_LOG_ERROR,
-                   "context=1 is not compatible with "
-                   "2 pass huffyuv encoding\n");
-            return -1;
-        }
-    }else s->context= 0;
-
-    if (avctx->codec->id == AV_CODEC_ID_HUFFYUV) {
-        if (avctx->pix_fmt == AV_PIX_FMT_YUV420P) {
-            av_log(avctx, AV_LOG_ERROR,
-                   "Error: YV12 is not supported by huffyuv; use "
-                   "vcodec=ffvhuff or format=422p\n");
-            return -1;
-        }
-        if (avctx->context_model) {
-            av_log(avctx, AV_LOG_ERROR,
-                   "Error: per-frame huffman tables are not supported "
-                   "by huffyuv; use vcodec=ffvhuff\n");
-            return -1;
-        }
-        if (s->interlaced != ( s->height > 288 ))
-            av_log(avctx, AV_LOG_INFO,
-                   "using huffyuv 2.2.0 or newer interlacing flag\n");
-    }
-
-    if (s->bitstream_bpp >= 24 && s->predictor == MEDIAN) {
-        av_log(avctx, AV_LOG_ERROR,
-               "Error: RGB is incompatible with median predictor\n");
-        return -1;
-    }
-
-    ((uint8_t*)avctx->extradata)[0] = s->predictor | (s->decorrelate << 6);
-    ((uint8_t*)avctx->extradata)[1] = s->bitstream_bpp;
-    ((uint8_t*)avctx->extradata)[2] = s->interlaced ? 0x10 : 0x20;
-    if (s->context)
-        ((uint8_t*)avctx->extradata)[2] |= 0x40;
-    ((uint8_t*)avctx->extradata)[3] = 0;
-    s->avctx->extradata_size = 4;
-
-    if (avctx->stats_in) {
-        char *p = avctx->stats_in;
-
-        for (i = 0; i < 3; i++)
-            for (j = 0; j < 256; j++)
-                s->stats[i][j] = 1;
-
-        for (;;) {
-            for (i = 0; i < 3; i++) {
-                char *next;
-
-                for (j = 0; j < 256; j++) {
-                    s->stats[i][j] += strtol(p, &next, 0);
-                    if (next == p) return -1;
-                    p = next;
-                }
-            }
-            if (p[0] == 0 || p[1] == 0 || p[2] == 0) break;
-        }
-    } else {
-        for (i = 0; i < 3; i++)
-            for (j = 0; j < 256; j++) {
-                int d = FFMIN(j, 256 - j);
-
-                s->stats[i][j] = 100000000 / (d + 1);
-            }
-    }
-
-    for (i = 0; i < 3; i++) {
-        ff_huff_gen_len_table(s->len[i], s->stats[i]);
-
-        if (generate_bits_table(s->bits[i], s->len[i]) < 0) {
-            return -1;
-        }
-
-        s->avctx->extradata_size +=
-            store_table(s, s->len[i], &((uint8_t*)s->avctx->extradata)[s->avctx->extradata_size]);
-    }
-
-    if (s->context) {
-        for (i = 0; i < 3; i++) {
-            int pels = s->width * s->height / (i ? 40 : 10);
-            for (j = 0; j < 256; j++) {
-                int d = FFMIN(j, 256 - j);
-                s->stats[i][j] = pels/(d + 1);
-            }
-        }
-    } else {
-        for (i = 0; i < 3; i++)
-            for (j = 0; j < 256; j++)
-                s->stats[i][j]= 0;
-    }
-
-    alloc_temp(s);
-
-    s->picture_number=0;
-
-    return 0;
-}
-#endif /* CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER */
-
-/* TODO instead of restarting the read when the code isn't in the first level
- * of the joint table, jump into the 2nd level of the individual table. */
-#define READ_2PIX(dst0, dst1, plane1){\
-    uint16_t code = get_vlc2(&s->gb, s->vlc[3+plane1].table, VLC_BITS, 1);\
-    if(code != 0xffff){\
-        dst0 = code>>8;\
-        dst1 = code;\
-    }else{\
-        dst0 = get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);\
-        dst1 = get_vlc2(&s->gb, s->vlc[plane1].table, VLC_BITS, 3);\
-    }\
-}
-
-static void decode_422_bitstream(HYuvContext *s, int count)
-{
-    int i;
-
-    count /= 2;
-
-    if (count >= (get_bits_left(&s->gb)) / (31 * 4)) {
-        for (i = 0; i < count && get_bits_left(&s->gb) > 0; i++) {
-            READ_2PIX(s->temp[0][2 * i    ], s->temp[1][i], 1);
-            READ_2PIX(s->temp[0][2 * i + 1], s->temp[2][i], 2);
-        }
-    } else {
-        for (i = 0; i < count; i++) {
-            READ_2PIX(s->temp[0][2 * i    ], s->temp[1][i], 1);
-            READ_2PIX(s->temp[0][2 * i + 1], s->temp[2][i], 2);
-        }
-    }
-}
-
-static void decode_gray_bitstream(HYuvContext *s, int count)
-{
-    int i;
-
-    count/=2;
-
-    if (count >= (get_bits_left(&s->gb)) / (31 * 2)) {
-        for (i = 0; i < count && get_bits_left(&s->gb) > 0; i++) {
-            READ_2PIX(s->temp[0][2 * i], s->temp[0][2 * i + 1], 0);
-        }
-    } else {
-        for(i=0; i<count; i++){
-            READ_2PIX(s->temp[0][2 * i], s->temp[0][2 * i + 1], 0);
-        }
-    }
-}
-
-#if CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER
-static int encode_422_bitstream(HYuvContext *s, int offset, int count)
-{
-    int i;
-    const uint8_t *y = s->temp[0] + offset;
-    const uint8_t *u = s->temp[1] + offset / 2;
-    const uint8_t *v = s->temp[2] + offset / 2;
-
-    if (s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb) >> 3) < 2 * 4 * count) {
-        av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
-        return -1;
-    }
-
-#define LOAD4\
-            int y0 = y[2 * i];\
-            int y1 = y[2 * i + 1];\
-            int u0 = u[i];\
-            int v0 = v[i];
-
-    count /= 2;
-
-    if (s->flags & CODEC_FLAG_PASS1) {
-        for(i = 0; i < count; i++) {
-            LOAD4;
-            s->stats[0][y0]++;
-            s->stats[1][u0]++;
-            s->stats[0][y1]++;
-            s->stats[2][v0]++;
-        }
-    }
-    if (s->avctx->flags2 & CODEC_FLAG2_NO_OUTPUT)
-        return 0;
-    if (s->context) {
-        for (i = 0; i < count; i++) {
-            LOAD4;
-            s->stats[0][y0]++;
-            put_bits(&s->pb, s->len[0][y0], s->bits[0][y0]);
-            s->stats[1][u0]++;
-            put_bits(&s->pb, s->len[1][u0], s->bits[1][u0]);
-            s->stats[0][y1]++;
-            put_bits(&s->pb, s->len[0][y1], s->bits[0][y1]);
-            s->stats[2][v0]++;
-            put_bits(&s->pb, s->len[2][v0], s->bits[2][v0]);
-        }
-    } else {
-        for(i = 0; i < count; i++) {
-            LOAD4;
-            put_bits(&s->pb, s->len[0][y0], s->bits[0][y0]);
-            put_bits(&s->pb, s->len[1][u0], s->bits[1][u0]);
-            put_bits(&s->pb, s->len[0][y1], s->bits[0][y1]);
-            put_bits(&s->pb, s->len[2][v0], s->bits[2][v0]);
-        }
-    }
-    return 0;
-}
-
-static int encode_gray_bitstream(HYuvContext *s, int count)
-{
-    int i;
-
-    if (s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb) >> 3) < 4 * count) {
-        av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
-        return -1;
-    }
-
-#define LOAD2\
-            int y0 = s->temp[0][2 * i];\
-            int y1 = s->temp[0][2 * i + 1];
-#define STAT2\
-            s->stats[0][y0]++;\
-            s->stats[0][y1]++;
-#define WRITE2\
-            put_bits(&s->pb, s->len[0][y0], s->bits[0][y0]);\
-            put_bits(&s->pb, s->len[0][y1], s->bits[0][y1]);
-
-    count /= 2;
-
-    if (s->flags & CODEC_FLAG_PASS1) {
-        for (i = 0; i < count; i++) {
-            LOAD2;
-            STAT2;
-        }
-    }
-    if (s->avctx->flags2 & CODEC_FLAG2_NO_OUTPUT)
-        return 0;
-
-    if (s->context) {
-        for (i = 0; i < count; i++) {
-            LOAD2;
-            STAT2;
-            WRITE2;
-        }
-    } else {
-        for (i = 0; i < count; i++) {
-            LOAD2;
-            WRITE2;
-        }
-    }
-    return 0;
-}
-#endif /* CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER */
-
-static av_always_inline void decode_bgr_1(HYuvContext *s, int count,
-                                          int decorrelate, int alpha)
-{
-    int i;
-    for (i = 0; i < count; i++) {
-        int code = get_vlc2(&s->gb, s->vlc[3].table, VLC_BITS, 1);
-        if (code != -1) {
-            *(uint32_t*)&s->temp[0][4 * i] = s->pix_bgr_map[code];
-        } else if(decorrelate) {
-            s->temp[0][4 * i + G] = get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
-            s->temp[0][4 * i + B] = get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3) +
-                                    s->temp[0][4 * i + G];
-            s->temp[0][4 * i + R] = get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3) +
-                                    s->temp[0][4 * i + G];
-        } else {
-            s->temp[0][4 * i + B] = get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
-            s->temp[0][4 * i + G] = get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
-            s->temp[0][4 * i + R] = get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3);
-        }
-        if (alpha)
-            s->temp[0][4 * i + A] = get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3);
-    }
-}
-
-static void decode_bgr_bitstream(HYuvContext *s, int count)
-{
-    if (s->decorrelate) {
-        if (s->bitstream_bpp==24)
-            decode_bgr_1(s, count, 1, 0);
-        else
-            decode_bgr_1(s, count, 1, 1);
-    } else {
-        if (s->bitstream_bpp==24)
-            decode_bgr_1(s, count, 0, 0);
-        else
-            decode_bgr_1(s, count, 0, 1);
-    }
-}
-
-static inline int encode_bgra_bitstream(HYuvContext *s, int count, int planes)
-{
-    int i;
-
-    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]);
-
-    if ((s->flags & CODEC_FLAG_PASS1) &&
-        (s->avctx->flags2 & CODEC_FLAG2_NO_OUTPUT)) {
-        for (i = 0; i < count; i++) {
-            LOAD3;
-            STAT3;
-        }
-    } else if (s->context || (s->flags & CODEC_FLAG_PASS1)) {
-        for (i = 0; i < count; i++) {
-            LOAD3;
-            STAT3;
-            WRITE3;
-        }
-    } else {
-        for (i = 0; i < count; i++) {
-            LOAD3;
-            WRITE3;
-        }
-    }
-    return 0;
-}
-
-#if CONFIG_HUFFYUV_DECODER || CONFIG_FFVHUFF_DECODER
-static void draw_slice(HYuvContext *s, int y)
-{
-    int h, cy, i;
-    int offset[AV_NUM_DATA_POINTERS];
-
-    if (s->avctx->draw_horiz_band==NULL)
-        return;
-
-    h = y - s->last_slice_end;
-    y -= h;
-
-    if (s->bitstream_bpp == 12) {
-        cy = y>>1;
-    } else {
-        cy = y;
-    }
-
-    offset[0] = s->picture.linesize[0]*y;
-    offset[1] = s->picture.linesize[1]*cy;
-    offset[2] = s->picture.linesize[2]*cy;
-    for (i = 3; i < AV_NUM_DATA_POINTERS; i++)
-        offset[i] = 0;
-    emms_c();
-
-    s->avctx->draw_horiz_band(s->avctx, &s->picture, offset, y, 3, h);
-
-    s->last_slice_end = y + h;
-}
-
-static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
-                        AVPacket *avpkt)
-{
-    const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
-    HYuvContext *s = avctx->priv_data;
-    const int width = s->width;
-    const int width2 = s->width>>1;
-    const int height = s->height;
-    int fake_ystride, fake_ustride, fake_vstride;
-    AVFrame * const p = &s->picture;
-    int table_size = 0;
-
-    AVFrame *picture = data;
-
-    av_fast_malloc(&s->bitstream_buffer,
-                   &s->bitstream_buffer_size,
-                   buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
-    if (!s->bitstream_buffer)
-        return AVERROR(ENOMEM);
-
-    memset(s->bitstream_buffer + buf_size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
-    s->dsp.bswap_buf((uint32_t*)s->bitstream_buffer,
-                     (const uint32_t*)buf, buf_size / 4);
-
-    if (p->data[0])
-        ff_thread_release_buffer(avctx, p);
-
-    p->reference = 0;
-    if (ff_thread_get_buffer(avctx, p) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
-    }
-
-    if (s->context) {
-        table_size = read_huffman_tables(s, s->bitstream_buffer, buf_size);
-        if (table_size < 0)
-            return -1;
-    }
-
-    if ((unsigned)(buf_size-table_size) >= INT_MAX / 8)
-        return -1;
-
-    init_get_bits(&s->gb, s->bitstream_buffer+table_size,
-                  (buf_size-table_size) * 8);
-
-    fake_ystride = s->interlaced ? p->linesize[0] * 2  : p->linesize[0];
-    fake_ustride = s->interlaced ? p->linesize[1] * 2  : p->linesize[1];
-    fake_vstride = s->interlaced ? p->linesize[2] * 2  : p->linesize[2];
-
-    s->last_slice_end = 0;
-
-    if (s->bitstream_bpp < 24) {
-        int y, cy;
-        int lefty, leftu, leftv;
-        int lefttopy, lefttopu, lefttopv;
-
-        if (s->yuy2) {
-            p->data[0][3] = get_bits(&s->gb, 8);
-            p->data[0][2] = get_bits(&s->gb, 8);
-            p->data[0][1] = get_bits(&s->gb, 8);
-            p->data[0][0] = get_bits(&s->gb, 8);
-
-            av_log(avctx, AV_LOG_ERROR,
-                   "YUY2 output is not implemented yet\n");
-            return -1;
-        } else {
-
-            leftv = p->data[2][0] = get_bits(&s->gb, 8);
-            lefty = p->data[0][1] = get_bits(&s->gb, 8);
-            leftu = p->data[1][0] = get_bits(&s->gb, 8);
-                    p->data[0][0] = get_bits(&s->gb, 8);
-
-            switch (s->predictor) {
-            case LEFT:
-            case PLANE:
-                decode_422_bitstream(s, width-2);
-                lefty = s->dsp.add_hfyu_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty);
-                if (!(s->flags&CODEC_FLAG_GRAY)) {
-                    leftu = s->dsp.add_hfyu_left_prediction(p->data[1] + 1, s->temp[1], width2 - 1, leftu);
-                    leftv = s->dsp.add_hfyu_left_prediction(p->data[2] + 1, s->temp[2], width2 - 1, leftv);
-                }
-
-                for (cy = y = 1; y < s->height; y++, cy++) {
-                    uint8_t *ydst, *udst, *vdst;
-
-                    if (s->bitstream_bpp == 12) {
-                        decode_gray_bitstream(s, width);
-
-                        ydst = p->data[0] + p->linesize[0] * y;
-
-                        lefty = s->dsp.add_hfyu_left_prediction(ydst, s->temp[0], width, lefty);
-                        if (s->predictor == PLANE) {
-                            if (y > s->interlaced)
-                                s->dsp.add_bytes(ydst, ydst - fake_ystride, width);
-                        }
-                        y++;
-                        if (y >= s->height) break;
-                    }
-
-                    draw_slice(s, y);
-
-                    ydst = p->data[0] + p->linesize[0]*y;
-                    udst = p->data[1] + p->linesize[1]*cy;
-                    vdst = p->data[2] + p->linesize[2]*cy;
-
-                    decode_422_bitstream(s, width);
-                    lefty = s->dsp.add_hfyu_left_prediction(ydst, s->temp[0], width, lefty);
-                    if (!(s->flags & CODEC_FLAG_GRAY)) {
-                        leftu= s->dsp.add_hfyu_left_prediction(udst, s->temp[1], width2, leftu);
-                        leftv= s->dsp.add_hfyu_left_prediction(vdst, s->temp[2], width2, leftv);
-                    }
-                    if (s->predictor == PLANE) {
-                        if (cy > s->interlaced) {
-                            s->dsp.add_bytes(ydst, ydst - fake_ystride, width);
-                            if (!(s->flags & CODEC_FLAG_GRAY)) {
-                                s->dsp.add_bytes(udst, udst - fake_ustride, width2);
-                                s->dsp.add_bytes(vdst, vdst - fake_vstride, width2);
-                            }
-                        }
-                    }
-                }
-                draw_slice(s, height);
-
-                break;
-            case MEDIAN:
-                /* first line except first 2 pixels is left predicted */
-                decode_422_bitstream(s, width - 2);
-                lefty= s->dsp.add_hfyu_left_prediction(p->data[0] + 2, s->temp[0], width - 2, lefty);
-                if (!(s->flags & CODEC_FLAG_GRAY)) {
-                    leftu = s->dsp.add_hfyu_left_prediction(p->data[1] + 1, s->temp[1], width2 - 1, leftu);
-                    leftv = s->dsp.add_hfyu_left_prediction(p->data[2] + 1, s->temp[2], width2 - 1, leftv);
-                }
-
-                cy = y = 1;
-
-                /* second line is left predicted for interlaced case */
-                if (s->interlaced) {
-                    decode_422_bitstream(s, width);
-                    lefty = s->dsp.add_hfyu_left_prediction(p->data[0] + p->linesize[0], s->temp[0], width, lefty);
-                    if (!(s->flags & CODEC_FLAG_GRAY)) {
-                        leftu = s->dsp.add_hfyu_left_prediction(p->data[1] + p->linesize[2], s->temp[1], width2, leftu);
-                        leftv = s->dsp.add_hfyu_left_prediction(p->data[2] + p->linesize[1], s->temp[2], width2, leftv);
-                    }
-                    y++; cy++;
-                }
-
-                /* next 4 pixels are left predicted too */
-                decode_422_bitstream(s, 4);
-                lefty = s->dsp.add_hfyu_left_prediction(p->data[0] + fake_ystride, s->temp[0], 4, lefty);
-                if (!(s->flags&CODEC_FLAG_GRAY)) {
-                    leftu = s->dsp.add_hfyu_left_prediction(p->data[1] + fake_ustride, s->temp[1], 2, leftu);
-                    leftv = s->dsp.add_hfyu_left_prediction(p->data[2] + fake_vstride, s->temp[2], 2, leftv);
-                }
-
-                /* next line except the first 4 pixels is median predicted */
-                lefttopy = p->data[0][3];
-                decode_422_bitstream(s, width - 4);
-                s->dsp.add_hfyu_median_prediction(p->data[0] + fake_ystride+4, p->data[0]+4, s->temp[0], width-4, &lefty, &lefttopy);
-                if (!(s->flags&CODEC_FLAG_GRAY)) {
-                    lefttopu = p->data[1][1];
-                    lefttopv = p->data[2][1];
-                    s->dsp.add_hfyu_median_prediction(p->data[1] + fake_ustride+2, p->data[1] + 2, s->temp[1], width2 - 2, &leftu, &lefttopu);
-                    s->dsp.add_hfyu_median_prediction(p->data[2] + fake_vstride+2, p->data[2] + 2, s->temp[2], width2 - 2, &leftv, &lefttopv);
-                }
-                y++; cy++;
-
-                for (; y<height; y++, cy++) {
-                    uint8_t *ydst, *udst, *vdst;
-
-                    if (s->bitstream_bpp == 12) {
-                        while (2 * cy > y) {
-                            decode_gray_bitstream(s, width);
-                            ydst = p->data[0] + p->linesize[0] * y;
-                            s->dsp.add_hfyu_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy);
-                            y++;
-                        }
-                        if (y >= height) break;
-                    }
-                    draw_slice(s, y);
-
-                    decode_422_bitstream(s, width);
-
-                    ydst = p->data[0] + p->linesize[0] * y;
-                    udst = p->data[1] + p->linesize[1] * cy;
-                    vdst = p->data[2] + p->linesize[2] * cy;
-
-                    s->dsp.add_hfyu_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy);
-                    if (!(s->flags & CODEC_FLAG_GRAY)) {
-                        s->dsp.add_hfyu_median_prediction(udst, udst - fake_ustride, s->temp[1], width2, &leftu, &lefttopu);
-                        s->dsp.add_hfyu_median_prediction(vdst, vdst - fake_vstride, s->temp[2], width2, &leftv, &lefttopv);
-                    }
-                }
-
-                draw_slice(s, height);
-                break;
-            }
-        }
-    } else {
-        int y;
-        int leftr, leftg, leftb, lefta;
-        const int last_line = (height - 1) * p->linesize[0];
-
-        if (s->bitstream_bpp == 32) {
-            lefta = p->data[0][last_line+A] = get_bits(&s->gb, 8);
-            leftr = p->data[0][last_line+R] = get_bits(&s->gb, 8);
-            leftg = p->data[0][last_line+G] = get_bits(&s->gb, 8);
-            leftb = p->data[0][last_line+B] = get_bits(&s->gb, 8);
-        } else {
-            leftr = p->data[0][last_line+R] = get_bits(&s->gb, 8);
-            leftg = p->data[0][last_line+G] = get_bits(&s->gb, 8);
-            leftb = p->data[0][last_line+B] = get_bits(&s->gb, 8);
-            lefta = p->data[0][last_line+A] = 255;
-            skip_bits(&s->gb, 8);
-        }
-
-        if (s->bgr32) {
-            switch (s->predictor) {
-            case LEFT:
-            case PLANE:
-                decode_bgr_bitstream(s, width - 1);
-                s->dsp.add_hfyu_left_prediction_bgr32(p->data[0] + last_line+4, s->temp[0], width - 1, &leftr, &leftg, &leftb, &lefta);
-
-                for (y = s->height - 2; y >= 0; y--) { //Yes it is stored upside down.
-                    decode_bgr_bitstream(s, width);
-
-                    s->dsp.add_hfyu_left_prediction_bgr32(p->data[0] + p->linesize[0]*y, s->temp[0], width, &leftr, &leftg, &leftb, &lefta);
-                    if (s->predictor == PLANE) {
-                        if (s->bitstream_bpp != 32) lefta = 0;
-                        if ((y & s->interlaced) == 0 &&
-                            y < s->height - 1 - s->interlaced) {
-                            s->dsp.add_bytes(p->data[0] + p->linesize[0] * y,
-                                             p->data[0] + p->linesize[0] * y +
-                                             fake_ystride, fake_ystride);
-                        }
-                    }
-                }
-                // just 1 large slice as this is not possible in reverse order
-                draw_slice(s, height);
-                break;
-            default:
-                av_log(avctx, AV_LOG_ERROR,
-                       "prediction type not supported!\n");
-            }
-        }else{
-            av_log(avctx, AV_LOG_ERROR,
-                   "BGR24 output is not implemented yet\n");
-            return -1;
-        }
-    }
-    emms_c();
-
-    *picture = *p;
-    *data_size = sizeof(AVFrame);
-
-    return (get_bits_count(&s->gb) + 31) / 32 * 4 + table_size;
-}
-#endif /* CONFIG_HUFFYUV_DECODER || CONFIG_FFVHUFF_DECODER */
-
-static int common_end(HYuvContext *s)
+av_cold void ff_huffyuv_common_end(HYuvContext *s)
 {
     int i;
 
     for(i = 0; i < 3; i++) {
         av_freep(&s->temp[i]);
     }
-    return 0;
 }
-
-#if CONFIG_HUFFYUV_DECODER || CONFIG_FFVHUFF_DECODER
-static av_cold int decode_end(AVCodecContext *avctx)
-{
-    HYuvContext *s = avctx->priv_data;
-    int i;
-
-    if (s->picture.data[0])
-        avctx->release_buffer(avctx, &s->picture);
-
-    common_end(s);
-    av_freep(&s->bitstream_buffer);
-
-    for (i = 0; i < 6; i++) {
-        ff_free_vlc(&s->vlc[i]);
-    }
-
-    return 0;
-}
-#endif /* CONFIG_HUFFYUV_DECODER || CONFIG_FFVHUFF_DECODER */
-
-#if CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER
-static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
-                        const AVFrame *pict, int *got_packet)
-{
-    HYuvContext *s = avctx->priv_data;
-    const int width = s->width;
-    const int width2 = s->width>>1;
-    const int height = s->height;
-    const int fake_ystride = s->interlaced ? pict->linesize[0]*2  : pict->linesize[0];
-    const int fake_ustride = s->interlaced ? pict->linesize[1]*2  : pict->linesize[1];
-    const int fake_vstride = s->interlaced ? pict->linesize[2]*2  : pict->linesize[2];
-    AVFrame * const p = &s->picture;
-    int i, j, size = 0, ret;
-
-    if ((ret = ff_alloc_packet2(avctx, pkt, width * height * 3 * 4 + FF_MIN_BUFFER_SIZE)) < 0)
-        return ret;
-
-    *p = *pict;
-    p->pict_type = AV_PICTURE_TYPE_I;
-    p->key_frame = 1;
-
-    if (s->context) {
-        for (i = 0; i < 3; i++) {
-            ff_huff_gen_len_table(s->len[i], s->stats[i]);
-            if (generate_bits_table(s->bits[i], s->len[i]) < 0)
-                return -1;
-            size += store_table(s, s->len[i], &pkt->data[size]);
-        }
-
-        for (i = 0; i < 3; i++)
-            for (j = 0; j < 256; j++)
-                s->stats[i][j] >>= 1;
-    }
-
-    init_put_bits(&s->pb, pkt->data + size, pkt->size - size);
-
-    if (avctx->pix_fmt == AV_PIX_FMT_YUV422P ||
-        avctx->pix_fmt == AV_PIX_FMT_YUV420P) {
-        int lefty, leftu, leftv, y, cy;
-
-        put_bits(&s->pb, 8, leftv = p->data[2][0]);
-        put_bits(&s->pb, 8, lefty = p->data[0][1]);
-        put_bits(&s->pb, 8, leftu = p->data[1][0]);
-        put_bits(&s->pb, 8,         p->data[0][0]);
-
-        lefty = sub_left_prediction(s, s->temp[0], p->data[0], width , 0);
-        leftu = sub_left_prediction(s, s->temp[1], p->data[1], width2, 0);
-        leftv = sub_left_prediction(s, s->temp[2], p->data[2], width2, 0);
-
-        encode_422_bitstream(s, 2, width-2);
-
-        if (s->predictor==MEDIAN) {
-            int lefttopy, lefttopu, lefttopv;
-            cy = y = 1;
-            if (s->interlaced) {
-                lefty = sub_left_prediction(s, s->temp[0], p->data[0] + p->linesize[0], width , lefty);
-                leftu = sub_left_prediction(s, s->temp[1], p->data[1] + p->linesize[1], width2, leftu);
-                leftv = sub_left_prediction(s, s->temp[2], p->data[2] + p->linesize[2], width2, leftv);
-
-                encode_422_bitstream(s, 0, width);
-                y++; cy++;
-            }
-
-            lefty = sub_left_prediction(s, s->temp[0], p->data[0] + fake_ystride, 4, lefty);
-            leftu = sub_left_prediction(s, s->temp[1], p->data[1] + fake_ustride, 2, leftu);
-            leftv = sub_left_prediction(s, s->temp[2], p->data[2] + fake_vstride, 2, leftv);
-
-            encode_422_bitstream(s, 0, 4);
-
-            lefttopy = p->data[0][3];
-            lefttopu = p->data[1][1];
-            lefttopv = p->data[2][1];
-            s->dsp.sub_hfyu_median_prediction(s->temp[0], p->data[0]+4, p->data[0] + fake_ystride + 4, width - 4 , &lefty, &lefttopy);
-            s->dsp.sub_hfyu_median_prediction(s->temp[1], p->data[1]+2, p->data[1] + fake_ustride + 2, width2 - 2, &leftu, &lefttopu);
-            s->dsp.sub_hfyu_median_prediction(s->temp[2], p->data[2]+2, p->data[2] + fake_vstride + 2, width2 - 2, &leftv, &lefttopv);
-            encode_422_bitstream(s, 0, width - 4);
-            y++; cy++;
-
-            for (; y < height; y++,cy++) {
-                uint8_t *ydst, *udst, *vdst;
-
-                if (s->bitstream_bpp == 12) {
-                    while (2 * cy > y) {
-                        ydst = p->data[0] + p->linesize[0] * y;
-                        s->dsp.sub_hfyu_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy);
-                        encode_gray_bitstream(s, width);
-                        y++;
-                    }
-                    if (y >= height) break;
-                }
-                ydst = p->data[0] + p->linesize[0] * y;
-                udst = p->data[1] + p->linesize[1] * cy;
-                vdst = p->data[2] + p->linesize[2] * cy;
-
-                s->dsp.sub_hfyu_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy);
-                s->dsp.sub_hfyu_median_prediction(s->temp[1], udst - fake_ustride, udst, width2, &leftu, &lefttopu);
-                s->dsp.sub_hfyu_median_prediction(s->temp[2], vdst - fake_vstride, vdst, width2, &leftv, &lefttopv);
-
-                encode_422_bitstream(s, 0, width);
-            }
-        } else {
-            for (cy = y = 1; y < height; y++, cy++) {
-                uint8_t *ydst, *udst, *vdst;
-
-                /* encode a luma only line & y++ */
-                if (s->bitstream_bpp == 12) {
-                    ydst = p->data[0] + p->linesize[0] * y;
-
-                    if (s->predictor == PLANE && s->interlaced < y) {
-                        s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width);
-
-                        lefty = sub_left_prediction(s, s->temp[0], s->temp[1], width , lefty);
-                    } else {
-                        lefty = sub_left_prediction(s, s->temp[0], ydst, width , lefty);
-                    }
-                    encode_gray_bitstream(s, width);
-                    y++;
-                    if (y >= height) break;
-                }
-
-                ydst = p->data[0] + p->linesize[0] * y;
-                udst = p->data[1] + p->linesize[1] * cy;
-                vdst = p->data[2] + p->linesize[2] * cy;
-
-                if (s->predictor == PLANE && s->interlaced < cy) {
-                    s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width);
-                    s->dsp.diff_bytes(s->temp[2], udst, udst - fake_ustride, width2);
-                    s->dsp.diff_bytes(s->temp[2] + width2, vdst, vdst - fake_vstride, width2);
-
-                    lefty = sub_left_prediction(s, s->temp[0], s->temp[1], width , lefty);
-                    leftu = sub_left_prediction(s, s->temp[1], s->temp[2], width2, leftu);
-                    leftv = sub_left_prediction(s, s->temp[2], s->temp[2] + width2, width2, leftv);
-                } else {
-                    lefty = sub_left_prediction(s, s->temp[0], ydst, width , lefty);
-                    leftu = sub_left_prediction(s, s->temp[1], udst, width2, leftu);
-                    leftv = sub_left_prediction(s, s->temp[2], vdst, width2, leftv);
-                }
-
-                encode_422_bitstream(s, 0, width);
-            }
-        }
-    } else if(avctx->pix_fmt == AV_PIX_FMT_RGB32) {
-        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, lefta;
-
-        put_bits(&s->pb, 8, lefta = data[A]);
-        put_bits(&s->pb, 8, leftr = data[R]);
-        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);
-        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);
-            } else {
-                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];
-        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, 0);
-
-        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);
-            }
-            encode_bgra_bitstream(s, width, 3);
-        }
-    } else {
-        av_log(avctx, AV_LOG_ERROR, "Format not supported!\n");
-    }
-    emms_c();
-
-    size += (put_bits_count(&s->pb) + 31) / 8;
-    put_bits(&s->pb, 16, 0);
-    put_bits(&s->pb, 15, 0);
-    size /= 4;
-
-    if ((s->flags&CODEC_FLAG_PASS1) && (s->picture_number & 31) == 0) {
-        int j;
-        char *p = avctx->stats_out;
-        char *end = p + 1024*30;
-        for (i = 0; i < 3; i++) {
-            for (j = 0; j < 256; j++) {
-                snprintf(p, end-p, "%"PRIu64" ", s->stats[i][j]);
-                p += strlen(p);
-                s->stats[i][j]= 0;
-            }
-            snprintf(p, end-p, "\n");
-            p++;
-        }
-    } else
-        avctx->stats_out[0] = '\0';
-    if (!(s->avctx->flags2 & CODEC_FLAG2_NO_OUTPUT)) {
-        flush_put_bits(&s->pb);
-        s->dsp.bswap_buf((uint32_t*)pkt->data, (uint32_t*)pkt->data, size);
-    }
-
-    s->picture_number++;
-
-    pkt->size   = size * 4;
-    pkt->flags |= AV_PKT_FLAG_KEY;
-    *got_packet = 1;
-
-    return 0;
-}
-
-static av_cold int encode_end(AVCodecContext *avctx)
-{
-    HYuvContext *s = avctx->priv_data;
-
-    common_end(s);
-
-    av_freep(&avctx->extradata);
-    av_freep(&avctx->stats_out);
-
-    return 0;
-}
-#endif /* CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER */
-
-#if CONFIG_HUFFYUV_DECODER
-AVCodec ff_huffyuv_decoder = {
-    .name             = "huffyuv",
-    .type             = AVMEDIA_TYPE_VIDEO,
-    .id               = AV_CODEC_ID_HUFFYUV,
-    .priv_data_size   = sizeof(HYuvContext),
-    .init             = decode_init,
-    .close            = decode_end,
-    .decode           = decode_frame,
-    .capabilities     = CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND |
-                        CODEC_CAP_FRAME_THREADS,
-    .init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy),
-    .long_name        = NULL_IF_CONFIG_SMALL("Huffyuv / HuffYUV"),
-};
-#endif
-
-#if CONFIG_FFVHUFF_DECODER
-AVCodec ff_ffvhuff_decoder = {
-    .name             = "ffvhuff",
-    .type             = AVMEDIA_TYPE_VIDEO,
-    .id               = AV_CODEC_ID_FFVHUFF,
-    .priv_data_size   = sizeof(HYuvContext),
-    .init             = decode_init,
-    .close            = decode_end,
-    .decode           = decode_frame,
-    .capabilities     = CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND |
-                        CODEC_CAP_FRAME_THREADS,
-    .init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy),
-    .long_name        = NULL_IF_CONFIG_SMALL("Huffyuv FFmpeg variant"),
-};
-#endif
-
-#if CONFIG_HUFFYUV_ENCODER
-AVCodec ff_huffyuv_encoder = {
-    .name           = "huffyuv",
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_HUFFYUV,
-    .priv_data_size = sizeof(HYuvContext),
-    .init           = encode_init,
-    .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
-    },
-    .long_name      = NULL_IF_CONFIG_SMALL("Huffyuv / HuffYUV"),
-};
-#endif
-
-#if CONFIG_FFVHUFF_ENCODER
-AVCodec ff_ffvhuff_encoder = {
-    .name           = "ffvhuff",
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_FFVHUFF,
-    .priv_data_size = sizeof(HYuvContext),
-    .init           = encode_init,
-    .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
-    },
-    .long_name      = NULL_IF_CONFIG_SMALL("Huffyuv FFmpeg variant"),
-};
-#endif
diff --git a/libavcodec/huffyuv.h b/libavcodec/huffyuv.h
new file mode 100644
index 0000000..e34b562
--- /dev/null
+++ b/libavcodec/huffyuv.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2002-2003 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * see http://www.pcisys.net/~melanson/codecs/huffyuv.txt for a description of
+ * the algorithm used
+ *
+ * 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
+ * huffyuv codec for libavcodec.
+ */
+
+#ifndef AVCODEC_HUFFYUV_H
+#define AVCODEC_HUFFYUV_H
+
+#include <stdint.h>
+
+#include "avcodec.h"
+#include "dsputil.h"
+#include "get_bits.h"
+#include "put_bits.h"
+
+#define VLC_BITS 11
+
+#if HAVE_BIGENDIAN
+#define B 3
+#define G 2
+#define R 1
+#define A 0
+#else
+#define B 0
+#define G 1
+#define R 2
+#define A 3
+#endif
+
+typedef enum Predictor {
+    LEFT = 0,
+    PLANE,
+    MEDIAN,
+} Predictor;
+
+typedef struct HYuvContext {
+    AVCodecContext *avctx;
+    Predictor predictor;
+    GetBitContext gb;
+    PutBitContext pb;
+    int interlaced;
+    int decorrelate;
+    int bitstream_bpp;
+    int version;
+    int yuy2;                               //use yuy2 instead of 422P
+    int bgr32;                              //use bgr32 instead of bgr24
+    int width, height;
+    int flags;
+    int context;
+    int picture_number;
+    int last_slice_end;
+    uint8_t *temp[3];
+    uint64_t stats[3][256];
+    uint8_t len[3][256];
+    uint32_t bits[3][256];
+    uint32_t pix_bgr_map[1<<VLC_BITS];
+    VLC vlc[6];                             //Y,U,V,YY,YU,YV
+    AVFrame picture;
+    uint8_t *bitstream_buffer;
+    unsigned int bitstream_buffer_size;
+    DSPContext dsp;
+} HYuvContext;
+
+void ff_huffyuv_common_init(AVCodecContext *s);
+void ff_huffyuv_common_end(HYuvContext *s);
+int  ff_huffyuv_alloc_temp(HYuvContext *s);
+int ff_huffyuv_generate_bits_table(uint32_t *dst, const uint8_t *len_table);
+
+#endif /* AVCODEC_HUFFYUV_H */
diff --git a/libavcodec/huffyuvdec.c b/libavcodec/huffyuvdec.c
new file mode 100644
index 0000000..159a517
--- /dev/null
+++ b/libavcodec/huffyuvdec.c
@@ -0,0 +1,810 @@
+/*
+ * huffyuv decoder
+ *
+ * Copyright (c) 2002-2003 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * see http://www.pcisys.net/~melanson/codecs/huffyuv.txt for a description of
+ * the algorithm used
+ *
+ * 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
+ * huffyuv decoder
+ */
+
+#include "avcodec.h"
+#include "get_bits.h"
+#include "huffyuv.h"
+#include "thread.h"
+
+#define classic_shift_luma_table_size 42
+static const unsigned char classic_shift_luma[classic_shift_luma_table_size + FF_INPUT_BUFFER_PADDING_SIZE] = {
+  34,36,35,69,135,232,9,16,10,24,11,23,12,16,13,10,14,8,15,8,
+  16,8,17,20,16,10,207,206,205,236,11,8,10,21,9,23,8,8,199,70,
+  69,68, 0,
+  0,0,0,0,0,0,0,0,
+};
+
+#define classic_shift_chroma_table_size 59
+static const unsigned char classic_shift_chroma[classic_shift_chroma_table_size + FF_INPUT_BUFFER_PADDING_SIZE] = {
+  66,36,37,38,39,40,41,75,76,77,110,239,144,81,82,83,84,85,118,183,
+  56,57,88,89,56,89,154,57,58,57,26,141,57,56,58,57,58,57,184,119,
+  214,245,116,83,82,49,80,79,78,77,44,75,41,40,39,38,37,36,34, 0,
+  0,0,0,0,0,0,0,0,
+};
+
+static const unsigned char classic_add_luma[256] = {
+    3,  9,  5, 12, 10, 35, 32, 29, 27, 50, 48, 45, 44, 41, 39, 37,
+   73, 70, 68, 65, 64, 61, 58, 56, 53, 50, 49, 46, 44, 41, 38, 36,
+   68, 65, 63, 61, 58, 55, 53, 51, 48, 46, 45, 43, 41, 39, 38, 36,
+   35, 33, 32, 30, 29, 27, 26, 25, 48, 47, 46, 44, 43, 41, 40, 39,
+   37, 36, 35, 34, 32, 31, 30, 28, 27, 26, 24, 23, 22, 20, 19, 37,
+   35, 34, 33, 31, 30, 29, 27, 26, 24, 23, 21, 20, 18, 17, 15, 29,
+   27, 26, 24, 22, 21, 19, 17, 16, 14, 26, 25, 23, 21, 19, 18, 16,
+   15, 27, 25, 23, 21, 19, 17, 16, 14, 26, 25, 23, 21, 18, 17, 14,
+   12, 17, 19, 13,  4,  9,  2, 11,  1,  7,  8,  0, 16,  3, 14,  6,
+   12, 10,  5, 15, 18, 11, 10, 13, 15, 16, 19, 20, 22, 24, 27, 15,
+   18, 20, 22, 24, 26, 14, 17, 20, 22, 24, 27, 15, 18, 20, 23, 25,
+   28, 16, 19, 22, 25, 28, 32, 36, 21, 25, 29, 33, 38, 42, 45, 49,
+   28, 31, 34, 37, 40, 42, 44, 47, 49, 50, 52, 54, 56, 57, 59, 60,
+   62, 64, 66, 67, 69, 35, 37, 39, 40, 42, 43, 45, 47, 48, 51, 52,
+   54, 55, 57, 59, 60, 62, 63, 66, 67, 69, 71, 72, 38, 40, 42, 43,
+   46, 47, 49, 51, 26, 28, 30, 31, 33, 34, 18, 19, 11, 13,  7,  8,
+};
+
+static const unsigned char classic_add_chroma[256] = {
+    3,  1,  2,  2,  2,  2,  3,  3,  7,  5,  7,  5,  8,  6, 11,  9,
+    7, 13, 11, 10,  9,  8,  7,  5,  9,  7,  6,  4,  7,  5,  8,  7,
+   11,  8, 13, 11, 19, 15, 22, 23, 20, 33, 32, 28, 27, 29, 51, 77,
+   43, 45, 76, 81, 46, 82, 75, 55, 56,144, 58, 80, 60, 74,147, 63,
+  143, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+   80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 27, 30, 21, 22,
+   17, 14,  5,  6,100, 54, 47, 50, 51, 53,106,107,108,109,110,111,
+  112,113,114,115,  4,117,118, 92, 94,121,122,  3,124,103,  2,  1,
+    0,129,130,131,120,119,126,125,136,137,138,139,140,141,142,134,
+  135,132,133,104, 64,101, 62, 57,102, 95, 93, 59, 61, 28, 97, 96,
+   52, 49, 48, 29, 32, 25, 24, 46, 23, 98, 45, 44, 43, 20, 42, 41,
+   19, 18, 99, 40, 15, 39, 38, 16, 13, 12, 11, 37, 10,  9,  8, 36,
+    7,128,127,105,123,116, 35, 34, 33,145, 31, 79, 42,146, 78, 26,
+   83, 48, 49, 50, 44, 47, 26, 31, 30, 18, 17, 19, 21, 24, 25, 13,
+   14, 16, 17, 18, 20, 21, 12, 14, 15,  9, 10,  6,  9,  6,  5,  8,
+    6, 12,  8, 10,  7,  9,  6,  4,  6,  2,  2,  3,  3,  3,  3,  2,
+};
+
+static int read_len_table(uint8_t *dst, GetBitContext *gb)
+{
+    int i, val, repeat;
+
+    for (i = 0; i < 256;) {
+        repeat = get_bits(gb, 3);
+        val    = get_bits(gb, 5);
+        if (repeat == 0)
+            repeat = get_bits(gb, 8);
+        if (i + repeat > 256 || get_bits_left(gb) < 0) {
+            av_log(NULL, AV_LOG_ERROR, "Error reading huffman table\n");
+            return -1;
+        }
+        while (repeat--)
+            dst[i++] = val;
+    }
+    return 0;
+}
+
+static int generate_joint_tables(HYuvContext *s)
+{
+    uint16_t symbols[1 << VLC_BITS];
+    uint16_t bits[1 << VLC_BITS];
+    uint8_t len[1 << VLC_BITS];
+    int ret;
+
+    if (s->bitstream_bpp < 24) {
+        int p, i, y, u;
+        for (p = 0; p < 3; p++) {
+            for (i = y = 0; y < 256; y++) {
+                int len0 = s->len[0][y];
+                int limit = VLC_BITS - len0;
+                if(limit <= 0 || !len0)
+                    continue;
+                for (u = 0; u < 256; u++) {
+                    int len1 = s->len[p][u];
+                    if (len1 > limit || !len1)
+                        continue;
+                    av_assert0(i < (1 << VLC_BITS));
+                    len[i] = len0 + len1;
+                    bits[i] = (s->bits[0][y] << len1) + s->bits[p][u];
+                    symbols[i] = (y << 8) + u;
+                    if(symbols[i] != 0xffff) // reserved to mean "invalid"
+                        i++;
+                }
+            }
+            ff_free_vlc(&s->vlc[3 + p]);
+            if ((ret = ff_init_vlc_sparse(&s->vlc[3 + p], VLC_BITS, i, len, 1, 1,
+                                          bits, 2, 2, symbols, 2, 2, 0)) < 0)
+                return ret;
+        }
+    } else {
+        uint8_t (*map)[4] = (uint8_t(*)[4])s->pix_bgr_map;
+        int i, b, g, r, code;
+        int p0 = s->decorrelate;
+        int p1 = !s->decorrelate;
+        // restrict the range to +/-16 because that's pretty much guaranteed to
+        // cover all the combinations that fit in 11 bits total, and it doesn't
+        // matter if we miss a few rare codes.
+        for (i = 0, g = -16; g < 16; g++) {
+            int len0 = s->len[p0][g & 255];
+            int limit0 = VLC_BITS - len0;
+            if (limit0 < 2 || !len0)
+                continue;
+            for (b = -16; b < 16; b++) {
+                int len1 = s->len[p1][b & 255];
+                int limit1 = limit0 - len1;
+                if (limit1 < 1 || !len1)
+                    continue;
+                code = (s->bits[p0][g & 255] << len1) + s->bits[p1][b & 255];
+                for (r = -16; r < 16; r++) {
+                    int len2 = s->len[2][r & 255];
+                    if (len2 > limit1 || !len2)
+                        continue;
+                    av_assert0(i < (1 << VLC_BITS));
+                    len[i] = len0 + len1 + len2;
+                    bits[i] = (code << len2) + s->bits[2][r & 255];
+                    if (s->decorrelate) {
+                        map[i][G] = g;
+                        map[i][B] = g + b;
+                        map[i][R] = g + r;
+                    } else {
+                        map[i][B] = g;
+                        map[i][G] = b;
+                        map[i][R] = r;
+                    }
+                    i++;
+                }
+            }
+        }
+        ff_free_vlc(&s->vlc[3]);
+        if ((ret = init_vlc(&s->vlc[3], VLC_BITS, i, len, 1, 1, bits, 2, 2, 0)) < 0)
+            return ret;
+    }
+    return 0;
+}
+
+static int read_huffman_tables(HYuvContext *s, const uint8_t *src, int length)
+{
+    GetBitContext gb;
+    int i;
+    int ret;
+
+    init_get_bits(&gb, src, length * 8);
+
+    for (i = 0; i < 3; i++) {
+        if (read_len_table(s->len[i], &gb) < 0)
+            return -1;
+        if (ff_huffyuv_generate_bits_table(s->bits[i], s->len[i]) < 0) {
+            return -1;
+        }
+        ff_free_vlc(&s->vlc[i]);
+        if ((ret = init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1,
+                           s->bits[i], 4, 4, 0)) < 0)
+            return ret;
+    }
+
+    if ((ret = generate_joint_tables(s)) < 0)
+        return ret;
+
+    return (get_bits_count(&gb) + 7) / 8;
+}
+
+static int read_old_huffman_tables(HYuvContext *s)
+{
+    GetBitContext gb;
+    int i;
+    int ret;
+
+    init_get_bits(&gb, classic_shift_luma,
+                  classic_shift_luma_table_size * 8);
+    if (read_len_table(s->len[0], &gb) < 0)
+        return -1;
+
+    init_get_bits(&gb, classic_shift_chroma,
+                  classic_shift_chroma_table_size * 8);
+    if (read_len_table(s->len[1], &gb) < 0)
+        return -1;
+
+    for(i=0; i<256; i++) s->bits[0][i] = classic_add_luma  [i];
+    for(i=0; i<256; i++) s->bits[1][i] = classic_add_chroma[i];
+
+    if (s->bitstream_bpp >= 24) {
+        memcpy(s->bits[1], s->bits[0], 256 * sizeof(uint32_t));
+        memcpy(s->len[1] , s->len [0], 256 * sizeof(uint8_t));
+    }
+    memcpy(s->bits[2], s->bits[1], 256 * sizeof(uint32_t));
+    memcpy(s->len[2] , s->len [1], 256 * sizeof(uint8_t));
+
+    for (i = 0; i < 3; i++) {
+        ff_free_vlc(&s->vlc[i]);
+        if ((ret = init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1,
+                            s->bits[i], 4, 4, 0)) < 0)
+            return ret;
+    }
+
+    if ((ret = generate_joint_tables(s)) < 0)
+        return ret;
+
+    return 0;
+}
+
+static av_cold int decode_init(AVCodecContext *avctx)
+{
+    HYuvContext *s = avctx->priv_data;
+
+    ff_huffyuv_common_init(avctx);
+    memset(s->vlc, 0, 3 * sizeof(VLC));
+
+    avctx->coded_frame = &s->picture;
+    avcodec_get_frame_defaults(&s->picture);
+    s->interlaced = s->height > 288;
+
+    s->bgr32 = 1;
+
+    if (avctx->extradata_size) {
+        if ((avctx->bits_per_coded_sample & 7) &&
+            avctx->bits_per_coded_sample != 12)
+            s->version = 1; // do such files exist at all?
+        else
+            s->version = 2;
+    } else
+        s->version = 0;
+
+    if (s->version == 2) {
+        int method, interlace;
+
+        if (avctx->extradata_size < 4)
+            return -1;
+
+        method = ((uint8_t*)avctx->extradata)[0];
+        s->decorrelate = method & 64 ? 1 : 0;
+        s->predictor = method & 63;
+        s->bitstream_bpp = ((uint8_t*)avctx->extradata)[1];
+        if (s->bitstream_bpp == 0)
+            s->bitstream_bpp = avctx->bits_per_coded_sample & ~7;
+        interlace = (((uint8_t*)avctx->extradata)[2] & 0x30) >> 4;
+        s->interlaced = (interlace == 1) ? 1 : (interlace == 2) ? 0 : s->interlaced;
+        s->context = ((uint8_t*)avctx->extradata)[2] & 0x40 ? 1 : 0;
+
+        if ( read_huffman_tables(s, ((uint8_t*)avctx->extradata) + 4,
+                                 avctx->extradata_size - 4) < 0)
+            return AVERROR_INVALIDDATA;
+    }else{
+        switch (avctx->bits_per_coded_sample & 7) {
+        case 1:
+            s->predictor = LEFT;
+            s->decorrelate = 0;
+            break;
+        case 2:
+            s->predictor = LEFT;
+            s->decorrelate = 1;
+            break;
+        case 3:
+            s->predictor = PLANE;
+            s->decorrelate = avctx->bits_per_coded_sample >= 24;
+            break;
+        case 4:
+            s->predictor = MEDIAN;
+            s->decorrelate = 0;
+            break;
+        default:
+            s->predictor = LEFT; //OLD
+            s->decorrelate = 0;
+            break;
+        }
+        s->bitstream_bpp = avctx->bits_per_coded_sample & ~7;
+        s->context = 0;
+
+        if (read_old_huffman_tables(s) < 0)
+            return AVERROR_INVALIDDATA;
+    }
+
+    switch (s->bitstream_bpp) {
+    case 12:
+        avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+        break;
+    case 16:
+        if (s->yuy2) {
+            avctx->pix_fmt = AV_PIX_FMT_YUYV422;
+        } else {
+            avctx->pix_fmt = AV_PIX_FMT_YUV422P;
+        }
+        break;
+    case 24:
+    case 32:
+        if (s->bgr32) {
+            avctx->pix_fmt = AV_PIX_FMT_RGB32;
+        } else {
+            avctx->pix_fmt = AV_PIX_FMT_BGR24;
+        }
+        break;
+    default:
+        return AVERROR_INVALIDDATA;
+    }
+
+    if ((avctx->pix_fmt == AV_PIX_FMT_YUV422P || avctx->pix_fmt == AV_PIX_FMT_YUV420P) && avctx->width & 1) {
+        av_log(avctx, AV_LOG_ERROR, "width must be even for this colorspace\n");
+        return AVERROR_INVALIDDATA;
+    }
+    if (s->predictor == MEDIAN && avctx->pix_fmt == AV_PIX_FMT_YUV422P && avctx->width%4) {
+        av_log(avctx, AV_LOG_ERROR, "width must be a multiple of 4 this colorspace and predictor\n");
+        return AVERROR_INVALIDDATA;
+    }
+    if (ff_huffyuv_alloc_temp(s)) {
+        ff_huffyuv_common_end(s);
+        return AVERROR(ENOMEM);
+    }
+
+    return 0;
+}
+
+static av_cold int decode_init_thread_copy(AVCodecContext *avctx)
+{
+    HYuvContext *s = avctx->priv_data;
+    int i;
+
+    avctx->coded_frame= &s->picture;
+    if (ff_huffyuv_alloc_temp(s)) {
+        ff_huffyuv_common_end(s);
+        return AVERROR(ENOMEM);
+    }
+
+    for (i = 0; i < 6; i++)
+        s->vlc[i].table = NULL;
+
+    if (s->version == 2) {
+        if (read_huffman_tables(s, ((uint8_t*)avctx->extradata) + 4,
+                                avctx->extradata_size) < 0)
+            return AVERROR_INVALIDDATA;
+    } else {
+        if (read_old_huffman_tables(s) < 0)
+            return AVERROR_INVALIDDATA;
+    }
+
+    return 0;
+}
+
+/* TODO instead of restarting the read when the code isn't in the first level
+ * of the joint table, jump into the 2nd level of the individual table. */
+#define READ_2PIX(dst0, dst1, plane1){\
+    uint16_t code = get_vlc2(&s->gb, s->vlc[3+plane1].table, VLC_BITS, 1);\
+    if(code != 0xffff){\
+        dst0 = code>>8;\
+        dst1 = code;\
+    }else{\
+        dst0 = get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);\
+        dst1 = get_vlc2(&s->gb, s->vlc[plane1].table, VLC_BITS, 3);\
+    }\
+}
+
+static void decode_422_bitstream(HYuvContext *s, int count)
+{
+    int i;
+
+    count /= 2;
+
+    if (count >= (get_bits_left(&s->gb)) / (31 * 4)) {
+        for (i = 0; i < count && get_bits_left(&s->gb) > 0; i++) {
+            READ_2PIX(s->temp[0][2 * i    ], s->temp[1][i], 1);
+            READ_2PIX(s->temp[0][2 * i + 1], s->temp[2][i], 2);
+        }
+    } else {
+        for (i = 0; i < count; i++) {
+            READ_2PIX(s->temp[0][2 * i    ], s->temp[1][i], 1);
+            READ_2PIX(s->temp[0][2 * i + 1], s->temp[2][i], 2);
+        }
+    }
+}
+
+static void decode_gray_bitstream(HYuvContext *s, int count)
+{
+    int i;
+
+    count/=2;
+
+    if (count >= (get_bits_left(&s->gb)) / (31 * 2)) {
+        for (i = 0; i < count && get_bits_left(&s->gb) > 0; i++) {
+            READ_2PIX(s->temp[0][2 * i], s->temp[0][2 * i + 1], 0);
+        }
+    } else {
+        for(i=0; i<count; i++){
+            READ_2PIX(s->temp[0][2 * i], s->temp[0][2 * i + 1], 0);
+        }
+    }
+}
+
+static av_always_inline void decode_bgr_1(HYuvContext *s, int count,
+                                          int decorrelate, int alpha)
+{
+    int i;
+    for (i = 0; i < count; i++) {
+        int code = get_vlc2(&s->gb, s->vlc[3].table, VLC_BITS, 1);
+        if (code != -1) {
+            *(uint32_t*)&s->temp[0][4 * i] = s->pix_bgr_map[code];
+        } else if(decorrelate) {
+            s->temp[0][4 * i + G] = get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
+            s->temp[0][4 * i + B] = get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3) +
+                                    s->temp[0][4 * i + G];
+            s->temp[0][4 * i + R] = get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3) +
+                                    s->temp[0][4 * i + G];
+        } else {
+            s->temp[0][4 * i + B] = get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
+            s->temp[0][4 * i + G] = get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
+            s->temp[0][4 * i + R] = get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3);
+        }
+        if (alpha)
+            s->temp[0][4 * i + A] = get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3);
+    }
+}
+
+static void decode_bgr_bitstream(HYuvContext *s, int count)
+{
+    if (s->decorrelate) {
+        if (s->bitstream_bpp==24)
+            decode_bgr_1(s, count, 1, 0);
+        else
+            decode_bgr_1(s, count, 1, 1);
+    } else {
+        if (s->bitstream_bpp==24)
+            decode_bgr_1(s, count, 0, 0);
+        else
+            decode_bgr_1(s, count, 0, 1);
+    }
+}
+
+static void draw_slice(HYuvContext *s, int y)
+{
+    int h, cy, i;
+    int offset[AV_NUM_DATA_POINTERS];
+
+    if (s->avctx->draw_horiz_band==NULL)
+        return;
+
+    h = y - s->last_slice_end;
+    y -= h;
+
+    if (s->bitstream_bpp == 12) {
+        cy = y>>1;
+    } else {
+        cy = y;
+    }
+
+    offset[0] = s->picture.linesize[0]*y;
+    offset[1] = s->picture.linesize[1]*cy;
+    offset[2] = s->picture.linesize[2]*cy;
+    for (i = 3; i < AV_NUM_DATA_POINTERS; i++)
+        offset[i] = 0;
+    emms_c();
+
+    s->avctx->draw_horiz_band(s->avctx, &s->picture, offset, y, 3, h);
+
+    s->last_slice_end = y + h;
+}
+
+static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
+                        AVPacket *avpkt)
+{
+    const uint8_t *buf = avpkt->data;
+    int buf_size = avpkt->size;
+    HYuvContext *s = avctx->priv_data;
+    const int width = s->width;
+    const int width2 = s->width>>1;
+    const int height = s->height;
+    int fake_ystride, fake_ustride, fake_vstride;
+    AVFrame * const p = &s->picture;
+    int table_size = 0, ret;
+
+    AVFrame *picture = data;
+
+    av_fast_padded_malloc(&s->bitstream_buffer,
+                   &s->bitstream_buffer_size,
+                   buf_size);
+    if (!s->bitstream_buffer)
+        return AVERROR(ENOMEM);
+
+    s->dsp.bswap_buf((uint32_t*)s->bitstream_buffer,
+                     (const uint32_t*)buf, buf_size / 4);
+
+    if (p->data[0])
+        ff_thread_release_buffer(avctx, p);
+
+    p->reference = 0;
+    if ((ret = ff_thread_get_buffer(avctx, p)) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+        return ret;
+    }
+
+    if (s->context) {
+        table_size = read_huffman_tables(s, s->bitstream_buffer, buf_size);
+        if (table_size < 0)
+            return AVERROR_INVALIDDATA;
+    }
+
+    if ((unsigned)(buf_size-table_size) >= INT_MAX / 8)
+        return AVERROR_INVALIDDATA;
+
+    init_get_bits(&s->gb, s->bitstream_buffer+table_size,
+                  (buf_size-table_size) * 8);
+
+    fake_ystride = s->interlaced ? p->linesize[0] * 2  : p->linesize[0];
+    fake_ustride = s->interlaced ? p->linesize[1] * 2  : p->linesize[1];
+    fake_vstride = s->interlaced ? p->linesize[2] * 2  : p->linesize[2];
+
+    s->last_slice_end = 0;
+
+    if (s->bitstream_bpp < 24) {
+        int y, cy;
+        int lefty, leftu, leftv;
+        int lefttopy, lefttopu, lefttopv;
+
+        if (s->yuy2) {
+            p->data[0][3] = get_bits(&s->gb, 8);
+            p->data[0][2] = get_bits(&s->gb, 8);
+            p->data[0][1] = get_bits(&s->gb, 8);
+            p->data[0][0] = get_bits(&s->gb, 8);
+
+            av_log(avctx, AV_LOG_ERROR,
+                   "YUY2 output is not implemented yet\n");
+            return AVERROR_PATCHWELCOME;
+        } else {
+
+            leftv = p->data[2][0] = get_bits(&s->gb, 8);
+            lefty = p->data[0][1] = get_bits(&s->gb, 8);
+            leftu = p->data[1][0] = get_bits(&s->gb, 8);
+                    p->data[0][0] = get_bits(&s->gb, 8);
+
+            switch (s->predictor) {
+            case LEFT:
+            case PLANE:
+                decode_422_bitstream(s, width-2);
+                lefty = s->dsp.add_hfyu_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty);
+                if (!(s->flags&CODEC_FLAG_GRAY)) {
+                    leftu = s->dsp.add_hfyu_left_prediction(p->data[1] + 1, s->temp[1], width2 - 1, leftu);
+                    leftv = s->dsp.add_hfyu_left_prediction(p->data[2] + 1, s->temp[2], width2 - 1, leftv);
+                }
+
+                for (cy = y = 1; y < s->height; y++, cy++) {
+                    uint8_t *ydst, *udst, *vdst;
+
+                    if (s->bitstream_bpp == 12) {
+                        decode_gray_bitstream(s, width);
+
+                        ydst = p->data[0] + p->linesize[0] * y;
+
+                        lefty = s->dsp.add_hfyu_left_prediction(ydst, s->temp[0], width, lefty);
+                        if (s->predictor == PLANE) {
+                            if (y > s->interlaced)
+                                s->dsp.add_bytes(ydst, ydst - fake_ystride, width);
+                        }
+                        y++;
+                        if (y >= s->height) break;
+                    }
+
+                    draw_slice(s, y);
+
+                    ydst = p->data[0] + p->linesize[0]*y;
+                    udst = p->data[1] + p->linesize[1]*cy;
+                    vdst = p->data[2] + p->linesize[2]*cy;
+
+                    decode_422_bitstream(s, width);
+                    lefty = s->dsp.add_hfyu_left_prediction(ydst, s->temp[0], width, lefty);
+                    if (!(s->flags & CODEC_FLAG_GRAY)) {
+                        leftu= s->dsp.add_hfyu_left_prediction(udst, s->temp[1], width2, leftu);
+                        leftv= s->dsp.add_hfyu_left_prediction(vdst, s->temp[2], width2, leftv);
+                    }
+                    if (s->predictor == PLANE) {
+                        if (cy > s->interlaced) {
+                            s->dsp.add_bytes(ydst, ydst - fake_ystride, width);
+                            if (!(s->flags & CODEC_FLAG_GRAY)) {
+                                s->dsp.add_bytes(udst, udst - fake_ustride, width2);
+                                s->dsp.add_bytes(vdst, vdst - fake_vstride, width2);
+                            }
+                        }
+                    }
+                }
+                draw_slice(s, height);
+
+                break;
+            case MEDIAN:
+                /* first line except first 2 pixels is left predicted */
+                decode_422_bitstream(s, width - 2);
+                lefty= s->dsp.add_hfyu_left_prediction(p->data[0] + 2, s->temp[0], width - 2, lefty);
+                if (!(s->flags & CODEC_FLAG_GRAY)) {
+                    leftu = s->dsp.add_hfyu_left_prediction(p->data[1] + 1, s->temp[1], width2 - 1, leftu);
+                    leftv = s->dsp.add_hfyu_left_prediction(p->data[2] + 1, s->temp[2], width2 - 1, leftv);
+                }
+
+                cy = y = 1;
+
+                /* second line is left predicted for interlaced case */
+                if (s->interlaced) {
+                    decode_422_bitstream(s, width);
+                    lefty = s->dsp.add_hfyu_left_prediction(p->data[0] + p->linesize[0], s->temp[0], width, lefty);
+                    if (!(s->flags & CODEC_FLAG_GRAY)) {
+                        leftu = s->dsp.add_hfyu_left_prediction(p->data[1] + p->linesize[2], s->temp[1], width2, leftu);
+                        leftv = s->dsp.add_hfyu_left_prediction(p->data[2] + p->linesize[1], s->temp[2], width2, leftv);
+                    }
+                    y++; cy++;
+                }
+
+                /* next 4 pixels are left predicted too */
+                decode_422_bitstream(s, 4);
+                lefty = s->dsp.add_hfyu_left_prediction(p->data[0] + fake_ystride, s->temp[0], 4, lefty);
+                if (!(s->flags&CODEC_FLAG_GRAY)) {
+                    leftu = s->dsp.add_hfyu_left_prediction(p->data[1] + fake_ustride, s->temp[1], 2, leftu);
+                    leftv = s->dsp.add_hfyu_left_prediction(p->data[2] + fake_vstride, s->temp[2], 2, leftv);
+                }
+
+                /* next line except the first 4 pixels is median predicted */
+                lefttopy = p->data[0][3];
+                decode_422_bitstream(s, width - 4);
+                s->dsp.add_hfyu_median_prediction(p->data[0] + fake_ystride+4, p->data[0]+4, s->temp[0], width-4, &lefty, &lefttopy);
+                if (!(s->flags&CODEC_FLAG_GRAY)) {
+                    lefttopu = p->data[1][1];
+                    lefttopv = p->data[2][1];
+                    s->dsp.add_hfyu_median_prediction(p->data[1] + fake_ustride+2, p->data[1] + 2, s->temp[1], width2 - 2, &leftu, &lefttopu);
+                    s->dsp.add_hfyu_median_prediction(p->data[2] + fake_vstride+2, p->data[2] + 2, s->temp[2], width2 - 2, &leftv, &lefttopv);
+                }
+                y++; cy++;
+
+                for (; y<height; y++, cy++) {
+                    uint8_t *ydst, *udst, *vdst;
+
+                    if (s->bitstream_bpp == 12) {
+                        while (2 * cy > y) {
+                            decode_gray_bitstream(s, width);
+                            ydst = p->data[0] + p->linesize[0] * y;
+                            s->dsp.add_hfyu_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy);
+                            y++;
+                        }
+                        if (y >= height) break;
+                    }
+                    draw_slice(s, y);
+
+                    decode_422_bitstream(s, width);
+
+                    ydst = p->data[0] + p->linesize[0] * y;
+                    udst = p->data[1] + p->linesize[1] * cy;
+                    vdst = p->data[2] + p->linesize[2] * cy;
+
+                    s->dsp.add_hfyu_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy);
+                    if (!(s->flags & CODEC_FLAG_GRAY)) {
+                        s->dsp.add_hfyu_median_prediction(udst, udst - fake_ustride, s->temp[1], width2, &leftu, &lefttopu);
+                        s->dsp.add_hfyu_median_prediction(vdst, vdst - fake_vstride, s->temp[2], width2, &leftv, &lefttopv);
+                    }
+                }
+
+                draw_slice(s, height);
+                break;
+            }
+        }
+    } else {
+        int y;
+        int leftr, leftg, leftb, lefta;
+        const int last_line = (height - 1) * p->linesize[0];
+
+        if (s->bitstream_bpp == 32) {
+            lefta = p->data[0][last_line+A] = get_bits(&s->gb, 8);
+            leftr = p->data[0][last_line+R] = get_bits(&s->gb, 8);
+            leftg = p->data[0][last_line+G] = get_bits(&s->gb, 8);
+            leftb = p->data[0][last_line+B] = get_bits(&s->gb, 8);
+        } else {
+            leftr = p->data[0][last_line+R] = get_bits(&s->gb, 8);
+            leftg = p->data[0][last_line+G] = get_bits(&s->gb, 8);
+            leftb = p->data[0][last_line+B] = get_bits(&s->gb, 8);
+            lefta = p->data[0][last_line+A] = 255;
+            skip_bits(&s->gb, 8);
+        }
+
+        if (s->bgr32) {
+            switch (s->predictor) {
+            case LEFT:
+            case PLANE:
+                decode_bgr_bitstream(s, width - 1);
+                s->dsp.add_hfyu_left_prediction_bgr32(p->data[0] + last_line+4, s->temp[0], width - 1, &leftr, &leftg, &leftb, &lefta);
+
+                for (y = s->height - 2; y >= 0; y--) { //Yes it is stored upside down.
+                    decode_bgr_bitstream(s, width);
+
+                    s->dsp.add_hfyu_left_prediction_bgr32(p->data[0] + p->linesize[0]*y, s->temp[0], width, &leftr, &leftg, &leftb, &lefta);
+                    if (s->predictor == PLANE) {
+                        if (s->bitstream_bpp != 32) lefta = 0;
+                        if ((y & s->interlaced) == 0 &&
+                            y < s->height - 1 - s->interlaced) {
+                            s->dsp.add_bytes(p->data[0] + p->linesize[0] * y,
+                                             p->data[0] + p->linesize[0] * y +
+                                             fake_ystride, fake_ystride);
+                        }
+                    }
+                }
+                // just 1 large slice as this is not possible in reverse order
+                draw_slice(s, height);
+                break;
+            default:
+                av_log(avctx, AV_LOG_ERROR,
+                       "prediction type not supported!\n");
+            }
+        }else{
+            av_log(avctx, AV_LOG_ERROR,
+                   "BGR24 output is not implemented yet\n");
+            return AVERROR_PATCHWELCOME;
+        }
+    }
+    emms_c();
+
+    *picture = *p;
+    *got_frame = 1;
+
+    return (get_bits_count(&s->gb) + 31) / 32 * 4 + table_size;
+}
+
+static av_cold int decode_end(AVCodecContext *avctx)
+{
+    HYuvContext *s = avctx->priv_data;
+    int i;
+
+    if (s->picture.data[0])
+        avctx->release_buffer(avctx, &s->picture);
+
+    ff_huffyuv_common_end(s);
+    av_freep(&s->bitstream_buffer);
+
+    for (i = 0; i < 6; i++) {
+        ff_free_vlc(&s->vlc[i]);
+    }
+
+    return 0;
+}
+
+#if CONFIG_HUFFYUV_DECODER
+AVCodec ff_huffyuv_decoder = {
+    .name             = "huffyuv",
+    .type             = AVMEDIA_TYPE_VIDEO,
+    .id               = AV_CODEC_ID_HUFFYUV,
+    .priv_data_size   = sizeof(HYuvContext),
+    .init             = decode_init,
+    .close            = decode_end,
+    .decode           = decode_frame,
+    .capabilities     = CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND |
+                        CODEC_CAP_FRAME_THREADS,
+    .init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy),
+    .long_name        = NULL_IF_CONFIG_SMALL("Huffyuv / HuffYUV"),
+};
+#endif
+
+#if CONFIG_FFVHUFF_DECODER
+AVCodec ff_ffvhuff_decoder = {
+    .name             = "ffvhuff",
+    .type             = AVMEDIA_TYPE_VIDEO,
+    .id               = AV_CODEC_ID_FFVHUFF,
+    .priv_data_size   = sizeof(HYuvContext),
+    .init             = decode_init,
+    .close            = decode_end,
+    .decode           = decode_frame,
+    .capabilities     = CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND |
+                        CODEC_CAP_FRAME_THREADS,
+    .init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy),
+    .long_name        = NULL_IF_CONFIG_SMALL("Huffyuv FFmpeg variant"),
+};
+#endif
diff --git a/libavcodec/huffyuvenc.c b/libavcodec/huffyuvenc.c
new file mode 100644
index 0000000..95dcb88
--- /dev/null
+++ b/libavcodec/huffyuvenc.c
@@ -0,0 +1,700 @@
+/*
+ * Copyright (c) 2002-2003 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * see http://www.pcisys.net/~melanson/codecs/huffyuv.txt for a description of
+ * the algorithm used
+ *
+ * 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
+ * huffyuv encoder
+ */
+
+#include "avcodec.h"
+#include "huffyuv.h"
+#include "huffman.h"
+#include "internal.h"
+#include "put_bits.h"
+
+static inline int sub_left_prediction(HYuvContext *s, uint8_t *dst,
+                                      const uint8_t *src, int w, int left)
+{
+    int i;
+    if (w < 32) {
+        for (i = 0; i < w; i++) {
+            const int temp = src[i];
+            dst[i] = temp - left;
+            left   = temp;
+        }
+        return left;
+    } else {
+        for (i = 0; i < 16; i++) {
+            const int temp = src[i];
+            dst[i] = temp - left;
+            left   = temp;
+        }
+        s->dsp.diff_bytes(dst + 16, src + 16, src + 15, w - 16);
+        return src[w-1];
+    }
+}
+
+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 i;
+    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];
+        const int bt = src[i * 4 + B];
+        const int at = src[i * 4 + A];
+        dst[i * 4 + R] = rt - r;
+        dst[i * 4 + G] = gt - g;
+        dst[i * 4 + B] = bt - b;
+        dst[i * 4 + A] = at - a;
+        r = rt;
+        g = gt;
+        b = bt;
+        a = at;
+    }
+
+    s->dsp.diff_bytes(dst + 16, src + 16, src + 12, w * 4 - 16);
+
+    *red   = src[(w - 1) * 4 + R];
+    *green = src[(w - 1) * 4 + G];
+    *blue  = src[(w - 1) * 4 + B];
+    *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){
+    int i;
+    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;
+        r = rt;
+        g = gt;
+        b = bt;
+    }
+
+    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];
+}
+
+static int store_table(HYuvContext *s, const uint8_t *len, uint8_t *buf)
+{
+    int i;
+    int index = 0;
+
+    for (i = 0; i < 256;) {
+        int val = len[i];
+        int repeat = 0;
+
+        for (; i < 256 && len[i] == val && repeat < 255; i++)
+            repeat++;
+
+        av_assert0(val < 32 && val >0 && repeat<256 && repeat>0);
+        if (repeat > 7) {
+            buf[index++] = val;
+            buf[index++] = repeat;
+        } else {
+            buf[index++] = val | (repeat << 5);
+        }
+    }
+
+    return index;
+}
+
+static av_cold int encode_init(AVCodecContext *avctx)
+{
+    HYuvContext *s = avctx->priv_data;
+    int i, j;
+
+    ff_huffyuv_common_init(avctx);
+
+    avctx->extradata = av_mallocz(1024*30); // 256*3+4 == 772
+    avctx->stats_out = av_mallocz(1024*30); // 21*256*3(%llu ) + 3(\n) + 1(0) = 16132
+    if (!avctx->extradata || !avctx->stats_out) {
+        av_freep(&avctx->stats_out);
+        return AVERROR(ENOMEM);
+    }
+    s->version = 2;
+
+    avctx->coded_frame = &s->picture;
+
+    switch (avctx->pix_fmt) {
+    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");
+            return AVERROR(EINVAL);
+        }
+        s->bitstream_bpp = avctx->pix_fmt == AV_PIX_FMT_YUV420P ? 12 : 16;
+        break;
+    case AV_PIX_FMT_RGB32:
+        s->bitstream_bpp = 32;
+        break;
+    case AV_PIX_FMT_RGB24:
+        s->bitstream_bpp = 24;
+        break;
+    default:
+        av_log(avctx, AV_LOG_ERROR, "format not supported\n");
+        return AVERROR(EINVAL);
+    }
+    avctx->bits_per_coded_sample = s->bitstream_bpp;
+    s->decorrelate = s->bitstream_bpp >= 24;
+    s->predictor = avctx->prediction_method;
+    s->interlaced = avctx->flags&CODEC_FLAG_INTERLACED_ME ? 1 : 0;
+    if (avctx->context_model == 1) {
+        s->context = avctx->context_model;
+        if (s->flags & (CODEC_FLAG_PASS1|CODEC_FLAG_PASS2)) {
+            av_log(avctx, AV_LOG_ERROR,
+                   "context=1 is not compatible with "
+                   "2 pass huffyuv encoding\n");
+            return AVERROR(EINVAL);
+        }
+    }else s->context= 0;
+
+    if (avctx->codec->id == AV_CODEC_ID_HUFFYUV) {
+        if (avctx->pix_fmt == AV_PIX_FMT_YUV420P) {
+            av_log(avctx, AV_LOG_ERROR,
+                   "Error: YV12 is not supported by huffyuv; use "
+                   "vcodec=ffvhuff or format=422p\n");
+            return AVERROR(EINVAL);
+        }
+        if (avctx->context_model) {
+            av_log(avctx, AV_LOG_ERROR,
+                   "Error: per-frame huffman tables are not supported "
+                   "by huffyuv; use vcodec=ffvhuff\n");
+            return AVERROR(EINVAL);
+        }
+        if (s->interlaced != ( s->height > 288 ))
+            av_log(avctx, AV_LOG_INFO,
+                   "using huffyuv 2.2.0 or newer interlacing flag\n");
+    }
+
+    if (s->bitstream_bpp >= 24 && s->predictor == MEDIAN) {
+        av_log(avctx, AV_LOG_ERROR,
+               "Error: RGB is incompatible with median predictor\n");
+        return AVERROR(EINVAL);
+    }
+
+    ((uint8_t*)avctx->extradata)[0] = s->predictor | (s->decorrelate << 6);
+    ((uint8_t*)avctx->extradata)[1] = s->bitstream_bpp;
+    ((uint8_t*)avctx->extradata)[2] = s->interlaced ? 0x10 : 0x20;
+    if (s->context)
+        ((uint8_t*)avctx->extradata)[2] |= 0x40;
+    ((uint8_t*)avctx->extradata)[3] = 0;
+    s->avctx->extradata_size = 4;
+
+    if (avctx->stats_in) {
+        char *p = avctx->stats_in;
+
+        for (i = 0; i < 3; i++)
+            for (j = 0; j < 256; j++)
+                s->stats[i][j] = 1;
+
+        for (;;) {
+            for (i = 0; i < 3; i++) {
+                char *next;
+
+                for (j = 0; j < 256; j++) {
+                    s->stats[i][j] += strtol(p, &next, 0);
+                    if (next == p) return -1;
+                    p = next;
+                }
+            }
+            if (p[0] == 0 || p[1] == 0 || p[2] == 0) break;
+        }
+    } else {
+        for (i = 0; i < 3; i++)
+            for (j = 0; j < 256; j++) {
+                int d = FFMIN(j, 256 - j);
+
+                s->stats[i][j] = 100000000 / (d + 1);
+            }
+    }
+
+    for (i = 0; i < 3; i++) {
+        ff_huff_gen_len_table(s->len[i], s->stats[i]);
+
+        if (ff_huffyuv_generate_bits_table(s->bits[i], s->len[i]) < 0) {
+            return -1;
+        }
+
+        s->avctx->extradata_size +=
+            store_table(s, s->len[i], &((uint8_t*)s->avctx->extradata)[s->avctx->extradata_size]);
+    }
+
+    if (s->context) {
+        for (i = 0; i < 3; i++) {
+            int pels = s->width * s->height / (i ? 40 : 10);
+            for (j = 0; j < 256; j++) {
+                int d = FFMIN(j, 256 - j);
+                s->stats[i][j] = pels/(d + 1);
+            }
+        }
+    } else {
+        for (i = 0; i < 3; i++)
+            for (j = 0; j < 256; j++)
+                s->stats[i][j]= 0;
+    }
+
+    if (ff_huffyuv_alloc_temp(s)) {
+        ff_huffyuv_common_end(s);
+        return AVERROR(ENOMEM);
+    }
+
+    s->picture_number=0;
+
+    return 0;
+}
+static int encode_422_bitstream(HYuvContext *s, int offset, int count)
+{
+    int i;
+    const uint8_t *y = s->temp[0] + offset;
+    const uint8_t *u = s->temp[1] + offset / 2;
+    const uint8_t *v = s->temp[2] + offset / 2;
+
+    if (s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb) >> 3) < 2 * 4 * count) {
+        av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
+        return -1;
+    }
+
+#define LOAD4\
+            int y0 = y[2 * i];\
+            int y1 = y[2 * i + 1];\
+            int u0 = u[i];\
+            int v0 = v[i];
+
+    count /= 2;
+
+    if (s->flags & CODEC_FLAG_PASS1) {
+        for(i = 0; i < count; i++) {
+            LOAD4;
+            s->stats[0][y0]++;
+            s->stats[1][u0]++;
+            s->stats[0][y1]++;
+            s->stats[2][v0]++;
+        }
+    }
+    if (s->avctx->flags2 & CODEC_FLAG2_NO_OUTPUT)
+        return 0;
+    if (s->context) {
+        for (i = 0; i < count; i++) {
+            LOAD4;
+            s->stats[0][y0]++;
+            put_bits(&s->pb, s->len[0][y0], s->bits[0][y0]);
+            s->stats[1][u0]++;
+            put_bits(&s->pb, s->len[1][u0], s->bits[1][u0]);
+            s->stats[0][y1]++;
+            put_bits(&s->pb, s->len[0][y1], s->bits[0][y1]);
+            s->stats[2][v0]++;
+            put_bits(&s->pb, s->len[2][v0], s->bits[2][v0]);
+        }
+    } else {
+        for(i = 0; i < count; i++) {
+            LOAD4;
+            put_bits(&s->pb, s->len[0][y0], s->bits[0][y0]);
+            put_bits(&s->pb, s->len[1][u0], s->bits[1][u0]);
+            put_bits(&s->pb, s->len[0][y1], s->bits[0][y1]);
+            put_bits(&s->pb, s->len[2][v0], s->bits[2][v0]);
+        }
+    }
+    return 0;
+}
+
+static int encode_gray_bitstream(HYuvContext *s, int count)
+{
+    int i;
+
+    if (s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb) >> 3) < 4 * count) {
+        av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
+        return -1;
+    }
+
+#define LOAD2\
+            int y0 = s->temp[0][2 * i];\
+            int y1 = s->temp[0][2 * i + 1];
+#define STAT2\
+            s->stats[0][y0]++;\
+            s->stats[0][y1]++;
+#define WRITE2\
+            put_bits(&s->pb, s->len[0][y0], s->bits[0][y0]);\
+            put_bits(&s->pb, s->len[0][y1], s->bits[0][y1]);
+
+    count /= 2;
+
+    if (s->flags & CODEC_FLAG_PASS1) {
+        for (i = 0; i < count; i++) {
+            LOAD2;
+            STAT2;
+        }
+    }
+    if (s->avctx->flags2 & CODEC_FLAG2_NO_OUTPUT)
+        return 0;
+
+    if (s->context) {
+        for (i = 0; i < count; i++) {
+            LOAD2;
+            STAT2;
+            WRITE2;
+        }
+    } else {
+        for (i = 0; i < count; i++) {
+            LOAD2;
+            WRITE2;
+        }
+    }
+    return 0;
+}
+
+static inline int encode_bgra_bitstream(HYuvContext *s, int count, int planes)
+{
+    int i;
+
+    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]);
+
+    if ((s->flags & CODEC_FLAG_PASS1) &&
+        (s->avctx->flags2 & CODEC_FLAG2_NO_OUTPUT)) {
+        for (i = 0; i < count; i++) {
+            LOAD3;
+            STAT3;
+        }
+    } else if (s->context || (s->flags & CODEC_FLAG_PASS1)) {
+        for (i = 0; i < count; i++) {
+            LOAD3;
+            STAT3;
+            WRITE3;
+        }
+    } else {
+        for (i = 0; i < count; i++) {
+            LOAD3;
+            WRITE3;
+        }
+    }
+    return 0;
+}
+
+static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
+                        const AVFrame *pict, int *got_packet)
+{
+    HYuvContext *s = avctx->priv_data;
+    const int width = s->width;
+    const int width2 = s->width>>1;
+    const int height = s->height;
+    const int fake_ystride = s->interlaced ? pict->linesize[0]*2  : pict->linesize[0];
+    const int fake_ustride = s->interlaced ? pict->linesize[1]*2  : pict->linesize[1];
+    const int fake_vstride = s->interlaced ? pict->linesize[2]*2  : pict->linesize[2];
+    AVFrame * const p = &s->picture;
+    int i, j, size = 0, ret;
+
+    if ((ret = ff_alloc_packet2(avctx, pkt, width * height * 3 * 4 + FF_MIN_BUFFER_SIZE)) < 0)
+        return ret;
+
+    *p = *pict;
+    p->pict_type = AV_PICTURE_TYPE_I;
+    p->key_frame = 1;
+
+    if (s->context) {
+        for (i = 0; i < 3; i++) {
+            ff_huff_gen_len_table(s->len[i], s->stats[i]);
+            if (ff_huffyuv_generate_bits_table(s->bits[i], s->len[i]) < 0)
+                return -1;
+            size += store_table(s, s->len[i], &pkt->data[size]);
+        }
+
+        for (i = 0; i < 3; i++)
+            for (j = 0; j < 256; j++)
+                s->stats[i][j] >>= 1;
+    }
+
+    init_put_bits(&s->pb, pkt->data + size, pkt->size - size);
+
+    if (avctx->pix_fmt == AV_PIX_FMT_YUV422P ||
+        avctx->pix_fmt == AV_PIX_FMT_YUV420P) {
+        int lefty, leftu, leftv, y, cy;
+
+        put_bits(&s->pb, 8, leftv = p->data[2][0]);
+        put_bits(&s->pb, 8, lefty = p->data[0][1]);
+        put_bits(&s->pb, 8, leftu = p->data[1][0]);
+        put_bits(&s->pb, 8,         p->data[0][0]);
+
+        lefty = sub_left_prediction(s, s->temp[0], p->data[0], width , 0);
+        leftu = sub_left_prediction(s, s->temp[1], p->data[1], width2, 0);
+        leftv = sub_left_prediction(s, s->temp[2], p->data[2], width2, 0);
+
+        encode_422_bitstream(s, 2, width-2);
+
+        if (s->predictor==MEDIAN) {
+            int lefttopy, lefttopu, lefttopv;
+            cy = y = 1;
+            if (s->interlaced) {
+                lefty = sub_left_prediction(s, s->temp[0], p->data[0] + p->linesize[0], width , lefty);
+                leftu = sub_left_prediction(s, s->temp[1], p->data[1] + p->linesize[1], width2, leftu);
+                leftv = sub_left_prediction(s, s->temp[2], p->data[2] + p->linesize[2], width2, leftv);
+
+                encode_422_bitstream(s, 0, width);
+                y++; cy++;
+            }
+
+            lefty = sub_left_prediction(s, s->temp[0], p->data[0] + fake_ystride, 4, lefty);
+            leftu = sub_left_prediction(s, s->temp[1], p->data[1] + fake_ustride, 2, leftu);
+            leftv = sub_left_prediction(s, s->temp[2], p->data[2] + fake_vstride, 2, leftv);
+
+            encode_422_bitstream(s, 0, 4);
+
+            lefttopy = p->data[0][3];
+            lefttopu = p->data[1][1];
+            lefttopv = p->data[2][1];
+            s->dsp.sub_hfyu_median_prediction(s->temp[0], p->data[0]+4, p->data[0] + fake_ystride + 4, width - 4 , &lefty, &lefttopy);
+            s->dsp.sub_hfyu_median_prediction(s->temp[1], p->data[1]+2, p->data[1] + fake_ustride + 2, width2 - 2, &leftu, &lefttopu);
+            s->dsp.sub_hfyu_median_prediction(s->temp[2], p->data[2]+2, p->data[2] + fake_vstride + 2, width2 - 2, &leftv, &lefttopv);
+            encode_422_bitstream(s, 0, width - 4);
+            y++; cy++;
+
+            for (; y < height; y++,cy++) {
+                uint8_t *ydst, *udst, *vdst;
+
+                if (s->bitstream_bpp == 12) {
+                    while (2 * cy > y) {
+                        ydst = p->data[0] + p->linesize[0] * y;
+                        s->dsp.sub_hfyu_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy);
+                        encode_gray_bitstream(s, width);
+                        y++;
+                    }
+                    if (y >= height) break;
+                }
+                ydst = p->data[0] + p->linesize[0] * y;
+                udst = p->data[1] + p->linesize[1] * cy;
+                vdst = p->data[2] + p->linesize[2] * cy;
+
+                s->dsp.sub_hfyu_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy);
+                s->dsp.sub_hfyu_median_prediction(s->temp[1], udst - fake_ustride, udst, width2, &leftu, &lefttopu);
+                s->dsp.sub_hfyu_median_prediction(s->temp[2], vdst - fake_vstride, vdst, width2, &leftv, &lefttopv);
+
+                encode_422_bitstream(s, 0, width);
+            }
+        } else {
+            for (cy = y = 1; y < height; y++, cy++) {
+                uint8_t *ydst, *udst, *vdst;
+
+                /* encode a luma only line & y++ */
+                if (s->bitstream_bpp == 12) {
+                    ydst = p->data[0] + p->linesize[0] * y;
+
+                    if (s->predictor == PLANE && s->interlaced < y) {
+                        s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width);
+
+                        lefty = sub_left_prediction(s, s->temp[0], s->temp[1], width , lefty);
+                    } else {
+                        lefty = sub_left_prediction(s, s->temp[0], ydst, width , lefty);
+                    }
+                    encode_gray_bitstream(s, width);
+                    y++;
+                    if (y >= height) break;
+                }
+
+                ydst = p->data[0] + p->linesize[0] * y;
+                udst = p->data[1] + p->linesize[1] * cy;
+                vdst = p->data[2] + p->linesize[2] * cy;
+
+                if (s->predictor == PLANE && s->interlaced < cy) {
+                    s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width);
+                    s->dsp.diff_bytes(s->temp[2], udst, udst - fake_ustride, width2);
+                    s->dsp.diff_bytes(s->temp[2] + width2, vdst, vdst - fake_vstride, width2);
+
+                    lefty = sub_left_prediction(s, s->temp[0], s->temp[1], width , lefty);
+                    leftu = sub_left_prediction(s, s->temp[1], s->temp[2], width2, leftu);
+                    leftv = sub_left_prediction(s, s->temp[2], s->temp[2] + width2, width2, leftv);
+                } else {
+                    lefty = sub_left_prediction(s, s->temp[0], ydst, width , lefty);
+                    leftu = sub_left_prediction(s, s->temp[1], udst, width2, leftu);
+                    leftv = sub_left_prediction(s, s->temp[2], vdst, width2, leftv);
+                }
+
+                encode_422_bitstream(s, 0, width);
+            }
+        }
+    } else if(avctx->pix_fmt == AV_PIX_FMT_RGB32) {
+        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, lefta;
+
+        put_bits(&s->pb, 8, lefta = data[A]);
+        put_bits(&s->pb, 8, leftr = data[R]);
+        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);
+        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);
+            } else {
+                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];
+        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, 0);
+
+        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);
+            }
+            encode_bgra_bitstream(s, width, 3);
+        }
+    } else {
+        av_log(avctx, AV_LOG_ERROR, "Format not supported!\n");
+    }
+    emms_c();
+
+    size += (put_bits_count(&s->pb) + 31) / 8;
+    put_bits(&s->pb, 16, 0);
+    put_bits(&s->pb, 15, 0);
+    size /= 4;
+
+    if ((s->flags&CODEC_FLAG_PASS1) && (s->picture_number & 31) == 0) {
+        int j;
+        char *p = avctx->stats_out;
+        char *end = p + 1024*30;
+        for (i = 0; i < 3; i++) {
+            for (j = 0; j < 256; j++) {
+                snprintf(p, end-p, "%"PRIu64" ", s->stats[i][j]);
+                p += strlen(p);
+                s->stats[i][j]= 0;
+            }
+            snprintf(p, end-p, "\n");
+            p++;
+        }
+    } else
+        avctx->stats_out[0] = '\0';
+    if (!(s->avctx->flags2 & CODEC_FLAG2_NO_OUTPUT)) {
+        flush_put_bits(&s->pb);
+        s->dsp.bswap_buf((uint32_t*)pkt->data, (uint32_t*)pkt->data, size);
+    }
+
+    s->picture_number++;
+
+    pkt->size   = size * 4;
+    pkt->flags |= AV_PKT_FLAG_KEY;
+    *got_packet = 1;
+
+    return 0;
+}
+
+static av_cold int encode_end(AVCodecContext *avctx)
+{
+    HYuvContext *s = avctx->priv_data;
+
+    ff_huffyuv_common_end(s);
+
+    av_freep(&avctx->extradata);
+    av_freep(&avctx->stats_out);
+
+    return 0;
+}
+
+#if CONFIG_HUFFYUV_ENCODER
+AVCodec ff_huffyuv_encoder = {
+    .name           = "huffyuv",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_HUFFYUV,
+    .priv_data_size = sizeof(HYuvContext),
+    .init           = encode_init,
+    .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
+    },
+    .long_name      = NULL_IF_CONFIG_SMALL("Huffyuv / HuffYUV"),
+};
+#endif
+
+#if CONFIG_FFVHUFF_ENCODER
+AVCodec ff_ffvhuff_encoder = {
+    .name           = "ffvhuff",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_FFVHUFF,
+    .priv_data_size = sizeof(HYuvContext),
+    .init           = encode_init,
+    .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
+    },
+    .long_name      = NULL_IF_CONFIG_SMALL("Huffyuv FFmpeg variant"),
+};
+#endif
diff --git a/libavcodec/idcinvideo.c b/libavcodec/idcinvideo.c
index a517d9d..2070419 100644
--- a/libavcodec/idcinvideo.c
+++ b/libavcodec/idcinvideo.c
@@ -49,6 +49,7 @@
 #include <string.h>
 
 #include "avcodec.h"
+#include "internal.h"
 #include "libavutil/internal.h"
 
 #define HUFFMAN_TABLE_SIZE 64 * 1024
@@ -168,7 +169,6 @@
     }
 
     avcodec_get_frame_defaults(&s->frame);
-    s->frame.data[0] = NULL;
 
     return 0;
 }
@@ -212,7 +212,7 @@
 }
 
 static int idcin_decode_frame(AVCodecContext *avctx,
-                              void *data, int *data_size,
+                              void *data, int *got_frame,
                               AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
@@ -227,7 +227,7 @@
     if (s->frame.data[0])
         avctx->release_buffer(avctx, &s->frame);
 
-    if ((ret = avctx->get_buffer(avctx, &s->frame))) {
+    if ((ret = ff_get_buffer(avctx, &s->frame))) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -242,7 +242,7 @@
     /* make the palette available on the way out */
     memcpy(s->frame.data[1], s->pal, AVPALETTE_SIZE);
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*)data = s->frame;
 
     /* report that the buffer was completely consumed */
diff --git a/libavcodec/iff.c b/libavcodec/iff.c
index 04c359e..8e7f8ca 100644
--- a/libavcodec/iff.c
+++ b/libavcodec/iff.c
@@ -29,6 +29,7 @@
 #include "bytestream.h"
 #include "avcodec.h"
 #include "get_bits.h"
+#include "internal.h"
 
 // TODO: masking bits
 typedef enum {
@@ -53,6 +54,7 @@
     unsigned  transparency; ///< TODO: transparency color index in palette
     unsigned  masking;      ///< TODO: masking method used
     int init; // 1 if buffer and palette data already initialized, 0 otherwise
+    int16_t   tvdc[16];     ///< TVDC lookup table
 } IffContext;
 
 #define LUT8_PART(plane, v)                             \
@@ -137,7 +139,7 @@
 /**
  * Convert CMAP buffer (stored in extradata) to lavc palette format
  */
-static int ff_cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
+static int cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
 {
     IffContext *s = avctx->priv_data;
     int count, i;
@@ -191,7 +193,7 @@
     const uint8_t *buf;
     unsigned buf_size;
     IffContext *s = avctx->priv_data;
-    int palette_size;
+    int i, palette_size;
 
     if (avctx->extradata_size < 2) {
         av_log(avctx, AV_LOG_ERROR, "not enough extradata\n");
@@ -223,13 +225,16 @@
         }
     }
 
-    if (buf_size > 8) {
+    if (buf_size >= 41) {
         s->compression  = bytestream_get_byte(&buf);
         s->bpp          = bytestream_get_byte(&buf);
         s->ham          = bytestream_get_byte(&buf);
         s->flags        = bytestream_get_byte(&buf);
         s->transparency = bytestream_get_be16(&buf);
         s->masking      = bytestream_get_byte(&buf);
+        for (i = 0; i < 16; i++)
+            s->tvdc[i] = bytestream_get_be16(&buf);
+
         if (s->masking == MASK_HAS_MASK) {
             if (s->bpp >= 8 && !s->ham) {
                 avctx->pix_fmt = AV_PIX_FMT_RGB32;
@@ -330,9 +335,13 @@
         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('D','E','E','P')) {
+        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')) {
+            avctx->pix_fmt = AV_PIX_FMT_RGB444;
+        } else if (avctx->codec_tag != MKTAG('D','E','E','P')) {
             if (avctx->bits_per_coded_sample == 24) {
-                avctx->pix_fmt = AV_PIX_FMT_RGB0;
+                avctx->pix_fmt = AV_PIX_FMT_0BGR32;
             } else if (avctx->bits_per_coded_sample == 32) {
                 avctx->pix_fmt = AV_PIX_FMT_BGR32;
             } else {
@@ -479,6 +488,61 @@
     return buf - buf_start;
 }
 
+#define DECODE_RGBX_COMMON(type) \
+    if (!length) { \
+        length = bytestream2_get_byte(gb); \
+        if (!length) { \
+            length = bytestream2_get_be16(gb); \
+            if (!length) \
+                return; \
+        } \
+    } \
+    for (i = 0; i < length; i++) { \
+        *(type *)(dst + y*linesize + x * sizeof(type)) = pixel; \
+        x += 1; \
+        if (x >= width) { \
+            y += 1; \
+            if (y >= height) \
+                return; \
+            x = 0; \
+        } \
+    }
+
+/**
+ * Decode RGB8 buffer
+ * @param[out] dst Destination buffer
+ * @param width Width of destination buffer (pixels)
+ * @param height Height of destination buffer (pixels)
+ * @param linesize Line size of destination buffer (bytes)
+ */
+static void decode_rgb8(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
+{
+    int x = 0, y = 0, i, length;
+    while (bytestream2_get_bytes_left(gb) >= 4) {
+        uint32_t pixel = 0xFF000000 | bytestream2_get_be24(gb);
+        length = bytestream2_get_byte(gb) & 0x7F;
+        DECODE_RGBX_COMMON(uint32_t)
+    }
+}
+
+/**
+ * Decode RGBN buffer
+ * @param[out] dst Destination buffer
+ * @param width Width of destination buffer (pixels)
+ * @param height Height of destination buffer (pixels)
+ * @param linesize Line size of destination buffer (bytes)
+ */
+static void decode_rgbn(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
+{
+    int x = 0, y = 0, i, length;
+    while (bytestream2_get_bytes_left(gb) >= 2) {
+        uint32_t pixel = bytestream2_get_be16u(gb);
+        length = pixel & 0x7;
+        pixel >>= 4;
+        DECODE_RGBX_COMMON(uint16_t)
+    }
+}
+
 /**
  * Decode DEEP RLE 32-bit buffer
  * @param[out] dst Destination buffer
@@ -512,7 +576,7 @@
             }
         } else {
             int size = -opcode + 1;
-            uint32_t pixel = AV_RL32(src);
+            uint32_t pixel = AV_RN32(src);
             for (i = 0; i < size; i++) {
                 *(uint32_t *)(dst + y*linesize + x * 4) = pixel;
                 x += 1;
@@ -528,6 +592,56 @@
     }
 }
 
+/**
+ * Decode DEEP TVDC 32-bit buffer
+ * @param[out] dst Destination buffer
+ * @param[in] src Source buffer
+ * @param src_size Source buffer size (bytes)
+ * @param width Width of destination buffer (pixels)
+ * @param height Height of destination buffer (pixels)
+ * @param linesize Line size of destination buffer (bytes)
+ * @param[int] tvdc TVDC lookup table
+ */
+static void decode_deep_tvdc32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize, const int16_t *tvdc)
+{
+    int x = 0, y = 0, plane = 0;
+    int8_t pixel = 0;
+    int i, j;
+
+    for (i = 0; i < src_size * 2;) {
+#define GETNIBBLE ((i & 1) ?  (src[i>>1] & 0xF) : (src[i>>1] >> 4))
+        int d = tvdc[GETNIBBLE];
+        i++;
+        if (d) {
+            pixel += d;
+            dst[y * linesize + x*4 + plane] = pixel;
+            x++;
+        } else {
+            if (i >= src_size * 2)
+                return;
+            d = GETNIBBLE + 1;
+            i++;
+            d = FFMIN(d, width - x);
+            for (j = 0; j < d; j++) {
+                dst[y * linesize + x*4 + plane] = pixel;
+                x++;
+            }
+        }
+        if (x >= width) {
+            plane++;
+            if (plane >= 4) {
+                y++;
+                if (y >= height)
+                    return;
+                plane = 0;
+            }
+            x = 0;
+            pixel = 0;
+            i = (i + 1) & ~1;
+        }
+    }
+}
+
 static int unsupported(AVCodecContext *avctx)
 {
     IffContext *s = avctx->priv_data;
@@ -536,7 +650,7 @@
 }
 
 static int decode_frame(AVCodecContext *avctx,
-                            void *data, int *data_size,
+                            void *data, int *got_frame,
                             AVPacket *avpkt)
 {
     IffContext *s = avctx->priv_data;
@@ -544,6 +658,7 @@
     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;
 
     if ((res = extract_header(avctx, avpkt)) < 0)
         return res;
@@ -552,14 +667,14 @@
             av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
             return res;
         }
-    } else if ((res = avctx->get_buffer(avctx, &s->frame)) < 0) {
+    } else if ((res = ff_get_buffer(avctx, &s->frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return res;
     } else if (avctx->bits_per_coded_sample <= 8 && avctx->pix_fmt == AV_PIX_FMT_PAL8) {
-        if ((res = ff_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 (avctx->pix_fmt == AV_PIX_FMT_RGB32 && avctx->bits_per_coded_sample <= 8) {
-        if ((res = ff_cmap_read_palette(avctx, s->mask_palbuf)) < 0)
+        if ((res = cmap_read_palette(avctx, s->mask_palbuf)) < 0)
             return res;
     }
     s->init = 1;
@@ -715,11 +830,30 @@
                 return unsupported(avctx);
         }
         break;
+    case 4:
+        bytestream2_init(&gb, buf, buf_size);
+        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'))
+            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')) {
+            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);
+            else
+                return unsupported(avctx);
+        } else
+            return unsupported(avctx);
+        break;
     default:
         return unsupported(avctx);
     }
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*)data = s->frame;
     return buf_size;
 }
diff --git a/libavcodec/iirfilter.c b/libavcodec/iirfilter.c
index 3774d6e..610add1 100644
--- a/libavcodec/iirfilter.c
+++ b/libavcodec/iirfilter.c
@@ -312,7 +312,6 @@
 }
 
 #ifdef TEST
-#undef printf
 #include <stdio.h>
 
 #define FILT_ORDER 4
diff --git a/libavcodec/imc.c b/libavcodec/imc.c
index feca07c..0f43461 100644
--- a/libavcodec/imc.c
+++ b/libavcodec/imc.c
@@ -36,11 +36,14 @@
 #include <stdio.h>
 
 #include "libavutil/channel_layout.h"
+#include "libavutil/float_dsp.h"
+#include "libavutil/internal.h"
 #include "libavutil/libm.h"
 #include "avcodec.h"
 #include "get_bits.h"
 #include "dsputil.h"
 #include "fft.h"
+#include "internal.h"
 #include "sinewin.h"
 
 #include "imcdata.h"
@@ -78,8 +81,6 @@
 } IMCChannel;
 
 typedef struct {
-    AVFrame frame;
-
     IMCChannel chctx[2];
 
     /** MDCT tables */
@@ -95,6 +96,7 @@
     GetBitContext gb;
 
     DSPContext dsp;
+    AVFloatDSPContext fdsp;
     FFTContext fft;
     DECLARE_ALIGNED(32, FFTComplex, samples)[COEFFS / 2];
     float *out_samples;
@@ -244,13 +246,11 @@
         return ret;
     }
     ff_dsputil_init(&q->dsp, avctx);
+    avpriv_float_dsp_init(&q->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
     avctx->sample_fmt     = AV_SAMPLE_FMT_FLTP;
     avctx->channel_layout = avctx->channels == 1 ? AV_CH_LAYOUT_MONO
                                                  : AV_CH_LAYOUT_STEREO;
 
-    avcodec_get_frame_defaults(&q->frame);
-    avctx->coded_frame = &q->frame;
-
     return 0;
 }
 
@@ -932,6 +932,7 @@
 static int imc_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;
     int ret, i;
@@ -946,14 +947,14 @@
     }
 
     /* get output buffer */
-    q->frame.nb_samples = COEFFS;
-    if ((ret = avctx->get_buffer(avctx, &q->frame)) < 0) {
+    frame->nb_samples = COEFFS;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
 
     for (i = 0; i < avctx->channels; i++) {
-        q->out_samples = (float *)q->frame.extended_data[i];
+        q->out_samples = (float *)frame->extended_data[i];
 
         q->dsp.bswap16_buf(buf16, (const uint16_t*)buf, IMC_BLOCK_SIZE / 2);
 
@@ -966,12 +967,11 @@
     }
 
     if (avctx->channels == 2) {
-        q->dsp.butterflies_float((float *)q->frame.extended_data[0],
-                                 (float *)q->frame.extended_data[1], COEFFS);
+        q->fdsp.butterflies_float((float *)frame->extended_data[0],
+                                  (float *)frame->extended_data[1], COEFFS);
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = q->frame;
+    *got_frame_ptr = 1;
 
     return IMC_BLOCK_SIZE * avctx->channels;
 }
diff --git a/libavcodec/imgconvert.c b/libavcodec/imgconvert.c
index 66ce9cd..7b5be5c 100644
--- a/libavcodec/imgconvert.c
+++ b/libavcodec/imgconvert.c
@@ -32,6 +32,7 @@
 
 #include "avcodec.h"
 #include "dsputil.h"
+#include "imgconvert.h"
 #include "internal.h"
 #include "libavutil/avassert.h"
 #include "libavutil/colorspace.h"
@@ -69,7 +70,7 @@
     *v_shift = desc->log2_chroma_h;
 }
 
-static int get_color_type(AVPixFmtDescriptor *desc) {
+static int get_color_type(const AVPixFmtDescriptor *desc) {
     if(desc->nb_components == 1 || desc->nb_components == 2)
         return FF_COLOR_GRAY;
 
@@ -103,24 +104,25 @@
     return 0;
 }
 
-int avcodec_get_pix_fmt_loss(enum AVPixelFormat dst_pix_fmt,
-                             enum AVPixelFormat src_pix_fmt,
-                             int has_alpha)
+static int get_pix_fmt_score(enum AVPixelFormat dst_pix_fmt,
+                              enum AVPixelFormat src_pix_fmt,
+                              unsigned *lossp, unsigned consider)
 {
     const AVPixFmtDescriptor *src_desc = av_pix_fmt_desc_get(src_pix_fmt);
     const AVPixFmtDescriptor *dst_desc = av_pix_fmt_desc_get(dst_pix_fmt);
     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;
 
     if (dst_pix_fmt >= AV_PIX_FMT_NB || dst_pix_fmt <= AV_PIX_FMT_NONE)
         return ~0;
 
     /* compute loss */
-    loss = 0;
+    *lossp = loss = 0;
 
     if (dst_pix_fmt == src_pix_fmt)
-        return 0;
+        return INT_MAX;
 
     if ((ret = get_pix_fmt_depth(&src_min_depth, &src_max_depth, src_pix_fmt)) < 0)
         return ret;
@@ -132,13 +134,28 @@
     nb_components = FFMIN(src_desc->nb_components, dst_desc->nb_components);
 
     for (i = 0; i < nb_components; i++)
-        if (src_desc->comp[i].depth_minus1 > dst_desc->comp[i].depth_minus1)
+        if (src_desc->comp[i].depth_minus1 > dst_desc->comp[i].depth_minus1 && (consider & FF_LOSS_DEPTH)) {
             loss |= FF_LOSS_DEPTH;
+            score -= 65536 >> dst_desc->comp[i].depth_minus1;
+        }
 
-    if (dst_desc->log2_chroma_w > src_desc->log2_chroma_w ||
-        dst_desc->log2_chroma_h > src_desc->log2_chroma_h)
-        loss |= FF_LOSS_RESOLUTION;
+    if (consider & FF_LOSS_RESOLUTION) {
+        if (dst_desc->log2_chroma_w > src_desc->log2_chroma_w) {
+            loss |= FF_LOSS_RESOLUTION;
+            score -= 256 << dst_desc->log2_chroma_w;
+        }
+        if (dst_desc->log2_chroma_h > src_desc->log2_chroma_h) {
+            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
+        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;
+        }
+    }
 
+    if(consider & FF_LOSS_COLORSPACE)
     switch(dst_color) {
     case FF_COLOR_RGB:
         if (src_color != FF_COLOR_RGB &&
@@ -165,15 +182,36 @@
             loss |= FF_LOSS_COLORSPACE;
         break;
     }
-    if (dst_color == FF_COLOR_GRAY &&
-        src_color != FF_COLOR_GRAY)
-        loss |= FF_LOSS_CHROMA;
-    if (!pixdesc_has_alpha(dst_desc) && (pixdesc_has_alpha(src_desc) && has_alpha))
-        loss |= FF_LOSS_ALPHA;
-    if (dst_pix_fmt == AV_PIX_FMT_PAL8 &&
-        (src_pix_fmt != AV_PIX_FMT_PAL8 && (src_color != FF_COLOR_GRAY || (pixdesc_has_alpha(src_desc) && has_alpha))))
-        loss |= FF_LOSS_COLORQUANT;
+    if(loss & FF_LOSS_COLORSPACE)
+        score -= (nb_components * 65536) >> FFMIN(dst_desc->comp[0].depth_minus1, src_desc->comp[0].depth_minus1);
 
+    if (dst_color == FF_COLOR_GRAY &&
+        src_color != FF_COLOR_GRAY && (consider & FF_LOSS_CHROMA)) {
+        loss |= FF_LOSS_CHROMA;
+        score -= 2 * 65536;
+    }
+    if (!pixdesc_has_alpha(dst_desc) && (pixdesc_has_alpha(src_desc) && (consider & FF_LOSS_ALPHA))) {
+        loss |= FF_LOSS_ALPHA;
+        score -= 65536;
+    }
+    if (dst_pix_fmt == AV_PIX_FMT_PAL8 && (consider & FF_LOSS_COLORQUANT) &&
+        (src_pix_fmt != AV_PIX_FMT_PAL8 && (src_color != FF_COLOR_GRAY || (pixdesc_has_alpha(src_desc) && (consider & FF_LOSS_ALPHA))))) {
+        loss |= FF_LOSS_COLORQUANT;
+        score -= 65536;
+    }
+
+    *lossp = loss;
+    return score;
+}
+
+int avcodec_get_pix_fmt_loss(enum AVPixelFormat dst_pix_fmt,
+                             enum AVPixelFormat src_pix_fmt,
+                             int has_alpha)
+{
+    int loss;
+    int ret = get_pix_fmt_score(dst_pix_fmt, src_pix_fmt, &loss, has_alpha ? ~0 : ~FF_LOSS_ALPHA);
+    if (ret < 0)
+        return ret;
     return loss;
 }
 
@@ -200,43 +238,27 @@
                                             enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr)
 {
     enum AVPixelFormat dst_pix_fmt;
-    int loss1, loss2, loss_order1, loss_order2, i, loss_mask;
+    int loss1, loss2, loss_mask;
     const AVPixFmtDescriptor *desc1 = av_pix_fmt_desc_get(dst_pix_fmt1);
     const AVPixFmtDescriptor *desc2 = av_pix_fmt_desc_get(dst_pix_fmt2);
-    static const int loss_mask_order[] = {
-        ~0, /* no loss first */
-        ~FF_LOSS_ALPHA,
-        ~FF_LOSS_RESOLUTION,
-        ~FF_LOSS_COLORSPACE,
-        ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION),
-        ~FF_LOSS_COLORQUANT,
-        ~FF_LOSS_DEPTH,
-        ~(FF_LOSS_DEPTH|FF_LOSS_COLORSPACE),
-        ~(FF_LOSS_RESOLUTION | FF_LOSS_DEPTH | FF_LOSS_COLORSPACE | FF_LOSS_ALPHA |
-          FF_LOSS_COLORQUANT | FF_LOSS_CHROMA),
-        0x80000, //non zero entry that combines all loss variants including future additions
-        0,
-    };
+    int score1, score2;
 
     loss_mask= loss_ptr?~*loss_ptr:~0; /* use loss mask if provided */
+    if(!has_alpha)
+        loss_mask &= ~FF_LOSS_ALPHA;
+
     dst_pix_fmt = AV_PIX_FMT_NONE;
-    loss1 = avcodec_get_pix_fmt_loss(dst_pix_fmt1, src_pix_fmt, has_alpha) & loss_mask;
-    loss2 = avcodec_get_pix_fmt_loss(dst_pix_fmt2, src_pix_fmt, has_alpha) & loss_mask;
+    score1 = get_pix_fmt_score(dst_pix_fmt1, src_pix_fmt, &loss1, loss_mask);
+    score2 = get_pix_fmt_score(dst_pix_fmt2, src_pix_fmt, &loss2, loss_mask);
 
-    /* try with successive loss */
-    for(i = 0;loss_mask_order[i] != 0 && dst_pix_fmt == AV_PIX_FMT_NONE;i++) {
-        loss_order1 = loss1 & loss_mask_order[i];
-        loss_order2 = loss2 & loss_mask_order[i];
-
-        if (loss_order1 == 0 && loss_order2 == 0 && dst_pix_fmt2 != AV_PIX_FMT_NONE && dst_pix_fmt1 != AV_PIX_FMT_NONE){ /* use format with smallest depth */
-            if(av_get_padded_bits_per_pixel(desc2) != av_get_padded_bits_per_pixel(desc1)) {
-                dst_pix_fmt = av_get_padded_bits_per_pixel(desc2) < av_get_padded_bits_per_pixel(desc1) ? dst_pix_fmt2 : dst_pix_fmt1;
-            } else {
-                dst_pix_fmt = desc2->nb_components < desc1->nb_components ? dst_pix_fmt2 : dst_pix_fmt1;
-            }
-        } else if (loss_order1 == 0 || loss_order2 == 0) { /* use format with no loss */
-            dst_pix_fmt = loss_order2 ? dst_pix_fmt1 : dst_pix_fmt2;
+    if (score1 == score2) {
+        if(av_get_padded_bits_per_pixel(desc2) != av_get_padded_bits_per_pixel(desc1)) {
+            dst_pix_fmt = av_get_padded_bits_per_pixel(desc2) < av_get_padded_bits_per_pixel(desc1) ? dst_pix_fmt2 : dst_pix_fmt1;
+        } else {
+            dst_pix_fmt = desc2->nb_components < desc1->nb_components ? dst_pix_fmt2 : dst_pix_fmt1;
         }
+    } else {
+        dst_pix_fmt = score1 < score2 ? dst_pix_fmt2 : dst_pix_fmt1;
     }
 
     if (loss_ptr)
diff --git a/libavcodec/x86/dwt.h b/libavcodec/imgconvert.h
similarity index 62%
copy from libavcodec/x86/dwt.h
copy to libavcodec/imgconvert.h
index 199f611..df8cee7 100644
--- a/libavcodec/x86/dwt.h
+++ b/libavcodec/imgconvert.h
@@ -16,15 +16,14 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#ifndef AVCODEC_X86_DWT_H
-#define AVCODEC_X86_DWT_H
+#ifndef AVCODEC_IMGCONVERT_H
+#define AVCODEC_IMGCONVERT_H
 
-#include "libavcodec/dwt.h"
+#include <stdint.h>
 
-void ff_horizontal_compose_dd97i_end_c(IDWTELEM *b, IDWTELEM *tmp, int w2, int x);
-void ff_horizontal_compose_haar1i_end_c(IDWTELEM *b, IDWTELEM *tmp, int w2, int x);
-void ff_horizontal_compose_haar0i_end_c(IDWTELEM *b, IDWTELEM *tmp, int w2, int x);
+/* 1/2^n downscaling functions */
+void ff_shrink22(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height);
+void ff_shrink44(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height);
+void ff_shrink88(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height);
 
-void ff_spatial_idwt_init_mmx(DWTContext *d, enum dwt_type type);
-
-#endif
+#endif /* AVCODEC_IMGCONVERT_H */
diff --git a/libavcodec/indeo2.c b/libavcodec/indeo2.c
index 74a9800..ec6ff3c 100644
--- a/libavcodec/indeo2.c
+++ b/libavcodec/indeo2.c
@@ -47,8 +47,8 @@
     return get_vlc2(gb, ir2_vlc.table, CODE_VLC_BITS, 1) + 1;
 }
 
-static int ir2_decode_plane(Ir2Context *ctx, int width, int height, uint8_t *dst, int stride,
-                             const uint8_t *table)
+static int ir2_decode_plane(Ir2Context *ctx, int width, int height, uint8_t *dst,
+                            int stride, const uint8_t *table)
 {
     int i;
     int j;
@@ -56,16 +56,16 @@
     int c;
     int t;
 
-    if(width&1)
-        return -1;
+    if (width & 1)
+        return AVERROR_INVALIDDATA;
 
     /* first line contain absolute values, other lines contain deltas */
-    while (out < width){
+    while (out < width) {
         c = ir2_get_code(&ctx->gb);
-        if(c >= 0x80) { /* we have a run */
+        if (c >= 0x80) { /* we have a run */
             c -= 0x7F;
-            if(out + c*2 > width)
-                return -1;
+            if (out + c*2 > width)
+                return AVERROR_INVALIDDATA;
             for (i = 0; i < c * 2; i++)
                 dst[out++] = 0x80;
         } else { /* copy two values from table */
@@ -75,25 +75,25 @@
     }
     dst += stride;
 
-    for (j = 1; j < height; j++){
+    for (j = 1; j < height; j++) {
         out = 0;
-        while (out < width){
+        while (out < width) {
             c = ir2_get_code(&ctx->gb);
-            if(c >= 0x80) { /* we have a skip */
+            if (c >= 0x80) { /* we have a skip */
                 c -= 0x7F;
-                if(out + c*2 > width)
-                    return -1;
+                if (out + c*2 > width)
+                    return AVERROR_INVALIDDATA;
                 for (i = 0; i < c * 2; i++) {
                     dst[out] = dst[out - stride];
                     out++;
                 }
             } else { /* add two deltas from table */
-                t = dst[out - stride] + (table[c * 2] - 128);
-                t= av_clip_uint8(t);
+                t        = dst[out - stride] + (table[c * 2] - 128);
+                t        = av_clip_uint8(t);
                 dst[out] = t;
                 out++;
-                t = dst[out - stride] + (table[(c * 2) + 1] - 128);
-                t= av_clip_uint8(t);
+                t        = dst[out - stride] + (table[(c * 2) + 1] - 128);
+                t        = av_clip_uint8(t);
                 dst[out] = t;
                 out++;
             }
@@ -103,31 +103,31 @@
     return 0;
 }
 
-static int ir2_decode_plane_inter(Ir2Context *ctx, int width, int height, uint8_t *dst, int stride,
-                             const uint8_t *table)
+static int ir2_decode_plane_inter(Ir2Context *ctx, int width, int height, uint8_t *dst,
+                                  int stride, const uint8_t *table)
 {
     int j;
     int out = 0;
     int c;
     int t;
 
-    if(width&1)
-        return -1;
+    if (width & 1)
+        return AVERROR_INVALIDDATA;
 
-    for (j = 0; j < height; j++){
+    for (j = 0; j < height; j++) {
         out = 0;
-        while (out < width){
+        while (out < width) {
             c = ir2_get_code(&ctx->gb);
-            if(c >= 0x80) { /* we have a skip */
-                c -= 0x7F;
+            if (c >= 0x80) { /* we have a skip */
+                c   -= 0x7F;
                 out += c * 2;
             } else { /* add two deltas from table */
-                t = dst[out] + (((table[c * 2] - 128)*3) >> 2);
-                t= av_clip_uint8(t);
+                t        = dst[out] + (((table[c * 2] - 128)*3) >> 2);
+                t        = av_clip_uint8(t);
                 dst[out] = t;
                 out++;
-                t = dst[out] + (((table[(c * 2) + 1] - 128)*3) >> 2);
-                t= av_clip_uint8(t);
+                t        = dst[out] + (((table[(c * 2) + 1] - 128)*3) >> 2);
+                t        = av_clip_uint8(t);
                 dst[out] = t;
                 out++;
             }
@@ -138,21 +138,21 @@
 }
 
 static int ir2_decode_frame(AVCodecContext *avctx,
-                        void *data, int *data_size,
+                        void *data, int *got_frame,
                         AVPacket *avpkt)
 {
-    const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
     Ir2Context * const s = avctx->priv_data;
-    AVFrame *picture = data;
-    AVFrame * const p = &s->picture;
-    int start;
+    const uint8_t *buf   = avpkt->data;
+    int buf_size         = avpkt->size;
+    AVFrame *picture     = data;
+    AVFrame * const p    = &s->picture;
+    int start, ret;
 
     p->reference = 3;
     p->buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if (avctx->reget_buffer(avctx, p)) {
+    if ((ret = avctx->reget_buffer(avctx, p)) < 0) {
         av_log(s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     start = 48; /* hardcoded for now */
@@ -173,30 +173,44 @@
     init_get_bits(&s->gb, buf + start, (buf_size - start) * 8);
 
     if (s->decode_delta) { /* intraframe */
-        ir2_decode_plane(s, avctx->width, avctx->height,
-                         s->picture.data[0], s->picture.linesize[0], ir2_luma_table);
+        if ((ret = ir2_decode_plane(s, avctx->width, avctx->height,
+                                    s->picture.data[0], s->picture.linesize[0],
+                                    ir2_luma_table)) < 0)
+            return ret;
+
         /* swapped U and V */
-        ir2_decode_plane(s, avctx->width >> 2, avctx->height >> 2,
-                         s->picture.data[2], s->picture.linesize[2], ir2_luma_table);
-        ir2_decode_plane(s, avctx->width >> 2, avctx->height >> 2,
-                         s->picture.data[1], s->picture.linesize[1], ir2_luma_table);
+        if ((ret = ir2_decode_plane(s, avctx->width >> 2, avctx->height >> 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],
+                                    ir2_luma_table)) < 0)
+            return ret;
     } else { /* interframe */
-        ir2_decode_plane_inter(s, avctx->width, avctx->height,
-                         s->picture.data[0], s->picture.linesize[0], ir2_luma_table);
+        if ((ret = ir2_decode_plane_inter(s, avctx->width, avctx->height,
+                                          s->picture.data[0], s->picture.linesize[0],
+                                          ir2_luma_table)) < 0)
+            return ret;
         /* swapped U and V */
-        ir2_decode_plane_inter(s, avctx->width >> 2, avctx->height >> 2,
-                         s->picture.data[2], s->picture.linesize[2], ir2_luma_table);
-        ir2_decode_plane_inter(s, avctx->width >> 2, avctx->height >> 2,
-                         s->picture.data[1], s->picture.linesize[1], ir2_luma_table);
+        if ((ret = ir2_decode_plane_inter(s, avctx->width >> 2, avctx->height >> 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],
+                                          ir2_luma_table)) < 0)
+            return ret;
     }
 
     *picture   = s->picture;
-    *data_size = sizeof(AVPicture);
+    *got_frame = 1;
 
     return buf_size;
 }
 
-static av_cold int ir2_decode_init(AVCodecContext *avctx){
+static av_cold int ir2_decode_init(AVCodecContext *avctx)
+{
     Ir2Context * const ic = avctx->priv_data;
     static VLC_TYPE vlc_tables[1 << CODE_VLC_BITS][2];
 
@@ -220,7 +234,8 @@
     return 0;
 }
 
-static av_cold int ir2_decode_end(AVCodecContext *avctx){
+static av_cold int ir2_decode_end(AVCodecContext *avctx)
+{
     Ir2Context * const ic = avctx->priv_data;
     AVFrame *pic = &ic->picture;
 
diff --git a/libavcodec/indeo3.c b/libavcodec/indeo3.c
index 013d610..a94b087 100644
--- a/libavcodec/indeo3.c
+++ b/libavcodec/indeo3.c
@@ -32,9 +32,11 @@
 #include "libavutil/imgutils.h"
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
+#include "copy_block.h"
 #include "dsputil.h"
 #include "bytestream.h"
 #include "get_bits.h"
+#include "internal.h"
 
 #include "indeo3data.h"
 
@@ -409,7 +411,8 @@
     }
 
 
-static int decode_cell_data(Cell *cell, uint8_t *block, uint8_t *ref_block,
+static int decode_cell_data(Indeo3DecodeContext *ctx, Cell *cell,
+                            uint8_t *block, uint8_t *ref_block,
                             int pitch, int h_zoom, int v_zoom, int mode,
                             const vqEntry *delta[2], int swap_quads[2],
                             const uint8_t **data_ptr, const uint8_t *last_ptr)
@@ -655,14 +658,16 @@
         }
 
         zoom_fac = mode >= 3;
-        error = decode_cell_data(cell, block, ref_block, plane->pitch, 0, zoom_fac,
-                                 mode, delta, swap_quads, &data_ptr, last_ptr);
+        error = decode_cell_data(ctx, cell, block, ref_block, plane->pitch,
+                                 0, zoom_fac, mode, delta, swap_quads,
+                                 &data_ptr, last_ptr);
         break;
     case 10: /*-------------------- MODE 10 (8x8 block processing) ---------------------*/
     case 11: /*----------------- MODE 11 (4x8 INTER block processing) ------------------*/
         if (mode == 10 && !cell->mv_ptr) { /* MODE 10 INTRA processing */
-            error = decode_cell_data(cell, block, ref_block, plane->pitch, 1, 1,
-                                     mode, delta, swap_quads, &data_ptr, last_ptr);
+            error = decode_cell_data(ctx, cell, block, ref_block, plane->pitch,
+                                     1, 1, mode, delta, swap_quads,
+                                     &data_ptr, last_ptr);
         } else { /* mode 10 and 11 INTER processing */
             if (mode == 11 && !cell->mv_ptr) {
                av_log(avctx, AV_LOG_ERROR, "Attempt to use Mode 11 for an INTRA cell!\n");
@@ -670,7 +675,7 @@
             }
 
             zoom_fac = mode == 10;
-            error = decode_cell_data(cell, block, ref_block, plane->pitch,
+            error = decode_cell_data(ctx, cell, block, ref_block, plane->pitch,
                                      zoom_fac, 1, mode, delta, swap_quads,
                                      &data_ptr, last_ptr);
         }
@@ -1053,7 +1058,7 @@
 }
 
 
-static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         AVPacket *avpkt)
 {
     Indeo3DecodeContext *ctx = avctx->priv_data;
@@ -1068,7 +1073,7 @@
     /* skip sync(null) frames */
     if (res) {
         // we have processed 16 bytes but no data was decoded
-        *data_size = 0;
+        *got_frame = 0;
         return buf_size;
     }
 
@@ -1088,7 +1093,7 @@
         avctx->release_buffer(avctx, &ctx->frame);
 
     ctx->frame.reference = 0;
-    if ((res = avctx->get_buffer(avctx, &ctx->frame)) < 0) {
+    if ((res = ff_get_buffer(avctx, &ctx->frame)) < 0) {
         av_log(ctx->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return res;
     }
@@ -1114,7 +1119,7 @@
                  ctx->frame.data[2], ctx->frame.linesize[2],
                  (avctx->height + 3) >> 2);
 
-    *data_size      = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*)data = ctx->frame;
 
     return buf_size;
diff --git a/libavcodec/indeo3data.h b/libavcodec/indeo3data.h
index 0b5648e..e7e28a3 100644
--- a/libavcodec/indeo3data.h
+++ b/libavcodec/indeo3data.h
@@ -235,7 +235,7 @@
 
 /**
  * Pack two delta values (a,b) into one 16bit word
- * according with endianess of the host machine.
+ * according with endianness of the host machine.
  */
 #if HAVE_BIGENDIAN
 #define PD(a,b) (((a) << 8) + (b))
@@ -282,7 +282,7 @@
 
 /**
  * Pack four delta values (a,a,b,b) into one 32bit word
- * according with endianess of the host machine.
+ * according with endianness of the host machine.
  */
 #if HAVE_BIGENDIAN
 #define PD(a,b) (((a) << 24) + ((a) << 16) + ((b) << 8) + (b))
diff --git a/libavcodec/indeo4.c b/libavcodec/indeo4.c
index 0766ed4..e810003 100644
--- a/libavcodec/indeo4.c
+++ b/libavcodec/indeo4.c
@@ -30,7 +30,6 @@
 #define BITSTREAM_READER_LE
 #include "avcodec.h"
 #include "get_bits.h"
-#include "dsputil.h"
 #include "ivi_dsp.h"
 #include "ivi_common.h"
 #include "indeo4data.h"
@@ -387,6 +386,10 @@
             av_log(avctx, AV_LOG_ERROR, "mismatching scan table!\n");
             return AVERROR_INVALIDDATA;
         }
+        if (band->transform_size == 8 && band->blk_size < 8) {
+            av_log(avctx, AV_LOG_ERROR, "mismatching transform_size!\n");
+            return AVERROR_INVALIDDATA;
+        }
 
         /* decode block huffman codebook */
         if (ff_ivi_dec_huff_desc(&ctx->gb, get_bits1(&ctx->gb), IVI_BLK_HUFF,
diff --git a/libavcodec/internal.h b/libavcodec/internal.h
index 17ca8bb..3402cc2 100644
--- a/libavcodec/internal.h
+++ b/libavcodec/internal.h
@@ -39,9 +39,6 @@
     int width;
     int height;
     enum AVPixelFormat pix_fmt;
-    uint8_t **extended_data;
-    int audio_data_size;
-    int nb_channels;
 } InternalBuffer;
 
 typedef struct AVCodecInternal {
@@ -80,6 +77,12 @@
     int last_audio_frame;
 
     /**
+     * The data for the last allocated audio frame.
+     * Stored here so we can free it.
+     */
+    uint8_t *audio_data;
+
+    /**
      * temporary buffer used for encoders to store their bitstream
      */
     uint8_t *byte_buffer;
@@ -121,11 +124,18 @@
  */
 void ff_init_buffer_info(AVCodecContext *s, AVFrame *frame);
 
+
+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);
+
 int avpriv_lock_avformat(void);
 int avpriv_unlock_avformat(void);
 
@@ -169,12 +179,23 @@
                         avctx->time_base);
 }
 
+/**
+ * Get a buffer for a frame. This is a wrapper around
+ * AVCodecContext.get_buffer() and should be used instead calling get_buffer()
+ * directly.
+ */
+int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame);
+
 int ff_thread_can_start_frame(AVCodecContext *avctx);
 
 int ff_get_logical_cpus(AVCodecContext *avctx);
 
 int avpriv_h264_has_num_reorder_frames(AVCodecContext *avctx);
 
+void ff_print_debug_info2(AVCodecContext *avctx, AVFrame *pict, uint8_t *mbskip_table,
+                         uint8_t *visualization_buffer[3], int *low_delay,
+                         int mb_width, int mb_height, int mb_stride, int quarter_sample);
+
 /**
  * Call avcodec_open2 recursively by decrementing counter, unlocking mutex,
  * calling the function and then restoring again. Assumes the mutex is
@@ -187,4 +208,9 @@
  */
 int ff_codec_close_recursive(AVCodecContext *avctx);
 
+/**
+ * Finalize buf into extradata and set its size appropriately.
+ */
+int avpriv_bprint_to_extradata(AVCodecContext *avctx, struct AVBPrint *buf);
+
 #endif /* AVCODEC_INTERNAL_H */
diff --git a/libavcodec/interplayvideo.c b/libavcodec/interplayvideo.c
index 6892936..e0550a7 100644
--- a/libavcodec/interplayvideo.c
+++ b/libavcodec/interplayvideo.c
@@ -43,6 +43,7 @@
 #include "dsputil.h"
 #define BITSTREAM_READER_LE
 #include "get_bits.h"
+#include "internal.h"
 
 #define PALETTE_COUNT 256
 
@@ -73,11 +74,11 @@
                        + delta_x * (1 + s->is_16bpp);
     if (motion_offset < 0) {
         av_log(s->avctx, AV_LOG_ERROR, "motion offset < 0 (%d)\n", motion_offset);
-        return -1;
+        return AVERROR_INVALIDDATA;
     } else if (motion_offset > s->upper_motion_limit_offset) {
         av_log(s->avctx, AV_LOG_ERROR, "motion offset above limit (%d >= %d)\n",
             motion_offset, s->upper_motion_limit_offset);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     if (src->data[0] == NULL) {
         av_log(s->avctx, AV_LOG_ERROR, "Invalid decode type, corrupted header?\n");
@@ -881,12 +882,8 @@
     int x, y;
     unsigned char opcode;
     int ret;
-    static int frame = 0;
     GetBitContext gb;
 
-    av_dlog(s->avctx, "frame %d\n", frame);
-    frame++;
-
     bytestream2_skip(&s->stream_ptr, 14); /* data starts 14 bytes in */
     if (!s->is_16bpp) {
         /* this is PAL8, so make the palette available */
@@ -922,7 +919,7 @@
             }
             if (ret != 0) {
                 av_log(s->avctx, AV_LOG_ERROR, "decode problem on frame %d, @ block (%d, %d)\n",
-                       frame, x, y);
+                       s->avctx->frame_number, x, y);
                 return;
             }
         }
@@ -956,12 +953,13 @@
 }
 
 static int ipvideo_decode_frame(AVCodecContext *avctx,
-                                void *data, int *data_size,
+                                void *data, int *got_frame,
                                 AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     IpvideoContext *s = avctx->priv_data;
+    int ret;
 
     /* decoding map contains 4 bits of information per 8x8 block */
     s->decoding_map_size = avctx->width * avctx->height / (8 * 8 * 2);
@@ -971,14 +969,21 @@
     if (buf_size < s->decoding_map_size)
         return buf_size;
 
+    if (s->last_frame.data[0] && av_packet_get_side_data(avpkt, AV_PKT_DATA_PARAM_CHANGE, NULL)) {
+        if (s->last_frame.data[0])
+            avctx->release_buffer(avctx, &s->last_frame);
+        if (s->second_last_frame.data[0])
+            avctx->release_buffer(avctx, &s->second_last_frame);
+    }
+
     s->decoding_map = buf;
     bytestream2_init(&s->stream_ptr, buf + s->decoding_map_size,
                      buf_size - s->decoding_map_size);
 
     s->current_frame.reference = 3;
-    if (avctx->get_buffer(avctx, &s->current_frame)) {
+    if ((ret = ff_get_buffer(avctx, &s->current_frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     if (!s->is_16bpp) {
@@ -991,7 +996,7 @@
 
     ipvideo_decode_opcodes(s);
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*)data = s->current_frame;
 
     /* shuffle frames */
diff --git a/libavcodec/intrax8.c b/libavcodec/intrax8.c
index fe1e770..5b76942 100644
--- a/libavcodec/intrax8.c
+++ b/libavcodec/intrax8.c
@@ -776,12 +776,12 @@
             s->dest[0]+= 8;
         }
         if(s->mb_y&1){
-            ff_draw_horiz_band(s, (s->mb_y-1)*8, 16);
+            ff_mpeg_draw_horiz_band(s, (s->mb_y-1)*8, 16);
         }
     }
 
 error:
-    ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y,
+    ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y,
                         (s->mb_x>>1)-1, (s->mb_y>>1)-1,
                         ER_MB_END );
     return 0;
diff --git a/libavcodec/intrax8dsp.c b/libavcodec/intrax8dsp.c
index 447ad21..1b34f89 100644
--- a/libavcodec/intrax8dsp.c
+++ b/libavcodec/intrax8dsp.c
@@ -21,7 +21,6 @@
  *@brief IntraX8 frame subdecoder image manipulation routines
  */
 
-#include "dsputil.h"
 #include "intrax8dsp.h"
 #include "libavutil/common.h"
 
diff --git a/libavcodec/ituh263dec.c b/libavcodec/ituh263dec.c
index 461af3a..f8623d9 100644
--- a/libavcodec/ituh263dec.c
+++ b/libavcodec/ituh263dec.c
@@ -30,8 +30,8 @@
 //#define DEBUG
 #include <limits.h>
 
+#include "libavutil/internal.h"
 #include "libavutil/mathematics.h"
-#include "dsputil.h"
 #include "avcodec.h"
 #include "mpegvideo.h"
 #include "h263.h"
@@ -98,7 +98,7 @@
 /* init vlcs */
 
 /* XXX: find a better solution to handle static init */
-void ff_h263_decode_init_vlc(MpegEncContext *s)
+void ff_h263_decode_init_vlc(void)
 {
     static volatile int done = 0;
 
@@ -437,7 +437,7 @@
     ff_set_qscale(s, s->qscale);
 }
 
-static int h263_decode_block(MpegEncContext * s, DCTELEM * block,
+static int h263_decode_block(MpegEncContext * s, int16_t * block,
                              int n, int coded)
 {
     int code, level, i, j, last, run;
@@ -562,13 +562,15 @@
 
 static int h263_skip_b_part(MpegEncContext *s, int cbp)
 {
-    LOCAL_ALIGNED_16(DCTELEM, dblock, [64]);
+    LOCAL_ALIGNED_16(int16_t, dblock, [64]);
     int i, mbi;
+    int bli[6];
 
     /* we have to set s->mb_intra to zero to decode B-part of PB-frame correctly
      * but real value should be restored in order to be used later (in OBMC condition)
      */
     mbi = s->mb_intra;
+    memcpy(bli, s->block_last_index, sizeof(bli));
     s->mb_intra = 0;
     for (i = 0; i < 6; i++) {
         if (h263_decode_block(s, dblock, i, cbp&32) < 0)
@@ -576,6 +578,7 @@
         cbp+=cbp;
     }
     s->mb_intra = mbi;
+    memcpy(s->block_last_index, bli, sizeof(bli));
     return 0;
 }
 
@@ -598,7 +601,7 @@
 }
 
 int ff_h263_decode_mb(MpegEncContext *s,
-                      DCTELEM block[6][64])
+                      int16_t block[6][64])
 {
     int cbpc, cbpy, i, cbp, pred_x, pred_y, mx, my, dquant;
     int16_t *mot_val;
diff --git a/libavcodec/ituh263enc.c b/libavcodec/ituh263enc.c
index 3eb198f..bdcc415 100644
--- a/libavcodec/ituh263enc.c
+++ b/libavcodec/ituh263enc.c
@@ -30,7 +30,6 @@
 //#define DEBUG
 #include <limits.h>
 
-#include "dsputil.h"
 #include "avcodec.h"
 #include "mpegvideo.h"
 #include "h263.h"
@@ -303,7 +302,7 @@
  * @param block the 8x8 block
  * @param n block index (0-3 are luma, 4-5 are chroma)
  */
-static void h263_encode_block(MpegEncContext * s, DCTELEM * block, int n)
+static void h263_encode_block(MpegEncContext * s, int16_t * block, int n)
 {
     int level, run, last, i, j, last_index, last_non_zero, sign, slevel, code;
     RLTable *rl;
@@ -452,7 +451,7 @@
 }
 
 void ff_h263_encode_mb(MpegEncContext * s,
-                       DCTELEM block[6][64],
+                       int16_t block[6][64],
                        int motion_x, int motion_y)
 {
     int cbpc, cbpy, i, cbp, pred_x, pred_y;
diff --git a/libavcodec/ivi_common.c b/libavcodec/ivi_common.c
index c20ce77..21954ec 100644
--- a/libavcodec/ivi_common.c
+++ b/libavcodec/ivi_common.c
@@ -30,6 +30,7 @@
 #include "libavutil/attributes.h"
 #include "avcodec.h"
 #include "get_bits.h"
+#include "internal.h"
 #include "mathops.h"
 #include "ivi_common.h"
 #include "ivi_dsp.h"
@@ -37,8 +38,8 @@
 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
 
-VLC ff_ivi_mb_vlc_tabs [8];
-VLC ff_ivi_blk_vlc_tabs[8];
+static VLC ivi_mb_vlc_tabs [8]; ///< static macroblock Huffman tables
+static VLC ivi_blk_vlc_tabs[8]; ///< static block Huffman tables
 
 /**
  *  Reverse "nbits" bits of the value "val" and return the result
@@ -56,7 +57,16 @@
     return res;
 }
 
-int ff_ivi_create_huff_from_desc(const IVIHuffDesc *cb, VLC *vlc, int flag)
+/*
+ *  Generate a huffman codebook from the given descriptor
+ *  and convert it into the FFmpeg VLC table.
+ *
+ *  @param[in]   cb    pointer to codebook descriptor
+ *  @param[out]  vlc   where to place the generated VLC table
+ *  @param[in]   flag  flag: 1 - for static or 0 for dynamic tables
+ *  @return     result code: 0 - OK, -1 = error (invalid codebook descriptor)
+ */
+static int ivi_create_huff_from_desc(const IVIHuffDesc *cb, VLC *vlc, int flag)
 {
     int         pos, i, j, codes_per_row, prefix, not_last_row;
     uint16_t    codewords[256]; /* FIXME: move this temporal storage out? */
@@ -99,16 +109,41 @@
     if (initialized_vlcs)
         return;
     for (i = 0; i < 8; i++) {
-        ff_ivi_mb_vlc_tabs[i].table = table_data + i * 2 * 8192;
-        ff_ivi_mb_vlc_tabs[i].table_allocated = 8192;
-        ff_ivi_create_huff_from_desc(&ff_ivi_mb_huff_desc[i],  &ff_ivi_mb_vlc_tabs[i],  1);
-        ff_ivi_blk_vlc_tabs[i].table = table_data + (i * 2 + 1) * 8192;
-        ff_ivi_blk_vlc_tabs[i].table_allocated = 8192;
-        ff_ivi_create_huff_from_desc(&ff_ivi_blk_huff_desc[i], &ff_ivi_blk_vlc_tabs[i], 1);
+        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_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);
     }
     initialized_vlcs = 1;
 }
 
+/*
+ *  Copy huffman codebook descriptors.
+ *
+ *  @param[out]  dst  ptr to the destination descriptor
+ *  @param[in]   src  ptr to the source descriptor
+ */
+static void ivi_huff_desc_copy(IVIHuffDesc *dst, const IVIHuffDesc *src)
+{
+    dst->num_rows = src->num_rows;
+    memcpy(dst->xbits, src->xbits, src->num_rows);
+}
+
+/*
+ *  Compare two huffman codebook descriptors.
+ *
+ *  @param[in]  desc1  ptr to the 1st descriptor to compare
+ *  @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)
+{
+    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)
 {
@@ -117,8 +152,8 @@
 
     if (!desc_coded) {
         /* select default table */
-        huff_tab->tab = (which_tab) ? &ff_ivi_blk_vlc_tabs[7]
-            : &ff_ivi_mb_vlc_tabs [7];
+        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) {
@@ -133,12 +168,12 @@
                 new_huff.xbits[i] = get_bits(gb, 4);
 
             /* Have we got the same custom table? Rebuild if not. */
-            if (ff_ivi_huff_desc_cmp(&new_huff, &huff_tab->cust_desc) || !huff_tab->cust_tab.table) {
-                ff_ivi_huff_desc_copy(&huff_tab->cust_desc, &new_huff);
+            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 = ff_ivi_create_huff_from_desc(&huff_tab->cust_desc,
+                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
@@ -150,24 +185,38 @@
             huff_tab->tab = &huff_tab->cust_tab;
         } else {
             /* select one of predefined tables */
-            huff_tab->tab = (which_tab) ? &ff_ivi_blk_vlc_tabs[huff_tab->tab_sel]
-                : &ff_ivi_mb_vlc_tabs [huff_tab->tab_sel];
+            huff_tab->tab = (which_tab) ? &ivi_blk_vlc_tabs[huff_tab->tab_sel]
+                : &ivi_mb_vlc_tabs [huff_tab->tab_sel];
         }
     }
 
     return 0;
 }
 
-int ff_ivi_huff_desc_cmp(const IVIHuffDesc *desc1, const IVIHuffDesc *desc2)
+/*
+ *  Free planes, bands and macroblocks buffers.
+ *
+ *  @param[in]  planes  pointer to the array of the plane descriptors
+ */
+static av_cold void ivi_free_buffers(IVIPlaneDesc *planes)
 {
-    return    desc1->num_rows != desc2->num_rows
-           || memcmp(desc1->xbits, desc2->xbits, desc1->num_rows);
-}
+    int p, b, t;
 
-void ff_ivi_huff_desc_copy(IVIHuffDesc *dst, const IVIHuffDesc *src)
-{
-    dst->num_rows = src->num_rows;
-    memcpy(dst->xbits, src->xbits, src->num_rows);
+    for (p = 0; p < 3; p++) {
+        if (planes[p].bands)
+        for (b = 0; b < planes[p].num_bands; b++) {
+            av_freep(&planes[p].bands[b].bufs[0]);
+            av_freep(&planes[p].bands[b].bufs[1]);
+            av_freep(&planes[p].bands[b].bufs[2]);
+
+            if (planes[p].bands[b].blk_vlc.cust_tab.table)
+                ff_free_vlc(&planes[p].bands[b].blk_vlc.cust_tab);
+            for (t = 0; t < planes[p].bands[b].num_tiles; t++)
+                av_freep(&planes[p].bands[b].tiles[t].mbs);
+            av_freep(&planes[p].bands[b].tiles);
+        }
+        av_freep(&planes[p].bands);
+    }
 }
 
 av_cold int ff_ivi_init_planes(IVIPlaneDesc *planes, const IVIPicConfig *cfg)
@@ -176,7 +225,7 @@
     uint32_t    b_width, b_height, align_fac, width_aligned, height_aligned, buf_size;
     IVIBandDesc *band;
 
-    ff_ivi_free_buffers(planes);
+    ivi_free_buffers(planes);
 
     /* fill in the descriptor of the luminance plane */
     planes[0].width     = cfg->pic_width;
@@ -234,27 +283,6 @@
     return 0;
 }
 
-av_cold void ff_ivi_free_buffers(IVIPlaneDesc *planes)
-{
-    int p, b, t;
-
-    for (p = 0; p < 3; p++) {
-        if (planes[p].bands)
-        for (b = 0; b < planes[p].num_bands; b++) {
-            av_freep(&planes[p].bands[b].bufs[0]);
-            av_freep(&planes[p].bands[b].bufs[1]);
-            av_freep(&planes[p].bands[b].bufs[2]);
-
-            if (planes[p].bands[b].blk_vlc.cust_tab.table)
-                ff_free_vlc(&planes[p].bands[b].blk_vlc.cust_tab);
-            for (t = 0; t < planes[p].bands[b].num_tiles; t++)
-                av_freep(&planes[p].bands[b].tiles[t].mbs);
-            av_freep(&planes[p].bands[b].tiles);
-        }
-        av_freep(&planes[p].bands);
-    }
-}
-
 av_cold int ff_ivi_init_tiles(IVIPlaneDesc *planes, int tile_width, int tile_height)
 {
     int         p, b, x, y, x_tiles, y_tiles, t_width, t_height;
@@ -325,7 +353,17 @@
     return 0;
 }
 
-int ff_ivi_dec_tile_data_size(GetBitContext *gb)
+/*
+ *  Decode size of the tile data.
+ *  The size is stored as a variable-length field having the following format:
+ *  if (tile_data_size < 255) than this field is only one byte long
+ *  if (tile_data_size >= 255) than this field four is byte long: 0xFF X1 X2 X3
+ *  where X1-X3 is size of the tile data
+ *
+ *  @param[in,out]  gb  the GetBit context
+ *  @return     size of the tile data in bytes
+ */
+static int ivi_dec_tile_data_size(GetBitContext *gb)
 {
     int    len;
 
@@ -342,13 +380,25 @@
     return len;
 }
 
-int ff_ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile)
+/*
+ *  Decode block data:
+ *  extract huffman-coded transform coefficients from the bitstream,
+ *  dequantize them, apply inverse transform and motion compensation
+ *  in order to reconstruct the picture.
+ *
+ *  @param[in,out]  gb    the GetBit context
+ *  @param[in]      band  pointer to the band descriptor
+ *  @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)
 {
     int         mbn, blk, num_blocks, num_coeffs, blk_size, scan_pos, run, val,
-                pos, is_intra, mc_type = 0, mv_x, mv_y, col_mask;
+                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, sym, lo, hi, quant, buf_offs, q;
+    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);
@@ -417,6 +467,11 @@
             }
 
             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 */
@@ -433,7 +488,7 @@
                         val = IVI_TOSIGNED((hi << 6) | lo); /* merge them and convert into signed val */
                     } else {
                         if (sym >= 256U) {
-                            av_log(NULL, AV_LOG_ERROR, "Invalid sym encountered: %d.\n", sym);
+                            av_log(avctx, AV_LOG_ERROR, "Invalid sym encountered: %d.\n", sym);
                             return -1;
                         }
                         run = rvmap->runtab[sym];
@@ -447,7 +502,7 @@
                     pos = band->scan[scan_pos];
 
                     if (!val)
-                        av_dlog(NULL, "Val = 0 encountered!\n");
+                        av_dlog(avctx, "Val = 0 encountered!\n");
 
                     q = (base_tab[pos] * quant) >> 9;
                     if (q > 1)
@@ -645,7 +700,16 @@
 }
 #endif
 
-void ff_ivi_output_plane(IVIPlaneDesc *plane, uint8_t *dst, int dst_pitch)
+/*
+ *  Convert and output the current plane.
+ *  This conversion is done by adding back the bias value of 128
+ *  (subtracted in the encoder) and clipping the result.
+ *
+ *  @param[in]   plane      pointer to the descriptor of the plane being processed
+ *  @param[out]  dst        pointer to the buffer receiving converted pixels
+ *  @param[in]   dst_pitch  pitch for moving to the next y line
+ */
+static void ivi_output_plane(IVIPlaneDesc *plane, uint8_t *dst, int dst_pitch)
 {
     int             x, y;
     const int16_t   *src  = plane->bands[0].buf;
@@ -728,7 +792,7 @@
                 break;
             av_dlog(avctx, "Empty tile encountered!\n");
         } else {
-            tile->data_size = ff_ivi_dec_tile_data_size(&ctx->gb);
+            tile->data_size = ivi_dec_tile_data_size(&ctx->gb);
             if (!tile->data_size) {
                 av_log(avctx, AV_LOG_ERROR, "Tile data size is zero!\n");
                 result = AVERROR_INVALIDDATA;
@@ -739,7 +803,7 @@
             if (result < 0)
                 break;
 
-            result = ff_ivi_decode_blocks(&ctx->gb, band, tile);
+            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");
                 break;
@@ -777,7 +841,7 @@
     return result;
 }
 
-int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         AVPacket *avpkt)
 {
     IVI45DecContext *ctx = avctx->priv_data;
@@ -844,7 +908,7 @@
 
     ctx->frame.reference = 0;
     avcodec_set_dimensions(avctx, ctx->planes[0].width, ctx->planes[0].height);
-    if ((result = avctx->get_buffer(avctx, &ctx->frame)) < 0) {
+    if ((result = ff_get_buffer(avctx, &ctx->frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return result;
     }
@@ -855,13 +919,13 @@
         else
             ff_ivi_recompose53   (&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0]);
     } else {
-        ff_ivi_output_plane(&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0]);
+        ivi_output_plane(&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0]);
     }
 
-    ff_ivi_output_plane(&ctx->planes[2], ctx->frame.data[1], ctx->frame.linesize[1]);
-    ff_ivi_output_plane(&ctx->planes[1], ctx->frame.data[2], ctx->frame.linesize[2]);
+    ivi_output_plane(&ctx->planes[2], ctx->frame.data[1], ctx->frame.linesize[1]);
+    ivi_output_plane(&ctx->planes[1], ctx->frame.data[2], ctx->frame.linesize[2]);
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*)data = ctx->frame;
 
     return buf_size;
@@ -874,7 +938,7 @@
 {
     IVI45DecContext *ctx = avctx->priv_data;
 
-    ff_ivi_free_buffers(&ctx->planes[0]);
+    ivi_free_buffers(&ctx->planes[0]);
 
     if (ctx->mb_vlc.cust_tab.table)
         ff_free_vlc(&ctx->mb_vlc.cust_tab);
diff --git a/libavcodec/ivi_common.h b/libavcodec/ivi_common.h
index e3afe43..86acbe6 100644
--- a/libavcodec/ivi_common.h
+++ b/libavcodec/ivi_common.h
@@ -63,9 +63,6 @@
     IVI_BLK_HUFF  = 1       /// Huffman table is used for coding blocks
 };
 
-extern VLC ff_ivi_mb_vlc_tabs [8]; ///< static macroblock Huffman tables
-extern VLC ff_ivi_blk_vlc_tabs[8]; ///< static block Huffman tables
-
 
 /**
  *  Common scan patterns (defined in ivi_common.c)
@@ -281,17 +278,6 @@
 }
 
 /**
- *  Generate a huffman codebook from the given descriptor
- *  and convert it into the FFmpeg VLC table.
- *
- *  @param[in]   cb    pointer to codebook descriptor
- *  @param[out]  vlc   where to place the generated VLC table
- *  @param[in]   flag  flag: 1 - for static or 0 for dynamic tables
- *  @return     result code: 0 - OK, -1 = error (invalid codebook descriptor)
- */
-int  ff_ivi_create_huff_from_desc(const IVIHuffDesc *cb, VLC *vlc, int flag);
-
-/**
  * Initialize static codes used for macroblock and block decoding.
  */
 void ff_ivi_init_static_vlc(void);
@@ -311,23 +297,6 @@
                           IVIHuffTab *huff_tab, AVCodecContext *avctx);
 
 /**
- *  Compare two huffman codebook descriptors.
- *
- *  @param[in]  desc1  ptr to the 1st descriptor to compare
- *  @param[in]  desc2  ptr to the 2nd descriptor to compare
- *  @return         comparison result: 0 - equal, 1 - not equal
- */
-int  ff_ivi_huff_desc_cmp(const IVIHuffDesc *desc1, const IVIHuffDesc *desc2);
-
-/**
- *  Copy huffman codebook descriptors.
- *
- *  @param[out]  dst  ptr to the destination descriptor
- *  @param[in]   src  ptr to the source descriptor
- */
-void ff_ivi_huff_desc_copy(IVIHuffDesc *dst, const IVIHuffDesc *src);
-
-/**
  *  Initialize planes (prepares descriptors, allocates buffers etc).
  *
  *  @param[in,out]  planes  pointer to the array of the plane descriptors
@@ -337,13 +306,6 @@
 int  ff_ivi_init_planes(IVIPlaneDesc *planes, const IVIPicConfig *cfg);
 
 /**
- *  Free planes, bands and macroblocks buffers.
- *
- *  @param[in]  planes  pointer to the array of the plane descriptors
- */
-void ff_ivi_free_buffers(IVIPlaneDesc *planes);
-
-/**
  *  Initialize tile and macroblock descriptors.
  *
  *  @param[in,out]  planes       pointer to the array of the plane descriptors
@@ -353,44 +315,8 @@
  */
 int  ff_ivi_init_tiles(IVIPlaneDesc *planes, int tile_width, int tile_height);
 
-/**
- *  Decode size of the tile data.
- *  The size is stored as a variable-length field having the following format:
- *  if (tile_data_size < 255) than this field is only one byte long
- *  if (tile_data_size >= 255) than this field four is byte long: 0xFF X1 X2 X3
- *  where X1-X3 is size of the tile data
- *
- *  @param[in,out]  gb  the GetBit context
- *  @return     size of the tile data in bytes
- */
-int  ff_ivi_dec_tile_data_size(GetBitContext *gb);
-
-/**
- *  Decode block data:
- *  extract huffman-coded transform coefficients from the bitstream,
- *  dequantize them, apply inverse transform and motion compensation
- *  in order to reconstruct the picture.
- *
- *  @param[in,out]  gb    the GetBit context
- *  @param[in]      band  pointer to the band descriptor
- *  @param[in]      tile  pointer to the tile descriptor
- *  @return     result code: 0 - OK, -1 = error (corrupted blocks data)
- */
-int  ff_ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile);
-
-/**
- *  Convert and output the current plane.
- *  This conversion is done by adding back the bias value of 128
- *  (subtracted in the encoder) and clipping the result.
- *
- *  @param[in]   plane      pointer to the descriptor of the plane being processed
- *  @param[out]  dst        pointer to the buffer receiving converted pixels
- *  @param[in]   dst_pitch  pitch for moving to the next y line
- */
-void ff_ivi_output_plane(IVIPlaneDesc *plane, uint8_t *dst, int dst_pitch);
-
-int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         AVPacket *avpkt);
-av_cold int ff_ivi_decode_close(AVCodecContext *avctx);
+int ff_ivi_decode_close(AVCodecContext *avctx);
 
 #endif /* AVCODEC_IVI_COMMON_H */
diff --git a/libavcodec/ivi_dsp.c b/libavcodec/ivi_dsp.c
index 52cd402..84e2436 100644
--- a/libavcodec/ivi_dsp.c
+++ b/libavcodec/ivi_dsp.c
@@ -27,8 +27,6 @@
  */
 
 #include "avcodec.h"
-#include "dsputil.h"
-#include "dwt.h"
 #include "ivi_common.h"
 #include "ivi_dsp.h"
 
@@ -40,7 +38,7 @@
     int32_t         b0_1, b0_2, b1_1, b1_2, b1_3, b2_1, b2_2, b2_3, b2_4, b2_5, b2_6;
     int32_t         b3_1, b3_2, b3_3, b3_4, b3_5, b3_6, b3_7, b3_8, b3_9;
     int32_t         pitch, back_pitch;
-    const IDWTELEM *b0_ptr, *b1_ptr, *b2_ptr, *b3_ptr;
+    const short     *b0_ptr, *b1_ptr, *b2_ptr, *b3_ptr;
     const int       num_bands = 4;
 
     /* all bands should have the same pitch */
@@ -193,7 +191,7 @@
                            const int dst_pitch)
 {
     int             x, y, indx, b0, b1, b2, b3, p0, p1, p2, p3;
-    const IDWTELEM *b0_ptr, *b1_ptr, *b2_ptr, *b3_ptr;
+    const short     *b0_ptr, *b1_ptr, *b2_ptr, *b3_ptr;
     int32_t         pitch;
 
     /* all bands should have the same pitch */
diff --git a/libavcodec/j2k.c b/libavcodec/j2k.c
index f5b40b1..e3c0c13 100644
--- a/libavcodec/j2k.c
+++ b/libavcodec/j2k.c
@@ -36,16 +36,16 @@
 {
     int i;
     for (i = 0; i < l; i++)
-        printf("%.3d ", tab[i]);
-    printf("\n");
+        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++)
-        printf("%.3hd ", tab[i]);
-    printf("\n");
+        av_log(NULL, AV_LOG_DEBUG, "%.3hd ", tab[i]);
+    av_log(NULL, AV_LOG_DEBUG, "\n");
 }
 #endif
 
diff --git a/libavcodec/j2kdec.c b/libavcodec/j2kdec.c
index de94f51..53c4f07 100644
--- a/libavcodec/j2kdec.c
+++ b/libavcodec/j2kdec.c
@@ -29,6 +29,7 @@
 
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 #include "j2k.h"
 #include "libavutil/common.h"
 
@@ -283,7 +284,7 @@
     if (s->picture.data[0])
         s->avctx->release_buffer(s->avctx, &s->picture);
 
-    if ((ret = s->avctx->get_buffer(s->avctx, &s->picture)) < 0)
+    if ((ret = ff_get_buffer(s->avctx, &s->picture)) < 0)
         return ret;
 
     s->picture.pict_type = AV_PICTURE_TYPE_I;
@@ -1017,7 +1018,7 @@
 }
 
 static int decode_frame(AVCodecContext *avctx,
-                        void *data, int *data_size,
+                        void *data, int *got_frame,
                         AVPacket *avpkt)
 {
     J2kDecoderContext *s = avctx->priv_data;
@@ -1060,7 +1061,7 @@
 
     cleanup(s);
 
-    *data_size = sizeof(AVPicture);
+    *got_frame = 1;
     *picture = s->picture;
 
     return bytestream2_tell(&s->g);
diff --git a/libavcodec/j2kenc.c b/libavcodec/j2kenc.c
index c1a4981..5d447ed 100644
--- a/libavcodec/j2kenc.c
+++ b/libavcodec/j2kenc.c
@@ -94,27 +94,11 @@
     while(n--) putc(' ', fd);
 }
 
-static void printv(int *tab, int l)
-{
-    int i;
-    for (i = 0; i < l; i++)
-        printf("%.3d ", tab[i]);
-    printf("\n");
-}
-
-static void printu(uint8_t *tab, int l)
-{
-    int i;
-    for (i = 0; i < l; i++)
-        printf("%.3hd ", tab[i]);
-    printf("\n");
-}
-
 static void printcomp(J2kComponent *comp)
 {
     int i;
     for (i = 0; i < comp->y1 - comp->y0; i++)
-        printv(comp->data + i * (comp->x1 - comp->x0), comp->x1 - comp->x0);
+        ff_j2k_printv(comp->data + i * (comp->x1 - comp->x0), comp->x1 - comp->x0);
 }
 
 static void dump(J2kEncoderContext *s, FILE *fd)
diff --git a/libavcodec/jfdctfst.c b/libavcodec/jfdctfst.c
index 3e30e5d..bbcf598 100644
--- a/libavcodec/jfdctfst.c
+++ b/libavcodec/jfdctfst.c
@@ -69,7 +69,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include "libavutil/common.h"
-#include "dsputil.h"
+#include "dct.h"
 
 #define DCTSIZE 8
 #define GLOBAL(x) x
@@ -136,17 +136,17 @@
 #endif
 
 
-/* Multiply a DCTELEM variable by an int32_t constant, and immediately
- * descale to yield a DCTELEM result.
+/* Multiply a int16_t variable by an int32_t constant, and immediately
+ * descale to yield a int16_t result.
  */
 
-#define MULTIPLY(var,const)  ((DCTELEM) DESCALE((var) * (const), CONST_BITS))
+#define MULTIPLY(var,const)  ((int16_t) DESCALE((var) * (const), CONST_BITS))
 
-static av_always_inline void row_fdct(DCTELEM * data){
+static av_always_inline void row_fdct(int16_t * data){
   int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
   int tmp10, tmp11, tmp12, tmp13;
   int z1, z2, z3, z4, z5, z11, z13;
-  DCTELEM *dataptr;
+  int16_t *dataptr;
   int ctr;
 
   /* Pass 1: process rows. */
@@ -205,12 +205,12 @@
  */
 
 GLOBAL(void)
-ff_fdct_ifast (DCTELEM * data)
+ff_fdct_ifast (int16_t * data)
 {
   int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
   int tmp10, tmp11, tmp12, tmp13;
   int z1, z2, z3, z4, z5, z11, z13;
-  DCTELEM *dataptr;
+  int16_t *dataptr;
   int ctr;
 
   row_fdct(data);
@@ -271,12 +271,12 @@
  */
 
 GLOBAL(void)
-ff_fdct_ifast248 (DCTELEM * data)
+ff_fdct_ifast248 (int16_t * data)
 {
   int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
   int tmp10, tmp11, tmp12, tmp13;
   int z1;
-  DCTELEM *dataptr;
+  int16_t *dataptr;
   int ctr;
 
   row_fdct(data);
diff --git a/libavcodec/jfdctint_template.c b/libavcodec/jfdctint_template.c
index 5175390..c6a1638 100644
--- a/libavcodec/jfdctint_template.c
+++ b/libavcodec/jfdctint_template.c
@@ -60,7 +60,7 @@
  */
 
 #include "libavutil/common.h"
-#include "dsputil.h"
+#include "dct.h"
 
 #include "bit_depth_template.c"
 
@@ -184,12 +184,12 @@
 #endif
 
 
-static av_always_inline void FUNC(row_fdct)(DCTELEM *data)
+static av_always_inline void FUNC(row_fdct)(int16_t *data)
 {
   int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
   int tmp10, tmp11, tmp12, tmp13;
   int z1, z2, z3, z4, z5;
-  DCTELEM *dataptr;
+  int16_t *dataptr;
   int ctr;
 
   /* Pass 1: process rows. */
@@ -216,13 +216,13 @@
     tmp11 = tmp1 + tmp2;
     tmp12 = tmp1 - tmp2;
 
-    dataptr[0] = (DCTELEM) ((tmp10 + tmp11) << PASS1_BITS);
-    dataptr[4] = (DCTELEM) ((tmp10 - tmp11) << PASS1_BITS);
+    dataptr[0] = (int16_t) ((tmp10 + tmp11) << PASS1_BITS);
+    dataptr[4] = (int16_t) ((tmp10 - tmp11) << PASS1_BITS);
 
     z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100);
-    dataptr[2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865),
+    dataptr[2] = (int16_t) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865),
                                    CONST_BITS-PASS1_BITS);
-    dataptr[6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065),
+    dataptr[6] = (int16_t) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065),
                                    CONST_BITS-PASS1_BITS);
 
     /* Odd part per figure 8 --- note paper omits factor of sqrt(2).
@@ -248,10 +248,10 @@
     z3 += z5;
     z4 += z5;
 
-    dataptr[7] = (DCTELEM) DESCALE(tmp4 + z1 + z3, CONST_BITS-PASS1_BITS);
-    dataptr[5] = (DCTELEM) DESCALE(tmp5 + z2 + z4, CONST_BITS-PASS1_BITS);
-    dataptr[3] = (DCTELEM) DESCALE(tmp6 + z2 + z3, CONST_BITS-PASS1_BITS);
-    dataptr[1] = (DCTELEM) DESCALE(tmp7 + z1 + z4, CONST_BITS-PASS1_BITS);
+    dataptr[7] = (int16_t) DESCALE(tmp4 + z1 + z3, CONST_BITS-PASS1_BITS);
+    dataptr[5] = (int16_t) DESCALE(tmp5 + z2 + z4, CONST_BITS-PASS1_BITS);
+    dataptr[3] = (int16_t) DESCALE(tmp6 + z2 + z3, CONST_BITS-PASS1_BITS);
+    dataptr[1] = (int16_t) DESCALE(tmp7 + z1 + z4, CONST_BITS-PASS1_BITS);
 
     dataptr += DCTSIZE;         /* advance pointer to next row */
   }
@@ -262,12 +262,12 @@
  */
 
 GLOBAL(void)
-FUNC(ff_jpeg_fdct_islow)(DCTELEM *data)
+FUNC(ff_jpeg_fdct_islow)(int16_t *data)
 {
   int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
   int tmp10, tmp11, tmp12, tmp13;
   int z1, z2, z3, z4, z5;
-  DCTELEM *dataptr;
+  int16_t *dataptr;
   int ctr;
 
   FUNC(row_fdct)(data);
@@ -344,12 +344,12 @@
  * you do even part two times.
  */
 GLOBAL(void)
-FUNC(ff_fdct248_islow)(DCTELEM *data)
+FUNC(ff_fdct248_islow)(int16_t *data)
 {
   int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
   int tmp10, tmp11, tmp12, tmp13;
   int z1;
-  DCTELEM *dataptr;
+  int16_t *dataptr;
   int ctr;
 
   FUNC(row_fdct)(data);
diff --git a/libavcodec/jpeglsenc.c b/libavcodec/jpeglsenc.c
index e51e47a..be979aa 100644
--- a/libavcodec/jpeglsenc.c
+++ b/libavcodec/jpeglsenc.c
@@ -27,10 +27,10 @@
 
 #include "avcodec.h"
 #include "get_bits.h"
+#include "put_bits.h"
 #include "golomb.h"
 #include "internal.h"
 #include "mathops.h"
-#include "dsputil.h"
 #include "mjpeg.h"
 #include "jpegls.h"
 
diff --git a/libavcodec/jrevdct.c b/libavcodec/jrevdct.c
index 395eb8c..91780b2 100644
--- a/libavcodec/jrevdct.c
+++ b/libavcodec/jrevdct.c
@@ -63,7 +63,7 @@
  */
 
 #include "libavutil/common.h"
-#include "dsputil.h"
+#include "dct.h"
 
 #define EIGHT_BIT_SAMPLES
 
@@ -74,7 +74,7 @@
 
 #define RIGHT_SHIFT(x, n) ((x) >> (n))
 
-typedef DCTELEM DCTBLOCK[DCTSIZE2];
+typedef int16_t DCTBLOCK[DCTSIZE2];
 
 #define CONST_BITS 13
 
@@ -213,7 +213,7 @@
   int32_t tmp10, tmp11, tmp12, tmp13;
   int32_t z1, z2, z3, z4, z5;
   int32_t d0, d1, d2, d3, d4, d5, d6, d7;
-  register DCTELEM *dataptr;
+  register int16_t *dataptr;
   int rowctr;
 
   /* Pass 1: process rows. */
@@ -249,7 +249,7 @@
       /* AC terms all zero */
       if (d0) {
           /* Compute a 32 bit value to assign. */
-          DCTELEM dcval = (DCTELEM) (d0 << PASS1_BITS);
+          int16_t dcval = (int16_t) (d0 << PASS1_BITS);
           register int v = (dcval & 0xffff) | ((dcval << 16) & 0xffff0000);
 
           idataptr[0] = v;
@@ -574,14 +574,14 @@
 }
     /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
 
-    dataptr[0] = (DCTELEM) DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS);
-    dataptr[7] = (DCTELEM) DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS);
-    dataptr[1] = (DCTELEM) DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS);
-    dataptr[6] = (DCTELEM) DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS);
-    dataptr[2] = (DCTELEM) DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS);
-    dataptr[5] = (DCTELEM) DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS);
-    dataptr[3] = (DCTELEM) DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS);
-    dataptr[4] = (DCTELEM) DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS);
+    dataptr[0] = (int16_t) DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS);
+    dataptr[7] = (int16_t) DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS);
+    dataptr[1] = (int16_t) DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS);
+    dataptr[6] = (int16_t) DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS);
+    dataptr[2] = (int16_t) DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS);
+    dataptr[5] = (int16_t) DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS);
+    dataptr[3] = (int16_t) DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS);
+    dataptr[4] = (int16_t) DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS);
 
     dataptr += DCTSIZE;         /* advance pointer to next row */
   }
@@ -920,21 +920,21 @@
 
     /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
 
-    dataptr[DCTSIZE*0] = (DCTELEM) DESCALE(tmp10 + tmp3,
+    dataptr[DCTSIZE*0] = (int16_t) DESCALE(tmp10 + tmp3,
                                            CONST_BITS+PASS1_BITS+3);
-    dataptr[DCTSIZE*7] = (DCTELEM) DESCALE(tmp10 - tmp3,
+    dataptr[DCTSIZE*7] = (int16_t) DESCALE(tmp10 - tmp3,
                                            CONST_BITS+PASS1_BITS+3);
-    dataptr[DCTSIZE*1] = (DCTELEM) DESCALE(tmp11 + tmp2,
+    dataptr[DCTSIZE*1] = (int16_t) DESCALE(tmp11 + tmp2,
                                            CONST_BITS+PASS1_BITS+3);
-    dataptr[DCTSIZE*6] = (DCTELEM) DESCALE(tmp11 - tmp2,
+    dataptr[DCTSIZE*6] = (int16_t) DESCALE(tmp11 - tmp2,
                                            CONST_BITS+PASS1_BITS+3);
-    dataptr[DCTSIZE*2] = (DCTELEM) DESCALE(tmp12 + tmp1,
+    dataptr[DCTSIZE*2] = (int16_t) DESCALE(tmp12 + tmp1,
                                            CONST_BITS+PASS1_BITS+3);
-    dataptr[DCTSIZE*5] = (DCTELEM) DESCALE(tmp12 - tmp1,
+    dataptr[DCTSIZE*5] = (int16_t) DESCALE(tmp12 - tmp1,
                                            CONST_BITS+PASS1_BITS+3);
-    dataptr[DCTSIZE*3] = (DCTELEM) DESCALE(tmp13 + tmp0,
+    dataptr[DCTSIZE*3] = (int16_t) DESCALE(tmp13 + tmp0,
                                            CONST_BITS+PASS1_BITS+3);
-    dataptr[DCTSIZE*4] = (DCTELEM) DESCALE(tmp13 - tmp0,
+    dataptr[DCTSIZE*4] = (int16_t) DESCALE(tmp13 - tmp0,
                                            CONST_BITS+PASS1_BITS+3);
 
     dataptr++;                  /* advance pointer to next column */
@@ -951,7 +951,7 @@
   int32_t tmp10, tmp11, tmp12, tmp13;
   int32_t z1;
   int32_t d0, d2, d4, d6;
-  register DCTELEM *dataptr;
+  register int16_t *dataptr;
   int rowctr;
 
   /* Pass 1: process rows. */
@@ -983,7 +983,7 @@
       /* AC terms all zero */
       if (d0) {
           /* Compute a 32 bit value to assign. */
-          DCTELEM dcval = (DCTELEM) (d0 << PASS1_BITS);
+          int16_t dcval = (int16_t) (d0 << PASS1_BITS);
           register int v = (dcval & 0xffff) | ((dcval << 16) & 0xffff0000);
 
           idataptr[0] = v;
@@ -1045,10 +1045,10 @@
 
     /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
 
-    dataptr[0] = (DCTELEM) DESCALE(tmp10, CONST_BITS-PASS1_BITS);
-    dataptr[1] = (DCTELEM) DESCALE(tmp11, CONST_BITS-PASS1_BITS);
-    dataptr[2] = (DCTELEM) DESCALE(tmp12, CONST_BITS-PASS1_BITS);
-    dataptr[3] = (DCTELEM) DESCALE(tmp13, CONST_BITS-PASS1_BITS);
+    dataptr[0] = (int16_t) DESCALE(tmp10, CONST_BITS-PASS1_BITS);
+    dataptr[1] = (int16_t) DESCALE(tmp11, CONST_BITS-PASS1_BITS);
+    dataptr[2] = (int16_t) DESCALE(tmp12, CONST_BITS-PASS1_BITS);
+    dataptr[3] = (int16_t) DESCALE(tmp13, CONST_BITS-PASS1_BITS);
 
     dataptr += DCTSTRIDE;       /* advance pointer to next row */
   }
diff --git a/libavcodec/jvdec.c b/libavcodec/jvdec.c
index 5e54a16..53d8285 100644
--- a/libavcodec/jvdec.c
+++ b/libavcodec/jvdec.c
@@ -129,7 +129,7 @@
 }
 
 static int decode_frame(AVCodecContext *avctx,
-                        void *data, int *data_size,
+                        void *data, int *got_frame,
                         AVPacket *avpkt)
 {
     JvContext *s           = avctx->priv_data;
@@ -190,7 +190,7 @@
         s->palette_has_changed       = 0;
         memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE);
 
-        *data_size      = sizeof(AVFrame);
+        *got_frame = 1;
         *(AVFrame*)data = s->frame;
     }
 
diff --git a/libavcodec/kbdwin.c b/libavcodec/kbdwin.c
index 2722312..5a62e9d 100644
--- a/libavcodec/kbdwin.c
+++ b/libavcodec/kbdwin.c
@@ -16,9 +16,8 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-
-#include <libavutil/avassert.h>
-#include <libavutil/mathematics.h>
+#include "libavutil/avassert.h"
+#include "libavutil/mathematics.h"
 #include "libavutil/attributes.h"
 #include "kbdwin.h"
 
diff --git a/libavcodec/kgv1dec.c b/libavcodec/kgv1dec.c
index 6c1daa9..008843c 100644
--- a/libavcodec/kgv1dec.c
+++ b/libavcodec/kgv1dec.c
@@ -28,6 +28,7 @@
 #include "libavutil/intreadwrite.h"
 #include "libavutil/imgutils.h"
 #include "avcodec.h"
+#include "internal.h"
 
 typedef struct {
     AVCodecContext *avctx;
@@ -42,7 +43,8 @@
         avctx->release_buffer(avctx, &c->prev);
 }
 
-static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt)
+static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
+                        AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
     const uint8_t *buf_end = buf + avpkt->size;
@@ -53,14 +55,14 @@
     int w, h, i, res;
 
     if (avpkt->size < 2)
-        return -1;
+        return AVERROR_INVALIDDATA;
 
     w = (buf[0] + 1) * 8;
     h = (buf[1] + 1) * 8;
     buf += 2;
 
-    if (av_image_check_size(w, h, 0, avctx))
-        return -1;
+    if ((res = av_image_check_size(w, h, 0, avctx)) < 0)
+        return res;
 
     if (w != avctx->width || h != avctx->height) {
         if (c->prev.data[0])
@@ -71,7 +73,7 @@
     maxcnt = w * h;
 
     c->cur.reference = 3;
-    if ((res = avctx->get_buffer(avctx, &c->cur)) < 0)
+    if ((res = ff_get_buffer(avctx, &c->cur)) < 0)
         return res;
     out  = (uint16_t *) c->cur.data[0];
     if (c->prev.data[0]) {
@@ -154,7 +156,7 @@
     if (outcnt - maxcnt)
         av_log(avctx, AV_LOG_DEBUG, "frame finished with %d diff\n", outcnt - maxcnt);
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*)data = c->cur;
 
     if (c->prev.data[0])
diff --git a/libavcodec/kmvc.c b/libavcodec/kmvc.c
index 2046d28..ffef771 100644
--- a/libavcodec/kmvc.c
+++ b/libavcodec/kmvc.c
@@ -29,6 +29,7 @@
 
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 
 #define KMVC_KEYFRAME 0x80
 #define KMVC_PALETTE  0x40
@@ -258,15 +259,15 @@
     return 0;
 }
 
-static int decode_frame(AVCodecContext * avctx, void *data, int *data_size, AVPacket *avpkt)
+static int decode_frame(AVCodecContext * avctx, void *data, int *got_frame,
+                        AVPacket *avpkt)
 {
     KmvcContext *const ctx = avctx->priv_data;
     uint8_t *out, *src;
-    int i;
+    int i, ret;
     int header;
     int blocksize;
     const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);
-    int ret;
 
     bytestream2_init(&ctx->g, avpkt->data, avpkt->size);
     if (ctx->pic.data[0])
@@ -274,7 +275,7 @@
 
     ctx->pic.reference = 3;
     ctx->pic.buffer_hints = FF_BUFFER_HINTS_VALID;
-    if ((ret = avctx->get_buffer(avctx, &ctx->pic)) < 0) {
+    if ((ret = ff_get_buffer(avctx, &ctx->pic)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -360,7 +361,7 @@
         ctx->prev = ctx->frm1;
     }
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame *) data = ctx->pic;
 
     /* always report that the buffer was completely consumed */
@@ -381,7 +382,7 @@
 
     if (avctx->width > 320 || avctx->height > 200) {
         av_log(avctx, AV_LOG_ERROR, "KMVC supports frames <= 320x200\n");
-        return AVERROR_INVALIDDATA;
+        return AVERROR(EINVAL);
     }
 
     c->frm0 = av_mallocz(320 * 200);
diff --git a/libavcodec/lagarith.c b/libavcodec/lagarith.c
index d0a5049..eb8a77e 100644
--- a/libavcodec/lagarith.c
+++ b/libavcodec/lagarith.c
@@ -198,7 +198,7 @@
             }
             /* Comment from reference source:
              * if (b & 0x80 == 0) {     // order of operations is 'wrong'; it has been left this way
-             *                          // since the compression change is negligable and fixing it
+             *                          // since the compression change is negligible and fixing it
              *                          // breaks backwards compatibility
              *      b =- (signed int)b;
              *      b &= 0xFF;
@@ -507,7 +507,7 @@
  * @return number of consumed bytes on success or negative if decode fails
  */
 static int lag_decode_frame(AVCodecContext *avctx,
-                            void *data, int *data_size, AVPacket *avpkt)
+                            void *data, int *got_frame, AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
     unsigned int buf_size = avpkt->size;
@@ -518,6 +518,7 @@
     uint32_t offs[4];
     uint8_t *srcs[4], *dst;
     int i, j, planes = 3;
+    int ret;
 
     AVFrame *picture = data;
 
@@ -535,18 +536,33 @@
     switch (frametype) {
     case FRAME_SOLID_RGBA:
         avctx->pix_fmt = AV_PIX_FMT_RGB32;
+    case FRAME_SOLID_GRAY:
+        if (frametype == FRAME_SOLID_GRAY)
+            if (avctx->bits_per_coded_sample == 24) {
+                avctx->pix_fmt = AV_PIX_FMT_RGB24;
+            } else {
+                avctx->pix_fmt = AV_PIX_FMT_0RGB32;
+                planes = 4;
+            }
 
-        if (ff_thread_get_buffer(avctx, p) < 0) {
+        if ((ret = ff_thread_get_buffer(avctx, p)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-            return -1;
+            return ret;
         }
 
         dst = p->data[0];
+        if (frametype == FRAME_SOLID_RGBA) {
         for (j = 0; j < avctx->height; j++) {
             for (i = 0; i < avctx->width; i++)
                 AV_WN32(dst + i * 4, offset_gu);
             dst += p->linesize[0];
         }
+        } else {
+            for (j = 0; j < avctx->height; j++) {
+                memset(dst, buf[1], avctx->width * planes);
+                dst += p->linesize[0];
+            }
+        }
         break;
     case FRAME_ARITH_RGBA:
         avctx->pix_fmt = AV_PIX_FMT_RGB32;
@@ -558,9 +574,9 @@
         if (frametype == FRAME_ARITH_RGB24 || frametype == FRAME_U_RGB24)
             avctx->pix_fmt = AV_PIX_FMT_RGB24;
 
-        if (ff_thread_get_buffer(avctx, p) < 0) {
+        if ((ret = ff_thread_get_buffer(avctx, p)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-            return -1;
+            return ret;
         }
 
         offs[0] = offset_bv;
@@ -617,9 +633,9 @@
     case FRAME_ARITH_YUY2:
         avctx->pix_fmt = AV_PIX_FMT_YUV422P;
 
-        if (ff_thread_get_buffer(avctx, p) < 0) {
+        if ((ret = ff_thread_get_buffer(avctx, p)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-            return -1;
+            return ret;
         }
 
         if (offset_ry >= buf_size ||
@@ -643,9 +659,9 @@
     case FRAME_ARITH_YV12:
         avctx->pix_fmt = AV_PIX_FMT_YUV420P;
 
-        if (ff_thread_get_buffer(avctx, p) < 0) {
+        if ((ret = ff_thread_get_buffer(avctx, p)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-            return -1;
+            return ret;
         }
         if (buf_size <= offset_ry || buf_size <= offset_gu || buf_size <= offset_bv) {
             return AVERROR_INVALIDDATA;
@@ -672,11 +688,11 @@
     default:
         av_log(avctx, AV_LOG_ERROR,
                "Unsupported Lagarith frame type: %#x\n", frametype);
-        return -1;
+        return AVERROR_PATCHWELCOME;
     }
 
     *picture = *p;
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
 
     return buf_size;
 }
diff --git a/libavcodec/lagarithrac.h b/libavcodec/lagarithrac.h
index d8d38f2..9892d11 100644
--- a/libavcodec/lagarithrac.h
+++ b/libavcodec/lagarithrac.h
@@ -107,6 +107,9 @@
         l->range -= range_scaled * l->prob[255];
     }
 
+    if (!l->range)
+        l->range = 0x80;
+
     l->low -= range_scaled * l->prob[val];
 
     return val;
diff --git a/libavcodec/lcldec.c b/libavcodec/lcldec.c
index 66db7c7..f8d45da 100644
--- a/libavcodec/lcldec.c
+++ b/libavcodec/lcldec.c
@@ -44,6 +44,7 @@
 #include "libavutil/mem.h"
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 #include "lcl.h"
 
 #if CONFIG_ZLIB_DECODER
@@ -137,21 +138,21 @@
     int zret = inflateReset(&c->zstream);
     if (zret != Z_OK) {
         av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret);
-        return -1;
+        return AVERROR_UNKNOWN;
     }
-    c->zstream.next_in = src;
+    c->zstream.next_in = (uint8_t *)src;
     c->zstream.avail_in = src_len;
     c->zstream.next_out = c->decomp_buf + offset;
     c->zstream.avail_out = c->decomp_size - offset;
     zret = inflate(&c->zstream, Z_FINISH);
     if (zret != Z_OK && zret != Z_STREAM_END) {
         av_log(avctx, AV_LOG_ERROR, "Inflate error: %d\n", zret);
-        return -1;
+        return AVERROR_UNKNOWN;
     }
     if (expected != (unsigned int)c->zstream.total_out) {
         av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %lu)\n",
                expected, c->zstream.total_out);
-        return -1;
+        return AVERROR_UNKNOWN;
     }
     return c->zstream.total_out;
 }
@@ -163,7 +164,7 @@
  * Decode a frame
  *
  */
-static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt)
+static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
@@ -177,7 +178,7 @@
     unsigned int height = avctx->height; // Real image height
     unsigned int mszh_dlen;
     unsigned char yq, y1q, uq, vq;
-    int uqvq;
+    int uqvq, ret;
     unsigned int mthread_inlen, mthread_outlen;
     unsigned int len = buf_size;
 
@@ -186,9 +187,9 @@
 
     c->pic.reference = 0;
     c->pic.buffer_hints = FF_BUFFER_HINTS_VALID;
-    if(avctx->get_buffer(avctx, &c->pic) < 0){
+    if ((ret = ff_get_buffer(avctx, &c->pic)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     outptr = c->pic.data[0]; // Output image pointer
@@ -202,6 +203,10 @@
                 ;
             } else if (c->flags & FLAG_MULTITHREAD) {
                 mthread_inlen = AV_RL32(encoded);
+                if (len < 8) {
+                    av_log(avctx, AV_LOG_ERROR, "len %d is too small\n", len);
+                    return AVERROR_INVALIDDATA;
+                }
                 mthread_inlen = FFMIN(mthread_inlen, len - 8);
                 mthread_outlen = AV_RL32(encoded+4);
                 mthread_outlen = FFMIN(mthread_outlen, c->decomp_size);
@@ -209,14 +214,14 @@
                 if (mthread_outlen != mszh_dlen) {
                     av_log(avctx, AV_LOG_ERROR, "Mthread1 decoded size differs (%d != %d)\n",
                            mthread_outlen, mszh_dlen);
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 }
                 mszh_dlen = mszh_decomp(encoded + 8 + mthread_inlen, len - 8 - mthread_inlen,
                                         c->decomp_buf + mthread_outlen, c->decomp_size - mthread_outlen);
                 if (mthread_outlen != mszh_dlen) {
                     av_log(avctx, AV_LOG_ERROR, "Mthread2 decoded size differs (%d != %d)\n",
                            mthread_outlen, mszh_dlen);
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 }
                 encoded = c->decomp_buf;
                 len = c->decomp_size;
@@ -225,7 +230,7 @@
                 if (c->decomp_size != mszh_dlen) {
                     av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %d)\n",
                            c->decomp_size, mszh_dlen);
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 }
                 encoded = c->decomp_buf;
                 len = mszh_dlen;
@@ -256,7 +261,7 @@
         }
         default:
             av_log(avctx, AV_LOG_ERROR, "BUG! Unknown MSZH compression in frame decoder.\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
         break;
 #if CONFIG_ZLIB_DECODER
@@ -273,7 +278,6 @@
                 break;
             }
         } else if (c->flags & FLAG_MULTITHREAD) {
-            int ret;
             mthread_inlen = AV_RL32(encoded);
             mthread_inlen = FFMIN(mthread_inlen, len - 8);
             mthread_outlen = AV_RL32(encoded+4);
@@ -293,7 +297,7 @@
 #endif
     default:
         av_log(avctx, AV_LOG_ERROR, "BUG! Unknown codec in frame decoder compression switch.\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
 
@@ -377,7 +381,7 @@
             break;
         default:
             av_log(avctx, AV_LOG_ERROR, "BUG! Unknown imagetype in pngfilter switch.\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
     }
 
@@ -465,10 +469,10 @@
         break;
     default:
         av_log(avctx, AV_LOG_ERROR, "BUG! Unknown imagetype in image decoder.\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*)data = c->pic;
 
     /* always report that the buffer was completely consumed */
diff --git a/libavcodec/libaacplus.c b/libavcodec/libaacplus.c
index 7872fec..e9e50f8 100644
--- a/libavcodec/libaacplus.c
+++ b/libavcodec/libaacplus.c
@@ -92,9 +92,7 @@
             avctx->extradata_size = decoder_specific_info_size;
             memcpy(avctx->extradata, buffer, avctx->extradata_size);
         }
-#undef free
         free(buffer);
-#define free please_use_av_free
     }
     return 0;
 }
diff --git a/libavcodec/libavcodec.v b/libavcodec/libavcodec.v
index 314d305..826a547 100644
--- a/libavcodec/libavcodec.v
+++ b/libavcodec/libavcodec.v
@@ -1,10 +1,10 @@
 LIBAVCODEC_$MAJOR {
         global: av*;
+                #deprecated, remove after next bump
                 audio_resample;
                 audio_resample_close;
-                #deprecated, remove after next bump
-                img_get_alpha_info;
                 dsputil_init;
+                ff_dsputil_init;
                 ff_find_pix_fmt;
                 ff_framenum_to_drop_timecode;
                 ff_framenum_to_smtpe_timecode;
diff --git a/libavcodec/libcelt_dec.c b/libavcodec/libcelt_dec.c
index 18b7a5e..a66f9f5 100644
--- a/libavcodec/libcelt_dec.c
+++ b/libavcodec/libcelt_dec.c
@@ -22,12 +22,12 @@
 #include <celt/celt.h>
 #include <celt/celt_header.h>
 #include "avcodec.h"
+#include "internal.h"
 #include "libavutil/intreadwrite.h"
 
 struct libcelt_context {
     CELTMode *mode;
     CELTDecoder *dec;
-    AVFrame frame;
     int discard;
 };
 
@@ -90,8 +90,6 @@
                    version, lib_version);
     }
     c->sample_fmt = AV_SAMPLE_FMT_S16;
-    avcodec_get_frame_defaults(&celt->frame);
-    c->coded_frame = &celt->frame;
     return 0;
 }
 
@@ -104,31 +102,31 @@
     return 0;
 }
 
-static int libcelt_dec_decode(AVCodecContext *c, void *frame,
+static int libcelt_dec_decode(AVCodecContext *c, void *data,
                               int *got_frame_ptr, AVPacket *pkt)
 {
     struct libcelt_context *celt = c->priv_data;
+    AVFrame *frame = data;
     int err;
     int16_t *pcm;
 
-    celt->frame.nb_samples = c->frame_size;
-    err = c->get_buffer(c, &celt->frame);
+    frame->nb_samples = c->frame_size;
+    err = ff_get_buffer(c, frame);
     if (err < 0) {
         av_log(c, AV_LOG_ERROR, "get_buffer() failed\n");
         return err;
     }
-    pcm = (int16_t *)celt->frame.data[0];
+    pcm = (int16_t *)frame->data[0];
     err = celt_decode(celt->dec, pkt->data, pkt->size, pcm, c->frame_size);
     if (err < 0)
         return ff_celt_error_to_averror(err);
     if (celt->discard) {
-        celt->frame.nb_samples -= celt->discard;
+        frame->nb_samples -= celt->discard;
         memmove(pcm, pcm + celt->discard * c->channels,
-                celt->frame.nb_samples * c->channels * sizeof(int16_t));
+                frame->nb_samples * c->channels * sizeof(int16_t));
         celt->discard = 0;
     }
     *got_frame_ptr = 1;
-    *(AVFrame *)frame = celt->frame;
     return pkt->size;
 }
 
diff --git a/libavcodec/libfaac.c b/libavcodec/libfaac.c
index a7bf503..bf226af 100644
--- a/libavcodec/libfaac.c
+++ b/libavcodec/libfaac.c
@@ -158,9 +158,7 @@
             memcpy(avctx->extradata, buffer, avctx->extradata_size);
             faac_cfg->outputFormat = 0;
         }
-#undef free
         free(buffer);
-#define free please_use_av_free
     }
 
     if (!faacEncSetConfiguration(s->faac_handle, faac_cfg)) {
@@ -201,7 +199,7 @@
 
     /* add current frame to the queue */
     if (frame) {
-        if ((ret = ff_af_queue_add(&s->afq, frame) < 0))
+        if ((ret = ff_af_queue_add(&s->afq, frame)) < 0)
             return ret;
     }
 
diff --git a/libavcodec/libfdk-aacenc.c b/libavcodec/libfdk-aacenc.c
index c2d8a2b..d76b215 100644
--- a/libavcodec/libfdk-aacenc.c
+++ b/libavcodec/libfdk-aacenc.c
@@ -250,14 +250,14 @@
     }
 
     if (avctx->cutoff > 0) {
-        if (avctx->cutoff < (avctx->sample_rate + 255) >> 8) {
+        if (avctx->cutoff < (avctx->sample_rate + 255) >> 8 || avctx->cutoff > 20000) {
             av_log(avctx, AV_LOG_ERROR, "cutoff valid range is %d-20000\n",
                    (avctx->sample_rate + 255) >> 8);
             goto error;
         }
         if ((err = aacEncoder_SetParam(s->handle, AACENC_BANDWIDTH,
                                        avctx->cutoff)) != AACENC_OK) {
-            av_log(avctx, AV_LOG_ERROR, "Unable to set the encoder bandwith to %d: %s\n",
+            av_log(avctx, AV_LOG_ERROR, "Unable to set the encoder bandwidth to %d: %s\n",
                    avctx->cutoff, aac_get_error(err));
             goto error;
         }
@@ -334,7 +334,7 @@
         in_buf.bufElSizes        = &in_buffer_element_size;
 
         /* add current frame to the queue */
-        if ((ret = ff_af_queue_add(&s->afq, frame) < 0))
+        if ((ret = ff_af_queue_add(&s->afq, frame)) < 0)
             return ret;
     }
 
diff --git a/libavcodec/libgsm.c b/libavcodec/libgsm.c
index 8915ef5..470cd61 100644
--- a/libavcodec/libgsm.c
+++ b/libavcodec/libgsm.c
@@ -27,7 +27,12 @@
 
 // The idiosyncrasies of GSM-in-WAV are explained at http://kbs.cs.tu-berlin.de/~jutta/toast.html
 
+#include "config.h"
+#if HAVE_GSM_H
+#include <gsm.h>
+#else
 #include <gsm/gsm.h>
+#endif
 
 #include "libavutil/channel_layout.h"
 #include "libavutil/common.h"
@@ -147,7 +152,6 @@
 #endif
 
 typedef struct LibGSMDecodeContext {
-    AVFrame frame;
     struct gsm_state *state;
 } LibGSMDecodeContext;
 
@@ -175,9 +179,6 @@
         }
     }
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     return 0;
 }
 
@@ -194,6 +195,7 @@
 {
     int i, ret;
     LibGSMDecodeContext *s = avctx->priv_data;
+    AVFrame *frame         = data;
     uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     int16_t *samples;
@@ -204,12 +206,12 @@
     }
 
     /* get output buffer */
-    s->frame.nb_samples = avctx->frame_size;
-    if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = avctx->frame_size;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    samples = (int16_t *)s->frame.data[0];
+    samples = (int16_t *)frame->data[0];
 
     for (i = 0; i < avctx->frame_size / GSM_FRAME_SIZE; i++) {
         if ((ret = gsm_decode(s->state, buf, samples)) < 0)
@@ -218,8 +220,7 @@
         samples += GSM_FRAME_SIZE;
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
+    *got_frame_ptr = 1;
 
     return avctx->block_align;
 }
diff --git a/libavcodec/libilbc.c b/libavcodec/libilbc.c
index bcc01ed..56cb51f 100644
--- a/libavcodec/libilbc.c
+++ b/libavcodec/libilbc.c
@@ -41,7 +41,6 @@
 
 typedef struct ILBCDecContext {
     const AVClass *class;
-    AVFrame frame;
     iLBC_Dec_Inst_t decoder;
     int enhance;
 } ILBCDecContext;
@@ -69,8 +68,6 @@
     }
 
     WebRtcIlbcfix_InitDecode(&s->decoder, mode, s->enhance);
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
 
     avctx->channels       = 1;
     avctx->channel_layout = AV_CH_LAYOUT_MONO;
@@ -86,6 +83,7 @@
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
     ILBCDecContext *s  = avctx->priv_data;
+    AVFrame *frame     = data;
     int ret;
 
     if (s->decoder.no_of_bytes > buf_size) {
@@ -94,17 +92,16 @@
         return AVERROR_INVALIDDATA;
     }
 
-    s->frame.nb_samples = s->decoder.blockl;
-    if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = s->decoder.blockl;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
 
-    WebRtcIlbcfix_DecodeImpl((WebRtc_Word16*) s->frame.data[0],
+    WebRtcIlbcfix_DecodeImpl((WebRtc_Word16*) frame->data[0],
                              (const WebRtc_UWord16*) buf, &s->decoder, 1);
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
+    *got_frame_ptr = 1;
 
     return s->decoder.no_of_bytes;
 }
diff --git a/libavcodec/libmp3lame.c b/libavcodec/libmp3lame.c
index 1447d6a..034fee7 100644
--- a/libavcodec/libmp3lame.c
+++ b/libavcodec/libmp3lame.c
@@ -237,7 +237,7 @@
 
     /* add current frame to the queue */
     if (frame) {
-        if ((ret = ff_af_queue_add(&s->afq, frame) < 0))
+        if ((ret = ff_af_queue_add(&s->afq, frame)) < 0)
             return ret;
     }
 
diff --git a/libavcodec/libopencore-amr.c b/libavcodec/libopencore-amr.c
index f0207ae..6877f4c 100644
--- a/libavcodec/libopencore-amr.c
+++ b/libavcodec/libopencore-amr.c
@@ -50,6 +50,98 @@
 #include <opencore-amrnb/interf_dec.h>
 #include <opencore-amrnb/interf_enc.h>
 
+typedef struct AMRContext {
+    AVClass *av_class;
+    void *dec_state;
+    void *enc_state;
+    int   enc_bitrate;
+    int   enc_mode;
+    int   enc_dtx;
+    int   enc_last_frame;
+    AudioFrameQueue afq;
+} AMRContext;
+
+#if CONFIG_LIBOPENCORE_AMRNB_DECODER
+static av_cold int amr_nb_decode_init(AVCodecContext *avctx)
+{
+    AMRContext *s  = avctx->priv_data;
+    int ret;
+
+    if ((ret = amr_decode_fix_avctx(avctx)) < 0)
+        return ret;
+
+    s->dec_state   = Decoder_Interface_init();
+    if (!s->dec_state) {
+        av_log(avctx, AV_LOG_ERROR, "Decoder_Interface_init error\n");
+        return -1;
+    }
+
+    return 0;
+}
+
+static av_cold int amr_nb_decode_close(AVCodecContext *avctx)
+{
+    AMRContext *s = avctx->priv_data;
+
+    Decoder_Interface_exit(s->dec_state);
+
+    return 0;
+}
+
+static int amr_nb_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;
+    AMRContext *s      = avctx->priv_data;
+    static const uint8_t block_size[16] = { 12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0 };
+    enum Mode dec_mode;
+    int packet_size, ret;
+
+    av_dlog(avctx, "amr_decode_frame buf=%p buf_size=%d frame_count=%d!!\n",
+            buf, buf_size, avctx->frame_number);
+
+    /* get output buffer */
+    frame->nb_samples = 160;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+        return ret;
+    }
+
+    dec_mode    = (buf[0] >> 3) & 0x000F;
+    packet_size = block_size[dec_mode] + 1;
+
+    if (packet_size > buf_size) {
+        av_log(avctx, AV_LOG_ERROR, "amr frame too short (%u, should be %u)\n",
+               buf_size, packet_size);
+        return AVERROR_INVALIDDATA;
+    }
+
+    av_dlog(avctx, "packet_size=%d buf= 0x%X %X %X %X\n",
+              packet_size, buf[0], buf[1], buf[2], buf[3]);
+    /* call decoder */
+    Decoder_Interface_Decode(s->dec_state, buf, (short *)frame->data[0], 0);
+
+    *got_frame_ptr = 1;
+
+    return packet_size;
+}
+
+AVCodec ff_libopencore_amrnb_decoder = {
+    .name           = "libopencore_amrnb",
+    .type           = AVMEDIA_TYPE_AUDIO,
+    .id             = AV_CODEC_ID_AMR_NB,
+    .priv_data_size = sizeof(AMRContext),
+    .init           = amr_nb_decode_init,
+    .close          = amr_nb_decode_close,
+    .decode         = amr_nb_decode_frame,
+    .capabilities   = CODEC_CAP_DR1,
+    .long_name      = NULL_IF_CONFIG_SMALL("OpenCORE AMR-NB (Adaptive Multi-Rate Narrow-Band)"),
+};
+#endif /* CONFIG_LIBOPENCORE_AMRNB_DECODER */
+
+#if CONFIG_LIBOPENCORE_AMRNB_ENCODER
 /* Common code for fixed and float version*/
 typedef struct AMR_bitrates {
     int       rate;
@@ -85,18 +177,6 @@
     return best;
 }
 
-typedef struct AMRContext {
-    AVClass *av_class;
-    AVFrame frame;
-    void *dec_state;
-    void *enc_state;
-    int   enc_bitrate;
-    int   enc_mode;
-    int   enc_dtx;
-    int   enc_last_frame;
-    AudioFrameQueue afq;
-} AMRContext;
-
 static const AVOption options[] = {
     { "dtx", "Allow DTX (generate comfort noise)", offsetof(AMRContext, enc_dtx), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM },
     { NULL }
@@ -106,87 +186,6 @@
     "libopencore_amrnb", av_default_item_name, options, LIBAVUTIL_VERSION_INT
 };
 
-static av_cold int amr_nb_decode_init(AVCodecContext *avctx)
-{
-    AMRContext *s  = avctx->priv_data;
-    int ret;
-
-    if ((ret = amr_decode_fix_avctx(avctx)) < 0)
-        return ret;
-
-    s->dec_state   = Decoder_Interface_init();
-    if (!s->dec_state) {
-        av_log(avctx, AV_LOG_ERROR, "Decoder_Interface_init error\n");
-        return -1;
-    }
-
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
-    return 0;
-}
-
-static av_cold int amr_nb_decode_close(AVCodecContext *avctx)
-{
-    AMRContext *s = avctx->priv_data;
-
-    Decoder_Interface_exit(s->dec_state);
-
-    return 0;
-}
-
-static int amr_nb_decode_frame(AVCodecContext *avctx, void *data,
-                               int *got_frame_ptr, AVPacket *avpkt)
-{
-    const uint8_t *buf = avpkt->data;
-    int buf_size       = avpkt->size;
-    AMRContext *s      = avctx->priv_data;
-    static const uint8_t block_size[16] = { 12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0 };
-    enum Mode dec_mode;
-    int packet_size, ret;
-
-    av_dlog(avctx, "amr_decode_frame buf=%p buf_size=%d frame_count=%d!!\n",
-            buf, buf_size, avctx->frame_number);
-
-    /* get output buffer */
-    s->frame.nb_samples = 160;
-    if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return ret;
-    }
-
-    dec_mode    = (buf[0] >> 3) & 0x000F;
-    packet_size = block_size[dec_mode] + 1;
-
-    if (packet_size > buf_size) {
-        av_log(avctx, AV_LOG_ERROR, "amr frame too short (%u, should be %u)\n",
-               buf_size, packet_size);
-        return AVERROR_INVALIDDATA;
-    }
-
-    av_dlog(avctx, "packet_size=%d buf= 0x%X %X %X %X\n",
-              packet_size, buf[0], buf[1], buf[2], buf[3]);
-    /* call decoder */
-    Decoder_Interface_Decode(s->dec_state, buf, (short *)s->frame.data[0], 0);
-
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
-
-    return packet_size;
-}
-
-AVCodec ff_libopencore_amrnb_decoder = {
-    .name           = "libopencore_amrnb",
-    .type           = AVMEDIA_TYPE_AUDIO,
-    .id             = AV_CODEC_ID_AMR_NB,
-    .priv_data_size = sizeof(AMRContext),
-    .init           = amr_nb_decode_init,
-    .close          = amr_nb_decode_close,
-    .decode         = amr_nb_decode_frame,
-    .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("OpenCORE AMR-NB (Adaptive Multi-Rate Narrow-Band)"),
-};
-
 static av_cold int amr_nb_encode_init(AVCodecContext *avctx)
 {
     AMRContext *s = avctx->priv_data;
@@ -261,7 +260,7 @@
             if (frame->nb_samples < avctx->frame_size - avctx->delay)
                 s->enc_last_frame = -1;
         }
-        if ((ret = ff_af_queue_add(&s->afq, frame) < 0)) {
+        if ((ret = ff_af_queue_add(&s->afq, frame)) < 0) {
             av_freep(&flush_buf);
             return ret;
         }
@@ -304,17 +303,17 @@
     .long_name      = NULL_IF_CONFIG_SMALL("OpenCORE AMR-NB (Adaptive Multi-Rate Narrow-Band)"),
     .priv_class     = &class,
 };
+#endif /* CONFIG_LIBOPENCORE_AMRNB_ENCODER */
 
-#endif
+#endif /* CONFIG_LIBOPENCORE_AMRNB */
 
 /* -----------AMR wideband ------------*/
-#if CONFIG_LIBOPENCORE_AMRWB
+#if CONFIG_LIBOPENCORE_AMRWB_DECODER
 
 #include <opencore-amrwb/dec_if.h>
 #include <opencore-amrwb/if_rom.h>
 
 typedef struct AMRWBContext {
-    AVFrame frame;
     void  *state;
 } AMRWBContext;
 
@@ -328,15 +327,13 @@
 
     s->state        = D_IF_init();
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     return 0;
 }
 
 static int amr_wb_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;
     AMRWBContext *s    = avctx->priv_data;
@@ -345,8 +342,8 @@
     static const uint8_t block_size[16] = {18, 24, 33, 37, 41, 47, 51, 59, 61, 6, 6, 0, 0, 0, 1, 1};
 
     /* get output buffer */
-    s->frame.nb_samples = 320;
-    if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = 320;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -364,10 +361,9 @@
         return AVERROR_INVALIDDATA;
     }
 
-    D_IF_decode(s->state, buf, (short *)s->frame.data[0], _good_frame);
+    D_IF_decode(s->state, buf, (short *)frame->data[0], _good_frame);
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
+    *got_frame_ptr = 1;
 
     return packet_size;
 }
@@ -392,4 +388,4 @@
     .long_name      = NULL_IF_CONFIG_SMALL("OpenCORE AMR-WB (Adaptive Multi-Rate Wide-Band)"),
 };
 
-#endif /* CONFIG_LIBOPENCORE_AMRWB */
+#endif /* CONFIG_LIBOPENCORE_AMRWB_DECODER */
diff --git a/libavcodec/libopenjpegdec.c b/libavcodec/libopenjpegdec.c
index 5f3c36b..eeb3dd6 100644
--- a/libavcodec/libopenjpegdec.c
+++ b/libavcodec/libopenjpegdec.c
@@ -25,7 +25,6 @@
  */
 
 #define  OPJ_STATIC
-#include <openjpeg.h>
 
 #include "libavutil/common.h"
 #include "libavutil/intreadwrite.h"
@@ -35,6 +34,12 @@
 #include "avcodec.h"
 #include "thread.h"
 
+#if HAVE_OPENJPEG_1_5_OPENJPEG_H
+# include <openjpeg-1.5/openjpeg.h>
+#else
+# include <openjpeg.h>
+#endif
+
 #define JP2_SIG_TYPE    0x6A502020
 #define JP2_SIG_VALUE   0x0D0A870A
 
@@ -230,7 +235,7 @@
 }
 
 static int libopenjpeg_decode_frame(AVCodecContext *avctx,
-                                    void *data, int *data_size,
+                                    void *data, int *got_frame,
                                     AVPacket *avpkt)
 {
     uint8_t *buf = avpkt->data;
@@ -246,7 +251,7 @@
     int ispacked = 0;
     int i;
 
-    *data_size = 0;
+    *got_frame = 0;
 
     // Check if input is a raw jpeg2k codestream or in jp2 wrapping
     if ((AV_RB32(buf)     == 12)           &&
@@ -381,7 +386,7 @@
     }
 
     *output    = ctx->image;
-    *data_size = sizeof(AVPicture);
+    *got_frame = 1;
     ret        = buf_size;
 
 done:
diff --git a/libavcodec/libopenjpegenc.c b/libavcodec/libopenjpegenc.c
index b87d4d4..c355083 100644
--- a/libavcodec/libopenjpegenc.c
+++ b/libavcodec/libopenjpegenc.c
@@ -25,7 +25,6 @@
  */
 
 #define  OPJ_STATIC
-#include <openjpeg.h>
 
 #include "libavutil/avassert.h"
 #include "libavutil/common.h"
@@ -35,6 +34,12 @@
 #include "avcodec.h"
 #include "internal.h"
 
+#if HAVE_OPENJPEG_1_5_OPENJPEG_H
+# include <openjpeg-1.5/openjpeg.h>
+#else
+# include <openjpeg.h>
+#endif
+
 typedef struct {
     AVClass *avclass;
     opj_image_t *image;
@@ -95,6 +100,12 @@
     case AV_PIX_FMT_RGBA:
     case AV_PIX_FMT_RGB48:
     case AV_PIX_FMT_RGBA64:
+    case AV_PIX_FMT_GBR24P:
+    case AV_PIX_FMT_GBRP9:
+    case AV_PIX_FMT_GBRP10:
+    case AV_PIX_FMT_GBRP12:
+    case AV_PIX_FMT_GBRP14:
+    case AV_PIX_FMT_GBRP16:
         color_space = CLRSPC_SRGB;
         break;
     case AV_PIX_FMT_YUV410P:
@@ -177,6 +188,35 @@
     ctx->enc_params.tcp_numlayers = ctx->numlayers;
     ctx->enc_params.tcp_rates[0] = FFMAX(avctx->compression_level, 0) * 2;
 
+    if (ctx->cinema_mode > 0) {
+        ctx->enc_params.irreversible = 1;
+        ctx->enc_params.tcp_mct = 1;
+        ctx->enc_params.tile_size_on = 0;
+        /* no subsampling */
+        ctx->enc_params.cp_tdx=1;
+        ctx->enc_params.cp_tdy=1;
+        ctx->enc_params.subsampling_dx = 1;
+        ctx->enc_params.subsampling_dy = 1;
+        /* Tile and Image shall be at (0,0) */
+        ctx->enc_params.cp_tx0 = 0;
+        ctx->enc_params.cp_ty0 = 0;
+        ctx->enc_params.image_offset_x0 = 0;
+        ctx->enc_params.image_offset_y0 = 0;
+        /* Codeblock size= 32*32 */
+        ctx->enc_params.cblockw_init = 32;
+        ctx->enc_params.cblockh_init = 32;
+        ctx->enc_params.csty |= 0x01;
+        /* No ROI */
+        ctx->enc_params.roi_compno = -1;
+
+        if (ctx->enc_params.prog_order != CPRL) {
+            av_log(avctx, AV_LOG_ERROR, "prog_order forced to CPRL\n");
+            ctx->enc_params.prog_order = CPRL;
+        }
+        ctx->enc_params.tp_flag = 'C';
+        ctx->enc_params.tp_on = 1;
+    }
+
     ctx->compress = opj_create_compress(ctx->format);
     if (!ctx->compress) {
         av_log(avctx, AV_LOG_ERROR, "Error creating the compressor\n");
@@ -346,6 +386,7 @@
     opj_cio_t *stream;
     int cpyresult = 0;
     int ret, len;
+    AVFrame gbrframe;
 
     // x0, y0 is the top left corner of the image
     // x1, y1 is the width, height of the reference grid
@@ -364,6 +405,25 @@
     case AV_PIX_FMT_RGBA64:
         cpyresult = libopenjpeg_copy_packed16(avctx, frame, image);
         break;
+    case AV_PIX_FMT_GBR24P:
+    case AV_PIX_FMT_GBRP9:
+    case AV_PIX_FMT_GBRP10:
+    case AV_PIX_FMT_GBRP12:
+    case AV_PIX_FMT_GBRP14:
+    case AV_PIX_FMT_GBRP16:
+        gbrframe = *frame;
+        gbrframe.data[0] = frame->data[2]; // swap to be rgb
+        gbrframe.data[1] = frame->data[0];
+        gbrframe.data[2] = frame->data[1];
+        gbrframe.linesize[0] = frame->linesize[2];
+        gbrframe.linesize[1] = frame->linesize[0];
+        gbrframe.linesize[2] = frame->linesize[1];
+        if (avctx->pix_fmt == AV_PIX_FMT_GBR24P) {
+            cpyresult = libopenjpeg_copy_unpacked8(avctx, &gbrframe, image);
+        } else {
+            cpyresult = libopenjpeg_copy_unpacked16(avctx, &gbrframe, image);
+        }
+        break;
     case AV_PIX_FMT_GRAY8:
     case AV_PIX_FMT_YUV410P:
     case AV_PIX_FMT_YUV411P:
@@ -500,6 +560,8 @@
     .capabilities   = 0,
     .pix_fmts       = (const enum AVPixelFormat[]) {
         AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA, AV_PIX_FMT_RGB48, AV_PIX_FMT_RGBA64,
+        AV_PIX_FMT_GBR24P,
+        AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16,
         AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY8A, AV_PIX_FMT_GRAY16,
         AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUVA420P,
         AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVA422P,
diff --git a/libavcodec/libopusdec.c b/libavcodec/libopusdec.c
index f3cad25..686b8a6 100644
--- a/libavcodec/libopusdec.c
+++ b/libavcodec/libopusdec.c
@@ -32,7 +32,6 @@
 
 struct libopus_context {
     OpusMSDecoder *dec;
-    AVFrame frame;
     int pre_skip;
 #ifndef OPUS_SET_GAIN
     union { int i; double d; } gain;
@@ -111,8 +110,7 @@
 
     avc->internal->skip_samples = opus->pre_skip;
     avc->delay = 3840;  /* Decoder delay (in samples) at 48kHz */
-    avcodec_get_frame_defaults(&opus->frame);
-    avc->coded_frame = &opus->frame;
+
     return 0;
 }
 
@@ -126,14 +124,15 @@
 
 #define MAX_FRAME_SIZE (960 * 6)
 
-static int libopus_decode(AVCodecContext *avc, void *frame,
+static int libopus_decode(AVCodecContext *avc, void *data,
                           int *got_frame_ptr, AVPacket *pkt)
 {
     struct libopus_context *opus = avc->priv_data;
+    AVFrame *frame               = data;
     int ret, nb_samples;
 
-    opus->frame.nb_samples = MAX_FRAME_SIZE;
-    ret = avc->get_buffer(avc, &opus->frame);
+    frame->nb_samples = MAX_FRAME_SIZE;
+    ret = ff_get_buffer(avc, frame);
     if (ret < 0) {
         av_log(avc, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
@@ -141,12 +140,12 @@
 
     if (avc->sample_fmt == AV_SAMPLE_FMT_S16)
         nb_samples = opus_multistream_decode(opus->dec, pkt->data, pkt->size,
-                                             (opus_int16 *)opus->frame.data[0],
-                                             opus->frame.nb_samples, 0);
+                                             (opus_int16 *)frame->data[0],
+                                             frame->nb_samples, 0);
     else
         nb_samples = opus_multistream_decode_float(opus->dec, pkt->data, pkt->size,
-                                                   (float *)opus->frame.data[0],
-                                                   opus->frame.nb_samples, 0);
+                                                   (float *)frame->data[0],
+                                                   frame->nb_samples, 0);
 
     if (nb_samples < 0) {
         av_log(avc, AV_LOG_ERROR, "Decoding error: %s\n",
@@ -158,20 +157,20 @@
     {
         int i = avc->channels * nb_samples;
         if (avc->sample_fmt == AV_SAMPLE_FMT_FLT) {
-            float *pcm = (float *)opus->frame.data[0];
+            float *pcm = (float *)frame->data[0];
             for (; i > 0; i--, pcm++)
                 *pcm = av_clipf(*pcm * opus->gain.d, -1, 1);
         } else {
-            int16_t *pcm = (int16_t *)opus->frame.data[0];
+            int16_t *pcm = (int16_t *)frame->data[0];
             for (; i > 0; i--, pcm++)
                 *pcm = av_clip_int16(((int64_t)opus->gain.i * *pcm) >> 16);
         }
     }
 #endif
 
-    opus->frame.nb_samples = nb_samples;
-    *(AVFrame *)frame = opus->frame;
-    *got_frame_ptr = 1;
+    frame->nb_samples = nb_samples;
+    *got_frame_ptr    = 1;
+
     return pkt->size;
 }
 
diff --git a/libavcodec/libopusenc.c b/libavcodec/libopusenc.c
index d198798..a4aa37c 100644
--- a/libavcodec/libopusenc.c
+++ b/libavcodec/libopusenc.c
@@ -107,6 +107,13 @@
 {
     int ret;
 
+    if (avctx->global_quality) {
+        av_log(avctx, AV_LOG_ERROR,
+               "Quality-based encoding not supported, "
+               "please specify a bitrate and VBR setting.\n");
+        return AVERROR(EINVAL);
+    }
+
     ret = opus_multistream_encoder_ctl(enc, OPUS_SET_BITRATE(avctx->bit_rate));
     if (ret != OPUS_OK) {
         av_log(avctx, AV_LOG_ERROR,
diff --git a/libavcodec/libschroedinger.c b/libavcodec/libschroedinger.c
index c4963e1..f452d70 100644
--- a/libavcodec/libschroedinger.c
+++ b/libavcodec/libschroedinger.c
@@ -46,7 +46,7 @@
     { 4096, 2160, 24,    1   },
 };
 
-static unsigned int get_video_format_idx(AVCodecContext *avccontext)
+static unsigned int get_video_format_idx(AVCodecContext *avctx)
 {
     unsigned int ret_idx = 0;
     unsigned int idx;
@@ -55,11 +55,11 @@
 
     for (idx = 1; idx < num_formats; ++idx) {
         const SchroVideoFormatInfo *vf = &ff_schro_video_format_info[idx];
-        if (avccontext->width  == vf->width &&
-            avccontext->height == vf->height) {
+        if (avctx->width  == vf->width &&
+            avctx->height == vf->height) {
             ret_idx = idx;
-            if (avccontext->time_base.den == vf->frame_rate_num &&
-                avccontext->time_base.num == vf->frame_rate_denom)
+            if (avctx->time_base.den == vf->frame_rate_num &&
+                avctx->time_base.num == vf->frame_rate_denom)
                 return idx;
         }
     }
@@ -136,12 +136,12 @@
     SCHRO_VIDEO_FORMAT_DC4K_24    ,
 };
 
-SchroVideoFormatEnum ff_get_schro_video_format_preset(AVCodecContext *avccontext)
+SchroVideoFormatEnum ff_get_schro_video_format_preset(AVCodecContext *avctx)
 {
     unsigned int num_formats = sizeof(ff_schro_video_formats) /
                                sizeof(ff_schro_video_formats[0]);
 
-    unsigned int idx = get_video_format_idx(avccontext);
+    unsigned int idx = get_video_format_idx(avctx);
 
     return (idx < num_formats) ? ff_schro_video_formats[idx] :
                                  SCHRO_VIDEO_FORMAT_CUSTOM;
@@ -175,7 +175,7 @@
     av_freep(&p_pic);
 }
 
-SchroFrame *ff_create_schro_frame(AVCodecContext *avccontext,
+SchroFrame *ff_create_schro_frame(AVCodecContext *avctx,
                                   SchroFrameFormat schro_frame_fmt)
 {
     AVPicture *p_pic;
@@ -184,13 +184,13 @@
     int y_height, uv_height;
     int i;
 
-    y_width   = avccontext->width;
-    y_height  = avccontext->height;
+    y_width   = avctx->width;
+    y_height  = avctx->height;
     uv_width  = y_width  >> (SCHRO_FRAME_FORMAT_H_SHIFT(schro_frame_fmt));
     uv_height = y_height >> (SCHRO_FRAME_FORMAT_V_SHIFT(schro_frame_fmt));
 
     p_pic = av_mallocz(sizeof(AVPicture));
-    if (!p_pic || avpicture_alloc(p_pic, avccontext->pix_fmt, y_width, y_height) < 0) {
+    if (!p_pic || avpicture_alloc(p_pic, avctx->pix_fmt, y_width, y_height) < 0) {
         av_free(p_pic);
         return NULL;
     }
diff --git a/libavcodec/libschroedinger.h b/libavcodec/libschroedinger.h
index f2e513b..12fe57c 100644
--- a/libavcodec/libschroedinger.h
+++ b/libavcodec/libschroedinger.h
@@ -114,7 +114,7 @@
 * Returns the video format preset matching the input video dimensions and
 * time base.
 */
-SchroVideoFormatEnum ff_get_schro_video_format_preset (AVCodecContext *avccontext);
+SchroVideoFormatEnum ff_get_schro_video_format_preset (AVCodecContext *avctx);
 
 /**
 * Sets the Schroedinger frame format corresponding to the Schro chroma format
@@ -127,7 +127,7 @@
 * Create a Schro frame based on the dimensions and frame format
 * passed. Returns a pointer to a frame on success, NULL on failure.
 */
-SchroFrame *ff_create_schro_frame(AVCodecContext *avccontext,
+SchroFrame *ff_create_schro_frame(AVCodecContext *avctx,
                                   SchroFrameFormat schro_frame_fmt);
 
 #endif /* AVCODEC_LIBSCHROEDINGER_H */
diff --git a/libavcodec/libschroedingerdec.c b/libavcodec/libschroedingerdec.c
index 4e523dc..985ae60 100644
--- a/libavcodec/libschroedingerdec.c
+++ b/libavcodec/libschroedingerdec.c
@@ -34,6 +34,7 @@
 #include "libavutil/intreadwrite.h"
 #include "libavutil/mem.h"
 #include "avcodec.h"
+#include "internal.h"
 #include "libschroedinger.h"
 
 #include <schroedinger/schro.h>
@@ -146,14 +147,14 @@
     return AV_PIX_FMT_NONE;
 }
 
-static av_cold int libschroedinger_decode_init(AVCodecContext *avccontext)
+static av_cold int libschroedinger_decode_init(AVCodecContext *avctx)
 {
 
-    SchroDecoderParams *p_schro_params = avccontext->priv_data;
+    SchroDecoderParams *p_schro_params = avctx->priv_data;
     /* First of all, initialize our supporting libraries. */
     schro_init();
 
-    schro_debug_set_level(avccontext->debug);
+    schro_debug_set_level(avctx->debug);
     p_schro_params->decoder = schro_decoder_new();
     schro_decoder_set_skip_ratio(p_schro_params->decoder, 1);
 
@@ -170,39 +171,39 @@
     schro_frame_unref(frame);
 }
 
-static void libschroedinger_handle_first_access_unit(AVCodecContext *avccontext)
+static void libschroedinger_handle_first_access_unit(AVCodecContext *avctx)
 {
-    SchroDecoderParams *p_schro_params = avccontext->priv_data;
+    SchroDecoderParams *p_schro_params = avctx->priv_data;
     SchroDecoder *decoder = p_schro_params->decoder;
 
     p_schro_params->format = schro_decoder_get_video_format(decoder);
 
     /* Tell FFmpeg about sequence details. */
     if (av_image_check_size(p_schro_params->format->width,
-                            p_schro_params->format->height, 0, avccontext) < 0) {
-        av_log(avccontext, AV_LOG_ERROR, "invalid dimensions (%dx%d)\n",
+                            p_schro_params->format->height, 0, avctx) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "invalid dimensions (%dx%d)\n",
                p_schro_params->format->width, p_schro_params->format->height);
-        avccontext->height = avccontext->width = 0;
+        avctx->height = avctx->width = 0;
         return;
     }
-    avccontext->height  = p_schro_params->format->height;
-    avccontext->width   = p_schro_params->format->width;
-    avccontext->pix_fmt = get_chroma_format(p_schro_params->format->chroma_format);
+    avctx->height  = p_schro_params->format->height;
+    avctx->width   = p_schro_params->format->width;
+    avctx->pix_fmt = get_chroma_format(p_schro_params->format->chroma_format);
 
     if (ff_get_schro_frame_format(p_schro_params->format->chroma_format,
                                   &p_schro_params->frame_format) == -1) {
-        av_log(avccontext, AV_LOG_ERROR,
+        av_log(avctx, AV_LOG_ERROR,
                "This codec currently only supports planar YUV 4:2:0, 4:2:2 "
                "and 4:4:4 formats.\n");
         return;
     }
 
-    avccontext->time_base.den = p_schro_params->format->frame_rate_numerator;
-    avccontext->time_base.num = p_schro_params->format->frame_rate_denominator;
+    avctx->time_base.den = p_schro_params->format->frame_rate_numerator;
+    avctx->time_base.num = p_schro_params->format->frame_rate_denominator;
 }
 
-static int libschroedinger_decode_frame(AVCodecContext *avccontext,
-                                        void *data, int *data_size,
+static int libschroedinger_decode_frame(AVCodecContext *avctx,
+                                        void *data, int *got_frame,
                                         AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
@@ -210,7 +211,7 @@
     int64_t pts  = avpkt->pts;
     SchroTag *tag;
 
-    SchroDecoderParams *p_schro_params = avccontext->priv_data;
+    SchroDecoderParams *p_schro_params = avctx->priv_data;
     SchroDecoder *decoder = p_schro_params->decoder;
     SchroBuffer *enc_buf;
     SchroFrame* frame;
@@ -220,7 +221,7 @@
     SchroParseUnitContext parse_ctx;
     LibSchroFrameContext *framewithpts = NULL;
 
-    *data_size = 0;
+    *got_frame = 0;
 
     parse_context_init(&parse_ctx, buf, buf_size);
     if (!buf_size) {
@@ -236,17 +237,17 @@
             /* Set Schrotag with the pts to be recovered after decoding*/
             enc_buf->tag = schro_tag_new(av_malloc(sizeof(int64_t)), av_free);
             if (!enc_buf->tag->value) {
-                av_log(avccontext, AV_LOG_ERROR, "Unable to allocate SchroTag\n");
+                av_log(avctx, AV_LOG_ERROR, "Unable to allocate SchroTag\n");
                 return AVERROR(ENOMEM);
             }
             AV_WN(64, enc_buf->tag->value, pts);
             /* Push buffer into decoder. */
             if (SCHRO_PARSE_CODE_IS_PICTURE(enc_buf->data[4]) &&
                 SCHRO_PARSE_CODE_NUM_REFS(enc_buf->data[4]) > 0)
-                avccontext->has_b_frames = 1;
+                avctx->has_b_frames = 1;
             state = schro_decoder_push(decoder, enc_buf);
             if (state == SCHRO_DECODER_FIRST_ACCESS_UNIT)
-                libschroedinger_handle_first_access_unit(avccontext);
+                libschroedinger_handle_first_access_unit(avctx);
             go = 1;
         } else
             outer = 0;
@@ -256,7 +257,7 @@
             state = schro_decoder_wait(decoder);
             switch (state) {
             case SCHRO_DECODER_FIRST_ACCESS_UNIT:
-                libschroedinger_handle_first_access_unit(avccontext);
+                libschroedinger_handle_first_access_unit(avctx);
                 break;
 
             case SCHRO_DECODER_NEED_BITS:
@@ -266,7 +267,7 @@
 
             case SCHRO_DECODER_NEED_FRAME:
                 /* Decoder needs a frame - create one and push it in. */
-                frame = ff_create_schro_frame(avccontext,
+                frame = ff_create_schro_frame(avctx,
                                               p_schro_params->frame_format);
                 schro_decoder_add_output_picture(decoder, frame);
                 break;
@@ -280,7 +281,7 @@
                     /* Add relation between schroframe and pts. */
                     framewithpts = av_malloc(sizeof(LibSchroFrameContext));
                     if (!framewithpts) {
-                        av_log(avccontext, AV_LOG_ERROR, "Unable to allocate FrameWithPts\n");
+                        av_log(avctx, AV_LOG_ERROR, "Unable to allocate FrameWithPts\n");
                         return AVERROR(ENOMEM);
                     }
                     framewithpts->frame = frame;
@@ -308,9 +309,9 @@
 
     if (framewithpts && framewithpts->frame) {
         if (p_schro_params->dec_frame.data[0])
-            avccontext->release_buffer(avccontext, &p_schro_params->dec_frame);
-        if (avccontext->get_buffer(avccontext, &p_schro_params->dec_frame) < 0) {
-            av_log(avccontext, AV_LOG_ERROR, "Unable to allocate buffer\n");
+            avctx->release_buffer(avctx, &p_schro_params->dec_frame);
+        if (ff_get_buffer(avctx, &p_schro_params->dec_frame) < 0) {
+            av_log(avctx, AV_LOG_ERROR, "Unable to allocate buffer\n");
             return AVERROR(ENOMEM);
         }
 
@@ -336,28 +337,28 @@
         p_schro_params->dec_frame.linesize[2] = framewithpts->frame->components[2].stride;
 
         *(AVFrame*)data = p_schro_params->dec_frame;
-        *data_size      = sizeof(AVFrame);
+        *got_frame      = 1;
 
         /* Now free the frame resources. */
         libschroedinger_decode_frame_free(framewithpts->frame);
         av_free(framewithpts);
     } else {
         data       = NULL;
-        *data_size = 0;
+        *got_frame = 0;
     }
     return buf_size;
 }
 
 
-static av_cold int libschroedinger_decode_close(AVCodecContext *avccontext)
+static av_cold int libschroedinger_decode_close(AVCodecContext *avctx)
 {
-    SchroDecoderParams *p_schro_params = avccontext->priv_data;
+    SchroDecoderParams *p_schro_params = avctx->priv_data;
     /* Free the decoder. */
     schro_decoder_free(p_schro_params->decoder);
     av_freep(&p_schro_params->format);
 
     if (p_schro_params->dec_frame.data[0])
-        avccontext->release_buffer(avccontext, &p_schro_params->dec_frame);
+        avctx->release_buffer(avctx, &p_schro_params->dec_frame);
 
     /* Free data in the output frame queue. */
     ff_schro_queue_free(&p_schro_params->dec_frame_queue,
@@ -366,11 +367,11 @@
     return 0;
 }
 
-static void libschroedinger_flush(AVCodecContext *avccontext)
+static void libschroedinger_flush(AVCodecContext *avctx)
 {
     /* Got a seek request. Free the decoded frames queue and then reset
      * the decoder */
-    SchroDecoderParams *p_schro_params = avccontext->priv_data;
+    SchroDecoderParams *p_schro_params = avctx->priv_data;
 
     /* Free data in the output frame queue. */
     ff_schro_queue_free(&p_schro_params->dec_frame_queue,
diff --git a/libavcodec/libschroedingerenc.c b/libavcodec/libschroedingerenc.c
index aed7818..297c6c5 100644
--- a/libavcodec/libschroedingerenc.c
+++ b/libavcodec/libschroedingerenc.c
@@ -77,33 +77,32 @@
 /**
 * Works out Schro-compatible chroma format.
 */
-static int set_chroma_format(AVCodecContext *avccontext)
+static int set_chroma_format(AVCodecContext *avctx)
 {
     int num_formats = sizeof(schro_pixel_format_map) /
                       sizeof(schro_pixel_format_map[0]);
     int idx;
 
-    SchroEncoderParams *p_schro_params = avccontext->priv_data;
+    SchroEncoderParams *p_schro_params = avctx->priv_data;
 
     for (idx = 0; idx < num_formats; ++idx) {
-        if (schro_pixel_format_map[idx].ff_pix_fmt ==
-            avccontext->pix_fmt) {
+        if (schro_pixel_format_map[idx].ff_pix_fmt == avctx->pix_fmt) {
             p_schro_params->format->chroma_format =
                             schro_pixel_format_map[idx].schro_pix_fmt;
             return 0;
         }
     }
 
-    av_log(avccontext, AV_LOG_ERROR,
+    av_log(avctx, AV_LOG_ERROR,
            "This codec currently only supports planar YUV 4:2:0, 4:2:2"
            " and 4:4:4 formats.\n");
 
     return -1;
 }
 
-static int libschroedinger_encode_init(AVCodecContext *avccontext)
+static int libschroedinger_encode_init(AVCodecContext *avctx)
 {
-    SchroEncoderParams *p_schro_params = avccontext->priv_data;
+    SchroEncoderParams *p_schro_params = avctx->priv_data;
     SchroVideoFormatEnum preset;
 
     /* Initialize the libraries that libschroedinger depends on. */
@@ -113,75 +112,75 @@
     p_schro_params->encoder = schro_encoder_new();
 
     if (!p_schro_params->encoder) {
-        av_log(avccontext, AV_LOG_ERROR,
+        av_log(avctx, AV_LOG_ERROR,
                "Unrecoverable Error: schro_encoder_new failed. ");
         return -1;
     }
 
     /* Initialize the format. */
-    preset = ff_get_schro_video_format_preset(avccontext);
+    preset = ff_get_schro_video_format_preset(avctx);
     p_schro_params->format =
                     schro_encoder_get_video_format(p_schro_params->encoder);
     schro_video_format_set_std_video_format(p_schro_params->format, preset);
-    p_schro_params->format->width  = avccontext->width;
-    p_schro_params->format->height = avccontext->height;
+    p_schro_params->format->width  = avctx->width;
+    p_schro_params->format->height = avctx->height;
 
-    if (set_chroma_format(avccontext) == -1)
+    if (set_chroma_format(avctx) == -1)
         return -1;
 
-    if (avccontext->color_primaries == AVCOL_PRI_BT709) {
+    if (avctx->color_primaries == AVCOL_PRI_BT709) {
         p_schro_params->format->colour_primaries = SCHRO_COLOUR_PRIMARY_HDTV;
-    } else if (avccontext->color_primaries == AVCOL_PRI_BT470BG) {
+    } else if (avctx->color_primaries == AVCOL_PRI_BT470BG) {
         p_schro_params->format->colour_primaries = SCHRO_COLOUR_PRIMARY_SDTV_625;
-    } else if (avccontext->color_primaries == AVCOL_PRI_SMPTE170M) {
+    } else if (avctx->color_primaries == AVCOL_PRI_SMPTE170M) {
         p_schro_params->format->colour_primaries = SCHRO_COLOUR_PRIMARY_SDTV_525;
     }
 
-    if (avccontext->colorspace == AVCOL_SPC_BT709) {
+    if (avctx->colorspace == AVCOL_SPC_BT709) {
         p_schro_params->format->colour_matrix = SCHRO_COLOUR_MATRIX_HDTV;
-    } else if (avccontext->colorspace == AVCOL_SPC_BT470BG) {
+    } else if (avctx->colorspace == AVCOL_SPC_BT470BG) {
         p_schro_params->format->colour_matrix = SCHRO_COLOUR_MATRIX_SDTV;
     }
 
-    if (avccontext->color_trc == AVCOL_TRC_BT709) {
+    if (avctx->color_trc == AVCOL_TRC_BT709) {
         p_schro_params->format->transfer_function = SCHRO_TRANSFER_CHAR_TV_GAMMA;
     }
 
     if (ff_get_schro_frame_format(p_schro_params->format->chroma_format,
                                   &p_schro_params->frame_format) == -1) {
-        av_log(avccontext, AV_LOG_ERROR,
+        av_log(avctx, AV_LOG_ERROR,
                "This codec currently supports only planar YUV 4:2:0, 4:2:2"
                " and 4:4:4 formats.\n");
         return -1;
     }
 
-    p_schro_params->format->frame_rate_numerator   = avccontext->time_base.den;
-    p_schro_params->format->frame_rate_denominator = avccontext->time_base.num;
+    p_schro_params->format->frame_rate_numerator   = avctx->time_base.den;
+    p_schro_params->format->frame_rate_denominator = avctx->time_base.num;
 
-    p_schro_params->frame_size = avpicture_get_size(avccontext->pix_fmt,
-                                                    avccontext->width,
-                                                    avccontext->height);
+    p_schro_params->frame_size = avpicture_get_size(avctx->pix_fmt,
+                                                    avctx->width,
+                                                    avctx->height);
 
-    avccontext->coded_frame = &p_schro_params->picture;
+    avctx->coded_frame = &p_schro_params->picture;
 
-    if (!avccontext->gop_size) {
+    if (!avctx->gop_size) {
         schro_encoder_setting_set_double(p_schro_params->encoder,
                                          "gop_structure",
                                          SCHRO_ENCODER_GOP_INTRA_ONLY);
 
-        if (avccontext->coder_type == FF_CODER_TYPE_VLC)
+        if (avctx->coder_type == FF_CODER_TYPE_VLC)
             schro_encoder_setting_set_double(p_schro_params->encoder,
                                              "enable_noarith", 1);
     } else {
         schro_encoder_setting_set_double(p_schro_params->encoder,
-                                         "au_distance", avccontext->gop_size);
-        avccontext->has_b_frames = 1;
+                                         "au_distance", avctx->gop_size);
+        avctx->has_b_frames = 1;
         p_schro_params->dts = -1;
     }
 
     /* FIXME - Need to handle SCHRO_ENCODER_RATE_CONTROL_LOW_DELAY. */
-    if (avccontext->flags & CODEC_FLAG_QSCALE) {
-        if (!avccontext->global_quality) {
+    if (avctx->flags & CODEC_FLAG_QSCALE) {
+        if (!avctx->global_quality) {
             /* lossless coding */
             schro_encoder_setting_set_double(p_schro_params->encoder,
                                              "rate_control",
@@ -192,7 +191,7 @@
                                              "rate_control",
                                              SCHRO_ENCODER_RATE_CONTROL_CONSTANT_QUALITY);
 
-            quality = avccontext->global_quality / FF_QP2LAMBDA;
+            quality = avctx->global_quality / FF_QP2LAMBDA;
             if (quality > 10)
                 quality = 10;
             schro_encoder_setting_set_double(p_schro_params->encoder,
@@ -204,19 +203,17 @@
                                          SCHRO_ENCODER_RATE_CONTROL_CONSTANT_BITRATE);
 
         schro_encoder_setting_set_double(p_schro_params->encoder,
-                                         "bitrate",
-                                         avccontext->bit_rate);
-
+                                         "bitrate", avctx->bit_rate);
     }
 
-    if (avccontext->flags & CODEC_FLAG_INTERLACED_ME)
+    if (avctx->flags & CODEC_FLAG_INTERLACED_ME)
         /* All material can be coded as interlaced or progressive
            irrespective of the type of source material. */
         schro_encoder_setting_set_double(p_schro_params->encoder,
                                          "interlaced_coding", 1);
 
     schro_encoder_setting_set_double(p_schro_params->encoder, "open_gop",
-                                     !(avccontext->flags & CODEC_FLAG_CLOSED_GOP));
+                                     !(avctx->flags & CODEC_FLAG_CLOSED_GOP));
 
     /* FIXME: Signal range hardcoded to 8-bit data until both libschroedinger
      * and libdirac support other bit-depth data. */
@@ -228,7 +225,7 @@
                                    p_schro_params->format);
 
     /* Set the debug level. */
-    schro_debug_set_level(avccontext->debug);
+    schro_debug_set_level(avctx->debug);
 
     schro_encoder_start(p_schro_params->encoder);
 
@@ -237,19 +234,19 @@
     return 0;
 }
 
-static SchroFrame *libschroedinger_frame_from_data(AVCodecContext *avccontext,
+static SchroFrame *libschroedinger_frame_from_data(AVCodecContext *avctx,
                                                    const AVFrame *frame)
 {
-    SchroEncoderParams *p_schro_params = avccontext->priv_data;
+    SchroEncoderParams *p_schro_params = avctx->priv_data;
     SchroFrame *in_frame;
     /* Input line size may differ from what the codec supports. Especially
      * when transcoding from one format to another. So use avpicture_layout
      * to copy the frame. */
-    in_frame = ff_create_schro_frame(avccontext, p_schro_params->frame_format);
+    in_frame = ff_create_schro_frame(avctx, p_schro_params->frame_format);
 
     if (in_frame)
-        avpicture_layout((const AVPicture *)frame, avccontext->pix_fmt,
-                          avccontext->width, avccontext->height,
+        avpicture_layout((const AVPicture *)frame, avctx->pix_fmt,
+                          avctx->width, avctx->height,
                           in_frame->components[0].data,
                           p_schro_params->frame_size);
 
@@ -264,11 +261,11 @@
     av_free(enc_frame);
 }
 
-static int libschroedinger_encode_frame(AVCodecContext *avccontext, AVPacket *pkt,
+static int libschroedinger_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                                         const AVFrame *frame, int *got_packet)
 {
     int enc_size = 0;
-    SchroEncoderParams *p_schro_params = avccontext->priv_data;
+    SchroEncoderParams *p_schro_params = avctx->priv_data;
     SchroEncoder *encoder = p_schro_params->encoder;
     struct FFSchroEncodedFrame *p_frame_output = NULL;
     int go = 1;
@@ -286,8 +283,7 @@
         }
     } else {
         /* Allocate frame data to schro input buffer. */
-        SchroFrame *in_frame = libschroedinger_frame_from_data(avccontext,
-                                                               frame);
+        SchroFrame *in_frame = libschroedinger_frame_from_data(avctx, frame);
         /* Load next frame. */
         schro_encoder_push_frame(encoder, in_frame);
     }
@@ -358,7 +354,7 @@
             break;
 
         default:
-            av_log(avccontext, AV_LOG_ERROR, "Unknown Schro Encoder state\n");
+            av_log(avctx, AV_LOG_ERROR, "Unknown Schro Encoder state\n");
             return -1;
         }
     }
@@ -377,16 +373,16 @@
     pkt_size = p_frame_output->size;
     if (last_frame_in_sequence && p_schro_params->enc_buf_size > 0)
         pkt_size += p_schro_params->enc_buf_size;
-    if ((ret = ff_alloc_packet2(avccontext, pkt, pkt_size)) < 0)
+    if ((ret = ff_alloc_packet2(avctx, pkt, pkt_size)) < 0)
         goto error;
 
     memcpy(pkt->data, p_frame_output->p_encbuf, p_frame_output->size);
-    avccontext->coded_frame->key_frame = p_frame_output->key_frame;
+    avctx->coded_frame->key_frame = p_frame_output->key_frame;
     /* Use the frame number of the encoded frame as the pts. It is OK to
      * do so since Dirac is a constant frame rate codec. It expects input
      * to be of constant frame rate. */
     pkt->pts =
-    avccontext->coded_frame->pts = p_frame_output->frame_num;
+    avctx->coded_frame->pts = p_frame_output->frame_num;
     pkt->dts = p_schro_params->dts++;
     enc_size = p_frame_output->size;
 
@@ -411,9 +407,9 @@
 }
 
 
-static int libschroedinger_encode_close(AVCodecContext *avccontext)
+static int libschroedinger_encode_close(AVCodecContext *avctx)
 {
-    SchroEncoderParams *p_schro_params = avccontext->priv_data;
+    SchroEncoderParams *p_schro_params = avctx->priv_data;
 
     /* Close the encoder. */
     schro_encoder_free(p_schro_params->encoder);
diff --git a/libavcodec/libspeexdec.c b/libavcodec/libspeexdec.c
index 935bebb..1b2db78 100644
--- a/libavcodec/libspeexdec.c
+++ b/libavcodec/libspeexdec.c
@@ -26,9 +26,9 @@
 #include "libavutil/channel_layout.h"
 #include "libavutil/common.h"
 #include "avcodec.h"
+#include "internal.h"
 
 typedef struct {
-    AVFrame frame;
     SpeexBits bits;
     SpeexStereoState stereo;
     void *dec_state;
@@ -103,9 +103,6 @@
         speex_decoder_ctl(s->dec_state, SPEEX_SET_HANDLER, &callback);
     }
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     return 0;
 }
 
@@ -115,23 +112,24 @@
     uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     LibSpeexContext *s = avctx->priv_data;
+    AVFrame *frame     = data;
     int16_t *output;
     int ret, consumed = 0;
 
     /* get output buffer */
-    s->frame.nb_samples = s->frame_size;
-    if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = s->frame_size;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    output = (int16_t *)s->frame.data[0];
+    output = (int16_t *)frame->data[0];
 
     /* if there is not enough data left for the smallest possible frame or the
        next 5 bits are a terminator code, reset the libspeex buffer using the
        current packet, otherwise ignore the current packet and keep decoding
        frames from the libspeex buffer. */
     if (speex_bits_remaining(&s->bits) < 5 ||
-        speex_bits_peek_unsigned(&s->bits, 5) == 0x1F) {
+        speex_bits_peek_unsigned(&s->bits, 5) == 0xF) {
         /* check for flush packet */
         if (!buf || !buf_size) {
             *got_frame_ptr = 0;
@@ -151,8 +149,7 @@
     if (avctx->channels == 2)
         speex_decode_stereo_int(output, s->frame_size, &s->stereo);
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
+    *got_frame_ptr = 1;
 
     return consumed;
 }
diff --git a/libavcodec/libspeexenc.c b/libavcodec/libspeexenc.c
index 7dfc6d3..23ebe72 100644
--- a/libavcodec/libspeexenc.c
+++ b/libavcodec/libspeexenc.c
@@ -288,7 +288,7 @@
             speex_encode_stereo_int(samples, s->header.frame_size, &s->bits);
         speex_encode_int(s->enc_state, samples, &s->bits);
         s->pkt_frame_count++;
-        if ((ret = ff_af_queue_add(&s->afq, frame) < 0))
+        if ((ret = ff_af_queue_add(&s->afq, frame)) < 0)
             return ret;
     } else {
         /* handle end-of-stream */
diff --git a/libavcodec/libstagefright.cpp b/libavcodec/libstagefright.cpp
index f741df9..4c270b0 100644
--- a/libavcodec/libstagefright.cpp
+++ b/libavcodec/libstagefright.cpp
@@ -185,7 +185,7 @@
                 buffer->release();
                 goto push_frame;
             }
-            ret = avctx->get_buffer(avctx, frame->vframe);
+            ret = ff_get_buffer(avctx, frame->vframe);
             if (ret < 0) {
                 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
                 frame->status = ret;
@@ -354,7 +354,7 @@
 }
 
 static int Stagefright_decode_frame(AVCodecContext *avctx, void *data,
-                                    int *data_size, AVPacket *avpkt)
+                                    int *got_frame, AVPacket *avpkt)
 {
     StagefrightContext *s = (StagefrightContext*)avctx->priv_data;
     Frame *frame;
@@ -463,7 +463,7 @@
     }
     s->prev_frame = ret_frame;
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*)data = *ret_frame;
     return orig_size;
 }
diff --git a/libavcodec/libtheoraenc.c b/libavcodec/libtheoraenc.c
index 5a86674..893370f 100644
--- a/libavcodec/libtheoraenc.c
+++ b/libavcodec/libtheoraenc.c
@@ -212,7 +212,7 @@
                 * 0 <= p <=63
                 * an int value
          */
-        t_info.quality        = av_clip(avc_context->global_quality / (float)FF_QP2LAMBDA, 0, 10) * 6.3;
+        t_info.quality        = av_clipf(avc_context->global_quality / (float)FF_QP2LAMBDA, 0, 10) * 6.3;
         t_info.target_bitrate = 0;
     } else {
         t_info.target_bitrate = avc_context->bit_rate;
@@ -341,7 +341,7 @@
     memcpy(pkt->data, o_packet.packet, o_packet.bytes);
 
     // HACK: assumes no encoder delay, this is true until libtheora becomes
-    // multithreaded (which will be disabled unless explictly requested)
+    // multithreaded (which will be disabled unless explicitly requested)
     pkt->pts = pkt->dts = frame->pts;
     avc_context->coded_frame->key_frame = !(o_packet.granulepos & h->keyframe_mask);
     if (avc_context->coded_frame->key_frame)
diff --git a/libavcodec/libutvideo.h b/libavcodec/libutvideo.h
index a9387e1..ac665b2 100644
--- a/libavcodec/libutvideo.h
+++ b/libavcodec/libutvideo.h
@@ -31,6 +31,16 @@
 #include <utvideo/utvideo.h>
 #include <utvideo/Codec.h>
 
+/* Ut Video version 12.0.0 removed the _WIN names, so if those are
+ * absent, redefine them to maintain compatibility with pre-v12 versions.*/
+#if !defined(UTVF_RGB24_WIN)
+#define UTVF_RGB24_WIN UTVF_NFCC_BGR_BU
+#endif
+
+#if !defined(UTVF_RGB32_WIN)
+#define UTVF_RGB32_WIN UTVF_NFCC_BGRA_BU
+#endif
+
 typedef struct {
     uint32_t version;
     uint32_t original_format;
diff --git a/libavcodec/libutvideodec.cpp b/libavcodec/libutvideodec.cpp
index f4ba8b3..f70ac4f 100644
--- a/libavcodec/libutvideodec.cpp
+++ b/libavcodec/libutvideodec.cpp
@@ -115,7 +115,7 @@
 }
 
 static int utvideo_decode_frame(AVCodecContext *avctx, void *data,
-                                int *data_size, AVPacket *avpkt)
+                                int *got_frame, AVPacket *avpkt)
 {
     UtVideoContext *utv = (UtVideoContext *)avctx->priv_data;
     AVFrame *pic = avctx->coded_frame;
@@ -150,7 +150,7 @@
         break;
     }
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame *)data = *pic;
 
     return avpkt->size;
diff --git a/libavcodec/libvo-aacenc.c b/libavcodec/libvo-aacenc.c
index a09c74c..1414aad 100644
--- a/libavcodec/libvo-aacenc.c
+++ b/libavcodec/libvo-aacenc.c
@@ -157,7 +157,7 @@
             samples = (VO_PBYTE)frame->data[0];
         }
         /* add current frame to the queue */
-        if ((ret = ff_af_queue_add(&s->afq, frame) < 0))
+        if ((ret = ff_af_queue_add(&s->afq, frame)) < 0)
             return ret;
     }
 
diff --git a/libavcodec/libvorbisdec.c b/libavcodec/libvorbisdec.c
index 93c65b8..99fb83a 100644
--- a/libavcodec/libvorbisdec.c
+++ b/libavcodec/libvorbisdec.c
@@ -22,9 +22,9 @@
 
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 
 typedef struct OggVorbisDecContext {
-    AVFrame frame;
     vorbis_info vi;                     /**< vorbis_info used during init   */
     vorbis_dsp_state vd;                /**< DSP state used for analysis    */
     vorbis_block vb;                    /**< vorbis_block used for analysis */
@@ -98,6 +98,7 @@
 
     avccontext->channels = context->vi.channels;
     avccontext->sample_rate = context->vi.rate;
+    avccontext->sample_fmt = AV_SAMPLE_FMT_S16;
     avccontext->time_base= (AVRational){1, avccontext->sample_rate};
 
     vorbis_synthesis_init(&context->vd, &context->vi);
@@ -129,6 +130,7 @@
                         int *got_frame_ptr, AVPacket *avpkt)
 {
     OggVorbisDecContext *context = avccontext->priv_data ;
+    AVFrame *frame = data;
     float **pcm ;
     ogg_packet *op= &context->op;
     int samples, total_samples, total_bytes;
@@ -140,12 +142,12 @@
         return 0;
     }
 
-    context->frame.nb_samples = 8192*4;
-    if ((ret = avccontext->get_buffer(avccontext, &context->frame)) < 0) {
+    frame->nb_samples = 8192*4;
+    if ((ret = ff_get_buffer(avccontext, frame)) < 0) {
         av_log(avccontext, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    output = (int16_t *)context->frame.data[0];
+    output = (int16_t *)frame->data[0];
 
 
     op->packet = avpkt->data;
@@ -170,9 +172,8 @@
         vorbis_synthesis_read(&context->vd, samples) ;
     }
 
-    context->frame.nb_samples = total_samples;
+    frame->nb_samples = total_samples;
     *got_frame_ptr   = 1;
-    *(AVFrame *)data = context->frame;
     return avpkt->size;
 }
 
diff --git a/libavcodec/libvorbisenc.c b/libavcodec/libvorbisenc.c
index c81375c..188c8cc 100644
--- a/libavcodec/libvorbisenc.c
+++ b/libavcodec/libvorbisenc.c
@@ -305,7 +305,7 @@
             av_log(avctx, AV_LOG_ERROR, "error in vorbis_analysis_wrote()\n");
             return vorbis_error_to_averror(ret);
         }
-        if ((ret = ff_af_queue_add(&s->afq, frame) < 0))
+        if ((ret = ff_af_queue_add(&s->afq, frame)) < 0)
             return ret;
     } else {
         if (!s->eof)
diff --git a/libavcodec/libvpxdec.c b/libavcodec/libvpxdec.c
index 61dbaa7..7e41e80 100644
--- a/libavcodec/libvpxdec.c
+++ b/libavcodec/libvpxdec.c
@@ -35,10 +35,10 @@
     struct vpx_codec_ctx decoder;
 } VP8Context;
 
-static av_cold int vp8_init(AVCodecContext *avctx)
+static av_cold int vpx_init(AVCodecContext *avctx,
+                            const struct vpx_codec_iface *iface)
 {
     VP8Context *ctx = avctx->priv_data;
-    const struct vpx_codec_iface *iface = &vpx_codec_vp8_dx_algo;
     struct vpx_codec_dec_cfg deccfg = {
         /* token partitions+1 would be a decent choice */
         .threads = FFMIN(avctx->thread_count, 16)
@@ -59,7 +59,7 @@
 }
 
 static int vp8_decode(AVCodecContext *avctx,
-                      void *data, int *data_size, AVPacket *avpkt)
+                      void *data, int *got_frame, AVPacket *avpkt)
 {
     VP8Context *ctx = avctx->priv_data;
     AVFrame *picture = data;
@@ -100,7 +100,7 @@
         picture->linesize[1] = img->stride[1];
         picture->linesize[2] = img->stride[2];
         picture->linesize[3] = 0;
-        *data_size           = sizeof(AVPicture);
+        *got_frame           = 1;
     }
     return avpkt->size;
 }
@@ -112,7 +112,13 @@
     return 0;
 }
 
-AVCodec ff_libvpx_decoder = {
+#if CONFIG_LIBVPX_VP8_DECODER
+static av_cold int vp8_init(AVCodecContext *avctx)
+{
+    return vpx_init(avctx, &vpx_codec_vp8_dx_algo);
+}
+
+AVCodec ff_libvpx_vp8_decoder = {
     .name           = "libvpx",
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_VP8,
@@ -123,3 +129,23 @@
     .capabilities   = CODEC_CAP_AUTO_THREADS,
     .long_name      = NULL_IF_CONFIG_SMALL("libvpx VP8"),
 };
+#endif /* CONFIG_LIBVPX_VP8_DECODER */
+
+#if CONFIG_LIBVPX_VP9_DECODER
+static av_cold int vp9_init(AVCodecContext *avctx)
+{
+    return vpx_init(avctx, &vpx_codec_vp9_dx_algo);
+}
+
+AVCodec ff_libvpx_vp9_decoder = {
+    .name           = "libvpx-vp9",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_VP9,
+    .priv_data_size = sizeof(VP8Context),
+    .init           = vp9_init,
+    .close          = vp8_free,
+    .decode         = vp8_decode,
+    .capabilities   = CODEC_CAP_AUTO_THREADS | CODEC_CAP_EXPERIMENTAL,
+    .long_name      = NULL_IF_CONFIG_SMALL("libvpx VP9"),
+};
+#endif /* CONFIG_LIBVPX_VP9_DECODER */
diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c
index 320f5f8..4f1adb8 100644
--- a/libavcodec/libvpxenc.c
+++ b/libavcodec/libvpxenc.c
@@ -48,6 +48,9 @@
     unsigned long duration;          /**< duration to show frame
                                           (in timebase units) */
     uint32_t flags;                  /**< flags for this frame */
+    uint64_t sse[4];
+    int have_sse;                    /**< true if we have pending sse[] */
+    uint64_t frame_number;
     struct FrameListData *next;
 };
 
@@ -57,6 +60,9 @@
     struct vpx_image rawimg;
     struct vpx_fixed_buf twopass_stats;
     int deadline; //i.e., RT/GOOD/BEST
+    uint64_t sse[4];
+    int have_sse; /**< true if we have pending sse[] */
+    uint64_t frame_number;
     struct FrameListData *coded_frame_list;
 
     int cpu_used;
@@ -227,11 +233,12 @@
     return 0;
 }
 
-static av_cold int vp8_init(AVCodecContext *avctx)
+static av_cold int vpx_init(AVCodecContext *avctx,
+                            const struct vpx_codec_iface *iface)
 {
     VP8Context *ctx = avctx->priv_data;
-    const struct vpx_codec_iface *iface = &vpx_codec_vp8_cx_algo;
     struct vpx_codec_enc_cfg enccfg;
+    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());
@@ -285,10 +292,20 @@
         }
     }
 
-    if (avctx->qmin > 0)
+    if (avctx->qmin >= 0)
         enccfg.rc_min_quantizer = avctx->qmin;
     if (avctx->qmax > 0)
         enccfg.rc_max_quantizer = avctx->qmax;
+
+    if (enccfg.rc_end_usage == VPX_CQ) {
+        if (ctx->crf < enccfg.rc_min_quantizer || ctx->crf > enccfg.rc_max_quantizer) {
+                av_log(avctx, AV_LOG_ERROR,
+                       "CQ level must be between minimum and maximum quantizer value (%d-%d)\n",
+                       enccfg.rc_min_quantizer, enccfg.rc_max_quantizer);
+                return AVERROR(EINVAL);
+        }
+    }
+
     enccfg.rc_dropframe_thresh = avctx->frame_skip_threshold;
 
     //0-100 (0 => CBR, 100 => VBR)
@@ -354,7 +371,7 @@
 
     dump_enc_cfg(avctx, &enccfg);
     /* Construct Encoder Context */
-    res = vpx_codec_enc_init(&ctx->encoder, iface, &enccfg, 0);
+    res = vpx_codec_enc_init(&ctx->encoder, iface, &enccfg, flags);
     if (res != VPX_CODEC_OK) {
         log_encoder_error(avctx, "Failed to initialize encoder");
         return AVERROR(EINVAL);
@@ -397,13 +414,30 @@
 }
 
 static inline void cx_pktcpy(struct FrameListData *dst,
-                             const struct vpx_codec_cx_pkt *src)
+                             const struct vpx_codec_cx_pkt *src,
+                             VP8Context *ctx)
 {
     dst->pts      = src->data.frame.pts;
     dst->duration = src->data.frame.duration;
     dst->flags    = src->data.frame.flags;
     dst->sz       = src->data.frame.sz;
     dst->buf      = src->data.frame.buf;
+    dst->have_sse = 0;
+    /* For alt-ref frame, don't store PSNR or increment frame_number */
+    if (!(dst->flags & VPX_FRAME_IS_INVISIBLE)) {
+        dst->frame_number = ++ctx->frame_number;
+        dst->have_sse = ctx->have_sse;
+        if (ctx->have_sse) {
+            /* associate last-seen SSE to the frame. */
+            /* Transfers ownership from ctx to dst. */
+            /* WARNING! This makes the assumption that PSNR_PKT comes
+               just before the frame it refers to! */
+            memcpy(dst->sse, ctx->sse, sizeof(dst->sse));
+            ctx->have_sse = 0;
+        }
+    } else {
+        dst->frame_number = -1;   /* sanity marker */
+    }
 }
 
 /**
@@ -428,6 +462,19 @@
             pkt->flags            |= AV_PKT_FLAG_KEY;
         } else
             coded_frame->pict_type = AV_PICTURE_TYPE_P;
+
+        if (cx_frame->have_sse) {
+            int i;
+            /* Beware of the Y/U/V/all order! */
+            coded_frame->error[0] = cx_frame->sse[1];
+            coded_frame->error[1] = cx_frame->sse[2];
+            coded_frame->error[2] = cx_frame->sse[3];
+            coded_frame->error[3] = 0;    // alpha
+            for (i = 0; i < 4; ++i) {
+                avctx->error[i] += coded_frame->error[i];
+            }
+            cx_frame->have_sse = 0;
+        }
     } else {
         return ret;
     }
@@ -471,7 +518,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);
+                cx_pktcpy(&cx_frame, pkt, ctx);
                 size = storeframe(avctx, &cx_frame, pkt_out, coded_frame);
                 if (size < 0)
                     return size;
@@ -484,7 +531,7 @@
                            "Frame queue element alloc failed\n");
                     return AVERROR(ENOMEM);
                 }
-                cx_pktcpy(cx_frame, pkt);
+                cx_pktcpy(cx_frame, pkt, ctx);
                 cx_frame->buf = av_malloc(cx_frame->sz);
 
                 if (!cx_frame->buf) {
@@ -511,7 +558,14 @@
             stats->sz += pkt->data.twopass_stats.sz;
             break;
         }
-        case VPX_CODEC_PSNR_PKT: //FIXME add support for CODEC_FLAG_PSNR
+        case VPX_CODEC_PSNR_PKT:
+            av_assert0(!ctx->have_sse);
+            ctx->sse[0] = pkt->data.psnr.sse[0];
+            ctx->sse[1] = pkt->data.psnr.sse[1];
+            ctx->sse[2] = pkt->data.psnr.sse[2];
+            ctx->sse[3] = pkt->data.psnr.sse[3];
+            ctx->have_sse = 1;
+            break;
         case VPX_CODEC_CUSTOM_PKT:
             //ignore unsupported/unrecognized packet types
             break;
@@ -527,8 +581,8 @@
     VP8Context *ctx = avctx->priv_data;
     struct vpx_image *rawimg = NULL;
     int64_t timestamp = 0;
-    long flags = 0;
     int res, coded_size;
+    vpx_enc_frame_flags_t flags = 0;
 
     if (frame) {
         rawimg                      = &ctx->rawimg;
@@ -539,7 +593,8 @@
         rawimg->stride[VPX_PLANE_U] = frame->linesize[1];
         rawimg->stride[VPX_PLANE_V] = frame->linesize[2];
         timestamp                   = frame->pts;
-        flags                       = frame->pict_type == AV_PICTURE_TYPE_I ? VPX_EFLAG_FORCE_KF : 0;
+        if (frame->pict_type == AV_PICTURE_TYPE_I)
+            flags |= VPX_EFLAG_FORCE_KF;
     }
 
     res = vpx_codec_encode(&ctx->encoder, rawimg, timestamp,
@@ -607,13 +662,6 @@
     { NULL }
 };
 
-static const AVClass class = {
-    .class_name = "libvpx encoder",
-    .item_name  = av_default_item_name,
-    .option     = options,
-    .version    = LIBAVUTIL_VERSION_INT,
-};
-
 static const AVCodecDefault defaults[] = {
     { "qmin",             "-1" },
     { "qmax",             "-1" },
@@ -622,7 +670,20 @@
     { NULL },
 };
 
-AVCodec ff_libvpx_encoder = {
+#if CONFIG_LIBVPX_VP8_ENCODER
+static av_cold int vp8_init(AVCodecContext *avctx)
+{
+    return vpx_init(avctx, &vpx_codec_vp8_cx_algo);
+}
+
+static const AVClass class_vp8 = {
+    .class_name = "libvpx encoder",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+AVCodec ff_libvpx_vp8_encoder = {
     .name           = "libvpx",
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_VP8,
@@ -633,6 +694,36 @@
     .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("libvpx VP8"),
-    .priv_class     = &class,
+    .priv_class     = &class_vp8,
     .defaults       = defaults,
 };
+#endif /* CONFIG_LIBVPX_VP8_ENCODER */
+
+#if CONFIG_LIBVPX_VP9_ENCODER
+static av_cold int vp9_init(AVCodecContext *avctx)
+{
+    return vpx_init(avctx, &vpx_codec_vp9_cx_algo);
+}
+
+static const AVClass class_vp9 = {
+    .class_name = "libvpx encoder",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+AVCodec ff_libvpx_vp9_encoder = {
+    .name           = "libvpx-vp9",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_VP9,
+    .priv_data_size = sizeof(VP8Context),
+    .init           = vp9_init,
+    .encode2        = vp8_encode,
+    .close          = vp8_free,
+    .capabilities   = CODEC_CAP_DELAY | CODEC_CAP_AUTO_THREADS | CODEC_CAP_EXPERIMENTAL,
+    .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
+    .long_name      = NULL_IF_CONFIG_SMALL("libvpx VP9"),
+    .priv_class     = &class_vp9,
+    .defaults       = defaults,
+};
+#endif /* CONFIG_LIBVPX_VP9_ENCODER */
diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
index 8765e56..a394213 100644
--- a/libavcodec/libx264.c
+++ b/libavcodec/libx264.c
@@ -73,6 +73,7 @@
     int slice_max_size;
     char *stats;
     int nal_hrd;
+    char *x264_params;
 } X264Context;
 
 static void X264_log(void *p, int level, const char *fmt, va_list args)
@@ -285,7 +286,6 @@
 
     x4->params.b_deblocking_filter         = avctx->flags & CODEC_FLAG_LOOP_FILTER;
 
-    x4->params.rc.f_ip_factor             = 1 / fabs(avctx->i_quant_factor);
     x4->params.rc.f_pb_factor             = avctx->b_quant_factor;
     x4->params.analyse.i_chroma_qp_offset = avctx->chromaoffset;
     if (x4->preset || x4->tune)
@@ -335,7 +335,7 @@
             x4->params.rc.f_rf_constant_max = x4->crf_max;
     }
 
-    if (avctx->rc_buffer_size && avctx->rc_initial_buffer_occupancy &&
+    if (avctx->rc_buffer_size && avctx->rc_initial_buffer_occupancy > 0 &&
         (avctx->rc_initial_buffer_occupancy <= avctx->rc_buffer_size)) {
         x4->params.rc.f_vbv_buffer_init =
             (float)avctx->rc_initial_buffer_occupancy / avctx->rc_buffer_size;
@@ -356,6 +356,9 @@
         }
     }
 
+    if (avctx->i_quant_factor > 0)
+        x4->params.rc.f_ip_factor         = 1 / fabs(avctx->i_quant_factor);
+
     if (avctx->me_method == ME_EPZS)
         x4->params.analyse.i_me_method = X264_ME_DIA;
     else if (avctx->me_method == ME_HEX)
@@ -522,6 +525,22 @@
     if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER)
         x4->params.b_repeat_headers = 0;
 
+    if (x4->x264_params) {
+        AVDictionary *dict    = NULL;
+        AVDictionaryEntry *en = NULL;
+
+        if (!av_dict_parse_string(&dict, x4->x264_params, "=", ":", 0)) {
+            while ((en = av_dict_get(dict, "", en, AV_DICT_IGNORE_SUFFIX))) {
+                if (x264_param_parse(&x4->params, en->key, en->value) < 0)
+                    av_log(avctx, AV_LOG_WARNING,
+                           "Error parsing option '%s = %s'.\n",
+                            en->key, en->value);
+            }
+
+            av_dict_free(&dict);
+        }
+    }
+
     // update AVCodecContext with x264 parameters
     avctx->has_b_frames = x4->params.i_bframe ?
         x4->params.i_bframe_pyramid ? 2 : 1 : 0;
@@ -653,6 +672,7 @@
     { "none",          NULL, 0, AV_OPT_TYPE_CONST, {.i64 = X264_NAL_HRD_NONE}, INT_MIN, INT_MAX, VE, "nal-hrd" },
     { "vbr",           NULL, 0, AV_OPT_TYPE_CONST, {.i64 = X264_NAL_HRD_VBR},  INT_MIN, INT_MAX, VE, "nal-hrd" },
     { "cbr",           NULL, 0, AV_OPT_TYPE_CONST, {.i64 = X264_NAL_HRD_CBR},  INT_MIN, INT_MAX, VE, "nal-hrd" },
+    { "x264-params",  "Override the x264 configuration using a :-separated list of key=value parameters", OFFSET(x264_params), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE },
     { NULL },
 };
 
@@ -675,6 +695,7 @@
     { "bf",               "-1" },
     { "flags2",           "0" },
     { "g",                "-1" },
+    { "i_qfactor",        "-1" },
     { "qmin",             "-1" },
     { "qmax",             "-1" },
     { "qdiff",            "-1" },
@@ -695,6 +716,7 @@
     { "threads",          AV_STRINGIFY(X264_THREADS_AUTO) },
     { "thread_type",      "0" },
     { "flags",            "+cgop" },
+    { "rc_init_occupancy","-1" },
     { NULL },
 };
 
diff --git a/libavcodec/libxvid_rc.c b/libavcodec/libxvid_rc.c
index 93aeb71..4a5842f 100644
--- a/libavcodec/libxvid_rc.c
+++ b/libavcodec/libxvid_rc.c
@@ -26,7 +26,6 @@
 #include "libavutil/file.h"
 #include "avcodec.h"
 #include "libxvid.h"
-//#include "dsputil.h"
 #include "mpegvideo.h"
 
 #undef NDEBUG
diff --git a/libavcodec/ljpegenc.c b/libavcodec/ljpegenc.c
index d3c2921..064b911 100644
--- a/libavcodec/ljpegenc.c
+++ b/libavcodec/ljpegenc.c
@@ -31,7 +31,6 @@
  */
 
 #include "avcodec.h"
-#include "dsputil.h"
 #include "internal.h"
 #include "mpegvideo.h"
 #include "mjpeg.h"
@@ -57,6 +56,13 @@
         max_pkt_size += mb_width * mb_height * 3 * 4
                         * s->mjpeg_hsample[0] * s->mjpeg_vsample[0];
     }
+
+    if (!s->edge_emu_buffer &&
+        (ret = ff_mpv_frame_size_alloc(s, pict->linesize[0])) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "failed to allocate context scratch buffers.\n");
+        return ret;
+    }
+
     if ((ret = ff_alloc_packet2(avctx, pkt, max_pkt_size)) < 0)
         return ret;
 
diff --git a/libavcodec/loco.c b/libavcodec/loco.c
index 53bdb58..2b71166 100644
--- a/libavcodec/loco.c
+++ b/libavcodec/loco.c
@@ -27,31 +27,42 @@
 #include "avcodec.h"
 #include "get_bits.h"
 #include "golomb.h"
+#include "internal.h"
 #include "mathops.h"
 
-enum LOCO_MODE {LOCO_UNKN=0, LOCO_CYUY2=-1, LOCO_CRGB=-2, LOCO_CRGBA=-3, LOCO_CYV12=-4,
- LOCO_YUY2=1, LOCO_UYVY=2, LOCO_RGB=3, LOCO_RGBA=4, LOCO_YV12=5};
+enum LOCO_MODE {
+    LOCO_UNKN  =  0,
+    LOCO_CYUY2 = -1,
+    LOCO_CRGB  = -2,
+    LOCO_CRGBA = -3,
+    LOCO_CYV12 = -4,
+    LOCO_YUY2  =  1,
+    LOCO_UYVY  =  2,
+    LOCO_RGB   =  3,
+    LOCO_RGBA  =  4,
+    LOCO_YV12  =  5,
+};
 
-typedef struct LOCOContext{
+typedef struct LOCOContext {
     AVCodecContext *avctx;
     AVFrame pic;
     int lossy;
     int mode;
 } LOCOContext;
 
-typedef struct RICEContext{
+typedef struct RICEContext {
     GetBitContext gb;
     int save, run, run2; /* internal rice decoder state */
     int sum, count; /* sum and count for getting rice parameter */
     int lossy;
-}RICEContext;
+} RICEContext;
 
 static int loco_get_rice_param(RICEContext *r)
 {
     int cnt = 0;
     int val = r->count;
 
-    while(r->sum > val && cnt < 9) {
+    while (r->sum > val && cnt < 9) {
         val <<= 1;
         cnt++;
     }
@@ -64,8 +75,8 @@
     r->sum += val;
     r->count++;
 
-    if(r->count == 16) {
-        r->sum >>= 1;
+    if (r->count == 16) {
+        r->sum   >>= 1;
         r->count >>= 1;
     }
 }
@@ -79,19 +90,18 @@
         return 0;
     }
     v = get_ur_golomb_jpegls(&r->gb, loco_get_rice_param(r), INT_MAX, 0);
-    loco_update_rice_param(r, (v+1)>>1);
+    loco_update_rice_param(r, (v + 1) >> 1);
     if (!v) {
         if (r->save >= 0) {
             r->run = get_ur_golomb_jpegls(&r->gb, 2, INT_MAX, 0);
-            if(r->run > 1)
+            if (r->run > 1)
                 r->save += r->run + 1;
             else
                 r->save -= 3;
-        }
-        else
+        } else
             r->run2++;
     } else {
-        v = ((v>>1) + r->lossy) ^ -(v&1);
+        v = ((v >> 1) + r->lossy) ^ -(v & 1);
         if (r->run2 > 0) {
             if (r->run2 > 2)
                 r->save += r->run2;
@@ -127,16 +137,16 @@
         return -1;
 
     init_get_bits(&rc.gb, buf, buf_size*8);
-    rc.save = 0;
-    rc.run = 0;
-    rc.run2 = 0;
+    rc.save  = 0;
+    rc.run   = 0;
+    rc.run2  = 0;
     rc.lossy = l->lossy;
 
-    rc.sum = 8;
+    rc.sum   = 8;
     rc.count = 1;
 
     /* restore top left pixel */
-    val = loco_get_rice(&rc);
+    val     = loco_get_rice(&rc);
     data[0] = 128 + val;
     /* restore top line */
     for (i = 1; i < width; i++) {
@@ -160,27 +170,27 @@
 }
 
 static int decode_frame(AVCodecContext *avctx,
-                        void *data, int *data_size,
+                        void *data, int *got_frame,
                         AVPacket *avpkt)
 {
-    const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
     LOCOContext * const l = avctx->priv_data;
-    AVFrame * const p = &l->pic;
-    int decoded;
+    const uint8_t *buf    = avpkt->data;
+    int buf_size          = avpkt->size;
+    AVFrame * const p     = &l->pic;
+    int decoded, ret;
 
-    if(p->data[0])
+    if (p->data[0])
         avctx->release_buffer(avctx, p);
 
     p->reference = 0;
-    if(avctx->get_buffer(avctx, p) < 0){
+    if ((ret = ff_get_buffer(avctx, p)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
     p->key_frame = 1;
 
 #define ADVANCE_BY_DECODED do { \
-    if (decoded < 0) goto stop; \
+    if (decoded < 0 || decoded >= buf_size) goto buf_too_small; \
     buf += decoded; buf_size -= decoded; \
 } while(0)
     switch(l->mode) {
@@ -214,29 +224,39 @@
         decoded = loco_decode_plane(l, p->data[0] + p->linesize[0]*(avctx->height-1) + 2, avctx->width, avctx->height,
                                     -p->linesize[0], buf, buf_size, 3);
         break;
-    case LOCO_CRGBA: case LOCO_RGBA:
-        decoded = loco_decode_plane(l, p->data[0], avctx->width, avctx->height,
-                                    p->linesize[0], buf, buf_size, 4);
+    case LOCO_CRGBA:
+    case LOCO_RGBA:
+        decoded = loco_decode_plane(l, p->data[0] + p->linesize[0]*(avctx->height-1), avctx->width, avctx->height,
+                                    -p->linesize[0], buf, buf_size, 4);
         ADVANCE_BY_DECODED;
-        decoded = loco_decode_plane(l, p->data[0] + 1, avctx->width, avctx->height,
-                                    p->linesize[0], buf, buf_size, 4);
+        decoded = loco_decode_plane(l, p->data[0] + p->linesize[0]*(avctx->height-1) + 1, avctx->width, avctx->height,
+                                    -p->linesize[0], buf, buf_size, 4);
         ADVANCE_BY_DECODED;
-        decoded = loco_decode_plane(l, p->data[0] + 2, avctx->width, avctx->height,
-                                    p->linesize[0], buf, buf_size, 4);
+        decoded = loco_decode_plane(l, p->data[0] + p->linesize[0]*(avctx->height-1) + 2, avctx->width, avctx->height,
+                                    -p->linesize[0], buf, buf_size, 4);
         ADVANCE_BY_DECODED;
-        decoded = loco_decode_plane(l, p->data[0] + 3, avctx->width, avctx->height,
-                                    p->linesize[0], buf, buf_size, 4);
+        decoded = loco_decode_plane(l, p->data[0] + p->linesize[0]*(avctx->height-1) + 3, avctx->width, avctx->height,
+                                    -p->linesize[0], buf, buf_size, 4);
         break;
+    default:
+        av_assert0(0);
     }
-stop:
 
-    *data_size = sizeof(AVFrame);
+    if (decoded < 0 || decoded > buf_size)
+        goto buf_too_small;
+    buf_size -= decoded;
+
+    *got_frame      = 1;
     *(AVFrame*)data = l->pic;
 
-    return buf_size < 0 ? -1 : avpkt->size - buf_size;
+    return avpkt->size - buf_size;
+buf_too_small:
+    av_log(avctx, AV_LOG_ERROR, "Input data too small.\n");
+    return AVERROR(EINVAL);
 }
 
-static av_cold int decode_init(AVCodecContext *avctx){
+static av_cold int decode_init(AVCodecContext *avctx)
+{
     LOCOContext * const l = avctx->priv_data;
     int version;
 
@@ -244,10 +264,10 @@
     if (avctx->extradata_size < 12) {
         av_log(avctx, AV_LOG_ERROR, "Extradata size must be >= 12 instead of %i\n",
                avctx->extradata_size);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     version = AV_RL32(avctx->extradata);
-    switch(version) {
+    switch (version) {
     case 1:
         l->lossy = 0;
         break;
@@ -260,24 +280,29 @@
     }
 
     l->mode = AV_RL32(avctx->extradata + 4);
-    switch(l->mode) {
-    case LOCO_CYUY2: case LOCO_YUY2: case LOCO_UYVY:
+    switch (l->mode) {
+    case LOCO_CYUY2:
+    case LOCO_YUY2:
+    case LOCO_UYVY:
         avctx->pix_fmt = AV_PIX_FMT_YUV422P;
         break;
-    case LOCO_CRGB: case LOCO_RGB:
+    case LOCO_CRGB:
+    case LOCO_RGB:
         avctx->pix_fmt = AV_PIX_FMT_BGR24;
         break;
-    case LOCO_CYV12: case LOCO_YV12:
+    case LOCO_CYV12:
+    case LOCO_YV12:
         avctx->pix_fmt = AV_PIX_FMT_YUV420P;
         break;
-    case LOCO_CRGBA: case LOCO_RGBA:
-        avctx->pix_fmt = AV_PIX_FMT_RGB32;
+    case LOCO_CRGBA:
+    case LOCO_RGBA:
+        avctx->pix_fmt = AV_PIX_FMT_BGRA;
         break;
     default:
         av_log(avctx, AV_LOG_INFO, "Unknown colorspace, index = %i\n", l->mode);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
-    if(avctx->debug & FF_DEBUG_PICT_INFO)
+    if (avctx->debug & FF_DEBUG_PICT_INFO)
         av_log(avctx, AV_LOG_INFO, "lossy:%i, version:%i, mode: %i\n", l->lossy, version, l->mode);
 
     avcodec_get_frame_defaults(&l->pic);
@@ -285,7 +310,8 @@
     return 0;
 }
 
-static av_cold int decode_end(AVCodecContext *avctx){
+static av_cold int decode_end(AVCodecContext *avctx)
+{
     LOCOContext * const l = avctx->priv_data;
     AVFrame *pic = &l->pic;
 
diff --git a/libavcodec/lpc.c b/libavcodec/lpc.c
index 019689a..4149135 100644
--- a/libavcodec/lpc.c
+++ b/libavcodec/lpc.c
@@ -207,7 +207,7 @@
             lpc_passes = 2;
 
         for(pass=0; pass<lpc_passes; pass++){
-            av_init_lls(&m[pass&1], max_order);
+            avpriv_init_lls(&m[pass&1], max_order);
 
             weight=0;
             for(i=max_order; i<blocksize; i++){
@@ -216,7 +216,7 @@
 
                 if(pass){
                     double eval, inv, rinv;
-                    eval= av_evaluate_lls(&m[(pass-1)&1], var+1, max_order-1);
+                    eval= avpriv_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,9 +226,9 @@
                 }else
                     weight++;
 
-                av_update_lls(&m[pass&1], var, 1.0);
+                avpriv_update_lls(&m[pass&1], var, 1.0);
             }
-            av_solve_lls(&m[pass&1], 0.001, 0);
+            avpriv_solve_lls(&m[pass&1], 0.001, 0);
         }
 
         for(i=0; i<max_order; i++){
diff --git a/libavcodec/lpc.h b/libavcodec/lpc.h
index 24f776a..8fa56ad 100644
--- a/libavcodec/lpc.h
+++ b/libavcodec/lpc.h
@@ -24,7 +24,6 @@
 
 #include <stdint.h>
 #include "libavutil/avassert.h"
-#include "dsputil.h"
 
 #define ORDER_METHOD_EST     0
 #define ORDER_METHOD_2LEVEL  1
diff --git a/libavcodec/lzw.c b/libavcodec/lzw.c
index 97f6e6a..43e3e05 100644
--- a/libavcodec/lzw.c
+++ b/libavcodec/lzw.c
@@ -92,11 +92,6 @@
     return c & s->curmask;
 }
 
-const uint8_t* ff_lzw_cur_ptr(LZWState *p)
-{
-    return ((struct LZWState*)p)->pbuf;
-}
-
 void ff_lzw_decode_tail(LZWState *p)
 {
     struct LZWState *s = (struct LZWState *)p;
diff --git a/libavcodec/lzw.h b/libavcodec/lzw.h
index 115ca4e..4653c1c 100644
--- a/libavcodec/lzw.h
+++ b/libavcodec/lzw.h
@@ -47,7 +47,6 @@
 void ff_lzw_decode_close(LZWState **p);
 int ff_lzw_decode_init(LZWState *s, int csize, const uint8_t *buf, int buf_size, int mode);
 int ff_lzw_decode(LZWState *s, uint8_t *buf, int len);
-const uint8_t* ff_lzw_cur_ptr(LZWState *lzw);
 void ff_lzw_decode_tail(LZWState *lzw);
 
 /** LZW encode state */
diff --git a/libavcodec/mace.c b/libavcodec/mace.c
index c76f486..e78c49f 100644
--- a/libavcodec/mace.c
+++ b/libavcodec/mace.c
@@ -25,6 +25,7 @@
  */
 
 #include "avcodec.h"
+#include "internal.h"
 #include "libavutil/common.h"
 
 /*
@@ -154,7 +155,6 @@
 } ChannelData;
 
 typedef struct MACEContext {
-    AVFrame frame;
     ChannelData chd[2];
 } MACEContext;
 
@@ -226,21 +226,17 @@
 
 static av_cold int mace_decode_init(AVCodecContext * avctx)
 {
-    MACEContext *ctx = avctx->priv_data;
-
     if (avctx->channels > 2 || avctx->channels <= 0)
         return -1;
     avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
 
-    avcodec_get_frame_defaults(&ctx->frame);
-    avctx->coded_frame = &ctx->frame;
-
     return 0;
 }
 
 static int mace_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;
     int16_t **samples;
@@ -249,12 +245,12 @@
     int is_mace3 = (avctx->codec_id == AV_CODEC_ID_MACE3);
 
     /* get output buffer */
-    ctx->frame.nb_samples = 3 * (buf_size << (1 - is_mace3)) / avctx->channels;
-    if ((ret = avctx->get_buffer(avctx, &ctx->frame)) < 0) {
+    frame->nb_samples = 3 * (buf_size << (1 - is_mace3)) / avctx->channels;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    samples = (int16_t **)ctx->frame.extended_data;
+    samples = (int16_t **)frame->extended_data;
 
     for(i = 0; i < avctx->channels; i++) {
         int16_t *output = samples[i];
@@ -278,8 +274,7 @@
             }
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = ctx->frame;
+    *got_frame_ptr = 1;
 
     return buf_size;
 }
diff --git a/libavcodec/mdec.c b/libavcodec/mdec.c
index 52b9040..7e59c34 100644
--- a/libavcodec/mdec.c
+++ b/libavcodec/mdec.c
@@ -28,12 +28,11 @@
  */
 
 #include "avcodec.h"
-#include "dsputil.h"
 #include "mpegvideo.h"
 #include "mpeg12.h"
 #include "thread.h"
 
-typedef struct MDECContext{
+typedef struct MDECContext {
     AVCodecContext *avctx;
     DSPContext dsp;
     AVFrame picture;
@@ -45,48 +44,48 @@
     int mb_width;
     int mb_height;
     int mb_x, mb_y;
-    DECLARE_ALIGNED(16, DCTELEM, block)[6][64];
+    DECLARE_ALIGNED(16, int16_t, block)[6][64];
     uint8_t *bitstream_buffer;
     unsigned int bitstream_buffer_size;
     int block_last_index[6];
 } MDECContext;
 
 //very similar to MPEG-1
-static inline int mdec_decode_block_intra(MDECContext *a, DCTELEM *block, int n)
+static inline int mdec_decode_block_intra(MDECContext *a, int16_t *block, int n)
 {
     int level, diff, i, j, run;
     int component;
     RLTable *rl = &ff_rl_mpeg1;
-    uint8_t * const scantable= a->scantable.permutated;
-    const uint16_t *quant_matrix= ff_mpeg1_default_intra_matrix;
-    const int qscale= a->qscale;
+    uint8_t * const scantable = a->scantable.permutated;
+    const uint16_t *quant_matrix = ff_mpeg1_default_intra_matrix;
+    const int qscale = a->qscale;
 
     /* DC coefficient */
-    if(a->version==2){
-        block[0]= 2*get_sbits(&a->gb, 10) + 1024;
-    }else{
+    if (a->version == 2) {
+        block[0] = 2 * get_sbits(&a->gb, 10) + 1024;
+    } else {
         component = (n <= 3 ? 0 : n - 4 + 1);
         diff = decode_dc(&a->gb, component);
         if (diff >= 0xffff)
-            return -1;
-        a->last_dc[component]+= diff;
-        block[0] = a->last_dc[component]<<3;
+            return AVERROR_INVALIDDATA;
+        a->last_dc[component] += diff;
+        block[0] = a->last_dc[component] << 3;
     }
 
     i = 0;
     {
         OPEN_READER(re, &a->gb);
         /* now quantify & encode AC coefficients */
-        for(;;) {
+        for (;;) {
             UPDATE_CACHE(re, &a->gb);
             GET_RL_VLC(level, run, re, &a->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
 
-            if(level == 127){
+            if (level == 127) {
                 break;
-            } else if(level != 0) {
-                i += run;
-                j = scantable[i];
-                level= (level*qscale*quant_matrix[j])>>3;
+            } else if (level != 0) {
+                i    += run;
+                j     = scantable[i];
+                level = (level * qscale * quant_matrix[j]) >> 3;
                 level = (level ^ SHOW_SBITS(re, &a->gb, 1)) - SHOW_SBITS(re, &a->gb, 1);
                 LAST_SKIP_BITS(re, &a->gb, 1);
             } else {
@@ -94,21 +93,21 @@
                 run = SHOW_UBITS(re, &a->gb, 6)+1; LAST_SKIP_BITS(re, &a->gb, 6);
                 UPDATE_CACHE(re, &a->gb);
                 level = SHOW_SBITS(re, &a->gb, 10); SKIP_BITS(re, &a->gb, 10);
-                i += run;
-                j = scantable[i];
-                if(level<0){
-                    level= -level;
-                    level= (level*qscale*quant_matrix[j])>>3;
-                    level= (level-1)|1;
-                    level= -level;
-                }else{
-                    level= (level*qscale*quant_matrix[j])>>3;
-                    level= (level-1)|1;
+                i    += run;
+                j     = scantable[i];
+                if (level < 0) {
+                    level = -level;
+                    level = (level * qscale * quant_matrix[j]) >> 3;
+                    level = (level - 1) | 1;
+                    level = -level;
+                } else {
+                    level = (level * qscale * quant_matrix[j]) >> 3;
+                    level = (level - 1) | 1;
                 }
             }
-            if (i > 63){
+            if (i > 63) {
                 av_log(a->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", a->mb_x, a->mb_y);
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
 
             block[j] = level;
@@ -119,149 +118,147 @@
     return 0;
 }
 
-static inline int decode_mb(MDECContext *a, DCTELEM block[6][64]){
-    int i;
-    const int block_index[6]= {5,4,0,1,2,3};
+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 };
 
     a->dsp.clear_blocks(block[0]);
 
-    for(i=0; i<6; i++){
-        if( mdec_decode_block_intra(a, block[ block_index[i] ], block_index[i]) < 0 ||
-            get_bits_left(&a->gb) < 0)
-            return -1;
+    for (i = 0; i < 6; i++) {
+        if ((ret = mdec_decode_block_intra(a, block[block_index[i]],
+                                           block_index[i])) < 0)
+            return ret;
+        if (get_bits_left(&a->gb) < 0)
+            return AVERROR_INVALIDDATA;
     }
     return 0;
 }
 
-static inline void idct_put(MDECContext *a, int mb_x, int mb_y){
-    DCTELEM (*block)[64]= a->block;
-    int linesize= a->picture.linesize[0];
+static inline void idct_put(MDECContext *a, int mb_x, int mb_y)
+{
+    int16_t (*block)[64] = a->block;
+    int linesize = a->picture.linesize[0];
 
-    uint8_t *dest_y  = a->picture.data[0] + (mb_y * 16* linesize              ) + mb_x * 16;
-    uint8_t *dest_cb = a->picture.data[1] + (mb_y * 8 * a->picture.linesize[1]) + mb_x * 8;
-    uint8_t *dest_cr = a->picture.data[2] + (mb_y * 8 * a->picture.linesize[2]) + mb_x * 8;
+    uint8_t *dest_y  = a->picture.data[0] + (mb_y * 16 * linesize              ) + mb_x * 16;
+    uint8_t *dest_cb = a->picture.data[1] + (mb_y * 8  * a->picture.linesize[1]) + mb_x * 8;
+    uint8_t *dest_cr = a->picture.data[2] + (mb_y * 8  * a->picture.linesize[2]) + mb_x * 8;
 
-    a->dsp.idct_put(dest_y                 , linesize, block[0]);
-    a->dsp.idct_put(dest_y              + 8, linesize, block[1]);
-    a->dsp.idct_put(dest_y + 8*linesize    , linesize, block[2]);
-    a->dsp.idct_put(dest_y + 8*linesize + 8, linesize, block[3]);
+    a->dsp.idct_put(dest_y,                    linesize, block[0]);
+    a->dsp.idct_put(dest_y                + 8, linesize, block[1]);
+    a->dsp.idct_put(dest_y + 8 * linesize,     linesize, block[2]);
+    a->dsp.idct_put(dest_y + 8 * linesize + 8, linesize, block[3]);
 
-    if(!(a->avctx->flags&CODEC_FLAG_GRAY)){
+    if (!(a->avctx->flags & CODEC_FLAG_GRAY)) {
         a->dsp.idct_put(dest_cb, a->picture.linesize[1], block[4]);
         a->dsp.idct_put(dest_cr, a->picture.linesize[2], block[5]);
     }
 }
 
 static int decode_frame(AVCodecContext *avctx,
-                        void *data, int *data_size,
+                        void *data, int *got_frame,
                         AVPacket *avpkt)
 {
-    const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
     MDECContext * const a = avctx->priv_data;
-    AVFrame *picture = data;
-    AVFrame * const p= &a->picture;
-    int i;
+    const uint8_t *buf    = avpkt->data;
+    int buf_size          = avpkt->size;
+    AVFrame *picture      = data;
+    AVFrame * const p     = &a->picture;
+    int i, ret;
 
-    if(p->data[0])
+    if (p->data[0])
         ff_thread_release_buffer(avctx, p);
 
-    p->reference= 0;
-    if(ff_thread_get_buffer(avctx, p) < 0){
+    p->reference = 0;
+    if ((ret = ff_thread_get_buffer(avctx, p)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
-    p->pict_type= AV_PICTURE_TYPE_I;
-    p->key_frame= 1;
+    p->pict_type = AV_PICTURE_TYPE_I;
+    p->key_frame = 1;
 
     av_fast_malloc(&a->bitstream_buffer, &a->bitstream_buffer_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
     if (!a->bitstream_buffer)
         return AVERROR(ENOMEM);
-    for(i=0; i<buf_size; i+=2){
-        a->bitstream_buffer[i]  = buf[i+1];
-        a->bitstream_buffer[i+1]= buf[i  ];
+    for (i = 0; i < buf_size; i += 2) {
+        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);
+    init_get_bits(&a->gb, a->bitstream_buffer, buf_size * 8);
 
     /* skip over 4 preamble bytes in stream (typically 0xXX 0xXX 0x00 0x38) */
     skip_bits(&a->gb, 32);
 
-    a->qscale=  get_bits(&a->gb, 16);
-    a->version= get_bits(&a->gb, 16);
+    a->qscale  = get_bits(&a->gb, 16);
+    a->version = get_bits(&a->gb, 16);
 
-    a->last_dc[0]=
-    a->last_dc[1]=
-    a->last_dc[2]= 128;
+    a->last_dc[0] = a->last_dc[1] = a->last_dc[2] = 128;
 
-    for(a->mb_x=0; a->mb_x<a->mb_width; a->mb_x++){
-        for(a->mb_y=0; a->mb_y<a->mb_height; a->mb_y++){
-            if( decode_mb(a, a->block) <0)
-                return -1;
+    for (a->mb_x = 0; a->mb_x < a->mb_width; a->mb_x++) {
+        for (a->mb_y = 0; a->mb_y < a->mb_height; a->mb_y++) {
+            if ((ret = decode_mb(a, a->block)) < 0)
+                return ret;
 
             idct_put(a, a->mb_x, a->mb_y);
         }
     }
 
-    p->quality= a->qscale * FF_QP2LAMBDA;
+    p->quality = a->qscale * FF_QP2LAMBDA;
     memset(p->qscale_table, a->qscale, a->mb_width);
 
     *picture   = a->picture;
-    *data_size = sizeof(AVPicture);
+    *got_frame = 1;
 
-    return (get_bits_count(&a->gb)+31)/32*4;
+    return (get_bits_count(&a->gb) + 31) / 32 * 4;
 }
 
-static av_cold void mdec_common_init(AVCodecContext *avctx){
+static av_cold int decode_init(AVCodecContext *avctx)
+{
     MDECContext * const a = avctx->priv_data;
+    AVFrame *p            = &a->picture;
 
-    ff_dsputil_init(&a->dsp, avctx);
-
-    a->mb_width   = (avctx->coded_width  + 15) / 16;
-    a->mb_height  = (avctx->coded_height + 15) / 16;
+    a->mb_width  = (avctx->coded_width  + 15) / 16;
+    a->mb_height = (avctx->coded_height + 15) / 16;
 
     avcodec_get_frame_defaults(&a->picture);
-    avctx->coded_frame= &a->picture;
-    a->avctx= avctx;
-}
+    avctx->coded_frame = &a->picture;
+    a->avctx           = avctx;
 
-static av_cold int decode_init(AVCodecContext *avctx){
-    MDECContext * const a = avctx->priv_data;
-    AVFrame *p= &a->picture;
-
-    mdec_common_init(avctx);
+    ff_dsputil_init(&a->dsp, avctx);
     ff_mpeg12_init_vlcs();
     ff_init_scantable(a->dsp.idct_permutation, &a->scantable, ff_zigzag_direct);
 
-    if( avctx->idct_algo == FF_IDCT_AUTO )
+    if (avctx->idct_algo == FF_IDCT_AUTO)
         avctx->idct_algo = FF_IDCT_SIMPLE;
-    p->qstride= 0;
-    p->qscale_table= av_mallocz(a->mb_width);
-    avctx->pix_fmt= AV_PIX_FMT_YUVJ420P;
+    p->qstride      = 0;
+    p->qscale_table = av_mallocz(a->mb_width);
+    avctx->pix_fmt  = AV_PIX_FMT_YUVJ420P;
 
     return 0;
 }
 
-static av_cold int decode_init_thread_copy(AVCodecContext *avctx){
+static av_cold int decode_init_thread_copy(AVCodecContext *avctx)
+{
     MDECContext * const a = avctx->priv_data;
-    AVFrame *p = &a->picture;
+    AVFrame *p            = &a->picture;
 
-    avctx->coded_frame= p;
-    a->avctx= avctx;
+    avctx->coded_frame = p;
+    a->avctx           = avctx;
 
     p->qscale_table= av_mallocz(a->mb_width);
 
     return 0;
 }
 
-
-static av_cold int decode_end(AVCodecContext *avctx){
+static av_cold int decode_end(AVCodecContext *avctx)
+{
     MDECContext * const a = avctx->priv_data;
 
-    if(a->picture.data[0])
+    if (a->picture.data[0])
         avctx->release_buffer(avctx, &a->picture);
     av_freep(&a->bitstream_buffer);
     av_freep(&a->picture.qscale_table);
-    a->bitstream_buffer_size=0;
+    a->bitstream_buffer_size = 0;
 
     return 0;
 }
diff --git a/libavcodec/microdvddec.c b/libavcodec/microdvddec.c
index e08cc31..f3c640f 100644
--- a/libavcodec/microdvddec.c
+++ b/libavcodec/microdvddec.c
@@ -260,6 +260,7 @@
 {
     AVSubtitle *sub = data;
     AVBPrint new_line;
+    char c;
     char *decoded_sub;
     char *line = avpkt->data;
     char *end = avpkt->data + avpkt->size;
@@ -268,11 +269,16 @@
     if (avpkt->size <= 0)
         return avpkt->size;
 
-    av_bprint_init(&new_line, 0, 2048);
+    /* To be removed later */
+    if (sscanf(line, "{%*d}{%*[0123456789]}%c", &c) == 1 &&
+        line[avpkt->size - 1] == '\n') {
+        av_log(avctx, AV_LOG_ERROR, "AVPacket is not clean (contains timing "
+               "information and a trailing line break). You need to upgrade "
+               "your libavformat or sanitize your packet.\n");
+        return AVERROR_INVALIDDATA;
+    }
 
-    // skip {frame_start}{frame_end}
-    line = strchr(line, '}'); if (!line) goto end; line++;
-    line = strchr(line, '}'); if (!line) goto end; line++;
+    av_bprint_init(&new_line, 0, 2048);
 
     // subtitle content
     while (line < end && *line) {
@@ -294,8 +300,9 @@
             line++;
         }
     }
+    if (new_line.len) {
+        av_bprintf(&new_line, "\r\n");
 
-end:
     av_bprint_finalize(&new_line, &decoded_sub);
     if (*decoded_sub) {
         int64_t start    = avpkt->pts;
@@ -306,6 +313,7 @@
         ff_ass_add_rect(sub, decoded_sub, ts_start, ts_duration, 0);
     }
     av_free(decoded_sub);
+    }
 
     *got_sub_ptr = sub->num_rects > 0;
     return avpkt->size;
diff --git a/libavcodec/mimic.c b/libavcodec/mimic.c
index 25db9ca..54d27e8 100644
--- a/libavcodec/mimic.c
+++ b/libavcodec/mimic.c
@@ -47,7 +47,7 @@
     AVFrame         buf_ptrs    [16];
     AVPicture       flipped_ptrs[16];
 
-    DECLARE_ALIGNED(16, DCTELEM, dct_block)[64];
+    DECLARE_ALIGNED(16, int16_t, dct_block)[64];
 
     GetBitContext   gb;
     ScanTable       scantable;
@@ -112,14 +112,15 @@
 static av_cold int mimic_decode_init(AVCodecContext *avctx)
 {
     MimicContext *ctx = avctx->priv_data;
+    int ret;
 
     ctx->prev_index = 0;
-    ctx->cur_index = 15;
+    ctx->cur_index  = 15;
 
-    if(init_vlc(&ctx->vlc, 11, FF_ARRAY_ELEMS(huffbits),
-                 huffbits, 1, 1, huffcodes, 4, 4, 0)) {
+    if ((ret = init_vlc(&ctx->vlc, 11, FF_ARRAY_ELEMS(huffbits),
+                        huffbits, 1, 1, huffcodes, 4, 4, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "error initializing vlc table\n");
-        return -1;
+        return ret;
     }
     ff_dsputil_init(&ctx->dsp, avctx);
     ff_init_scantable(ctx->dsp.idct_permutation, &ctx->scantable, col_zag);
@@ -131,7 +132,8 @@
 {
     MimicContext *dst = avctx->priv_data, *src = avctx_from->priv_data;
 
-    if (avctx == avctx_from) return 0;
+    if (avctx == avctx_from)
+        return 0;
 
     dst->cur_index  = src->next_cur_index;
     dst->prev_index = src->next_prev_index;
@@ -183,30 +185,30 @@
 
 static int vlc_decode_block(MimicContext *ctx, int num_coeffs, int qscale)
 {
-    DCTELEM *block = ctx->dct_block;
+    int16_t *block = ctx->dct_block;
     unsigned int pos;
 
     ctx->dsp.clear_block(block);
 
     block[0] = get_bits(&ctx->gb, 8) << 3;
 
-    for(pos = 1; pos < num_coeffs; pos++) {
+    for (pos = 1; pos < num_coeffs; pos++) {
         uint32_t vlc, num_bits;
         int value;
         int coeff;
 
         vlc = get_vlc2(&ctx->gb, ctx->vlc.table, ctx->vlc.bits, 3);
-        if(!vlc) /* end-of-block code */
-            return 1;
-        if(vlc == -1)
+        if (!vlc) /* end-of-block code */
             return 0;
+        if (vlc == -1)
+            return AVERROR_INVALIDDATA;
 
         /* pos_add and num_bits are coded in the vlc code */
-        pos +=     vlc&15; // pos_add
-        num_bits = vlc>>4; // num_bits
+        pos     += vlc & 15; // pos_add
+        num_bits = vlc >> 4; // num_bits
 
-        if(pos >= 64)
-            return 0;
+        if (pos >= 64)
+            return AVERROR_INVALIDDATA;
 
         value = get_bits(&ctx->gb, num_bits);
 
@@ -214,7 +216,7 @@
          * a factor of 4 was added to the input */
 
         coeff = vlcdec_lookup[num_bits][value];
-        if(pos<3)
+        if (pos < 3)
             coeff <<= 4;
         else /* TODO Use >> 10 instead of / 1001 */
             coeff = (coeff * qscale) / 1001;
@@ -222,47 +224,50 @@
         block[ctx->scantable.permutated[pos]] = coeff;
     }
 
-    return 1;
+    return 0;
 }
 
 static int decode(MimicContext *ctx, int quality, int num_coeffs,
                   int is_iframe)
 {
-    int y, x, plane, cur_row = 0;
+    int ret, y, x, plane, cur_row = 0;
 
-    for(plane = 0; plane < 3; plane++) {
+    for (plane = 0; plane < 3; plane++) {
         const int is_chroma = !!plane;
-        const int qscale = av_clip(10000-quality,is_chroma?1000:2000,10000)<<2;
-        const int stride = ctx->flipped_ptrs[ctx->cur_index].linesize[plane];
-        const uint8_t *src = ctx->flipped_ptrs[ctx->prev_index].data[plane];
-        uint8_t       *dst = ctx->flipped_ptrs[ctx->cur_index ].data[plane];
+        const int qscale    = av_clip(10000 - quality, is_chroma ? 1000 : 2000,
+                                      10000) << 2;
+        const int stride    = ctx->flipped_ptrs[ctx->cur_index ].linesize[plane];
+        const uint8_t *src  = ctx->flipped_ptrs[ctx->prev_index].data[plane];
+        uint8_t       *dst  = ctx->flipped_ptrs[ctx->cur_index ].data[plane];
 
-        for(y = 0; y < ctx->num_vblocks[plane]; y++) {
-            for(x = 0; x < ctx->num_hblocks[plane]; x++) {
-
+        for (y = 0; y < ctx->num_vblocks[plane]; y++) {
+            for (x = 0; x < ctx->num_hblocks[plane]; x++) {
                 /* Check for a change condition in the current block.
                  * - iframes always change.
                  * - Luma plane changes on get_bits1 == 0
                  * - Chroma planes change on get_bits1 == 1 */
-                if(is_iframe || get_bits1(&ctx->gb) == is_chroma) {
-
+                if (is_iframe || get_bits1(&ctx->gb) == is_chroma) {
                     /* Luma planes may use a backreference from the 15 last
                      * frames preceding the previous. (get_bits1 == 1)
                      * Chroma planes don't use backreferences. */
-                    if(is_chroma || is_iframe || !get_bits1(&ctx->gb)) {
-
-                        if(!vlc_decode_block(ctx, num_coeffs, qscale))
-                            return 0;
+                    if (is_chroma || is_iframe || !get_bits1(&ctx->gb)) {
+                        if ((ret = vlc_decode_block(ctx, num_coeffs,
+                                                    qscale)) < 0) {
+                            av_log(ctx->avctx, AV_LOG_ERROR, "Error decoding "
+                                   "block.\n");
+                            return ret;
+                        }
                         ctx->dsp.idct_put(dst, stride, ctx->dct_block);
                     } else {
                         unsigned int backref = get_bits(&ctx->gb, 4);
-                        int index = (ctx->cur_index+backref)&15;
-                        uint8_t *p = ctx->flipped_ptrs[index].data[0];
+                        int index            = (ctx->cur_index + backref) & 15;
+                        uint8_t *p           = ctx->flipped_ptrs[index].data[0];
 
                         if (index != ctx->cur_index && p) {
-                            ff_thread_await_progress(&ctx->buf_ptrs[index], cur_row, 0);
+                            ff_thread_await_progress(&ctx->buf_ptrs[index],
+                                                     cur_row, 0);
                             p += src -
-                                ctx->flipped_ptrs[ctx->prev_index].data[plane];
+                                 ctx->flipped_ptrs[ctx->prev_index].data[plane];
                             ctx->dsp.put_pixels_tab[1][0](dst, p, stride, 8);
                         } else {
                             av_log(ctx->avctx, AV_LOG_ERROR,
@@ -270,52 +275,54 @@
                         }
                     }
                 } else {
-                    ff_thread_await_progress(&ctx->buf_ptrs[ctx->prev_index], cur_row, 0);
+                    ff_thread_await_progress(&ctx->buf_ptrs[ctx->prev_index],
+                                             cur_row, 0);
                     ctx->dsp.put_pixels_tab[1][0](dst, src, stride, 8);
                 }
                 src += 8;
                 dst += 8;
             }
-            src += (stride - ctx->num_hblocks[plane])<<3;
-            dst += (stride - ctx->num_hblocks[plane])<<3;
+            src += (stride - ctx->num_hblocks[plane]) << 3;
+            dst += (stride - ctx->num_hblocks[plane]) << 3;
 
-            ff_thread_report_progress(&ctx->buf_ptrs[ctx->cur_index], cur_row++, 0);
+            ff_thread_report_progress(&ctx->buf_ptrs[ctx->cur_index],
+                                      cur_row++, 0);
         }
     }
 
-    return 1;
+    return 0;
 }
 
 /**
  * Flip the buffer upside-down and put it in the YVU order to match the
  * way Mimic encodes frames.
  */
-static void prepare_avpic(MimicContext *ctx, AVPicture *dst, AVPicture *src)
+static void prepare_avpic(MimicContext *ctx, AVPicture *dst, AVFrame *src)
 {
     int i;
-    dst->data[0] = src->data[0]+( ctx->avctx->height    -1)*src->linesize[0];
-    dst->data[1] = src->data[2]+((ctx->avctx->height>>1)-1)*src->linesize[2];
-    dst->data[2] = src->data[1]+((ctx->avctx->height>>1)-1)*src->linesize[1];
-    for(i = 0; i < 3; i++)
+    dst->data[0] = src->data[0] + ( ctx->avctx->height       - 1) * src->linesize[0];
+    dst->data[1] = src->data[2] + ((ctx->avctx->height >> 1) - 1) * src->linesize[2];
+    dst->data[2] = src->data[1] + ((ctx->avctx->height >> 1) - 1) * src->linesize[1];
+    for (i = 0; i < 3; i++)
         dst->linesize[i] = -src->linesize[i];
 }
 
 static int mimic_decode_frame(AVCodecContext *avctx, void *data,
-                              int *data_size, AVPacket *avpkt)
+                              int *got_frame, AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
-    MimicContext *ctx = avctx->priv_data;
+    int buf_size       = avpkt->size;
+    int swap_buf_size  = buf_size - MIMIC_HEADER_SIZE;
+    MimicContext *ctx  = avctx->priv_data;
     GetByteContext gb;
     int is_pframe;
     int width, height;
     int quality, num_coeffs;
-    int swap_buf_size = buf_size - MIMIC_HEADER_SIZE;
     int res;
 
     if (buf_size <= MIMIC_HEADER_SIZE) {
         av_log(avctx, AV_LOG_ERROR, "insufficient data\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     bytestream2_init(&gb, buf, MIMIC_HEADER_SIZE);
@@ -328,74 +335,75 @@
     num_coeffs = bytestream2_get_byteu(&gb);
     bytestream2_skip(&gb, 3); /* some constant */
 
-    if(!ctx->avctx) {
+    if (!ctx->avctx) {
         int i;
 
-        if(!(width == 160 && height == 120) &&
-           !(width == 320 && height == 240)) {
+        if (!(width == 160 && height == 120) &&
+            !(width == 320 && height == 240)) {
             av_log(avctx, AV_LOG_ERROR, "invalid width/height!\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
 
         ctx->avctx     = avctx;
         avctx->width   = width;
         avctx->height  = height;
         avctx->pix_fmt = AV_PIX_FMT_YUV420P;
-        for(i = 0; i < 3; i++) {
+        for (i = 0; i < 3; i++) {
             ctx->num_vblocks[i] = -((-height) >> (3 + !!i));
-            ctx->num_hblocks[i] =     width   >> (3 + !!i) ;
+            ctx->num_hblocks[i] =     width   >> (3 + !!i);
         }
-    } else if(width != ctx->avctx->width || height != ctx->avctx->height) {
-        av_log(avctx, AV_LOG_ERROR, "resolution changing is not supported\n");
-        return -1;
+    } else if (width != ctx->avctx->width || height != ctx->avctx->height) {
+        av_log_missing_feature(avctx, "resolution changing", 1);
+        return AVERROR_PATCHWELCOME;
     }
 
-    if(is_pframe && !ctx->buf_ptrs[ctx->prev_index].data[0]) {
+    if (is_pframe && !ctx->buf_ptrs[ctx->prev_index].data[0]) {
         av_log(avctx, AV_LOG_ERROR, "decoding must start with keyframe\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     ctx->buf_ptrs[ctx->cur_index].reference = 3;
-    ctx->buf_ptrs[ctx->cur_index].pict_type = is_pframe ? AV_PICTURE_TYPE_P:AV_PICTURE_TYPE_I;
-    if(ff_thread_get_buffer(avctx, &ctx->buf_ptrs[ctx->cur_index])) {
+    ctx->buf_ptrs[ctx->cur_index].pict_type = is_pframe ? AV_PICTURE_TYPE_P :
+                                                          AV_PICTURE_TYPE_I;
+    if ((res = ff_thread_get_buffer(avctx, &ctx->buf_ptrs[ctx->cur_index])) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return res;
     }
 
     ctx->next_prev_index = ctx->cur_index;
     ctx->next_cur_index  = (ctx->cur_index - 1) & 15;
 
     prepare_avpic(ctx, &ctx->flipped_ptrs[ctx->cur_index],
-                  (AVPicture*) &ctx->buf_ptrs[ctx->cur_index]);
+                  &ctx->buf_ptrs[ctx->cur_index]);
 
     ff_thread_finish_setup(avctx);
 
     av_fast_padded_malloc(&ctx->swap_buf, &ctx->swap_buf_size, swap_buf_size);
-    if(!ctx->swap_buf)
+    if (!ctx->swap_buf)
         return AVERROR(ENOMEM);
 
     ctx->dsp.bswap_buf(ctx->swap_buf,
-                        (const uint32_t*) (buf + MIMIC_HEADER_SIZE),
-                        swap_buf_size>>2);
+                       (const uint32_t*) (buf + MIMIC_HEADER_SIZE),
+                       swap_buf_size >> 2);
     init_get_bits(&ctx->gb, ctx->swap_buf, swap_buf_size << 3);
 
     res = decode(ctx, quality, num_coeffs, !is_pframe);
     ff_thread_report_progress(&ctx->buf_ptrs[ctx->cur_index], INT_MAX, 0);
-    if (!res) {
+    if (res < 0) {
         if (!(avctx->active_thread_type & FF_THREAD_FRAME)) {
             ff_thread_release_buffer(avctx, &ctx->buf_ptrs[ctx->cur_index]);
-            return -1;
+            return res;
         }
     }
 
     *(AVFrame*)data = ctx->buf_ptrs[ctx->cur_index];
-    *data_size = sizeof(AVFrame);
+    *got_frame      = 1;
 
     ctx->prev_index = ctx->next_prev_index;
     ctx->cur_index  = ctx->next_cur_index;
 
     /* Only release frames that aren't used for backreferences anymore */
-    if(ctx->buf_ptrs[ctx->cur_index].data[0])
+    if (ctx->buf_ptrs[ctx->cur_index].data[0])
         ff_thread_release_buffer(avctx, &ctx->buf_ptrs[ctx->cur_index]);
 
     return buf_size;
@@ -411,8 +419,8 @@
     if (avctx->internal->is_copy)
         return 0;
 
-    for(i = 0; i < 16; i++)
-        if(ctx->buf_ptrs[i].data[0])
+    for (i = 0; i < 16; i++)
+        if (ctx->buf_ptrs[i].data[0])
             ff_thread_release_buffer(avctx, &ctx->buf_ptrs[i]);
     ff_free_vlc(&ctx->vlc);
 
diff --git a/libavcodec/mips/Makefile b/libavcodec/mips/Makefile
index feeec99..8223f11 100644
--- a/libavcodec/mips/Makefile
+++ b/libavcodec/mips/Makefile
@@ -11,6 +11,9 @@
 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/dsputil_mips.o           \
-                                             mips/fmtconvert_mips.o
+MIPSFPU-OBJS                              += mips/fmtconvert_mips.o
 OBJS-$(CONFIG_AC3DSP)                     += mips/ac3dsp_mips.o
+OBJS-$(CONFIG_AAC_DECODER)                += mips/aacdec_mips.o            \
+                                             mips/aacsbr_mips.o            \
+                                             mips/sbrdsp_mips.o            \
+                                             mips/aacpsdsp_mips.o
diff --git a/libavcodec/mips/aacdec_mips.c b/libavcodec/mips/aacdec_mips.c
new file mode 100644
index 0000000..e403366
--- /dev/null
+++ b/libavcodec/mips/aacdec_mips.c
@@ -0,0 +1,831 @@
+/*
+ * 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:  Darko Laus      (darko@mips.com)
+ *           Djordje Pesut   (djordje@mips.com)
+ *           Mirjana Vulin   (mvulin@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
+ * Reference: libavcodec/aacdec.c
+ */
+
+#include "libavcodec/aac.h"
+#include "aacdec_mips.h"
+#include "libavcodec/aactab.h"
+#include "libavcodec/sinewin.h"
+
+#if HAVE_INLINE_ASM
+static av_always_inline int lcg_random(unsigned previous_val)
+{
+    union { unsigned u; int s; } v = { previous_val * 1664525u + 1013904223 };
+    return v.s;
+}
+
+static void imdct_and_windowing_mips(AACContext *ac, SingleChannelElement *sce)
+{
+    IndividualChannelStream *ics = &sce->ics;
+    float *in    = sce->coeffs;
+    float *out   = sce->ret;
+    float *saved = sce->saved;
+    const float *swindow      = ics->use_kb_window[0] ? ff_aac_kbd_short_128 : ff_sine_128;
+    const float *lwindow_prev = ics->use_kb_window[1] ? ff_aac_kbd_long_1024 : ff_sine_1024;
+    const float *swindow_prev = ics->use_kb_window[1] ? ff_aac_kbd_short_128 : ff_sine_128;
+    float *buf  = ac->buf_mdct;
+    int i;
+
+    if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
+        for (i = 0; i < 1024; i += 128)
+            ac->mdct_small.imdct_half(&ac->mdct_small, buf + i, in + i);
+    } else
+        ac->mdct.imdct_half(&ac->mdct, buf, in);
+
+    /* window overlapping
+     * NOTE: To simplify the overlapping code, all 'meaningless' short to long
+     * and long to short transitions are considered to be short to short
+     * transitions. This leaves just two cases (long to long and short to short)
+     * with a little special sauce for EIGHT_SHORT_SEQUENCE.
+     */
+    if ((ics->window_sequence[1] == ONLY_LONG_SEQUENCE || ics->window_sequence[1] == LONG_STOP_SEQUENCE) &&
+            (ics->window_sequence[0] == ONLY_LONG_SEQUENCE || ics->window_sequence[0] == LONG_START_SEQUENCE)) {
+        ac->fdsp.vector_fmul_window(    out,               saved,            buf,         lwindow_prev, 512);
+    } else {
+        {
+            float *buf1 = saved;
+            float *buf2 = out;
+            int temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
+            int loop_end;
+
+            /* loop unrolled 8 times */
+            __asm__ volatile (
+                ".set push                               \n\t"
+                ".set noreorder                          \n\t"
+                "addiu   %[loop_end], %[src],      1792  \n\t"
+            "1:                                          \n\t"
+                "lw      %[temp0],    0(%[src])          \n\t"
+                "lw      %[temp1],    4(%[src])          \n\t"
+                "lw      %[temp2],    8(%[src])          \n\t"
+                "lw      %[temp3],    12(%[src])         \n\t"
+                "lw      %[temp4],    16(%[src])         \n\t"
+                "lw      %[temp5],    20(%[src])         \n\t"
+                "lw      %[temp6],    24(%[src])         \n\t"
+                "lw      %[temp7],    28(%[src])         \n\t"
+                "addiu   %[src],      %[src],      32    \n\t"
+                "sw      %[temp0],    0(%[dst])          \n\t"
+                "sw      %[temp1],    4(%[dst])          \n\t"
+                "sw      %[temp2],    8(%[dst])          \n\t"
+                "sw      %[temp3],    12(%[dst])         \n\t"
+                "sw      %[temp4],    16(%[dst])         \n\t"
+                "sw      %[temp5],    20(%[dst])         \n\t"
+                "sw      %[temp6],    24(%[dst])         \n\t"
+                "sw      %[temp7],    28(%[dst])         \n\t"
+                "bne     %[src],      %[loop_end], 1b    \n\t"
+                " addiu  %[dst],      %[dst],      32    \n\t"
+                ".set pop                                \n\t"
+
+                : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1),
+                  [temp2]"=&r"(temp2), [temp3]"=&r"(temp3),
+                  [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+                  [temp6]"=&r"(temp6), [temp7]"=&r"(temp7),
+                  [loop_end]"=&r"(loop_end), [src]"+r"(buf1),
+                  [dst]"+r"(buf2)
+                :
+                : "memory"
+            );
+        }
+
+        if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
+            {
+                float wi;
+                float wj;
+                int i;
+                float temp0, temp1, temp2, temp3;
+                float *dst0 = out + 448 + 0*128;
+                float *dst1 = dst0 + 64 + 63;
+                float *dst2 = saved + 63;
+                float *win0 = (float*)swindow;
+                float *win1 = win0 + 64 + 63;
+                float *win0_prev = (float*)swindow_prev;
+                float *win1_prev = win0_prev + 64 + 63;
+                float *src0_prev = saved + 448;
+                float *src1_prev = buf + 0*128 + 63;
+                float *src0 = buf + 0*128 + 64;
+                float *src1 = buf + 1*128 + 63;
+
+                for(i = 0; i < 64; i++)
+                {
+                    temp0 = src0_prev[0];
+                    temp1 = src1_prev[0];
+                    wi = *win0_prev;
+                    wj = *win1_prev;
+                    temp2 = src0[0];
+                    temp3 = src1[0];
+                    dst0[0] = temp0 * wj - temp1 * wi;
+                    dst1[0] = temp0 * wi + temp1 * wj;
+
+                    wi = *win0;
+                    wj = *win1;
+
+                    temp0 = src0[128];
+                    temp1 = src1[128];
+                    dst0[128] = temp2 * wj - temp3 * wi;
+                    dst1[128] = temp2 * wi + temp3 * wj;
+
+                    temp2 = src0[256];
+                    temp3 = src1[256];
+                    dst0[256] = temp0 * wj - temp1 * wi;
+                    dst1[256] = temp0 * wi + temp1 * wj;
+                    dst0[384] = temp2 * wj - temp3 * wi;
+                    dst1[384] = temp2 * wi + temp3 * wj;
+
+                    temp0 = src0[384];
+                    temp1 = src1[384];
+                    dst0[512] = temp0 * wj - temp1 * wi;
+                    dst2[0] = temp0 * wi + temp1 * wj;
+
+                    src0++;
+                    src1--;
+                    src0_prev++;
+                    src1_prev--;
+                    win0++;
+                    win1--;
+                    win0_prev++;
+                    win1_prev--;
+                    dst0++;
+                    dst1--;
+                    dst2--;
+                }
+            }
+        } else {
+            ac->fdsp.vector_fmul_window(out + 448,         saved + 448,      buf,         swindow_prev, 64);
+            {
+                float *buf1 = buf + 64;
+                float *buf2 = out + 576;
+                int temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
+                int loop_end;
+
+                /* loop unrolled 8 times */
+                __asm__ volatile (
+                    ".set push                               \n\t"
+                    ".set noreorder                          \n\t"
+                    "addiu   %[loop_end], %[src],      1792  \n\t"
+                "1:                                          \n\t"
+                    "lw      %[temp0],    0(%[src])          \n\t"
+                    "lw      %[temp1],    4(%[src])          \n\t"
+                    "lw      %[temp2],    8(%[src])          \n\t"
+                    "lw      %[temp3],    12(%[src])         \n\t"
+                    "lw      %[temp4],    16(%[src])         \n\t"
+                    "lw      %[temp5],    20(%[src])         \n\t"
+                    "lw      %[temp6],    24(%[src])         \n\t"
+                    "lw      %[temp7],    28(%[src])         \n\t"
+                    "addiu   %[src],      %[src],      32    \n\t"
+                    "sw      %[temp0],    0(%[dst])          \n\t"
+                    "sw      %[temp1],    4(%[dst])          \n\t"
+                    "sw      %[temp2],    8(%[dst])          \n\t"
+                    "sw      %[temp3],    12(%[dst])         \n\t"
+                    "sw      %[temp4],    16(%[dst])         \n\t"
+                    "sw      %[temp5],    20(%[dst])         \n\t"
+                    "sw      %[temp6],    24(%[dst])         \n\t"
+                    "sw      %[temp7],    28(%[dst])         \n\t"
+                    "bne     %[src],      %[loop_end], 1b    \n\t"
+                    " addiu  %[dst],      %[dst],      32    \n\t"
+                    ".set pop                                \n\t"
+
+                    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1),
+                      [temp2]"=&r"(temp2), [temp3]"=&r"(temp3),
+                      [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+                      [temp6]"=&r"(temp6), [temp7]"=&r"(temp7),
+                      [loop_end]"=&r"(loop_end), [src]"+r"(buf1),
+                      [dst]"+r"(buf2)
+                    :
+                    : "memory"
+                );
+            }
+        }
+    }
+
+    // buffer update
+    if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
+        ac->fdsp.vector_fmul_window(saved + 64,  buf + 4*128 + 64, buf + 5*128, swindow, 64);
+        ac->fdsp.vector_fmul_window(saved + 192, buf + 5*128 + 64, buf + 6*128, swindow, 64);
+        ac->fdsp.vector_fmul_window(saved + 320, buf + 6*128 + 64, buf + 7*128, swindow, 64);
+        {
+            float *buf1 = buf + 7*128 + 64;
+            float *buf2 = saved + 448;
+            int temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
+            int loop_end;
+
+            /* loop unrolled 8 times */
+            __asm__ volatile (
+                ".set push                                \n\t"
+                ".set noreorder                           \n\t"
+                "addiu   %[loop_end], %[src],       256   \n\t"
+            "1:                                           \n\t"
+                "lw      %[temp0],    0(%[src])           \n\t"
+                "lw      %[temp1],    4(%[src])           \n\t"
+                "lw      %[temp2],    8(%[src])           \n\t"
+                "lw      %[temp3],    12(%[src])          \n\t"
+                "lw      %[temp4],    16(%[src])          \n\t"
+                "lw      %[temp5],    20(%[src])          \n\t"
+                "lw      %[temp6],    24(%[src])          \n\t"
+                "lw      %[temp7],    28(%[src])          \n\t"
+                "addiu   %[src],      %[src],       32    \n\t"
+                "sw      %[temp0],    0(%[dst])           \n\t"
+                "sw      %[temp1],    4(%[dst])           \n\t"
+                "sw      %[temp2],    8(%[dst])           \n\t"
+                "sw      %[temp3],    12(%[dst])          \n\t"
+                "sw      %[temp4],    16(%[dst])          \n\t"
+                "sw      %[temp5],    20(%[dst])          \n\t"
+                "sw      %[temp6],    24(%[dst])          \n\t"
+                "sw      %[temp7],    28(%[dst])          \n\t"
+                "bne     %[src],      %[loop_end],  1b    \n\t"
+                " addiu  %[dst],      %[dst],       32    \n\t"
+                ".set pop                                 \n\t"
+
+                : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1),
+                  [temp2]"=&r"(temp2), [temp3]"=&r"(temp3),
+                  [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+                  [temp6]"=&r"(temp6), [temp7]"=&r"(temp7),
+                  [loop_end]"=&r"(loop_end), [src]"+r"(buf1),
+                  [dst]"+r"(buf2)
+                :
+                : "memory"
+            );
+        }
+    } else if (ics->window_sequence[0] == LONG_START_SEQUENCE) {
+        float *buf1 = buf + 512;
+        float *buf2 = saved;
+        int temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
+        int loop_end;
+
+        /* loop unrolled 8 times */
+        __asm__ volatile (
+            ".set push                                \n\t"
+            ".set noreorder                           \n\t"
+            "addiu   %[loop_end], %[src],       1792  \n\t"
+        "1:                                           \n\t"
+            "lw      %[temp0],    0(%[src])           \n\t"
+            "lw      %[temp1],    4(%[src])           \n\t"
+            "lw      %[temp2],    8(%[src])           \n\t"
+            "lw      %[temp3],    12(%[src])          \n\t"
+            "lw      %[temp4],    16(%[src])          \n\t"
+            "lw      %[temp5],    20(%[src])          \n\t"
+            "lw      %[temp6],    24(%[src])          \n\t"
+            "lw      %[temp7],    28(%[src])          \n\t"
+            "addiu   %[src],      %[src],       32    \n\t"
+            "sw      %[temp0],    0(%[dst])           \n\t"
+            "sw      %[temp1],    4(%[dst])           \n\t"
+            "sw      %[temp2],    8(%[dst])           \n\t"
+            "sw      %[temp3],    12(%[dst])          \n\t"
+            "sw      %[temp4],    16(%[dst])          \n\t"
+            "sw      %[temp5],    20(%[dst])          \n\t"
+            "sw      %[temp6],    24(%[dst])          \n\t"
+            "sw      %[temp7],    28(%[dst])          \n\t"
+            "bne     %[src],      %[loop_end],  1b    \n\t"
+            " addiu  %[dst],      %[dst],       32    \n\t"
+            ".set pop                                 \n\t"
+
+            : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1),
+              [temp2]"=&r"(temp2), [temp3]"=&r"(temp3),
+              [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+              [temp6]"=&r"(temp6), [temp7]"=&r"(temp7),
+              [loop_end]"=&r"(loop_end), [src]"+r"(buf1),
+              [dst]"+r"(buf2)
+            :
+            : "memory"
+        );
+        {
+            float *buf1 = buf + 7*128 + 64;
+            float *buf2 = saved + 448;
+            int temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
+            int loop_end;
+
+            /* loop unrolled 8 times */
+            __asm__ volatile (
+                ".set push                                 \n\t"
+                ".set noreorder                            \n\t"
+                "addiu   %[loop_end], %[src],        256   \n\t"
+            "1:                                            \n\t"
+                "lw      %[temp0],    0(%[src])            \n\t"
+                "lw      %[temp1],    4(%[src])            \n\t"
+                "lw      %[temp2],    8(%[src])            \n\t"
+                "lw      %[temp3],    12(%[src])           \n\t"
+                "lw      %[temp4],    16(%[src])           \n\t"
+                "lw      %[temp5],    20(%[src])           \n\t"
+                "lw      %[temp6],    24(%[src])           \n\t"
+                "lw      %[temp7],    28(%[src])           \n\t"
+                "addiu   %[src],      %[src],        32    \n\t"
+                "sw      %[temp0],    0(%[dst])            \n\t"
+                "sw      %[temp1],    4(%[dst])            \n\t"
+                "sw      %[temp2],    8(%[dst])            \n\t"
+                "sw      %[temp3],    12(%[dst])           \n\t"
+                "sw      %[temp4],    16(%[dst])           \n\t"
+                "sw      %[temp5],    20(%[dst])           \n\t"
+                "sw      %[temp6],    24(%[dst])           \n\t"
+                "sw      %[temp7],    28(%[dst])           \n\t"
+                "bne     %[src],      %[loop_end],   1b    \n\t"
+                " addiu  %[dst],      %[dst],        32    \n\t"
+                ".set pop                                  \n\t"
+
+                : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1),
+                  [temp2]"=&r"(temp2), [temp3]"=&r"(temp3),
+                  [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+                  [temp6]"=&r"(temp6), [temp7]"=&r"(temp7),
+                  [loop_end]"=&r"(loop_end), [src]"+r"(buf1),
+                  [dst]"+r"(buf2)
+                :
+                : "memory"
+            );
+        }
+    } else { // LONG_STOP or ONLY_LONG
+        float *buf1 = buf + 512;
+        float *buf2 = saved;
+        int temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
+        int loop_end;
+
+        /* loop unrolled 8 times */
+        __asm__ volatile (
+            ".set push                                 \n\t"
+            ".set noreorder                            \n\t"
+            "addiu   %[loop_end], %[src],        2048  \n\t"
+        "1:                                            \n\t"
+            "lw      %[temp0],    0(%[src])            \n\t"
+            "lw      %[temp1],    4(%[src])            \n\t"
+            "lw      %[temp2],    8(%[src])            \n\t"
+            "lw      %[temp3],    12(%[src])           \n\t"
+            "lw      %[temp4],    16(%[src])           \n\t"
+            "lw      %[temp5],    20(%[src])           \n\t"
+            "lw      %[temp6],    24(%[src])           \n\t"
+            "lw      %[temp7],    28(%[src])           \n\t"
+            "addiu   %[src],      %[src],        32    \n\t"
+            "sw      %[temp0],    0(%[dst])            \n\t"
+            "sw      %[temp1],    4(%[dst])            \n\t"
+            "sw      %[temp2],    8(%[dst])            \n\t"
+            "sw      %[temp3],    12(%[dst])           \n\t"
+            "sw      %[temp4],    16(%[dst])           \n\t"
+            "sw      %[temp5],    20(%[dst])           \n\t"
+            "sw      %[temp6],    24(%[dst])           \n\t"
+            "sw      %[temp7],    28(%[dst])           \n\t"
+            "bne     %[src],      %[loop_end],   1b    \n\t"
+            " addiu  %[dst],      %[dst],        32    \n\t"
+            ".set pop                                  \n\t"
+
+            : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1),
+              [temp2]"=&r"(temp2), [temp3]"=&r"(temp3),
+              [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+              [temp6]"=&r"(temp6), [temp7]"=&r"(temp7),
+              [loop_end]"=&r"(loop_end), [src]"+r"(buf1),
+              [dst]"+r"(buf2)
+            :
+            : "memory"
+        );
+    }
+}
+
+static void apply_ltp_mips(AACContext *ac, SingleChannelElement *sce)
+{
+    const LongTermPrediction *ltp = &sce->ics.ltp;
+    const uint16_t *offsets = sce->ics.swb_offset;
+    int i, sfb;
+    int j, k;
+
+    if (sce->ics.window_sequence[0] != EIGHT_SHORT_SEQUENCE) {
+        float *predTime = sce->ret;
+        float *predFreq = ac->buf_mdct;
+        float *p_predTime;
+        int16_t num_samples = 2048;
+
+        if (ltp->lag < 1024)
+            num_samples = ltp->lag + 1024;
+            j = (2048 - num_samples) >> 2;
+            k = (2048 - num_samples) & 3;
+            p_predTime = &predTime[num_samples];
+
+        for (i = 0; i < num_samples; i++)
+            predTime[i] = sce->ltp_state[i + 2048 - ltp->lag] * ltp->coef;
+        for (i = 0; i < j; i++) {
+
+            /* loop unrolled 4 times */
+            __asm__ volatile (
+                "sw      $0,              0(%[p_predTime])        \n\t"
+                "sw      $0,              4(%[p_predTime])        \n\t"
+                "sw      $0,              8(%[p_predTime])        \n\t"
+                "sw      $0,              12(%[p_predTime])       \n\t"
+                "addiu   %[p_predTime],   %[p_predTime],     16   \n\t"
+
+                : [p_predTime]"+r"(p_predTime)
+                :
+                : "memory"
+            );
+        }
+        for (i = 0; i < k; i++) {
+
+            __asm__ volatile (
+                "sw      $0,              0(%[p_predTime])        \n\t"
+                "addiu   %[p_predTime],   %[p_predTime],     4    \n\t"
+
+                : [p_predTime]"+r"(p_predTime)
+                :
+                : "memory"
+            );
+        }
+
+        ac->windowing_and_mdct_ltp(ac, predFreq, predTime, &sce->ics);
+
+        if (sce->tns.present)
+            ac->apply_tns(predFreq, &sce->tns, &sce->ics, 0);
+
+        for (sfb = 0; sfb < FFMIN(sce->ics.max_sfb, MAX_LTP_LONG_SFB); sfb++)
+            if (ltp->used[sfb])
+                for (i = offsets[sfb]; i < offsets[sfb + 1]; i++)
+                    sce->coeffs[i] += predFreq[i];
+    }
+}
+
+#if HAVE_MIPSFPU
+static void update_ltp_mips(AACContext *ac, SingleChannelElement *sce)
+{
+    IndividualChannelStream *ics = &sce->ics;
+    float *saved     = sce->saved;
+    float *saved_ltp = sce->coeffs;
+    const float *lwindow = ics->use_kb_window[0] ? ff_aac_kbd_long_1024 : ff_sine_1024;
+    const float *swindow = ics->use_kb_window[0] ? ff_aac_kbd_short_128 : ff_sine_128;
+    int i;
+    int loop_end, loop_end1, loop_end2;
+    float temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8, temp9, temp10, temp11;
+
+    if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
+        float *buf = saved;
+        float *buf0 = saved_ltp;
+        float *p_saved_ltp = saved_ltp + 576;
+        float *ptr1 = &saved_ltp[512];
+        float *ptr2 = &ac->buf_mdct[1023];
+        float *ptr3 = (float*)&swindow[63];
+        loop_end1 = (int)(p_saved_ltp + 448);
+
+        /* loop unrolled 8 times */
+        __asm__ volatile (
+            ".set push                                     \n\t"
+            ".set noreorder                                \n\t"
+            "addiu   %[loop_end],   %[src],         2048   \n\t"
+        "1:                                                \n\t"
+            "lw      %[temp0],      0(%[src])              \n\t"
+            "lw      %[temp1],      4(%[src])              \n\t"
+            "lw      %[temp2],      8(%[src])              \n\t"
+            "lw      %[temp3],      12(%[src])             \n\t"
+            "lw      %[temp4],      16(%[src])             \n\t"
+            "lw      %[temp5],      20(%[src])             \n\t"
+            "lw      %[temp6],      24(%[src])             \n\t"
+            "lw      %[temp7],      28(%[src])             \n\t"
+            "addiu   %[src],        %[src],         32     \n\t"
+            "sw      %[temp0],      0(%[dst])              \n\t"
+            "sw      %[temp1],      4(%[dst])              \n\t"
+            "sw      %[temp2],      8(%[dst])              \n\t"
+            "sw      %[temp3],      12(%[dst])             \n\t"
+            "sw      %[temp4],      16(%[dst])             \n\t"
+            "sw      %[temp5],      20(%[dst])             \n\t"
+            "sw      %[temp6],      24(%[dst])             \n\t"
+            "sw      %[temp7],      28(%[dst])             \n\t"
+            "bne     %[src],        %[loop_end],    1b     \n\t"
+            " addiu  %[dst],        %[dst],         32     \n\t"
+            ".set pop                                      \n\t"
+
+            : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1),
+              [temp2]"=&r"(temp2), [temp3]"=&r"(temp3),
+              [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+              [temp6]"=&r"(temp6), [temp7]"=&r"(temp7),
+              [loop_end]"=&r"(loop_end), [src]"+r"(buf),
+              [dst]"+r"(buf0)
+            :
+            : "memory"
+        );
+
+        /* loop unrolled 8 times */
+        __asm__ volatile (
+        "1:                                                   \n\t"
+            "sw     $0,              0(%[p_saved_ltp])        \n\t"
+            "sw     $0,              4(%[p_saved_ltp])        \n\t"
+            "sw     $0,              8(%[p_saved_ltp])        \n\t"
+            "sw     $0,              12(%[p_saved_ltp])       \n\t"
+            "sw     $0,              16(%[p_saved_ltp])       \n\t"
+            "sw     $0,              20(%[p_saved_ltp])       \n\t"
+            "sw     $0,              24(%[p_saved_ltp])       \n\t"
+            "sw     $0,              28(%[p_saved_ltp])       \n\t"
+            "addiu  %[p_saved_ltp],  %[p_saved_ltp],     32   \n\t"
+            "bne    %[p_saved_ltp],  %[loop_end1],       1b   \n\t"
+
+            : [p_saved_ltp]"+r"(p_saved_ltp)
+            : [loop_end1]"r"(loop_end1)
+            : "memory"
+        );
+
+        ac->fdsp.vector_fmul_reverse(saved_ltp + 448, ac->buf_mdct + 960,     &swindow[64],      64);
+        for (i = 0; i < 16; i++){
+            /* loop unrolled 4 times */
+            __asm__ volatile (
+                "lwc1    %[temp0],    0(%[ptr2])                \n\t"
+                "lwc1    %[temp1],    -4(%[ptr2])               \n\t"
+                "lwc1    %[temp2],    -8(%[ptr2])               \n\t"
+                "lwc1    %[temp3],    -12(%[ptr2])              \n\t"
+                "lwc1    %[temp4],    0(%[ptr3])                \n\t"
+                "lwc1    %[temp5],    -4(%[ptr3])               \n\t"
+                "lwc1    %[temp6],    -8(%[ptr3])               \n\t"
+                "lwc1    %[temp7],    -12(%[ptr3])              \n\t"
+                "mul.s   %[temp8],    %[temp0],     %[temp4]    \n\t"
+                "mul.s   %[temp9],    %[temp1],     %[temp5]    \n\t"
+                "mul.s   %[temp10],   %[temp2],     %[temp6]    \n\t"
+                "mul.s   %[temp11],   %[temp3],     %[temp7]    \n\t"
+                "swc1    %[temp8],    0(%[ptr1])                \n\t"
+                "swc1    %[temp9],    4(%[ptr1])                \n\t"
+                "swc1    %[temp10],   8(%[ptr1])                \n\t"
+                "swc1    %[temp11],   12(%[ptr1])               \n\t"
+                "addiu   %[ptr1],     %[ptr1],      16          \n\t"
+                "addiu   %[ptr2],     %[ptr2],      -16         \n\t"
+                "addiu   %[ptr3],     %[ptr3],      -16         \n\t"
+
+                : [temp0]"=&f"(temp0), [temp1]"=&f"(temp1),
+                  [temp2]"=&f"(temp2), [temp3]"=&f"(temp3),
+                  [temp4]"=&f"(temp4), [temp5]"=&f"(temp5),
+                  [temp6]"=&f"(temp6), [temp7]"=&f"(temp7),
+                  [temp8]"=&f"(temp8), [temp9]"=&f"(temp9),
+                  [temp10]"=&f"(temp10), [temp11]"=&f"(temp11),
+                  [ptr1]"+r"(ptr1), [ptr2]"+r"(ptr2), [ptr3]"+r"(ptr3)
+                :
+                : "memory"
+            );
+        }
+    } else if (ics->window_sequence[0] == LONG_START_SEQUENCE) {
+        float *buff0 = saved;
+        float *buff1 = saved_ltp;
+        float *ptr1 = &saved_ltp[512];
+        float *ptr2 = &ac->buf_mdct[1023];
+        float *ptr3 = (float*)&swindow[63];
+        loop_end = (int)(saved + 448);
+
+        /* loop unrolled 8 times */
+        __asm__ volatile (
+            ".set push                                  \n\t"
+            ".set noreorder                             \n\t"
+        "1:                                             \n\t"
+            "lw      %[temp0],    0(%[src])             \n\t"
+            "lw      %[temp1],    4(%[src])             \n\t"
+            "lw      %[temp2],    8(%[src])             \n\t"
+            "lw      %[temp3],    12(%[src])            \n\t"
+            "lw      %[temp4],    16(%[src])            \n\t"
+            "lw      %[temp5],    20(%[src])            \n\t"
+            "lw      %[temp6],    24(%[src])            \n\t"
+            "lw      %[temp7],    28(%[src])            \n\t"
+            "addiu   %[src],      %[src],         32    \n\t"
+            "sw      %[temp0],    0(%[dst])             \n\t"
+            "sw      %[temp1],    4(%[dst])             \n\t"
+            "sw      %[temp2],    8(%[dst])             \n\t"
+            "sw      %[temp3],    12(%[dst])            \n\t"
+            "sw      %[temp4],    16(%[dst])            \n\t"
+            "sw      %[temp5],    20(%[dst])            \n\t"
+            "sw      %[temp6],    24(%[dst])            \n\t"
+            "sw      %[temp7],    28(%[dst])            \n\t"
+            "sw      $0,          2304(%[dst])          \n\t"
+            "sw      $0,          2308(%[dst])          \n\t"
+            "sw      $0,          2312(%[dst])          \n\t"
+            "sw      $0,          2316(%[dst])          \n\t"
+            "sw      $0,          2320(%[dst])          \n\t"
+            "sw      $0,          2324(%[dst])          \n\t"
+            "sw      $0,          2328(%[dst])          \n\t"
+            "sw      $0,          2332(%[dst])          \n\t"
+            "bne     %[src],      %[loop_end],    1b    \n\t"
+            " addiu  %[dst],      %[dst],         32    \n\t"
+            ".set pop                                   \n\t"
+
+            : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1),
+              [temp2]"=&r"(temp2), [temp3]"=&r"(temp3),
+              [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+              [temp6]"=&r"(temp6), [temp7]"=&r"(temp7),
+              [src]"+r"(buff0), [dst]"+r"(buff1)
+            : [loop_end]"r"(loop_end)
+            : "memory"
+        );
+        ac->fdsp.vector_fmul_reverse(saved_ltp + 448, ac->buf_mdct + 960,     &swindow[64],      64);
+        for (i = 0; i < 16; i++){
+            /* loop unrolled 8 times */
+            __asm__ volatile (
+                "lwc1    %[temp0],    0(%[ptr2])                \n\t"
+                "lwc1    %[temp1],    -4(%[ptr2])               \n\t"
+                "lwc1    %[temp2],    -8(%[ptr2])               \n\t"
+                "lwc1    %[temp3],    -12(%[ptr2])              \n\t"
+                "lwc1    %[temp4],    0(%[ptr3])                \n\t"
+                "lwc1    %[temp5],    -4(%[ptr3])               \n\t"
+                "lwc1    %[temp6],    -8(%[ptr3])               \n\t"
+                "lwc1    %[temp7],    -12(%[ptr3])              \n\t"
+                "mul.s   %[temp8],    %[temp0],     %[temp4]    \n\t"
+                "mul.s   %[temp9],    %[temp1],     %[temp5]    \n\t"
+                "mul.s   %[temp10],   %[temp2],     %[temp6]    \n\t"
+                "mul.s   %[temp11],   %[temp3],     %[temp7]    \n\t"
+                "swc1    %[temp8],    0(%[ptr1])                \n\t"
+                "swc1    %[temp9],    4(%[ptr1])                \n\t"
+                "swc1    %[temp10],   8(%[ptr1])                \n\t"
+                "swc1    %[temp11],   12(%[ptr1])               \n\t"
+                "addiu   %[ptr1],     %[ptr1],      16          \n\t"
+                "addiu   %[ptr2],     %[ptr2],      -16         \n\t"
+                "addiu   %[ptr3],     %[ptr3],      -16         \n\t"
+
+                : [temp0]"=&f"(temp0), [temp1]"=&f"(temp1),
+                  [temp2]"=&f"(temp2), [temp3]"=&f"(temp3),
+                  [temp4]"=&f"(temp4), [temp5]"=&f"(temp5),
+                  [temp6]"=&f"(temp6), [temp7]"=&f"(temp7),
+                  [temp8]"=&f"(temp8), [temp9]"=&f"(temp9),
+                  [temp10]"=&f"(temp10), [temp11]"=&f"(temp11),
+                  [ptr1]"+r"(ptr1), [ptr2]"+r"(ptr2), [ptr3]"+r"(ptr3)
+                :
+                : "memory"
+            );
+        }
+    } else { // LONG_STOP or ONLY_LONG
+        float *ptr1, *ptr2, *ptr3;
+        ac->fdsp.vector_fmul_reverse(saved_ltp,       ac->buf_mdct + 512,     &lwindow[512],     512);
+
+        ptr1 = &saved_ltp[512];
+        ptr2 = &ac->buf_mdct[1023];
+        ptr3 = (float*)&lwindow[511];
+
+        for (i = 0; i < 512; i+=4){
+            /* loop unrolled 4 times */
+            __asm__ volatile (
+                "lwc1    %[temp0],    0(%[ptr2])                \n\t"
+                "lwc1    %[temp1],    -4(%[ptr2])               \n\t"
+                "lwc1    %[temp2],    -8(%[ptr2])               \n\t"
+                "lwc1    %[temp3],    -12(%[ptr2])              \n\t"
+                "lwc1    %[temp4],    0(%[ptr3])                \n\t"
+                "lwc1    %[temp5],    -4(%[ptr3])               \n\t"
+                "lwc1    %[temp6],    -8(%[ptr3])               \n\t"
+                "lwc1    %[temp7],    -12(%[ptr3])              \n\t"
+                "mul.s   %[temp8],    %[temp0],     %[temp4]    \n\t"
+                "mul.s   %[temp9],    %[temp1],     %[temp5]    \n\t"
+                "mul.s   %[temp10],   %[temp2],     %[temp6]    \n\t"
+                "mul.s   %[temp11],   %[temp3],     %[temp7]    \n\t"
+                "swc1    %[temp8],    0(%[ptr1])                \n\t"
+                "swc1    %[temp9],    4(%[ptr1])                \n\t"
+                "swc1    %[temp10],   8(%[ptr1])                \n\t"
+                "swc1    %[temp11],   12(%[ptr1])               \n\t"
+                "addiu   %[ptr1],     %[ptr1],      16          \n\t"
+                "addiu   %[ptr2],     %[ptr2],      -16         \n\t"
+                "addiu   %[ptr3],     %[ptr3],      -16         \n\t"
+
+                : [temp0]"=&f"(temp0), [temp1]"=&f"(temp1),
+                  [temp2]"=&f"(temp2), [temp3]"=&f"(temp3),
+                  [temp4]"=&f"(temp4), [temp5]"=&f"(temp5),
+                  [temp6]"=&f"(temp6), [temp7]"=&f"(temp7),
+                  [temp8]"=&f"(temp8), [temp9]"=&f"(temp9),
+                  [temp10]"=&f"(temp10), [temp11]"=&f"(temp11),
+                  [ptr1]"+r"(ptr1), [ptr2]"+r"(ptr2),
+                  [ptr3]"+r"(ptr3)
+                :
+                : "memory"
+            );
+        }
+    }
+
+    {
+        float *buf1 = sce->ltp_state+1024;
+        float *buf2 = sce->ltp_state;
+        float *buf3 = sce->ret;
+        float *buf4 = sce->ltp_state+1024;
+        float *buf5 = saved_ltp;
+        float *buf6 = sce->ltp_state+2048;
+
+        /* loops unrolled 8 times */
+        __asm__ volatile (
+            ".set push                                    \n\t"
+            ".set noreorder                               \n\t"
+            "addiu   %[loop_end],   %[src],         4096  \n\t"
+            "addiu   %[loop_end1],  %[src1],        4096  \n\t"
+            "addiu   %[loop_end2],  %[src2],        4096  \n\t"
+        "1:                                               \n\t"
+            "lw      %[temp0],      0(%[src])             \n\t"
+            "lw      %[temp1],      4(%[src])             \n\t"
+            "lw      %[temp2],      8(%[src])             \n\t"
+            "lw      %[temp3],      12(%[src])            \n\t"
+            "lw      %[temp4],      16(%[src])            \n\t"
+            "lw      %[temp5],      20(%[src])            \n\t"
+            "lw      %[temp6],      24(%[src])            \n\t"
+            "lw      %[temp7],      28(%[src])            \n\t"
+            "addiu   %[src],        %[src],         32    \n\t"
+            "sw      %[temp0],      0(%[dst])             \n\t"
+            "sw      %[temp1],      4(%[dst])             \n\t"
+            "sw      %[temp2],      8(%[dst])             \n\t"
+            "sw      %[temp3],      12(%[dst])            \n\t"
+            "sw      %[temp4],      16(%[dst])            \n\t"
+            "sw      %[temp5],      20(%[dst])            \n\t"
+            "sw      %[temp6],      24(%[dst])            \n\t"
+            "sw      %[temp7],      28(%[dst])            \n\t"
+            "bne     %[src],        %[loop_end],    1b    \n\t"
+            " addiu  %[dst],        %[dst],         32    \n\t"
+        "2:                                               \n\t"
+            "lw      %[temp0],      0(%[src1])            \n\t"
+            "lw      %[temp1],      4(%[src1])            \n\t"
+            "lw      %[temp2],      8(%[src1])            \n\t"
+            "lw      %[temp3],      12(%[src1])           \n\t"
+            "lw      %[temp4],      16(%[src1])           \n\t"
+            "lw      %[temp5],      20(%[src1])           \n\t"
+            "lw      %[temp6],      24(%[src1])           \n\t"
+            "lw      %[temp7],      28(%[src1])           \n\t"
+            "addiu   %[src1],       %[src1],        32    \n\t"
+            "sw      %[temp0],      0(%[dst1])            \n\t"
+            "sw      %[temp1],      4(%[dst1])            \n\t"
+            "sw      %[temp2],      8(%[dst1])            \n\t"
+            "sw      %[temp3],      12(%[dst1])           \n\t"
+            "sw      %[temp4],      16(%[dst1])           \n\t"
+            "sw      %[temp5],      20(%[dst1])           \n\t"
+            "sw      %[temp6],      24(%[dst1])           \n\t"
+            "sw      %[temp7],      28(%[dst1])           \n\t"
+            "bne     %[src1],       %[loop_end1],   2b    \n\t"
+            " addiu  %[dst1],       %[dst1],        32    \n\t"
+        "3:                                               \n\t"
+            "lw      %[temp0],      0(%[src2])            \n\t"
+            "lw      %[temp1],      4(%[src2])            \n\t"
+            "lw      %[temp2],      8(%[src2])            \n\t"
+            "lw      %[temp3],      12(%[src2])           \n\t"
+            "lw      %[temp4],      16(%[src2])           \n\t"
+            "lw      %[temp5],      20(%[src2])           \n\t"
+            "lw      %[temp6],      24(%[src2])           \n\t"
+            "lw      %[temp7],      28(%[src2])           \n\t"
+            "addiu   %[src2],       %[src2],        32    \n\t"
+            "sw      %[temp0],      0(%[dst2])            \n\t"
+            "sw      %[temp1],      4(%[dst2])            \n\t"
+            "sw      %[temp2],      8(%[dst2])            \n\t"
+            "sw      %[temp3],      12(%[dst2])           \n\t"
+            "sw      %[temp4],      16(%[dst2])           \n\t"
+            "sw      %[temp5],      20(%[dst2])           \n\t"
+            "sw      %[temp6],      24(%[dst2])           \n\t"
+            "sw      %[temp7],      28(%[dst2])           \n\t"
+            "bne     %[src2],       %[loop_end2],   3b    \n\t"
+            " addiu  %[dst2],       %[dst2],        32    \n\t"
+            ".set pop                                     \n\t"
+
+            : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1),
+              [temp2]"=&r"(temp2), [temp3]"=&r"(temp3),
+              [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+              [temp6]"=&r"(temp6), [temp7]"=&r"(temp7),
+              [loop_end]"=&r"(loop_end), [loop_end1]"=&r"(loop_end1),
+              [loop_end2]"=&r"(loop_end2), [src]"+r"(buf1),
+              [dst]"+r"(buf2), [src1]"+r"(buf3), [dst1]"+r"(buf4),
+              [src2]"+r"(buf5), [dst2]"+r"(buf6)
+            :
+            : "memory"
+        );
+    }
+}
+#endif /* HAVE_MIPSFPU */
+#endif /* HAVE_INLINE_ASM */
+
+void ff_aacdec_init_mips(AACContext *c)
+{
+#if HAVE_INLINE_ASM
+    c->imdct_and_windowing         = imdct_and_windowing_mips;
+    c->apply_ltp                   = apply_ltp_mips;
+#if HAVE_MIPSFPU
+    c->update_ltp                  = update_ltp_mips;
+#endif /* HAVE_MIPSFPU */
+#endif /* HAVE_INLINE_ASM */
+}
diff --git a/libavcodec/mips/aacdec_mips.h b/libavcodec/mips/aacdec_mips.h
new file mode 100644
index 0000000..9ba3079
--- /dev/null
+++ b/libavcodec/mips/aacdec_mips.h
@@ -0,0 +1,249 @@
+/*
+ * 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:  Darko Laus      (darko@mips.com)
+ *           Djordje Pesut   (djordje@mips.com)
+ *           Mirjana Vulin   (mvulin@mips.com)
+ *
+ * AAC Spectral Band Replication decoding functions optimized for MIPS
+ *
+ * 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
+ * Reference: libavcodec/aacdec.c
+ */
+
+#ifndef AVCODEC_MIPS_AACDEC_FLOAT_H
+#define AVCODEC_MIPS_AACDEC_FLOAT_H
+
+#include "libavcodec/aac.h"
+
+#if HAVE_INLINE_ASM && HAVE_MIPSFPU
+static inline float *VMUL2_mips(float *dst, const float *v, unsigned idx,
+                           const float *scale)
+{
+    float temp0, temp1, temp2;
+    int temp3, temp4;
+    float *ret;
+
+    __asm__ volatile(
+        "andi    %[temp3],  %[idx],       15           \n\t"
+        "ext     %[temp4],  %[idx],       4,      4    \n\t"
+        "sll     %[temp3],  %[temp3],     2            \n\t"
+        "sll     %[temp4],  %[temp4],     2            \n\t"
+        "lwc1    %[temp2],  0(%[scale])                \n\t"
+        "lwxc1   %[temp0],  %[temp3](%[v])             \n\t"
+        "lwxc1   %[temp1],  %[temp4](%[v])             \n\t"
+        "mul.s   %[temp0],  %[temp0],     %[temp2]     \n\t"
+        "mul.s   %[temp1],  %[temp1],     %[temp2]     \n\t"
+        "addiu   %[ret],    %[dst],       8            \n\t"
+        "swc1    %[temp0],  0(%[dst])                  \n\t"
+        "swc1    %[temp1],  4(%[dst])                  \n\t"
+
+        : [temp0]"=&f"(temp0), [temp1]"=&f"(temp1),
+          [temp2]"=&f"(temp2), [temp3]"=&r"(temp3),
+          [temp4]"=&r"(temp4), [ret]"=&r"(ret)
+        : [idx]"r"(idx), [scale]"r"(scale), [v]"r"(v),
+          [dst]"r"(dst)
+        : "memory"
+    );
+    return ret;
+}
+
+static inline float *VMUL4_mips(float *dst, const float *v, unsigned idx,
+                           const float *scale)
+{
+    int temp0, temp1, temp2, temp3;
+    float temp4, temp5, temp6, temp7, temp8;
+    float *ret;
+
+    __asm__ volatile(
+        "andi    %[temp0],  %[idx],       3           \n\t"
+        "ext     %[temp1],  %[idx],       2,      2   \n\t"
+        "ext     %[temp2],  %[idx],       4,      2   \n\t"
+        "ext     %[temp3],  %[idx],       6,      2   \n\t"
+        "sll     %[temp0],  %[temp0],     2           \n\t"
+        "sll     %[temp1],  %[temp1],     2           \n\t"
+        "sll     %[temp2],  %[temp2],     2           \n\t"
+        "sll     %[temp3],  %[temp3],     2           \n\t"
+        "lwc1    %[temp4],  0(%[scale])               \n\t"
+        "lwxc1   %[temp5],  %[temp0](%[v])            \n\t"
+        "lwxc1   %[temp6],  %[temp1](%[v])            \n\t"
+        "lwxc1   %[temp7],  %[temp2](%[v])            \n\t"
+        "lwxc1   %[temp8],  %[temp3](%[v])            \n\t"
+        "mul.s   %[temp5],  %[temp5],     %[temp4]    \n\t"
+        "mul.s   %[temp6],  %[temp6],     %[temp4]    \n\t"
+        "mul.s   %[temp7],  %[temp7],     %[temp4]    \n\t"
+        "mul.s   %[temp8],  %[temp8],     %[temp4]    \n\t"
+        "addiu   %[ret],    %[dst],       16          \n\t"
+        "swc1    %[temp5],  0(%[dst])                 \n\t"
+        "swc1    %[temp6],  4(%[dst])                 \n\t"
+        "swc1    %[temp7],  8(%[dst])                 \n\t"
+        "swc1    %[temp8],  12(%[dst])                \n\t"
+
+        : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1),
+          [temp2]"=&r"(temp2), [temp3]"=&r"(temp3),
+          [temp4]"=&f"(temp4), [temp5]"=&f"(temp5),
+          [temp6]"=&f"(temp6), [temp7]"=&f"(temp7),
+          [temp8]"=&f"(temp8), [ret]"=&r"(ret)
+        : [idx]"r"(idx), [scale]"r"(scale), [v]"r"(v),
+          [dst]"r"(dst)
+        : "memory"
+    );
+    return ret;
+}
+
+static inline float *VMUL2S_mips(float *dst, const float *v, unsigned idx,
+                            unsigned sign, const float *scale)
+{
+    int temp0, temp1, temp2, temp3, temp4, temp5;
+    float temp6, temp7, temp8, temp9;
+    float *ret;
+
+    __asm__ volatile(
+        "andi    %[temp0],  %[idx],       15         \n\t"
+        "ext     %[temp1],  %[idx],       4,     4   \n\t"
+        "lw      %[temp4],  0(%[scale])              \n\t"
+        "srl     %[temp2],  %[sign],      1          \n\t"
+        "sll     %[temp3],  %[sign],      31         \n\t"
+        "sll     %[temp2],  %[temp2],     31         \n\t"
+        "sll     %[temp0],  %[temp0],     2          \n\t"
+        "sll     %[temp1],  %[temp1],     2          \n\t"
+        "lwxc1   %[temp8],  %[temp0](%[v])           \n\t"
+        "lwxc1   %[temp9],  %[temp1](%[v])           \n\t"
+        "xor     %[temp5],  %[temp4],     %[temp2]   \n\t"
+        "xor     %[temp4],  %[temp4],     %[temp3]   \n\t"
+        "mtc1    %[temp5],  %[temp6]                 \n\t"
+        "mtc1    %[temp4],  %[temp7]                 \n\t"
+        "mul.s   %[temp8],  %[temp8],     %[temp6]   \n\t"
+        "mul.s   %[temp9],  %[temp9],     %[temp7]   \n\t"
+        "addiu   %[ret],    %[dst],       8          \n\t"
+        "swc1    %[temp8],  0(%[dst])                \n\t"
+        "swc1    %[temp9],  4(%[dst])                \n\t"
+
+        : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1),
+          [temp2]"=&r"(temp2), [temp3]"=&r"(temp3),
+          [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+          [temp6]"=&f"(temp6), [temp7]"=&f"(temp7),
+          [temp8]"=&f"(temp8), [temp9]"=&f"(temp9),
+          [ret]"=&r"(ret)
+        : [idx]"r"(idx), [scale]"r"(scale), [v]"r"(v),
+          [dst]"r"(dst), [sign]"r"(sign)
+        : "memory"
+    );
+    return ret;
+}
+
+static inline float *VMUL4S_mips(float *dst, const float *v, unsigned idx,
+                            unsigned sign, const float *scale)
+{
+    int temp0, temp1, temp2, temp3, temp4;
+    float temp10, temp11, temp12, temp13, temp14, temp15, temp16, temp17;
+    float *ret;
+    unsigned int mask = 1U << 31;
+
+    __asm__ volatile(
+        "lw      %[temp0],   0(%[scale])               \n\t"
+        "and     %[temp1],   %[idx],       3           \n\t"
+        "ext     %[temp2],   %[idx],       2,      2   \n\t"
+        "ext     %[temp3],   %[idx],       4,      2   \n\t"
+        "ext     %[temp4],   %[idx],       6,      2   \n\t"
+        "sll     %[temp1],   %[temp1],     2           \n\t"
+        "sll     %[temp2],   %[temp2],     2           \n\t"
+        "sll     %[temp3],   %[temp3],     2           \n\t"
+        "sll     %[temp4],   %[temp4],     2           \n\t"
+        "lwxc1   %[temp10],  %[temp1](%[v])            \n\t"
+        "lwxc1   %[temp11],  %[temp2](%[v])            \n\t"
+        "lwxc1   %[temp12],  %[temp3](%[v])            \n\t"
+        "lwxc1   %[temp13],  %[temp4](%[v])            \n\t"
+        "and     %[temp1],   %[sign],      %[mask]     \n\t"
+        "ext     %[temp2],   %[idx],       12,     1   \n\t"
+        "ext     %[temp3],   %[idx],       13,     1   \n\t"
+        "ext     %[temp4],   %[idx],       14,     1   \n\t"
+        "sllv    %[sign],    %[sign],      %[temp2]    \n\t"
+        "xor     %[temp1],   %[temp0],     %[temp1]    \n\t"
+        "and     %[temp2],   %[sign],      %[mask]     \n\t"
+        "mtc1    %[temp1],   %[temp14]                 \n\t"
+        "xor     %[temp2],   %[temp0],     %[temp2]    \n\t"
+        "sllv    %[sign],    %[sign],      %[temp3]    \n\t"
+        "mtc1    %[temp2],   %[temp15]                 \n\t"
+        "and     %[temp3],   %[sign],      %[mask]     \n\t"
+        "sllv    %[sign],    %[sign],      %[temp4]    \n\t"
+        "xor     %[temp3],   %[temp0],     %[temp3]    \n\t"
+        "and     %[temp4],   %[sign],      %[mask]     \n\t"
+        "mtc1    %[temp3],   %[temp16]                 \n\t"
+        "xor     %[temp4],   %[temp0],     %[temp4]    \n\t"
+        "mtc1    %[temp4],   %[temp17]                 \n\t"
+        "mul.s   %[temp10],  %[temp10],    %[temp14]   \n\t"
+        "mul.s   %[temp11],  %[temp11],    %[temp15]   \n\t"
+        "mul.s   %[temp12],  %[temp12],    %[temp16]   \n\t"
+        "mul.s   %[temp13],  %[temp13],    %[temp17]   \n\t"
+        "addiu   %[ret],     %[dst],       16          \n\t"
+        "swc1    %[temp10],  0(%[dst])                 \n\t"
+        "swc1    %[temp11],  4(%[dst])                 \n\t"
+        "swc1    %[temp12],  8(%[dst])                 \n\t"
+        "swc1    %[temp13],  12(%[dst])                \n\t"
+
+        : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1),
+          [temp2]"=&r"(temp2), [temp3]"=&r"(temp3),
+          [temp4]"=&r"(temp4), [temp10]"=&f"(temp10),
+          [temp11]"=&f"(temp11), [temp12]"=&f"(temp12),
+          [temp13]"=&f"(temp13), [temp14]"=&f"(temp14),
+          [temp15]"=&f"(temp15), [temp16]"=&f"(temp16),
+          [temp17]"=&f"(temp17), [ret]"=&r"(ret),
+          [sign]"+r"(sign)
+        : [idx]"r"(idx), [scale]"r"(scale), [v]"r"(v),
+          [dst]"r"(dst), [mask]"r"(mask)
+        : "memory"
+    );
+    return ret;
+}
+
+#define VMUL2 VMUL2_mips
+#define VMUL4 VMUL4_mips
+#define VMUL2S VMUL2S_mips
+#define VMUL4S VMUL4S_mips
+#endif /* HAVE_INLINE_ASM && HAVE_MIPSFPU */
+
+#endif /* AVCODEC_MIPS_AACDEC_FLOAT_H */
diff --git a/libavcodec/mips/aacpsdsp_mips.c b/libavcodec/mips/aacpsdsp_mips.c
new file mode 100644
index 0000000..4730a7f
--- /dev/null
+++ b/libavcodec/mips/aacpsdsp_mips.c
@@ -0,0 +1,459 @@
+/*
+ * 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:  Darko Laus      (darko@mips.com)
+ *           Djordje Pesut   (djordje@mips.com)
+ *           Mirjana Vulin   (mvulin@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
+ * Reference: libavcodec/aacpsdsp.c
+ */
+
+#include "config.h"
+#include "libavcodec/aacpsdsp.h"
+
+#if HAVE_INLINE_ASM
+static void ps_hybrid_analysis_ileave_mips(float (*out)[32][2], float L[2][38][64],
+                                        int i, int len)
+{
+    int temp0, temp1, temp2, temp3;
+    int temp4, temp5, temp6, temp7;
+    float *out1=&out[i][0][0];
+    float *L1=&L[0][0][i];
+    float *j=out1+ len*2;
+
+    for (; i < 64; i++) {
+
+        /* loop unrolled 8 times */
+        __asm__ volatile (
+        "1:                                          \n\t"
+            "lw      %[temp0],   0(%[L1])            \n\t"
+            "lw      %[temp1],   9728(%[L1])         \n\t"
+            "lw      %[temp2],   256(%[L1])          \n\t"
+            "lw      %[temp3],   9984(%[L1])         \n\t"
+            "lw      %[temp4],   512(%[L1])          \n\t"
+            "lw      %[temp5],   10240(%[L1])        \n\t"
+            "lw      %[temp6],   768(%[L1])          \n\t"
+            "lw      %[temp7],   10496(%[L1])        \n\t"
+            "sw      %[temp0],   0(%[out1])          \n\t"
+            "sw      %[temp1],   4(%[out1])          \n\t"
+            "sw      %[temp2],   8(%[out1])          \n\t"
+            "sw      %[temp3],   12(%[out1])         \n\t"
+            "sw      %[temp4],   16(%[out1])         \n\t"
+            "sw      %[temp5],   20(%[out1])         \n\t"
+            "sw      %[temp6],   24(%[out1])         \n\t"
+            "sw      %[temp7],   28(%[out1])         \n\t"
+            "addiu   %[out1],    %[out1],      32    \n\t"
+            "addiu   %[L1],      %[L1],        1024  \n\t"
+            "bne     %[out1],    %[j],         1b    \n\t"
+
+            : [out1]"+r"(out1), [L1]"+r"(L1), [j]"+r"(j),
+              [temp0]"=&r"(temp0), [temp1]"=&r"(temp1),
+              [temp2]"=&r"(temp2), [temp3]"=&r"(temp3),
+              [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+              [temp6]"=&r"(temp6), [temp7]"=&r"(temp7)
+            : [len]"r"(len)
+            : "memory"
+        );
+        out1-=(len<<1)-64;
+        L1-=(len<<6)-1;
+        j+=len*2;
+    }
+}
+
+static void ps_hybrid_synthesis_deint_mips(float out[2][38][64],
+                                        float (*in)[32][2],
+                                        int i, int len)
+{
+    int n;
+    int temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
+    float *out1 = (float*)out + i;
+    float *out2 = (float*)out + 2432 + i;
+    float *in1 = (float*)in + 64 * i;
+    float *in2 = (float*)in + 64 * i + 1;
+
+    for (; i < 64; i++) {
+        for (n = 0; n < 7; n++) {
+
+            /* loop unrolled 8 times */
+            __asm__ volatile (
+                 "lw      %[temp0],   0(%[in1])               \n\t"
+                 "lw      %[temp1],   0(%[in2])               \n\t"
+                 "lw      %[temp2],   8(%[in1])               \n\t"
+                 "lw      %[temp3],   8(%[in2])               \n\t"
+                 "lw      %[temp4],   16(%[in1])              \n\t"
+                 "lw      %[temp5],   16(%[in2])              \n\t"
+                 "lw      %[temp6],   24(%[in1])              \n\t"
+                 "lw      %[temp7],   24(%[in2])              \n\t"
+                 "addiu   %[out1],    %[out1],         1024   \n\t"
+                 "addiu   %[out2],    %[out2],         1024   \n\t"
+                 "addiu   %[in1],     %[in1],          32     \n\t"
+                 "addiu   %[in2],     %[in2],          32     \n\t"
+                 "sw      %[temp0],   -1024(%[out1])          \n\t"
+                 "sw      %[temp1],   -1024(%[out2])          \n\t"
+                 "sw      %[temp2],   -768(%[out1])           \n\t"
+                 "sw      %[temp3],   -768(%[out2])           \n\t"
+                 "sw      %[temp4],   -512(%[out1])           \n\t"
+                 "sw      %[temp5],   -512(%[out2])           \n\t"
+                 "sw      %[temp6],   -256(%[out1])           \n\t"
+                 "sw      %[temp7],   -256(%[out2])           \n\t"
+
+                 : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1),
+                   [temp2]"=&r"(temp2), [temp3]"=&r"(temp3),
+                   [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+                   [temp6]"=&r"(temp6), [temp7]"=&r"(temp7),
+                   [out1]"+r"(out1), [out2]"+r"(out2),
+                   [in1]"+r"(in1), [in2]"+r"(in2)
+                 :
+                 : "memory"
+            );
+        }
+        /* loop unrolled 8 times */
+        __asm__ volatile (
+            "lw      %[temp0],   0(%[in1])               \n\t"
+            "lw      %[temp1],   0(%[in2])               \n\t"
+            "lw      %[temp2],   8(%[in1])               \n\t"
+            "lw      %[temp3],   8(%[in2])               \n\t"
+            "lw      %[temp4],   16(%[in1])              \n\t"
+            "lw      %[temp5],   16(%[in2])              \n\t"
+            "lw      %[temp6],   24(%[in1])              \n\t"
+            "lw      %[temp7],   24(%[in2])              \n\t"
+            "addiu   %[out1],    %[out1],        -7164   \n\t"
+            "addiu   %[out2],    %[out2],        -7164   \n\t"
+            "addiu   %[in1],     %[in1],         32      \n\t"
+            "addiu   %[in2],     %[in2],         32      \n\t"
+            "sw      %[temp0],   7164(%[out1])           \n\t"
+            "sw      %[temp1],   7164(%[out2])           \n\t"
+            "sw      %[temp2],   7420(%[out1])           \n\t"
+            "sw      %[temp3],   7420(%[out2])           \n\t"
+            "sw      %[temp4],   7676(%[out1])           \n\t"
+            "sw      %[temp5],   7676(%[out2])           \n\t"
+            "sw      %[temp6],   7932(%[out1])           \n\t"
+            "sw      %[temp7],   7932(%[out2])           \n\t"
+
+            : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1),
+              [temp2]"=&r"(temp2), [temp3]"=&r"(temp3),
+              [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+              [temp6]"=&r"(temp6), [temp7]"=&r"(temp7),
+              [out1]"+r"(out1), [out2]"+r"(out2),
+              [in1]"+r"(in1), [in2]"+r"(in2)
+            :
+            : "memory"
+        );
+    }
+}
+
+#if HAVE_MIPSFPU
+static void ps_add_squares_mips(float *dst, const float (*src)[2], int n)
+{
+    int i;
+    float temp0, temp1, temp2, temp3, temp4, temp5;
+    float temp6, temp7, temp8, temp9, temp10, temp11;
+    float *src0 = (float*)&src[0][0];
+    float *dst0 = &dst[0];
+
+    for (i = 0; i < 8; i++) {
+        /* loop unrolled 4 times */
+        __asm__ volatile (
+            "lwc1     %[temp0],    0(%[src0])                          \n\t"
+            "lwc1     %[temp1],    4(%[src0])                          \n\t"
+            "lwc1     %[temp2],    8(%[src0])                          \n\t"
+            "lwc1     %[temp3],    12(%[src0])                         \n\t"
+            "lwc1     %[temp4],    16(%[src0])                         \n\t"
+            "lwc1     %[temp5],    20(%[src0])                         \n\t"
+            "lwc1     %[temp6],    24(%[src0])                         \n\t"
+            "lwc1     %[temp7],    28(%[src0])                         \n\t"
+            "lwc1     %[temp8],    0(%[dst0])                          \n\t"
+            "lwc1     %[temp9],    4(%[dst0])                          \n\t"
+            "lwc1     %[temp10],   8(%[dst0])                          \n\t"
+            "lwc1     %[temp11],   12(%[dst0])                         \n\t"
+            "mul.s    %[temp1],    %[temp1],    %[temp1]               \n\t"
+            "mul.s    %[temp3],    %[temp3],    %[temp3]               \n\t"
+            "mul.s    %[temp5],    %[temp5],    %[temp5]               \n\t"
+            "mul.s    %[temp7],    %[temp7],    %[temp7]               \n\t"
+            "madd.s   %[temp0],    %[temp1],    %[temp0],   %[temp0]   \n\t"
+            "madd.s   %[temp2],    %[temp3],    %[temp2],   %[temp2]   \n\t"
+            "madd.s   %[temp4],    %[temp5],    %[temp4],   %[temp4]   \n\t"
+            "madd.s   %[temp6],    %[temp7],    %[temp6],   %[temp6]   \n\t"
+            "add.s    %[temp0],    %[temp8],    %[temp0]               \n\t"
+            "add.s    %[temp2],    %[temp9],    %[temp2]               \n\t"
+            "add.s    %[temp4],    %[temp10],   %[temp4]               \n\t"
+            "add.s    %[temp6],    %[temp11],   %[temp6]               \n\t"
+            "swc1     %[temp0],    0(%[dst0])                          \n\t"
+            "swc1     %[temp2],    4(%[dst0])                          \n\t"
+            "swc1     %[temp4],    8(%[dst0])                          \n\t"
+            "swc1     %[temp6],    12(%[dst0])                         \n\t"
+            "addiu    %[dst0],     %[dst0],     16                     \n\t"
+            "addiu    %[src0],     %[src0],     32                     \n\t"
+
+            : [temp0]"=&f"(temp0), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
+              [temp3]"=&f"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5),
+              [temp6]"=&f"(temp6), [temp7]"=&f"(temp7), [temp8]"=&f"(temp8),
+              [temp9]"=&f"(temp9), [dst0]"+r"(dst0), [src0]"+r"(src0),
+              [temp10]"=&f"(temp10), [temp11]"=&f"(temp11)
+            :
+            : "memory"
+        );
+   }
+}
+
+static void ps_mul_pair_single_mips(float (*dst)[2], float (*src0)[2], float *src1,
+                                 int n)
+{
+    float temp0, temp1, temp2;
+    float *p_d, *p_s0, *p_s1, *end;
+    p_d = &dst[0][0];
+    p_s0 = &src0[0][0];
+    p_s1 = &src1[0];
+    end = p_s1 + n;
+
+    __asm__ volatile(
+        ".set push                                      \n\t"
+        ".set noreorder                                 \n\t"
+        "1:                                             \n\t"
+        "lwc1     %[temp2],   0(%[p_s1])                \n\t"
+        "lwc1     %[temp0],   0(%[p_s0])                \n\t"
+        "lwc1     %[temp1],   4(%[p_s0])                \n\t"
+        "addiu    %[p_d],     %[p_d],       8           \n\t"
+        "mul.s    %[temp0],   %[temp0],     %[temp2]    \n\t"
+        "mul.s    %[temp1],   %[temp1],     %[temp2]    \n\t"
+        "addiu    %[p_s0],    %[p_s0],      8           \n\t"
+        "swc1     %[temp0],   -8(%[p_d])                \n\t"
+        "swc1     %[temp1],   -4(%[p_d])                \n\t"
+        "bne      %[p_s1],    %[end],       1b          \n\t"
+        " addiu   %[p_s1],    %[p_s1],      4           \n\t"
+        ".set pop                                       \n\t"
+
+        : [temp0]"=&f"(temp0), [temp1]"=&f"(temp1),
+          [temp2]"=&f"(temp2), [p_d]"+r"(p_d),
+          [p_s0]"+r"(p_s0), [p_s1]"+r"(p_s1)
+        : [end]"r"(end)
+        : "memory"
+    );
+}
+
+static void ps_decorrelate_mips(float (*out)[2], float (*delay)[2],
+                             float (*ap_delay)[PS_QMF_TIME_SLOTS + PS_MAX_AP_DELAY][2],
+                             const float phi_fract[2], float (*Q_fract)[2],
+                             const float *transient_gain,
+                             float g_decay_slope,
+                             int len)
+{
+    float *p_delay = &delay[0][0];
+    float *p_out = &out[0][0];
+    float *p_ap_delay = &ap_delay[0][0][0];
+    float *p_t_gain = (float*)transient_gain;
+    float *p_Q_fract = &Q_fract[0][0];
+    float ag0, ag1, ag2;
+    float phi_fract0 = phi_fract[0];
+    float phi_fract1 = phi_fract[1];
+    float temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8, temp9;
+
+    len = (int)((int*)p_delay + (len << 1));
+
+    /* merged 2 loops */
+    __asm__ volatile(
+        ".set    push                                                    \n\t"
+        ".set    noreorder                                               \n\t"
+        "li.s    %[ag0],        0.65143905753106                         \n\t"
+        "li.s    %[ag1],        0.56471812200776                         \n\t"
+        "li.s    %[ag2],        0.48954165955695                         \n\t"
+        "mul.s   %[ag0],        %[ag0],        %[g_decay_slope]          \n\t"
+        "mul.s   %[ag1],        %[ag1],        %[g_decay_slope]          \n\t"
+        "mul.s   %[ag2],        %[ag2],        %[g_decay_slope]          \n\t"
+    "1:                                                                  \n\t"
+        "lwc1    %[temp0],      0(%[p_delay])                            \n\t"
+        "lwc1    %[temp1],      4(%[p_delay])                            \n\t"
+        "lwc1    %[temp4],      16(%[p_ap_delay])                        \n\t"
+        "lwc1    %[temp5],      20(%[p_ap_delay])                        \n\t"
+        "mul.s   %[temp3],      %[temp0],      %[phi_fract1]             \n\t"
+        "lwc1    %[temp6],      0(%[p_Q_fract])                          \n\t"
+        "mul.s   %[temp2],      %[temp1],      %[phi_fract1]             \n\t"
+        "lwc1    %[temp7],      4(%[p_Q_fract])                          \n\t"
+        "madd.s  %[temp3],      %[temp3],      %[temp1], %[phi_fract0]   \n\t"
+        "msub.s  %[temp2],      %[temp2],      %[temp0], %[phi_fract0]   \n\t"
+        "mul.s   %[temp8],      %[temp5],      %[temp7]                  \n\t"
+        "mul.s   %[temp9],      %[temp4],      %[temp7]                  \n\t"
+        "lwc1    %[temp7],      12(%[p_Q_fract])                         \n\t"
+        "mul.s   %[temp0],      %[ag0],        %[temp2]                  \n\t"
+        "mul.s   %[temp1],      %[ag0],        %[temp3]                  \n\t"
+        "msub.s  %[temp8],      %[temp8],      %[temp4], %[temp6]        \n\t"
+        "lwc1    %[temp4],      304(%[p_ap_delay])                       \n\t"
+        "madd.s  %[temp9],      %[temp9],      %[temp5], %[temp6]        \n\t"
+        "lwc1    %[temp5],      308(%[p_ap_delay])                       \n\t"
+        "sub.s   %[temp0],      %[temp8],      %[temp0]                  \n\t"
+        "sub.s   %[temp1],      %[temp9],      %[temp1]                  \n\t"
+        "madd.s  %[temp2],      %[temp2],      %[ag0],   %[temp0]        \n\t"
+        "lwc1    %[temp6],      8(%[p_Q_fract])                          \n\t"
+        "madd.s  %[temp3],      %[temp3],      %[ag0],   %[temp1]        \n\t"
+        "mul.s   %[temp8],      %[temp5],      %[temp7]                  \n\t"
+        "mul.s   %[temp9],      %[temp4],      %[temp7]                  \n\t"
+        "lwc1    %[temp7],      20(%[p_Q_fract])                         \n\t"
+        "msub.s  %[temp8],      %[temp8],      %[temp4], %[temp6]        \n\t"
+        "swc1    %[temp2],      40(%[p_ap_delay])                        \n\t"
+        "mul.s   %[temp2],      %[ag1],        %[temp0]                  \n\t"
+        "swc1    %[temp3],      44(%[p_ap_delay])                        \n\t"
+        "mul.s   %[temp3],      %[ag1],        %[temp1]                  \n\t"
+        "lwc1    %[temp4],      592(%[p_ap_delay])                       \n\t"
+        "madd.s  %[temp9],      %[temp9],      %[temp5], %[temp6]        \n\t"
+        "lwc1    %[temp5],      596(%[p_ap_delay])                       \n\t"
+        "sub.s   %[temp2],      %[temp8],      %[temp2]                  \n\t"
+        "sub.s   %[temp3],      %[temp9],      %[temp3]                  \n\t"
+        "lwc1    %[temp6],      16(%[p_Q_fract])                         \n\t"
+        "madd.s  %[temp0],      %[temp0],      %[ag1],   %[temp2]        \n\t"
+        "madd.s  %[temp1],      %[temp1],      %[ag1],   %[temp3]        \n\t"
+        "mul.s   %[temp8],      %[temp5],      %[temp7]                  \n\t"
+        "mul.s   %[temp9],      %[temp4],      %[temp7]                  \n\t"
+        "msub.s  %[temp8],      %[temp8],      %[temp4], %[temp6]        \n\t"
+        "madd.s  %[temp9],      %[temp9],      %[temp5], %[temp6]        \n\t"
+        "swc1    %[temp0],      336(%[p_ap_delay])                       \n\t"
+        "mul.s   %[temp0],      %[ag2],        %[temp2]                  \n\t"
+        "swc1    %[temp1],      340(%[p_ap_delay])                       \n\t"
+        "mul.s   %[temp1],      %[ag2],        %[temp3]                  \n\t"
+        "lwc1    %[temp4],      0(%[p_t_gain])                           \n\t"
+        "sub.s   %[temp0],      %[temp8],      %[temp0]                  \n\t"
+        "addiu   %[p_ap_delay], %[p_ap_delay], 8                         \n\t"
+        "sub.s   %[temp1],      %[temp9],      %[temp1]                  \n\t"
+        "addiu   %[p_t_gain],   %[p_t_gain],   4                         \n\t"
+        "madd.s  %[temp2],      %[temp2],      %[ag2],   %[temp0]        \n\t"
+        "addiu   %[p_delay],    %[p_delay],    8                         \n\t"
+        "madd.s  %[temp3],      %[temp3],      %[ag2],   %[temp1]        \n\t"
+        "addiu   %[p_out],      %[p_out],      8                         \n\t"
+        "mul.s   %[temp5],      %[temp4],      %[temp0]                  \n\t"
+        "mul.s   %[temp6],      %[temp4],      %[temp1]                  \n\t"
+        "swc1    %[temp2],      624(%[p_ap_delay])                       \n\t"
+        "swc1    %[temp3],      628(%[p_ap_delay])                       \n\t"
+        "swc1    %[temp5],      -8(%[p_out])                             \n\t"
+        "swc1    %[temp6],      -4(%[p_out])                             \n\t"
+        "bne     %[p_delay],    %[len],        1b                        \n\t"
+        " swc1   %[temp6],      -4(%[p_out])                             \n\t"
+        ".set    pop                                                     \n\t"
+
+        : [temp0]"=&f"(temp0), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
+          [temp3]"=&f"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5),
+          [temp6]"=&f"(temp6), [temp7]"=&f"(temp7), [temp8]"=&f"(temp8),
+          [temp9]"=&f"(temp9), [p_delay]"+r"(p_delay), [p_ap_delay]"+r"(p_ap_delay),
+          [p_Q_fract]"+r"(p_Q_fract), [p_t_gain]"+r"(p_t_gain), [p_out]"+r"(p_out),
+          [ag0]"=&f"(ag0), [ag1]"=&f"(ag1), [ag2]"=&f"(ag2)
+        : [phi_fract0]"f"(phi_fract0), [phi_fract1]"f"(phi_fract1),
+          [len]"r"(len), [g_decay_slope]"f"(g_decay_slope)
+        : "memory"
+    );
+}
+
+static void ps_stereo_interpolate_mips(float (*l)[2], float (*r)[2],
+                                    float h[2][4], float h_step[2][4],
+                                    int len)
+{
+    float h0 = h[0][0];
+    float h1 = h[0][1];
+    float h2 = h[0][2];
+    float h3 = h[0][3];
+    float hs0 = h_step[0][0];
+    float hs1 = h_step[0][1];
+    float hs2 = h_step[0][2];
+    float hs3 = h_step[0][3];
+    float temp0, temp1, temp2, temp3;
+    float l_re, l_im, r_re, r_im;
+
+    len = (int)((int*)l + (len << 1));
+
+    __asm__ volatile(
+        ".set    push                                     \n\t"
+        ".set    noreorder                                \n\t"
+    "1:                                                   \n\t"
+        "add.s   %[h0],     %[h0],     %[hs0]             \n\t"
+        "lwc1    %[l_re],   0(%[l])                       \n\t"
+        "add.s   %[h1],     %[h1],     %[hs1]             \n\t"
+        "lwc1    %[r_re],   0(%[r])                       \n\t"
+        "add.s   %[h2],     %[h2],     %[hs2]             \n\t"
+        "lwc1    %[l_im],   4(%[l])                       \n\t"
+        "add.s   %[h3],     %[h3],     %[hs3]             \n\t"
+        "lwc1    %[r_im],   4(%[r])                       \n\t"
+        "mul.s   %[temp0],  %[h0],     %[l_re]            \n\t"
+        "addiu   %[l],      %[l],      8                  \n\t"
+        "mul.s   %[temp2],  %[h1],     %[l_re]            \n\t"
+        "addiu   %[r],      %[r],      8                  \n\t"
+        "madd.s  %[temp0],  %[temp0],  %[h2],   %[r_re]   \n\t"
+        "madd.s  %[temp2],  %[temp2],  %[h3],   %[r_re]   \n\t"
+        "mul.s   %[temp1],  %[h0],     %[l_im]            \n\t"
+        "mul.s   %[temp3],  %[h1],     %[l_im]            \n\t"
+        "madd.s  %[temp1],  %[temp1],  %[h2],   %[r_im]   \n\t"
+        "madd.s  %[temp3],  %[temp3],  %[h3],   %[r_im]   \n\t"
+        "swc1    %[temp0],  -8(%[l])                      \n\t"
+        "swc1    %[temp2],  -8(%[r])                      \n\t"
+        "swc1    %[temp1],  -4(%[l])                      \n\t"
+        "bne     %[l],      %[len],    1b                 \n\t"
+        " swc1   %[temp3],  -4(%[r])                      \n\t"
+        ".set    pop                                      \n\t"
+
+        : [temp0]"=&f"(temp0), [temp1]"=&f"(temp1),
+          [temp2]"=&f"(temp2), [temp3]"=&f"(temp3),
+          [h0]"+f"(h0), [h1]"+f"(h1), [h2]"+f"(h2),
+          [h3]"+f"(h3), [l]"+r"(l), [r]"+r"(r),
+          [l_re]"=&f"(l_re), [l_im]"=&f"(l_im),
+          [r_re]"=&f"(r_re), [r_im]"=&f"(r_im)
+        : [hs0]"f"(hs0), [hs1]"f"(hs1), [hs2]"f"(hs2),
+          [hs3]"f"(hs3), [len]"r"(len)
+        : "memory"
+    );
+}
+#endif /* HAVE_MIPSFPU */
+#endif /* HAVE_INLINE_ASM */
+
+void ff_psdsp_init_mips(PSDSPContext *s)
+{
+#if HAVE_INLINE_ASM
+    s->hybrid_analysis_ileave = ps_hybrid_analysis_ileave_mips;
+    s->hybrid_synthesis_deint = ps_hybrid_synthesis_deint_mips;
+#if HAVE_MIPSFPU
+    s->add_squares            = ps_add_squares_mips;
+    s->mul_pair_single        = ps_mul_pair_single_mips;
+    s->decorrelate            = ps_decorrelate_mips;
+    s->stereo_interpolate[0]  = ps_stereo_interpolate_mips;
+#endif /* HAVE_MIPSFPU */
+#endif /* HAVE_INLINE_ASM */
+}
diff --git a/libavcodec/mips/aacsbr_mips.c b/libavcodec/mips/aacsbr_mips.c
new file mode 100644
index 0000000..53a5fd0
--- /dev/null
+++ b/libavcodec/mips/aacsbr_mips.c
@@ -0,0 +1,618 @@
+/*
+ * 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:  Djordje Pesut   (djordje@mips.com)
+ *           Mirjana Vulin   (mvulin@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
+ * Reference: libavcodec/aacsbr.c
+ */
+
+#include "libavcodec/aac.h"
+#include "libavcodec/aacsbr.h"
+
+#define ENVELOPE_ADJUSTMENT_OFFSET 2
+
+#if HAVE_INLINE_ASM
+static int sbr_lf_gen_mips(AACContext *ac, SpectralBandReplication *sbr,
+                      float X_low[32][40][2], const float W[2][32][32][2],
+                      int buf_idx)
+{
+    int i, k;
+    int temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
+    float *p_x_low = &X_low[0][8][0];
+    float *p_w = (float*)&W[buf_idx][0][0][0];
+    float *p_x1_low = &X_low[0][0][0];
+    float *p_w1 = (float*)&W[1-buf_idx][24][0][0];
+
+    float *loop_end=p_x1_low + 2560;
+
+    /* loop unrolled 8 times */
+    __asm__ volatile (
+    "1:                                                 \n\t"
+        "sw     $0,            0(%[p_x1_low])           \n\t"
+        "sw     $0,            4(%[p_x1_low])           \n\t"
+        "sw     $0,            8(%[p_x1_low])           \n\t"
+        "sw     $0,            12(%[p_x1_low])          \n\t"
+        "sw     $0,            16(%[p_x1_low])          \n\t"
+        "sw     $0,            20(%[p_x1_low])          \n\t"
+        "sw     $0,            24(%[p_x1_low])          \n\t"
+        "sw     $0,            28(%[p_x1_low])          \n\t"
+        "addiu  %[p_x1_low],   %[p_x1_low],      32     \n\t"
+        "bne    %[p_x1_low],   %[loop_end],      1b     \n\t"
+        "addiu  %[p_x1_low],   %[p_x1_low],      -10240 \n\t"
+
+        : [p_x1_low]"+r"(p_x1_low)
+        : [loop_end]"r"(loop_end)
+        : "memory"
+    );
+
+    for (k = 0; k < sbr->kx[1]; k++) {
+        for (i = 0; i < 32; i+=4) {
+            /* loop unrolled 4 times */
+            __asm__ volatile (
+                "lw     %[temp0],   0(%[p_w])               \n\t"
+                "lw     %[temp1],   4(%[p_w])               \n\t"
+                "lw     %[temp2],   256(%[p_w])             \n\t"
+                "lw     %[temp3],   260(%[p_w])             \n\t"
+                "lw     %[temp4],   512(%[p_w])             \n\t"
+                "lw     %[temp5],   516(%[p_w])             \n\t"
+                "lw     %[temp6],   768(%[p_w])             \n\t"
+                "lw     %[temp7],   772(%[p_w])             \n\t"
+                "sw     %[temp0],   0(%[p_x_low])           \n\t"
+                "sw     %[temp1],   4(%[p_x_low])           \n\t"
+                "sw     %[temp2],   8(%[p_x_low])           \n\t"
+                "sw     %[temp3],   12(%[p_x_low])          \n\t"
+                "sw     %[temp4],   16(%[p_x_low])          \n\t"
+                "sw     %[temp5],   20(%[p_x_low])          \n\t"
+                "sw     %[temp6],   24(%[p_x_low])          \n\t"
+                "sw     %[temp7],   28(%[p_x_low])          \n\t"
+                "addiu  %[p_x_low], %[p_x_low],     32      \n\t"
+                "addiu  %[p_w],     %[p_w],         1024    \n\t"
+
+                : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1),
+                  [temp2]"=&r"(temp2), [temp3]"=&r"(temp3),
+                  [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+                  [temp6]"=&r"(temp6), [temp7]"=&r"(temp7),
+                  [p_w]"+r"(p_w), [p_x_low]"+r"(p_x_low)
+                :
+                : "memory"
+            );
+        }
+        p_x_low += 16;
+        p_w -= 2046;
+    }
+
+    for (k = 0; k < sbr->kx[0]; k++) {
+        for (i = 0; i < 2; i++) {
+
+            /* loop unrolled 4 times */
+            __asm__ volatile (
+                "lw     %[temp0],    0(%[p_w1])             \n\t"
+                "lw     %[temp1],    4(%[p_w1])             \n\t"
+                "lw     %[temp2],    256(%[p_w1])           \n\t"
+                "lw     %[temp3],    260(%[p_w1])           \n\t"
+                "lw     %[temp4],    512(%[p_w1])           \n\t"
+                "lw     %[temp5],    516(%[p_w1])           \n\t"
+                "lw     %[temp6],    768(%[p_w1])           \n\t"
+                "lw     %[temp7],    772(%[p_w1])           \n\t"
+                "sw     %[temp0],    0(%[p_x1_low])         \n\t"
+                "sw     %[temp1],    4(%[p_x1_low])         \n\t"
+                "sw     %[temp2],    8(%[p_x1_low])         \n\t"
+                "sw     %[temp3],    12(%[p_x1_low])        \n\t"
+                "sw     %[temp4],    16(%[p_x1_low])        \n\t"
+                "sw     %[temp5],    20(%[p_x1_low])        \n\t"
+                "sw     %[temp6],    24(%[p_x1_low])        \n\t"
+                "sw     %[temp7],    28(%[p_x1_low])        \n\t"
+                "addiu  %[p_x1_low], %[p_x1_low],   32      \n\t"
+                "addiu  %[p_w1],     %[p_w1],       1024    \n\t"
+
+                : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1),
+                  [temp2]"=&r"(temp2), [temp3]"=&r"(temp3),
+                  [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+                  [temp6]"=&r"(temp6), [temp7]"=&r"(temp7),
+                  [p_w1]"+r"(p_w1), [p_x1_low]"+r"(p_x1_low)
+                :
+                : "memory"
+            );
+        }
+        p_x1_low += 64;
+        p_w1 -= 510;
+    }
+    return 0;
+}
+
+static int sbr_x_gen_mips(SpectralBandReplication *sbr, float X[2][38][64],
+                     const float Y0[38][64][2], const float Y1[38][64][2],
+                     const float X_low[32][40][2], int ch)
+{
+    int k, i;
+    const int i_f = 32;
+    int temp0, temp1, temp2, temp3;
+    const float *X_low1, *Y01, *Y11;
+    float *x1=&X[0][0][0];
+    float *j=x1+4864;
+    const int i_Temp = FFMAX(2*sbr->data[ch].t_env_num_env_old - i_f, 0);
+
+    /* loop unrolled 8 times */
+    __asm__ volatile (
+    "1:                                       \n\t"
+        "sw     $0,      0(%[x1])             \n\t"
+        "sw     $0,      4(%[x1])             \n\t"
+        "sw     $0,      8(%[x1])             \n\t"
+        "sw     $0,      12(%[x1])            \n\t"
+        "sw     $0,      16(%[x1])            \n\t"
+        "sw     $0,      20(%[x1])            \n\t"
+        "sw     $0,      24(%[x1])            \n\t"
+        "sw     $0,      28(%[x1])            \n\t"
+        "addiu  %[x1],   %[x1],      32       \n\t"
+        "bne    %[x1],   %[j],       1b       \n\t"
+        "addiu  %[x1],   %[x1],      -19456   \n\t"
+
+        : [x1]"+r"(x1)
+        : [j]"r"(j)
+        : "memory"
+    );
+
+    if (i_Temp != 0) {
+
+        X_low1=&X_low[0][2][0];
+
+        for (k = 0; k < sbr->kx[0]; k++) {
+
+            __asm__ volatile (
+                "move    %[i],        $zero                  \n\t"
+            "2:                                              \n\t"
+                "lw      %[temp0],    0(%[X_low1])           \n\t"
+                "lw      %[temp1],    4(%[X_low1])           \n\t"
+                "sw      %[temp0],    0(%[x1])               \n\t"
+                "sw      %[temp1],    9728(%[x1])            \n\t"
+                "addiu   %[x1],       %[x1],         256     \n\t"
+                "addiu   %[X_low1],   %[X_low1],     8       \n\t"
+                "addiu   %[i],        %[i],          1       \n\t"
+                "bne     %[i],        %[i_Temp],     2b      \n\t"
+
+                : [x1]"+r"(x1), [X_low1]"+r"(X_low1), [i]"=&r"(i),
+                  [temp0]"=&r"(temp0), [temp1]"=&r"(temp1)
+                : [i_Temp]"r"(i_Temp)
+                : "memory"
+            );
+            x1-=(i_Temp<<6)-1;
+            X_low1-=(i_Temp<<1)-80;
+        }
+
+        x1=&X[0][0][k];
+        Y01=(float*)&Y0[32][k][0];
+
+        for (; k < sbr->kx[0] + sbr->m[0]; k++) {
+            __asm__ volatile (
+                "move    %[i],       $zero               \n\t"
+            "3:                                          \n\t"
+                "lw      %[temp0],   0(%[Y01])           \n\t"
+                "lw      %[temp1],   4(%[Y01])           \n\t"
+                "sw      %[temp0],   0(%[x1])            \n\t"
+                "sw      %[temp1],   9728(%[x1])         \n\t"
+                "addiu   %[x1],      %[x1],      256     \n\t"
+                "addiu   %[Y01],     %[Y01],     512     \n\t"
+                "addiu   %[i],       %[i],       1       \n\t"
+                "bne     %[i],       %[i_Temp],  3b      \n\t"
+
+                : [x1]"+r"(x1), [Y01]"+r"(Y01), [i]"=&r"(i),
+                  [temp0]"=&r"(temp0), [temp1]"=&r"(temp1)
+                : [i_Temp]"r"(i_Temp)
+                : "memory"
+            );
+            x1 -=(i_Temp<<6)-1;
+            Y01 -=(i_Temp<<7)-2;
+        }
+    }
+
+    x1=&X[0][i_Temp][0];
+    X_low1=&X_low[0][i_Temp+2][0];
+    temp3=38;
+
+    for (k = 0; k < sbr->kx[1]; k++) {
+
+        __asm__ volatile (
+            "move    %[i],       %[i_Temp]              \n\t"
+        "4:                                             \n\t"
+            "lw      %[temp0],   0(%[X_low1])           \n\t"
+            "lw      %[temp1],   4(%[X_low1])           \n\t"
+            "sw      %[temp0],   0(%[x1])               \n\t"
+            "sw      %[temp1],   9728(%[x1])            \n\t"
+            "addiu   %[x1],      %[x1],         256     \n\t"
+            "addiu   %[X_low1],  %[X_low1],     8       \n\t"
+            "addiu   %[i],       %[i],          1       \n\t"
+            "bne     %[i],       %[temp3],      4b      \n\t"
+
+            : [x1]"+r"(x1), [X_low1]"+r"(X_low1), [i]"=&r"(i),
+              [temp0]"=&r"(temp0), [temp1]"=&r"(temp1),
+              [temp2]"=&r"(temp2)
+            : [i_Temp]"r"(i_Temp), [temp3]"r"(temp3)
+            : "memory"
+        );
+        x1 -= ((38-i_Temp)<<6)-1;
+        X_low1 -= ((38-i_Temp)<<1)- 80;
+    }
+
+    x1=&X[0][i_Temp][k];
+    Y11=&Y1[i_Temp][k][0];
+    temp2=32;
+
+    for (; k < sbr->kx[1] + sbr->m[1]; k++) {
+
+        __asm__ volatile (
+           "move    %[i],       %[i_Temp]               \n\t"
+        "5:                                             \n\t"
+           "lw      %[temp0],   0(%[Y11])               \n\t"
+           "lw      %[temp1],   4(%[Y11])               \n\t"
+           "sw      %[temp0],   0(%[x1])                \n\t"
+           "sw      %[temp1],   9728(%[x1])             \n\t"
+           "addiu   %[x1],      %[x1],          256     \n\t"
+           "addiu   %[Y11],     %[Y11],         512     \n\t"
+           "addiu   %[i],       %[i],           1       \n\t"
+           "bne     %[i],       %[temp2],       5b      \n\t"
+
+           : [x1]"+r"(x1), [Y11]"+r"(Y11), [i]"=&r"(i),
+             [temp0]"=&r"(temp0), [temp1]"=&r"(temp1)
+           : [i_Temp]"r"(i_Temp), [temp3]"r"(temp3),
+             [temp2]"r"(temp2)
+           : "memory"
+        );
+
+        x1 -= ((32-i_Temp)<<6)-1;
+        Y11 -= ((32-i_Temp)<<7)-2;
+   }
+      return 0;
+}
+
+#if HAVE_MIPSFPU
+static void sbr_hf_assemble_mips(float Y1[38][64][2],
+                            const float X_high[64][40][2],
+                            SpectralBandReplication *sbr, SBRData *ch_data,
+                            const int e_a[2])
+{
+    int e, i, j, m;
+    const int h_SL = 4 * !sbr->bs_smoothing_mode;
+    const int kx = sbr->kx[1];
+    const int m_max = sbr->m[1];
+    static const float h_smooth[5] = {
+        0.33333333333333,
+        0.30150283239582,
+        0.21816949906249,
+        0.11516383427084,
+        0.03183050093751,
+    };
+
+    float (*g_temp)[48] = ch_data->g_temp, (*q_temp)[48] = ch_data->q_temp;
+    int indexnoise = ch_data->f_indexnoise;
+    int indexsine  = ch_data->f_indexsine;
+    float *g_temp1, *q_temp1, *pok, *pok1;
+    float temp1, temp2, temp3, temp4;
+    int size = m_max;
+
+    if (sbr->reset) {
+        for (i = 0; i < h_SL; i++) {
+            memcpy(g_temp[i + 2*ch_data->t_env[0]], sbr->gain[0], m_max * sizeof(sbr->gain[0][0]));
+            memcpy(q_temp[i + 2*ch_data->t_env[0]], sbr->q_m[0],  m_max * sizeof(sbr->q_m[0][0]));
+        }
+    } else if (h_SL) {
+        memcpy(g_temp[2*ch_data->t_env[0]], g_temp[2*ch_data->t_env_num_env_old], 4*sizeof(g_temp[0]));
+        memcpy(q_temp[2*ch_data->t_env[0]], q_temp[2*ch_data->t_env_num_env_old], 4*sizeof(q_temp[0]));
+    }
+
+    for (e = 0; e < ch_data->bs_num_env; e++) {
+        for (i = 2 * ch_data->t_env[e]; i < 2 * ch_data->t_env[e + 1]; i++) {
+            g_temp1 = g_temp[h_SL + i];
+            pok = sbr->gain[e];
+            q_temp1 = q_temp[h_SL + i];
+            pok1 = sbr->q_m[e];
+
+            /* loop unrolled 4 times */
+            for (j=0; j<(size>>2); j++) {
+                __asm__ volatile (
+                    "lw      %[temp1],   0(%[pok])               \n\t"
+                    "lw      %[temp2],   4(%[pok])               \n\t"
+                    "lw      %[temp3],   8(%[pok])               \n\t"
+                    "lw      %[temp4],   12(%[pok])              \n\t"
+                    "sw      %[temp1],   0(%[g_temp1])           \n\t"
+                    "sw      %[temp2],   4(%[g_temp1])           \n\t"
+                    "sw      %[temp3],   8(%[g_temp1])           \n\t"
+                    "sw      %[temp4],   12(%[g_temp1])          \n\t"
+                    "lw      %[temp1],   0(%[pok1])              \n\t"
+                    "lw      %[temp2],   4(%[pok1])              \n\t"
+                    "lw      %[temp3],   8(%[pok1])              \n\t"
+                    "lw      %[temp4],   12(%[pok1])             \n\t"
+                    "sw      %[temp1],   0(%[q_temp1])           \n\t"
+                    "sw      %[temp2],   4(%[q_temp1])           \n\t"
+                    "sw      %[temp3],   8(%[q_temp1])           \n\t"
+                    "sw      %[temp4],   12(%[q_temp1])          \n\t"
+                    "addiu   %[pok],     %[pok],           16    \n\t"
+                    "addiu   %[g_temp1], %[g_temp1],       16    \n\t"
+                    "addiu   %[pok1],    %[pok1],          16    \n\t"
+                    "addiu   %[q_temp1], %[q_temp1],       16    \n\t"
+
+                    : [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+                      [temp3]"=&r"(temp3), [temp4]"=&r"(temp4),
+                      [pok]"+r"(pok), [g_temp1]"+r"(g_temp1),
+                      [pok1]"+r"(pok1), [q_temp1]"+r"(q_temp1)
+                    :
+                    : "memory"
+                );
+            }
+
+            for (j=0; j<(size&3); j++) {
+                __asm__ volatile (
+                    "lw      %[temp1],   0(%[pok])              \n\t"
+                    "lw      %[temp2],   0(%[pok1])             \n\t"
+                    "sw      %[temp1],   0(%[g_temp1])          \n\t"
+                    "sw      %[temp2],   0(%[q_temp1])          \n\t"
+                    "addiu   %[pok],     %[pok],          4     \n\t"
+                    "addiu   %[g_temp1], %[g_temp1],      4     \n\t"
+                    "addiu   %[pok1],    %[pok1],         4     \n\t"
+                    "addiu   %[q_temp1], %[q_temp1],      4     \n\t"
+
+                    : [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+                      [temp3]"=&r"(temp3), [temp4]"=&r"(temp4),
+                      [pok]"+r"(pok), [g_temp1]"+r"(g_temp1),
+                      [pok1]"+r"(pok1), [q_temp1]"+r"(q_temp1)
+                    :
+                    : "memory"
+                );
+            }
+        }
+    }
+
+    for (e = 0; e < ch_data->bs_num_env; e++) {
+        for (i = 2 * ch_data->t_env[e]; i < 2 * ch_data->t_env[e + 1]; i++) {
+            LOCAL_ALIGNED_16(float, g_filt_tab, [48]);
+            LOCAL_ALIGNED_16(float, q_filt_tab, [48]);
+            float *g_filt, *q_filt;
+
+            if (h_SL && e != e_a[0] && e != e_a[1]) {
+                g_filt = g_filt_tab;
+                q_filt = q_filt_tab;
+
+                for (m = 0; m < m_max; m++) {
+                    const int idx1 = i + h_SL;
+                    g_filt[m] = 0.0f;
+                    q_filt[m] = 0.0f;
+
+                    for (j = 0; j <= h_SL; j++) {
+                        g_filt[m] += g_temp[idx1 - j][m] * h_smooth[j];
+                        q_filt[m] += q_temp[idx1 - j][m] * h_smooth[j];
+                    }
+                }
+            } else {
+                g_filt = g_temp[i + h_SL];
+                q_filt = q_temp[i];
+            }
+
+            sbr->dsp.hf_g_filt(Y1[i] + kx, X_high + kx, g_filt, m_max,
+                               i + ENVELOPE_ADJUSTMENT_OFFSET);
+
+            if (e != e_a[0] && e != e_a[1]) {
+                sbr->dsp.hf_apply_noise[indexsine](Y1[i] + kx, sbr->s_m[e],
+                                                   q_filt, indexnoise,
+                                                   kx, m_max);
+            } else {
+                int idx = indexsine&1;
+                int A = (1-((indexsine+(kx & 1))&2));
+                int B = (A^(-idx)) + idx;
+                float *out = &Y1[i][kx][idx];
+                float *in  = sbr->s_m[e];
+                float temp0, temp1, temp2, temp3, temp4, temp5;
+                float A_f = (float)A;
+                float B_f = (float)B;
+
+                for (m = 0; m+1 < m_max; m+=2) {
+
+                    temp2 = out[0];
+                    temp3 = out[2];
+
+                    __asm__ volatile(
+                        "lwc1    %[temp0],  0(%[in])                     \n\t"
+                        "lwc1    %[temp1],  4(%[in])                     \n\t"
+                        "madd.s  %[temp4],  %[temp2],  %[temp0], %[A_f]  \n\t"
+                        "madd.s  %[temp5],  %[temp3],  %[temp1], %[B_f]  \n\t"
+                        "swc1    %[temp4],  0(%[out])                    \n\t"
+                        "swc1    %[temp5],  8(%[out])                    \n\t"
+                        "addiu   %[in],     %[in],     8                 \n\t"
+                        "addiu   %[out],    %[out],    16                \n\t"
+
+                        : [temp0]"=&f" (temp0), [temp1]"=&f"(temp1),
+                          [temp4]"=&f" (temp4), [temp5]"=&f"(temp5),
+                          [in]"+r"(in), [out]"+r"(out)
+                        : [A_f]"f"(A_f), [B_f]"f"(B_f), [temp2]"f"(temp2),
+                          [temp3]"f"(temp3)
+                        : "memory"
+                    );
+                }
+                if(m_max&1)
+                    out[2*m  ] += in[m  ] * A;
+            }
+            indexnoise = (indexnoise + m_max) & 0x1ff;
+            indexsine = (indexsine + 1) & 3;
+        }
+    }
+    ch_data->f_indexnoise = indexnoise;
+    ch_data->f_indexsine  = indexsine;
+}
+
+static void sbr_hf_inverse_filter_mips(SBRDSPContext *dsp,
+                                  float (*alpha0)[2], float (*alpha1)[2],
+                                  const float X_low[32][40][2], int k0)
+{
+    int k;
+    float temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7, c;
+    float *phi1, *alpha_1, *alpha_0, res1, res2, temp_real, temp_im;
+
+    c = 1.000001f;
+
+    for (k = 0; k < k0; k++) {
+        LOCAL_ALIGNED_16(float, phi, [3], [2][2]);
+        float dk;
+        phi1 = &phi[0][0][0];
+        alpha_1 = &alpha1[k][0];
+        alpha_0 = &alpha0[k][0];
+        dsp->autocorrelate(X_low[k], phi);
+
+        __asm__ volatile (
+            "lwc1    %[temp0],  40(%[phi1])                       \n\t"
+            "lwc1    %[temp1],  16(%[phi1])                       \n\t"
+            "lwc1    %[temp2],  24(%[phi1])                       \n\t"
+            "lwc1    %[temp3],  28(%[phi1])                       \n\t"
+            "mul.s   %[dk],     %[temp0],    %[temp1]             \n\t"
+            "lwc1    %[temp4],  0(%[phi1])                        \n\t"
+            "mul.s   %[res2],   %[temp2],    %[temp2]             \n\t"
+            "lwc1    %[temp5],  4(%[phi1])                        \n\t"
+            "madd.s  %[res2],   %[res2],     %[temp3],  %[temp3]  \n\t"
+            "lwc1    %[temp6],  8(%[phi1])                        \n\t"
+            "div.s   %[res2],   %[res2],     %[c]                 \n\t"
+            "lwc1    %[temp0],  12(%[phi1])                       \n\t"
+            "sub.s   %[dk],     %[dk],       %[res2]              \n\t"
+
+            : [temp0]"=&f"(temp0), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
+              [temp3]"=&f"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5),
+              [temp6]"=&f"(temp6), [res2]"=&f"(res2), [dk]"=&f"(dk)
+            : [phi1]"r"(phi1), [c]"f"(c)
+            : "memory"
+        );
+
+        if (!dk) {
+            alpha_1[0] = 0;
+            alpha_1[1] = 0;
+        } else {
+            __asm__ volatile (
+                "mul.s   %[temp_real], %[temp4],     %[temp2]            \n\t"
+                "nmsub.s %[temp_real], %[temp_real], %[temp5], %[temp3]  \n\t"
+                "nmsub.s %[temp_real], %[temp_real], %[temp6], %[temp1]  \n\t"
+                "mul.s   %[temp_im],   %[temp4],     %[temp3]            \n\t"
+                "madd.s  %[temp_im],   %[temp_im],   %[temp5], %[temp2]  \n\t"
+                "nmsub.s %[temp_im],   %[temp_im],   %[temp0], %[temp1]  \n\t"
+                "div.s   %[temp_real], %[temp_real], %[dk]               \n\t"
+                "div.s   %[temp_im],   %[temp_im],   %[dk]               \n\t"
+                "swc1    %[temp_real], 0(%[alpha_1])                     \n\t"
+                "swc1    %[temp_im],   4(%[alpha_1])                     \n\t"
+
+                : [temp_real]"=&f" (temp_real), [temp_im]"=&f"(temp_im)
+                : [phi1]"r"(phi1), [temp0]"f"(temp0), [temp1]"f"(temp1),
+                  [temp2]"f"(temp2), [temp3]"f"(temp3), [temp4]"f"(temp4),
+                  [temp5]"f"(temp5), [temp6]"f"(temp6),
+                  [alpha_1]"r"(alpha_1), [dk]"f"(dk)
+                : "memory"
+            );
+        }
+
+        if (!phi1[4]) {
+            alpha_0[0] = 0;
+            alpha_0[1] = 0;
+        } else {
+            __asm__ volatile (
+                "lwc1    %[temp6],     0(%[alpha_1])                     \n\t"
+                "lwc1    %[temp7],     4(%[alpha_1])                     \n\t"
+                "mul.s   %[temp_real], %[temp6],     %[temp2]            \n\t"
+                "add.s   %[temp_real], %[temp_real], %[temp4]            \n\t"
+                "madd.s  %[temp_real], %[temp_real], %[temp7], %[temp3]  \n\t"
+                "mul.s   %[temp_im],   %[temp7],     %[temp2]            \n\t"
+                "add.s   %[temp_im],   %[temp_im],   %[temp5]            \n\t"
+                "nmsub.s %[temp_im],   %[temp_im],   %[temp6], %[temp3]  \n\t"
+                "div.s   %[temp_real], %[temp_real], %[temp1]            \n\t"
+                "div.s   %[temp_im],   %[temp_im],   %[temp1]            \n\t"
+                "neg.s   %[temp_real], %[temp_real]                      \n\t"
+                "neg.s   %[temp_im],   %[temp_im]                        \n\t"
+                "swc1    %[temp_real], 0(%[alpha_0])                     \n\t"
+                "swc1    %[temp_im],   4(%[alpha_0])                     \n\t"
+
+                : [temp_real]"=&f"(temp_real), [temp_im]"=&f"(temp_im),
+                  [temp6]"=&f"(temp6), [temp7]"=&f"(temp7),
+                  [res1]"=&f"(res1), [res2]"=&f"(res2)
+                : [alpha_1]"r"(alpha_1), [alpha_0]"r"(alpha_0),
+                  [temp0]"f"(temp0), [temp1]"f"(temp1), [temp2]"f"(temp2),
+                  [temp3]"f"(temp3), [temp4]"f"(temp4), [temp5]"f"(temp5)
+                : "memory"
+            );
+        }
+
+        __asm__ volatile (
+            "lwc1    %[temp1],      0(%[alpha_1])                           \n\t"
+            "lwc1    %[temp2],      4(%[alpha_1])                           \n\t"
+            "lwc1    %[temp_real],  0(%[alpha_0])                           \n\t"
+            "lwc1    %[temp_im],    4(%[alpha_0])                           \n\t"
+            "mul.s   %[res1],       %[temp1],      %[temp1]                 \n\t"
+            "madd.s  %[res1],       %[res1],       %[temp2],    %[temp2]    \n\t"
+            "mul.s   %[res2],       %[temp_real],  %[temp_real]             \n\t"
+            "madd.s  %[res2],       %[res2],       %[temp_im],  %[temp_im]  \n\t"
+
+            : [temp_real]"=&f"(temp_real), [temp_im]"=&f"(temp_im),
+              [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
+              [res1]"=&f"(res1), [res2]"=&f"(res2)
+            : [alpha_1]"r"(alpha_1), [alpha_0]"r"(alpha_0)
+            : "memory"
+        );
+
+        if (res1 >= 16.0f || res2 >= 16.0f) {
+            alpha_1[0] = 0;
+            alpha_1[1] = 0;
+            alpha_0[0] = 0;
+            alpha_0[1] = 0;
+        }
+    }
+}
+#endif /* HAVE_MIPSFPU */
+#endif /* HAVE_INLINE_ASM */
+
+void ff_aacsbr_func_ptr_init_mips(AACSBRContext *c)
+{
+#if HAVE_INLINE_ASM
+    c->sbr_lf_gen            = sbr_lf_gen_mips;
+    c->sbr_x_gen             = sbr_x_gen_mips;
+#if HAVE_MIPSFPU
+    c->sbr_hf_inverse_filter = sbr_hf_inverse_filter_mips;
+    c->sbr_hf_assemble       = sbr_hf_assemble_mips;
+#endif /* HAVE_MIPSFPU */
+#endif /* HAVE_INLINE_ASM */
+}
diff --git a/libavcodec/mips/aacsbr_mips.h b/libavcodec/mips/aacsbr_mips.h
new file mode 100644
index 0000000..8e6ad7d
--- /dev/null
+++ b/libavcodec/mips/aacsbr_mips.h
@@ -0,0 +1,493 @@
+/*
+ * 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:  Djordje Pesut   (djordje@mips.com)
+ *           Mirjana Vulin   (mvulin@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
+ * Reference: libavcodec/aacsbr.c
+ */
+
+#ifndef AVCODEC_MIPS_AACSBR_FLOAT_H
+#define AVCODEC_MIPS_AACSBR_FLOAT_H
+
+#include "libavcodec/aac.h"
+#include "libavcodec/sbr.h"
+
+#if HAVE_INLINE_ASM
+static void sbr_qmf_analysis_mips(AVFloatDSPContext *fdsp, FFTContext *mdct,
+                             SBRDSPContext *sbrdsp, const float *in, float *x,
+                             float z[320], float W[2][32][32][2], int buf_idx)
+{
+    int i;
+    float *w0;
+    float *w1;
+    int temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
+
+    w0 = x;
+    w1 = x + 1024;
+    for(i = 0; i < 36; i++)
+    {
+        /* loop unrolled 8 times */
+        __asm__ volatile(
+            "lw      %[temp0],   0(%[w1])         \n\t"
+            "lw      %[temp1],   4(%[w1])         \n\t"
+            "lw      %[temp2],   8(%[w1])         \n\t"
+            "lw      %[temp3],   12(%[w1])        \n\t"
+            "lw      %[temp4],   16(%[w1])        \n\t"
+            "lw      %[temp5],   20(%[w1])        \n\t"
+            "lw      %[temp6],   24(%[w1])        \n\t"
+            "lw      %[temp7],   28(%[w1])        \n\t"
+            "sw      %[temp0],   0(%[w0])         \n\t"
+            "sw      %[temp1],   4(%[w0])         \n\t"
+            "sw      %[temp2],   8(%[w0])         \n\t"
+            "sw      %[temp3],   12(%[w0])        \n\t"
+            "sw      %[temp4],   16(%[w0])        \n\t"
+            "sw      %[temp5],   20(%[w0])        \n\t"
+            "sw      %[temp6],   24(%[w0])        \n\t"
+            "sw      %[temp7],   28(%[w0])        \n\t"
+            "addiu   %[w0],      %[w0],     32    \n\t"
+            "addiu   %[w1],      %[w1],     32    \n\t"
+
+            : [w0]"+r"(w0), [w1]"+r"(w1),
+              [temp0]"=&r"(temp0), [temp1]"=&r"(temp1),
+              [temp2]"=&r"(temp2), [temp3]"=&r"(temp3),
+              [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+              [temp6]"=&r"(temp6), [temp7]"=&r"(temp7)
+            :
+            : "memory"
+        );
+    }
+
+    w0 = x + 288;
+    w1 = (float*)in;
+    for(i = 0; i < 128; i++)
+    {
+        /* loop unrolled 8 times */
+        __asm__ volatile(
+            "lw       %[temp0],    0(%[w1])        \n\t"
+            "lw       %[temp1],    4(%[w1])        \n\t"
+            "lw       %[temp2],    8(%[w1])        \n\t"
+            "lw       %[temp3],    12(%[w1])       \n\t"
+            "lw       %[temp4],    16(%[w1])       \n\t"
+            "lw       %[temp5],    20(%[w1])       \n\t"
+            "lw       %[temp6],    24(%[w1])       \n\t"
+            "lw       %[temp7],    28(%[w1])       \n\t"
+            "sw       %[temp0],    0(%[w0])        \n\t"
+            "sw       %[temp1],    4(%[w0])        \n\t"
+            "sw       %[temp2],    8(%[w0])        \n\t"
+            "sw       %[temp3],    12(%[w0])       \n\t"
+            "sw       %[temp4],    16(%[w0])       \n\t"
+            "sw       %[temp5],    20(%[w0])       \n\t"
+            "sw       %[temp6],    24(%[w0])       \n\t"
+            "sw       %[temp7],    28(%[w0])       \n\t"
+            "addiu    %[w0],       %[w0],     32   \n\t"
+            "addiu    %[w1],       %[w1],     32   \n\t"
+
+            : [w0]"+r"(w0), [w1]"+r"(w1),
+              [temp0]"=&r"(temp0), [temp1]"=&r"(temp1),
+              [temp2]"=&r"(temp2), [temp3]"=&r"(temp3),
+              [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+              [temp6]"=&r"(temp6), [temp7]"=&r"(temp7)
+            :
+            : "memory"
+        );
+    }
+
+    for (i = 0; i < 32; i++) { // numTimeSlots*RATE = 16*2 as 960 sample frames
+                               // are not supported
+        fdsp->vector_fmul_reverse(z, sbr_qmf_window_ds, x, 320);
+        sbrdsp->sum64x5(z);
+        sbrdsp->qmf_pre_shuffle(z);
+        mdct->imdct_half(mdct, z, z+64);
+        sbrdsp->qmf_post_shuffle(W[buf_idx][i], z);
+        x += 32;
+    }
+}
+
+#if HAVE_MIPSFPU
+static void sbr_qmf_synthesis_mips(FFTContext *mdct,
+                              SBRDSPContext *sbrdsp, AVFloatDSPContext *fdsp,
+                              float *out, float X[2][38][64],
+                              float mdct_buf[2][64],
+                              float *v0, int *v_off, const unsigned int div)
+{
+    int i, n;
+    const float *sbr_qmf_window = div ? sbr_qmf_window_ds : sbr_qmf_window_us;
+    const int step = 128 >> div;
+    float *v;
+    float temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8, temp9, temp10, temp11, temp12, temp13;
+    float temp14, temp15, temp16, temp17, temp18, temp19;
+    float *vv0, *s0, *dst;
+    dst = out;
+
+    for (i = 0; i < 32; i++) {
+        if (*v_off < step) {
+            int saved_samples = (1280 - 128) >> div;
+            memcpy(&v0[SBR_SYNTHESIS_BUF_SIZE - saved_samples], v0, saved_samples * sizeof(float));
+            *v_off = SBR_SYNTHESIS_BUF_SIZE - saved_samples - step;
+        } else {
+            *v_off -= step;
+        }
+        v = v0 + *v_off;
+        if (div) {
+            for (n = 0; n < 32; n++) {
+                X[0][i][   n] = -X[0][i][n];
+                X[0][i][32+n] =  X[1][i][31-n];
+            }
+            mdct->imdct_half(mdct, mdct_buf[0], X[0][i]);
+            sbrdsp->qmf_deint_neg(v, mdct_buf[0]);
+        } else {
+            sbrdsp->neg_odd_64(X[1][i]);
+            mdct->imdct_half(mdct, mdct_buf[0], X[0][i]);
+            mdct->imdct_half(mdct, mdct_buf[1], X[1][i]);
+            sbrdsp->qmf_deint_bfly(v, mdct_buf[1], mdct_buf[0]);
+        }
+
+        if(div == 0)
+        {
+            float *v0_end;
+            vv0 = v;
+            v0_end = v + 60;
+            s0 = (float*)sbr_qmf_window;
+
+            /* 10 calls of function vector_fmul_add merged into one loop
+               and loop unrolled 4 times */
+            __asm__ volatile(
+                ".set    push                                           \n\t"
+                ".set    noreorder                                      \n\t"
+                "lwc1    %[temp4],   0(%[v0])                           \n\t"
+                "lwc1    %[temp5],   0(%[s0])                           \n\t"
+                "lwc1    %[temp6],   4(%[v0])                           \n\t"
+                "lwc1    %[temp7],   4(%[s0])                           \n\t"
+                "lwc1    %[temp8],   8(%[v0])                           \n\t"
+                "lwc1    %[temp9],   8(%[s0])                           \n\t"
+                "lwc1    %[temp10],  12(%[v0])                          \n\t"
+                "lwc1    %[temp11],  12(%[s0])                          \n\t"
+                "lwc1    %[temp12],  768(%[v0])                         \n\t"
+                "lwc1    %[temp13],  256(%[s0])                         \n\t"
+                "lwc1    %[temp14],  772(%[v0])                         \n\t"
+                "lwc1    %[temp15],  260(%[s0])                         \n\t"
+                "lwc1    %[temp16],  776(%[v0])                         \n\t"
+                "lwc1    %[temp17],  264(%[s0])                         \n\t"
+                "lwc1    %[temp18],  780(%[v0])                         \n\t"
+                "lwc1    %[temp19],  268(%[s0])                         \n\t"
+            "1:                                                         \n\t"
+                "mul.s   %[temp0],   %[temp4],   %[temp5]               \n\t"
+                "lwc1    %[temp4],   1024(%[v0])                        \n\t"
+                "mul.s   %[temp1],   %[temp6],   %[temp7]               \n\t"
+                "lwc1    %[temp5],   512(%[s0])                         \n\t"
+                "mul.s   %[temp2],   %[temp8],   %[temp9]               \n\t"
+                "lwc1    %[temp6],   1028(%[v0])                        \n\t"
+                "mul.s   %[temp3],   %[temp10],  %[temp11]              \n\t"
+                "lwc1    %[temp7],   516(%[s0])                         \n\t"
+                "madd.s  %[temp0],   %[temp0],   %[temp12],  %[temp13]  \n\t"
+                "lwc1    %[temp8],   1032(%[v0])                        \n\t"
+                "madd.s  %[temp1],   %[temp1],   %[temp14],  %[temp15]  \n\t"
+                "lwc1    %[temp9],   520(%[s0])                         \n\t"
+                "madd.s  %[temp2],   %[temp2],   %[temp16],  %[temp17]  \n\t"
+                "lwc1    %[temp10],  1036(%[v0])                        \n\t"
+                "madd.s  %[temp3],   %[temp3],   %[temp18],  %[temp19]  \n\t"
+                "lwc1    %[temp11],  524(%[s0])                         \n\t"
+                "lwc1    %[temp12],  1792(%[v0])                        \n\t"
+                "lwc1    %[temp13],  768(%[s0])                         \n\t"
+                "lwc1    %[temp14],  1796(%[v0])                        \n\t"
+                "lwc1    %[temp15],  772(%[s0])                         \n\t"
+                "lwc1    %[temp16],  1800(%[v0])                        \n\t"
+                "lwc1    %[temp17],  776(%[s0])                         \n\t"
+                "lwc1    %[temp18],  1804(%[v0])                        \n\t"
+                "lwc1    %[temp19],  780(%[s0])                         \n\t"
+                "madd.s  %[temp0],   %[temp0],   %[temp4],   %[temp5]   \n\t"
+                "lwc1    %[temp4],   2048(%[v0])                        \n\t"
+                "madd.s  %[temp1],   %[temp1],   %[temp6],   %[temp7]   \n\t"
+                "lwc1    %[temp5],   1024(%[s0])                        \n\t"
+                "madd.s  %[temp2],   %[temp2],   %[temp8],   %[temp9]   \n\t"
+                "lwc1    %[temp6],   2052(%[v0])                        \n\t"
+                "madd.s  %[temp3],   %[temp3],   %[temp10],  %[temp11]  \n\t"
+                "lwc1    %[temp7],   1028(%[s0])                        \n\t"
+                "madd.s  %[temp0],   %[temp0],   %[temp12],  %[temp13]  \n\t"
+                "lwc1    %[temp8],   2056(%[v0])                        \n\t"
+                "madd.s  %[temp1],   %[temp1],   %[temp14],  %[temp15]  \n\t"
+                "lwc1    %[temp9],   1032(%[s0])                        \n\t"
+                "madd.s  %[temp2],   %[temp2],   %[temp16],  %[temp17]  \n\t"
+                "lwc1    %[temp10],  2060(%[v0])                        \n\t"
+                "madd.s  %[temp3],   %[temp3],   %[temp18],  %[temp19]  \n\t"
+                "lwc1    %[temp11],  1036(%[s0])                        \n\t"
+                "lwc1    %[temp12],  2816(%[v0])                        \n\t"
+                "lwc1    %[temp13],  1280(%[s0])                        \n\t"
+                "lwc1    %[temp14],  2820(%[v0])                        \n\t"
+                "lwc1    %[temp15],  1284(%[s0])                        \n\t"
+                "lwc1    %[temp16],  2824(%[v0])                        \n\t"
+                "lwc1    %[temp17],  1288(%[s0])                        \n\t"
+                "lwc1    %[temp18],  2828(%[v0])                        \n\t"
+                "lwc1    %[temp19],  1292(%[s0])                        \n\t"
+                "madd.s  %[temp0],   %[temp0],   %[temp4],   %[temp5]   \n\t"
+                "lwc1    %[temp4],   3072(%[v0])                        \n\t"
+                "madd.s  %[temp1],   %[temp1],   %[temp6],   %[temp7]   \n\t"
+                "lwc1    %[temp5],   1536(%[s0])                        \n\t"
+                "madd.s  %[temp2],   %[temp2],   %[temp8],   %[temp9]   \n\t"
+                "lwc1    %[temp6],   3076(%[v0])                        \n\t"
+                "madd.s  %[temp3],   %[temp3],   %[temp10],  %[temp11]  \n\t"
+                "lwc1    %[temp7],   1540(%[s0])                        \n\t"
+                "madd.s  %[temp0],   %[temp0],   %[temp12],  %[temp13]  \n\t"
+                "lwc1    %[temp8],   3080(%[v0])                        \n\t"
+                "madd.s  %[temp1],   %[temp1],   %[temp14],  %[temp15]  \n\t"
+                "lwc1    %[temp9],   1544(%[s0])                        \n\t"
+                "madd.s  %[temp2],   %[temp2],   %[temp16],  %[temp17]  \n\t"
+                "lwc1    %[temp10],  3084(%[v0])                        \n\t"
+                "madd.s  %[temp3],   %[temp3],   %[temp18],  %[temp19]  \n\t"
+                "lwc1    %[temp11],  1548(%[s0])                        \n\t"
+                "lwc1    %[temp12],  3840(%[v0])                        \n\t"
+                "lwc1    %[temp13],  1792(%[s0])                        \n\t"
+                "lwc1    %[temp14],  3844(%[v0])                        \n\t"
+                "lwc1    %[temp15],  1796(%[s0])                        \n\t"
+                "lwc1    %[temp16],  3848(%[v0])                        \n\t"
+                "lwc1    %[temp17],  1800(%[s0])                        \n\t"
+                "lwc1    %[temp18],  3852(%[v0])                        \n\t"
+                "lwc1    %[temp19],  1804(%[s0])                        \n\t"
+                "madd.s  %[temp0],   %[temp0],   %[temp4],   %[temp5]   \n\t"
+                "lwc1    %[temp4],   4096(%[v0])                        \n\t"
+                "madd.s  %[temp1],   %[temp1],   %[temp6],   %[temp7]   \n\t"
+                "lwc1    %[temp5],   2048(%[s0])                        \n\t"
+                "madd.s  %[temp2],   %[temp2],   %[temp8],   %[temp9]   \n\t"
+                "lwc1    %[temp6],   4100(%[v0])                        \n\t"
+                "madd.s  %[temp3],   %[temp3],   %[temp10],  %[temp11]  \n\t"
+                "lwc1    %[temp7],   2052(%[s0])                        \n\t"
+                "madd.s  %[temp0],   %[temp0],   %[temp12],  %[temp13]  \n\t"
+                "lwc1    %[temp8],   4104(%[v0])                        \n\t"
+                "addiu   %[dst],     %[dst],     16                     \n\t"
+                "madd.s  %[temp1],   %[temp1],   %[temp14],  %[temp15]  \n\t"
+                "lwc1    %[temp9],   2056(%[s0])                        \n\t"
+                "addiu   %[s0],      %[s0],      16                     \n\t"
+                "madd.s  %[temp2],   %[temp2],   %[temp16],  %[temp17]  \n\t"
+                "lwc1    %[temp10],  4108(%[v0])                        \n\t"
+                "addiu   %[v0],      %[v0],      16                     \n\t"
+                "madd.s  %[temp3],   %[temp3],   %[temp18],  %[temp19]  \n\t"
+                "lwc1    %[temp11],  2044(%[s0])                        \n\t"
+                "lwc1    %[temp12],  4848(%[v0])                        \n\t"
+                "lwc1    %[temp13],  2288(%[s0])                        \n\t"
+                "lwc1    %[temp14],  4852(%[v0])                        \n\t"
+                "lwc1    %[temp15],  2292(%[s0])                        \n\t"
+                "lwc1    %[temp16],  4856(%[v0])                        \n\t"
+                "lwc1    %[temp17],  2296(%[s0])                        \n\t"
+                "lwc1    %[temp18],  4860(%[v0])                        \n\t"
+                "lwc1    %[temp19],  2300(%[s0])                        \n\t"
+                "madd.s  %[temp0],   %[temp0],   %[temp4],   %[temp5]   \n\t"
+                "lwc1    %[temp4],   0(%[v0])                           \n\t"
+                "madd.s  %[temp1],   %[temp1],   %[temp6],   %[temp7]   \n\t"
+                "lwc1    %[temp5],   0(%[s0])                           \n\t"
+                "madd.s  %[temp2],   %[temp2],   %[temp8],   %[temp9]   \n\t"
+                "lwc1    %[temp6],   4(%[v0])                           \n\t"
+                "madd.s  %[temp3],   %[temp3],   %[temp10],  %[temp11]  \n\t"
+                "lwc1    %[temp7],   4(%[s0])                           \n\t"
+                "madd.s  %[temp0],   %[temp0],   %[temp12],  %[temp13]  \n\t"
+                "lwc1    %[temp8],   8(%[v0])                           \n\t"
+                "madd.s  %[temp1],   %[temp1],   %[temp14],  %[temp15]  \n\t"
+                "lwc1    %[temp9],   8(%[s0])                           \n\t"
+                "madd.s  %[temp2],   %[temp2],   %[temp16],  %[temp17]  \n\t"
+                "lwc1    %[temp10],  12(%[v0])                          \n\t"
+                "madd.s  %[temp3],   %[temp3],   %[temp18],  %[temp19]  \n\t"
+                "lwc1    %[temp11],  12(%[s0])                          \n\t"
+                "lwc1    %[temp12],  768(%[v0])                         \n\t"
+                "lwc1    %[temp13],  256(%[s0])                         \n\t"
+                "lwc1    %[temp14],  772(%[v0])                         \n\t"
+                "lwc1    %[temp15],  260(%[s0])                         \n\t"
+                "lwc1    %[temp16],  776(%[v0])                         \n\t"
+                "lwc1    %[temp17],  264(%[s0])                         \n\t"
+                "lwc1    %[temp18],  780(%[v0])                         \n\t"
+                "lwc1    %[temp19],  268(%[s0])                         \n\t"
+                "swc1    %[temp0],   -16(%[dst])                        \n\t"
+                "swc1    %[temp1],   -12(%[dst])                        \n\t"
+                "swc1    %[temp2],   -8(%[dst])                         \n\t"
+                "bne     %[v0],      %[v0_end],  1b                     \n\t"
+                " swc1   %[temp3],   -4(%[dst])                         \n\t"
+                "mul.s   %[temp0],   %[temp4],   %[temp5]               \n\t"
+                "lwc1    %[temp4],   1024(%[v0])                        \n\t"
+                "mul.s   %[temp1],   %[temp6],   %[temp7]               \n\t"
+                "lwc1    %[temp5],   512(%[s0])                         \n\t"
+                "mul.s   %[temp2],   %[temp8],   %[temp9]               \n\t"
+                "lwc1    %[temp6],   1028(%[v0])                        \n\t"
+                "mul.s   %[temp3],   %[temp10],  %[temp11]              \n\t"
+                "lwc1    %[temp7],   516(%[s0])                         \n\t"
+                "madd.s  %[temp0],   %[temp0],   %[temp12],  %[temp13]  \n\t"
+                "lwc1    %[temp8],   1032(%[v0])                        \n\t"
+                "madd.s  %[temp1],   %[temp1],   %[temp14],  %[temp15]  \n\t"
+                "lwc1    %[temp9],   520(%[s0])                         \n\t"
+                "madd.s  %[temp2],   %[temp2],   %[temp16],  %[temp17]  \n\t"
+                "lwc1    %[temp10],  1036(%[v0])                        \n\t"
+                "madd.s  %[temp3],   %[temp3],   %[temp18],  %[temp19]  \n\t"
+                "lwc1    %[temp11],  524(%[s0])                         \n\t"
+                "lwc1    %[temp12],  1792(%[v0])                        \n\t"
+                "lwc1    %[temp13],  768(%[s0])                         \n\t"
+                "lwc1    %[temp14],  1796(%[v0])                        \n\t"
+                "lwc1    %[temp15],  772(%[s0])                         \n\t"
+                "lwc1    %[temp16],  1800(%[v0])                        \n\t"
+                "lwc1    %[temp17],  776(%[s0])                         \n\t"
+                "lwc1    %[temp18],  1804(%[v0])                        \n\t"
+                "lwc1    %[temp19],  780(%[s0])                         \n\t"
+                "madd.s  %[temp0],   %[temp0],   %[temp4],   %[temp5]   \n\t"
+                "lwc1    %[temp4],   2048(%[v0])                        \n\t"
+                "madd.s  %[temp1],   %[temp1],   %[temp6],   %[temp7]   \n\t"
+                "lwc1    %[temp5],   1024(%[s0])                        \n\t"
+                "madd.s  %[temp2],   %[temp2],   %[temp8],   %[temp9]   \n\t"
+                "lwc1    %[temp6],   2052(%[v0])                        \n\t"
+                "madd.s  %[temp3],   %[temp3],   %[temp10],  %[temp11]  \n\t"
+                "lwc1    %[temp7],   1028(%[s0])                        \n\t"
+                "madd.s  %[temp0],   %[temp0],   %[temp12],  %[temp13]  \n\t"
+                "lwc1    %[temp8],   2056(%[v0])                        \n\t"
+                "madd.s  %[temp1],   %[temp1],   %[temp14],  %[temp15]  \n\t"
+                "lwc1    %[temp9],   1032(%[s0])                        \n\t"
+                "madd.s  %[temp2],   %[temp2],   %[temp16],  %[temp17]  \n\t"
+                "lwc1    %[temp10],  2060(%[v0])                        \n\t"
+                "madd.s  %[temp3],   %[temp3],   %[temp18],  %[temp19]  \n\t"
+                "lwc1    %[temp11],  1036(%[s0])                        \n\t"
+                "lwc1    %[temp12],  2816(%[v0])                        \n\t"
+                "lwc1    %[temp13],  1280(%[s0])                        \n\t"
+                "lwc1    %[temp14],  2820(%[v0])                        \n\t"
+                "lwc1    %[temp15],  1284(%[s0])                        \n\t"
+                "lwc1    %[temp16],  2824(%[v0])                        \n\t"
+                "lwc1    %[temp17],  1288(%[s0])                        \n\t"
+                "lwc1    %[temp18],  2828(%[v0])                        \n\t"
+                "lwc1    %[temp19],  1292(%[s0])                        \n\t"
+                "madd.s  %[temp0],   %[temp0],   %[temp4],   %[temp5]   \n\t"
+                "lwc1    %[temp4],   3072(%[v0])                        \n\t"
+                "madd.s  %[temp1],   %[temp1],   %[temp6],   %[temp7]   \n\t"
+                "lwc1    %[temp5],   1536(%[s0])                        \n\t"
+                "madd.s  %[temp2],   %[temp2],   %[temp8],   %[temp9]   \n\t"
+                "lwc1    %[temp6],   3076(%[v0])                        \n\t"
+                "madd.s  %[temp3],   %[temp3],   %[temp10],  %[temp11]  \n\t"
+                "lwc1    %[temp7],   1540(%[s0])                        \n\t"
+                "madd.s  %[temp0],   %[temp0],   %[temp12],  %[temp13]  \n\t"
+                "lwc1    %[temp8],   3080(%[v0])                        \n\t"
+                "madd.s  %[temp1],   %[temp1],   %[temp14],  %[temp15]  \n\t"
+                "lwc1    %[temp9],   1544(%[s0])                        \n\t"
+                "madd.s  %[temp2],   %[temp2],   %[temp16],  %[temp17]  \n\t"
+                "lwc1    %[temp10],  3084(%[v0])                        \n\t"
+                "madd.s  %[temp3],   %[temp3],   %[temp18],  %[temp19]  \n\t"
+                "lwc1    %[temp11],  1548(%[s0])                        \n\t"
+                "lwc1    %[temp12],  3840(%[v0])                        \n\t"
+                "lwc1    %[temp13],  1792(%[s0])                        \n\t"
+                "lwc1    %[temp14],  3844(%[v0])                        \n\t"
+                "lwc1    %[temp15],  1796(%[s0])                        \n\t"
+                "lwc1    %[temp16],  3848(%[v0])                        \n\t"
+                "lwc1    %[temp17],  1800(%[s0])                        \n\t"
+                "lwc1    %[temp18],  3852(%[v0])                        \n\t"
+                "lwc1    %[temp19],  1804(%[s0])                        \n\t"
+                "madd.s  %[temp0],   %[temp0],   %[temp4],   %[temp5]   \n\t"
+                "lwc1    %[temp4],   4096(%[v0])                        \n\t"
+                "madd.s  %[temp1],   %[temp1],   %[temp6],   %[temp7]   \n\t"
+                "lwc1    %[temp5],   2048(%[s0])                        \n\t"
+                "madd.s  %[temp2],   %[temp2],   %[temp8],   %[temp9]   \n\t"
+                "lwc1    %[temp6],   4100(%[v0])                        \n\t"
+                "madd.s  %[temp3],   %[temp3],   %[temp10],  %[temp11]  \n\t"
+                "lwc1    %[temp7],   2052(%[s0])                        \n\t"
+                "madd.s  %[temp0],   %[temp0],   %[temp12],  %[temp13]  \n\t"
+                "lwc1    %[temp8],   4104(%[v0])                        \n\t"
+                "madd.s  %[temp1],   %[temp1],   %[temp14],  %[temp15]  \n\t"
+                "lwc1    %[temp9],   2056(%[s0])                        \n\t"
+                "madd.s  %[temp2],   %[temp2],   %[temp16],  %[temp17]  \n\t"
+                "lwc1    %[temp10],  4108(%[v0])                        \n\t"
+                "madd.s  %[temp3],   %[temp3],   %[temp18],  %[temp19]  \n\t"
+                "lwc1    %[temp11],  2060(%[s0])                        \n\t"
+                "lwc1    %[temp12],  4864(%[v0])                        \n\t"
+                "lwc1    %[temp13],  2304(%[s0])                        \n\t"
+                "lwc1    %[temp14],  4868(%[v0])                        \n\t"
+                "lwc1    %[temp15],  2308(%[s0])                        \n\t"
+                "madd.s  %[temp0],   %[temp0],   %[temp4],   %[temp5]   \n\t"
+                "lwc1    %[temp16],  4872(%[v0])                        \n\t"
+                "madd.s  %[temp1],   %[temp1],   %[temp6],   %[temp7]   \n\t"
+                "lwc1    %[temp17],  2312(%[s0])                        \n\t"
+                "madd.s  %[temp2],   %[temp2],   %[temp8],   %[temp9]   \n\t"
+                "lwc1    %[temp18],  4876(%[v0])                        \n\t"
+                "madd.s  %[temp3],   %[temp3],   %[temp10],  %[temp11]  \n\t"
+                "lwc1    %[temp19],  2316(%[s0])                        \n\t"
+                "madd.s  %[temp0],   %[temp0],   %[temp12],  %[temp13]  \n\t"
+                "addiu   %[dst],     %[dst],     16                     \n\t"
+                "madd.s  %[temp1],   %[temp1],   %[temp14],  %[temp15]  \n\t"
+                "madd.s  %[temp2],   %[temp2],   %[temp16],  %[temp17]  \n\t"
+                "madd.s  %[temp3],   %[temp3],   %[temp18],  %[temp19]  \n\t"
+                "swc1    %[temp0],   -16(%[dst])                        \n\t"
+                "swc1    %[temp1],   -12(%[dst])                        \n\t"
+                "swc1    %[temp2],   -8(%[dst])                         \n\t"
+                "swc1    %[temp3],   -4(%[dst])                         \n\t"
+                ".set    pop                                            \n\t"
+
+                : [dst]"+r"(dst), [v0]"+r"(vv0), [s0]"+r"(s0),
+                  [temp0]"=&f"(temp0), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
+                  [temp3]"=&f"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5),
+                  [temp6]"=&f"(temp6), [temp7]"=&f"(temp7), [temp8]"=&f"(temp8),
+                  [temp9]"=&f"(temp9), [temp10]"=&f"(temp10), [temp11]"=&f"(temp11),
+                  [temp12]"=&f"(temp12), [temp13]"=&f"(temp13), [temp14]"=&f"(temp14),
+                  [temp15]"=&f"(temp15), [temp16]"=&f"(temp16), [temp17]"=&f"(temp17),
+                  [temp18]"=&f"(temp18), [temp19]"=&f"(temp19)
+                : [v0_end]"r"(v0_end)
+                : "memory"
+            );
+        }
+        else
+        {
+            fdsp->vector_fmul   (out, v                , sbr_qmf_window                       , 64 >> div);
+            fdsp->vector_fmul_add(out, v + ( 192 >> div), sbr_qmf_window + ( 64 >> div), out   , 64 >> div);
+            fdsp->vector_fmul_add(out, v + ( 256 >> div), sbr_qmf_window + (128 >> div), out   , 64 >> div);
+            fdsp->vector_fmul_add(out, v + ( 448 >> div), sbr_qmf_window + (192 >> div), out   , 64 >> div);
+            fdsp->vector_fmul_add(out, v + ( 512 >> div), sbr_qmf_window + (256 >> div), out   , 64 >> div);
+            fdsp->vector_fmul_add(out, v + ( 704 >> div), sbr_qmf_window + (320 >> div), out   , 64 >> div);
+            fdsp->vector_fmul_add(out, v + ( 768 >> div), sbr_qmf_window + (384 >> div), out   , 64 >> div);
+            fdsp->vector_fmul_add(out, v + ( 960 >> div), sbr_qmf_window + (448 >> div), out   , 64 >> div);
+            fdsp->vector_fmul_add(out, v + (1024 >> div), sbr_qmf_window + (512 >> div), out   , 64 >> div);
+            fdsp->vector_fmul_add(out, v + (1216 >> div), sbr_qmf_window + (576 >> div), out   , 64 >> div);
+            out += 64 >> div;
+        }
+    }
+}
+
+#define sbr_qmf_analysis sbr_qmf_analysis_mips
+#define sbr_qmf_synthesis sbr_qmf_synthesis_mips
+
+#endif /* HAVE_MIPSFPU */
+#endif /* HAVE_INLINE_ASM */
+
+#endif /* AVCODEC_MIPS_AACSBR_FLOAT_H */
diff --git a/libavcodec/mips/ac3dsp_mips.c b/libavcodec/mips/ac3dsp_mips.c
index e503645..f33c6f1 100644
--- a/libavcodec/mips/ac3dsp_mips.c
+++ b/libavcodec/mips/ac3dsp_mips.c
@@ -26,7 +26,8 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * Author:  Branimir Vasic (bvasic@mips.com)
+ * Authors:  Branimir Vasic (bvasic@mips.com)
+ *           Nedeljko Babic (nbabic@mips.com)
  *
  * Various AC-3 DSP Utils optimized for MIPS
  *
@@ -198,7 +199,7 @@
 }
 #endif
 
-#if HAVE_MIPSFPU
+#if HAVE_MIPSFPU && HAVE_MIPS32R2
 static void float_to_fixed24_mips(int32_t *dst, const float *src, unsigned int len)
 {
     const float scale = 1 << 24;
@@ -266,93 +267,132 @@
     } while (len > 0);
 }
 
-static void ac3_downmix_mips(float (*samples)[256], float (*matrix)[2], int out_ch, int in_ch, int len)
+static void ac3_downmix_mips(float **samples, float (*matrix)[2],
+                          int out_ch, int in_ch, int len)
 {
-    int i, j;
+    int i, j, i1, i2, i3;
     float v0, v1, v2, v3;
     float v4, v5, v6, v7;
     float samples0, samples1, samples2, samples3, matrix_j, matrix_j2;
-    float *samples_p,*matrix_p;
-    if (out_ch == 2) {
-        for (i = 0; i < len; i += 4) {
-            v0 = v1 = v2 = v3 = 0.0f;
-            v4 = v5 = v6 = v7 = 0.0f;
-            samples_p = &samples[0][i];
-            matrix_p = &matrix[0][0];
-            __asm__ volatile (
-                "move   %[j],           $zero                               \n\t"
-                "1:                                                         \n\t"
-                "lwc1   %[matrix_j],    0(%[matrix_p])                      \n\t"
-                "lwc1   %[matrix_j2],   4(%[matrix_p])                      \n\t"
-                "lwc1   %[samples0],    0(%[samples_p])                     \n\t"
-                "lwc1   %[samples1],    4(%[samples_p])                     \n\t"
-                "lwc1   %[samples2],    8(%[samples_p])                     \n\t"
-                "lwc1   %[samples3],    12(%[samples_p])                    \n\t"
-                "addiu  %[matrix_p],    8                                   \n\t"
-                "madd.s %[v0],          %[v0],  %[samples0],    %[matrix_j] \n\t"
-                "madd.s %[v1],          %[v1],  %[samples1],    %[matrix_j] \n\t"
-                "madd.s %[v2],          %[v2],  %[samples2],    %[matrix_j] \n\t"
-                "madd.s %[v3],          %[v3],  %[samples3],    %[matrix_j] \n\t"
-                "madd.s %[v4],          %[v4],  %[samples0],    %[matrix_j2]\n\t"
-                "madd.s %[v5],          %[v5],  %[samples1],    %[matrix_j2]\n\t"
-                "madd.s %[v6],          %[v6],  %[samples2],    %[matrix_j2]\n\t"
-                "madd.s %[v7],          %[v7],  %[samples3],    %[matrix_j2]\n\t"
-                "addiu  %[j],           1                                   \n\t"
-                "addiu  %[samples_p],   1024                                \n\t"
-                "bne    %[j],           %[in_ch],   1b                      \n\t"
-                :[samples0]"=&f"(samples0), [samples1]"=&f"(samples1),
-                 [samples2]"=&f"(samples2), [samples3]"=&f"(samples3),
-                 [samples_p]"+r"(samples_p), [matrix_j]"=&f"(matrix_j),
-                 [matrix_p]"+r"(matrix_p), [v0]"+f"(v0), [v1]"+f"(v1),
-                 [v2]"+f"(v2), [v3]"+f"(v3), [v4]"+f"(v4), [v5]"+f"(v5),
-                 [v6]"+f"(v6), [v7]"+f"(v7),[j]"=&r"(j), [matrix_j2]"=&f"(matrix_j2)
-                :[in_ch]"r"(in_ch)
-                :"memory"
-            );
-            samples[0][i  ] = v0;
-            samples[0][i+1] = v1;
-            samples[0][i+2] = v2;
-            samples[0][i+3] = v3;
-            samples[1][i  ] = v4;
-            samples[1][i+1] = v5;
-            samples[1][i+2] = v6;
-            samples[1][i+3] = v7;
-        }
-    } else if (out_ch == 1) {
-        for (i = 0; i < len; i += 4) {
-            v0 = v1 = v2 = v3 = 0.0f;
-            samples_p = &samples[0][i];
-            matrix_p = &matrix[0][0];
-            __asm__ volatile (
-                "move   %[j],           $zero                               \n\t"
-                "1:                                                         \n\t"
-                "lwc1   %[matrix_j],    0(%[matrix_p])                      \n\t"
-                "lwc1   %[samples0],    0(%[samples_p])                     \n\t"
-                "lwc1   %[samples1],    4(%[samples_p])                     \n\t"
-                "lwc1   %[samples2],    8(%[samples_p])                     \n\t"
-                "lwc1   %[samples3],    12(%[samples_p])                    \n\t"
-                "addiu  %[matrix_p],    8                                   \n\t"
-                "madd.s %[v0],          %[v0],  %[samples0],    %[matrix_j] \n\t"
-                "madd.s %[v1],          %[v1],  %[samples1],    %[matrix_j] \n\t"
-                "madd.s %[v2],          %[v2],  %[samples2],    %[matrix_j] \n\t"
-                "madd.s %[v3],          %[v3],  %[samples3],    %[matrix_j] \n\t"
-                "addiu  %[j],           1                                   \n\t"
-                "addiu  %[samples_p],   1024                                \n\t"
-                "bne    %[j],           %[in_ch],   1b                      \n\t"
-                :[samples0]"=&f"(samples0), [samples1]"=&f"(samples1),
-                 [samples2]"=&f"(samples2), [samples3]"=&f"(samples3),
-                 [samples_p]"+r"(samples_p), [matrix_j]"=&f"(matrix_j),
-                 [matrix_p]"+r"(matrix_p), [v0]"+f"(v0), [v1]"+f"(v1),
-                 [v2]"+f"(v2), [v3]"+f"(v3), [j]"=&r"(j)
-                :[in_ch]"r"(in_ch)
-                :"memory"
-            );
-            samples[0][i  ] = v0;
-            samples[0][i+1] = v1;
-            samples[0][i+2] = v2;
-            samples[0][i+3] = v3;
-        }
-    }
+    float *samples_p,*matrix_p, **samples_x, **samples_end, **samples_sw;
+
+    __asm__ volatile(
+        ".set   push                                                \n\t"
+        ".set   noreorder                                           \n\t"
+
+        "li     %[i1],          2                                   \n\t"
+        "sll    %[len],         2                                   \n\t"
+        "move   %[i],           $zero                               \n\t"
+        "sll    %[j],           %[in_ch],               2           \n\t"
+
+        "bne    %[out_ch],      %[i1],                  3f          \n\t"   // if (out_ch == 2)
+        " li    %[i2],          1                                   \n\t"
+
+        "2:                                                         \n\t"   // start of the for loop (for (i = 0; i < len; i+=4))
+        "move   %[matrix_p],    %[matrix]                           \n\t"
+        "move   %[samples_x],   %[samples]                          \n\t"
+        "mtc1   $zero,          %[v0]                               \n\t"
+        "mtc1   $zero,          %[v1]                               \n\t"
+        "mtc1   $zero,          %[v2]                               \n\t"
+        "mtc1   $zero,          %[v3]                               \n\t"
+        "mtc1   $zero,          %[v4]                               \n\t"
+        "mtc1   $zero,          %[v5]                               \n\t"
+        "mtc1   $zero,          %[v6]                               \n\t"
+        "mtc1   $zero,          %[v7]                               \n\t"
+        "addiu  %[i1],          %[i],                  4            \n\t"
+        "addiu  %[i2],          %[i],                  8            \n\t"
+        "lw     %[samples_p],   0(%[samples_x])                     \n\t"
+        "addiu  %[i3],          %[i],                  12           \n\t"
+        "addu   %[samples_end], %[samples_x],          %[j]         \n\t"
+        "move   %[samples_sw],  %[samples_p]                        \n\t"
+
+        "1:                                                         \n\t"   // start of the inner for loop (for (j = 0; j < in_ch; j++))
+        "lwc1   %[matrix_j],    0(%[matrix_p])                      \n\t"
+        "lwc1   %[matrix_j2],   4(%[matrix_p])                      \n\t"
+        "lwxc1  %[samples0],    %[i](%[samples_p])                  \n\t"
+        "lwxc1  %[samples1],    %[i1](%[samples_p])                 \n\t"
+        "lwxc1  %[samples2],    %[i2](%[samples_p])                 \n\t"
+        "lwxc1  %[samples3],    %[i3](%[samples_p])                 \n\t"
+        "addiu  %[matrix_p],    8                                   \n\t"
+        "addiu  %[samples_x],   4                                   \n\t"
+        "madd.s %[v0],          %[v0],  %[samples0],    %[matrix_j] \n\t"
+        "madd.s %[v1],          %[v1],  %[samples1],    %[matrix_j] \n\t"
+        "madd.s %[v2],          %[v2],  %[samples2],    %[matrix_j] \n\t"
+        "madd.s %[v3],          %[v3],  %[samples3],    %[matrix_j] \n\t"
+        "madd.s %[v4],          %[v4],  %[samples0],    %[matrix_j2]\n\t"
+        "madd.s %[v5],          %[v5],  %[samples1],    %[matrix_j2]\n\t"
+        "madd.s %[v6],          %[v6],  %[samples2],    %[matrix_j2]\n\t"
+        "madd.s %[v7],          %[v7],  %[samples3],    %[matrix_j2]\n\t"
+        "bne    %[samples_x],   %[samples_end],         1b          \n\t"
+        " lw    %[samples_p],   0(%[samples_x])                     \n\t"
+
+        "lw     %[samples_p],   4(%[samples])                       \n\t"
+        "swxc1  %[v0],          %[i](%[samples_sw])                 \n\t"
+        "swxc1  %[v1],          %[i1](%[samples_sw])                \n\t"
+        "swxc1  %[v2],          %[i2](%[samples_sw])                \n\t"
+        "swxc1  %[v3],          %[i3](%[samples_sw])                \n\t"
+        "swxc1  %[v4],          %[i](%[samples_p])                  \n\t"
+        "addiu  %[i],           16                                  \n\t"
+        "swxc1  %[v5],          %[i1](%[samples_p])                 \n\t"
+        "swxc1  %[v6],          %[i2](%[samples_p])                 \n\t"
+        "bne    %[i],           %[len],                 2b          \n\t"
+        " swxc1 %[v7],          %[i3](%[samples_p])                 \n\t"
+
+        "3:                                                         \n\t"
+        "bne    %[out_ch],      %[i2],                  6f          \n\t"   // if (out_ch == 1)
+        " nop                                                       \n\t"
+
+        "5:                                                         \n\t"   // start of the outer for loop (for (i = 0; i < len; i+=4))
+        "move   %[matrix_p],    %[matrix]                           \n\t"
+        "move   %[samples_x],   %[samples]                          \n\t"
+        "mtc1   $zero,          %[v0]                               \n\t"
+        "mtc1   $zero,          %[v1]                               \n\t"
+        "mtc1   $zero,          %[v2]                               \n\t"
+        "mtc1   $zero,          %[v3]                               \n\t"
+        "addiu  %[i1],          %[i],                  4            \n\t"
+        "addiu  %[i2],          %[i],                  8            \n\t"
+        "lw     %[samples_p],   0(%[samples_x])                     \n\t"
+        "addiu  %[i3],          %[i],                  12           \n\t"
+        "addu   %[samples_end], %[samples_x],          %[j]         \n\t"
+        "move   %[samples_sw],  %[samples_p]                        \n\t"
+
+        "4:                                                         \n\t"   // start of the inner for loop (for (j = 0; j < in_ch; j++))
+        "lwc1   %[matrix_j],    0(%[matrix_p])                      \n\t"
+        "lwxc1  %[samples0],    %[i](%[samples_p])                  \n\t"
+        "lwxc1  %[samples1],    %[i1](%[samples_p])                 \n\t"
+        "lwxc1  %[samples2],    %[i2](%[samples_p])                 \n\t"
+        "lwxc1  %[samples3],    %[i3](%[samples_p])                 \n\t"
+        "addiu  %[matrix_p],    8                                   \n\t"
+        "addiu  %[samples_x],   4                                   \n\t"
+        "madd.s %[v0],          %[v0],  %[samples0],    %[matrix_j] \n\t"
+        "madd.s %[v1],          %[v1],  %[samples1],    %[matrix_j] \n\t"
+        "madd.s %[v2],          %[v2],  %[samples2],    %[matrix_j] \n\t"
+        "madd.s %[v3],          %[v3],  %[samples3],    %[matrix_j] \n\t"
+        "bne    %[samples_x],   %[samples_end],         4b          \n\t"
+        " lw    %[samples_p],   0(%[samples_x])                     \n\t"
+
+        "swxc1  %[v0],          %[i](%[samples_sw])                 \n\t"
+        "addiu  %[i],           16                                  \n\t"
+        "swxc1  %[v1],          %[i1](%[samples_sw])                \n\t"
+        "swxc1  %[v2],          %[i2](%[samples_sw])                \n\t"
+        "bne    %[i],           %[len],                 5b          \n\t"
+        " swxc1 %[v3],          %[i3](%[samples_sw])                \n\t"
+        "6:                                                         \n\t"
+
+        ".set   pop"
+        :[samples_p]"=&r"(samples_p), [matrix_j]"=&f"(matrix_j), [matrix_j2]"=&f"(matrix_j2),
+         [samples0]"=&f"(samples0), [samples1]"=&f"(samples1),
+         [samples2]"=&f"(samples2), [samples3]"=&f"(samples3),
+         [v0]"=&f"(v0), [v1]"=&f"(v1), [v2]"=&f"(v2), [v3]"=&f"(v3),
+         [v4]"=&f"(v4), [v5]"=&f"(v5), [v6]"=&f"(v6), [v7]"=&f"(v7),
+         [samples_x]"=&r"(samples_x), [matrix_p]"=&r"(matrix_p),
+         [samples_end]"=&r"(samples_end), [samples_sw]"=&r"(samples_sw),
+         [i1]"=&r"(i1), [i2]"=&r"(i2), [i3]"=&r"(i3), [i]"=&r"(i),
+         [j]"=&r"(j), [len]"+r"(len)
+        :[samples]"r"(samples), [matrix]"r"(matrix),
+         [in_ch]"r"(in_ch), [out_ch]"r"(out_ch)
+        :"memory"
+    );
 }
 #endif
 #endif /* HAVE_INLINE_ASM */
@@ -363,7 +403,7 @@
     c->bit_alloc_calc_bap = ac3_bit_alloc_calc_bap_mips;
     c->update_bap_counts  = ac3_update_bap_counts_mips;
 #endif
-#if HAVE_MIPSFPU
+#if HAVE_MIPSFPU && HAVE_MIPS32R2
     c->float_to_fixed24 = float_to_fixed24_mips;
     c->downmix          = ac3_downmix_mips;
 #endif
diff --git a/libavcodec/mips/dsputil_mips.c b/libavcodec/mips/dsputil_mips.c
deleted file mode 100644
index 76dc664..0000000
--- a/libavcodec/mips/dsputil_mips.c
+++ /dev/null
@@ -1,168 +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 is
- *    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:  Zoran Lukic (zoranl@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
- */
-#include "config.h"
-#include "libavcodec/dsputil.h"
-
-#if HAVE_INLINE_ASM
-static void vector_fmul_window_mips(float *dst, const float *src0,
-        const float *src1, const float *win, int len)
-{
-    int i, j;
-    /*
-     * variables used in inline assembler
-     */
-    float * dst_i, * dst_j, * dst_i2, * dst_j2;
-    float temp, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
-
-    dst  += len;
-    win  += len;
-    src0 += len;
-
-    for (i = -len, j = len - 1; i < 0; i += 8, j -= 8) {
-
-        dst_i = dst + i;
-        dst_j = dst + j;
-
-        dst_i2 = dst + i + 4;
-        dst_j2 = dst + j - 4;
-
-        __asm__ volatile (
-            "mul.s   %[temp],   %[s1],       %[wi]            \n\t"
-            "mul.s   %[temp1],  %[s1],       %[wj]            \n\t"
-            "mul.s   %[temp2],  %[s11],      %[wi1]           \n\t"
-            "mul.s   %[temp3],  %[s11],      %[wj1]           \n\t"
-
-            "msub.s  %[temp],   %[temp],     %[s0],  %[wj]    \n\t"
-            "madd.s  %[temp1],  %[temp1],    %[s0],  %[wi]    \n\t"
-            "msub.s  %[temp2],  %[temp2],    %[s01], %[wj1]   \n\t"
-            "madd.s  %[temp3],  %[temp3],    %[s01], %[wi1]   \n\t"
-
-            "swc1    %[temp],   0(%[dst_i])                   \n\t" /* dst[i] = s0*wj - s1*wi; */
-            "swc1    %[temp1],  0(%[dst_j])                   \n\t" /* dst[j] = s0*wi + s1*wj; */
-            "swc1    %[temp2],  4(%[dst_i])                   \n\t" /* dst[i+1] = s01*wj1 - s11*wi1; */
-            "swc1    %[temp3], -4(%[dst_j])                   \n\t" /* dst[j-1] = s01*wi1 + s11*wj1; */
-
-            "mul.s   %[temp4],  %[s12],      %[wi2]           \n\t"
-            "mul.s   %[temp5],  %[s12],      %[wj2]           \n\t"
-            "mul.s   %[temp6],  %[s13],      %[wi3]           \n\t"
-            "mul.s   %[temp7],  %[s13],      %[wj3]           \n\t"
-
-            "msub.s  %[temp4],  %[temp4],    %[s02], %[wj2]   \n\t"
-            "madd.s  %[temp5],  %[temp5],    %[s02], %[wi2]   \n\t"
-            "msub.s  %[temp6],  %[temp6],    %[s03], %[wj3]   \n\t"
-            "madd.s  %[temp7],  %[temp7],    %[s03], %[wi3]   \n\t"
-
-            "swc1    %[temp4],  8(%[dst_i])                   \n\t" /* dst[i+2] = s02*wj2 - s12*wi2; */
-            "swc1    %[temp5], -8(%[dst_j])                   \n\t" /* dst[j-2] = s02*wi2 + s12*wj2; */
-            "swc1    %[temp6],  12(%[dst_i])                  \n\t" /* dst[i+2] = s03*wj3 - s13*wi3; */
-            "swc1    %[temp7], -12(%[dst_j])                  \n\t" /* dst[j-3] = s03*wi3 + s13*wj3; */
-            : [temp]"=&f"(temp),  [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
-              [temp3]"=&f"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5),
-              [temp6]"=&f"(temp6), [temp7]"=&f"(temp7)
-            : [dst_j]"r"(dst_j),     [dst_i]"r" (dst_i),
-              [s0] "f"(src0[i]),     [wj] "f"(win[j]),     [s1] "f"(src1[j]),
-              [wi] "f"(win[i]),      [s01]"f"(src0[i + 1]),[wj1]"f"(win[j - 1]),
-              [s11]"f"(src1[j - 1]), [wi1]"f"(win[i + 1]), [s02]"f"(src0[i + 2]),
-              [wj2]"f"(win[j - 2]),  [s12]"f"(src1[j - 2]),[wi2]"f"(win[i + 2]),
-              [s03]"f"(src0[i + 3]), [wj3]"f"(win[j - 3]), [s13]"f"(src1[j - 3]),
-              [wi3]"f"(win[i + 3])
-            : "memory"
-        );
-
-        __asm__ volatile (
-            "mul.s  %[temp],   %[s1],       %[wi]            \n\t"
-            "mul.s  %[temp1],  %[s1],       %[wj]            \n\t"
-            "mul.s  %[temp2],  %[s11],      %[wi1]           \n\t"
-            "mul.s  %[temp3],  %[s11],      %[wj1]           \n\t"
-
-            "msub.s %[temp],   %[temp],     %[s0],  %[wj]    \n\t"
-            "madd.s %[temp1],  %[temp1],    %[s0],  %[wi]    \n\t"
-            "msub.s %[temp2],  %[temp2],    %[s01], %[wj1]   \n\t"
-            "madd.s %[temp3],  %[temp3],    %[s01], %[wi1]   \n\t"
-
-            "swc1   %[temp],   0(%[dst_i2])                  \n\t" /* dst[i] = s0*wj - s1*wi; */
-            "swc1   %[temp1],  0(%[dst_j2])                  \n\t" /* dst[j] = s0*wi + s1*wj; */
-            "swc1   %[temp2],  4(%[dst_i2])                  \n\t" /* dst[i+1] = s01*wj1 - s11*wi1; */
-            "swc1   %[temp3], -4(%[dst_j2])                  \n\t" /* dst[j-1] = s01*wi1 + s11*wj1; */
-
-            "mul.s  %[temp4],  %[s12],      %[wi2]           \n\t"
-            "mul.s  %[temp5],  %[s12],      %[wj2]           \n\t"
-            "mul.s  %[temp6],  %[s13],      %[wi3]           \n\t"
-            "mul.s  %[temp7],  %[s13],      %[wj3]           \n\t"
-
-            "msub.s %[temp4],  %[temp4],    %[s02], %[wj2]   \n\t"
-            "madd.s %[temp5],  %[temp5],    %[s02], %[wi2]   \n\t"
-            "msub.s %[temp6],  %[temp6],    %[s03], %[wj3]   \n\t"
-            "madd.s %[temp7],  %[temp7],    %[s03], %[wi3]   \n\t"
-
-            "swc1   %[temp4],  8(%[dst_i2])                  \n\t" /* dst[i+2] = s02*wj2 - s12*wi2; */
-            "swc1   %[temp5], -8(%[dst_j2])                  \n\t" /* dst[j-2] = s02*wi2 + s12*wj2; */
-            "swc1   %[temp6],  12(%[dst_i2])                 \n\t" /* dst[i+2] = s03*wj3 - s13*wi3; */
-            "swc1   %[temp7], -12(%[dst_j2])                 \n\t" /* dst[j-3] = s03*wi3 + s13*wj3; */
-            : [temp]"=&f"(temp),
-              [temp1]"=&f"(temp1), [temp2]"=&f"(temp2), [temp3]"=&f"(temp3),
-              [temp4]"=&f"(temp4), [temp5]"=&f"(temp5), [temp6]"=&f"(temp6),
-              [temp7]  "=&f" (temp7)
-            : [dst_j2]"r"(dst_j2),   [dst_i2]"r"(dst_i2),
-              [s0] "f"(src0[i + 4]), [wj] "f"(win[j - 4]), [s1] "f"(src1[j - 4]),
-              [wi] "f"(win[i + 4]),  [s01]"f"(src0[i + 5]),[wj1]"f"(win[j - 5]),
-              [s11]"f"(src1[j - 5]), [wi1]"f"(win[i + 5]), [s02]"f"(src0[i + 6]),
-              [wj2]"f"(win[j - 6]),  [s12]"f"(src1[j - 6]),[wi2]"f"(win[i + 6]),
-              [s03]"f"(src0[i + 7]), [wj3]"f"(win[j - 7]), [s13]"f"(src1[j - 7]),
-              [wi3]"f"(win[i + 7])
-            : "memory"
-        );
-    }
-}
-#endif /* HAVE_INLINE_ASM */
-
-av_cold void ff_dsputil_init_mips( DSPContext* c, AVCodecContext *avctx )
-{
-#if HAVE_INLINE_ASM
-    c->vector_fmul_window = vector_fmul_window_mips;
-#endif
-}
diff --git a/libavcodec/mips/sbrdsp_mips.c b/libavcodec/mips/sbrdsp_mips.c
new file mode 100644
index 0000000..d4460ba
--- /dev/null
+++ b/libavcodec/mips/sbrdsp_mips.c
@@ -0,0 +1,940 @@
+/*
+ * 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:  Darko Laus      (darko@mips.com)
+ *           Djordje Pesut   (djordje@mips.com)
+ *           Mirjana Vulin   (mvulin@mips.com)
+ *
+ * AAC Spectral Band Replication decoding functions optimized for MIPS
+ *
+ * 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
+ * Reference: libavcodec/sbrdsp.c
+ */
+
+#include "config.h"
+#include "libavcodec/sbrdsp.h"
+
+#if HAVE_INLINE_ASM
+static void sbr_neg_odd_64_mips(float *x)
+{
+    int Temp1, Temp2, Temp3, Temp4, Temp5;
+    float *x1    = &x[1];
+    float *x_end = x1 + 64;
+
+    /* loop unrolled 4 times */
+    __asm__ volatile (
+        "lui    %[Temp5],   0x8000                  \n\t"
+    "1:                                             \n\t"
+        "lw     %[Temp1],   0(%[x1])                \n\t"
+        "lw     %[Temp2],   8(%[x1])                \n\t"
+        "lw     %[Temp3],   16(%[x1])               \n\t"
+        "lw     %[Temp4],   24(%[x1])               \n\t"
+        "xor    %[Temp1],   %[Temp1],   %[Temp5]    \n\t"
+        "xor    %[Temp2],   %[Temp2],   %[Temp5]    \n\t"
+        "xor    %[Temp3],   %[Temp3],   %[Temp5]    \n\t"
+        "xor    %[Temp4],   %[Temp4],   %[Temp5]    \n\t"
+        "sw     %[Temp1],   0(%[x1])                \n\t"
+        "sw     %[Temp2],   8(%[x1])                \n\t"
+        "sw     %[Temp3],   16(%[x1])               \n\t"
+        "sw     %[Temp4],   24(%[x1])               \n\t"
+        "addiu  %[x1],      %[x1],      32          \n\t"
+        "bne    %[x1],      %[x_end],   1b          \n\t"
+
+        : [Temp1]"=&r"(Temp1), [Temp2]"=&r"(Temp2),
+          [Temp3]"=&r"(Temp3), [Temp4]"=&r"(Temp4),
+          [Temp5]"=&r"(Temp5), [x1]"+r"(x1)
+        : [x_end]"r"(x_end)
+        : "memory"
+    );
+}
+
+static void sbr_qmf_pre_shuffle_mips(float *z)
+{
+    int Temp1, Temp2, Temp3, Temp4, Temp5, Temp6;
+    float *z1 = &z[66];
+    float *z2 = &z[59];
+    float *z3 = &z[2];
+    float *z4 = z1 + 60;
+
+    /* loop unrolled 5 times */
+    __asm__ volatile (
+        "lui    %[Temp6],   0x8000                  \n\t"
+    "1:                                             \n\t"
+        "lw     %[Temp1],   0(%[z2])                \n\t"
+        "lw     %[Temp2],   4(%[z2])                \n\t"
+        "lw     %[Temp3],   8(%[z2])                \n\t"
+        "lw     %[Temp4],   12(%[z2])               \n\t"
+        "lw     %[Temp5],   16(%[z2])               \n\t"
+        "xor    %[Temp1],   %[Temp1],   %[Temp6]    \n\t"
+        "xor    %[Temp2],   %[Temp2],   %[Temp6]    \n\t"
+        "xor    %[Temp3],   %[Temp3],   %[Temp6]    \n\t"
+        "xor    %[Temp4],   %[Temp4],   %[Temp6]    \n\t"
+        "xor    %[Temp5],   %[Temp5],   %[Temp6]    \n\t"
+        "addiu  %[z2],      %[z2],      -20         \n\t"
+        "sw     %[Temp1],   32(%[z1])               \n\t"
+        "sw     %[Temp2],   24(%[z1])               \n\t"
+        "sw     %[Temp3],   16(%[z1])               \n\t"
+        "sw     %[Temp4],   8(%[z1])                \n\t"
+        "sw     %[Temp5],   0(%[z1])                \n\t"
+        "lw     %[Temp1],   0(%[z3])                \n\t"
+        "lw     %[Temp2],   4(%[z3])                \n\t"
+        "lw     %[Temp3],   8(%[z3])                \n\t"
+        "lw     %[Temp4],   12(%[z3])               \n\t"
+        "lw     %[Temp5],   16(%[z3])               \n\t"
+        "sw     %[Temp1],   4(%[z1])                \n\t"
+        "sw     %[Temp2],   12(%[z1])               \n\t"
+        "sw     %[Temp3],   20(%[z1])               \n\t"
+        "sw     %[Temp4],   28(%[z1])               \n\t"
+        "sw     %[Temp5],   36(%[z1])               \n\t"
+        "addiu  %[z3],      %[z3],      20          \n\t"
+        "addiu  %[z1],      %[z1],      40          \n\t"
+        "bne    %[z1],      %[z4],      1b          \n\t"
+        "lw     %[Temp1],   132(%[z])               \n\t"
+        "lw     %[Temp2],   128(%[z])               \n\t"
+        "lw     %[Temp3],   0(%[z])                 \n\t"
+        "lw     %[Temp4],   4(%[z])                 \n\t"
+        "xor    %[Temp1],   %[Temp1],   %[Temp6]    \n\t"
+        "sw     %[Temp1],   504(%[z])               \n\t"
+        "sw     %[Temp2],   508(%[z])               \n\t"
+        "sw     %[Temp3],   256(%[z])               \n\t"
+        "sw     %[Temp4],   260(%[z])               \n\t"
+
+        : [Temp1]"=&r"(Temp1), [Temp2]"=&r"(Temp2),
+          [Temp3]"=&r"(Temp3), [Temp4]"=&r"(Temp4),
+          [Temp5]"=&r"(Temp5), [Temp6]"=&r"(Temp6),
+          [z1]"+r"(z1), [z2]"+r"(z2), [z3]"+r"(z3)
+        : [z4]"r"(z4), [z]"r"(z)
+        : "memory"
+    );
+}
+
+static void sbr_qmf_post_shuffle_mips(float W[32][2], const float *z)
+{
+    int Temp1, Temp2, Temp3, Temp4, Temp5;
+    float *W_ptr = (float *)W;
+    float *z1    = (float *)z;
+    float *z2    = (float *)&z[60];
+    float *z_end = z1 + 32;
+
+     /* loop unrolled 4 times */
+    __asm__ volatile (
+        "lui    %[Temp5],   0x8000                  \n\t"
+    "1:                                             \n\t"
+        "lw     %[Temp1],   0(%[z2])                \n\t"
+        "lw     %[Temp2],   4(%[z2])                \n\t"
+        "lw     %[Temp3],   8(%[z2])                \n\t"
+        "lw     %[Temp4],   12(%[z2])               \n\t"
+        "xor    %[Temp1],   %[Temp1],   %[Temp5]    \n\t"
+        "xor    %[Temp2],   %[Temp2],   %[Temp5]    \n\t"
+        "xor    %[Temp3],   %[Temp3],   %[Temp5]    \n\t"
+        "xor    %[Temp4],   %[Temp4],   %[Temp5]    \n\t"
+        "addiu  %[z2],      %[z2],      -16         \n\t"
+        "sw     %[Temp1],   24(%[W_ptr])            \n\t"
+        "sw     %[Temp2],   16(%[W_ptr])            \n\t"
+        "sw     %[Temp3],   8(%[W_ptr])             \n\t"
+        "sw     %[Temp4],   0(%[W_ptr])             \n\t"
+        "lw     %[Temp1],   0(%[z1])                \n\t"
+        "lw     %[Temp2],   4(%[z1])                \n\t"
+        "lw     %[Temp3],   8(%[z1])                \n\t"
+        "lw     %[Temp4],   12(%[z1])               \n\t"
+        "sw     %[Temp1],   4(%[W_ptr])             \n\t"
+        "sw     %[Temp2],   12(%[W_ptr])            \n\t"
+        "sw     %[Temp3],   20(%[W_ptr])            \n\t"
+        "sw     %[Temp4],   28(%[W_ptr])            \n\t"
+        "addiu  %[z1],      %[z1],      16          \n\t"
+        "addiu  %[W_ptr],   %[W_ptr],   32          \n\t"
+        "bne    %[z1],      %[z_end],   1b          \n\t"
+
+        : [Temp1]"=&r"(Temp1), [Temp2]"=&r"(Temp2),
+          [Temp3]"=&r"(Temp3), [Temp4]"=&r"(Temp4),
+          [Temp5]"=&r"(Temp5), [z1]"+r"(z1),
+          [z2]"+r"(z2), [W_ptr]"+r"(W_ptr)
+        : [z_end]"r"(z_end)
+        : "memory"
+    );
+}
+
+#if HAVE_MIPSFPU
+static void sbr_sum64x5_mips(float *z)
+{
+    int k;
+    float *z1;
+    float f1, f2, f3, f4, f5, f6, f7, f8;
+    for (k = 0; k < 64; k += 8) {
+
+        z1 = &z[k];
+
+         /* loop unrolled 8 times */
+        __asm__ volatile (
+            "lwc1   $f0,    0(%[z1])        \n\t"
+            "lwc1   $f1,    256(%[z1])      \n\t"
+            "lwc1   $f2,    4(%[z1])        \n\t"
+            "lwc1   $f3,    260(%[z1])      \n\t"
+            "lwc1   $f4,    8(%[z1])        \n\t"
+            "add.s  %[f1],  $f0,    $f1     \n\t"
+            "lwc1   $f5,    264(%[z1])      \n\t"
+            "add.s  %[f2],  $f2,    $f3     \n\t"
+            "lwc1   $f6,    12(%[z1])       \n\t"
+            "lwc1   $f7,    268(%[z1])      \n\t"
+            "add.s  %[f3],  $f4,    $f5     \n\t"
+            "lwc1   $f8,    16(%[z1])       \n\t"
+            "lwc1   $f9,    272(%[z1])      \n\t"
+            "add.s  %[f4],  $f6,    $f7     \n\t"
+            "lwc1   $f10,   20(%[z1])       \n\t"
+            "lwc1   $f11,   276(%[z1])      \n\t"
+            "add.s  %[f5],  $f8,    $f9     \n\t"
+            "lwc1   $f12,   24(%[z1])       \n\t"
+            "lwc1   $f13,   280(%[z1])      \n\t"
+            "add.s  %[f6],  $f10,   $f11    \n\t"
+            "lwc1   $f14,   28(%[z1])       \n\t"
+            "lwc1   $f15,   284(%[z1])      \n\t"
+            "add.s  %[f7],  $f12,   $f13    \n\t"
+            "lwc1   $f0,    512(%[z1])      \n\t"
+            "lwc1   $f1,    516(%[z1])      \n\t"
+            "add.s  %[f8],  $f14,   $f15    \n\t"
+            "lwc1   $f2,    520(%[z1])      \n\t"
+            "add.s  %[f1],  %[f1],  $f0     \n\t"
+            "add.s  %[f2],  %[f2],  $f1     \n\t"
+            "lwc1   $f3,    524(%[z1])      \n\t"
+            "add.s  %[f3],  %[f3],  $f2     \n\t"
+            "lwc1   $f4,    528(%[z1])      \n\t"
+            "lwc1   $f5,    532(%[z1])      \n\t"
+            "add.s  %[f4],  %[f4],  $f3     \n\t"
+            "lwc1   $f6,    536(%[z1])      \n\t"
+            "add.s  %[f5],  %[f5],  $f4     \n\t"
+            "add.s  %[f6],  %[f6],  $f5     \n\t"
+            "lwc1   $f7,    540(%[z1])      \n\t"
+            "add.s  %[f7],  %[f7],  $f6     \n\t"
+            "lwc1   $f0,    768(%[z1])      \n\t"
+            "lwc1   $f1,    772(%[z1])      \n\t"
+            "add.s  %[f8],  %[f8],  $f7     \n\t"
+            "lwc1   $f2,    776(%[z1])      \n\t"
+            "add.s  %[f1],  %[f1],  $f0     \n\t"
+            "add.s  %[f2],  %[f2],  $f1     \n\t"
+            "lwc1   $f3,    780(%[z1])      \n\t"
+            "add.s  %[f3],  %[f3],  $f2     \n\t"
+            "lwc1   $f4,    784(%[z1])      \n\t"
+            "lwc1   $f5,    788(%[z1])      \n\t"
+            "add.s  %[f4],  %[f4],  $f3     \n\t"
+            "lwc1   $f6,    792(%[z1])      \n\t"
+            "add.s  %[f5],  %[f5],  $f4     \n\t"
+            "add.s  %[f6],  %[f6],  $f5     \n\t"
+            "lwc1   $f7,    796(%[z1])      \n\t"
+            "add.s  %[f7],  %[f7],  $f6     \n\t"
+            "lwc1   $f0,    1024(%[z1])     \n\t"
+            "lwc1   $f1,    1028(%[z1])     \n\t"
+            "add.s  %[f8],  %[f8],  $f7     \n\t"
+            "lwc1   $f2,    1032(%[z1])     \n\t"
+            "add.s  %[f1],  %[f1],  $f0     \n\t"
+            "add.s  %[f2],  %[f2],  $f1     \n\t"
+            "lwc1   $f3,    1036(%[z1])     \n\t"
+            "add.s  %[f3],  %[f3],  $f2     \n\t"
+            "lwc1   $f4,    1040(%[z1])     \n\t"
+            "lwc1   $f5,    1044(%[z1])     \n\t"
+            "add.s  %[f4],  %[f4],  $f3     \n\t"
+            "lwc1   $f6,    1048(%[z1])     \n\t"
+            "add.s  %[f5],  %[f5],  $f4     \n\t"
+            "add.s  %[f6],  %[f6],  $f5     \n\t"
+            "lwc1   $f7,    1052(%[z1])     \n\t"
+            "add.s  %[f7],  %[f7],  $f6     \n\t"
+            "swc1   %[f1],  0(%[z1])        \n\t"
+            "swc1   %[f2],  4(%[z1])        \n\t"
+            "add.s  %[f8],  %[f8],  $f7     \n\t"
+            "swc1   %[f3],  8(%[z1])        \n\t"
+            "swc1   %[f4],  12(%[z1])       \n\t"
+            "swc1   %[f5],  16(%[z1])       \n\t"
+            "swc1   %[f6],  20(%[z1])       \n\t"
+            "swc1   %[f7],  24(%[z1])       \n\t"
+            "swc1   %[f8],  28(%[z1])       \n\t"
+
+            : [f1]"=&f"(f1), [f2]"=&f"(f2), [f3]"=&f"(f3),
+              [f4]"=&f"(f4), [f5]"=&f"(f5), [f6]"=&f"(f6),
+              [f7]"=&f"(f7), [f8]"=&f"(f8)
+            : [z1]"r"(z1)
+            : "$f0", "$f1", "$f2", "$f3", "$f4", "$f5",
+              "$f6", "$f7", "$f8", "$f9", "$f10", "$f11",
+              "$f12", "$f13", "$f14", "$f15",
+              "memory"
+        );
+    }
+}
+
+static float sbr_sum_square_mips(float (*x)[2], int n)
+{
+    float sum0 = 0.0f, sum1 = 0.0f;
+    float *p_x;
+    float temp0, temp1, temp2, temp3;
+    float *loop_end;
+    p_x = &x[0][0];
+    loop_end = p_x + (n >> 1)*4 - 4;
+
+    __asm__ volatile (
+        ".set      push                                             \n\t"
+        ".set      noreorder                                        \n\t"
+        "lwc1      %[temp0],   0(%[p_x])                            \n\t"
+        "lwc1      %[temp1],   4(%[p_x])                            \n\t"
+        "lwc1      %[temp2],   8(%[p_x])                            \n\t"
+        "lwc1      %[temp3],   12(%[p_x])                           \n\t"
+    "1:                                                             \n\t"
+        "addiu     %[p_x],     %[p_x],       16                     \n\t"
+        "madd.s    %[sum0],    %[sum0],      %[temp0],   %[temp0]   \n\t"
+        "lwc1      %[temp0],   0(%[p_x])                            \n\t"
+        "madd.s    %[sum1],    %[sum1],      %[temp1],   %[temp1]   \n\t"
+        "lwc1      %[temp1],   4(%[p_x])                            \n\t"
+        "madd.s    %[sum0],    %[sum0],      %[temp2],   %[temp2]   \n\t"
+        "lwc1      %[temp2],   8(%[p_x])                            \n\t"
+        "madd.s    %[sum1],    %[sum1],      %[temp3],   %[temp3]   \n\t"
+        "bne       %[p_x],     %[loop_end],  1b                     \n\t"
+        " lwc1     %[temp3],   12(%[p_x])                           \n\t"
+        "madd.s    %[sum0],    %[sum0],      %[temp0],   %[temp0]   \n\t"
+        "madd.s    %[sum1],    %[sum1],      %[temp1],   %[temp1]   \n\t"
+        "madd.s    %[sum0],    %[sum0],      %[temp2],   %[temp2]   \n\t"
+        "madd.s    %[sum1],    %[sum1],      %[temp3],   %[temp3]   \n\t"
+        ".set      pop                                              \n\t"
+
+        : [temp0]"=&f"(temp0), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
+          [temp3]"=&f"(temp3), [sum0]"+f"(sum0), [sum1]"+f"(sum1),
+          [p_x]"+r"(p_x)
+        : [loop_end]"r"(loop_end)
+        : "memory"
+    );
+    return sum0 + sum1;
+}
+
+static void sbr_qmf_deint_bfly_mips(float *v, const float *src0, const float *src1)
+{
+    int i;
+    float temp0, temp1, temp2, temp3, temp4, temp5;
+    float temp6, temp7, temp8, temp9, temp10, temp11;
+    float *v0 = v;
+    float *v1 = &v[127];
+    float *psrc0 = (float*)src0;
+    float *psrc1 = (float*)&src1[63];
+
+    for (i = 0; i < 4; i++) {
+
+         /* loop unrolled 16 times */
+        __asm__ volatile(
+            "lwc1       %[temp0],   0(%[src0])             \n\t"
+            "lwc1       %[temp1],   0(%[src1])             \n\t"
+            "lwc1       %[temp3],   4(%[src0])             \n\t"
+            "lwc1       %[temp4],   -4(%[src1])            \n\t"
+            "lwc1       %[temp6],   8(%[src0])             \n\t"
+            "lwc1       %[temp7],   -8(%[src1])            \n\t"
+            "lwc1       %[temp9],   12(%[src0])            \n\t"
+            "lwc1       %[temp10],  -12(%[src1])           \n\t"
+            "add.s      %[temp2],   %[temp0],   %[temp1]   \n\t"
+            "add.s      %[temp5],   %[temp3],   %[temp4]   \n\t"
+            "add.s      %[temp8],   %[temp6],   %[temp7]   \n\t"
+            "add.s      %[temp11],  %[temp9],   %[temp10]  \n\t"
+            "sub.s      %[temp0],   %[temp0],   %[temp1]   \n\t"
+            "sub.s      %[temp3],   %[temp3],   %[temp4]   \n\t"
+            "sub.s      %[temp6],   %[temp6],   %[temp7]   \n\t"
+            "sub.s      %[temp9],   %[temp9],   %[temp10]  \n\t"
+            "swc1       %[temp2],   0(%[v1])               \n\t"
+            "swc1       %[temp0],   0(%[v0])               \n\t"
+            "swc1       %[temp5],   -4(%[v1])              \n\t"
+            "swc1       %[temp3],   4(%[v0])               \n\t"
+            "swc1       %[temp8],   -8(%[v1])              \n\t"
+            "swc1       %[temp6],   8(%[v0])               \n\t"
+            "swc1       %[temp11],  -12(%[v1])             \n\t"
+            "swc1       %[temp9],   12(%[v0])              \n\t"
+            "lwc1       %[temp0],   16(%[src0])            \n\t"
+            "lwc1       %[temp1],   -16(%[src1])           \n\t"
+            "lwc1       %[temp3],   20(%[src0])            \n\t"
+            "lwc1       %[temp4],   -20(%[src1])           \n\t"
+            "lwc1       %[temp6],   24(%[src0])            \n\t"
+            "lwc1       %[temp7],   -24(%[src1])           \n\t"
+            "lwc1       %[temp9],   28(%[src0])            \n\t"
+            "lwc1       %[temp10],  -28(%[src1])           \n\t"
+            "add.s      %[temp2],   %[temp0],   %[temp1]   \n\t"
+            "add.s      %[temp5],   %[temp3],   %[temp4]   \n\t"
+            "add.s      %[temp8],   %[temp6],   %[temp7]   \n\t"
+            "add.s      %[temp11],  %[temp9],   %[temp10]  \n\t"
+            "sub.s      %[temp0],   %[temp0],   %[temp1]   \n\t"
+            "sub.s      %[temp3],   %[temp3],   %[temp4]   \n\t"
+            "sub.s      %[temp6],   %[temp6],   %[temp7]   \n\t"
+            "sub.s      %[temp9],   %[temp9],   %[temp10]  \n\t"
+            "swc1       %[temp2],   -16(%[v1])             \n\t"
+            "swc1       %[temp0],   16(%[v0])              \n\t"
+            "swc1       %[temp5],   -20(%[v1])             \n\t"
+            "swc1       %[temp3],   20(%[v0])              \n\t"
+            "swc1       %[temp8],   -24(%[v1])             \n\t"
+            "swc1       %[temp6],   24(%[v0])              \n\t"
+            "swc1       %[temp11],  -28(%[v1])             \n\t"
+            "swc1       %[temp9],   28(%[v0])              \n\t"
+            "lwc1       %[temp0],   32(%[src0])            \n\t"
+            "lwc1       %[temp1],   -32(%[src1])           \n\t"
+            "lwc1       %[temp3],   36(%[src0])            \n\t"
+            "lwc1       %[temp4],   -36(%[src1])           \n\t"
+            "lwc1       %[temp6],   40(%[src0])            \n\t"
+            "lwc1       %[temp7],   -40(%[src1])           \n\t"
+            "lwc1       %[temp9],   44(%[src0])            \n\t"
+            "lwc1       %[temp10],  -44(%[src1])           \n\t"
+            "add.s      %[temp2],   %[temp0],   %[temp1]   \n\t"
+            "add.s      %[temp5],   %[temp3],   %[temp4]   \n\t"
+            "add.s      %[temp8],   %[temp6],   %[temp7]   \n\t"
+            "add.s      %[temp11],  %[temp9],   %[temp10]  \n\t"
+            "sub.s      %[temp0],   %[temp0],   %[temp1]   \n\t"
+            "sub.s      %[temp3],   %[temp3],   %[temp4]   \n\t"
+            "sub.s      %[temp6],   %[temp6],   %[temp7]   \n\t"
+            "sub.s      %[temp9],   %[temp9],   %[temp10]  \n\t"
+            "swc1       %[temp2],   -32(%[v1])             \n\t"
+            "swc1       %[temp0],   32(%[v0])              \n\t"
+            "swc1       %[temp5],   -36(%[v1])             \n\t"
+            "swc1       %[temp3],   36(%[v0])              \n\t"
+            "swc1       %[temp8],   -40(%[v1])             \n\t"
+            "swc1       %[temp6],   40(%[v0])              \n\t"
+            "swc1       %[temp11],  -44(%[v1])             \n\t"
+            "swc1       %[temp9],   44(%[v0])              \n\t"
+            "lwc1       %[temp0],   48(%[src0])            \n\t"
+            "lwc1       %[temp1],   -48(%[src1])           \n\t"
+            "lwc1       %[temp3],   52(%[src0])            \n\t"
+            "lwc1       %[temp4],   -52(%[src1])           \n\t"
+            "lwc1       %[temp6],   56(%[src0])            \n\t"
+            "lwc1       %[temp7],   -56(%[src1])           \n\t"
+            "lwc1       %[temp9],   60(%[src0])            \n\t"
+            "lwc1       %[temp10],  -60(%[src1])           \n\t"
+            "add.s      %[temp2],   %[temp0],   %[temp1]   \n\t"
+            "add.s      %[temp5],   %[temp3],   %[temp4]   \n\t"
+            "add.s      %[temp8],   %[temp6],   %[temp7]   \n\t"
+            "add.s      %[temp11],  %[temp9],   %[temp10]  \n\t"
+            "sub.s      %[temp0],   %[temp0],   %[temp1]   \n\t"
+            "sub.s      %[temp3],   %[temp3],   %[temp4]   \n\t"
+            "sub.s      %[temp6],   %[temp6],   %[temp7]   \n\t"
+            "sub.s      %[temp9],   %[temp9],   %[temp10]  \n\t"
+            "swc1       %[temp2],   -48(%[v1])             \n\t"
+            "swc1       %[temp0],   48(%[v0])              \n\t"
+            "swc1       %[temp5],   -52(%[v1])             \n\t"
+            "swc1       %[temp3],   52(%[v0])              \n\t"
+            "swc1       %[temp8],   -56(%[v1])             \n\t"
+            "swc1       %[temp6],   56(%[v0])              \n\t"
+            "swc1       %[temp11],  -60(%[v1])             \n\t"
+            "swc1       %[temp9],   60(%[v0])              \n\t"
+            "addiu      %[src0],    %[src0],    64         \n\t"
+            "addiu      %[src1],    %[src1],    -64        \n\t"
+            "addiu      %[v0],      %[v0],      64         \n\t"
+            "addiu      %[v1],      %[v1],      -64        \n\t"
+
+            : [v0]"+r"(v0), [v1]"+r"(v1), [src0]"+r"(psrc0), [src1]"+r"(psrc1),
+              [temp0]"=&f"(temp0), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
+              [temp3]"=&f"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5),
+              [temp6]"=&f"(temp6), [temp7]"=&f"(temp7), [temp8]"=&f"(temp8),
+              [temp9]"=&f"(temp9), [temp10]"=&f"(temp10), [temp11]"=&f"(temp11)
+            :
+            :"memory"
+        );
+    }
+}
+
+static void sbr_autocorrelate_mips(const float x[40][2], float phi[3][2][2])
+{
+    int i;
+    float real_sum_0 = 0.0f;
+    float real_sum_1 = 0.0f;
+    float real_sum_2 = 0.0f;
+    float imag_sum_1 = 0.0f;
+    float imag_sum_2 = 0.0f;
+    float *p_x, *p_phi;
+    float temp0, temp1, temp2, temp3, temp4, temp5, temp6;
+    float temp7, temp_r, temp_r1, temp_r2, temp_r3, temp_r4;
+    p_x = (float*)&x[0][0];
+    p_phi = &phi[0][0][0];
+
+    __asm__ volatile (
+        "lwc1    %[temp0],      8(%[p_x])                           \n\t"
+        "lwc1    %[temp1],      12(%[p_x])                          \n\t"
+        "lwc1    %[temp2],      16(%[p_x])                          \n\t"
+        "lwc1    %[temp3],      20(%[p_x])                          \n\t"
+        "lwc1    %[temp4],      24(%[p_x])                          \n\t"
+        "lwc1    %[temp5],      28(%[p_x])                          \n\t"
+        "mul.s   %[temp_r],     %[temp1],      %[temp1]             \n\t"
+        "mul.s   %[temp_r1],    %[temp1],      %[temp3]             \n\t"
+        "mul.s   %[temp_r2],    %[temp1],      %[temp2]             \n\t"
+        "mul.s   %[temp_r3],    %[temp1],      %[temp5]             \n\t"
+        "mul.s   %[temp_r4],    %[temp1],      %[temp4]             \n\t"
+        "madd.s  %[temp_r],     %[temp_r],     %[temp0],  %[temp0]  \n\t"
+        "madd.s  %[temp_r1],    %[temp_r1],    %[temp0],  %[temp2]  \n\t"
+        "msub.s  %[temp_r2],    %[temp_r2],    %[temp0],  %[temp3]  \n\t"
+        "madd.s  %[temp_r3],    %[temp_r3],    %[temp0],  %[temp4]  \n\t"
+        "msub.s  %[temp_r4],    %[temp_r4],    %[temp0],  %[temp5]  \n\t"
+        "add.s   %[real_sum_0], %[real_sum_0], %[temp_r]            \n\t"
+        "add.s   %[real_sum_1], %[real_sum_1], %[temp_r1]           \n\t"
+        "add.s   %[imag_sum_1], %[imag_sum_1], %[temp_r2]           \n\t"
+        "add.s   %[real_sum_2], %[real_sum_2], %[temp_r3]           \n\t"
+        "add.s   %[imag_sum_2], %[imag_sum_2], %[temp_r4]           \n\t"
+        "addiu   %[p_x],        %[p_x],        8                    \n\t"
+
+        : [temp0]"=&f"(temp0), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
+          [temp3]"=&f"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5),
+          [real_sum_0]"+f"(real_sum_0), [real_sum_1]"+f"(real_sum_1),
+          [imag_sum_1]"+f"(imag_sum_1), [real_sum_2]"+f"(real_sum_2),
+          [temp_r]"=&f"(temp_r), [temp_r1]"=&f"(temp_r1), [temp_r2]"=&f"(temp_r2),
+          [temp_r3]"=&f"(temp_r3), [temp_r4]"=&f"(temp_r4),
+          [p_x]"+r"(p_x), [imag_sum_2]"+f"(imag_sum_2)
+        :
+        : "memory"
+    );
+
+    for (i = 0; i < 12; i++) {
+        __asm__ volatile (
+            "lwc1    %[temp0],      8(%[p_x])                           \n\t"
+            "lwc1    %[temp1],      12(%[p_x])                          \n\t"
+            "lwc1    %[temp2],      16(%[p_x])                          \n\t"
+            "lwc1    %[temp3],      20(%[p_x])                          \n\t"
+            "lwc1    %[temp4],      24(%[p_x])                          \n\t"
+            "lwc1    %[temp5],      28(%[p_x])                          \n\t"
+            "mul.s   %[temp_r],     %[temp1],      %[temp1]             \n\t"
+            "mul.s   %[temp_r1],    %[temp1],      %[temp3]             \n\t"
+            "mul.s   %[temp_r2],    %[temp1],      %[temp2]             \n\t"
+            "mul.s   %[temp_r3],    %[temp1],      %[temp5]             \n\t"
+            "mul.s   %[temp_r4],    %[temp1],      %[temp4]             \n\t"
+            "madd.s  %[temp_r],     %[temp_r],     %[temp0],  %[temp0]  \n\t"
+            "madd.s  %[temp_r1],    %[temp_r1],    %[temp0],  %[temp2]  \n\t"
+            "msub.s  %[temp_r2],    %[temp_r2],    %[temp0],  %[temp3]  \n\t"
+            "madd.s  %[temp_r3],    %[temp_r3],    %[temp0],  %[temp4]  \n\t"
+            "msub.s  %[temp_r4],    %[temp_r4],    %[temp0],  %[temp5]  \n\t"
+            "add.s   %[real_sum_0], %[real_sum_0], %[temp_r]            \n\t"
+            "add.s   %[real_sum_1], %[real_sum_1], %[temp_r1]           \n\t"
+            "add.s   %[imag_sum_1], %[imag_sum_1], %[temp_r2]           \n\t"
+            "add.s   %[real_sum_2], %[real_sum_2], %[temp_r3]           \n\t"
+            "add.s   %[imag_sum_2], %[imag_sum_2], %[temp_r4]           \n\t"
+            "lwc1    %[temp0],      32(%[p_x])                          \n\t"
+            "lwc1    %[temp1],      36(%[p_x])                          \n\t"
+            "mul.s   %[temp_r],     %[temp3],      %[temp3]             \n\t"
+            "mul.s   %[temp_r1],    %[temp3],      %[temp5]             \n\t"
+            "mul.s   %[temp_r2],    %[temp3],      %[temp4]             \n\t"
+            "mul.s   %[temp_r3],    %[temp3],      %[temp1]             \n\t"
+            "mul.s   %[temp_r4],    %[temp3],      %[temp0]             \n\t"
+            "madd.s  %[temp_r],     %[temp_r],     %[temp2],  %[temp2]  \n\t"
+            "madd.s  %[temp_r1],    %[temp_r1],    %[temp2],  %[temp4]  \n\t"
+            "msub.s  %[temp_r2],    %[temp_r2],    %[temp2],  %[temp5]  \n\t"
+            "madd.s  %[temp_r3],    %[temp_r3],    %[temp2],  %[temp0]  \n\t"
+            "msub.s  %[temp_r4],    %[temp_r4],    %[temp2],  %[temp1]  \n\t"
+            "add.s   %[real_sum_0], %[real_sum_0], %[temp_r]            \n\t"
+            "add.s   %[real_sum_1], %[real_sum_1], %[temp_r1]           \n\t"
+            "add.s   %[imag_sum_1], %[imag_sum_1], %[temp_r2]           \n\t"
+            "add.s   %[real_sum_2], %[real_sum_2], %[temp_r3]           \n\t"
+            "add.s   %[imag_sum_2], %[imag_sum_2], %[temp_r4]           \n\t"
+            "lwc1    %[temp2],      40(%[p_x])                          \n\t"
+            "lwc1    %[temp3],      44(%[p_x])                          \n\t"
+            "mul.s   %[temp_r],     %[temp5],      %[temp5]             \n\t"
+            "mul.s   %[temp_r1],    %[temp5],      %[temp1]             \n\t"
+            "mul.s   %[temp_r2],    %[temp5],      %[temp0]             \n\t"
+            "mul.s   %[temp_r3],    %[temp5],      %[temp3]             \n\t"
+            "mul.s   %[temp_r4],    %[temp5],      %[temp2]             \n\t"
+            "madd.s  %[temp_r],     %[temp_r],     %[temp4],  %[temp4]  \n\t"
+            "madd.s  %[temp_r1],    %[temp_r1],    %[temp4],  %[temp0]  \n\t"
+            "msub.s  %[temp_r2],    %[temp_r2],    %[temp4],  %[temp1]  \n\t"
+            "madd.s  %[temp_r3],    %[temp_r3],    %[temp4],  %[temp2]  \n\t"
+            "msub.s  %[temp_r4],    %[temp_r4],    %[temp4],  %[temp3]  \n\t"
+            "add.s   %[real_sum_0], %[real_sum_0], %[temp_r]            \n\t"
+            "add.s   %[real_sum_1], %[real_sum_1], %[temp_r1]           \n\t"
+            "add.s   %[imag_sum_1], %[imag_sum_1], %[temp_r2]           \n\t"
+            "add.s   %[real_sum_2], %[real_sum_2], %[temp_r3]           \n\t"
+            "add.s   %[imag_sum_2], %[imag_sum_2], %[temp_r4]           \n\t"
+            "addiu   %[p_x],        %[p_x],        24                   \n\t"
+
+            : [temp0]"=&f"(temp0), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
+              [temp3]"=&f"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5),
+              [real_sum_0]"+f"(real_sum_0), [real_sum_1]"+f"(real_sum_1),
+              [imag_sum_1]"+f"(imag_sum_1), [real_sum_2]"+f"(real_sum_2),
+              [temp_r]"=&f"(temp_r), [temp_r1]"=&f"(temp_r1),
+              [temp_r2]"=&f"(temp_r2), [temp_r3]"=&f"(temp_r3),
+              [temp_r4]"=&f"(temp_r4), [p_x]"+r"(p_x),
+              [imag_sum_2]"+f"(imag_sum_2)
+            :
+            : "memory"
+        );
+    }
+    __asm__ volatile (
+        "lwc1    %[temp0],    -296(%[p_x])                        \n\t"
+        "lwc1    %[temp1],    -292(%[p_x])                        \n\t"
+        "lwc1    %[temp2],    8(%[p_x])                           \n\t"
+        "lwc1    %[temp3],    12(%[p_x])                          \n\t"
+        "lwc1    %[temp4],    -288(%[p_x])                        \n\t"
+        "lwc1    %[temp5],    -284(%[p_x])                        \n\t"
+        "lwc1    %[temp6],    -280(%[p_x])                        \n\t"
+        "lwc1    %[temp7],    -276(%[p_x])                        \n\t"
+        "madd.s  %[temp_r],   %[real_sum_0], %[temp0],  %[temp0]  \n\t"
+        "madd.s  %[temp_r1],  %[real_sum_0], %[temp2],  %[temp2]  \n\t"
+        "madd.s  %[temp_r2],  %[real_sum_1], %[temp0],  %[temp4]  \n\t"
+        "madd.s  %[temp_r3],  %[imag_sum_1], %[temp0],  %[temp5]  \n\t"
+        "madd.s  %[temp_r],   %[temp_r],     %[temp1],  %[temp1]  \n\t"
+        "madd.s  %[temp_r1],  %[temp_r1],    %[temp3],  %[temp3]  \n\t"
+        "madd.s  %[temp_r2],  %[temp_r2],    %[temp1],  %[temp5]  \n\t"
+        "nmsub.s  %[temp_r3], %[temp_r3],    %[temp1],  %[temp4]  \n\t"
+        "lwc1    %[temp4],    16(%[p_x])                          \n\t"
+        "lwc1    %[temp5],    20(%[p_x])                          \n\t"
+        "swc1    %[temp_r],   40(%[p_phi])                        \n\t"
+        "swc1    %[temp_r1],  16(%[p_phi])                        \n\t"
+        "swc1    %[temp_r2],  24(%[p_phi])                        \n\t"
+        "swc1    %[temp_r3],  28(%[p_phi])                        \n\t"
+        "madd.s  %[temp_r],   %[real_sum_1], %[temp2],  %[temp4]  \n\t"
+        "madd.s  %[temp_r1],  %[imag_sum_1], %[temp2],  %[temp5]  \n\t"
+        "madd.s  %[temp_r2],  %[real_sum_2], %[temp0],  %[temp6]  \n\t"
+        "madd.s  %[temp_r3],  %[imag_sum_2], %[temp0],  %[temp7]  \n\t"
+        "madd.s  %[temp_r],   %[temp_r],     %[temp3],  %[temp5]  \n\t"
+        "nmsub.s %[temp_r1],  %[temp_r1],    %[temp3],  %[temp4]  \n\t"
+        "madd.s  %[temp_r2],  %[temp_r2],    %[temp1],  %[temp7]  \n\t"
+        "nmsub.s %[temp_r3],  %[temp_r3],    %[temp1],  %[temp6]  \n\t"
+        "swc1    %[temp_r],   0(%[p_phi])                         \n\t"
+        "swc1    %[temp_r1],  4(%[p_phi])                         \n\t"
+        "swc1    %[temp_r2],  8(%[p_phi])                         \n\t"
+        "swc1    %[temp_r3],  12(%[p_phi])                        \n\t"
+
+        : [temp0]"=&f"(temp0), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
+          [temp3]"=&f"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5),
+          [temp6]"=&f"(temp6), [temp7]"=&f"(temp7), [temp_r]"=&f"(temp_r),
+          [real_sum_0]"+f"(real_sum_0), [real_sum_1]"+f"(real_sum_1),
+          [real_sum_2]"+f"(real_sum_2), [imag_sum_1]"+f"(imag_sum_1),
+          [temp_r2]"=&f"(temp_r2), [temp_r3]"=&f"(temp_r3),
+          [temp_r1]"=&f"(temp_r1), [p_phi]"+r"(p_phi),
+          [imag_sum_2]"+f"(imag_sum_2)
+        : [p_x]"r"(p_x)
+        : "memory"
+    );
+}
+
+static void sbr_hf_gen_mips(float (*X_high)[2], const float (*X_low)[2],
+                         const float alpha0[2], const float alpha1[2],
+                         float bw, int start, int end)
+{
+    float alpha[4];
+    int i;
+    float *p_x_low = (float*)&X_low[0][0] + 2*start;
+    float *p_x_high = &X_high[0][0] + 2*start;
+    float temp0, temp1, temp2, temp3, temp4, temp5, temp6;
+    float temp7, temp8, temp9, temp10, temp11, temp12;
+
+    alpha[0] = alpha1[0] * bw * bw;
+    alpha[1] = alpha1[1] * bw * bw;
+    alpha[2] = alpha0[0] * bw;
+    alpha[3] = alpha0[1] * bw;
+
+    for (i = start; i < end; i++) {
+        __asm__ volatile (
+            "lwc1    %[temp0],    -16(%[p_x_low])                        \n\t"
+            "lwc1    %[temp1],    -12(%[p_x_low])                        \n\t"
+            "lwc1    %[temp2],    -8(%[p_x_low])                         \n\t"
+            "lwc1    %[temp3],    -4(%[p_x_low])                         \n\t"
+            "lwc1    %[temp5],    0(%[p_x_low])                          \n\t"
+            "lwc1    %[temp6],    4(%[p_x_low])                          \n\t"
+            "lwc1    %[temp7],    0(%[alpha])                            \n\t"
+            "lwc1    %[temp8],    4(%[alpha])                            \n\t"
+            "lwc1    %[temp9],    8(%[alpha])                            \n\t"
+            "lwc1    %[temp10],   12(%[alpha])                           \n\t"
+            "addiu   %[p_x_high], %[p_x_high],     8                     \n\t"
+            "addiu   %[p_x_low],  %[p_x_low],      8                     \n\t"
+            "mul.s   %[temp11],   %[temp1],        %[temp8]              \n\t"
+            "msub.s  %[temp11],   %[temp11],       %[temp0],  %[temp7]   \n\t"
+            "madd.s  %[temp11],   %[temp11],       %[temp2],  %[temp9]   \n\t"
+            "nmsub.s %[temp11],   %[temp11],       %[temp3],  %[temp10]  \n\t"
+            "add.s   %[temp11],   %[temp11],       %[temp5]              \n\t"
+            "swc1    %[temp11],   -8(%[p_x_high])                        \n\t"
+            "mul.s   %[temp12],   %[temp1],        %[temp7]              \n\t"
+            "madd.s  %[temp12],   %[temp12],       %[temp0],  %[temp8]   \n\t"
+            "madd.s  %[temp12],   %[temp12],       %[temp3],  %[temp9]   \n\t"
+            "madd.s  %[temp12],   %[temp12],       %[temp2],  %[temp10]  \n\t"
+            "add.s   %[temp12],   %[temp12],       %[temp6]              \n\t"
+            "swc1    %[temp12],   -4(%[p_x_high])                        \n\t"
+
+            : [temp0]"=&f"(temp0), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
+              [temp3]"=&f"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5),
+              [temp6]"=&f"(temp6), [temp7]"=&f"(temp7), [temp8]"=&f"(temp8),
+              [temp9]"=&f"(temp9), [temp10]"=&f"(temp10), [temp11]"=&f"(temp11),
+              [temp12]"=&f"(temp12), [p_x_high]"+r"(p_x_high),
+              [p_x_low]"+r"(p_x_low)
+            : [alpha]"r"(alpha)
+            : "memory"
+        );
+    }
+}
+
+static void sbr_hf_g_filt_mips(float (*Y)[2], const float (*X_high)[40][2],
+                            const float *g_filt, int m_max, intptr_t ixh)
+{
+    float *p_y, *p_x, *p_g;
+    float temp0, temp1, temp2;
+    int loop_end;
+
+    p_g = (float*)&g_filt[0];
+    p_y = &Y[0][0];
+    p_x = (float*)&X_high[0][ixh][0];
+    loop_end = (int)((int*)p_g + m_max);
+
+    __asm__ volatile(
+        ".set    push                                \n\t"
+        ".set    noreorder                           \n\t"
+    "1:                                              \n\t"
+        "lwc1    %[temp0],   0(%[p_g])               \n\t"
+        "lwc1    %[temp1],   0(%[p_x])               \n\t"
+        "lwc1    %[temp2],   4(%[p_x])               \n\t"
+        "mul.s   %[temp1],   %[temp1],     %[temp0]  \n\t"
+        "mul.s   %[temp2],   %[temp2],     %[temp0]  \n\t"
+        "addiu   %[p_g],     %[p_g],       4         \n\t"
+        "addiu   %[p_x],     %[p_x],       320       \n\t"
+        "swc1    %[temp1],   0(%[p_y])               \n\t"
+        "swc1    %[temp2],   4(%[p_y])               \n\t"
+        "bne     %[p_g],     %[loop_end],  1b        \n\t"
+        " addiu  %[p_y],     %[p_y],       8         \n\t"
+        ".set    pop                                 \n\t"
+
+        : [temp0]"=&f"(temp0), [temp1]"=&f"(temp1),
+          [temp2]"=&f"(temp2), [p_x]"+r"(p_x),
+          [p_y]"+r"(p_y), [p_g]"+r"(p_g)
+        : [loop_end]"r"(loop_end)
+        : "memory"
+    );
+}
+
+static void sbr_hf_apply_noise_0_mips(float (*Y)[2], const float *s_m,
+                                 const float *q_filt, int noise,
+                                 int kx, int m_max)
+{
+    int m;
+
+    for (m = 0; m < m_max; m++){
+
+        float *Y1=&Y[m][0];
+        float *ff_table;
+        float y0,y1, temp1, temp2, temp4, temp5;
+        int temp0, temp3;
+        const float *s_m1=&s_m[m];
+        const float *q_filt1= &q_filt[m];
+
+        __asm__ volatile(
+            "lwc1    %[y0],       0(%[Y1])                                    \n\t"
+            "lwc1    %[temp1],    0(%[s_m1])                                  \n\t"
+            "addiu   %[noise],    %[noise],              1                    \n\t"
+            "andi    %[noise],    %[noise],              0x1ff                \n\t"
+            "sll     %[temp0],    %[noise], 3                                 \n\t"
+            "addu    %[ff_table], %[ff_sbr_noise_table], %[temp0]             \n\t"
+            "add.s   %[y0],       %[y0],                 %[temp1]             \n\t"
+            "mfc1    %[temp3],    %[temp1]                                    \n\t"
+            "bne     %[temp3],    $0,                    1f                   \n\t"
+            "lwc1    %[y1],       4(%[Y1])                                    \n\t"
+            "lwc1    %[temp2],    0(%[q_filt1])                               \n\t"
+            "lwc1    %[temp4],    0(%[ff_table])                              \n\t"
+            "lwc1    %[temp5],    4(%[ff_table])                              \n\t"
+            "madd.s  %[y0],       %[y0],                 %[temp2],  %[temp4]  \n\t"
+            "madd.s  %[y1],       %[y1],                 %[temp2],  %[temp5]  \n\t"
+            "swc1    %[y1],       4(%[Y1])                                    \n\t"
+        "1:                                                                   \n\t"
+            "swc1    %[y0],       0(%[Y1])                                    \n\t"
+
+            : [ff_table]"=&r"(ff_table), [y0]"=&f"(y0), [y1]"=&f"(y1),
+              [temp0]"=&r"(temp0), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
+              [temp3]"=&r"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5)
+            : [ff_sbr_noise_table]"r"(ff_sbr_noise_table), [noise]"r"(noise),
+              [Y1]"r"(Y1), [s_m1]"r"(s_m1), [q_filt1]"r"(q_filt1)
+            : "memory"
+        );
+    }
+}
+
+static void sbr_hf_apply_noise_1_mips(float (*Y)[2], const float *s_m,
+                                 const float *q_filt, int noise,
+                                 int kx, int m_max)
+{
+    float y0,y1,temp1, temp2, temp4, temp5;
+    int temp0, temp3, m;
+    float phi_sign = 1 - 2 * (kx & 1);
+
+    for (m = 0; m < m_max; m++) {
+
+        float *ff_table;
+        float *Y1=&Y[m][0];
+        const float *s_m1=&s_m[m];
+        const float *q_filt1= &q_filt[m];
+
+        __asm__ volatile(
+            "lwc1   %[y1],       4(%[Y1])                                     \n\t"
+            "lwc1   %[temp1],    0(%[s_m1])                                   \n\t"
+            "lw     %[temp3],    0(%[s_m1])                                   \n\t"
+            "addiu  %[noise],    %[noise],               1                    \n\t"
+            "andi   %[noise],    %[noise],               0x1ff                \n\t"
+            "sll    %[temp0],    %[noise],               3                    \n\t"
+            "addu   %[ff_table], %[ff_sbr_noise_table], %[temp0]              \n\t"
+            "madd.s %[y1],       %[y1],                 %[temp1], %[phi_sign] \n\t"
+            "bne    %[temp3],    $0,                    1f                    \n\t"
+            "lwc1   %[y0],       0(%[Y1])                                     \n\t"
+            "lwc1   %[temp2],    0(%[q_filt1])                                \n\t"
+            "lwc1   %[temp4],    0(%[ff_table])                               \n\t"
+            "lwc1   %[temp5],    4(%[ff_table])                               \n\t"
+            "madd.s %[y0],       %[y0],                 %[temp2], %[temp4]    \n\t"
+            "madd.s %[y1],       %[y1],                 %[temp2], %[temp5]    \n\t"
+            "swc1   %[y0],       0(%[Y1])                                     \n\t"
+        "1:                                                                   \n\t"
+            "swc1   %[y1],       4(%[Y1])                                     \n\t"
+
+            : [ff_table] "=&r" (ff_table), [y0] "=&f" (y0), [y1] "=&f" (y1),
+              [temp0] "=&r" (temp0), [temp1] "=&f" (temp1), [temp2] "=&f" (temp2),
+              [temp3] "=&r" (temp3), [temp4] "=&f" (temp4), [temp5] "=&f" (temp5)
+            : [ff_sbr_noise_table] "r" (ff_sbr_noise_table), [noise] "r" (noise),
+              [Y1] "r" (Y1), [s_m1] "r" (s_m1), [q_filt1] "r" (q_filt1),
+              [phi_sign] "f" (phi_sign)
+            : "memory"
+        );
+        phi_sign = -phi_sign;
+    }
+}
+
+static void sbr_hf_apply_noise_2_mips(float (*Y)[2], const float *s_m,
+                                 const float *q_filt, int noise,
+                                 int kx, int m_max)
+{
+    int m;
+    float *ff_table;
+    float y0,y1, temp0, temp1, temp2, temp3, temp4, temp5;
+
+    for (m = 0; m < m_max; m++) {
+
+        float *Y1=&Y[m][0];
+        const float *s_m1=&s_m[m];
+        const float *q_filt1= &q_filt[m];
+
+        __asm__ volatile(
+            "lwc1   %[y0],       0(%[Y1])                                  \n\t"
+            "lwc1   %[temp1],    0(%[s_m1])                                \n\t"
+            "addiu  %[noise],    %[noise],              1                  \n\t"
+            "andi   %[noise],    %[noise],              0x1ff              \n\t"
+            "sll    %[temp0],    %[noise],              3                  \n\t"
+            "addu   %[ff_table], %[ff_sbr_noise_table], %[temp0]           \n\t"
+            "sub.s  %[y0],       %[y0],                 %[temp1]           \n\t"
+            "mfc1   %[temp3],    %[temp1]                                  \n\t"
+            "bne    %[temp3],    $0,                    1f                 \n\t"
+            "lwc1   %[y1],       4(%[Y1])                                  \n\t"
+            "lwc1   %[temp2],    0(%[q_filt1])                             \n\t"
+            "lwc1   %[temp4],    0(%[ff_table])                            \n\t"
+            "lwc1   %[temp5],    4(%[ff_table])                            \n\t"
+            "madd.s %[y0],       %[y0],                 %[temp2], %[temp4] \n\t"
+            "madd.s %[y1],       %[y1],                 %[temp2], %[temp5] \n\t"
+            "swc1   %[y1],       4(%[Y1])                                  \n\t"
+        "1:                                                                \n\t"
+            "swc1   %[y0],       0(%[Y1])                                  \n\t"
+
+            : [temp0]"=&r"(temp0), [ff_table]"=&r"(ff_table), [y0]"=&f"(y0),
+              [y1]"=&f"(y1), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
+              [temp3]"=&r"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5)
+            : [ff_sbr_noise_table]"r"(ff_sbr_noise_table), [noise]"r"(noise),
+              [Y1]"r"(Y1), [s_m1]"r"(s_m1), [q_filt1]"r"(q_filt1)
+            : "memory"
+        );
+    }
+}
+
+static void sbr_hf_apply_noise_3_mips(float (*Y)[2], const float *s_m,
+                                 const float *q_filt, int noise,
+                                 int kx, int m_max)
+{
+    float phi_sign = 1 - 2 * (kx & 1);
+    int m;
+
+    for (m = 0; m < m_max; m++) {
+
+        float *Y1=&Y[m][0];
+        float *ff_table;
+        float y0,y1, temp1, temp2, temp4, temp5;
+        int temp0, temp3;
+        const float *s_m1=&s_m[m];
+        const float *q_filt1= &q_filt[m];
+
+        __asm__ volatile(
+            "lwc1    %[y1],       4(%[Y1])                                     \n\t"
+            "lwc1    %[temp1],    0(%[s_m1])                                   \n\t"
+            "addiu   %[noise],    %[noise],              1                     \n\t"
+            "andi    %[noise],    %[noise],              0x1ff                 \n\t"
+            "sll     %[temp0],    %[noise],              3                     \n\t"
+            "addu    %[ff_table], %[ff_sbr_noise_table], %[temp0]              \n\t"
+            "nmsub.s %[y1],       %[y1],                 %[temp1], %[phi_sign] \n\t"
+            "mfc1    %[temp3],    %[temp1]                                     \n\t"
+            "bne     %[temp3],    $0,                    1f                    \n\t"
+            "lwc1    %[y0],       0(%[Y1])                                     \n\t"
+            "lwc1    %[temp2],    0(%[q_filt1])                                \n\t"
+            "lwc1    %[temp4],    0(%[ff_table])                               \n\t"
+            "lwc1    %[temp5],    4(%[ff_table])                               \n\t"
+            "madd.s  %[y0],       %[y0],                 %[temp2], %[temp4]    \n\t"
+            "madd.s  %[y1],       %[y1],                 %[temp2], %[temp5]    \n\t"
+            "swc1    %[y0],       0(%[Y1])                                     \n\t"
+            "1:                                                                \n\t"
+            "swc1    %[y1],       4(%[Y1])                                     \n\t"
+
+            : [ff_table]"=&r"(ff_table), [y0]"=&f"(y0), [y1]"=&f"(y1),
+              [temp0]"=&r"(temp0), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
+              [temp3]"=&r"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5)
+            : [ff_sbr_noise_table]"r"(ff_sbr_noise_table), [noise]"r"(noise),
+              [Y1]"r"(Y1), [s_m1]"r"(s_m1), [q_filt1]"r"(q_filt1),
+              [phi_sign]"f"(phi_sign)
+            : "memory"
+        );
+       phi_sign = -phi_sign;
+    }
+}
+#endif /* HAVE_MIPSFPU */
+#endif /* HAVE_INLINE_ASM */
+
+void ff_sbrdsp_init_mips(SBRDSPContext *s)
+{
+#if HAVE_INLINE_ASM
+    s->neg_odd_64 = sbr_neg_odd_64_mips;
+    s->qmf_pre_shuffle = sbr_qmf_pre_shuffle_mips;
+    s->qmf_post_shuffle = sbr_qmf_post_shuffle_mips;
+#if HAVE_MIPSFPU
+    s->sum64x5 = sbr_sum64x5_mips;
+    s->sum_square = sbr_sum_square_mips;
+    s->qmf_deint_bfly = sbr_qmf_deint_bfly_mips;
+    s->autocorrelate = sbr_autocorrelate_mips;
+    s->hf_gen = sbr_hf_gen_mips;
+    s->hf_g_filt = sbr_hf_g_filt_mips;
+
+    s->hf_apply_noise[0] = sbr_hf_apply_noise_0_mips;
+    s->hf_apply_noise[1] = sbr_hf_apply_noise_1_mips;
+    s->hf_apply_noise[2] = sbr_hf_apply_noise_2_mips;
+    s->hf_apply_noise[3] = sbr_hf_apply_noise_3_mips;
+#endif /* HAVE_MIPSFPU */
+#endif /* HAVE_INLINE_ASM */
+}
diff --git a/libavcodec/mjpegbdec.c b/libavcodec/mjpegbdec.c
index 796ef84..5284233 100644
--- a/libavcodec/mjpegbdec.c
+++ b/libavcodec/mjpegbdec.c
@@ -38,7 +38,7 @@
 }
 
 static int mjpegb_decode_frame(AVCodecContext *avctx,
-                              void *data, int *data_size,
+                              void *data, int *got_frame,
                               AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
@@ -142,7 +142,7 @@
     }
 
     *picture= *s->picture_ptr;
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
 
     if(!s->lossless){
         picture->quality= FFMAX3(s->qscale[0], s->qscale[1], s->qscale[2]);
diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index c47093b..ba5753b 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -34,7 +34,8 @@
 #include "libavutil/avassert.h"
 #include "libavutil/opt.h"
 #include "avcodec.h"
-#include "dsputil.h"
+#include "copy_block.h"
+#include "internal.h"
 #include "mjpeg.h"
 #include "mjpegdec.h"
 #include "jpeglsdec.h"
@@ -128,10 +129,10 @@
     len = get_bits(&s->gb, 16) - 2;
 
     while (len >= 65) {
-        /* only 8 bit precision handled */
-        if (get_bits(&s->gb, 4) != 0) {
-            av_log(s->avctx, AV_LOG_ERROR, "dqt: 16bit precision\n");
-            return -1;
+        int pr = get_bits(&s->gb, 4);
+        if (pr > 1) {
+            av_log(s->avctx, AV_LOG_ERROR, "dqt: invalid precision\n");
+            return AVERROR_INVALIDDATA;
         }
         index = get_bits(&s->gb, 4);
         if (index >= 4)
@@ -140,7 +141,7 @@
         /* read quant table */
         for (i = 0; i < 64; i++) {
             j = s->scantable.permutated[i];
-            s->quant_matrixes[index][j] = get_bits(&s->gb, 8);
+            s->quant_matrixes[index][j] = get_bits(&s->gb, pr ? 16 : 8);
         }
 
         // XXX FIXME finetune, and perhaps add dc too
@@ -297,13 +298,11 @@
         return AVERROR_PATCHWELCOME;
     }
 
-    if (s->v_max == 1 && s->h_max == 1 && s->lossless==1 && nb_components==3)
-        s->rgb = 1;
 
     /* if different size, realloc/alloc picture */
     if (   width != s->width || height != s->height
-        || memcmp(s->h_count, h_count, sizeof(h_count[0])*nb_components)
-        || memcmp(s->v_count, v_count, sizeof(v_count[0])*nb_components)) {
+        || memcmp(s->h_count, h_count, sizeof(h_count))
+        || memcmp(s->v_count, v_count, sizeof(v_count))) {
         av_freep(&s->qscale_table);
 
         s->width      = width;
@@ -336,6 +335,10 @@
             return AVERROR_INVALIDDATA;
         }
     } else{
+        if (s->v_max == 1 && s->h_max == 1 && s->lossless==1 && nb_components==3)
+            s->rgb = 1;
+        else if (!s->lossless)
+            s->rgb = 0;
     /* XXX: not complete test ! */
     pix_fmt_id = (s->h_count[0] << 28) | (s->v_count[0] << 24) |
                  (s->h_count[1] << 20) | (s->v_count[1] << 16) |
@@ -387,6 +390,14 @@
         s->chroma_height = s->height / 2;
         break;
     case 0x11000000:
+    case 0x13000000:
+    case 0x14000000:
+    case 0x31000000:
+    case 0x33000000:
+    case 0x34000000:
+    case 0x41000000:
+    case 0x43000000:
+    case 0x44000000:
         if(s->bits <= 8)
             s->avctx->pix_fmt = AV_PIX_FMT_GRAY8;
         else
@@ -435,7 +446,7 @@
     if (s->picture_ptr->data[0])
         s->avctx->release_buffer(s->avctx, s->picture_ptr);
 
-    if (s->avctx->get_buffer(s->avctx, s->picture_ptr) < 0) {
+    if (ff_get_buffer(s->avctx, s->picture_ptr) < 0) {
         av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return -1;
     }
@@ -454,6 +465,11 @@
         av_log(s->avctx, AV_LOG_DEBUG, "decode_sof0: error, len(%d) mismatch\n", len);
     }
 
+    if (s->rgb && !s->lossless && !s->ls) {
+        av_log(s->avctx, AV_LOG_ERROR, "Unsupported coding and pixel format combination\n");
+        return AVERROR_PATCHWELCOME;
+    }
+
     /* totally blank picture as progressive JPEG will only add details to it */
     if (s->progressive) {
         int bw = (width  + s->h_max * 8 - 1) / (s->h_max * 8);
@@ -489,7 +505,7 @@
 }
 
 /* decode block and dequantize */
-static int decode_block(MJpegDecodeContext *s, DCTELEM *block, int component,
+static int decode_block(MJpegDecodeContext *s, int16_t *block, int component,
                         int dc_index, int ac_index, int16_t *quant_matrix)
 {
     int code, i, j, level, val;
@@ -537,7 +553,7 @@
     return 0;
 }
 
-static int decode_dc_progressive(MJpegDecodeContext *s, DCTELEM *block,
+static int decode_dc_progressive(MJpegDecodeContext *s, int16_t *block,
                                  int component, int dc_index,
                                  int16_t *quant_matrix, int Al)
 {
@@ -555,7 +571,7 @@
 }
 
 /* decode block and dequantize - progressive JPEG version */
-static int decode_block_progressive(MJpegDecodeContext *s, DCTELEM *block,
+static int decode_block_progressive(MJpegDecodeContext *s, int16_t *block,
                                     uint8_t *last_nnz, int ac_index,
                                     int16_t *quant_matrix,
                                     int ss, int se, int Al, int *EOBRUN)
@@ -653,7 +669,7 @@
 }
 
 /* decode block and dequantize - progressive JPEG refinement pass */
-static int decode_block_refinement(MJpegDecodeContext *s, DCTELEM *block,
+static int decode_block_refinement(MJpegDecodeContext *s, int16_t *block,
                                    uint8_t *last_nnz,
                                    int ac_index, int16_t *quant_matrix,
                                    int ss, int se, int Al, int *EOBRUN)
@@ -718,6 +734,33 @@
 #undef REFINE_BIT
 #undef ZERO_RUN
 
+static void handle_rstn(MJpegDecodeContext *s, int nb_components)
+{
+    int i;
+    if (s->restart_interval) {
+        s->restart_count--;
+        if(s->restart_count == 0 && s->avctx->codec_id == AV_CODEC_ID_THP){
+            align_get_bits(&s->gb);
+            for (i = 0; i < nb_components; i++) /* reset dc */
+                s->last_dc[i] = 1024;
+        }
+
+        i = 8 + ((-get_bits_count(&s->gb)) & 7);
+        /* skip RSTn */
+        if (s->restart_count == 0 && show_bits(&s->gb, i) == (1 << i) - 1) {
+            int pos = get_bits_count(&s->gb);
+            align_get_bits(&s->gb);
+            while (get_bits_left(&s->gb) >= 8 && show_bits(&s->gb, 8) == 0xFF)
+                skip_bits(&s->gb, 8);
+            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;
+            } else
+                skip_bits_long(&s->gb, pos - get_bits_count(&s->gb));
+        }
+    }
+}
+
 static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int nb_components, int predictor, int point_transform)
 {
     int i, mb_x, mb_y;
@@ -805,18 +848,17 @@
     return 0;
 }
 
-static int ljpeg_decode_yuv_scan(MJpegDecodeContext *s, int predictor,
+static int ljpeg_decode_yuv_scan(MJpegDecodeContext *s, int nb_components, int predictor,
                                  int point_transform)
 {
     int i, mb_x, mb_y;
-    const int nb_components=s->nb_components;
     int bits= (s->bits+7)&~7;
     int resync_mb_y = 0;
     int resync_mb_x = 0;
 
     point_transform += bits - s->bits;
 
-    av_assert0(nb_components==1 || nb_components==3);
+    av_assert0(nb_components>=1 && nb_components<=3);
 
     for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
         for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
@@ -949,11 +991,12 @@
     return 0;
 }
 
-static av_always_inline void mjpeg_copy_block(uint8_t *dst, const uint8_t *src,
+static av_always_inline void mjpeg_copy_block(MJpegDecodeContext *s,
+                                              uint8_t *dst, const uint8_t *src,
                                               int linesize, int lowres)
 {
     switch (lowres) {
-    case 0: copy_block8(dst, src, linesize, linesize, 8);
+    case 0: s->dsp.put_pixels_tab[1][0](dst, src, linesize, 8);
         break;
     case 1: copy_block4(dst, src, linesize, linesize, 4);
         break;
@@ -1029,8 +1072,9 @@
                     ptr = data[c] + block_offset;
                     if (!s->progressive) {
                         if (copy_mb)
-                            mjpeg_copy_block(ptr, reference_data[c] + block_offset,
+                            mjpeg_copy_block(s, ptr, reference_data[c] + block_offset,
                                              linesize[c], s->avctx->lowres);
+
                         else {
                             s->dsp.clear_block(s->block);
                             if (decode_block(s, s->block, i,
@@ -1045,7 +1089,7 @@
                     } else {
                         int block_idx  = s->block_stride[c] * (v * mb_y + y) +
                                          (h * mb_x + x);
-                        DCTELEM *block = s->blocks[c][block_idx];
+                        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;
@@ -1068,28 +1112,7 @@
                 }
             }
 
-            if (s->restart_interval) {
-                s->restart_count--;
-                if(s->restart_count == 0 && s->avctx->codec_id == AV_CODEC_ID_THP){
-                    align_get_bits(&s->gb);
-                    for (i = 0; i < nb_components; i++) /* reset dc */
-                        s->last_dc[i] = 1024;
-                }
-
-                i = 8 + ((-get_bits_count(&s->gb)) & 7);
-                /* skip RSTn */
-                if (show_bits(&s->gb, i) == (1 << i) - 1) {
-                    int pos = get_bits_count(&s->gb);
-                    align_get_bits(&s->gb);
-                    while (get_bits_left(&s->gb) >= 8 && show_bits(&s->gb, 8) == 0xFF)
-                        skip_bits(&s->gb, 8);
-                    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;
-                    } else
-                        skip_bits_long(&s->gb, pos - get_bits_count(&s->gb));
-                }
-            }
+            handle_rstn(s, nb_components);
         }
     }
     return 0;
@@ -1119,13 +1142,18 @@
     if (s->interlaced && s->bottom_field)
         data += linesize >> 1;
 
+    s->restart_count = 0;
+
     for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
         uint8_t *ptr     = data + (mb_y * linesize * 8 >> s->avctx->lowres);
         int block_idx    = mb_y * s->block_stride[c];
-        DCTELEM (*block)[64] = &s->blocks[c][block_idx];
+        int16_t (*block)[64] = &s->blocks[c][block_idx];
         uint8_t *last_nnz    = &s->last_nnz[c][block_idx];
         for (mb_x = 0; mb_x < s->mb_width; mb_x++, block++, last_nnz++) {
                 int ret;
+                if (s->restart_interval && !s->restart_count)
+                    s->restart_count = s->restart_interval;
+
                 if (Ah)
                     ret = decode_block_refinement(s, *block, last_nnz, s->ac_index[0],
                                                   quant_matrix, ss, se, Al, &EOBRUN);
@@ -1142,6 +1170,7 @@
                     s->dsp.idct_put(ptr, linesize, *block);
                     ptr += 8 >> s->avctx->lowres;
             }
+            handle_rstn(s, 0);
         }
     }
     return 0;
@@ -1263,7 +1292,7 @@
                 if ((ret = ljpeg_decode_rgb_scan(s, nb_components, predictor, point_transform)) < 0)
                     return ret;
             } else {
-                if ((ret = ljpeg_decode_yuv_scan(s, predictor, point_transform)) < 0)
+                if ((ret = ljpeg_decode_yuv_scan(s, nb_components, predictor, point_transform)) < 0)
                     return ret;
             }
         }
@@ -1402,9 +1431,9 @@
             av_log(s->avctx, AV_LOG_INFO,
                    "Pegasus lossless jpeg header found\n");
         skip_bits(&s->gb, 16); /* version ? */
-        skip_bits(&s->gb, 16); /* unknwon always 0? */
-        skip_bits(&s->gb, 16); /* unknwon always 0? */
-        skip_bits(&s->gb, 16); /* unknwon always 0? */
+        skip_bits(&s->gb, 16); /* unknown always 0? */
+        skip_bits(&s->gb, 16); /* unknown always 0? */
+        skip_bits(&s->gb, 16); /* unknown always 0? */
         switch (get_bits(&s->gb, 8)) {
         case 1:
             s->rgb         = 1;
@@ -1548,6 +1577,8 @@
         }
         *unescaped_buf_ptr  = s->buffer;
         *unescaped_buf_size = dst - s->buffer;
+        memset(s->buffer + *unescaped_buf_size, 0,
+               FF_INPUT_BUFFER_PADDING_SIZE);
 
         av_log(s->avctx, AV_LOG_DEBUG, "escaping removed %td bytes\n",
                (buf_end - *buf_ptr) - (dst - s->buffer));
@@ -1567,7 +1598,7 @@
                 while ((src + t < buf_end) && x == 0xff)
                     x = src[t++];
                 if (x & 0x80) {
-                    t -= 2;
+                    t -= FFMIN(2, t);
                     break;
                 }
             }
@@ -1589,6 +1620,8 @@
 
         *unescaped_buf_ptr  = dst;
         *unescaped_buf_size = (bit_count + 7) >> 3;
+        memset(s->buffer + *unescaped_buf_size, 0,
+               FF_INPUT_BUFFER_PADDING_SIZE);
     } else {
         *unescaped_buf_ptr  = *buf_ptr;
         *unescaped_buf_size = buf_end - *buf_ptr;
@@ -1597,7 +1630,7 @@
     return start_code;
 }
 
-int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                           AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
@@ -1710,23 +1743,23 @@
                     if (s->bottom_field == !s->interlace_polarity)
                         break;
                 }
-                    *picture   = *s->picture_ptr;
-                    *data_size = sizeof(AVFrame);
-                    s->got_picture = 0;
+                *picture   = *s->picture_ptr;
+                *got_frame = 1;
+                s->got_picture = 0;
 
-                    if (!s->lossless) {
-                        picture->quality      = FFMAX3(s->qscale[0],
-                                                       s->qscale[1],
-                                                       s->qscale[2]);
-                        picture->qstride      = 0;
-                        picture->qscale_table = s->qscale_table;
-                        memset(picture->qscale_table, picture->quality,
-                               (s->width + 15) / 16);
-                        if (avctx->debug & FF_DEBUG_QP)
-                            av_log(avctx, AV_LOG_DEBUG,
-                                   "QP: %d\n", picture->quality);
-                        picture->quality *= FF_QP2LAMBDA;
-                    }
+                if (!s->lossless) {
+                    picture->quality      = FFMAX3(s->qscale[0],
+                                                   s->qscale[1],
+                                                   s->qscale[2]);
+                    picture->qstride      = 0;
+                    picture->qscale_table = s->qscale_table;
+                    memset(picture->qscale_table, picture->quality,
+                           (s->width + 15) / 16);
+                    if (avctx->debug & FF_DEBUG_QP)
+                        av_log(avctx, AV_LOG_DEBUG,
+                               "QP: %d\n", picture->quality);
+                    picture->quality *= FF_QP2LAMBDA;
+                }
 
                 goto the_end;
             case SOS:
diff --git a/libavcodec/mjpegdec.h b/libavcodec/mjpegdec.h
index f35f20a..01f4323 100644
--- a/libavcodec/mjpegdec.h
+++ b/libavcodec/mjpegdec.h
@@ -91,8 +91,8 @@
     int got_picture;                                ///< we found a SOF and picture is valid, too.
     int linesize[MAX_COMPONENTS];                   ///< linesize << interlaced
     int8_t *qscale_table;
-    DECLARE_ALIGNED(16, DCTELEM, block)[64];
-    DCTELEM (*blocks[MAX_COMPONENTS])[64]; ///< intermediate sums (progressive mode)
+    DECLARE_ALIGNED(16, int16_t, block)[64];
+    int16_t (*blocks[MAX_COMPONENTS])[64]; ///< intermediate sums (progressive mode)
     uint8_t *last_nnz[MAX_COMPONENTS];
     uint64_t coefs_finished[MAX_COMPONENTS]; ///< bitmask of which coefs have been completely decoded (progressive mode)
     ScanTable scantable;
@@ -119,7 +119,7 @@
 int ff_mjpeg_decode_init(AVCodecContext *avctx);
 int ff_mjpeg_decode_end(AVCodecContext *avctx);
 int ff_mjpeg_decode_frame(AVCodecContext *avctx,
-                          void *data, int *data_size,
+                          void *data, int *got_frame,
                           AVPacket *avpkt);
 int ff_mjpeg_decode_dqt(MJpegDecodeContext *s);
 int ff_mjpeg_decode_dht(MJpegDecodeContext *s);
diff --git a/libavcodec/mjpegenc.c b/libavcodec/mjpegenc.c
index 381f0fb..80a4022 100644
--- a/libavcodec/mjpegenc.c
+++ b/libavcodec/mjpegenc.c
@@ -31,7 +31,6 @@
  */
 
 #include "avcodec.h"
-#include "dsputil.h"
 #include "mpegvideo.h"
 #include "mjpeg.h"
 #include "mjpegenc.h"
@@ -137,7 +136,7 @@
     if(s->avctx->active_thread_type & FF_THREAD_SLICE){
         put_marker(p, DRI);
         put_bits(p, 16, 4);
-        put_bits(p, 16, s->mb_width);
+        put_bits(p, 16, (s->width-1)/(8*s->mjpeg_hsample[0]) + 1);
     }
 
     /* huffman table */
@@ -397,7 +396,7 @@
     }
 }
 
-static void encode_block(MpegEncContext *s, DCTELEM *block, int n)
+static void encode_block(MpegEncContext *s, int16_t *block, int n)
 {
     int mant, nbits, code, i, j;
     int component, dc, run, last_index, val;
@@ -455,26 +454,36 @@
         put_bits(&s->pb, huff_size_ac[0], huff_code_ac[0]);
 }
 
-void ff_mjpeg_encode_mb(MpegEncContext *s, DCTELEM block[6][64])
+void ff_mjpeg_encode_mb(MpegEncContext *s, int16_t block[6][64])
 {
     int i;
-    for(i=0;i<5;i++) {
-        encode_block(s, block[i], i);
-    }
-    if (s->chroma_format == CHROMA_420) {
-        encode_block(s, block[5], 5);
-    } else if (s->chroma_format == CHROMA_422) {
-        encode_block(s, block[6], 6);
-        encode_block(s, block[5], 5);
-        encode_block(s, block[7], 7);
-    } else {
-        encode_block(s, block[6], 6);
+    if (s->chroma_format == CHROMA_444) {
+        encode_block(s, block[0], 0);
+        encode_block(s, block[2], 2);
+        encode_block(s, block[4], 4);
         encode_block(s, block[8], 8);
-        encode_block(s, block[10], 10);
         encode_block(s, block[5], 5);
-        encode_block(s, block[7], 7);
         encode_block(s, block[9], 9);
-        encode_block(s, block[11], 11);
+
+        if (16*s->mb_x+8 < s->width) {
+            encode_block(s, block[1], 1);
+            encode_block(s, block[3], 3);
+            encode_block(s, block[6], 6);
+            encode_block(s, block[10], 10);
+            encode_block(s, block[7], 7);
+            encode_block(s, block[11], 11);
+        }
+    } else {
+        for(i=0;i<5;i++) {
+            encode_block(s, block[i], i);
+        }
+        if (s->chroma_format == CHROMA_420) {
+            encode_block(s, block[5], 5);
+        } else {
+            encode_block(s, block[6], 6);
+            encode_block(s, block[5], 5);
+            encode_block(s, block[7], 7);
+        }
     }
 
     s->i_tex_bits += get_bits_diff(s);
diff --git a/libavcodec/mjpegenc.h b/libavcodec/mjpegenc.h
index 06f77c6..ce0c1cc 100644
--- a/libavcodec/mjpegenc.h
+++ b/libavcodec/mjpegenc.h
@@ -33,7 +33,8 @@
 #ifndef AVCODEC_MJPEGENC_H
 #define AVCODEC_MJPEGENC_H
 
-#include "dsputil.h"
+#include <stdint.h>
+
 #include "mpegvideo.h"
 
 typedef struct MJpegContext {
@@ -55,6 +56,6 @@
 void ff_mjpeg_encode_stuffing(MpegEncContext *s);
 void ff_mjpeg_encode_dc(MpegEncContext *s, int val,
                         uint8_t *huff_size, uint16_t *huff_code);
-void ff_mjpeg_encode_mb(MpegEncContext *s, DCTELEM block[6][64]);
+void ff_mjpeg_encode_mb(MpegEncContext *s, int16_t block[6][64]);
 
 #endif /* AVCODEC_MJPEGENC_H */
diff --git a/libavcodec/mlp_parser.c b/libavcodec/mlp_parser.c
index f1c0a0d..2cc4b91 100644
--- a/libavcodec/mlp_parser.c
+++ b/libavcodec/mlp_parser.c
@@ -126,7 +126,7 @@
 
 int ff_mlp_read_major_sync(void *log, MLPHeaderInfo *mh, GetBitContext *gb)
 {
-    int ratebits;
+    int ratebits, channel_arrangement;
     uint16_t checksum;
 
     av_assert1(get_bits_count(gb) == 0);
@@ -157,7 +157,10 @@
 
         skip_bits(gb, 11);
 
-        mh->channels_mlp = get_bits(gb, 5);
+        mh->channel_arrangement=
+        channel_arrangement    = get_bits(gb, 5);
+        mh->channels_mlp       = mlp_channels[channel_arrangement];
+        mh->channel_layout_mlp = ff_mlp_layout[channel_arrangement];
     } else if (mh->stream_type == 0xba) {
         mh->group1_bits = 24; // TODO: Is this information actually conveyed anywhere?
         mh->group2_bits = 0;
@@ -168,11 +171,16 @@
 
         skip_bits(gb, 8);
 
-        mh->channels_thd_stream1 = get_bits(gb, 5);
+        mh->channel_arrangement=
+        channel_arrangement            = get_bits(gb, 5);
+        mh->channels_thd_stream1       = truehd_channels(channel_arrangement);
+        mh->channel_layout_thd_stream1 = ff_truehd_layout(channel_arrangement);
 
         skip_bits(gb, 2);
 
-        mh->channels_thd_stream2 = get_bits(gb, 13);
+        channel_arrangement            = get_bits(gb, 13);
+        mh->channels_thd_stream2       = truehd_channels(channel_arrangement);
+        mh->channel_layout_thd_stream2 = ff_truehd_layout(channel_arrangement);
     } else
         return AVERROR_INVALIDDATA;
 
@@ -322,16 +330,45 @@
         if(!avctx->channels || !avctx->channel_layout) {
         if (mh.stream_type == 0xbb) {
             /* MLP stream */
-            avctx->channels = mlp_channels[mh.channels_mlp];
-            avctx->channel_layout = ff_mlp_layout[mh.channels_mlp];
+#if FF_API_REQUEST_CHANNELS
+            if (avctx->request_channels > 0 && avctx->request_channels <= 2 &&
+                mh.num_substreams > 1) {
+                avctx->channels       = 2;
+                avctx->channel_layout = AV_CH_LAYOUT_STEREO;
+            } else
+#endif
+            if (avctx->request_channel_layout == AV_CH_LAYOUT_STEREO &&
+                mh.num_substreams > 1) {
+                avctx->channels       = 2;
+                avctx->channel_layout = AV_CH_LAYOUT_STEREO;
+            } else {
+                avctx->channels       = mh.channels_mlp;
+                avctx->channel_layout = mh.channel_layout_mlp;
+            }
         } else { /* mh.stream_type == 0xba */
             /* TrueHD stream */
-            if (mh.channels_thd_stream2) {
-                avctx->channels = truehd_channels(mh.channels_thd_stream2);
-                avctx->channel_layout = ff_truehd_layout(mh.channels_thd_stream2);
+#if FF_API_REQUEST_CHANNELS
+            if (avctx->request_channels > 0 && avctx->request_channels <= 2 &&
+                mh.num_substreams > 1) {
+                avctx->channels       = 2;
+                avctx->channel_layout = AV_CH_LAYOUT_STEREO;
+            } else if (avctx->request_channels > 0 &&
+                       avctx->request_channels <= mh.channels_thd_stream1) {
+                avctx->channels       = mh.channels_thd_stream1;
+                avctx->channel_layout = mh.channel_layout_thd_stream1;
+            } else
+#endif
+            if (avctx->request_channel_layout == AV_CH_LAYOUT_STEREO &&
+                mh.num_substreams > 1) {
+                avctx->channels       = 2;
+                avctx->channel_layout = AV_CH_LAYOUT_STEREO;
+            } else if (avctx->request_channel_layout == mh.channel_layout_thd_stream1 ||
+                       !mh.channels_thd_stream2) {
+                avctx->channels       = mh.channels_thd_stream1;
+                avctx->channel_layout = mh.channel_layout_thd_stream1;
             } else {
-                avctx->channels = truehd_channels(mh.channels_thd_stream1);
-                avctx->channel_layout = ff_truehd_layout(mh.channels_thd_stream1);
+                avctx->channels       = mh.channels_thd_stream2;
+                avctx->channel_layout = mh.channel_layout_thd_stream2;
             }
         }
         }
diff --git a/libavcodec/mlp_parser.h b/libavcodec/mlp_parser.h
index 6aafed5..9967abb 100644
--- a/libavcodec/mlp_parser.h
+++ b/libavcodec/mlp_parser.h
@@ -31,25 +31,29 @@
 
 typedef struct MLPHeaderInfo
 {
-    int stream_type;            ///< 0xBB for MLP, 0xBA for TrueHD
+    int stream_type;                        ///< 0xBB for MLP, 0xBA for TrueHD
 
-    int group1_bits;            ///< The bit depth of the first substream
-    int group2_bits;            ///< Bit depth of the second substream (MLP only)
+    int group1_bits;                        ///< The bit depth of the first substream
+    int group2_bits;                        ///< Bit depth of the second substream (MLP only)
 
-    int group1_samplerate;      ///< Sample rate of first substream
-    int group2_samplerate;      ///< Sample rate of second substream (MLP only)
+    int group1_samplerate;                  ///< Sample rate of first substream
+    int group2_samplerate;                  ///< Sample rate of second substream (MLP only)
 
-    int channels_mlp;           ///< Channel arrangement for MLP streams
-    int channels_thd_stream1;   ///< Channel arrangement for substream 1 of TrueHD streams (5.1)
-    int channels_thd_stream2;   ///< Channel arrangement for substream 2 of TrueHD streams (7.1)
+    int channel_arrangement;
+    int channels_mlp;                       ///< Channel count for MLP streams
+    int channels_thd_stream1;               ///< Channel count for substream 1 of TrueHD streams ("6-channel presentation")
+    int channels_thd_stream2;               ///< Channel count for substream 2 of TrueHD streams ("8-channel presentation")
+    uint64_t channel_layout_mlp;            ///< Channel layout for MLP streams
+    uint64_t channel_layout_thd_stream1;    ///< Channel layout for substream 1 of TrueHD streams ("6-channel presentation")
+    uint64_t channel_layout_thd_stream2;    ///< Channel layout for substream 2 of TrueHD streams ("8-channel presentation")
 
-    int access_unit_size;       ///< Number of samples per coded frame
-    int access_unit_size_pow2;  ///< Next power of two above number of samples per frame
+    int access_unit_size;                   ///< Number of samples per coded frame
+    int access_unit_size_pow2;              ///< Next power of two above number of samples per frame
 
-    int is_vbr;                 ///< Stream is VBR instead of CBR
-    int peak_bitrate;           ///< Peak bitrate for VBR, actual bitrate (==peak) for CBR
+    int is_vbr;                             ///< Stream is VBR instead of CBR
+    int peak_bitrate;                       ///< Peak bitrate for VBR, actual bitrate (==peak) for CBR
 
-    int num_substreams;         ///< Number of substreams within stream
+    int num_substreams;                     ///< Number of substreams within stream
 } MLPHeaderInfo;
 
 
diff --git a/libavcodec/mlpdec.c b/libavcodec/mlpdec.c
index d587982..c763624 100644
--- a/libavcodec/mlpdec.c
+++ b/libavcodec/mlpdec.c
@@ -28,7 +28,9 @@
 
 #include "avcodec.h"
 #include "libavutil/intreadwrite.h"
+#include "libavutil/channel_layout.h"
 #include "get_bits.h"
+#include "internal.h"
 #include "libavutil/crc.h"
 #include "parser.h"
 #include "mlp_parser.h"
@@ -55,6 +57,8 @@
     uint8_t     max_matrix_channel;
     /// For each channel output by the matrix, the output channel to map it to
     uint8_t     ch_assign[MAX_CHANNELS];
+    /// The channel layout for this substream
+    uint64_t    ch_layout;
 
     /// Channel coding parameters for channels in the substream
     ChannelParams channel_params[MAX_CHANNELS];
@@ -114,7 +118,6 @@
 
 typedef struct MLPDecodeContext {
     AVCodecContext *avctx;
-    AVFrame     frame;
 
     /// Current access unit being read has a major sync.
     int         is_major_sync_unit;
@@ -148,6 +151,36 @@
     MLPDSPContext dsp;
 } MLPDecodeContext;
 
+static const uint64_t thd_channel_order[] = {
+    AV_CH_FRONT_LEFT, AV_CH_FRONT_RIGHT,                     // LR
+    AV_CH_FRONT_CENTER,                                      // C
+    AV_CH_LOW_FREQUENCY,                                     // LFE
+    AV_CH_SIDE_LEFT, AV_CH_SIDE_RIGHT,                       // LRs
+    AV_CH_TOP_FRONT_LEFT, AV_CH_TOP_FRONT_RIGHT,             // LRvh
+    AV_CH_FRONT_LEFT_OF_CENTER, AV_CH_FRONT_RIGHT_OF_CENTER, // LRc
+    AV_CH_BACK_LEFT, AV_CH_BACK_RIGHT,                       // LRrs
+    AV_CH_BACK_CENTER,                                       // Cs
+    AV_CH_TOP_CENTER,                                        // Ts
+    AV_CH_SURROUND_DIRECT_LEFT, AV_CH_SURROUND_DIRECT_RIGHT, // LRsd
+    AV_CH_WIDE_LEFT, AV_CH_WIDE_RIGHT,                       // LRw
+    AV_CH_TOP_FRONT_CENTER,                                  // Cvh
+    AV_CH_LOW_FREQUENCY_2,                                   // LFE2
+};
+
+static uint64_t thd_channel_layout_extract_channel(uint64_t channel_layout,
+                                                   int index)
+{
+    int i;
+
+    if (av_get_channel_layout_nb_channels(channel_layout) <= index)
+        return 0;
+
+    for (i = 0; i < FF_ARRAY_ELEMS(thd_channel_order); i++)
+        if (channel_layout & thd_channel_order[i] && !index--)
+            return thd_channel_order[i];
+    return 0;
+}
+
 static VLC huff_vlc[3];
 
 /** Initialize static data, constant between all invocations of the codec. */
@@ -237,9 +270,6 @@
         m->substream[substr].lossless_check_data = 0xffffffff;
     ff_mlpdsp_init(&m->dsp);
 
-    avcodec_get_frame_defaults(&m->frame);
-    avctx->coded_frame = &m->frame;
-
     return 0;
 }
 
@@ -327,31 +357,32 @@
     for (substr = 0; substr < MAX_SUBSTREAMS; substr++)
         m->substream[substr].restart_seen = 0;
 
-    if (mh.stream_type == 0xbb) {
-        /* MLP stream */
-        m->avctx->channel_layout = ff_mlp_layout[mh.channels_mlp];
-    } else { /* mh.stream_type == 0xba */
-        /* TrueHD stream */
-        if (mh.channels_thd_stream2) {
-            m->avctx->channel_layout = ff_truehd_layout(mh.channels_thd_stream2);
-        } else {
-            m->avctx->channel_layout = ff_truehd_layout(mh.channels_thd_stream1);
-        }
-        if (m->avctx->channels<=2 && m->avctx->channel_layout == AV_CH_LAYOUT_MONO && m->max_decoded_substream == 1) {
+    /* Set the layout for each substream. When there's more than one, the first
+     * substream is Stereo. Subsequent substreams' layouts are indicated in the
+     * major sync. */
+    if (m->avctx->codec_id == AV_CODEC_ID_MLP) {
+        if ((substr = (mh.num_substreams > 1)))
+            m->substream[0].ch_layout = AV_CH_LAYOUT_STEREO;
+        m->substream[substr].ch_layout = mh.channel_layout_mlp;
+    } else {
+        if ((substr = (mh.num_substreams > 1)))
+            m->substream[0].ch_layout = AV_CH_LAYOUT_STEREO;
+        if (mh.num_substreams > 2)
+            if (mh.channel_layout_thd_stream2)
+                m->substream[2].ch_layout = mh.channel_layout_thd_stream2;
+            else
+                m->substream[2].ch_layout = mh.channel_layout_thd_stream1;
+        m->substream[substr].ch_layout = mh.channel_layout_thd_stream1;
+
+        if (m->avctx->channels<=2 && m->substream[substr].ch_layout == AV_CH_LAYOUT_MONO && m->max_decoded_substream == 1) {
             av_log(m->avctx, AV_LOG_DEBUG, "Mono stream with 2 substreams, ignoring 2nd\n");
             m->max_decoded_substream = 0;
             if (m->avctx->channels==2)
                 m->avctx->channel_layout = AV_CH_LAYOUT_STEREO;
         }
-        if (m->avctx->channels &&
-            !m->avctx->request_channels && !m->avctx->request_channel_layout &&
-            av_get_channel_layout_nb_channels(m->avctx->channel_layout) != m->avctx->channels) {
-            m->avctx->channel_layout = 0;
-            av_log_ask_for_sample(m->avctx, "Unknown channel layout.");
-        }
     }
 
-    m->needs_reordering = mh.channels_mlp >= 18 && mh.channels_mlp <= 20;
+    m->needs_reordering = mh.channel_arrangement >= 18 && mh.channel_arrangement <= 20;
 
     return 0;
 }
@@ -427,14 +458,24 @@
     s->max_channel = max_channel;
     s->max_matrix_channel = matrix_channel;
 
-    if (m->avctx->request_channels > 0
-        && s->max_channel + 1 >= m->avctx->request_channels
-        && substr < m->max_decoded_substream) {
+#if FF_API_REQUEST_CHANNELS
+    if (m->avctx->request_channels > 0 &&
+        m->avctx->request_channels <= s->max_channel + 1 &&
+        m->max_decoded_substream > substr) {
         av_log(m->avctx, AV_LOG_DEBUG,
-               "Extracting %d channel downmix from substream %d. "
+               "Extracting %d-channel downmix from substream %d. "
                "Further substreams will be skipped.\n",
                s->max_channel + 1, substr);
         m->max_decoded_substream = substr;
+    } else
+#endif
+    if (m->avctx->request_channel_layout == s->ch_layout &&
+        m->max_decoded_substream > substr) {
+        av_log(m->avctx, AV_LOG_DEBUG,
+               "Extracting %d-channel downmix (0x%"PRIx64") from substream %d. "
+               "Further substreams will be skipped.\n",
+               s->max_channel + 1, s->ch_layout, substr);
+        m->max_decoded_substream = substr;
     }
 
     s->noise_shift   = get_bits(gbp,  4);
@@ -459,7 +500,13 @@
 
     for (ch = 0; ch <= s->max_matrix_channel; ch++) {
         int ch_assign = get_bits(gbp, 6);
-        if (ch_assign > s->max_matrix_channel) {
+        if (m->avctx->codec_id == AV_CODEC_ID_TRUEHD) {
+            uint64_t channel = thd_channel_layout_extract_channel(s->ch_layout,
+                                                                  ch_assign);
+            ch_assign = av_get_channel_layout_channel_index(s->ch_layout,
+                                                            channel);
+        }
+        if ((unsigned)ch_assign > s->max_matrix_channel) {
             av_log_ask_for_sample(m->avctx,
                    "Assignment of matrix channel %d to invalid output channel %d.\n",
                    ch, ch_assign);
@@ -468,33 +515,6 @@
         s->ch_assign[ch_assign] = ch;
     }
 
-    if (m->avctx->codec_id == AV_CODEC_ID_MLP && m->needs_reordering) {
-        if (m->avctx->channel_layout == (AV_CH_LAYOUT_QUAD|AV_CH_LOW_FREQUENCY) ||
-            m->avctx->channel_layout == AV_CH_LAYOUT_5POINT0_BACK) {
-            int i = s->ch_assign[4];
-            s->ch_assign[4] = s->ch_assign[3];
-            s->ch_assign[3] = s->ch_assign[2];
-            s->ch_assign[2] = i;
-        } else if (m->avctx->channel_layout == AV_CH_LAYOUT_5POINT1_BACK) {
-            FFSWAP(int, s->ch_assign[2], s->ch_assign[4]);
-            FFSWAP(int, s->ch_assign[3], s->ch_assign[5]);
-        }
-    }
-    if (m->avctx->codec_id == AV_CODEC_ID_TRUEHD &&
-        (m->avctx->channel_layout == AV_CH_LAYOUT_7POINT1 ||
-        m->avctx->channel_layout == AV_CH_LAYOUT_7POINT1_WIDE)) {
-        FFSWAP(int, s->ch_assign[4], s->ch_assign[6]);
-        FFSWAP(int, s->ch_assign[5], s->ch_assign[7]);
-    } else if (m->avctx->codec_id == AV_CODEC_ID_TRUEHD &&
-        (m->avctx->channel_layout == AV_CH_LAYOUT_6POINT1 ||
-        m->avctx->channel_layout == (AV_CH_LAYOUT_6POINT1 | AV_CH_TOP_CENTER) ||
-        m->avctx->channel_layout == (AV_CH_LAYOUT_6POINT1 | AV_CH_TOP_FRONT_CENTER))) {
-        int i = s->ch_assign[6];
-        s->ch_assign[6] = s->ch_assign[5];
-        s->ch_assign[5] = s->ch_assign[4];
-        s->ch_assign[4] = i;
-    }
-
     checksum = ff_mlp_restart_checksum(buf, get_bits_count(gbp) - start_count);
 
     if (checksum != get_bits(gbp, 8))
@@ -523,8 +543,24 @@
         cp->huff_lsbs        = 24;
     }
 
-    if (substr == m->max_decoded_substream)
-        m->avctx->channels = s->max_matrix_channel + 1;
+    if (substr == m->max_decoded_substream) {
+        m->avctx->channels       = s->max_matrix_channel + 1;
+        m->avctx->channel_layout = s->ch_layout;
+
+        if (m->avctx->codec_id == AV_CODEC_ID_MLP && m->needs_reordering) {
+            if (m->avctx->channel_layout == (AV_CH_LAYOUT_QUAD|AV_CH_LOW_FREQUENCY) ||
+                m->avctx->channel_layout == AV_CH_LAYOUT_5POINT0_BACK) {
+                int i = s->ch_assign[4];
+                s->ch_assign[4] = s->ch_assign[3];
+                s->ch_assign[3] = s->ch_assign[2];
+                s->ch_assign[2] = i;
+            } else if (m->avctx->channel_layout == AV_CH_LAYOUT_5POINT1_BACK) {
+                FFSWAP(int, s->ch_assign[2], s->ch_assign[4]);
+                FFSWAP(int, s->ch_assign[3], s->ch_assign[5]);
+            }
+        }
+
+    }
 
     return 0;
 }
@@ -716,6 +752,7 @@
 
     if (cp->huff_lsbs > 24) {
         av_log(m->avctx, AV_LOG_ERROR, "Invalid huff_lsbs.\n");
+        cp->huff_lsbs = 0;
         return AVERROR_INVALIDDATA;
     }
 
@@ -964,7 +1001,7 @@
 /** Write the audio data into the output buffer. */
 
 static int output_data(MLPDecodeContext *m, unsigned int substr,
-                       void *data, int *got_frame_ptr)
+                       AVFrame *frame, int *got_frame_ptr)
 {
     AVCodecContext *avctx = m->avctx;
     SubStream *s = &m->substream[substr];
@@ -979,14 +1016,19 @@
         return AVERROR_INVALIDDATA;
     }
 
+    if (!s->blockpos) {
+        av_log(avctx, AV_LOG_ERROR, "No samples to output.\n");
+        return AVERROR_INVALIDDATA;
+    }
+
     /* get output buffer */
-    m->frame.nb_samples = s->blockpos;
-    if ((ret = avctx->get_buffer(avctx, &m->frame)) < 0) {
+    frame->nb_samples = s->blockpos;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    data_32 = (int32_t *)m->frame.data[0];
-    data_16 = (int16_t *)m->frame.data[0];
+    data_32 = (int32_t *)frame->data[0];
+    data_16 = (int16_t *)frame->data[0];
 
     for (i = 0; i < s->blockpos; i++) {
         for (out_ch = 0; out_ch <= s->max_matrix_channel; out_ch++) {
@@ -999,8 +1041,7 @@
         }
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = m->frame;
+    *got_frame_ptr = 1;
 
     return 0;
 }
diff --git a/libavcodec/mmvideo.c b/libavcodec/mmvideo.c
index 0120e9f..c61cd57 100644
--- a/libavcodec/mmvideo.c
+++ b/libavcodec/mmvideo.c
@@ -173,7 +173,7 @@
 }
 
 static int mm_decode_frame(AVCodecContext *avctx,
-                            void *data, int *data_size,
+                            void *data, int *got_frame,
                             AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
@@ -210,7 +210,7 @@
 
     memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE);
 
-    *data_size = sizeof(AVFrame);
+    *got_frame      = 1;
     *(AVFrame*)data = s->frame;
 
     return avpkt->size;
diff --git a/libavcodec/motion-test.c b/libavcodec/motion-test.c
index 2cdb1c0..53cfedb 100644
--- a/libavcodec/motion-test.c
+++ b/libavcodec/motion-test.c
@@ -127,12 +127,12 @@
     printf("ffmpeg motion test\n");
 
     ctx = avcodec_alloc_context3(NULL);
-    ctx->dsp_mask = AV_CPU_FLAG_FORCE;
+    ctx->flags |= CODEC_FLAG_BITEXACT;
     memset(&cctx, 0, sizeof(cctx));
     ff_dsputil_init(&cctx, ctx);
     for (c = 0; c < flags_size; c++) {
         int x;
-        ctx->dsp_mask = AV_CPU_FLAG_FORCE | flags[c];
+        av_force_cpu_flags(flags[c]);
         memset(&mmxctx, 0, sizeof(mmxctx));
         ff_dsputil_init(&mmxctx, ctx);
 
diff --git a/libavcodec/motion_est.c b/libavcodec/motion_est.c
index a303d37..d9d6a1f 100644
--- a/libavcodec/motion_est.c
+++ b/libavcodec/motion_est.c
@@ -32,7 +32,6 @@
 #include <limits.h>
 
 #include "avcodec.h"
-#include "dsputil.h"
 #include "mathops.h"
 #include "mpegvideo.h"
 
@@ -290,7 +289,7 @@
     return 0;
 }
 
-static void zero_hpel(uint8_t *a, const uint8_t *b, int stride, int h){
+static void zero_hpel(uint8_t *a, const uint8_t *b, ptrdiff_t stride, int h){
 }
 
 int ff_init_me(MpegEncContext *s){
@@ -516,6 +515,7 @@
 {
     MotionEstContext * const c= &s->me;
     int range= c->avctx->me_range >> (1 + !!(c->flags&FLAG_QPEL));
+    int max_range = MAX_MV >> (1 + !!(c->flags&FLAG_QPEL));
 /*
     if(c->avctx->me_range) c->range= c->avctx->me_range >> 1;
     else                   c->range= 16;
@@ -537,6 +537,8 @@
         c->xmax = - x + s->mb_width *16 - 16;
         c->ymax = - y + s->mb_height*16 - 16;
     }
+    if(!range || range > max_range)
+        range = max_range;
     if(range){
         c->xmin = FFMAX(c->xmin,-range);
         c->xmax = FFMIN(c->xmax, range);
@@ -984,6 +986,30 @@
     return d;
 }
 
+static inline int get_penalty_factor(int lambda, int lambda2, int type){
+    switch(type&0xFF){
+    default:
+    case FF_CMP_SAD:
+        return lambda>>FF_LAMBDA_SHIFT;
+    case FF_CMP_DCT:
+        return (3*lambda)>>(FF_LAMBDA_SHIFT+1);
+    case FF_CMP_W53:
+        return (4*lambda)>>(FF_LAMBDA_SHIFT);
+    case FF_CMP_W97:
+        return (2*lambda)>>(FF_LAMBDA_SHIFT);
+    case FF_CMP_SATD:
+    case FF_CMP_DCT264:
+        return (2*lambda)>>FF_LAMBDA_SHIFT;
+    case FF_CMP_RD:
+    case FF_CMP_PSNR:
+    case FF_CMP_SSE:
+    case FF_CMP_NSSE:
+        return lambda2>>FF_LAMBDA_SHIFT;
+    case FF_CMP_BIT:
+        return 1;
+    }
+}
+
 void ff_estimate_p_frame_motion(MpegEncContext * s,
                                 int mb_x, int mb_y)
 {
@@ -1089,7 +1115,6 @@
     vard = s->dsp.sse[0](NULL, pix, ppix, s->linesize, 16);
 
     pic->mc_mb_var[s->mb_stride * mb_y + mb_x] = (vard+128)>>8;
-//    pic->mb_cmp_score[s->mb_stride * mb_y + mb_x] = dmin;
     c->mc_mb_var_sum_temp += (vard+128)>>8;
 
     if(mb_type){
@@ -1168,7 +1193,6 @@
             }
         }
 
-//        pic->mb_cmp_score[s->mb_stride * mb_y + mb_x] = dmin;
         set_p_mv_tables(s, mx, my, mb_type!=CANDIDATE_MB_TYPE_INTER4V);
 
         /* get intra luma score */
diff --git a/libavcodec/motion_est_template.c b/libavcodec/motion_est_template.c
index 2b1c6e1..3123edc 100644
--- a/libavcodec/motion_est_template.c
+++ b/libavcodec/motion_est_template.c
@@ -89,7 +89,7 @@
         const int b= score_map[(index+(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)]
                      + (mv_penalty[bx   - pred_x] + mv_penalty[by+2 - pred_y])*c->penalty_factor;
 
-#if 1
+#if defined(ASSERT_LEVEL) && ASSERT_LEVEL > 1
         unsigned key;
         unsigned map_generation= c->map_generation;
         key= ((my-1)<<ME_MAP_MV_BITS) + (mx) + map_generation;
@@ -400,10 +400,10 @@
 }
 
 #define check(x,y,S,v)\
-if( (x)<(xmin<<(S)) ) printf("%d %d %d %d %d xmin" #v, xmin, (x), (y), s->mb_x, s->mb_y);\
-if( (x)>(xmax<<(S)) ) printf("%d %d %d %d %d xmax" #v, xmax, (x), (y), s->mb_x, s->mb_y);\
-if( (y)<(ymin<<(S)) ) printf("%d %d %d %d %d ymin" #v, ymin, (x), (y), s->mb_x, s->mb_y);\
-if( (y)>(ymax<<(S)) ) printf("%d %d %d %d %d ymax" #v, ymax, (x), (y), s->mb_x, s->mb_y);\
+if( (x)<(xmin<<(S)) ) av_log(NULL, AV_LOG_ERROR, "%d %d %d %d %d xmin" #v, xmin, (x), (y), s->mb_x, s->mb_y);\
+if( (x)>(xmax<<(S)) ) av_log(NULL, AV_LOG_ERROR, "%d %d %d %d %d xmax" #v, xmax, (x), (y), s->mb_x, s->mb_y);\
+if( (y)<(ymin<<(S)) ) av_log(NULL, AV_LOG_ERROR, "%d %d %d %d %d ymin" #v, ymin, (x), (y), s->mb_x, s->mb_y);\
+if( (y)>(ymax<<(S)) ) av_log(NULL, AV_LOG_ERROR, "%d %d %d %d %d ymax" #v, ymax, (x), (y), s->mb_x, s->mb_y);\
 
 #define LOAD_COMMON2\
     uint32_t *map= c->map;\
diff --git a/libavcodec/motionpixels.c b/libavcodec/motionpixels.c
index 8d457e0..4fa45e9 100644
--- a/libavcodec/motionpixels.c
+++ b/libavcodec/motionpixels.c
@@ -101,38 +101,48 @@
     }
 }
 
-static void mp_get_code(MotionPixelsContext *mp, GetBitContext *gb, int size, int code)
+static int mp_get_code(MotionPixelsContext *mp, GetBitContext *gb, int size, int code)
 {
     while (get_bits1(gb)) {
         ++size;
         if (size > mp->max_codes_bits) {
             av_log(mp->avctx, AV_LOG_ERROR, "invalid code size %d/%d\n", size, mp->max_codes_bits);
-            return;
+            return AVERROR_INVALIDDATA;
         }
         code <<= 1;
-        mp_get_code(mp, gb, size, code + 1);
+        if (mp_get_code(mp, gb, size, code + 1) < 0)
+            return AVERROR_INVALIDDATA;
     }
     if (mp->current_codes_count >= MAX_HUFF_CODES) {
         av_log(mp->avctx, AV_LOG_ERROR, "too many codes\n");
-        return;
+        return AVERROR_INVALIDDATA;
     }
+
     mp->codes[mp->current_codes_count  ].code = code;
     mp->codes[mp->current_codes_count++].size = size;
+    return 0;
 }
 
-static void mp_read_codes_table(MotionPixelsContext *mp, GetBitContext *gb)
+static int mp_read_codes_table(MotionPixelsContext *mp, GetBitContext *gb)
 {
     if (mp->codes_count == 1) {
         mp->codes[0].delta = get_bits(gb, 4);
     } else {
         int i;
+        int ret;
 
         mp->max_codes_bits = get_bits(gb, 4);
         for (i = 0; i < mp->codes_count; ++i)
             mp->codes[i].delta = get_bits(gb, 4);
         mp->current_codes_count = 0;
-        mp_get_code(mp, gb, 0, 0);
+        if ((ret = mp_get_code(mp, gb, 0, 0)) < 0)
+            return ret;
+        if (mp->current_codes_count < mp->codes_count) {
+            av_log(mp->avctx, AV_LOG_ERROR, "too few codes\n");
+            return AVERROR_INVALIDDATA;
+        }
    }
+   return 0;
 }
 
 static int mp_gradient(MotionPixelsContext *mp, int component, int v)
@@ -245,7 +255,7 @@
 }
 
 static int mp_decode_frame(AVCodecContext *avctx,
-                                 void *data, int *data_size,
+                                 void *data, int *got_frame,
                                  AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
@@ -287,7 +297,8 @@
         *(uint16_t *)mp->frame.data[0] = get_bits(&gb, 15);
         mp->changes_map[0] = 1;
     }
-    mp_read_codes_table(mp, &gb);
+    if (mp_read_codes_table(mp, &gb) < 0)
+        goto end;
 
     sz = get_bits(&gb, 18);
     if (avctx->extradata[0] != 5)
@@ -303,7 +314,7 @@
     ff_free_vlc(&mp->vlc);
 
 end:
-    *data_size = sizeof(AVFrame);
+    *got_frame       = 1;
     *(AVFrame *)data = mp->frame;
     return buf_size;
 }
diff --git a/libavcodec/movtextdec.c b/libavcodec/movtextdec.c
index a65bbb8..05ff53a 100644
--- a/libavcodec/movtextdec.c
+++ b/libavcodec/movtextdec.c
@@ -83,7 +83,7 @@
      * In complex cases, there are style descriptors appended to the string
      * so we can't just assume the packet size is the string size.
      */
-    end = ptr + FFMAX(2 + AV_RB16(ptr), avpkt->size);
+    end = ptr + FFMIN(2 + AV_RB16(ptr), avpkt->size);
     ptr += 2;
 
     ts_start = av_rescale_q(avpkt->pts,
diff --git a/libavcodec/movtextenc.c b/libavcodec/movtextenc.c
index 7f1b5b8..9b0a6c5 100644
--- a/libavcodec/movtextenc.c
+++ b/libavcodec/movtextenc.c
@@ -21,6 +21,7 @@
 
 #include <stdarg.h>
 #include "avcodec.h"
+#include "libavutil/avassert.h"
 #include "libavutil/avstring.h"
 #include "libavutil/intreadwrite.h"
 #include "ass_split.h"
@@ -87,15 +88,18 @@
 static void mov_text_text_cb(void *priv, const char *text, int len)
 {
     MovTextContext *s = priv;
+    av_assert0(s->end >= s->ptr);
     av_strlcpy(s->ptr, text, FFMIN(s->end - s->ptr, len + 1));
-    s->ptr += len;
+    s->ptr += FFMIN(s->end - s->ptr, len);
 }
 
 static void mov_text_new_line_cb(void *priv, int forced)
 {
     MovTextContext *s = priv;
+    av_assert0(s->end >= s->ptr);
     av_strlcpy(s->ptr, "\n", FFMIN(s->end - s->ptr, 2));
-    s->ptr++;
+    if (s->end > s->ptr)
+        s->ptr++;
 }
 
 static const ASSCodesCallbacks mov_text_callbacks = {
diff --git a/libavcodec/mpc.c b/libavcodec/mpc.c
index d064924..3bd2d35 100644
--- a/libavcodec/mpc.c
+++ b/libavcodec/mpc.c
@@ -28,7 +28,6 @@
 
 #include "avcodec.h"
 #include "get_bits.h"
-#include "dsputil.h"
 #include "mpegaudiodsp.h"
 #include "mpegaudio.h"
 
diff --git a/libavcodec/mpc.h b/libavcodec/mpc.h
index 7ee402b..295b4c7 100644
--- a/libavcodec/mpc.h
+++ b/libavcodec/mpc.h
@@ -50,7 +50,6 @@
 }Band;
 
 typedef struct MPCContext {
-    AVFrame frame;
     DSPContext dsp;
     MPADSPContext mpadsp;
     GetBitContext gb;
diff --git a/libavcodec/mpc7.c b/libavcodec/mpc7.c
index bacb78e..d4f5e2d 100644
--- a/libavcodec/mpc7.c
+++ b/libavcodec/mpc7.c
@@ -26,10 +26,12 @@
  */
 
 #include "libavutil/channel_layout.h"
+#include "libavutil/internal.h"
 #include "libavutil/lfg.h"
 #include "avcodec.h"
 #include "get_bits.h"
 #include "dsputil.h"
+#include "internal.h"
 #include "mpegaudiodsp.h"
 
 #include "mpc.h"
@@ -93,9 +95,6 @@
     avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
     avctx->channel_layout = AV_CH_LAYOUT_STEREO;
 
-    avcodec_get_frame_defaults(&c->frame);
-    avctx->coded_frame = &c->frame;
-
     if(vlc_initialized) return 0;
     av_log(avctx, AV_LOG_DEBUG, "Initing VLC\n");
     scfi_vlc.table = scfi_table;
@@ -195,6 +194,7 @@
 static int mpc7_decode_frame(AVCodecContext * avctx, void *data,
                              int *got_frame_ptr, AVPacket *avpkt)
 {
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     int buf_size;
     MPCContext *c = avctx->priv_data;
@@ -224,8 +224,8 @@
     buf_size  -= 4;
 
     /* get output buffer */
-    c->frame.nb_samples = MPC_FRAME_SIZE;
-    if ((ret = avctx->get_buffer(avctx, &c->frame)) < 0) {
+    frame->nb_samples = MPC_FRAME_SIZE;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -293,9 +293,9 @@
         for(ch = 0; ch < 2; ch++)
             idx_to_quant(c, &gb, bands[i].res[ch], c->Q[ch] + off);
 
-    ff_mpc_dequantize_and_synth(c, mb, (int16_t **)c->frame.extended_data, 2);
+    ff_mpc_dequantize_and_synth(c, mb, (int16_t **)frame->extended_data, 2);
     if(last_frame)
-        c->frame.nb_samples = c->lastframelen;
+        frame->nb_samples = c->lastframelen;
 
     bits_used = get_bits_count(&gb);
     bits_avail = buf_size * 8;
@@ -309,8 +309,7 @@
         return avpkt->size;
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = c->frame;
+    *got_frame_ptr = 1;
 
     return avpkt->size;
 }
diff --git a/libavcodec/mpc8.c b/libavcodec/mpc8.c
index 1af417a..489737a 100644
--- a/libavcodec/mpc8.c
+++ b/libavcodec/mpc8.c
@@ -30,6 +30,7 @@
 #include "avcodec.h"
 #include "get_bits.h"
 #include "dsputil.h"
+#include "internal.h"
 #include "mpegaudiodsp.h"
 
 #include "mpc.h"
@@ -143,9 +144,6 @@
     avctx->channel_layout = (channels==2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO;
     avctx->channels = channels;
 
-    avcodec_get_frame_defaults(&c->frame);
-    avctx->coded_frame = &c->frame;
-
     if(vlc_initialized) return 0;
     av_log(avctx, AV_LOG_DEBUG, "Initing VLC\n");
 
@@ -243,6 +241,7 @@
 static int mpc8_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;
     MPCContext *c = avctx->priv_data;
@@ -254,8 +253,8 @@
     int last[2];
 
     /* get output buffer */
-    c->frame.nb_samples = MPC_FRAME_SIZE;
-    if ((res = avctx->get_buffer(avctx, &c->frame)) < 0) {
+    frame->nb_samples = MPC_FRAME_SIZE;
+    if ((res = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return res;
     }
@@ -414,7 +413,7 @@
     }
 
     ff_mpc_dequantize_and_synth(c, maxband - 1,
-                                (int16_t **)c->frame.extended_data,
+                                (int16_t **)frame->extended_data,
                                 avctx->channels);
 
     c->cur_frame++;
@@ -425,8 +424,7 @@
     if(c->cur_frame >= c->frames)
         c->cur_frame = 0;
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = c->frame;
+    *got_frame_ptr = 1;
 
     return c->cur_frame ? c->last_bits_used >> 3 : buf_size;
 }
diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c
index 7115a99..0b09cbe 100644
--- a/libavcodec/mpeg12.c
+++ b/libavcodec/mpeg12.c
@@ -79,7 +79,7 @@
     return sign_extend(val, 5 + shift);
 }
 
-static inline int mpeg1_decode_block_intra(MpegEncContext *s, DCTELEM *block, int n)
+static inline int mpeg1_decode_block_intra(MpegEncContext *s, int16_t *block, int n)
 {
     int level, dc, diff, i, j, run;
     int component;
@@ -150,12 +150,12 @@
    return 0;
 }
 
-int ff_mpeg1_decode_block_intra(MpegEncContext *s, DCTELEM *block, int n)
+int ff_mpeg1_decode_block_intra(MpegEncContext *s, int16_t *block, int n)
 {
     return mpeg1_decode_block_intra(s, block, n);
 }
 
-static inline int mpeg1_decode_block_inter(MpegEncContext *s, DCTELEM *block, int n)
+static inline int mpeg1_decode_block_inter(MpegEncContext *s, int16_t *block, int n)
 {
     int level, i, j, run;
     RLTable *rl = &ff_rl_mpeg1;
@@ -235,7 +235,7 @@
  * Changing this would eat up any speed benefits it has.
  * Do not use "fast" flag if you need the code to be robust.
  */
-static inline int mpeg1_fast_decode_block_inter(MpegEncContext *s, DCTELEM *block, int n)
+static inline int mpeg1_fast_decode_block_inter(MpegEncContext *s, int16_t *block, int n)
 {
     int level, i, j, run;
     RLTable *rl = &ff_rl_mpeg1;
@@ -307,7 +307,7 @@
 }
 
 
-static inline int mpeg2_decode_block_non_intra(MpegEncContext *s, DCTELEM *block, int n)
+static inline int mpeg2_decode_block_non_intra(MpegEncContext *s, int16_t *block, int n)
 {
     int level, i, j, run;
     RLTable *rl = &ff_rl_mpeg1;
@@ -392,7 +392,7 @@
  * Do not use "fast" flag if you need the code to be robust.
  */
 static inline int mpeg2_fast_decode_block_non_intra(MpegEncContext *s,
-                                                    DCTELEM *block, int n)
+                                                    int16_t *block, int n)
 {
     int level, i, j, run;
     RLTable *rl = &ff_rl_mpeg1;
@@ -453,7 +453,7 @@
 }
 
 
-static inline int mpeg2_decode_block_intra(MpegEncContext *s, DCTELEM *block, int n)
+static inline int mpeg2_decode_block_intra(MpegEncContext *s, int16_t *block, int n)
 {
     int level, dc, diff, i, j, run;
     int component;
@@ -536,7 +536,7 @@
  * Changing this would eat up any speed benefits it has.
  * Do not use "fast" flag if you need the code to be robust.
  */
-static inline int mpeg2_fast_decode_block_intra(MpegEncContext *s, DCTELEM *block, int n)
+static inline int mpeg2_fast_decode_block_intra(MpegEncContext *s, int16_t *block, int n)
 {
     int level, dc, diff, j, run;
     int component;
@@ -735,7 +735,7 @@
 
 static void exchange_uv(MpegEncContext *s)
 {
-    DCTELEM (*tmp)[64];
+    int16_t (*tmp)[64];
 
     tmp           = s->pblocks[4];
     s->pblocks[4] = s->pblocks[5];
@@ -748,7 +748,7 @@
 #define MT_16X8  2
 #define MT_DMV   3
 
-static int mpeg_decode_mb(MpegEncContext *s, DCTELEM block[12][64])
+static int mpeg_decode_mb(MpegEncContext *s, int16_t block[12][64])
 {
     int i, j, k, cbp, val, mb_type, motion_type;
     const int mb_block_count = 4 + (1 << s->chroma_format);
@@ -768,8 +768,10 @@
                 mb_type = s->current_picture.f.mb_type[s->mb_x + s->mb_y * s->mb_stride - 1];
             else
                 mb_type = s->current_picture.f.mb_type[s->mb_width + (s->mb_y - 1) * s->mb_stride - 1]; // FIXME not sure if this is allowed in MPEG at all
-            if (IS_INTRA(mb_type))
+            if (IS_INTRA(mb_type)) {
+                av_log(s->avctx, AV_LOG_ERROR, "skip with previntra\n");
                 return -1;
+            }
             s->current_picture.f.mb_type[s->mb_x + s->mb_y*s->mb_stride] =
                 mb_type | MB_TYPE_SKIP;
 //            av_assert2(s->current_picture.f.mb_type[s->mb_x + s->mb_y * s->mb_stride - 1] & (MB_TYPE_16x16 | MB_TYPE_16x8));
@@ -874,7 +876,8 @@
 
             s->mv_dir = MV_DIR_FORWARD;
             if (s->picture_structure == PICT_FRAME) {
-                if (!s->frame_pred_frame_dct)
+                if (s->picture_structure == PICT_FRAME
+                    && !s->frame_pred_frame_dct)
                     s->interlaced_dct = get_bits1(&s->gb);
                 s->mv_type = MV_TYPE_16X16;
             } else {
@@ -896,7 +899,7 @@
             av_assert2(mb_type & MB_TYPE_L0L1);
             // FIXME decide if MBs in field pictures are MB_TYPE_INTERLACED
             /* get additional motion vector type */
-            if (s->frame_pred_frame_dct)
+            if (s->picture_structure == PICT_FRAME && s->frame_pred_frame_dct)
                 motion_type = MT_FRAME;
             else {
                 motion_type = get_bits(&s->gb, 2);
@@ -1057,7 +1060,7 @@
                  s->dsp.clear_blocks(s->block[6]);
             }
             if (cbp <= 0) {
-                av_log(s->avctx, AV_LOG_ERROR, "invalid cbp at %d %d\n", s->mb_x, s->mb_y);
+                av_log(s->avctx, AV_LOG_ERROR, "invalid cbp %d at %d %d\n", cbp, s->mb_x, s->mb_y);
                 return -1;
             }
 
@@ -1344,7 +1347,7 @@
         avctx->hwaccel = ff_find_hwaccel(avctx->codec->id, avctx->pix_fmt);
         // until then pix_fmt may be changed right after codec init
         if (avctx->pix_fmt == AV_PIX_FMT_XVMC_MPEG2_IDCT ||
-            avctx->hwaccel )
+            avctx->hwaccel || uses_vdpau(avctx))
             if (avctx->idct_algo == FF_IDCT_AUTO)
                 avctx->idct_algo = FF_IDCT_SIMPLE;
 
@@ -1604,7 +1607,7 @@
         if (ff_MPV_frame_start(s, avctx) < 0)
             return -1;
 
-        ff_er_frame_start(s);
+        ff_mpeg_er_frame_start(s);
 
         /* first check if we must repeat the frame */
         s->current_picture_ptr->f.repeat_pict = 0;
@@ -1804,7 +1807,7 @@
         if (++s->mb_x >= s->mb_width) {
             const int mb_size = 16 >> s->avctx->lowres;
 
-            ff_draw_horiz_band(s, mb_size*(s->mb_y >> field_pic), mb_size);
+            ff_mpeg_draw_horiz_band(s, mb_size*(s->mb_y >> field_pic), mb_size);
             ff_MPV_report_decode_progress(s);
 
             s->mb_x = 0;
@@ -1816,6 +1819,15 @@
                              && s->intra_dc_precision == 2 && s->q_scale_type == 1 && s->alternate_scan == 0
                              && s->progressive_frame == 0 /* vbv_delay == 0xBBB || 0xE10*/;
 
+                if (left >= 32 && !is_d10) {
+                    GetBitContext gb = s->gb;
+                    align_get_bits(&gb);
+                    if (show_bits(&gb, 24) == 0x060E2B) {
+                        av_log(avctx, AV_LOG_DEBUG, "Invalid MXF data found in video stream\n");
+                        is_d10 = 1;
+                    }
+                }
+
                 if (left < 0 || (left && show_bits(&s->gb, FFMIN(left, 23)) && !is_d10)
                     || ((avctx->err_recognition & (AV_EF_BITSTREAM | AV_EF_AGGRESSIVE)) && left > 8)) {
                     av_log(avctx, AV_LOG_ERROR, "end mismatch left=%d %0X\n", left, show_bits(&s->gb, FFMIN(left, 23)));
@@ -1898,7 +1910,7 @@
     int mb_y            = s->start_mb_y;
     const int field_pic = s->picture_structure != PICT_FRAME;
 
-    s->error_count = (3 * (s->end_mb_y - s->start_mb_y) * s->mb_width) >> field_pic;
+    s->er.error_count = (3 * (s->end_mb_y - s->start_mb_y) * s->mb_width) >> field_pic;
 
     for (;;) {
         uint32_t start_code;
@@ -1908,14 +1920,14 @@
         emms_c();
         av_dlog(c, "ret:%d resync:%d/%d mb:%d/%d ts:%d/%d ec:%d\n",
                 ret, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y,
-                s->start_mb_y, s->end_mb_y, s->error_count);
+                s->start_mb_y, s->end_mb_y, s->er.error_count);
         if (ret < 0) {
             if (c->err_recognition & AV_EF_EXPLODE)
                 return ret;
             if (s->resync_mb_x >= 0 && s->resync_mb_y >= 0)
-                ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_AC_ERROR | ER_DC_ERROR | ER_MV_ERROR);
+                ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_AC_ERROR | ER_DC_ERROR | ER_MV_ERROR);
         } else {
-            ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_AC_END | ER_DC_END | ER_MV_END);
+            ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_AC_END | ER_DC_END | ER_MV_END);
         }
 
         if (s->mb_y == s->end_mb_y)
@@ -1960,7 +1972,7 @@
 
         s->current_picture_ptr->f.qscale_type = FF_QSCALE_TYPE_MPEG2;
 
-        ff_er_frame_end(s);
+        ff_er_frame_end(&s->er);
 
         ff_MPV_frame_end(s);
 
@@ -1996,8 +2008,6 @@
 
     width  = get_bits(&s->gb, 12);
     height = get_bits(&s->gb, 12);
-    if (width <= 0 || height <= 0)
-        return -1;
     s->aspect_ratio_info = get_bits(&s->gb, 4);
     if (s->aspect_ratio_info == 0) {
         av_log(avctx, AV_LOG_ERROR, "aspect ratio has forbidden 0 value\n");
@@ -2082,7 +2092,7 @@
     avctx->pix_fmt = mpeg_get_pixelformat(avctx);
     avctx->hwaccel = ff_find_hwaccel(avctx->codec->id, avctx->pix_fmt);
 
-    if( avctx->pix_fmt == AV_PIX_FMT_XVMC_MPEG2_IDCT || avctx->hwaccel )
+    if (avctx->pix_fmt == AV_PIX_FMT_XVMC_MPEG2_IDCT || avctx->hwaccel || uses_vdpau(avctx))
         if (avctx->idct_algo == FF_IDCT_AUTO)
             avctx->idct_algo = FF_IDCT_SIMPLE;
 
@@ -2257,6 +2267,7 @@
     const uint8_t *buf_end = buf + buf_size;
     int ret, input_size;
     int last_code = 0;
+    int picture_start_code_seen = 0;
 
     for (;;) {
         /* find next start code */
@@ -2270,7 +2281,7 @@
 
                     avctx->execute(avctx, slice_decode_thread,  &s2->thread_context[0], NULL, s->slice_count, sizeof(void*));
                     for (i = 0; i < s->slice_count; i++)
-                        s2->error_count += s2->thread_context[i]->error_count;
+                        s2->er.error_count += s2->thread_context[i]->er.error_count;
                 }
 
                 if (CONFIG_VDPAU && uses_vdpau(avctx))
@@ -2307,6 +2318,19 @@
             break;
 
         case PICTURE_START_CODE:
+            if (picture_start_code_seen && s2->picture_structure == PICT_FRAME) {
+               /* If it's a frame picture, there can't be more than one picture header.
+                  Yet, it does happen and we need to handle it. */
+               av_log(avctx, AV_LOG_WARNING, "ignoring extra picture following a frame-picture\n");
+               break;
+            }
+            picture_start_code_seen = 1;
+
+            if (s2->width <= 0 || s2->height <= 0) {
+                av_log(avctx, AV_LOG_ERROR, "%dx%d is invalid\n", s2->width, s2->height);
+                return AVERROR_INVALIDDATA;
+            }
+
             if(s->tmpgexs){
                 s2->intra_dc_precision= 3;
                 s2->intra_matrix[0]= 1;
@@ -2318,7 +2342,7 @@
                                s2->thread_context, NULL,
                                s->slice_count, sizeof(void*));
                 for (i = 0; i < s->slice_count; i++)
-                    s2->error_count += s2->thread_context[i]->error_count;
+                    s2->er.error_count += s2->thread_context[i]->er.error_count;
                 s->slice_count = 0;
             }
             if (last_code == 0 || last_code == SLICE_MIN_START_CODE) {
@@ -2490,7 +2514,10 @@
                         thread_context->end_mb_y   = s2->mb_height;
                         if (s->slice_count) {
                             s2->thread_context[s->slice_count-1]->end_mb_y = mb_y;
-                            ff_update_duplicate_context(thread_context, s2);
+                            ret = ff_update_duplicate_context(thread_context,
+                                                              s2);
+                            if (ret < 0)
+                                return ret;
                         }
                         init_get_bits(&thread_context->gb, buf_ptr, input_size*8);
                         s->slice_count++;
@@ -2504,9 +2531,9 @@
                         if (avctx->err_recognition & AV_EF_EXPLODE)
                             return ret;
                         if (s2->resync_mb_x >= 0 && s2->resync_mb_y >= 0)
-                            ff_er_add_slice(s2, s2->resync_mb_x, s2->resync_mb_y, s2->mb_x, s2->mb_y, ER_AC_ERROR | ER_DC_ERROR | ER_MV_ERROR);
+                            ff_er_add_slice(&s2->er, s2->resync_mb_x, s2->resync_mb_y, s2->mb_x, s2->mb_y, ER_AC_ERROR | ER_DC_ERROR | ER_MV_ERROR);
                     } else {
-                        ff_er_add_slice(s2, s2->resync_mb_x, s2->resync_mb_y, s2->mb_x-1, s2->mb_y, ER_AC_END | ER_DC_END | ER_MV_END);
+                        ff_er_add_slice(&s2->er, s2->resync_mb_x, s2->resync_mb_y, s2->mb_x-1, s2->mb_y, ER_AC_END | ER_DC_END | ER_MV_END);
                     }
                 }
             }
@@ -2520,14 +2547,13 @@
                              AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
+    int ret;
     int buf_size = avpkt->size;
     Mpeg1Context *s = avctx->priv_data;
     AVFrame *picture = data;
     MpegEncContext *s2 = &s->mpeg_enc_ctx;
     av_dlog(avctx, "fill_buffer\n");
 
-    s2->current_picture_ptr = NULL;
-
     if (buf_size == 0 || (buf_size == 4 && AV_RB32(buf) == SEQ_END_CODE)) {
         /* special case for last picture */
         if (s2->low_delay == 0 && s2->next_picture_ptr) {
@@ -2554,18 +2580,24 @@
 
     s->slice_count = 0;
 
-    if (avctx->extradata && !s->parsed_extra) {
-        int ret = decode_chunks(avctx, picture, got_output, avctx->extradata, avctx->extradata_size);
+    if (avctx->extradata && !s->extradata_decoded) {
+        ret = decode_chunks(avctx, picture, got_output, avctx->extradata, avctx->extradata_size);
         if(*got_output) {
             av_log(avctx, AV_LOG_ERROR, "picture in extradata\n");
             *got_output = 0;
         }
-        s->parsed_extra = 1;
-        if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE))
+        s->extradata_decoded = 1;
+        if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE)) {
+            s2->current_picture_ptr = NULL;
             return ret;
+        }
     }
 
-    return decode_chunks(avctx, picture, got_output, buf, buf_size);
+    ret = decode_chunks(avctx, picture, got_output, buf, buf_size);
+    if (ret<0 || *got_output)
+        s2->current_picture_ptr = NULL;
+
+    return ret;
 }
 
 
diff --git a/libavcodec/mpeg12.h b/libavcodec/mpeg12.h
index c8cec48..1f36917 100644
--- a/libavcodec/mpeg12.h
+++ b/libavcodec/mpeg12.h
@@ -42,7 +42,7 @@
     AVRational frame_rate_ext;       ///< MPEG-2 specific framerate modificator
     int sync;                        ///< Did we reach a sync point like a GOP/SEQ/KEYFrame?
     int tmpgexs;
-    int parsed_extra;
+    int extradata_decoded;
 } Mpeg1Context;
 
 extern uint8_t ff_mpeg12_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3];
@@ -71,6 +71,6 @@
     return diff;
 }
 
-extern int ff_mpeg1_decode_block_intra(MpegEncContext *s, DCTELEM *block, int n);
+extern int ff_mpeg1_decode_block_intra(MpegEncContext *s, int16_t *block, int n);
 
 #endif /* AVCODEC_MPEG12_H */
diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c
index c615417..c8e7b45 100644
--- a/libavcodec/mpeg12enc.c
+++ b/libavcodec/mpeg12enc.c
@@ -26,7 +26,6 @@
  */
 
 #include "avcodec.h"
-#include "dsputil.h"
 #include "mathops.h"
 #include "mpegvideo.h"
 
@@ -52,7 +51,7 @@
 };
 
 static void mpeg1_encode_block(MpegEncContext *s,
-                         DCTELEM *block,
+                         int16_t *block,
                          int component);
 static void mpeg1_encode_motion(MpegEncContext *s, int val, int f_or_b_code);    // RAL: f_code parameter added
 
@@ -145,6 +144,9 @@
 {
     MpegEncContext *s = avctx->priv_data;
 
+    if (avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO && avctx->height > 2800)
+        avctx->thread_count = 1;
+
     if(ff_MPV_encode_init(avctx) < 0)
         return -1;
 
@@ -180,6 +182,19 @@
         }
     }
 
+    if ((avctx->width & 0xFFF) == 0 && (avctx->height & 0xFFF) == 1) {
+        av_log(avctx, AV_LOG_ERROR, "Width / Height is invalid for MPEG2\n");
+        return AVERROR(EINVAL);
+    }
+
+    if (s->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) {
+        if ((avctx->width & 0xFFF) == 0 || (avctx->height & 0xFFF) == 0) {
+            av_log(avctx, AV_LOG_ERROR, "Width or Height are not allowed to be multiplies of 4096\n"
+                                        "add '-strict %d' if you want to use them anyway.\n", FF_COMPLIANCE_UNOFFICIAL);
+            return AVERROR(EINVAL);
+        }
+    }
+
     s->drop_frame_timecode = s->drop_frame_timecode || !!(avctx->flags2 & CODEC_FLAG2_DROP_FRAME_TIMECODE);
     if (s->drop_frame_timecode)
         s->tc.flags |= AV_TIMECODE_FLAG_DROPFRAME;
@@ -227,8 +242,8 @@
             /* mpeg1 header repeated every gop */
             put_header(s, SEQ_START_CODE);
 
-            put_sbits(&s->pb, 12, s->width );
-            put_sbits(&s->pb, 12, s->height);
+            put_sbits(&s->pb, 12, s->width  & 0xFFF);
+            put_sbits(&s->pb, 12, s->height & 0xFFF);
 
             for(i=1; i<15; i++){
                 float error= aspect_ratio;
@@ -455,7 +470,7 @@
 }
 
 static av_always_inline void mpeg1_encode_mb_internal(MpegEncContext *s,
-                                                   DCTELEM block[6][64],
+                                                   int16_t block[6][64],
                                                    int motion_x, int motion_y,
                                                    int mb_block_count)
 {
@@ -472,7 +487,7 @@
     }
 
     if (cbp == 0 && !first_mb && s->mv_type == MV_TYPE_16X16 &&
-        (mb_x != s->mb_width - 1 || (mb_y != s->mb_height - 1 && s->codec_id == AV_CODEC_ID_MPEG1VIDEO)) &&
+        (mb_x != s->mb_width - 1 || (mb_y != s->end_mb_y - 1 && s->codec_id == AV_CODEC_ID_MPEG1VIDEO)) &&
         ((s->pict_type == AV_PICTURE_TYPE_P && (motion_x | motion_y) == 0) ||
         (s->pict_type == AV_PICTURE_TYPE_B && s->mv_dir == s->last_mv_dir && (((s->mv_dir & MV_DIR_FORWARD) ? ((s->mv[0][0][0] - s->last_mv[0][0][0])|(s->mv[0][0][1] - s->last_mv[0][0][1])) : 0) |
         ((s->mv_dir & MV_DIR_BACKWARD) ? ((s->mv[1][0][0] - s->last_mv[1][0][0])|(s->mv[1][0][1] - s->last_mv[1][0][1])) : 0)) == 0))) {
@@ -679,7 +694,7 @@
     }
 }
 
-void ff_mpeg1_encode_mb(MpegEncContext *s, DCTELEM block[6][64], int motion_x, int motion_y)
+void ff_mpeg1_encode_mb(MpegEncContext *s, int16_t block[6][64], int motion_x, int motion_y)
 {
     if (s->chroma_format == CHROMA_420) mpeg1_encode_mb_internal(s, block, motion_x, motion_y, 6);
     else                                mpeg1_encode_mb_internal(s, block, motion_x, motion_y, 8);
@@ -862,7 +877,7 @@
 }
 
 static void mpeg1_encode_block(MpegEncContext *s,
-                               DCTELEM *block,
+                               int16_t *block,
                                int n)
 {
     int alevel, level, last_non_zero, dc, diff, i, j, run, last_index, sign;
@@ -985,7 +1000,7 @@
     .supported_framerates = ff_mpeg12_frame_rate_tab + 1,
     .pix_fmts             = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P,
                                                         AV_PIX_FMT_NONE },
-    .capabilities         = CODEC_CAP_DELAY,
+    .capabilities         = CODEC_CAP_DELAY | CODEC_CAP_SLICE_THREADS,
     .long_name            = NULL_IF_CONFIG_SMALL("MPEG-1 video"),
     .priv_class           = &mpeg1_class,
 };
diff --git a/libavcodec/mpeg4audio.c b/libavcodec/mpeg4audio.c
index 8aa3219..68448e6 100644
--- a/libavcodec/mpeg4audio.c
+++ b/libavcodec/mpeg4audio.c
@@ -84,10 +84,8 @@
     GetBitContext gb;
     int specific_config_bitindex;
 
-    if(bit_size<=0)
+    if (bit_size <= 0 || init_get_bits(&gb, buf, bit_size) < 0)
         return AVERROR_INVALIDDATA;
-
-    init_get_bits(&gb, buf, bit_size);
     c->object_type = get_object_type(&gb);
     c->sample_rate = get_sample_rate(&gb, &c->sampling_index);
     c->chan_config = get_bits(&gb, 4);
diff --git a/libavcodec/mpeg4video.h b/libavcodec/mpeg4video.h
index 97c39b6..400ce4d 100644
--- a/libavcodec/mpeg4video.h
+++ b/libavcodec/mpeg4video.h
@@ -83,9 +83,9 @@
 extern const uint8_t ff_mpeg4_dc_threshold[8];
 
 void ff_mpeg4_encode_mb(MpegEncContext *s,
-                        DCTELEM block[6][64],
+                        int16_t block[6][64],
                         int motion_x, int motion_y);
-void ff_mpeg4_pred_ac(MpegEncContext * s, DCTELEM *block, int n,
+void ff_mpeg4_pred_ac(MpegEncContext * s, int16_t *block, int n,
                       int dir);
 void ff_set_mpeg4_time(MpegEncContext * s);
 void ff_mpeg4_encode_picture_header(MpegEncContext *s, int picture_number);
diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c
index 00de316..2551b51 100644
--- a/libavcodec/mpeg4videodec.c
+++ b/libavcodec/mpeg4videodec.c
@@ -51,7 +51,7 @@
  * @param n block index (0-3 are luma, 4-5 are chroma)
  * @param dir the ac prediction direction
  */
-void ff_mpeg4_pred_ac(MpegEncContext * s, DCTELEM *block, int n,
+void ff_mpeg4_pred_ac(MpegEncContext * s, int16_t *block, int n,
                       int dir)
 {
     int i;
@@ -796,13 +796,13 @@
 
     mb_num= mpeg4_decode_partition_a(s);
     if(mb_num<0){
-        ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, part_a_error);
+        ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, part_a_error);
         return -1;
     }
 
     if(s->resync_mb_x + s->resync_mb_y*s->mb_width + mb_num > s->mb_num){
         av_log(s->avctx, AV_LOG_ERROR, "slice below monitor ...\n");
-        ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, part_a_error);
+        ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, part_a_error);
         return -1;
     }
 
@@ -823,15 +823,15 @@
             return -1;
         }
     }
-    ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, part_a_end);
+    ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, part_a_end);
 
     if( mpeg4_decode_partition_b(s, mb_num) < 0){
         if(s->pict_type==AV_PICTURE_TYPE_P)
-            ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_DC_ERROR);
+            ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_DC_ERROR);
         return -1;
     }else{
         if(s->pict_type==AV_PICTURE_TYPE_P)
-            ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_DC_END);
+            ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_DC_END);
     }
 
     return 0;
@@ -841,7 +841,7 @@
  * Decode a block.
  * @return <0 if an error occurred
  */
-static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
+static inline int mpeg4_decode_block(MpegEncContext * s, int16_t * block,
                               int n, int coded, int intra, int rvlc)
 {
     int level, i, last, run;
@@ -1087,7 +1087,7 @@
  * decode partition C of one MB.
  * @return <0 if an error occurred
  */
-static int mpeg4_decode_partitioned_mb(MpegEncContext *s, DCTELEM block[6][64])
+static int mpeg4_decode_partitioned_mb(MpegEncContext *s, int16_t block[6][64])
 {
     int cbp, mb_type;
     const int xy= s->mb_x + s->mb_y*s->mb_stride;
@@ -1170,7 +1170,7 @@
 }
 
 static int mpeg4_decode_mb(MpegEncContext *s,
-                      DCTELEM block[6][64])
+                      int16_t block[6][64])
 {
     int cbpc, cbpy, i, cbp, pred_x, pred_y, mx, my, dquant;
     int16_t *mot_val;
@@ -2357,7 +2357,7 @@
     .flush                 = ff_mpeg_flush,
     .max_lowres            = 3,
     .long_name             = NULL_IF_CONFIG_SMALL("MPEG-4 part 2"),
-    .pix_fmts              = ff_hwaccel_pixfmt_list_420,
+    .pix_fmts              = ff_h263_hwaccel_pixfmt_list_420,
     .profiles              = NULL_IF_CONFIG_SMALL(mpeg4_video_profiles),
     .update_thread_context = ONLY_IF_THREADS_ENABLED(ff_mpeg_update_thread_context),
     .priv_class = &mpeg4_class,
diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c
index 3311506..a07f956 100644
--- a/libavcodec/mpeg4videoenc.c
+++ b/libavcodec/mpeg4videoenc.c
@@ -59,7 +59,7 @@
  * Return the number of bits that encoding the 8x8 block in block would need.
  * @param[in]  block_last_index last index in scantable order that refers to a non zero element in block.
  */
-static inline int get_block_rate(MpegEncContext * s, DCTELEM block[64], int block_last_index, uint8_t scantable[64]){
+static inline int get_block_rate(MpegEncContext * s, int16_t block[64], int block_last_index, uint8_t scantable[64]){
     int last=0;
     int j;
     int rate=0;
@@ -91,7 +91,7 @@
  * @param[out] st scantable for each 8x8 block
  * @param[in] zigzag_last_index index referring to the last non zero coefficient in zigzag order
  */
-static inline void restore_ac_coeffs(MpegEncContext * s, DCTELEM block[6][64], const int dir[6], uint8_t *st[6], const int zigzag_last_index[6])
+static inline void restore_ac_coeffs(MpegEncContext * s, int16_t block[6][64], const int dir[6], uint8_t *st[6], const int zigzag_last_index[6])
 {
     int i, n;
     memcpy(s->block_last_index, zigzag_last_index, sizeof(int)*6);
@@ -122,7 +122,7 @@
  * @param[out] st scantable for each 8x8 block
  * @param[out] zigzag_last_index index referring to the last non zero coefficient in zigzag order
  */
-static inline int decide_ac_pred(MpegEncContext * s, DCTELEM block[6][64], const int dir[6], uint8_t *st[6], int zigzag_last_index[6])
+static inline int decide_ac_pred(MpegEncContext * s, int16_t block[6][64], const int dir[6], uint8_t *st[6], int zigzag_last_index[6])
 {
     int score= 0;
     int i, n;
@@ -294,7 +294,7 @@
  * Encode an 8x8 block.
  * @param n block index (0-3 are luma, 4-5 are chroma)
  */
-static inline void mpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n, int intra_dc,
+static inline void mpeg4_encode_block(MpegEncContext * s, int16_t * block, int n, int intra_dc,
                                uint8_t *scan_table, PutBitContext *dc_pb, PutBitContext *ac_pb)
 {
     int i, last_non_zero;
@@ -345,7 +345,7 @@
     }
 }
 
-static int mpeg4_get_block_length(MpegEncContext * s, DCTELEM * block, int n, int intra_dc,
+static int mpeg4_get_block_length(MpegEncContext * s, int16_t * block, int n, int intra_dc,
                                uint8_t *scan_table)
 {
     int i, last_non_zero;
@@ -396,7 +396,7 @@
     return len;
 }
 
-static inline void mpeg4_encode_blocks(MpegEncContext * s, DCTELEM block[6][64], int intra_dc[6],
+static inline void mpeg4_encode_blocks(MpegEncContext * s, int16_t block[6][64], int intra_dc[6],
                                uint8_t **scan_table, PutBitContext *dc_pb, PutBitContext *ac_pb){
     int i;
 
@@ -425,7 +425,7 @@
     }
 }
 
-static inline int get_b_cbp(MpegEncContext * s, DCTELEM block[6][64],
+static inline int get_b_cbp(MpegEncContext * s, int16_t block[6][64],
                             int motion_x, int motion_y, int mb_type)
 {
     int cbp = 0, i;
@@ -469,7 +469,7 @@
 static const int dquant_code[5]= {1,0,9,2,3};
 
 void ff_mpeg4_encode_mb(MpegEncContext * s,
-                        DCTELEM block[6][64],
+                        int16_t block[6][64],
                         int motion_x, int motion_y)
 {
     int cbpc, cbpy, pred_x, pred_y;
@@ -1234,6 +1234,11 @@
     int ret;
     static int done = 0;
 
+    if (avctx->width >= (1<<13) || avctx->height >= (1<<13)) {
+        av_log(avctx, AV_LOG_ERROR, "dimensions too large for MPEG-4\n");
+        return AVERROR(EINVAL);
+    }
+
     if((ret=ff_MPV_encode_init(avctx)) < 0)
         return ret;
 
diff --git a/libavcodec/mpegaudiodec.c b/libavcodec/mpegaudiodec.c
index e33c643..0266afe 100644
--- a/libavcodec/mpegaudiodec.c
+++ b/libavcodec/mpegaudiodec.c
@@ -26,12 +26,13 @@
 
 #include "libavutil/avassert.h"
 #include "libavutil/channel_layout.h"
+#include "libavutil/float_dsp.h"
 #include "libavutil/libm.h"
 #include "avcodec.h"
 #include "get_bits.h"
+#include "internal.h"
 #include "mathops.h"
 #include "mpegaudiodsp.h"
-#include "dsputil.h"
 
 /*
  * TODO:
@@ -83,8 +84,8 @@
     int err_recognition;
     AVCodecContext* avctx;
     MPADSPContext mpadsp;
-    DSPContext dsp;
-    AVFrame frame;
+    AVFloatDSPContext fdsp;
+    AVFrame *frame;
 } MPADecodeContext;
 
 #if CONFIG_FLOAT
@@ -440,8 +441,8 @@
 
     s->avctx = avctx;
 
+    avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
     ff_mpadsp_init(&s->mpadsp);
-    ff_dsputil_init(&s->dsp, avctx);
 
     if (avctx->request_sample_fmt == OUT_FMT &&
         avctx->codec_id != AV_CODEC_ID_MP3ON4)
@@ -453,9 +454,6 @@
     if (avctx->codec_id == AV_CODEC_ID_MP3ADU)
         s->adu_mode = 1;
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     return 0;
 }
 
@@ -1163,7 +1161,7 @@
         /* NOTE: the 1/sqrt(2) normalization factor is included in the
            global gain */
 #if CONFIG_FLOAT
-       s-> dsp.butterflies_float(g0->sb_hybrid, g1->sb_hybrid, 576);
+       s->fdsp.butterflies_float(g0->sb_hybrid, g1->sb_hybrid, 576);
 #else
         tab0 = g0->sb_hybrid;
         tab1 = g1->sb_hybrid;
@@ -1628,12 +1626,13 @@
 
     /* get output buffer */
     if (!samples) {
-        s->frame.nb_samples = s->avctx->frame_size;
-        if ((ret = s->avctx->get_buffer(s->avctx, &s->frame)) < 0) {
+        av_assert0(s->frame != NULL);
+        s->frame->nb_samples = s->avctx->frame_size;
+        if ((ret = ff_get_buffer(s->avctx, s->frame)) < 0) {
             av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
             return ret;
         }
-        samples = (OUT_INT **)s->frame.extended_data;
+        samples = (OUT_INT **)s->frame->extended_data;
     }
 
     /* apply the synthesis filter */
@@ -1705,11 +1704,13 @@
         buf_size= s->frame_size;
     }
 
+    s->frame = data;
+
     ret = mp_decode_frame(s, NULL, buf, buf_size);
     if (ret >= 0) {
-        *got_frame_ptr   = 1;
-        *(AVFrame *)data = s->frame;
-        avctx->sample_rate = s->sample_rate;
+        s->frame->nb_samples = avctx->frame_size;
+        *got_frame_ptr       = 1;
+        avctx->sample_rate   = s->sample_rate;
         //FIXME maybe move the other codec info stuff from above here too
     } else {
         av_log(avctx, AV_LOG_ERROR, "Error while decoding MPEG audio frame.\n");
@@ -1777,14 +1778,15 @@
 
     s->frame_size = len;
 
+    s->frame = data;
+
     ret = mp_decode_frame(s, NULL, buf, buf_size);
     if (ret < 0) {
         av_log(avctx, AV_LOG_ERROR, "Error while decoding MPEG audio frame.\n");
         return ret;
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
+    *got_frame_ptr = 1;
 
     return buf_size;
 }
@@ -1796,7 +1798,6 @@
  * Context for MP3On4 decoder
  */
 typedef struct MP3On4DecodeContext {
-    AVFrame *frame;
     int frames;                     ///< number of mp3 frames per block (number of mp3 decoder instances)
     int syncword;                   ///< syncword patch
     const uint8_t *coff;            ///< channel offsets in output buffer
@@ -1885,7 +1886,6 @@
     // Put decoder context in place to make init_decode() happy
     avctx->priv_data = s->mp3decctx[0];
     decode_init(avctx);
-    s->frame = avctx->coded_frame;
     // Restore mp3on4 context pointer
     avctx->priv_data = s;
     s->mp3decctx[0]->adu_mode = 1; // Set adu mode
@@ -1922,6 +1922,7 @@
 static int decode_frame_mp3on4(AVCodecContext *avctx, void *data,
                                int *got_frame_ptr, AVPacket *avpkt)
 {
+    AVFrame *frame         = data;
     const uint8_t *buf     = avpkt->data;
     int buf_size           = avpkt->size;
     MP3On4DecodeContext *s = avctx->priv_data;
@@ -1933,12 +1934,12 @@
     int fr, ch, ret;
 
     /* get output buffer */
-    s->frame->nb_samples = s->frames * MPA_FRAME_SIZE;
-    if ((ret = avctx->get_buffer(avctx, s->frame)) < 0) {
+    frame->nb_samples = MPA_FRAME_SIZE;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    out_samples = (OUT_INT **)s->frame->extended_data;
+    out_samples = (OUT_INT **)frame->extended_data;
 
     // Discard too short frames
     if (buf_size < HEADER_SIZE)
@@ -1964,7 +1965,7 @@
 
         avpriv_mpegaudio_decode_header((MPADecodeHeader *)m, header);
 
-        if (ch + m->nb_channels > avctx->channels) {
+        if (ch + m->nb_channels > avctx->channels || s->coff[fr] + m->nb_channels > avctx->channels) {
             av_log(avctx, AV_LOG_ERROR, "frame channel count exceeds codec "
                                         "channel count\n");
             return AVERROR_INVALIDDATA;
@@ -1988,9 +1989,8 @@
     /* update codec info */
     avctx->sample_rate = s->mp3decctx[0]->sample_rate;
 
-    s->frame->nb_samples = out_size / (avctx->channels * sizeof(OUT_INT));
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = *s->frame;
+    frame->nb_samples = out_size / (avctx->channels * sizeof(OUT_INT));
+    *got_frame_ptr    = 1;
 
     return buf_size;
 }
diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index 8a308be..66a7ed5 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -30,6 +30,7 @@
 #include "libavutil/imgutils.h"
 #include "avcodec.h"
 #include "dsputil.h"
+#include "h264chroma.h"
 #include "internal.h"
 #include "mathops.h"
 #include "mpegvideo.h"
@@ -43,24 +44,21 @@
 //#include <assert.h>
 
 static void dct_unquantize_mpeg1_intra_c(MpegEncContext *s,
-                                   DCTELEM *block, int n, int qscale);
+                                   int16_t *block, int n, int qscale);
 static void dct_unquantize_mpeg1_inter_c(MpegEncContext *s,
-                                   DCTELEM *block, int n, int qscale);
+                                   int16_t *block, int n, int qscale);
 static void dct_unquantize_mpeg2_intra_c(MpegEncContext *s,
-                                   DCTELEM *block, int n, int qscale);
+                                   int16_t *block, int n, int qscale);
 static void dct_unquantize_mpeg2_intra_bitexact(MpegEncContext *s,
-                                   DCTELEM *block, int n, int qscale);
+                                   int16_t *block, int n, int qscale);
 static void dct_unquantize_mpeg2_inter_c(MpegEncContext *s,
-                                   DCTELEM *block, int n, int qscale);
+                                   int16_t *block, int n, int qscale);
 static void dct_unquantize_h263_intra_c(MpegEncContext *s,
-                                  DCTELEM *block, int n, int qscale);
+                                  int16_t *block, int n, int qscale);
 static void dct_unquantize_h263_inter_c(MpegEncContext *s,
-                                  DCTELEM *block, int n, int qscale);
+                                  int16_t *block, int n, int qscale);
 
 
-/* enable all paranoid tests for rounding, overflows, etc... */
-//#define PARANOID
-
 //#define DEBUG
 
 
@@ -130,13 +128,32 @@
     AV_PIX_FMT_NONE
 };
 
-const enum AVPixelFormat ff_hwaccel_pixfmt_list_420[] = {
-    AV_PIX_FMT_DXVA2_VLD,
-    AV_PIX_FMT_VAAPI_VLD,
-    AV_PIX_FMT_VDA_VLD,
-    AV_PIX_FMT_YUV420P,
-    AV_PIX_FMT_NONE
-};
+static void mpeg_er_decode_mb(void *opaque, int ref, int mv_dir, int mv_type,
+                              int (*mv)[2][4][2],
+                              int mb_x, int mb_y, int mb_intra, int mb_skipped)
+{
+    MpegEncContext *s = opaque;
+
+    s->mv_dir     = mv_dir;
+    s->mv_type    = mv_type;
+    s->mb_intra   = mb_intra;
+    s->mb_skipped = mb_skipped;
+    s->mb_x       = mb_x;
+    s->mb_y       = mb_y;
+    memcpy(s->mv, mv, sizeof(*mv));
+
+    ff_init_block_index(s);
+    ff_update_block_index(s);
+
+    s->dsp.clear_blocks(s->block[0]);
+
+    s->dest[0] = s->current_picture.f.data[0] + (s->mb_y *  16                       * s->linesize)   + s->mb_x *  16;
+    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);
+    ff_MPV_decode_mb(s, s->block);
+}
 
 const uint8_t *avpriv_mpv_find_start_code(const uint8_t *av_restrict p,
                                           const uint8_t *end,
@@ -175,6 +192,8 @@
 av_cold int ff_dct_common_init(MpegEncContext *s)
 {
     ff_dsputil_init(&s->dsp, s->avctx);
+    ff_h264chroma_init(&s->h264chroma, 8); //for lowres
+    ff_videodsp_init(&s->vdsp, s->avctx->bits_per_raw_sample);
 
     s->dct_unquantize_h263_intra = dct_unquantize_h263_intra_c;
     s->dct_unquantize_h263_inter = dct_unquantize_h263_inter_c;
@@ -224,6 +243,7 @@
  */
 static void free_frame_buffer(MpegEncContext *s, Picture *pic)
 {
+    pic->period_since_free = 0;
     /* WM Image / Screen codecs allocate internal buffers with different
      * dimensions / colorspaces; ignore user-defined callbacks for these. */
     if (s->codec_id != AV_CODEC_ID_WMV3IMAGE &&
@@ -235,12 +255,37 @@
     av_freep(&pic->f.hwaccel_picture_private);
 }
 
+int ff_mpv_frame_size_alloc(MpegEncContext *s, int linesize)
+{
+    int alloc_size = FFALIGN(FFABS(linesize) + 64, 32);
+
+    // edge emu needs blocksize + filter length - 1
+    // (= 17x17 for  halfpel / 21x21 for  h264)
+    // VC1 computes luma and chroma simultaneously and needs 19X19 + 9x9
+    // at uvlinesize. It supports only YUV420 so 24x24 is enough
+    // linesize * interlaced * MBsize
+    FF_ALLOCZ_OR_GOTO(s->avctx, s->edge_emu_buffer, alloc_size * 4 * 24,
+                      fail);
+
+    FF_ALLOCZ_OR_GOTO(s->avctx, s->me.scratchpad, alloc_size * 4 * 16 * 2,
+                      fail)
+    s->me.temp         = s->me.scratchpad;
+    s->rd_scratchpad   = s->me.scratchpad;
+    s->b_scratchpad    = s->me.scratchpad;
+    s->obmc_scratchpad = s->me.scratchpad + 16;
+
+    return 0;
+fail:
+    av_freep(&s->edge_emu_buffer);
+    return AVERROR(ENOMEM);
+}
+
 /**
  * Allocate a frame buffer
  */
 static int alloc_frame_buffer(MpegEncContext *s, Picture *pic)
 {
-    int r;
+    int r, ret;
 
     if (s->avctx->hwaccel) {
         assert(!pic->f.hwaccel_picture_private);
@@ -282,6 +327,14 @@
         return -1;
     }
 
+    if (!s->edge_emu_buffer &&
+        (ret = ff_mpv_frame_size_alloc(s, pic->f.linesize[0])) < 0) {
+        av_log(s->avctx, AV_LOG_ERROR,
+               "get_buffer() failed to allocate context scratch buffers.\n");
+        free_frame_buffer(s, pic);
+        return ret;
+    }
+
     return 0;
 }
 
@@ -359,7 +412,7 @@
         }
         if (s->avctx->debug&FF_DEBUG_DCT_COEFF) {
             FF_ALLOCZ_OR_GOTO(s->avctx, pic->f.dct_coeff,
-                              64 * mb_array_size * sizeof(DCTELEM) * 6, fail)
+                              64 * mb_array_size * sizeof(int16_t) * 6, fail)
         }
         pic->f.qstride = s->mb_stride;
         FF_ALLOCZ_OR_GOTO(s->avctx, pic->f.pan_scan,
@@ -412,26 +465,20 @@
     }
 }
 
-static int init_duplicate_context(MpegEncContext *s, MpegEncContext *base)
+static int init_duplicate_context(MpegEncContext *s)
 {
     int y_size = s->b8_stride * (2 * s->mb_height + 1);
     int c_size = s->mb_stride * (s->mb_height + 1);
     int yc_size = y_size + 2 * c_size;
     int i;
 
-    // edge emu needs blocksize + filter length - 1
-    // (= 17x17 for  halfpel / 21x21 for  h264)
-    FF_ALLOCZ_OR_GOTO(s->avctx, s->edge_emu_buffer,
-                      (s->width + 95) * 2 * 21 * 4, fail);    // (width + edge + align)*interlaced*MBsize*tolerance
+    s->edge_emu_buffer =
+    s->me.scratchpad   =
+    s->me.temp         =
+    s->rd_scratchpad   =
+    s->b_scratchpad    =
+    s->obmc_scratchpad = NULL;
 
-    // FIXME should be linesize instead of s->width * 2
-    // but that is not known before get_buffer()
-    FF_ALLOCZ_OR_GOTO(s->avctx, s->me.scratchpad,
-                      (s->width + 95) * 4 * 16 * 2 * sizeof(uint8_t), fail)
-    s->me.temp         = s->me.scratchpad;
-    s->rd_scratchpad   = s->me.scratchpad;
-    s->b_scratchpad    = s->me.scratchpad;
-    s->obmc_scratchpad = s->me.scratchpad + 16;
     if (s->encoding) {
         FF_ALLOCZ_OR_GOTO(s->avctx, s->me.map,
                           ME_MAP_SIZE * sizeof(uint32_t), fail)
@@ -442,7 +489,7 @@
                               2 * 64 * sizeof(int), fail)
         }
     }
-    FF_ALLOCZ_OR_GOTO(s->avctx, s->blocks, 64 * 12 * 2 * sizeof(DCTELEM), fail)
+    FF_ALLOCZ_OR_GOTO(s->avctx, s->blocks, 64 * 12 * 2 * sizeof(int16_t), fail)
     s->block = s->blocks[0];
 
     for (i = 0; i < 12; i++) {
@@ -510,10 +557,10 @@
 #undef COPY
 }
 
-void ff_update_duplicate_context(MpegEncContext *dst, MpegEncContext *src)
+int ff_update_duplicate_context(MpegEncContext *dst, MpegEncContext *src)
 {
     MpegEncContext bak;
-    int i;
+    int i, ret;
     // FIXME copy only needed parts
     // START_TIMER
     backup_duplicate_context(&bak, dst);
@@ -522,8 +569,15 @@
     for (i = 0; i < 12; i++) {
         dst->pblocks[i] = &dst->block[i];
     }
+    if (!dst->edge_emu_buffer &&
+        (ret = ff_mpv_frame_size_alloc(dst, dst->linesize)) < 0) {
+        av_log(dst->avctx, AV_LOG_ERROR, "failed to allocate context "
+               "scratch buffers.\n");
+        return ret;
+    }
     // STOP_TIMER("update_duplicate_context")
     // about 10k cycles / 0.01 sec for  1000frames on 1ghz with 2 threads
+    return 0;
 }
 
 int ff_mpeg_update_thread_context(AVCodecContext *dst,
@@ -550,8 +604,11 @@
         if (s1->context_initialized){
             s->picture_range_start  += MAX_PICTURE_COUNT;
             s->picture_range_end    += MAX_PICTURE_COUNT;
-            if((err = ff_MPV_common_init(s)) < 0)
+            if((err = ff_MPV_common_init(s)) < 0){
+                memset(s, 0, sizeof(MpegEncContext));
+                s->avctx = dst;
                 return err;
+            }
         }
     }
 
@@ -578,8 +635,10 @@
            (char *) &s1->last_picture_ptr - (char *) &s1->last_picture);
 
     // reset s->picture[].f.extended_data to s->picture[].f.data
-    for (i = 0; i < s->picture_count; i++)
+    for (i = 0; i < s->picture_count; i++) {
         s->picture[i].f.extended_data = s->picture[i].f.data;
+        s->picture[i].period_since_free ++;
+    }
 
     s->last_picture_ptr    = REBASE_PICTURE(s1->last_picture_ptr,    s, s1);
     s->current_picture_ptr = REBASE_PICTURE(s1->current_picture_ptr, s, s1);
@@ -597,7 +656,7 @@
     // B-frame info
     s->max_b_frames = s1->max_b_frames;
     s->low_delay    = s1->low_delay;
-    s->dropable     = s1->dropable;
+    s->droppable    = s1->droppable;
 
     // DivX handling (doesn't work)
     s->divx_packed  = s1->divx_packed;
@@ -615,6 +674,19 @@
                FF_INPUT_BUFFER_PADDING_SIZE);
     }
 
+    // linesize dependend scratch buffer allocation
+    if (!s->edge_emu_buffer)
+        if (s1->linesize) {
+            if (ff_mpv_frame_size_alloc(s, s1->linesize) < 0) {
+                av_log(s->avctx, AV_LOG_ERROR, "Failed to allocate context "
+                       "scratch buffers.\n");
+                return AVERROR(ENOMEM);
+            }
+        } else {
+            av_log(s->avctx, AV_LOG_ERROR, "Context scratch buffers could not "
+                   "be allocated due to unknown size.\n");
+        }
+
     // MPEG2/interlacing info
     memcpy(&s->progressive_sequence, &s1->progressive_sequence,
            (char *) &s1->rtp_mode - (char *) &s1->progressive_sequence);
@@ -672,6 +744,43 @@
     ff_MPV_common_defaults(s);
 }
 
+static int init_er(MpegEncContext *s)
+{
+    ERContext *er = &s->er;
+    int mb_array_size = s->mb_height * s->mb_stride;
+    int i;
+
+    er->avctx       = s->avctx;
+    er->dsp         = &s->dsp;
+
+    er->mb_index2xy = s->mb_index2xy;
+    er->mb_num      = s->mb_num;
+    er->mb_width    = s->mb_width;
+    er->mb_height   = s->mb_height;
+    er->mb_stride   = s->mb_stride;
+    er->b8_stride   = s->b8_stride;
+
+    er->er_temp_buffer     = av_malloc(s->mb_height * s->mb_stride);
+    er->error_status_table = av_mallocz(mb_array_size);
+    if (!er->er_temp_buffer || !er->error_status_table)
+        goto fail;
+
+    er->mbskip_table  = s->mbskip_table;
+    er->mbintra_table = s->mbintra_table;
+
+    for (i = 0; i < FF_ARRAY_ELEMS(s->dc_val); i++)
+        er->dc_val[i] = s->dc_val[i];
+
+    er->decode_mb = mpeg_er_decode_mb;
+    er->opaque    = s;
+
+    return 0;
+fail:
+    av_freep(&er->er_temp_buffer);
+    av_freep(&er->error_status_table);
+    return AVERROR(ENOMEM);
+}
+
 /**
  * Initialize and allocates MpegEncContext fields dependent on the resolution.
  */
@@ -738,12 +847,8 @@
 
     }
 
-    FF_ALLOC_OR_GOTO(s->avctx, s->er_temp_buffer,
-                     mb_array_size * sizeof(uint8_t), fail);
-    FF_ALLOCZ_OR_GOTO(s->avctx, s->error_status_table,
-                      mb_array_size * sizeof(uint8_t), fail);
-
-    if (s->codec_id == AV_CODEC_ID_MPEG4 || (s->flags & CODEC_FLAG_INTERLACED_ME)) {
+    if (s->codec_id == AV_CODEC_ID_MPEG4 ||
+        (s->flags & CODEC_FLAG_INTERLACED_ME)) {
         /* interlaced direct mode decoding tables */
         for (i = 0; i < 2; i++) {
             int j, k;
@@ -792,7 +897,7 @@
     FF_ALLOCZ_OR_GOTO(s->avctx, s->mbskip_table, mb_array_size + 2, fail);
     // Note the + 1 is for  a quicker mpeg4 slice_end detection
 
-    return 0;
+    return init_er(s);
 fail:
     return AVERROR(ENOMEM);
 }
@@ -896,7 +1001,7 @@
             }
 
             for (i = 0; i < nb_slices; i++) {
-                if (init_duplicate_context(s->thread_context[i], s) < 0)
+                if (init_duplicate_context(s->thread_context[i]) < 0)
                     goto fail;
                     s->thread_context[i]->start_mb_y =
                         (s->mb_height * (i) + nb_slices / 2) / nb_slices;
@@ -904,7 +1009,7 @@
                         (s->mb_height * (i + 1) + nb_slices / 2) / nb_slices;
             }
         } else {
-            if (init_duplicate_context(s, s) < 0)
+            if (init_duplicate_context(s) < 0)
                 goto fail;
             s->start_mb_y = 0;
             s->end_mb_y   = s->mb_height;
@@ -961,8 +1066,8 @@
 
     av_freep(&s->mbskip_table);
 
-    av_freep(&s->error_status_table);
-    av_freep(&s->er_temp_buffer);
+    av_freep(&s->er.error_status_table);
+    av_freep(&s->er.er_temp_buffer);
     av_freep(&s->mb_index2xy);
     av_freep(&s->lambda_table);
 
@@ -974,9 +1079,6 @@
     for (i = 0; i < 3; i++)
         av_freep(&s->visualization_buffer[i]);
 
-    if (!(s->avctx->active_thread_type & FF_THREAD_FRAME))
-        avcodec_default_free_buffers(s->avctx);
-
     return 0;
 }
 
@@ -1029,7 +1131,7 @@
             }
 
             for (i = 0; i < nb_slices; i++) {
-                if (init_duplicate_context(s->thread_context[i], s) < 0)
+                if (init_duplicate_context(s->thread_context[i]) < 0)
                     goto fail;
                     s->thread_context[i]->start_mb_y =
                         (s->mb_height * (i) + nb_slices / 2) / nb_slices;
@@ -1037,7 +1139,7 @@
                         (s->mb_height * (i + 1) + nb_slices / 2) / nb_slices;
             }
         } else {
-            if (init_duplicate_context(s, s) < 0)
+            if (init_duplicate_context(s) < 0)
                 goto fail;
             s->start_mb_y = 0;
             s->end_mb_y   = s->mb_height;
@@ -1096,6 +1198,9 @@
 
     free_context_frame(s);
 
+    if (!(s->avctx->active_thread_type & FF_THREAD_FRAME))
+        avcodec_default_free_buffers(s->avctx);
+
     s->context_initialized      = 0;
     s->last_picture_ptr         =
     s->next_picture_ptr         =
@@ -1212,9 +1317,13 @@
 
 static inline int pic_is_unused(MpegEncContext *s, Picture *pic)
 {
+    if (   (s->avctx->active_thread_type & FF_THREAD_FRAME)
+        && pic->f.qscale_table //check if the frame has anything allocated
+        && pic->period_since_free < s->avctx->thread_count)
+        return 0;
     if (pic->f.data[0] == NULL)
         return 1;
-    if (pic->needs_realloc)
+    if (pic->needs_realloc && !(pic->f.reference & DELAYED_PIC_REF))
         if (!pic->owner2 || pic->owner2 == s)
             return 1;
     return 0;
@@ -1351,7 +1460,7 @@
         }
 
         pic->f.reference = 0;
-        if (!s->dropable) {
+        if (!s->droppable) {
             if (s->codec_id == AV_CODEC_ID_H264)
                 pic->f.reference = s->picture_structure;
             else if (s->pict_type != AV_PICTURE_TYPE_B)
@@ -1386,7 +1495,7 @@
 
     if (s->pict_type != AV_PICTURE_TYPE_B) {
         s->last_picture_ptr = s->next_picture_ptr;
-        if (!s->dropable)
+        if (!s->droppable)
             s->next_picture_ptr = s->current_picture_ptr;
     }
     av_dlog(s->avctx, "L%p N%p C%p L%p N%p C%p type:%d drop:%d\n",
@@ -1394,13 +1503,16 @@
             s->last_picture_ptr    ? s->last_picture_ptr->f.data[0]    : NULL,
             s->next_picture_ptr    ? s->next_picture_ptr->f.data[0]    : NULL,
             s->current_picture_ptr ? s->current_picture_ptr->f.data[0] : NULL,
-            s->pict_type, s->dropable);
+            s->pict_type, s->droppable);
 
     if (s->codec_id != AV_CODEC_ID_H264) {
         if ((s->last_picture_ptr == NULL ||
              s->last_picture_ptr->f.data[0] == NULL) &&
             (s->pict_type != AV_PICTURE_TYPE_I ||
              s->picture_structure != PICT_FRAME)) {
+            int h_chroma_shift, v_chroma_shift;
+            av_pix_fmt_get_chroma_sub_sample(s->avctx->pix_fmt,
+                                             &h_chroma_shift, &v_chroma_shift);
             if (s->pict_type != AV_PICTURE_TYPE_I)
                 av_log(avctx, AV_LOG_ERROR,
                        "warning: first frame is no keyframe\n");
@@ -1421,6 +1533,15 @@
                 return -1;
             }
 
+            memset(s->last_picture_ptr->f.data[0], 0x80,
+                   avctx->height * s->last_picture_ptr->f.linesize[0]);
+            memset(s->last_picture_ptr->f.data[1], 0x80,
+                   (avctx->height >> v_chroma_shift) *
+                   s->last_picture_ptr->f.linesize[1]);
+            memset(s->last_picture_ptr->f.data[2], 0x80,
+                   (avctx->height >> v_chroma_shift) *
+                   s->last_picture_ptr->f.linesize[2]);
+
             if(s->codec_id == AV_CODEC_ID_FLV1 || s->codec_id == AV_CODEC_ID_H263){
                 for(i=0; i<avctx->height; i++)
                     memset(s->last_picture_ptr->f.data[0] + s->last_picture_ptr->f.linesize[0]*i, 16, avctx->width);
@@ -1451,6 +1572,8 @@
         }
     }
 
+    memset(s->last_picture.f.data, 0, sizeof(s->last_picture.f.data));
+    memset(s->next_picture.f.data, 0, sizeof(s->next_picture.f.data));
     if (s->last_picture_ptr)
         ff_copy_picture(&s->last_picture, s->last_picture_ptr);
     if (s->next_picture_ptr)
@@ -1515,7 +1638,7 @@
     // just to make sure that all data is rendered.
     if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration) {
         ff_xvmc_field_end(s);
-   } else if((s->error_count || s->encoding || !(s->avctx->codec->capabilities&CODEC_CAP_DRAW_HORIZ_BAND)) &&
+   } else if ((s->er.error_count || s->encoding || !(s->avctx->codec->capabilities&CODEC_CAP_DRAW_HORIZ_BAND)) &&
               !s->avctx->hwaccel &&
               !(s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) &&
               s->unrestricted_mv &&
@@ -1608,7 +1731,7 @@
         buf += sx + sy * stride;
         ex  -= sx;
         f    = ((ey - sy) << 16) / ex;
-        for(x= 0; x <= ex; x++){
+        for (x = 0; x <= ex; x++) {
             y  = (x * f) >> 16;
             fr = (x * f) & 0xFFFF;
             buf[y * stride + x]       += (color * (0x10000 - fr)) >> 16;
@@ -1672,134 +1795,136 @@
 /**
  * Print debugging info for the given picture.
  */
-void ff_print_debug_info(MpegEncContext *s, AVFrame *pict)
+void ff_print_debug_info2(AVCodecContext *avctx, AVFrame *pict, uint8_t *mbskip_table,
+                         uint8_t *visualization_buffer[3], int *low_delay,
+                         int mb_width, int mb_height, int mb_stride, int quarter_sample)
 {
-    if (   s->avctx->hwaccel || !pict || !pict->mb_type
-        || (s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU))
+    if (   avctx->hwaccel || !pict || !pict->mb_type
+        || (avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU))
         return;
 
 
-    if (s->avctx->debug & (FF_DEBUG_SKIP | FF_DEBUG_QP | FF_DEBUG_MB_TYPE)) {
+    if (avctx->debug & (FF_DEBUG_SKIP | FF_DEBUG_QP | FF_DEBUG_MB_TYPE)) {
         int x,y;
 
-        av_log(s->avctx, AV_LOG_DEBUG, "New frame, type: %c\n",
+        av_log(avctx, AV_LOG_DEBUG, "New frame, type: %c\n",
                av_get_picture_type_char(pict->pict_type));
-        for (y = 0; y < s->mb_height; y++) {
-            for (x = 0; x < s->mb_width; x++) {
-                if (s->avctx->debug & FF_DEBUG_SKIP) {
-                    int count = s->mbskip_table[x + y * s->mb_stride];
+        for (y = 0; y < mb_height; y++) {
+            for (x = 0; x < mb_width; x++) {
+                if (avctx->debug & FF_DEBUG_SKIP) {
+                    int count = mbskip_table[x + y * mb_stride];
                     if (count > 9)
                         count = 9;
-                    av_log(s->avctx, AV_LOG_DEBUG, "%1d", count);
+                    av_log(avctx, AV_LOG_DEBUG, "%1d", count);
                 }
-                if (s->avctx->debug & FF_DEBUG_QP) {
-                    av_log(s->avctx, AV_LOG_DEBUG, "%2d",
-                           pict->qscale_table[x + y * s->mb_stride]);
+                if (avctx->debug & FF_DEBUG_QP) {
+                    av_log(avctx, AV_LOG_DEBUG, "%2d",
+                           pict->qscale_table[x + y * mb_stride]);
                 }
-                if (s->avctx->debug & FF_DEBUG_MB_TYPE) {
-                    int mb_type = pict->mb_type[x + y * s->mb_stride];
+                if (avctx->debug & FF_DEBUG_MB_TYPE) {
+                    int mb_type = pict->mb_type[x + y * mb_stride];
                     // Type & MV direction
                     if (IS_PCM(mb_type))
-                        av_log(s->avctx, AV_LOG_DEBUG, "P");
+                        av_log(avctx, AV_LOG_DEBUG, "P");
                     else if (IS_INTRA(mb_type) && IS_ACPRED(mb_type))
-                        av_log(s->avctx, AV_LOG_DEBUG, "A");
+                        av_log(avctx, AV_LOG_DEBUG, "A");
                     else if (IS_INTRA4x4(mb_type))
-                        av_log(s->avctx, AV_LOG_DEBUG, "i");
+                        av_log(avctx, AV_LOG_DEBUG, "i");
                     else if (IS_INTRA16x16(mb_type))
-                        av_log(s->avctx, AV_LOG_DEBUG, "I");
+                        av_log(avctx, AV_LOG_DEBUG, "I");
                     else if (IS_DIRECT(mb_type) && IS_SKIP(mb_type))
-                        av_log(s->avctx, AV_LOG_DEBUG, "d");
+                        av_log(avctx, AV_LOG_DEBUG, "d");
                     else if (IS_DIRECT(mb_type))
-                        av_log(s->avctx, AV_LOG_DEBUG, "D");
+                        av_log(avctx, AV_LOG_DEBUG, "D");
                     else if (IS_GMC(mb_type) && IS_SKIP(mb_type))
-                        av_log(s->avctx, AV_LOG_DEBUG, "g");
+                        av_log(avctx, AV_LOG_DEBUG, "g");
                     else if (IS_GMC(mb_type))
-                        av_log(s->avctx, AV_LOG_DEBUG, "G");
+                        av_log(avctx, AV_LOG_DEBUG, "G");
                     else if (IS_SKIP(mb_type))
-                        av_log(s->avctx, AV_LOG_DEBUG, "S");
+                        av_log(avctx, AV_LOG_DEBUG, "S");
                     else if (!USES_LIST(mb_type, 1))
-                        av_log(s->avctx, AV_LOG_DEBUG, ">");
+                        av_log(avctx, AV_LOG_DEBUG, ">");
                     else if (!USES_LIST(mb_type, 0))
-                        av_log(s->avctx, AV_LOG_DEBUG, "<");
+                        av_log(avctx, AV_LOG_DEBUG, "<");
                     else {
                         av_assert2(USES_LIST(mb_type, 0) && USES_LIST(mb_type, 1));
-                        av_log(s->avctx, AV_LOG_DEBUG, "X");
+                        av_log(avctx, AV_LOG_DEBUG, "X");
                     }
 
                     // segmentation
                     if (IS_8X8(mb_type))
-                        av_log(s->avctx, AV_LOG_DEBUG, "+");
+                        av_log(avctx, AV_LOG_DEBUG, "+");
                     else if (IS_16X8(mb_type))
-                        av_log(s->avctx, AV_LOG_DEBUG, "-");
+                        av_log(avctx, AV_LOG_DEBUG, "-");
                     else if (IS_8X16(mb_type))
-                        av_log(s->avctx, AV_LOG_DEBUG, "|");
+                        av_log(avctx, AV_LOG_DEBUG, "|");
                     else if (IS_INTRA(mb_type) || IS_16X16(mb_type))
-                        av_log(s->avctx, AV_LOG_DEBUG, " ");
+                        av_log(avctx, AV_LOG_DEBUG, " ");
                     else
-                        av_log(s->avctx, AV_LOG_DEBUG, "?");
+                        av_log(avctx, AV_LOG_DEBUG, "?");
 
 
                     if (IS_INTERLACED(mb_type))
-                        av_log(s->avctx, AV_LOG_DEBUG, "=");
+                        av_log(avctx, AV_LOG_DEBUG, "=");
                     else
-                        av_log(s->avctx, AV_LOG_DEBUG, " ");
+                        av_log(avctx, AV_LOG_DEBUG, " ");
                 }
             }
-            av_log(s->avctx, AV_LOG_DEBUG, "\n");
+            av_log(avctx, AV_LOG_DEBUG, "\n");
         }
     }
 
-    if ((s->avctx->debug & (FF_DEBUG_VIS_QP | FF_DEBUG_VIS_MB_TYPE)) ||
-        (s->avctx->debug_mv)) {
-        const int shift = 1 + s->quarter_sample;
+    if ((avctx->debug & (FF_DEBUG_VIS_QP | FF_DEBUG_VIS_MB_TYPE)) ||
+        (avctx->debug_mv)) {
+        const int shift = 1 + quarter_sample;
         int mb_y;
         uint8_t *ptr;
         int i;
         int h_chroma_shift, v_chroma_shift, block_height;
-        const int width          = s->avctx->width;
-        const int height         = s->avctx->height;
+        const int width          = avctx->width;
+        const int height         = avctx->height;
         const int mv_sample_log2 = 4 - pict->motion_subsample_log2;
-        const int mv_stride      = (s->mb_width << mv_sample_log2) +
-                                   (s->codec_id == AV_CODEC_ID_H264 ? 0 : 1);
-        s->low_delay = 0; // needed to see the vectors without trashing the buffers
+        const int mv_stride      = (mb_width << mv_sample_log2) +
+                                   (avctx->codec->id == AV_CODEC_ID_H264 ? 0 : 1);
+        *low_delay = 0; // needed to see the vectors without trashing the buffers
 
-        avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &h_chroma_shift, &v_chroma_shift);
+        avcodec_get_chroma_sub_sample(avctx->pix_fmt, &h_chroma_shift, &v_chroma_shift);
 
         for (i = 0; i < 3; i++) {
             size_t size= (i == 0) ? pict->linesize[i] * FFALIGN(height, 16):
                          pict->linesize[i] * FFALIGN(height, 16) >> v_chroma_shift;
-            s->visualization_buffer[i]= av_realloc(s->visualization_buffer[i], size);
-            memcpy(s->visualization_buffer[i], pict->data[i], size);
-            pict->data[i] = s->visualization_buffer[i];
+            visualization_buffer[i]= av_realloc(visualization_buffer[i], size);
+            memcpy(visualization_buffer[i], pict->data[i], size);
+            pict->data[i] = visualization_buffer[i];
         }
         pict->type   = FF_BUFFER_TYPE_COPY;
         pict->opaque= NULL;
         ptr          = pict->data[0];
         block_height = 16 >> v_chroma_shift;
 
-        for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
+        for (mb_y = 0; mb_y < mb_height; mb_y++) {
             int mb_x;
-            for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
-                const int mb_index = mb_x + mb_y * s->mb_stride;
-                if ((s->avctx->debug_mv) && pict->motion_val[0]) {
+            for (mb_x = 0; mb_x < mb_width; mb_x++) {
+                const int mb_index = mb_x + mb_y * mb_stride;
+                if ((avctx->debug_mv) && pict->motion_val[0]) {
                     int type;
                     for (type = 0; type < 3; type++) {
                         int direction = 0;
                         switch (type) {
                         case 0:
-                            if ((!(s->avctx->debug_mv & FF_DEBUG_VIS_MV_P_FOR)) ||
+                            if ((!(avctx->debug_mv & FF_DEBUG_VIS_MV_P_FOR)) ||
                                 (pict->pict_type!= AV_PICTURE_TYPE_P))
                                 continue;
                             direction = 0;
                             break;
                         case 1:
-                            if ((!(s->avctx->debug_mv & FF_DEBUG_VIS_MV_B_FOR)) ||
+                            if ((!(avctx->debug_mv & FF_DEBUG_VIS_MV_B_FOR)) ||
                                 (pict->pict_type!= AV_PICTURE_TYPE_B))
                                 continue;
                             direction = 0;
                             break;
                         case 2:
-                            if ((!(s->avctx->debug_mv & FF_DEBUG_VIS_MV_B_BACK)) ||
+                            if ((!(avctx->debug_mv & FF_DEBUG_VIS_MV_B_BACK)) ||
                                 (pict->pict_type!= AV_PICTURE_TYPE_B))
                                 continue;
                             direction = 1;
@@ -1818,7 +1943,7 @@
                                 int mx = (pict->motion_val[direction][xy][0] >> shift) + sx;
                                 int my = (pict->motion_val[direction][xy][1] >> shift) + sy;
                                 draw_arrow(ptr, sx, sy, mx, my, width,
-                                           height, s->linesize, 100);
+                                           height, pict->linesize[0], 100);
                             }
                         } else if (IS_16X8(pict->mb_type[mb_index])) {
                             int i;
@@ -1833,7 +1958,7 @@
                                     my *= 2;
 
                             draw_arrow(ptr, sx, sy, mx + sx, my + sy, width,
-                                       height, s->linesize, 100);
+                                       height, pict->linesize[0], 100);
                             }
                         } else if (IS_8X16(pict->mb_type[mb_index])) {
                             int i;
@@ -1848,7 +1973,7 @@
                                     my *= 2;
 
                                 draw_arrow(ptr, sx, sy, mx + sx, my + sy, width,
-                                           height, s->linesize, 100);
+                                           height, pict->linesize[0], 100);
                             }
                         } else {
                               int sx= mb_x * 16 + 8;
@@ -1856,11 +1981,11 @@
                               int xy= (mb_x + mb_y * mv_stride) << mv_sample_log2;
                               int mx= (pict->motion_val[direction][xy][0]>>shift) + sx;
                               int my= (pict->motion_val[direction][xy][1]>>shift) + sy;
-                              draw_arrow(ptr, sx, sy, mx, my, width, height, s->linesize, 100);
+                              draw_arrow(ptr, sx, sy, mx, my, width, height, pict->linesize[0], 100);
                         }
                     }
                 }
-                if ((s->avctx->debug & FF_DEBUG_VIS_QP)) {
+                if ((avctx->debug & FF_DEBUG_VIS_QP)) {
                     uint64_t c = (pict->qscale_table[mb_index] * 128 / 31) *
                                  0x0101010101010101ULL;
                     int y;
@@ -1873,7 +1998,7 @@
                                       pict->linesize[2]) = c;
                     }
                 }
-                if ((s->avctx->debug & FF_DEBUG_VIS_MB_TYPE) &&
+                if ((avctx->debug & FF_DEBUG_VIS_MB_TYPE) &&
                     pict->motion_val[0]) {
                     int mb_type = pict->mb_type[mb_index];
                     uint64_t u,v;
@@ -1951,16 +2076,22 @@
                     }
 
                     if (IS_INTERLACED(mb_type) &&
-                        s->codec_id == AV_CODEC_ID_H264) {
+                        avctx->codec->id == AV_CODEC_ID_H264) {
                         // hmm
                     }
                 }
-                s->mbskip_table[mb_index] = 0;
+                mbskip_table[mb_index] = 0;
             }
         }
     }
 }
 
+void ff_print_debug_info(MpegEncContext *s, AVFrame *pict)
+{
+    ff_print_debug_info2(s->avctx, pict, s->mbskip_table, s->visualization_buffer, &s->low_delay,
+                             s->mb_width, s->mb_height, s->mb_stride, s->quarter_sample);
+}
+
 static inline int hpel_motion_lowres(MpegEncContext *s,
                                      uint8_t *dest, uint8_t *src,
                                      int field_based, int field_select,
@@ -1990,7 +2121,7 @@
 
     if ((unsigned)src_x > FFMAX( h_edge_pos - (!!sx) - w,                 0) ||
         (unsigned)src_y > FFMAX((v_edge_pos >> field_based) - (!!sy) - h, 0)) {
-        s->dsp.emulated_edge_mc(s->edge_emu_buffer, src, s->linesize, w + 1,
+        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, src, s->linesize, w + 1,
                                 (h + 1) << field_based, src_x,
                                 src_y   << field_based,
                                 h_edge_pos,
@@ -2092,18 +2223,18 @@
 
     if ((unsigned) src_x > FFMAX( h_edge_pos - (!!sx) - 2 * block_s,       0) ||
         (unsigned) src_y > FFMAX((v_edge_pos >> field_based) - (!!sy) - h, 0)) {
-        s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr_y,
+        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr_y,
                                 linesize >> field_based, 17, 17 + field_based,
                                 src_x, src_y << field_based, h_edge_pos,
                                 v_edge_pos);
         ptr_y = s->edge_emu_buffer;
         if (!CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) {
             uint8_t *uvbuf = s->edge_emu_buffer + 18 * s->linesize;
-            s->dsp.emulated_edge_mc(uvbuf , ptr_cb, uvlinesize >> field_based, 9,
+            s->vdsp.emulated_edge_mc(uvbuf , ptr_cb, uvlinesize >> field_based, 9,
                                     9 + field_based,
                                     uvsrc_x, uvsrc_y << field_based,
                                     h_edge_pos >> 1, v_edge_pos >> 1);
-            s->dsp.emulated_edge_mc(uvbuf + 16, ptr_cr, uvlinesize >> field_based, 9,
+            s->vdsp.emulated_edge_mc(uvbuf + 16, ptr_cr, uvlinesize >> field_based, 9,
                                     9 + field_based,
                                     uvsrc_x, uvsrc_y << field_based,
                                     h_edge_pos >> 1, v_edge_pos >> 1);
@@ -2175,7 +2306,7 @@
     if (s->flags & CODEC_FLAG_EMU_EDGE) {
         if ((unsigned) src_x > FFMAX(h_edge_pos - (!!sx) - block_s, 0) ||
             (unsigned) src_y > FFMAX(v_edge_pos - (!!sy) - block_s, 0)) {
-            s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize,
+            s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize,
                                     9, 9, src_x, src_y, h_edge_pos, v_edge_pos);
             ptr = s->edge_emu_buffer;
             emu = 1;
@@ -2187,7 +2318,7 @@
 
     ptr = ref_picture[2] + offset;
     if (emu) {
-        s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize, 9, 9,
+        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize, 9, 9,
                                 src_x, src_y, h_edge_pos, v_edge_pos);
         ptr = s->edge_emu_buffer;
     }
@@ -2310,7 +2441,7 @@
                                        s->mv[dir][2 * i + j][1],
                                        block_s, mb_y);
                 }
-                pix_op = s->dsp.avg_h264_chroma_pixels_tab;
+                pix_op = s->h264chroma.avg_h264_chroma_pixels_tab;
             }
         } else {
             for (i = 0; i < 2; i++) {
@@ -2321,7 +2452,7 @@
                                    2 * block_s, mb_y >> 1);
 
                 // after put we make avg of the same block
-                pix_op = s->dsp.avg_h264_chroma_pixels_tab;
+                pix_op = s->h264chroma.avg_h264_chroma_pixels_tab;
 
                 // opposite parity is always in the same
                 // frame if this is second field
@@ -2376,7 +2507,7 @@
 
 /* put block[] to dest[] */
 static inline void put_dct(MpegEncContext *s,
-                           DCTELEM *block, int i, uint8_t *dest, int line_size, int qscale)
+                           int16_t *block, int i, uint8_t *dest, int line_size, int qscale)
 {
     s->dct_unquantize_intra(s, block, i, qscale);
     s->dsp.idct_put (dest, line_size, block);
@@ -2384,7 +2515,7 @@
 
 /* add block[] to dest[] */
 static inline void add_dct(MpegEncContext *s,
-                           DCTELEM *block, int i, uint8_t *dest, int line_size)
+                           int16_t *block, int i, uint8_t *dest, int line_size)
 {
     if (s->block_last_index[i] >= 0) {
         s->dsp.idct_add (dest, line_size, block);
@@ -2392,7 +2523,7 @@
 }
 
 static inline void add_dequant_dct(MpegEncContext *s,
-                           DCTELEM *block, int i, uint8_t *dest, int line_size, int qscale)
+                           int16_t *block, int i, uint8_t *dest, int line_size, int qscale)
 {
     if (s->block_last_index[i] >= 0) {
         s->dct_unquantize_inter(s, block, i, qscale);
@@ -2445,7 +2576,7 @@
    s->interlaced_dct : true if interlaced dct used (mpeg2)
  */
 static av_always_inline
-void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM block[12][64],
+void MPV_decode_mb_internal(MpegEncContext *s, int16_t block[12][64],
                             int lowres_flag, int is_mpeg12)
 {
     const int mb_xy = s->mb_y * s->mb_stride + s->mb_x;
@@ -2457,7 +2588,7 @@
     if(s->avctx->debug&FF_DEBUG_DCT_COEFF) {
        /* save DCT coefficients */
        int i,j;
-       DCTELEM *dct = &s->current_picture.f.dct_coeff[mb_xy * 64 * 6];
+       int16_t *dct = &s->current_picture.f.dct_coeff[mb_xy * 64 * 6];
        av_log(s->avctx, AV_LOG_DEBUG, "DCT coeffs of MB at %dx%d:\n", s->mb_x, s->mb_y);
        for(i=0; i<6; i++){
            for(j=0; j<64; j++){
@@ -2542,11 +2673,11 @@
                 }
 
                 if(lowres_flag){
-                    h264_chroma_mc_func *op_pix = s->dsp.put_h264_chroma_pixels_tab;
+                    h264_chroma_mc_func *op_pix = s->h264chroma.put_h264_chroma_pixels_tab;
 
                     if (s->mv_dir & MV_DIR_FORWARD) {
                         MPV_motion_lowres(s, dest_y, dest_cb, dest_cr, 0, s->last_picture.f.data, op_pix);
-                        op_pix = s->dsp.avg_h264_chroma_pixels_tab;
+                        op_pix = s->h264chroma.avg_h264_chroma_pixels_tab;
                     }
                     if (s->mv_dir & MV_DIR_BACKWARD) {
                         MPV_motion_lowres(s, dest_y, dest_cb, dest_cr, 1, s->next_picture.f.data, op_pix);
@@ -2688,7 +2819,7 @@
     }
 }
 
-void ff_MPV_decode_mb(MpegEncContext *s, DCTELEM block[12][64]){
+void ff_MPV_decode_mb(MpegEncContext *s, int16_t block[12][64]){
 #if !CONFIG_SMALL
     if(s->out_format == FMT_MPEG1) {
         if(s->avctx->lowres) MPV_decode_mb_internal(s, block, 1, 1);
@@ -2702,73 +2833,91 @@
 /**
  * @param h is the normal height, this will be reduced automatically if needed for the last row
  */
-void ff_draw_horiz_band(MpegEncContext *s, int y, int h){
-    const int field_pic= s->picture_structure != PICT_FRAME;
+void ff_draw_horiz_band(AVCodecContext *avctx, DSPContext *dsp, Picture *cur,
+                        Picture *last, int y, int h, int picture_structure,
+                        int first_field, int draw_edges, int low_delay,
+                        int v_edge_pos, int h_edge_pos)
+{
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
+    int hshift = desc->log2_chroma_w;
+    int vshift = desc->log2_chroma_h;
+    const int field_pic = picture_structure != PICT_FRAME;
     if(field_pic){
         h <<= 1;
         y <<= 1;
     }
 
-    if (!s->avctx->hwaccel
-       && !(s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
-       && s->unrestricted_mv
-       && s->current_picture.f.reference
-       && !s->intra_only
-       && !(s->flags&CODEC_FLAG_EMU_EDGE)) {
-        const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(s->avctx->pix_fmt);
+    if (!avctx->hwaccel &&
+        !(avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) &&
+        draw_edges &&
+        cur->f.reference &&
+        !(avctx->flags & CODEC_FLAG_EMU_EDGE)) {
+        int *linesize = cur->f.linesize;
         int sides = 0, edge_h;
-        int hshift = desc->log2_chroma_w;
-        int vshift = desc->log2_chroma_h;
         if (y==0) sides |= EDGE_TOP;
-        if (y + h >= s->v_edge_pos) sides |= EDGE_BOTTOM;
+        if (y + h >= v_edge_pos)
+            sides |= EDGE_BOTTOM;
 
-        edge_h= FFMIN(h, s->v_edge_pos - y);
+        edge_h= FFMIN(h, v_edge_pos - y);
 
-        s->dsp.draw_edges(s->current_picture_ptr->f.data[0] +  y         *s->linesize,
-                          s->linesize,           s->h_edge_pos,         edge_h,
-                          EDGE_WIDTH,            EDGE_WIDTH,            sides);
-        s->dsp.draw_edges(s->current_picture_ptr->f.data[1] + (y>>vshift)*s->uvlinesize,
-                          s->uvlinesize,         s->h_edge_pos>>hshift, edge_h>>vshift,
-                          EDGE_WIDTH>>hshift,    EDGE_WIDTH>>vshift,    sides);
-        s->dsp.draw_edges(s->current_picture_ptr->f.data[2] + (y>>vshift)*s->uvlinesize,
-                          s->uvlinesize,         s->h_edge_pos>>hshift, edge_h>>vshift,
-                          EDGE_WIDTH>>hshift,    EDGE_WIDTH>>vshift,    sides);
+        dsp->draw_edges(cur->f.data[0] + y * linesize[0],
+                        linesize[0], h_edge_pos, edge_h,
+                        EDGE_WIDTH, EDGE_WIDTH, sides);
+        dsp->draw_edges(cur->f.data[1] + (y >> vshift) * linesize[1],
+                        linesize[1], h_edge_pos >> hshift, edge_h >> vshift,
+                        EDGE_WIDTH >> hshift, EDGE_WIDTH >> vshift, sides);
+        dsp->draw_edges(cur->f.data[2] + (y >> vshift) * linesize[2],
+                        linesize[2], h_edge_pos >> hshift, edge_h >> vshift,
+                        EDGE_WIDTH >> hshift, EDGE_WIDTH >> vshift, sides);
     }
 
-    h= FFMIN(h, s->avctx->height - y);
+    h = FFMIN(h, avctx->height - y);
 
-    if(field_pic && s->first_field && !(s->avctx->slice_flags&SLICE_FLAG_ALLOW_FIELD)) return;
+    if(field_pic && first_field && !(avctx->slice_flags&SLICE_FLAG_ALLOW_FIELD)) return;
 
-    if (s->avctx->draw_horiz_band) {
+    if (avctx->draw_horiz_band) {
         AVFrame *src;
         int offset[AV_NUM_DATA_POINTERS];
         int i;
 
-        if(s->pict_type==AV_PICTURE_TYPE_B || s->low_delay || (s->avctx->slice_flags&SLICE_FLAG_CODED_ORDER))
-            src = &s->current_picture_ptr->f;
-        else if(s->last_picture_ptr)
-            src = &s->last_picture_ptr->f;
+        if(cur->f.pict_type == AV_PICTURE_TYPE_B || low_delay ||
+           (avctx->slice_flags & SLICE_FLAG_CODED_ORDER))
+            src = &cur->f;
+        else if (last)
+            src = &last->f;
         else
             return;
 
-        if(s->pict_type==AV_PICTURE_TYPE_B && s->picture_structure == PICT_FRAME && s->out_format != FMT_H264){
+        if (cur->f.pict_type == AV_PICTURE_TYPE_B &&
+            picture_structure == PICT_FRAME    &&
+            avctx->codec_id != AV_CODEC_ID_H264  &&
+            avctx->codec_id != AV_CODEC_ID_SVQ3) {
             for (i = 0; i < AV_NUM_DATA_POINTERS; i++)
                 offset[i] = 0;
         }else{
-            offset[0]= y * s->linesize;
+            offset[0]= y * src->linesize[0];
             offset[1]=
-            offset[2]= (y >> s->chroma_y_shift) * s->uvlinesize;
+            offset[2]= (y >> vshift) * src->linesize[1];
             for (i = 3; i < AV_NUM_DATA_POINTERS; i++)
                 offset[i] = 0;
         }
 
         emms_c();
 
-        s->avctx->draw_horiz_band(s->avctx, src, offset,
-                                  y, s->picture_structure, h);
+        avctx->draw_horiz_band(avctx, src, offset,
+                               y, picture_structure, h);
     }
 }
 
+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,
+                       s->first_field, draw_edges, s->low_delay,
+                       s->v_edge_pos, s->h_edge_pos);
+}
+
 void ff_init_block_index(MpegEncContext *s){ //FIXME maybe rename
     const int linesize   = s->current_picture.f.linesize[0]; //not s->linesize as this would be wrong for field pics
     const int uvlinesize = s->current_picture.f.linesize[1];
@@ -2801,6 +2950,35 @@
     }
 }
 
+/**
+ * Permute an 8x8 block.
+ * @param block the block which will be permuted according to the given permutation vector
+ * @param permutation the permutation vector
+ * @param last the last non zero coefficient in scantable order, used to speed the permutation up
+ * @param scantable the used scantable, this is only used to speed the permutation up, the block is not
+ *                  (inverse) permutated to scantable order!
+ */
+void ff_block_permute(int16_t *block, uint8_t *permutation, const uint8_t *scantable, int last)
+{
+    int i;
+    int16_t temp[64];
+
+    if(last<=0) return;
+    //if(permutation[1]==1) return; //FIXME it is ok but not clean and might fail for some permutations
+
+    for(i=0; i<=last; i++){
+        const int j= scantable[i];
+        temp[j]= block[j];
+        block[j]=0;
+    }
+
+    for(i=0; i<=last; i++){
+        const int j= scantable[i];
+        const int perm_j= permutation[j];
+        block[perm_j]= temp[j];
+    }
+}
+
 void ff_mpeg_flush(AVCodecContext *avctx){
     int i;
     MpegEncContext *s = avctx->priv_data;
@@ -2830,7 +3008,7 @@
 }
 
 static void dct_unquantize_mpeg1_intra_c(MpegEncContext *s,
-                                   DCTELEM *block, int n, int qscale)
+                                   int16_t *block, int n, int qscale)
 {
     int i, level, nCoeffs;
     const uint16_t *quant_matrix;
@@ -2859,7 +3037,7 @@
 }
 
 static void dct_unquantize_mpeg1_inter_c(MpegEncContext *s,
-                                   DCTELEM *block, int n, int qscale)
+                                   int16_t *block, int n, int qscale)
 {
     int i, level, nCoeffs;
     const uint16_t *quant_matrix;
@@ -2888,7 +3066,7 @@
 }
 
 static void dct_unquantize_mpeg2_intra_c(MpegEncContext *s,
-                                   DCTELEM *block, int n, int qscale)
+                                   int16_t *block, int n, int qscale)
 {
     int i, level, nCoeffs;
     const uint16_t *quant_matrix;
@@ -2915,7 +3093,7 @@
 }
 
 static void dct_unquantize_mpeg2_intra_bitexact(MpegEncContext *s,
-                                   DCTELEM *block, int n, int qscale)
+                                   int16_t *block, int n, int qscale)
 {
     int i, level, nCoeffs;
     const uint16_t *quant_matrix;
@@ -2946,7 +3124,7 @@
 }
 
 static void dct_unquantize_mpeg2_inter_c(MpegEncContext *s,
-                                   DCTELEM *block, int n, int qscale)
+                                   int16_t *block, int n, int qscale)
 {
     int i, level, nCoeffs;
     const uint16_t *quant_matrix;
@@ -2977,7 +3155,7 @@
 }
 
 static void dct_unquantize_h263_intra_c(MpegEncContext *s,
-                                  DCTELEM *block, int n, int qscale)
+                                  int16_t *block, int n, int qscale)
 {
     int i, level, qmul, qadd;
     int nCoeffs;
@@ -3011,7 +3189,7 @@
 }
 
 static void dct_unquantize_h263_inter_c(MpegEncContext *s,
-                                  DCTELEM *block, int n, int qscale)
+                                  int16_t *block, int n, int qscale)
 {
     int i, level, qmul, qadd;
     int nCoeffs;
@@ -3055,6 +3233,22 @@
 
 void ff_MPV_report_decode_progress(MpegEncContext *s)
 {
-    if (s->pict_type != AV_PICTURE_TYPE_B && !s->partitioned_frame && !s->error_occurred)
+    if (s->pict_type != AV_PICTURE_TYPE_B && !s->partitioned_frame && !s->er.error_occurred)
         ff_thread_report_progress(&s->current_picture_ptr->f, s->mb_y, 0);
 }
+
+void ff_mpeg_er_frame_start(MpegEncContext *s)
+{
+    ERContext *er = &s->er;
+
+    er->cur_pic  = s->current_picture_ptr;
+    er->last_pic = s->last_picture_ptr;
+    er->next_pic = s->next_picture_ptr;
+
+    er->pp_time           = s->pp_time;
+    er->pb_time           = s->pb_time;
+    er->quarter_sample    = s->quarter_sample;
+    er->partitioned_frame = s->partitioned_frame;
+
+    ff_er_frame_start(er);
+}
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index b366899..4d6487d 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -30,15 +30,18 @@
 
 #include "avcodec.h"
 #include "dsputil.h"
+#include "error_resilience.h"
 #include "get_bits.h"
+#include "h264chroma.h"
 #include "put_bits.h"
 #include "ratecontrol.h"
 #include "parser.h"
 #include "mpeg12data.h"
 #include "rl.h"
-#include "libavutil/timecode.h"
+#include "videodsp.h"
 
 #include "libavutil/opt.h"
+#include "libavutil/timecode.h"
 
 #define FRAME_SKIPPED 100 ///< return value for header parsers if frame is not coded
 
@@ -56,11 +59,10 @@
 #define QMAT_SHIFT 21
 
 #define MAX_FCODE 7
-#define MAX_MV 2048
+#define MAX_MV 4096
 
 #define MAX_THREADS 32
-
-#define MAX_PICTURE_COUNT 34
+#define MAX_PICTURE_COUNT 36
 
 #define ME_MAP_SIZE 64
 #define ME_MAP_SHIFT 3
@@ -80,6 +82,12 @@
 #define EXT_START_CODE          0x000001b5
 #define USER_START_CODE         0x000001b2
 
+/**
+ * Value of Picture.reference when Picture is not a reference picture, but
+ * is held for delayed output.
+ */
+#define DELAYED_PIC_REF 4
+
 struct MpegEncContext;
 
 /**
@@ -88,10 +96,6 @@
 typedef struct Picture{
     struct AVFrame f;
 
-    /**
-     * halfpel luma planes.
-     */
-    uint8_t *interpolated[3];
     int8_t *qscale_table_base;
     int16_t (*motion_val_base[2])[2];
     uint32_t *mb_type_base;
@@ -138,10 +142,10 @@
     uint16_t *mb_var;           ///< Table for MB variances
     uint16_t *mc_mb_var;        ///< Table for motion compensated MB variances
     uint8_t *mb_mean;           ///< Table for MB luminance
-    int32_t *mb_cmp_score;      ///< Table for MB cmp scores, for mb decision FIXME remove
     int b_frame_score;          /* */
-    struct MpegEncContext *owner2; ///< pointer to the MpegEncContext that allocated this picture
+    void *owner2;               ///< pointer to the context that allocated this picture
     int needs_realloc;          ///< Picture needs to be reallocated (eg due to a frame size change)
+    int period_since_free;      ///< "cycles" since this Picture has been freed
 } Picture;
 
 /**
@@ -346,7 +350,7 @@
     int vbv_delay;
     int last_pict_type; //FIXME removes
     int last_non_b_pict_type;   ///< used for mpeg4 gmc b-frames & ratecontrol
-    int dropable;
+    int droppable;
     int frame_rate_index;
     AVRational mpeg2_frame_rate_ext;
     int last_lambda_for[5];     ///< last lambda for a specific pict type
@@ -357,6 +361,8 @@
     int h263_long_vectors;      ///< use horrible h263v1 long vector mode
 
     DSPContext dsp;             ///< pointers for accelerated dsp functions
+    H264ChromaContext h264chroma;
+    VideoDSPContext vdsp;
     int f_code;                 ///< forward MV resolution
     int b_code;                 ///< backward MV resolution for B Frames (mpeg4)
     int16_t (*p_mv_table_base)[2];
@@ -489,19 +495,6 @@
     int last_bits; ///< temp var used for calculating the above vars
 
     /* error concealment / resync */
-    int error_count, error_occurred;
-    uint8_t *error_status_table;       ///< table of the error status of each MB
-#define VP_START            1          ///< current MB is the first after a resync marker
-#define ER_AC_ERROR            2
-#define ER_DC_ERROR            4
-#define ER_MV_ERROR            8
-#define ER_AC_END              16
-#define ER_DC_END              32
-#define ER_MV_END              64
-
-#define ER_MB_ERROR (ER_AC_ERROR|ER_DC_ERROR|ER_MV_ERROR)
-#define ER_MB_END   (ER_AC_END|ER_DC_END|ER_MV_END)
-
     int resync_mb_x;                 ///< x position of last resync marker
     int resync_mb_y;                 ///< y position of last resync marker
     GetBitContext last_resync_gb;    ///< used to search for the next resync marker
@@ -673,58 +666,57 @@
 
     uint8_t *ptr_lastgob;
     int swap_uv;             //vcr2 codec is an MPEG-2 variant with U and V swapped
-    DCTELEM (*pblocks[12])[64];
+    int16_t (*pblocks[12])[64];
 
-    DCTELEM (*block)[64]; ///< points to one of the following blocks
-    DCTELEM (*blocks)[12][64]; // for HQ mode we need to keep the best block
-    int (*decode_mb)(struct MpegEncContext *s, DCTELEM block[6][64]); // used by some codecs to avoid a switch()
+    int16_t (*block)[64]; ///< points to one of the following blocks
+    int16_t (*blocks)[12][64]; // for HQ mode we need to keep the best block
+    int (*decode_mb)(struct MpegEncContext *s, int16_t block[6][64]); // used by some codecs to avoid a switch()
 #define SLICE_OK         0
 #define SLICE_ERROR     -1
 #define SLICE_END       -2 ///<end marker found
 #define SLICE_NOEND     -3 ///<no end marker or error found but mb count exceeded
 
     void (*dct_unquantize_mpeg1_intra)(struct MpegEncContext *s,
-                           DCTELEM *block/*align 16*/, int n, int qscale);
+                           int16_t *block/*align 16*/, int n, int qscale);
     void (*dct_unquantize_mpeg1_inter)(struct MpegEncContext *s,
-                           DCTELEM *block/*align 16*/, int n, int qscale);
+                           int16_t *block/*align 16*/, int n, int qscale);
     void (*dct_unquantize_mpeg2_intra)(struct MpegEncContext *s,
-                           DCTELEM *block/*align 16*/, int n, int qscale);
+                           int16_t *block/*align 16*/, int n, int qscale);
     void (*dct_unquantize_mpeg2_inter)(struct MpegEncContext *s,
-                           DCTELEM *block/*align 16*/, int n, int qscale);
+                           int16_t *block/*align 16*/, int n, int qscale);
     void (*dct_unquantize_h263_intra)(struct MpegEncContext *s,
-                           DCTELEM *block/*align 16*/, int n, int qscale);
+                           int16_t *block/*align 16*/, int n, int qscale);
     void (*dct_unquantize_h263_inter)(struct MpegEncContext *s,
-                           DCTELEM *block/*align 16*/, int n, int qscale);
+                           int16_t *block/*align 16*/, int n, int qscale);
     void (*dct_unquantize_h261_intra)(struct MpegEncContext *s,
-                           DCTELEM *block/*align 16*/, int n, int qscale);
+                           int16_t *block/*align 16*/, int n, int qscale);
     void (*dct_unquantize_h261_inter)(struct MpegEncContext *s,
-                           DCTELEM *block/*align 16*/, int n, int qscale);
+                           int16_t *block/*align 16*/, int n, int qscale);
     void (*dct_unquantize_intra)(struct MpegEncContext *s, // unquantizer to use (mpeg4 can use both)
-                           DCTELEM *block/*align 16*/, int n, int qscale);
+                           int16_t *block/*align 16*/, int n, int qscale);
     void (*dct_unquantize_inter)(struct MpegEncContext *s, // unquantizer to use (mpeg4 can use both)
-                           DCTELEM *block/*align 16*/, int n, int qscale);
-    int (*dct_quantize)(struct MpegEncContext *s, DCTELEM *block/*align 16*/, int n, int qscale, int *overflow);
-    int (*fast_dct_quantize)(struct MpegEncContext *s, DCTELEM *block/*align 16*/, int n, int qscale, int *overflow);
-    void (*denoise_dct)(struct MpegEncContext *s, DCTELEM *block);
+                           int16_t *block/*align 16*/, int n, int qscale);
+    int (*dct_quantize)(struct MpegEncContext *s, int16_t *block/*align 16*/, int n, int qscale, int *overflow);
+    int (*fast_dct_quantize)(struct MpegEncContext *s, int16_t *block/*align 16*/, int n, int qscale, int *overflow);
+    void (*denoise_dct)(struct MpegEncContext *s, int16_t *block);
 
     int mpv_flags;      ///< flags set by private options
     int quantizer_noise_shaping;
 
-    /* error resilience stuff */
-    uint8_t *er_temp_buffer;
-
     /* temp buffers for rate control */
     float *cplx_tab, *bits_tab;
 
     /* flag to indicate a reinitialization is required, e.g. after
      * a frame size change */
     int context_reinit;
+
+    ERContext er;
 } MpegEncContext;
 
-#define REBASE_PICTURE(pic, new_ctx, old_ctx) (pic ? \
-    (pic >= old_ctx->picture && pic < old_ctx->picture+old_ctx->picture_count ?\
-        &new_ctx->picture[pic - old_ctx->picture] : pic - (Picture*)old_ctx + (Picture*)new_ctx)\
-    : NULL)
+#define REBASE_PICTURE(pic, new_ctx, old_ctx)             \
+    ((pic && pic >= old_ctx->picture &&                   \
+      pic < old_ctx->picture + old_ctx->picture_count) ?  \
+        &new_ctx->picture[pic - old_ctx->picture] : NULL)
 
 /* mpegvideo_enc common options */
 #define FF_MPV_FLAG_SKIP_RD      0x0001
@@ -765,9 +757,10 @@
 
 void ff_MPV_decode_defaults(MpegEncContext *s);
 int ff_MPV_common_init(MpegEncContext *s);
+int ff_mpv_frame_size_alloc(MpegEncContext *s, int linesize);
 int ff_MPV_common_frame_size_change(MpegEncContext *s);
 void ff_MPV_common_end(MpegEncContext *s);
-void ff_MPV_decode_mb(MpegEncContext *s, DCTELEM block[12][64]);
+void ff_MPV_decode_mb(MpegEncContext *s, int16_t block[12][64]);
 int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx);
 void ff_MPV_frame_end(MpegEncContext *s);
 int ff_MPV_encode_init(AVCodecContext *avctx);
@@ -781,29 +774,31 @@
 void ff_MPV_common_init_altivec(MpegEncContext *s);
 void ff_MPV_common_init_bfin(MpegEncContext *s);
 void ff_clean_intra_table_entries(MpegEncContext *s);
-void ff_draw_horiz_band(MpegEncContext *s, int y, int h);
+void ff_draw_horiz_band(AVCodecContext *avctx, DSPContext *dsp, Picture *cur,
+                        Picture *last, int y, int h, int picture_structure,
+                        int first_field, int draw_edges, int low_delay,
+                        int v_edge_pos, int h_edge_pos);
+void ff_mpeg_draw_horiz_band(MpegEncContext *s, int y, int h);
 void ff_mpeg_flush(AVCodecContext *avctx);
 void ff_print_debug_info(MpegEncContext *s, AVFrame *pict);
 void ff_write_quant_matrix(PutBitContext *pb, uint16_t *matrix);
 void ff_release_unused_pictures(MpegEncContext *s, int remove_current);
 int ff_find_unused_picture(MpegEncContext *s, int shared);
-void ff_denoise_dct(MpegEncContext *s, DCTELEM *block);
-void ff_update_duplicate_context(MpegEncContext *dst, MpegEncContext *src);
+void ff_denoise_dct(MpegEncContext *s, int16_t *block);
+int ff_update_duplicate_context(MpegEncContext *dst, MpegEncContext *src);
 int ff_MPV_lowest_referenced_row(MpegEncContext *s, int dir);
 void ff_MPV_report_decode_progress(MpegEncContext *s);
 int ff_mpeg_update_thread_context(AVCodecContext *dst, const AVCodecContext *src);
 const uint8_t *avpriv_mpv_find_start_code(const uint8_t *p, const uint8_t *end, uint32_t *state);
 void ff_set_qscale(MpegEncContext * s, int qscale);
 
-void ff_er_frame_start(MpegEncContext *s);
-void ff_er_frame_end(MpegEncContext *s);
-void ff_er_add_slice(MpegEncContext *s, int startx, int starty, int endx, int endy, int status);
+void ff_mpeg_er_frame_start(MpegEncContext *s);
 
 int ff_dct_common_init(MpegEncContext *s);
 int ff_dct_encode_init(MpegEncContext *s);
 void ff_convert_matrix(DSPContext *dsp, int (*qmat)[64], uint16_t (*qmat16)[2][64],
                        const uint16_t *quant_matrix, int bias, int qmin, int qmax, int intra);
-int ff_dct_quantize_c(MpegEncContext *s, DCTELEM *block, int n, int qscale, int *overflow);
+int ff_dct_quantize_c(MpegEncContext *s, int16_t *block, int n, int qscale, int *overflow);
 
 void ff_init_block_index(MpegEncContext *s);
 void ff_copy_picture(Picture *dst, Picture *src);
@@ -822,7 +817,12 @@
 int ff_alloc_picture(MpegEncContext *s, Picture *pic, int shared);
 
 extern const enum AVPixelFormat ff_pixfmt_list_420[];
-extern const enum AVPixelFormat ff_hwaccel_pixfmt_list_420[];
+
+/**
+ * permute block according to permuatation.
+ * @param last last non zero element in scantable order
+ */
+void ff_block_permute(int16_t *block, uint8_t *permutation, const uint8_t *scantable, int last);
 
 static inline void ff_update_block_index(MpegEncContext *s){
     const int block_size= 8 >> s->avctx->lowres;
@@ -878,7 +878,7 @@
 
 void ff_mpeg1_encode_picture_header(MpegEncContext *s, int picture_number);
 void ff_mpeg1_encode_mb(MpegEncContext *s,
-                        DCTELEM block[6][64],
+                        int16_t block[6][64],
                         int motion_x, int motion_y);
 void ff_mpeg1_encode_init(MpegEncContext *s);
 void ff_mpeg1_encode_slice_header(MpegEncContext *s);
@@ -893,7 +893,7 @@
 void ff_h261_loop_filter(MpegEncContext *s);
 void ff_h261_reorder_mb_index(MpegEncContext* s);
 void ff_h261_encode_mb(MpegEncContext *s,
-                    DCTELEM block[6][64],
+                    int16_t block[6][64],
                     int motion_x, int motion_y);
 void ff_h261_encode_picture_header(MpegEncContext * s, int picture_number);
 void ff_h261_encode_init(MpegEncContext *s);
@@ -910,7 +910,7 @@
 void ff_msmpeg4_encode_picture_header(MpegEncContext * s, int picture_number);
 void ff_msmpeg4_encode_ext_header(MpegEncContext * s);
 void ff_msmpeg4_encode_mb(MpegEncContext * s,
-                          DCTELEM block[6][64],
+                          int16_t block[6][64],
                           int motion_x, int motion_y);
 int ff_msmpeg4_decode_picture_header(MpegEncContext * s);
 int ff_msmpeg4_decode_ext_header(MpegEncContext * s, int buf_size);
@@ -918,14 +918,14 @@
 void ff_msmpeg4_encode_init(MpegEncContext *s);
 int ff_wmv2_decode_picture_header(MpegEncContext * s);
 int ff_wmv2_decode_secondary_picture_header(MpegEncContext * s);
-void ff_wmv2_add_mb(MpegEncContext *s, DCTELEM block[6][64], uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr);
+void ff_wmv2_add_mb(MpegEncContext *s, int16_t block[6][64], uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr);
 void ff_mspel_motion(MpegEncContext *s,
                                uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
                                uint8_t **ref_picture, op_pixels_func (*pix_op)[4],
                                int motion_x, int motion_y, int h);
 int ff_wmv2_encode_picture_header(MpegEncContext * s, int picture_number);
 void ff_wmv2_encode_mb(MpegEncContext * s,
-                       DCTELEM block[6][64],
+                       int16_t block[6][64],
                        int motion_x, int motion_y);
 
 #endif /* AVCODEC_MPEGVIDEO_H */
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index d942fdd..a0e7a54 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -27,11 +27,13 @@
  * The simplest mpeg encoder (well, it was the simplest!).
  */
 
+#include "libavutil/internal.h"
 #include "libavutil/intmath.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/pixdesc.h"
 #include "libavutil/opt.h"
 #include "avcodec.h"
+#include "dct.h"
 #include "dsputil.h"
 #include "mpegvideo.h"
 #include "h263.h"
@@ -52,13 +54,10 @@
 //#include <assert.h>
 
 static int encode_picture(MpegEncContext *s, int picture_number);
-static int dct_quantize_refine(MpegEncContext *s, DCTELEM *block, int16_t *weight, DCTELEM *orig, int n, int qscale);
+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, DCTELEM *block);
-static int dct_quantize_trellis_c(MpegEncContext *s, DCTELEM *block, int n, int qscale, int *overflow);
-
-/* enable all paranoid tests for rounding, overflows, etc... */
-//#define PARANOID
+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
 
@@ -186,9 +185,8 @@
     }
 }
 
-static void copy_picture_attributes(MpegEncContext *s,
-                                    AVFrame *dst,
-                                    AVFrame *src)
+static void copy_picture_attributes(MpegEncContext *s, AVFrame *dst,
+                                    const AVFrame *src)
 {
     int i;
 
@@ -557,6 +555,20 @@
         return -1;
     }
 
+    if (s->codec_id == AV_CODEC_ID_RV10 &&
+        (avctx->width &15 ||
+         avctx->height&15 )) {
+        av_log(avctx, AV_LOG_ERROR, "width and height must be a multiple of 16\n");
+        return AVERROR(EINVAL);
+    }
+
+    if (s->codec_id == AV_CODEC_ID_RV20 &&
+        (avctx->width &3 ||
+         avctx->height&3 )) {
+        av_log(avctx, AV_LOG_ERROR, "width and height must be a multiple of 4\n");
+        return AVERROR(EINVAL);
+    }
+
     if ((s->codec_id == AV_CODEC_ID_WMV1 ||
          s->codec_id == AV_CODEC_ID_WMV2) &&
          avctx->width & 1) {
@@ -640,7 +652,7 @@
         return -1;
     }
 
-    if (s->avctx->thread_count > 1)
+    if (s->avctx->slices > 1 || s->avctx->thread_count > 1)
         s->rtp_mode = 1;
 
     if (s->avctx->thread_count > 1 && s->codec_id == AV_CODEC_ID_H263P)
@@ -740,6 +752,9 @@
             s->mjpeg_vsample[0] = s->mjpeg_hsample[0] =
             s->mjpeg_vsample[1] = s->mjpeg_hsample[1] =
             s->mjpeg_vsample[2] = s->mjpeg_hsample[2] = 1;
+        } else if (avctx->pix_fmt == AV_PIX_FMT_YUV444P || avctx->pix_fmt == AV_PIX_FMT_YUVJ444P) {
+            s->mjpeg_vsample[0] = s->mjpeg_vsample[1] = s->mjpeg_vsample[2] = 2;
+            s->mjpeg_hsample[0] = s->mjpeg_hsample[1] = s->mjpeg_hsample[2] = 1;
         } else {
             s->mjpeg_vsample[0] = 2;
             s->mjpeg_vsample[1] = 2 >> chroma_v_shift;
@@ -992,18 +1007,18 @@
 }
 
 
-static int load_input_picture(MpegEncContext *s, AVFrame *pic_arg)
+static int load_input_picture(MpegEncContext *s, const AVFrame *pic_arg)
 {
     AVFrame *pic = NULL;
     int64_t pts;
-    int i;
+    int i, display_picture_number = 0;
     const int encoding_delay = s->max_b_frames ? s->max_b_frames :
                                                  (s->low_delay ? 0 : 1);
     int direct = 1;
 
     if (pic_arg) {
         pts = pic_arg->pts;
-        pic_arg->display_picture_number = s->input_picture_number++;
+        display_picture_number = s->input_picture_number++;
 
         if (pts != AV_NOPTS_VALUE) {
             if (s->user_specified_pts != AV_NOPTS_VALUE) {
@@ -1017,7 +1032,7 @@
                     return -1;
                 }
 
-                if (!s->low_delay && pic_arg->display_picture_number == 1)
+                if (!s->low_delay && display_picture_number == 1)
                     s->dts_delta = time - last;
             }
             s->user_specified_pts = pts;
@@ -1029,91 +1044,103 @@
                        "Warning: AVFrame.pts=? trying to guess (%"PRId64")\n",
                        pts);
             } else {
-                pts = pic_arg->display_picture_number;
+                pts = display_picture_number;
             }
         }
     }
 
-  if (pic_arg) {
-    if (encoding_delay && !(s->flags & CODEC_FLAG_INPUT_PRESERVED))
-        direct = 0;
-    if (pic_arg->linesize[0] != s->linesize)
-        direct = 0;
-    if (pic_arg->linesize[1] != s->uvlinesize)
-        direct = 0;
-    if (pic_arg->linesize[2] != s->uvlinesize)
-        direct = 0;
+    if (pic_arg) {
+        if (encoding_delay && !(s->flags & CODEC_FLAG_INPUT_PRESERVED))
+            direct = 0;
+        if (pic_arg->linesize[0] != s->linesize)
+            direct = 0;
+        if (pic_arg->linesize[1] != s->uvlinesize)
+            direct = 0;
+        if (pic_arg->linesize[2] != s->uvlinesize)
+            direct = 0;
 
-    av_dlog(s->avctx, "%d %d %d %d\n", pic_arg->linesize[0],
-            pic_arg->linesize[1], s->linesize, s->uvlinesize);
+        av_dlog(s->avctx, "%d %d %d %d\n", pic_arg->linesize[0],
+                pic_arg->linesize[1], s->linesize, s->uvlinesize);
 
-    if (direct) {
-        i = ff_find_unused_picture(s, 1);
-        if (i < 0)
-            return i;
+        if (direct) {
+            i = ff_find_unused_picture(s, 1);
+            if (i < 0)
+                return i;
 
-        pic = &s->picture[i].f;
-        pic->reference = 3;
+            pic = &s->picture[i].f;
+            pic->reference = 3;
 
-        for (i = 0; i < 4; i++) {
-            pic->data[i]     = pic_arg->data[i];
-            pic->linesize[i] = pic_arg->linesize[i];
-        }
-        if (ff_alloc_picture(s, (Picture *) pic, 1) < 0) {
-            return -1;
-        }
-    } else {
-        i = ff_find_unused_picture(s, 0);
-        if (i < 0)
-            return i;
-
-        pic = &s->picture[i].f;
-        pic->reference = 3;
-
-        if (ff_alloc_picture(s, (Picture *) pic, 0) < 0) {
-            return -1;
-        }
-
-        if (pic->data[0] + INPLACE_OFFSET == pic_arg->data[0] &&
-            pic->data[1] + INPLACE_OFFSET == pic_arg->data[1] &&
-            pic->data[2] + INPLACE_OFFSET == pic_arg->data[2]) {
-            // empty
+            for (i = 0; i < 4; i++) {
+                pic->data[i]     = pic_arg->data[i];
+                pic->linesize[i] = pic_arg->linesize[i];
+            }
+            if (ff_alloc_picture(s, (Picture *) pic, 1) < 0) {
+                return -1;
+            }
         } else {
-            int h_chroma_shift, v_chroma_shift;
-            avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &h_chroma_shift, &v_chroma_shift);
+            i = ff_find_unused_picture(s, 0);
+            if (i < 0)
+                return i;
 
-            for (i = 0; i < 3; i++) {
-                int src_stride = pic_arg->linesize[i];
-                int dst_stride = i ? s->uvlinesize : s->linesize;
-                int h_shift = i ? h_chroma_shift : 0;
-                int v_shift = i ? v_chroma_shift : 0;
-                int w = s->width  >> h_shift;
-                int h = s->height >> v_shift;
-                uint8_t *src = pic_arg->data[i];
-                uint8_t *dst = pic->data[i];
+            pic = &s->picture[i].f;
+            pic->reference = 3;
 
-                if(s->codec_id == AV_CODEC_ID_AMV && !(s->avctx->flags & CODEC_FLAG_EMU_EDGE)){
-                    h= ((s->height+15)/16*16)>>v_shift;
-                }
+            if (ff_alloc_picture(s, (Picture *) pic, 0) < 0) {
+                return -1;
+            }
 
-                if (!s->avctx->rc_buffer_size)
-                    dst += INPLACE_OFFSET;
+            if (pic->data[0] + INPLACE_OFFSET == pic_arg->data[0] &&
+                pic->data[1] + INPLACE_OFFSET == pic_arg->data[1] &&
+                pic->data[2] + INPLACE_OFFSET == pic_arg->data[2]) {
+                // empty
+            } else {
+                int h_chroma_shift, v_chroma_shift;
+                av_pix_fmt_get_chroma_sub_sample(s->avctx->pix_fmt,
+                                                 &h_chroma_shift,
+                                                 &v_chroma_shift);
 
-                if (src_stride == dst_stride)
-                    memcpy(dst, src, src_stride * h);
-                else {
-                    while (h--) {
-                        memcpy(dst, src, w);
-                        dst += dst_stride;
-                        src += src_stride;
+                for (i = 0; i < 3; i++) {
+                    int src_stride = pic_arg->linesize[i];
+                    int dst_stride = i ? s->uvlinesize : s->linesize;
+                    int h_shift = i ? h_chroma_shift : 0;
+                    int v_shift = i ? v_chroma_shift : 0;
+                    int w = s->width  >> h_shift;
+                    int h = s->height >> v_shift;
+                    uint8_t *src = pic_arg->data[i];
+                    uint8_t *dst = pic->data[i];
+
+                    if (s->codec_id == AV_CODEC_ID_AMV && !(s->avctx->flags & CODEC_FLAG_EMU_EDGE)) {
+                        h = ((s->height + 15)/16*16) >> v_shift;
+                    }
+
+                    if (!s->avctx->rc_buffer_size)
+                        dst += INPLACE_OFFSET;
+
+                    if (src_stride == dst_stride)
+                        memcpy(dst, src, src_stride * h);
+                    else {
+                        int h2 = h;
+                        uint8_t *dst2 = dst;
+                        while (h2--) {
+                            memcpy(dst2, src, w);
+                            dst2 += dst_stride;
+                            src += src_stride;
+                        }
+                    }
+                    if ((s->width & 15) || (s->height & 15)) {
+                        s->dsp.draw_edges(dst, dst_stride,
+                                          w, h,
+                                          16>>h_shift,
+                                          16>>v_shift,
+                                          EDGE_BOTTOM);
                     }
                 }
             }
         }
+        copy_picture_attributes(s, pic, pic_arg);
+        pic->display_picture_number = display_picture_number;
+        pic->pts = pts; // we set this here to avoid modifiying pic_arg
     }
-    copy_picture_attributes(s, pic, pic_arg);
-    pic->pts = pts; // we set this here to avoid modifiying pic_arg
-  }
 
     /* shift buffer entries */
     for (i = 1; i < MAX_PICTURE_COUNT /*s->encoding_delay + 1*/; i++)
@@ -1713,7 +1740,7 @@
     int score = 0;
     int run = 0;
     int i;
-    DCTELEM *block = s->block[n];
+    int16_t *block = s->block[n];
     const int last_index = s->block_last_index[n];
     int skip_dc;
 
@@ -1753,7 +1780,7 @@
         s->block_last_index[n] = -1;
 }
 
-static inline void clip_coeffs(MpegEncContext *s, DCTELEM *block,
+static inline void clip_coeffs(MpegEncContext *s, int16_t *block,
                                int last_index)
 {
     int i;
@@ -1818,7 +1845,7 @@
                                                 int mb_block_count)
 {
     int16_t weight[12][64];
-    DCTELEM orig[12][64];
+    int16_t orig[12][64];
     const int mb_x = s->mb_x;
     const int mb_y = s->mb_y;
     int i;
@@ -1872,17 +1899,19 @@
 
     if((mb_x*16+16 > s->width || mb_y*16+16 > s->height) && s->codec_id != AV_CODEC_ID_AMV){
         uint8_t *ebuf = s->edge_emu_buffer + 32;
-        s->dsp.emulated_edge_mc(ebuf, ptr_y, wrap_y, 16, 16, mb_x * 16,
-                                mb_y * 16, s->width, s->height);
+        int cw = (s->width  + s->chroma_x_shift) >> s->chroma_x_shift;
+        int ch = (s->height + s->chroma_y_shift) >> s->chroma_y_shift;
+        s->vdsp.emulated_edge_mc(ebuf, ptr_y, wrap_y, 16, 16, mb_x * 16,
+                                 mb_y * 16, s->width, s->height);
         ptr_y = ebuf;
-        s->dsp.emulated_edge_mc(ebuf + 18 * wrap_y, ptr_cb, wrap_c, mb_block_width,
-                                mb_block_height, mb_x * 8, mb_y * 8,
-                                (s->width+1) >> 1, (s->height+1) >> 1);
+        s->vdsp.emulated_edge_mc(ebuf + 18 * wrap_y, ptr_cb, wrap_c, mb_block_width,
+                                 mb_block_height, mb_x * mb_block_width, mb_y * mb_block_height,
+                                 cw, ch);
         ptr_cb = ebuf + 18 * wrap_y;
-        s->dsp.emulated_edge_mc(ebuf + 18 * wrap_y + 8, ptr_cr, wrap_c, mb_block_width,
-                                mb_block_height, mb_x * 8, mb_y * 8,
-                                (s->width+1) >> 1, (s->height+1) >> 1);
-        ptr_cr = ebuf + 18 * wrap_y + 8;
+        s->vdsp.emulated_edge_mc(ebuf + 18 * wrap_y + 16, ptr_cr, wrap_c, mb_block_width,
+                                 mb_block_height, mb_x * mb_block_width, mb_y * mb_block_height,
+                                 cw, ch);
+        ptr_cr = ebuf + 18 * wrap_y + 16;
     }
 
     if (s->mb_intra) {
@@ -2077,7 +2106,7 @@
                 get_visual_weight(weight[7], ptr_cr + uv_dct_offset,
                                   wrap_c);
         }
-        memcpy(orig[0], s->block[0], sizeof(DCTELEM) * 64 * mb_block_count);
+        memcpy(orig[0], s->block[0], sizeof(int16_t) * 64 * mb_block_count);
     }
 
     /* DCT & quantize */
@@ -2127,6 +2156,12 @@
         s->block_last_index[5] = 0;
         s->block[4][0] =
         s->block[5][0] = (1024 + s->c_dc_scale / 2) / s->c_dc_scale;
+        if (!s->chroma_y_shift) { /* 422 / 444 */
+            for (i=6; i<12; i++) {
+                s->block_last_index[i] = 0;
+                s->block[i][0] = s->block[4][0];
+            }
+        }
     }
 
     // non c quantize code returns incorrect block_last_index FIXME
@@ -2823,9 +2858,10 @@
                     if(best_s.mv_type==MV_TYPE_16X16){ //FIXME move 4mv after QPRD
                         const int last_qp= backup_s.qscale;
                         int qpi, qp, dc[6];
-                        DCTELEM ac[6][16];
+                        int16_t ac[6][16];
                         const int mvdir= (best_s.mv_dir&MV_DIR_BACKWARD) ? 1 : 0;
                         static const int dquant_tab[4]={-1,1,-2,2};
+                        int storecoefs = s->mb_intra && s->dc_val[0];
 
                         av_assert2(backup_s.dquant == 0);
 
@@ -2845,20 +2881,20 @@
                             if(qp < s->avctx->qmin || qp > s->avctx->qmax)
                                 continue;
                             backup_s.dquant= dquant;
-                            if(s->mb_intra && s->dc_val[0]){
+                            if(storecoefs){
                                 for(i=0; i<6; i++){
                                     dc[i]= s->dc_val[0][ s->block_index[i] ];
-                                    memcpy(ac[i], s->ac_val[0][s->block_index[i]], sizeof(DCTELEM)*16);
+                                    memcpy(ac[i], s->ac_val[0][s->block_index[i]], sizeof(int16_t)*16);
                                 }
                             }
 
                             encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_INTER /* wrong but unused */, pb, pb2, tex_pb,
                                          &dmin, &next_block, s->mv[mvdir][0][0], s->mv[mvdir][0][1]);
                             if(best_s.qscale != qp){
-                                if(s->mb_intra && s->dc_val[0]){
+                                if(storecoefs){
                                     for(i=0; i<6; i++){
                                         s->dc_val[0][ s->block_index[i] ]= dc[i];
-                                        memcpy(s->ac_val[0][s->block_index[i]], ac[i], sizeof(DCTELEM)*16);
+                                        memcpy(s->ac_val[0][s->block_index[i]], ac[i], sizeof(int16_t)*16);
                                     }
                                 }
                             }
@@ -3142,7 +3178,7 @@
     MERGE(b_count);
     MERGE(skip_count);
     MERGE(misc_bits);
-    MERGE(error_count);
+    MERGE(er.error_count);
     MERGE(padding_bug_score);
     MERGE(current_picture.f.error[0]);
     MERGE(current_picture.f.error[1]);
@@ -3214,7 +3250,7 @@
 
 static int encode_picture(MpegEncContext *s, int picture_number)
 {
-    int i;
+    int i, ret;
     int bits;
     int context_count = s->slice_context_count;
 
@@ -3264,7 +3300,9 @@
 
     s->mb_intra=0; //for the rate distortion & bit compare functions
     for(i=1; i<context_count; i++){
-        ff_update_duplicate_context(s->thread_context[i], s);
+        ret = ff_update_duplicate_context(s->thread_context[i], s);
+        if (ret < 0)
+            return ret;
     }
 
     if(ff_init_me(s)<0)
@@ -3461,7 +3499,7 @@
     return 0;
 }
 
-static void denoise_dct_c(MpegEncContext *s, DCTELEM *block){
+static void denoise_dct_c(MpegEncContext *s, int16_t *block){
     const int intra= s->mb_intra;
     int i;
 
@@ -3486,7 +3524,7 @@
 }
 
 static int dct_quantize_trellis_c(MpegEncContext *s,
-                                  DCTELEM *block, int n,
+                                  int16_t *block, int n,
                                   int qscale, int *overflow){
     const int *qmat;
     const uint8_t *scantable= s->intra_scantable.scantable;
@@ -3593,7 +3631,7 @@
     *overflow= s->max_qcoeff < max; //overflow might have happened
 
     if(last_non_zero < start_i){
-        memset(block + start_i, 0, (64-start_i)*sizeof(DCTELEM));
+        memset(block + start_i, 0, (64-start_i)*sizeof(int16_t));
         return last_non_zero;
     }
 
@@ -3725,7 +3763,7 @@
 
     dc= FFABS(block[0]);
     last_non_zero= last_i - 1;
-    memset(block + start_i, 0, (64-start_i)*sizeof(DCTELEM));
+    memset(block + start_i, 0, (64-start_i)*sizeof(int16_t));
 
     if(last_non_zero < start_i)
         return last_non_zero;
@@ -3800,10 +3838,10 @@
 }
 
 static int dct_quantize_refine(MpegEncContext *s, //FIXME breaks denoise?
-                        DCTELEM *block, int16_t *weight, DCTELEM *orig,
+                        int16_t *block, int16_t *weight, int16_t *orig,
                         int n, int qscale){
     int16_t rem[64];
-    LOCAL_ALIGNED_16(DCTELEM, d1, [64]);
+    LOCAL_ALIGNED_16(int16_t, d1, [64]);
     const uint8_t *scantable= s->intra_scantable.scantable;
     const uint8_t *perm_scantable= s->intra_scantable.permutated;
 //    unsigned int threshold1, threshold2;
@@ -4140,7 +4178,7 @@
 #ifdef REFINE_STATS
 count++;
 if(256*256*256*64 % count == 0){
-    printf("after_last:%d to_zero:%d from_zero:%d raise:%d lower:%d sign:%d xyp:%d/%d/%d\n", after_last, to_zero, from_zero, raise, lower, messed_sign, s->mb_x, s->mb_y, s->picture_number);
+    av_log(s->avctx, AV_LOG_DEBUG, "after_last:%d to_zero:%d from_zero:%d raise:%d lower:%d sign:%d xyp:%d/%d/%d\n", after_last, to_zero, from_zero, raise, lower, messed_sign, s->mb_x, s->mb_y, s->picture_number);
 }
 #endif
             run=0;
@@ -4173,7 +4211,7 @@
 }
 
 int ff_dct_quantize_c(MpegEncContext *s,
-                        DCTELEM *block, int n,
+                        int16_t *block, int n,
                         int qscale, int *overflow)
 {
     int i, j, level, last_non_zero, q, start_i;
diff --git a/libavcodec/mpegvideo_motion.c b/libavcodec/mpegvideo_motion.c
index 18e6428..565f6cb 100644
--- a/libavcodec/mpegvideo_motion.c
+++ b/libavcodec/mpegvideo_motion.c
@@ -22,7 +22,9 @@
  */
 
 #include <string.h>
+
 #include "libavutil/avassert.h"
+#include "libavutil/internal.h"
 #include "avcodec.h"
 #include "dsputil.h"
 #include "mpegvideo.h"
@@ -60,7 +62,7 @@
     if(s->flags&CODEC_FLAG_EMU_EDGE){
         if(   (unsigned)src_x >= FFMAX(s->h_edge_pos - 17, 0)
            || (unsigned)src_y >= FFMAX(s->v_edge_pos - 17, 0)){
-            s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr, linesize, 17, 17, src_x, src_y, s->h_edge_pos, s->v_edge_pos);
+            s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, linesize, 17, 17, src_x, src_y, s->h_edge_pos, s->v_edge_pos);
             ptr= s->edge_emu_buffer;
         }
     }
@@ -99,7 +101,7 @@
     if(s->flags&CODEC_FLAG_EMU_EDGE){
         if(   (unsigned)src_x >= FFMAX((s->h_edge_pos>>1) - 9, 0)
            || (unsigned)src_y >= FFMAX((s->v_edge_pos>>1) - 9, 0)){
-            s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr, uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
+            s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
             ptr= s->edge_emu_buffer;
             emu=1;
         }
@@ -108,7 +110,7 @@
 
     ptr = ref_picture[2] + offset;
     if(emu){
-        s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr, uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
+        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
         ptr= s->edge_emu_buffer;
     }
     s->dsp.gmc1(dest_cr, ptr, uvlinesize, 8, motion_x&15, motion_y&15, 128 - s->no_rounding);
@@ -196,7 +198,7 @@
     if(s->unrestricted_mv && (s->flags&CODEC_FLAG_EMU_EDGE)){
         if(   (unsigned)src_x > FFMAX(s->h_edge_pos - (motion_x&1) - 8, 0)
            || (unsigned)src_y > FFMAX(s->v_edge_pos - (motion_y&1) - 8, 0)){
-            s->dsp.emulated_edge_mc(s->edge_emu_buffer, src, s->linesize, 9, 9,
+            s->vdsp.emulated_edge_mc(s->edge_emu_buffer, src, s->linesize, 9, 9,
                              src_x, src_y, s->h_edge_pos, s->v_edge_pos);
             src= s->edge_emu_buffer;
             emu=1;
@@ -286,19 +288,19 @@
                         "MPEG motion vector out of boundary (%d %d)\n", src_x, src_y);
                 return;
             }
-            s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr_y, s->linesize,
+            s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr_y, s->linesize,
                                 17, 17+field_based,
                                 src_x, src_y<<field_based,
                                 s->h_edge_pos, s->v_edge_pos);
             ptr_y = s->edge_emu_buffer;
             if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
                 uint8_t *uvbuf= s->edge_emu_buffer+18*s->linesize;
-                s->dsp.emulated_edge_mc(uvbuf ,
+                s->vdsp.emulated_edge_mc(uvbuf ,
                                     ptr_cb, s->uvlinesize,
                                     9, 9+field_based,
                                     uvsrc_x, uvsrc_y<<field_based,
                                     s->h_edge_pos>>1, s->v_edge_pos>>1);
-                s->dsp.emulated_edge_mc(uvbuf+16,
+                s->vdsp.emulated_edge_mc(uvbuf+16,
                                     ptr_cr, s->uvlinesize,
                                     9, 9+field_based,
                                     uvsrc_x, uvsrc_y<<field_based,
@@ -499,17 +501,17 @@
 
     if(   (unsigned)src_x > FFMAX(s->h_edge_pos - (motion_x&3) - 16, 0)
        || (unsigned)src_y > FFMAX(   v_edge_pos - (motion_y&3) - h , 0)){
-        s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr_y, s->linesize,
+        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr_y, s->linesize,
                             17, 17+field_based, src_x, src_y<<field_based,
                             s->h_edge_pos, s->v_edge_pos);
         ptr_y= s->edge_emu_buffer;
         if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
             uint8_t *uvbuf= s->edge_emu_buffer + 18*s->linesize;
-            s->dsp.emulated_edge_mc(uvbuf, ptr_cb, s->uvlinesize,
+            s->vdsp.emulated_edge_mc(uvbuf, ptr_cb, s->uvlinesize,
                                 9, 9 + field_based,
                                 uvsrc_x, uvsrc_y<<field_based,
                                 s->h_edge_pos>>1, s->v_edge_pos>>1);
-            s->dsp.emulated_edge_mc(uvbuf + 16, ptr_cr, s->uvlinesize,
+            s->vdsp.emulated_edge_mc(uvbuf + 16, ptr_cr, s->uvlinesize,
                                 9, 9 + field_based,
                                 uvsrc_x, uvsrc_y<<field_based,
                                 s->h_edge_pos>>1, s->v_edge_pos>>1);
@@ -578,7 +580,7 @@
     if(s->flags&CODEC_FLAG_EMU_EDGE){
         if(   (unsigned)src_x > FFMAX((s->h_edge_pos>>1) - (dxy &1) - 8, 0)
            || (unsigned)src_y > FFMAX((s->v_edge_pos>>1) - (dxy>>1) - 8, 0)){
-            s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize,
+            s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize,
                                 9, 9, src_x, src_y,
                                 s->h_edge_pos>>1, s->v_edge_pos>>1);
             ptr= s->edge_emu_buffer;
@@ -589,7 +591,7 @@
 
     ptr = ref_picture[2] + offset;
     if(emu){
-        s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize,
+        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize,
                             9, 9, src_x, src_y,
                             s->h_edge_pos>>1, s->v_edge_pos>>1);
         ptr= s->edge_emu_buffer;
@@ -604,9 +606,9 @@
     const int mx= (s->mv[dir][0][0]>>shift) + 16*s->mb_x + 8;
     const int my= (s->mv[dir][0][1]>>shift) + 16*s->mb_y;
     int off= mx + (my + (s->mb_x&3)*4)*s->linesize + 64;
-    s->dsp.prefetch(pix[0]+off, s->linesize, 4);
+    s->vdsp.prefetch(pix[0]+off, s->linesize, 4);
     off= (mx>>1) + ((my>>1) + (s->mb_x&7))*s->uvlinesize + 64;
-    s->dsp.prefetch(pix[1]+off, pix[2]-pix[1], 2);
+    s->vdsp.prefetch(pix[1]+off, pix[2]-pix[1], 2);
 }
 
 /**
@@ -758,7 +760,7 @@
                 if(s->flags&CODEC_FLAG_EMU_EDGE){
                     if(   (unsigned)src_x > FFMAX(s->h_edge_pos - (motion_x&3) - 8, 0)
                        || (unsigned)src_y > FFMAX(s->v_edge_pos - (motion_y&3) - 8, 0)){
-                        s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr,
+                        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr,
                                             s->linesize, 9, 9,
                                             src_x, src_y,
                                             s->h_edge_pos, s->v_edge_pos);
diff --git a/libavcodec/mpegvideo_parser.c b/libavcodec/mpegvideo_parser.c
index c112a94..35a9160 100644
--- a/libavcodec/mpegvideo_parser.c
+++ b/libavcodec/mpegvideo_parser.c
@@ -56,6 +56,7 @@
         case PICTURE_START_CODE:
             if (bytes_left >= 2) {
                 s->pict_type = (buf[1] >> 3) & 7;
+                if (bytes_left >= 4)
                 vbv_delay = ((buf[1] & 0x07) << 13) | (buf[2] << 5) | (buf[3]  >> 3);
             }
             break;
diff --git a/libavcodec/mpegvideo_xvmc.c b/libavcodec/mpegvideo_xvmc.c
index 6247e62..f30124c 100644
--- a/libavcodec/mpegvideo_xvmc.c
+++ b/libavcodec/mpegvideo_xvmc.c
@@ -23,7 +23,6 @@
 #include <X11/extensions/XvMC.h>
 
 #include "avcodec.h"
-#include "dsputil.h"
 #include "mpegvideo.h"
 
 #undef NDEBUG
@@ -44,7 +43,7 @@
     struct xvmc_pix_fmt *render = (struct xvmc_pix_fmt*)s->current_picture.f.data[2];
     assert(render && render->xvmc_id == AV_XVMC_ID);
 
-    s->block = (DCTELEM (*)[64])(render->data_blocks + render->next_free_data_block_num * 64);
+    s->block = (int16_t (*)[64])(render->data_blocks + render->next_free_data_block_num * 64);
 }
 
 /**
@@ -145,7 +144,7 @@
     assert(render);
 
     if (render->filled_mv_blocks_num > 0)
-        ff_draw_horiz_band(s, 0, 0);
+        ff_mpeg_draw_horiz_band(s, 0, 0);
 }
 
 /**
@@ -328,5 +327,5 @@
 
 
     if (render->filled_mv_blocks_num == render->allocated_mv_blocks)
-        ff_draw_horiz_band(s, 0, 0);
+        ff_mpeg_draw_horiz_band(s, 0, 0);
 }
diff --git a/libavcodec/mpl2dec.c b/libavcodec/mpl2dec.c
new file mode 100644
index 0000000..a777c7c
--- /dev/null
+++ b/libavcodec/mpl2dec.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2012 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
+ * MPL2 subtitles decoder
+ *
+ * @see http://web.archive.org/web/20090328040233/http://napisy.ussbrowarek.org/mpl2-eng.html
+ */
+
+#include "avcodec.h"
+#include "ass.h"
+#include "libavutil/bprint.h"
+
+static int mpl2_event_to_ass(AVBPrint *buf, const char *p)
+{
+    if (*p == ' ')
+        p++;
+
+    while (*p) {
+        int got_style = 0;
+
+        while (*p && strchr("/\\_", *p)) {
+            if      (*p == '/')  av_bprintf(buf, "{\\i1}");
+            else if (*p == '\\') av_bprintf(buf, "{\\b1}");
+            else if (*p == '_')  av_bprintf(buf, "{\\u1}");
+            got_style = 1;
+            p++;
+        }
+
+        while (*p && *p != '|') {
+            if (*p != '\r' && *p != '\n')
+                av_bprint_chars(buf, *p, 1);
+            p++;
+        }
+
+        if (*p == '|') {
+            if (got_style)
+                av_bprintf(buf, "{\\r}");
+            av_bprintf(buf, "\\N");
+            p++;
+        }
+    }
+
+    av_bprintf(buf, "\r\n");
+    return 0;
+}
+
+static int mpl2_decode_frame(AVCodecContext *avctx, void *data,
+                             int *got_sub_ptr, AVPacket *avpkt)
+{
+    AVBPrint buf;
+    AVSubtitle *sub = data;
+    const char *ptr = avpkt->data;
+    const int ts_start     = av_rescale_q(avpkt->pts,      avctx->time_base, (AVRational){1,100});
+    const int ts_duration  = avpkt->duration != -1 ?
+                             av_rescale_q(avpkt->duration, avctx->time_base, (AVRational){1,100}) : -1;
+
+    av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
+    if (ptr && avpkt->size > 0 && *ptr && !mpl2_event_to_ass(&buf, ptr)) {
+        if (!av_bprint_is_complete(&buf)) {
+            av_bprint_finalize(&buf, NULL);
+            return AVERROR(ENOMEM);
+        }
+        ff_ass_add_rect(sub, buf.str, ts_start, ts_duration, 0);
+    }
+    *got_sub_ptr = sub->num_rects > 0;
+    av_bprint_finalize(&buf, NULL);
+    return avpkt->size;
+}
+
+AVCodec ff_mpl2_decoder = {
+    .name           = "mpl2",
+    .long_name      = NULL_IF_CONFIG_SMALL("MPL2 subtitle"),
+    .type           = AVMEDIA_TYPE_SUBTITLE,
+    .id             = AV_CODEC_ID_MPL2,
+    .decode         = mpl2_decode_frame,
+    .init           = ff_ass_subtitle_header_default,
+};
diff --git a/libavcodec/msmpeg4.c b/libavcodec/msmpeg4.c
index e80db6d..278c5fc 100644
--- a/libavcodec/msmpeg4.c
+++ b/libavcodec/msmpeg4.c
@@ -404,7 +404,7 @@
     return val;
 }
 
-static int msmpeg4v12_decode_mb(MpegEncContext *s, DCTELEM block[6][64])
+static int msmpeg4v12_decode_mb(MpegEncContext *s, int16_t block[6][64])
 {
     int cbp, code, i;
     uint32_t * const mb_type_ptr = &s->current_picture.f.mb_type[s->mb_x + s->mb_y*s->mb_stride];
@@ -494,7 +494,7 @@
     return 0;
 }
 
-static int msmpeg4v34_decode_mb(MpegEncContext *s, DCTELEM block[6][64])
+static int msmpeg4v34_decode_mb(MpegEncContext *s, int16_t block[6][64])
 {
     int cbp, code, i;
     uint8_t *coded_val;
@@ -938,7 +938,7 @@
 }
 
 //#define ERROR_DETAILS
-int ff_msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
+int ff_msmpeg4_decode_block(MpegEncContext * s, int16_t * block,
                               int n, int coded, const uint8_t *scan_table)
 {
     int level, i, last, run, run_diff;
@@ -1145,6 +1145,7 @@
                 const int left= get_bits_left(&s->gb);
                 if(((i+192 == 64 && level/qmul==-1) || !(s->err_recognition&(AV_EF_BITSTREAM|AV_EF_COMPLIANT))) && left>=0){
                     av_log(s->avctx, AV_LOG_ERROR, "ignoring overflow at %d %d\n", s->mb_x, s->mb_y);
+                    i = 63;
                     break;
                 }else{
                     av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
diff --git a/libavcodec/msmpeg4.h b/libavcodec/msmpeg4.h
index abc414c..a723888 100644
--- a/libavcodec/msmpeg4.h
+++ b/libavcodec/msmpeg4.h
@@ -26,7 +26,6 @@
 
 #include "config.h"
 #include "avcodec.h"
-#include "dsputil.h"
 #include "mpegvideo.h"
 #include "msmpeg4data.h"
 #include "put_bits.h"
@@ -45,17 +44,17 @@
 
 void ff_msmpeg4_code012(PutBitContext *pb, int n);
 void ff_msmpeg4_common_init(MpegEncContext *s);
-void ff_msmpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n);
+void ff_msmpeg4_encode_block(MpegEncContext * s, int16_t * block, int n);
 void ff_msmpeg4_handle_slices(MpegEncContext *s);
 void ff_msmpeg4_encode_motion(MpegEncContext * s, int mx, int my);
 int ff_msmpeg4_coded_block_pred(MpegEncContext * s, int n,
                                 uint8_t **coded_block_ptr);
 int ff_msmpeg4_decode_motion(MpegEncContext * s, int *mx_ptr, int *my_ptr);
-int ff_msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
+int ff_msmpeg4_decode_block(MpegEncContext * s, int16_t * block,
                             int n, int coded, const uint8_t *scan_table);
 int ff_msmpeg4_pred_dc(MpegEncContext *s, int n,
                        int16_t **dc_val_ptr, int *dir_ptr);
-int ff_wmv2_decode_mb(MpegEncContext *s, DCTELEM block[6][64]);
+int ff_wmv2_decode_mb(MpegEncContext *s, int16_t block[6][64]);
 
 #define CONFIG_MSMPEG4_DECODER (CONFIG_MSMPEG4V1_DECODER || \
                                 CONFIG_MSMPEG4V2_DECODER || \
diff --git a/libavcodec/msmpeg4enc.c b/libavcodec/msmpeg4enc.c
index 458ec09..82e6646 100644
--- a/libavcodec/msmpeg4enc.c
+++ b/libavcodec/msmpeg4enc.c
@@ -369,7 +369,7 @@
 }
 
 void ff_msmpeg4_encode_mb(MpegEncContext * s,
-                          DCTELEM block[6][64],
+                          int16_t block[6][64],
                           int motion_x, int motion_y)
 {
     int cbp, coded_cbp, i;
@@ -494,7 +494,7 @@
 static void msmpeg4_encode_dc(MpegEncContext * s, int level, int n, int *dir_ptr)
 {
     int sign, code;
-    int pred, extquant;
+    int pred, av_uninit(extquant);
     int extrabits = 0;
 
     int16_t *dc_val;
@@ -570,7 +570,7 @@
 /* Encoding of a block. Very similar to MPEG4 except for a different
    escape coding (same as H263) and more vlc tables.
  */
-void ff_msmpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n)
+void ff_msmpeg4_encode_block(MpegEncContext * s, int16_t * block, int n)
 {
     int level, run, last, i, j, last_index;
     int last_non_zero, sign, slevel;
diff --git a/libavcodec/msrle.c b/libavcodec/msrle.c
index 2792f8b..7187d1a 100644
--- a/libavcodec/msrle.c
+++ b/libavcodec/msrle.c
@@ -33,7 +33,6 @@
 #include <string.h>
 
 #include "avcodec.h"
-#include "dsputil.h"
 #include "msrledec.h"
 
 typedef struct MsrleContext {
@@ -67,36 +66,37 @@
         break;
     default:
         av_log(avctx, AV_LOG_ERROR, "unsupported bits per sample\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     avcodec_get_frame_defaults(&s->frame);
     s->frame.data[0] = NULL;
 
-    if (avctx->extradata_size >= AVPALETTE_SIZE)
-        for (i = 0; i < AVPALETTE_SIZE/4; i++)
+    if (avctx->extradata_size >= 4)
+        for (i = 0; i < FFMIN(avctx->extradata_size, AVPALETTE_SIZE)/4; i++)
             s->pal[i] = 0xFFU<<24 | AV_RL32(avctx->extradata+4*i);
 
     return 0;
 }
 
 static int msrle_decode_frame(AVCodecContext *avctx,
-                              void *data, int *data_size,
+                              void *data, int *got_frame,
                               AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     MsrleContext *s = avctx->priv_data;
     int istride = FFALIGN(avctx->width*avctx->bits_per_coded_sample, 32) / 8;
+    int ret;
 
     s->buf = buf;
     s->size = buf_size;
 
     s->frame.reference = 3;
     s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if (avctx->reget_buffer(avctx, &s->frame)) {
+    if ((ret = avctx->reget_buffer(avctx, &s->frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     if (avctx->bits_per_coded_sample > 1 && avctx->bits_per_coded_sample <= 8) {
@@ -136,7 +136,7 @@
         ff_msrle_decode(avctx, (AVPicture*)&s->frame, avctx->bits_per_coded_sample, &s->gb);
     }
 
-    *data_size = sizeof(AVFrame);
+    *got_frame      = 1;
     *(AVFrame*)data = s->frame;
 
     /* report that the buffer was completely consumed */
diff --git a/libavcodec/msrledec.c b/libavcodec/msrledec.c
index 36a46b5..cd0a73d 100644
--- a/libavcodec/msrledec.c
+++ b/libavcodec/msrledec.c
@@ -144,8 +144,7 @@
         if(p1 == 0) { //Escape code
             p2 = bytestream2_get_byte(gb);
             if(p2 == 0) { //End-of-line
-                output = pic->data[0] + (--line) * pic->linesize[0];
-                if (line < 0) {
+                if (--line < 0) {
                     if (bytestream2_get_be16(gb) == 1) { // end-of-picture
                         return 0;
                     } else {
@@ -155,6 +154,7 @@
                         return AVERROR_INVALIDDATA;
                     }
                 }
+                output = pic->data[0] + line * pic->linesize[0];
                 pos = 0;
                 continue;
             } else if(p2 == 1) { //End-of-picture
@@ -203,36 +203,40 @@
             pos += p2;
         } else { //run of pixels
             uint8_t pix[3]; //original pixel
-            switch(depth){
-            case  8: pix[0] = bytestream2_get_byte(gb);
-                     break;
-            case 16: pix16  = bytestream2_get_le16(gb);
-                     break;
-            case 24: pix[0] = bytestream2_get_byte(gb);
-                     pix[1] = bytestream2_get_byte(gb);
-                     pix[2] = bytestream2_get_byte(gb);
-                     break;
-            case 32: pix32  = bytestream2_get_le32(gb);
-                     break;
-            }
             if ((pic->linesize[0] > 0 && output + p1 * (depth >> 3) > output_end) ||
                 (pic->linesize[0] < 0 && output + p1 * (depth >> 3) < output_end))
                 continue;
-            for(i = 0; i < p1; i++) {
-                switch(depth){
-                case  8: *output++ = pix[0];
-                         break;
-                case 16: *(uint16_t*)output = pix16;
-                         output += 2;
-                         break;
-                case 24: *output++ = pix[0];
-                         *output++ = pix[1];
-                         *output++ = pix[2];
-                         break;
-                case 32: *(uint32_t*)output = pix32;
-                         output += 4;
-                         break;
+
+            switch(depth){
+            case  8:
+                pix[0] = bytestream2_get_byte(gb);
+                for(i = 0; i < p1; i++)
+                        *output++ = pix[0];
+                break;
+            case 16:
+                pix16  = bytestream2_get_le16(gb);
+                for(i = 0; i < p1; i++) {
+                        *(uint16_t*)output = pix16;
+                        output += 2;
                 }
+                break;
+            case 24:
+                pix[0] = bytestream2_get_byte(gb);
+                pix[1] = bytestream2_get_byte(gb);
+                pix[2] = bytestream2_get_byte(gb);
+                for(i = 0; i < p1; i++) {
+                        *output++ = pix[0];
+                        *output++ = pix[1];
+                        *output++ = pix[2];
+                }
+                break;
+            case 32:
+                pix32  = bytestream2_get_le32(gb);
+                for(i = 0; i < p1; i++) {
+                        *(uint32_t*)output = pix32;
+                        output += 4;
+                }
+                break;
             }
             pos += p1;
         }
diff --git a/libavcodec/mss1.c b/libavcodec/mss1.c
index 6a55b4f..446339b 100644
--- a/libavcodec/mss1.c
+++ b/libavcodec/mss1.c
@@ -135,7 +135,7 @@
     return !!ncol;
 }
 
-static int mss1_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+static int mss1_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                              AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
@@ -180,7 +180,7 @@
     memcpy(ctx->pic.data[1], c->pal, AVPALETTE_SIZE);
     ctx->pic.palette_has_changed = pal_changed;
 
-    *data_size = sizeof(AVFrame);
+    *got_frame      = 1;
     *(AVFrame*)data = ctx->pic;
 
     /* always report that the buffer was completely consumed */
diff --git a/libavcodec/mss12.c b/libavcodec/mss12.c
index 59294b8..b522e4a 100644
--- a/libavcodec/mss12.c
+++ b/libavcodec/mss12.c
@@ -586,6 +586,11 @@
                avctx->coded_width, avctx->coded_height);
         return AVERROR_INVALIDDATA;
     }
+    if (avctx->coded_width < 1 || avctx->coded_height < 1) {
+        av_log(avctx, AV_LOG_ERROR, "Frame dimensions %dx%d too small",
+               avctx->coded_width, avctx->coded_height);
+        return AVERROR_INVALIDDATA;
+    }
 
     av_log(avctx, AV_LOG_DEBUG, "Encoder version %d.%d\n",
            AV_RB32(avctx->extradata + 4), AV_RB32(avctx->extradata + 8));
diff --git a/libavcodec/mss12.h b/libavcodec/mss12.h
index 42ceab5..a3f9a7c 100644
--- a/libavcodec/mss12.h
+++ b/libavcodec/mss12.h
@@ -95,9 +95,9 @@
                          int x, int y, int width, int height);
 void ff_mss12_model_update(Model *m, int val);
 void ff_mss12_slicecontext_reset(SliceContext *sc);
-av_cold int ff_mss12_decode_init(MSS12Context *c, int version,
-                                 SliceContext* sc1, SliceContext *sc2);
-av_cold int ff_mss12_decode_end(MSS12Context *ctx);
+int ff_mss12_decode_init(MSS12Context *c, int version,
+                         SliceContext *sc1, SliceContext *sc2);
+int ff_mss12_decode_end(MSS12Context *ctx);
 
 #define ARITH_GET_BIT(VERSION)                                          \
 static int arith ## VERSION ## _get_bit(ArithCoder *c)                  \
diff --git a/libavcodec/mss2.c b/libavcodec/mss2.c
index caeb800..afdf33c 100644
--- a/libavcodec/mss2.c
+++ b/libavcodec/mss2.c
@@ -24,6 +24,7 @@
  */
 
 #include "libavutil/avassert.h"
+#include "internal.h"
 #include "msmpeg4data.h"
 #include "vc1.h"
 #include "mss12.h"
@@ -162,7 +163,7 @@
 
     ncol = *buf++;
     if (ncol > ctx->free_colours || buf_size < 2 + ncol * 3)
-        return -1;
+        return AVERROR_INVALIDDATA;
     for (i = 0; i < ncol; i++)
         *pal++ = AV_RB24(buf + 3 * i);
 
@@ -188,7 +189,7 @@
         READ_PAIR(y, endy)
 
         if (endx >= w || endy >= h || x > endx || y > endy)
-            return -1;
+            return AVERROR_INVALIDDATA;
         dst += x + stride * y;
         w    = endx - x + 1;
         h    = endy - y + 1;
@@ -372,13 +373,14 @@
     VC1Context *v     = avctx->priv_data;
     MpegEncContext *s = &v->s;
     AVFrame *f;
+    int ret;
 
     ff_mpeg_flush(avctx);
 
     if (s->current_picture_ptr == NULL || s->current_picture_ptr->f.data[0]) {
         int i = ff_find_unused_picture(s, 0);
         if (i < 0)
-            return -1;
+            return i;
         s->current_picture_ptr = &s->picture[i];
     }
 
@@ -398,13 +400,13 @@
 
     avctx->pix_fmt = AV_PIX_FMT_YUV420P;
 
-    if (ff_MPV_frame_start(s, avctx) < 0) {
+    if ((ret = ff_MPV_frame_start(s, avctx)) < 0) {
         av_log(v->s.avctx, AV_LOG_ERROR, "ff_MPV_frame_start error\n");
         avctx->pix_fmt = AV_PIX_FMT_RGB24;
-        return -1;
+        return ret;
     }
 
-    ff_er_frame_start(s);
+    ff_mpeg_er_frame_start(s);
 
     v->bits = buf_size * 8;
 
@@ -417,7 +419,7 @@
 
     ff_vc1_decode_blocks(v);
 
-    ff_er_frame_end(s);
+    ff_er_frame_end(&s->er);
 
     ff_MPV_frame_end(s);
 
@@ -460,7 +462,7 @@
 #define MAX_WMV9_RECTANGLES 20
 #define ARITH2_PADDING 2
 
-static int mss2_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+static int mss2_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                              AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
@@ -605,7 +607,7 @@
                                 FF_BUFFER_HINTS_PRESERVE |
                                 FF_BUFFER_HINTS_REUSABLE;
 
-        if ((ret = avctx->get_buffer(avctx, &ctx->pic)) < 0) {
+        if ((ret = ff_get_buffer(avctx, &ctx->pic)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
             return ret;
         }
@@ -616,7 +618,7 @@
                               ctx->last_pic.linesize[0] * (avctx->height - 1);
         } else {
             av_log(avctx, AV_LOG_ERROR, "Missing keyframe\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
     } else {
         if (ctx->last_pic.data[0])
@@ -743,7 +745,7 @@
     if (buf_size)
         av_log(avctx, AV_LOG_WARNING, "buffer not fully consumed\n");
 
-    *data_size       = sizeof(AVFrame);
+    *got_frame       = 1;
     *(AVFrame *)data = ctx->pic;
 
     return avpkt->size;
@@ -752,16 +754,14 @@
 static av_cold int wmv9_init(AVCodecContext *avctx)
 {
     VC1Context *v = avctx->priv_data;
+    int ret;
 
     v->s.avctx    = avctx;
     avctx->flags |= CODEC_FLAG_EMU_EDGE;
     v->s.flags   |= CODEC_FLAG_EMU_EDGE;
 
-    if (avctx->idct_algo == FF_IDCT_AUTO)
-        avctx->idct_algo = FF_IDCT_WMV2;
-
-    if (ff_vc1_init_common(v) < 0)
-        return -1;
+    if ((ret = ff_vc1_init_common(v)) < 0)
+        return ret;
     ff_vc1dsp_init(&v->vc1dsp);
 
     v->profile = PROFILE_MAIN;
@@ -801,9 +801,9 @@
 
     ff_vc1_init_transposed_scantables(v);
 
-    if (ff_msmpeg4_decode_init(avctx) < 0 ||
-        ff_vc1_decode_init_alloc_tables(v) < 0)
-        return -1;
+    if ((ret = ff_msmpeg4_decode_init(avctx)) < 0 ||
+        (ret = ff_vc1_decode_init_alloc_tables(v)) < 0)
+        return ret;
 
     /* error concealment */
     v->s.me.qpel_put = v->s.dsp.put_qpel_pixels_tab;
diff --git a/libavcodec/mss2dsp.h b/libavcodec/mss2dsp.h
index e04aab0..7368abb 100644
--- a/libavcodec/mss2dsp.h
+++ b/libavcodec/mss2dsp.h
@@ -26,7 +26,7 @@
 #ifndef AVCODEC_MSS2DSP_H
 #define AVCODEC_MSS2DSP_H
 
-#include "dsputil.h"
+#include <stdint.h>
 
 typedef struct MSS2DSPContext {
     void (*mss2_blit_wmv9)(uint8_t *dst, int dst_stride,
@@ -45,6 +45,6 @@
     void (*upsample_plane)(uint8_t *plane, int plane_stride, int w, int h);
 } MSS2DSPContext;
 
-av_cold void ff_mss2dsp_init(MSS2DSPContext* dsp);
+void ff_mss2dsp_init(MSS2DSPContext *dsp);
 
 #endif /* AVCODEC_MSS2DSP_H */
diff --git a/libavcodec/mss3.c b/libavcodec/mss3.c
index 91aceb2..d5bb2d4 100644
--- a/libavcodec/mss3.c
+++ b/libavcodec/mss3.c
@@ -295,7 +295,7 @@
             c->low |= *c->src++;
         } else if (!c->low) {
             c->got_error = 1;
-            return;
+            c->low = 1;
         }
         if (c->range >= RAC_BOTTOM)
             return;
@@ -674,7 +674,7 @@
     }
 }
 
-static int mss3_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+static int mss3_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                              AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
@@ -740,7 +740,7 @@
     c->pic.key_frame = keyframe;
     c->pic.pict_type = keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
     if (!bytestream2_get_bytes_left(&gb)) {
-        *data_size = sizeof(AVFrame);
+        *got_frame      = 1;
         *(AVFrame*)data = c->pic;
 
         return buf_size;
@@ -798,7 +798,7 @@
         dst[2] += c->pic.linesize[2] * 8;
     }
 
-    *data_size = sizeof(AVFrame);
+    *got_frame      = 1;
     *(AVFrame*)data = c->pic;
 
     return buf_size;
diff --git a/libavcodec/mss4.c b/libavcodec/mss4.c
index 51db721..977e1e5 100644
--- a/libavcodec/mss4.c
+++ b/libavcodec/mss4.c
@@ -126,7 +126,6 @@
 
 typedef struct MSS4Context {
     AVFrame    pic;
-    DSPContext dsp;
 
     VLC        dc_vlc[2], ac_vlc[2];
     VLC        vec_entry_vlc[2];
@@ -506,7 +505,7 @@
     }
 }
 
-static int mss4_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+static int mss4_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                              AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
@@ -566,7 +565,7 @@
     c->pic.pict_type = (frame_type == INTRA_FRAME) ? AV_PICTURE_TYPE_I
                                                    : AV_PICTURE_TYPE_P;
     if (frame_type == SKIP_FRAME) {
-        *data_size = sizeof(AVFrame);
+        *got_frame      = 1;
         *(AVFrame*)data = c->pic;
 
         return buf_size;
@@ -623,7 +622,7 @@
         dst[2] += c->pic.linesize[2] * 16;
     }
 
-    *data_size = sizeof(AVFrame);
+    *got_frame      = 1;
     *(AVFrame*)data = c->pic;
 
     return buf_size;
diff --git a/libavcodec/msvideo1.c b/libavcodec/msvideo1.c
index 8d1164b..fd98b31 100644
--- a/libavcodec/msvideo1.c
+++ b/libavcodec/msvideo1.c
@@ -287,7 +287,7 @@
 }
 
 static int msvideo1_decode_frame(AVCodecContext *avctx,
-                                void *data, int *data_size,
+                                void *data, int *got_frame,
                                 AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
@@ -318,7 +318,7 @@
     else
         msvideo1_decode_16bit(s);
 
-    *data_size = sizeof(AVFrame);
+    *got_frame      = 1;
     *(AVFrame*)data = s->frame;
 
     /* report that the buffer was completely consumed */
diff --git a/libavcodec/mvcdec.c b/libavcodec/mvcdec.c
new file mode 100644
index 0000000..5131ae2
--- /dev/null
+++ b/libavcodec/mvcdec.c
@@ -0,0 +1,287 @@
+/*
+ * Silicon Graphics Motion Video Compressor 1 & 2 decoder
+ * Copyright (c) 2012 Peter Ross
+ *
+ * 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
+ * Silicon Graphics Motion Video Compressor 1 & 2 decoder
+ */
+
+#include "libavutil/intreadwrite.h"
+#include "avcodec.h"
+#include "bytestream.h"
+
+typedef struct MvcContext {
+    int vflip;
+} MvcContext;
+
+static av_cold int mvc_decode_init(AVCodecContext *avctx)
+{
+    MvcContext *s = avctx->priv_data;
+    int width  = avctx->width;
+    int height = avctx->height;
+
+    if (avctx->codec_id == AV_CODEC_ID_MVC1) {
+        width  += 3;
+        height += 3;
+    }
+    width  &= ~3;
+    height &= ~3;
+    if (width != avctx->width || height != avctx->height)
+        avcodec_set_dimensions(avctx, width, height);
+
+    avctx->pix_fmt = (avctx->codec_id == AV_CODEC_ID_MVC1) ? AV_PIX_FMT_RGB555 : AV_PIX_FMT_BGRA;
+    avctx->coded_frame = avcodec_alloc_frame();
+    if (!avctx->coded_frame)
+        return AVERROR(ENOMEM);
+
+    s->vflip = avctx->extradata_size >= 9 && !memcmp(avctx->extradata + avctx->extradata_size - 9, "BottomUp", 9);
+    return 0;
+}
+
+static int decode_mvc1(AVCodecContext *avctx, GetByteContext *gb, uint8_t *dst_start, int width, int height, int linesize)
+{
+    uint8_t *dst;
+    uint16_t v[8];
+    int mask, x, y, i;
+
+    x = y= 0;
+    while (bytestream2_get_bytes_left(gb) >= 6) {
+        mask = bytestream2_get_be16u(gb);
+        v[0] = bytestream2_get_be16u(gb);
+        v[1] = bytestream2_get_be16u(gb);
+        if ((v[0] & 0x8000)) {
+            if (bytestream2_get_bytes_left(gb) < 12) {
+                av_log(avctx, AV_LOG_WARNING, "buffer overflow\n");
+                return AVERROR_INVALIDDATA;
+            }
+            for (i = 2; i < 8; i++)
+                v[i] = bytestream2_get_be16u(gb);
+        } else {
+            v[2] = v[4] = v[6] = v[0];
+            v[3] = v[5] = v[7] = v[1];
+        }
+
+#define PIX16(target, true, false) \
+        i = (mask & target) ? true : false; \
+        AV_WN16A(dst, (v[i] & 0x7C00) | (v[i] & 0x3E0) | (v[i] & 0x1F)); \
+        dst += 2;
+
+#define ROW16(row, a1, a0, b1, b0) \
+        dst = dst_start + (y + row) * linesize + x * 2; \
+        PIX16(1 << (row * 4),     a1, a0) \
+        PIX16(1 << (row * 4 + 1), a1, a0) \
+        PIX16(1 << (row * 4 + 2), b1, b0) \
+        PIX16(1 << (row * 4 + 3), b1, b0)
+
+        ROW16(0, 0, 1, 2, 3);
+        ROW16(1, 0, 1, 2, 3);
+        ROW16(2, 4, 5, 6, 7);
+        ROW16(3, 4, 5, 6, 7);
+
+        x += 4;
+        if (x >= width) {
+            y += 4;
+            if (y >= height) {
+                break;
+            }
+            x = 0;
+        }
+    }
+    return 0;
+}
+
+static void set_4x4_block(uint8_t *dst, int linesize, uint32_t pixel)
+{
+    int i, j;
+    for (j = 0; j < 4; j++)
+        for (i = 0; i < 4; i++)
+            AV_WN32A(dst + j * linesize + i * 4, pixel);
+}
+
+#define PIX32(target, true, false) \
+    AV_WN32A(dst, (mask & target) ? v[true] : v[false]); \
+    dst += 4;
+
+#define ROW32(row, a1, a0, b1, b0) \
+    dst = dst_start + (y + row) * linesize + x * 4; \
+    PIX32(1 << (row * 4),     a1, a0) \
+    PIX32(1 << (row * 4 + 1), a1, a0) \
+    PIX32(1 << (row * 4 + 2), b1, b0) \
+    PIX32(1 << (row * 4 + 3), b1, b0)
+
+#define MVC2_BLOCK \
+    ROW32(0, 1, 0, 3, 2); \
+    ROW32(1, 1, 0, 3, 2); \
+    ROW32(2, 5, 4, 7, 6); \
+    ROW32(3, 5, 4, 7, 6);
+
+static int decode_mvc2(AVCodecContext *avctx, GetByteContext *gb, uint8_t *dst_start, int width, int height, int linesize, int vflip)
+{
+    uint8_t *dst;
+    uint32_t color[128], v[8];
+    int w, h, nb_colors, i, x, y, p0, p1, mask;
+
+    if (bytestream2_get_bytes_left(gb) < 6)
+        return AVERROR_INVALIDDATA;
+
+    w = bytestream2_get_be16u(gb);
+    h = bytestream2_get_be16u(gb);
+    if ((w & ~3) != width || (h & ~3) != height)
+        av_log(avctx, AV_LOG_WARNING, "dimension mismatch\n");
+
+    if (bytestream2_get_byteu(gb)) {
+        av_log_ask_for_sample(avctx, "bitmap feature\n");
+        return AVERROR_PATCHWELCOME;
+    }
+
+    nb_colors = bytestream2_get_byteu(gb);
+    if (bytestream2_get_bytes_left(gb) < nb_colors * 3)
+        return AVERROR_INVALIDDATA;
+    for (i = 0; i < FFMIN(nb_colors, 128); i++)
+        color[i] = 0xFF000000 | bytestream2_get_be24u(gb);
+    if (nb_colors > 128)
+        bytestream2_skip(gb, (nb_colors - 128) * 3);
+
+    if (vflip) {
+        dst_start += (height - 1) * linesize;
+        linesize = -linesize;
+    }
+    x = y = 0;
+    while (bytestream2_get_bytes_left(gb) >= 1) {
+        p0 = bytestream2_get_byteu(gb);
+        if ((p0 & 0x80)) {
+            if ((p0 & 0x40)) {
+                p0 &= 0x3F;
+                p0 = (p0 << 2) | (p0 >> 4);
+                set_4x4_block(dst_start + y * linesize + x * 4, linesize, 0xFF000000 | (p0 << 16) | (p0 << 8) | p0);
+            } else {
+                int g, r;
+                p0 &= 0x3F;
+                p0 = (p0 << 2) | (p0 >> 4);
+                if (bytestream2_get_bytes_left(gb) < 2)
+                    return AVERROR_INVALIDDATA;
+                g = bytestream2_get_byteu(gb);
+                r = bytestream2_get_byteu(gb);
+                set_4x4_block(dst_start + y * linesize + x * 4, linesize, 0xFF000000 | (r << 16) | (g << 8) | p0);
+            }
+        } else {
+            if (bytestream2_get_bytes_left(gb) < 1)
+                return AVERROR_INVALIDDATA;
+            p1 = bytestream2_get_byteu(gb);
+            if ((p1 & 0x80)) {
+                if ((p0 & 0x7F) == (p1 & 0x7F)) {
+                    set_4x4_block(dst_start + y * linesize + x * 4, linesize, color[p0 & 0x7F]);
+                } else {
+                    if (bytestream2_get_bytes_left(gb) < 2)
+                        return AVERROR_INVALIDDATA;
+                    v[0] = v[2] = v[4] = v[6] = color[p0 & 0x7F];
+                    v[1] = v[3] = v[5] = v[7] = color[p1 & 0x7F];
+                    mask = bytestream2_get_le16u(gb);
+                    MVC2_BLOCK
+                }
+            } else {
+                if (bytestream2_get_bytes_left(gb) < 8)
+                    return AVERROR_INVALIDDATA;
+                v[0] = color[p0 & 0x7F];
+                v[1] = color[p1 & 0x7F];
+                for (i = 2; i < 8; i++)
+                    v[i] = color[bytestream2_get_byteu(gb) & 0x7F];
+                mask = bytestream2_get_le16u(gb);
+                MVC2_BLOCK
+            }
+        }
+
+        x += 4;
+        if (x >= width) {
+            y += 4;
+            if (y >= height)
+                break;
+            x = 0;
+        }
+    }
+    return 0;
+}
+
+static int mvc_decode_frame(AVCodecContext *avctx,
+                            void *data, int *got_frame,
+                            AVPacket *avpkt)
+{
+    MvcContext *s = avctx->priv_data;
+    GetByteContext gb;
+    int ret;
+
+    avctx->coded_frame->reference = 3;
+    avctx->coded_frame->buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE |
+                            FF_BUFFER_HINTS_REUSABLE | FF_BUFFER_HINTS_READABLE;
+    ret = avctx->reget_buffer(avctx, avctx->coded_frame);
+    if (ret < 0) {
+        av_log (avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
+        return AVERROR(ENOMEM);
+    }
+
+    bytestream2_init(&gb, avpkt->data, avpkt->size);
+    if (avctx->codec_id == AV_CODEC_ID_MVC1)
+        ret = decode_mvc1(avctx, &gb, avctx->coded_frame->data[0], avctx->width, avctx->height, avctx->coded_frame->linesize[0]);
+    else
+        ret = decode_mvc2(avctx, &gb, avctx->coded_frame->data[0], avctx->width, avctx->height, avctx->coded_frame->linesize[0], s->vflip);
+    if (ret < 0)
+        return ret;
+
+    *got_frame      = 1;
+    *(AVFrame*)data = *avctx->coded_frame;
+    return avpkt->size;
+}
+
+static av_cold int mvc_decode_end(AVCodecContext *avctx)
+{
+    if (avctx->coded_frame->data[0])
+        avctx->release_buffer(avctx, avctx->coded_frame);
+    av_freep(&avctx->coded_frame);
+    return 0;
+}
+
+#if CONFIG_MVC1_DECODER
+AVCodec ff_mvc1_decoder = {
+    .name           = "mvc1",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_MVC1,
+    .priv_data_size = sizeof(MvcContext),
+    .init           = mvc_decode_init,
+    .close          = mvc_decode_end,
+    .decode         = mvc_decode_frame,
+    .capabilities   = CODEC_CAP_DR1,
+    .long_name      = NULL_IF_CONFIG_SMALL("Silicon Graphics Motion Video Compressor 1"),
+};
+#endif
+
+#if CONFIG_MVC2_DECODER
+AVCodec ff_mvc2_decoder = {
+    .name           = "mvc2",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_MVC2,
+    .priv_data_size = sizeof(MvcContext),
+    .init           = mvc_decode_init,
+    .close          = mvc_decode_end,
+    .decode         = mvc_decode_frame,
+    .capabilities   = CODEC_CAP_DR1,
+    .long_name      = NULL_IF_CONFIG_SMALL("Silicon Graphics Motion Video Compressor 2"),
+};
+#endif
diff --git a/libavcodec/mxpegdec.c b/libavcodec/mxpegdec.c
index c1e1512..59d41b6 100644
--- a/libavcodec/mxpegdec.c
+++ b/libavcodec/mxpegdec.c
@@ -25,6 +25,7 @@
  * MxPEG decoder
  */
 
+#include "internal.h"
 #include "mjpeg.h"
 #include "mjpegdec.h"
 
@@ -156,7 +157,7 @@
 }
 
 static int mxpeg_decode_frame(AVCodecContext *avctx,
-                          void *data, int *data_size,
+                          void *data, int *got_frame,
                           AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
@@ -250,7 +251,7 @@
                     /* use stored SOF data to allocate current picture */
                     if (jpg->picture_ptr->data[0])
                         avctx->release_buffer(avctx, jpg->picture_ptr);
-                    if (avctx->get_buffer(avctx, jpg->picture_ptr) < 0) {
+                    if (ff_get_buffer(avctx, jpg->picture_ptr) < 0) {
                         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
                         return AVERROR(ENOMEM);
                     }
@@ -269,7 +270,7 @@
 
                     /* allocate dummy reference picture if needed */
                     if (!reference_ptr->data[0] &&
-                        avctx->get_buffer(avctx, reference_ptr) < 0) {
+                        ff_get_buffer(avctx, reference_ptr) < 0) {
                         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
                         return AVERROR(ENOMEM);
                     }
@@ -293,7 +294,7 @@
 
 the_end:
     if (jpg->got_picture) {
-        *data_size = sizeof(AVFrame);
+        *got_frame = 1;
         *picture = *jpg->picture_ptr;
         s->picture_index ^= 1;
         jpg->picture_ptr = &s->picture[s->picture_index];
@@ -302,7 +303,7 @@
             if (!s->got_mxm_bitmask)
                 s->has_complete_frame = 1;
             else
-                *data_size = 0;
+                *got_frame = 0;
         }
     }
 
diff --git a/libavcodec/nellymoser.c b/libavcodec/nellymoser.c
index 195e2e8..0740c75 100644
--- a/libavcodec/nellymoser.c
+++ b/libavcodec/nellymoser.c
@@ -33,7 +33,6 @@
 
 #include "nellymoser.h"
 #include "avcodec.h"
-#include "dsputil.h"
 
 #define BITSTREAM_READER_LE
 #include "get_bits.h"
diff --git a/libavcodec/nellymoserdec.c b/libavcodec/nellymoserdec.c
index b4823a8..4b4b61c 100644
--- a/libavcodec/nellymoserdec.c
+++ b/libavcodec/nellymoserdec.c
@@ -32,12 +32,13 @@
  */
 
 #include "libavutil/channel_layout.h"
+#include "libavutil/float_dsp.h"
 #include "libavutil/lfg.h"
 #include "libavutil/random_seed.h"
 #include "avcodec.h"
-#include "dsputil.h"
 #include "fft.h"
 #include "fmtconvert.h"
+#include "internal.h"
 #include "nellymoser.h"
 #include "sinewin.h"
 
@@ -47,11 +48,10 @@
 
 typedef struct NellyMoserDecodeContext {
     AVCodecContext* avctx;
-    AVFrame         frame;
     AVLFG           random_state;
     GetBitContext   gb;
     float           scale_bias;
-    DSPContext      dsp;
+    AVFloatDSPContext fdsp;
     FFTContext      imdct_ctx;
     DECLARE_ALIGNED(32, float, imdct_buf)[2][NELLY_BUF_LEN];
     float          *imdct_out;
@@ -106,7 +106,9 @@
                (NELLY_BUF_LEN - NELLY_FILL_LEN) * sizeof(float));
 
         s->imdct_ctx.imdct_half(&s->imdct_ctx, s->imdct_out, aptr);
-        s->dsp.vector_fmul_window(aptr, s->imdct_prev + NELLY_BUF_LEN/2, s->imdct_out, ff_sine_128, NELLY_BUF_LEN/2);
+        s->fdsp.vector_fmul_window(aptr, s->imdct_prev + NELLY_BUF_LEN / 2,
+                                   s->imdct_out, ff_sine_128,
+                                   NELLY_BUF_LEN / 2);
         FFSWAP(float *, s->imdct_out, s->imdct_prev);
     }
 }
@@ -120,7 +122,7 @@
     av_lfg_init(&s->random_state, 0);
     ff_mdct_init(&s->imdct_ctx, 8, 1, 1.0);
 
-    ff_dsputil_init(&s->dsp, avctx);
+    avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
 
     s->scale_bias = 1.0/(32768*8);
     avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
@@ -132,15 +134,13 @@
     avctx->channels       = 1;
     avctx->channel_layout = AV_CH_LAYOUT_MONO;
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     return 0;
 }
 
 static int decode_tag(AVCodecContext *avctx, void *data,
                       int *got_frame_ptr, AVPacket *avpkt)
 {
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     const uint8_t *side=av_packet_get_side_data(avpkt, 'F', NULL);
     int buf_size = avpkt->size;
@@ -170,12 +170,12 @@
         avctx->sample_rate= 11025*(blocks/2);
 
     /* get output buffer */
-    s->frame.nb_samples = NELLY_SAMPLES * blocks;
-    if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = NELLY_SAMPLES * blocks;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    samples_flt = (float   *)s->frame.data[0];
+    samples_flt = (float *)frame->data[0];
 
     for (i=0 ; i<blocks ; i++) {
         nelly_decode_block(s, buf, samples_flt);
@@ -183,8 +183,7 @@
         buf += NELLY_BLOCK_LEN;
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
+    *got_frame_ptr = 1;
 
     return buf_size;
 }
diff --git a/libavcodec/nellymoserenc.c b/libavcodec/nellymoserenc.c
index 4317e32..121bd38 100644
--- a/libavcodec/nellymoserenc.c
+++ b/libavcodec/nellymoserenc.c
@@ -40,7 +40,6 @@
 #include "nellymoser.h"
 #include "avcodec.h"
 #include "audio_frame_queue.h"
-#include "dsputil.h"
 #include "fft.h"
 #include "internal.h"
 #include "sinewin.h"
@@ -55,7 +54,6 @@
 typedef struct NellyMoserEncodeContext {
     AVCodecContext  *avctx;
     int             last_frame;
-    DSPContext      dsp;
     AVFloatDSPContext fdsp;
     FFTContext      mdct_ctx;
     AudioFrameQueue afq;
@@ -122,12 +120,12 @@
     float *in1 = s->buf + NELLY_BUF_LEN;
     float *in2 = s->buf + 2 * NELLY_BUF_LEN;
 
-    s->fdsp.vector_fmul       (s->in_buff,                 in0, ff_sine_128, NELLY_BUF_LEN);
-    s->dsp.vector_fmul_reverse(s->in_buff + NELLY_BUF_LEN, in1, ff_sine_128, NELLY_BUF_LEN);
+    s->fdsp.vector_fmul        (s->in_buff,                 in0, ff_sine_128, NELLY_BUF_LEN);
+    s->fdsp.vector_fmul_reverse(s->in_buff + NELLY_BUF_LEN, in1, ff_sine_128, NELLY_BUF_LEN);
     s->mdct_ctx.mdct_calc(&s->mdct_ctx, s->mdct_out, s->in_buff);
 
-    s->fdsp.vector_fmul       (s->in_buff,                 in1, ff_sine_128, NELLY_BUF_LEN);
-    s->dsp.vector_fmul_reverse(s->in_buff + NELLY_BUF_LEN, in2, ff_sine_128, NELLY_BUF_LEN);
+    s->fdsp.vector_fmul        (s->in_buff,                 in1, ff_sine_128, NELLY_BUF_LEN);
+    s->fdsp.vector_fmul_reverse(s->in_buff + NELLY_BUF_LEN, in2, ff_sine_128, NELLY_BUF_LEN);
     s->mdct_ctx.mdct_calc(&s->mdct_ctx, s->mdct_out + NELLY_BUF_LEN, s->in_buff);
 }
 
@@ -173,7 +171,6 @@
     s->avctx = avctx;
     if ((ret = ff_mdct_init(&s->mdct_ctx, 8, 0, 32768.0)) < 0)
         goto error;
-    ff_dsputil_init(&s->dsp, avctx);
     avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
 
     /* Generate overlap window */
@@ -397,7 +394,7 @@
             if (frame->nb_samples >= NELLY_BUF_LEN)
                 s->last_frame = 1;
         }
-        if ((ret = ff_af_queue_add(&s->afq, frame) < 0))
+        if ((ret = ff_af_queue_add(&s->afq, frame)) < 0)
             return ret;
     } else {
         memset(s->buf + NELLY_BUF_LEN, 0, NELLY_SAMPLES * sizeof(*s->buf));
diff --git a/libavcodec/nuv.c b/libavcodec/nuv.c
index 09868e8..dffe339 100644
--- a/libavcodec/nuv.c
+++ b/libavcodec/nuv.c
@@ -28,7 +28,6 @@
 #include "libavutil/lzo.h"
 #include "libavutil/imgutils.h"
 #include "avcodec.h"
-#include "dsputil.h"
 #include "rtjpeg.h"
 
 typedef struct {
@@ -88,7 +87,7 @@
     int i;
     if (size < 2 * 64 * 4) {
         av_log(avctx, AV_LOG_ERROR, "insufficient rtjpeg quant data\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     for (i = 0; i < 64; i++, buf += 4)
         c->lq[i] = AV_RL32(buf);
@@ -114,6 +113,8 @@
                         int quality)
 {
     NuvContext *c = avctx->priv_data;
+    int ret;
+
     width  = FFALIGN(width,  2);
     height = FFALIGN(height, 2);
     if (quality >= 0)
@@ -121,9 +122,10 @@
     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;
-        if (av_image_check_size(height, width, 0, avctx) < 0 ||
-            buf_size > INT_MAX/8)
+        if (buf_size > INT_MAX/8)
             return -1;
+        if ((ret = av_image_check_size(height, width, 0, avctx)) < 0)
+            return ret;
         avctx->width  = c->width  = width;
         avctx->height = c->height = height;
         av_fast_malloc(&c->decomp_buf, &c->decomp_size,
@@ -143,7 +145,7 @@
     return 0;
 }
 
-static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
@@ -153,7 +155,7 @@
     int orig_size      = buf_size;
     int keyframe;
     int size_change = 0;
-    int result;
+    int result, init_frame = !avctx->frame_number;
     enum {
         NUV_UNCOMPRESSED  = '0',
         NUV_RTJPEG        = '1',
@@ -165,7 +167,7 @@
 
     if (buf_size < 12) {
         av_log(avctx, AV_LOG_ERROR, "coded frame too small\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     // codec data (rtjpeg quant tables)
@@ -184,7 +186,7 @@
 
     if (buf_size < 12 || buf[0] != 'V') {
         av_log(avctx, AV_LOG_ERROR, "not a nuv video frame\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     comptype = buf[1];
     switch (comptype) {
@@ -212,7 +214,6 @@
     }
     if (c->codec_frameheader) {
         int w, h, q;
-        int res;
         if (buf_size < RTJPEG_HEADER_SIZE) {
             av_log(avctx, AV_LOG_ERROR, "Too small NUV video frame\n");
             return AVERROR_INVALIDDATA;
@@ -227,28 +228,34 @@
         w = AV_RL16(&buf[6]);
         h = AV_RL16(&buf[8]);
         q = buf[10];
-        res = codec_reinit(avctx, w, h, q);
-        if (res < 0)
-            return res;
-        if (res) {
+        if ((result = codec_reinit(avctx, w, h, q)) < 0)
+            return result;
+        if (result) {
             buf = avpkt->data;
             buf_size = avpkt->size;
             size_change = 1;
             goto retry;
         }
-        buf = &buf[RTJPEG_HEADER_SIZE];
+        buf       = &buf[RTJPEG_HEADER_SIZE];
         buf_size -= RTJPEG_HEADER_SIZE;
     }
 
-    if ((size_change || keyframe) && c->pic.data[0])
+    if ((size_change || keyframe) && c->pic.data[0]) {
         avctx->release_buffer(avctx, &c->pic);
+        init_frame = 1;
+    }
     c->pic.reference    = 3;
     c->pic.buffer_hints = FF_BUFFER_HINTS_VALID    | FF_BUFFER_HINTS_READABLE |
                           FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
     result = avctx->reget_buffer(avctx, &c->pic);
     if (result < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return result;
+    }
+    if (init_frame) {
+        memset(c->pic.data[0], 0,    avctx->height * c->pic.linesize[0]);
+        memset(c->pic.data[1], 0x80, avctx->height * c->pic.linesize[1] / 2);
+        memset(c->pic.data[2], 0x80, avctx->height * c->pic.linesize[2] / 2);
     }
 
     c->pic.pict_type = keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
@@ -262,7 +269,8 @@
             av_log(avctx, AV_LOG_ERROR, "uncompressed frame too short\n");
             height = buf_size / c->width / 3 * 2;
         }
-        copy_frame(&c->pic, buf, c->width, height);
+        if(height > 0)
+            copy_frame(&c->pic, buf, c->width, height);
         break;
     }
     case NUV_RTJPEG_IN_LZO:
@@ -279,17 +287,19 @@
         break;
     default:
         av_log(avctx, AV_LOG_ERROR, "unknown compression\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     *picture   = c->pic;
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     return orig_size;
 }
 
 static av_cold int decode_init(AVCodecContext *avctx)
 {
     NuvContext *c  = avctx->priv_data;
+    int ret;
+
     avctx->pix_fmt = AV_PIX_FMT_YUV420P;
     c->pic.data[0] = NULL;
     c->decomp_buf  = NULL;
@@ -304,8 +314,8 @@
 
     ff_dsputil_init(&c->dsp, avctx);
 
-    if (codec_reinit(avctx, avctx->width, avctx->height, -1) < 0)
-        return 1;
+    if ((ret = codec_reinit(avctx, avctx->width, avctx->height, -1)) < 0)
+        return ret;
 
     return 0;
 }
diff --git a/libavcodec/options.c b/libavcodec/options.c
index 0da0db4..a922365 100644
--- a/libavcodec/options.c
+++ b/libavcodec/options.c
@@ -248,6 +248,7 @@
 static const AVOption frame_options[]={
 {"best_effort_timestamp", "", FOFFSET(best_effort_timestamp), AV_OPT_TYPE_INT64, {.i64 = AV_NOPTS_VALUE }, INT64_MIN, INT64_MAX, 0},
 {"pkt_pos", "", FOFFSET(pkt_pos), AV_OPT_TYPE_INT64, {.i64 = -1 }, INT64_MIN, INT64_MAX, 0},
+{"pkt_size", "", FOFFSET(pkt_size), AV_OPT_TYPE_INT64, {.i64 = -1 }, INT64_MIN, INT64_MAX, 0},
 {"sample_aspect_ratio", "", FOFFSET(sample_aspect_ratio), AV_OPT_TYPE_RATIONAL, {.dbl = 0 }, 0, INT_MAX, 0},
 {"width", "", FOFFSET(width), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
 {"height", "", FOFFSET(height), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h
index 1ae93c1..d0c55a2 100644
--- a/libavcodec/options_table.h
+++ b/libavcodec/options_table.h
@@ -19,8 +19,8 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#ifndef AVCODEC_OPTIONS_TABLE
-#define AVCODEC_OPTIONS_TABLE
+#ifndef AVCODEC_OPTIONS_TABLE_H
+#define AVCODEC_OPTIONS_TABLE_H
 
 #include <float.h>
 #include <limits.h>
@@ -46,39 +46,40 @@
 {"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 "
        "ratecontrol is willing to deviate from the target average bitrate value. This is not related "
-       "to min/max bitrate. Lowering tolerance too much has an adverse effect on quality.",
+       "to minimum/maximum bitrate. Lowering tolerance too much has an adverse effect on quality.",
        OFFSET(bit_rate_tolerance), AV_OPT_TYPE_INT, {.i64 = AV_CODEC_DEFAULT_BITRATE*20 }, 1, INT_MAX, V|E},
 {"flags", NULL, OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT }, 0, UINT_MAX, V|A|S|E|D, "flags"},
-{"mv4", "use four motion vector by macroblock (mpeg4)", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_4MV }, INT_MIN, INT_MAX, V|E, "flags"},
-{"qpel", "use 1/4 pel motion compensation", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_QPEL }, INT_MIN, INT_MAX, V|E, "flags"},
+{"mv4", "use four motion vectors per macroblock (MPEG-4)", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_4MV }, INT_MIN, INT_MAX, V|E, "flags"},
+{"qpel", "use 1/4-pel motion compensation", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_QPEL }, INT_MIN, INT_MAX, V|E, "flags"},
 {"loop", "use loop filter", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_LOOP_FILTER }, INT_MIN, INT_MAX, V|E, "flags"},
 {"qscale", "use fixed qscale", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_QSCALE }, INT_MIN, INT_MAX, 0, "flags"},
 {"gmc", "use gmc", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_GMC }, INT_MIN, INT_MAX, V|E, "flags"},
 {"mv0", "always try a mb with mv=<0,0>", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_MV0 }, INT_MIN, INT_MAX, V|E, "flags"},
 {"input_preserved", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_INPUT_PRESERVED }, INT_MIN, INT_MAX, 0, "flags"},
-{"pass1", "use internal 2pass ratecontrol in first  pass mode", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_PASS1 }, INT_MIN, INT_MAX, 0, "flags"},
-{"pass2", "use internal 2pass ratecontrol in second pass mode", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_PASS2 }, INT_MIN, INT_MAX, 0, "flags"},
+{"pass1", "use internal 2-pass ratecontrol in first  pass mode", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_PASS1 }, INT_MIN, INT_MAX, 0, "flags"},
+{"pass2", "use internal 2-pass ratecontrol in second pass mode", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_PASS2 }, INT_MIN, INT_MAX, 0, "flags"},
 {"gray", "only decode/encode grayscale", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_GRAY }, INT_MIN, INT_MAX, V|E|D, "flags"},
-{"emu_edge", "don't draw edges", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_EMU_EDGE }, INT_MIN, INT_MAX, 0, "flags"},
+{"emu_edge", "do not draw edges", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_EMU_EDGE }, INT_MIN, INT_MAX, 0, "flags"},
 {"psnr", "error[?] variables will be set during encoding", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_PSNR }, INT_MIN, INT_MAX, V|E, "flags"},
 {"truncated", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_TRUNCATED }, INT_MIN, INT_MAX, 0, "flags"},
 {"naq", "normalize adaptive quantization", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_NORMALIZE_AQP }, INT_MIN, INT_MAX, V|E, "flags"},
-{"ildct", "use interlaced dct", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_INTERLACED_DCT }, INT_MIN, INT_MAX, V|E, "flags"},
+{"ildct", "use interlaced DCT", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_INTERLACED_DCT }, INT_MIN, INT_MAX, V|E, "flags"},
 {"low_delay", "force low delay", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_LOW_DELAY }, INT_MIN, INT_MAX, V|D|E, "flags"},
 {"global_header", "place global headers in extradata instead of every keyframe", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_GLOBAL_HEADER }, INT_MIN, INT_MAX, V|A|E, "flags"},
-{"bitexact", "use only bitexact stuff (except (i)dct)", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_BITEXACT }, INT_MIN, INT_MAX, A|V|S|D|E, "flags"},
-{"aic", "h263 advanced intra coding / mpeg4 ac prediction", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_AC_PRED }, INT_MIN, INT_MAX, V|E, "flags"},
+{"bitexact", "use only bitexact functions (except (I)DCT)", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_BITEXACT }, INT_MIN, INT_MAX, A|V|S|D|E, "flags"},
+{"aic", "H.263 advanced intra coding / MPEG-4 AC prediction", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_AC_PRED }, INT_MIN, INT_MAX, V|E, "flags"},
 #if FF_API_MPV_GLOBAL_OPTS
 {"cbp", "Deprecated, use mpegvideo private options instead", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_CBP_RD }, INT_MIN, INT_MAX, V|E, "flags"},
 {"qprd", "Deprecated, use mpegvideo private options instead", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_QP_RD }, INT_MIN, INT_MAX, V|E, "flags"},
 #endif
 {"ilme", "interlaced motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_INTERLACED_ME }, INT_MIN, INT_MAX, V|E, "flags"},
-{"cgop", "closed gop", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_CLOSED_GOP }, INT_MIN, INT_MAX, V|E, "flags"},
-{"fast", "allow non spec compliant speedup tricks", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG2_FAST }, INT_MIN, INT_MAX, V|E, "flags2"},
+{"cgop", "closed GOP", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_CLOSED_GOP }, INT_MIN, INT_MAX, V|E, "flags"},
+{"fast", "allow non-spec-compliant speedup tricks", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG2_FAST }, INT_MIN, INT_MAX, V|E, "flags2"},
 #if FF_API_MPV_GLOBAL_OPTS
 {"sgop", "Deprecated, use mpegvideo private options instead", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG2_STRICT_GOP }, INT_MIN, INT_MAX, V|E, "flags2"},
 #endif
 {"noout", "skip bitstream encoding", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG2_NO_OUTPUT }, INT_MIN, INT_MAX, V|E, "flags2"},
+{"ignorecrop", "ignore cropping information from sps", 1, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG2_IGNORE_CROP }, INT_MIN, INT_MAX, V|D, "flags2"},
 {"local_header", "place global headers at every keyframe instead of in extradata", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG2_LOCAL_HEADER }, INT_MIN, INT_MAX, V|E, "flags2"},
 {"chunks", "Frame data might be split into multiple chunks", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG2_CHUNKS }, INT_MIN, INT_MAX, V|D, "flags2"},
 {"showall", "Show all frames before the first keyframe", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG2_SHOW_ALL }, INT_MIN, INT_MAX, V|D, "flags2"},
@@ -91,7 +92,7 @@
 {"epzs", "EPZS motion estimation (default)", 0, AV_OPT_TYPE_CONST, {.i64 = ME_EPZS }, INT_MIN, INT_MAX, V|E, "me_method" },
 {"esa", "esa motion estimation (alias for full)", 0, AV_OPT_TYPE_CONST, {.i64 = ME_FULL }, INT_MIN, INT_MAX, V|E, "me_method" },
 {"tesa", "tesa motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_TESA }, INT_MIN, INT_MAX, V|E, "me_method" },
-{"dia", "dia motion estimation (alias for epzs)", 0, AV_OPT_TYPE_CONST, {.i64 = ME_EPZS }, INT_MIN, INT_MAX, V|E, "me_method" },
+{"dia", "diamond motion estimation (alias for EPZS)", 0, AV_OPT_TYPE_CONST, {.i64 = ME_EPZS }, INT_MIN, INT_MAX, V|E, "me_method" },
 {"log", "log motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_LOG }, INT_MIN, INT_MAX, V|E, "me_method" },
 {"phods", "phods motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_PHODS }, INT_MIN, INT_MAX, V|E, "me_method" },
 {"x1", "X1 motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_X1 }, INT_MIN, INT_MAX, V|E, "me_method" },
@@ -100,7 +101,7 @@
 {"iter", "iter motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_ITER }, INT_MIN, INT_MAX, V|E, "me_method" },
 {"extradata_size", NULL, OFFSET(extradata_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
 {"time_base", NULL, OFFSET(time_base), AV_OPT_TYPE_RATIONAL, {.dbl = 0}, INT_MIN, INT_MAX},
-{"g", "set the group of picture size", OFFSET(gop_size), AV_OPT_TYPE_INT, {.i64 = 12 }, INT_MIN, INT_MAX, V|E},
+{"g", "set the group of picture (GOP) size", OFFSET(gop_size), AV_OPT_TYPE_INT, {.i64 = 12 }, INT_MIN, INT_MAX, V|E},
 {"ar", "set audio sampling rate (in Hz)", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, A|D|E},
 {"ac", "set number of audio channels", OFFSET(channels), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, A|D|E},
 {"cutoff", "set cutoff bandwidth", OFFSET(cutoff), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, A|E},
@@ -111,14 +112,14 @@
           "Recommended range for default rc_eq: 0.0-1.0",
           OFFSET(qcompress), AV_OPT_TYPE_FLOAT, {.dbl = 0.5 }, -FLT_MAX, FLT_MAX, V|E},
 {"qblur", "video quantizer scale blur (VBR)", OFFSET(qblur), AV_OPT_TYPE_FLOAT, {.dbl = 0.5 }, -1, FLT_MAX, V|E},
-{"qmin", "min video quantizer scale (VBR)", OFFSET(qmin), AV_OPT_TYPE_INT, {.i64 = 2 }, -1, 69, V|E},
-{"qmax", "max video quantizer scale (VBR)", OFFSET(qmax), AV_OPT_TYPE_INT, {.i64 = 31 }, -1, 1024, V|E},
-{"qdiff", "max difference between the quantizer scale (VBR)", OFFSET(max_qdiff), AV_OPT_TYPE_INT, {.i64 = 3 }, INT_MIN, INT_MAX, V|E},
+{"qmin", "minimum video quantizer scale (VBR)", OFFSET(qmin), AV_OPT_TYPE_INT, {.i64 = 2 }, -1, 69, V|E},
+{"qmax", "maximum video quantizer scale (VBR)", OFFSET(qmax), AV_OPT_TYPE_INT, {.i64 = 31 }, -1, 1024, V|E},
+{"qdiff", "maximum difference between the quantizer scales (VBR)", OFFSET(max_qdiff), AV_OPT_TYPE_INT, {.i64 = 3 }, INT_MIN, INT_MAX, V|E},
 {"bf", "use 'frames' B frames", OFFSET(max_b_frames), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, -1, FF_MAX_B_FRAMES, V|E},
-{"b_qfactor", "qp factor between p and b frames", OFFSET(b_quant_factor), AV_OPT_TYPE_FLOAT, {.dbl = 1.25 }, -FLT_MAX, FLT_MAX, V|E},
+{"b_qfactor", "QP factor between P- and B-frames", OFFSET(b_quant_factor), AV_OPT_TYPE_FLOAT, {.dbl = 1.25 }, -FLT_MAX, FLT_MAX, V|E},
 {"rc_strategy", "ratecontrol method", OFFSET(rc_strategy), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
 {"b_strategy", "strategy to choose between I/P/B-frames", OFFSET(b_frame_strategy), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, V|E},
-{"ps", "rtp payload size in bytes", OFFSET(rtp_payload_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
+{"ps", "RTP payload size in bytes", OFFSET(rtp_payload_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
 {"mv_bits", NULL, OFFSET(mv_bits), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
 {"header_bits", NULL, OFFSET(header_bits), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
 {"i_tex_bits", NULL, OFFSET(i_tex_bits), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
@@ -129,34 +130,34 @@
 {"misc_bits", NULL, OFFSET(misc_bits), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
 {"frame_bits", NULL, OFFSET(frame_bits), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
 {"codec_tag", NULL, OFFSET(codec_tag), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
-{"bug", "workaround not auto detected encoder bugs", OFFSET(workaround_bugs), AV_OPT_TYPE_FLAGS, {.i64 = FF_BUG_AUTODETECT }, INT_MIN, INT_MAX, V|D, "bug"},
+{"bug", "work around not autodetected encoder bugs", OFFSET(workaround_bugs), AV_OPT_TYPE_FLAGS, {.i64 = FF_BUG_AUTODETECT }, INT_MIN, INT_MAX, V|D, "bug"},
 {"autodetect", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_AUTODETECT }, INT_MIN, INT_MAX, V|D, "bug"},
-{"old_msmpeg4", "some old lavc generated msmpeg4v3 files (no autodetection)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_OLD_MSMPEG4 }, INT_MIN, INT_MAX, V|D, "bug"},
-{"xvid_ilace", "Xvid interlacing bug (autodetected if fourcc==XVIX)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_XVID_ILACE }, INT_MIN, INT_MAX, V|D, "bug"},
-{"ump4", "(autodetected if fourcc==UMP4)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_UMP4 }, INT_MIN, INT_MAX, V|D, "bug"},
+{"old_msmpeg4", "some old lavc-generated MSMPEG4v3 files (no autodetection)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_OLD_MSMPEG4 }, INT_MIN, INT_MAX, V|D, "bug"},
+{"xvid_ilace", "Xvid interlacing bug (autodetected if FOURCC == XVIX)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_XVID_ILACE }, INT_MIN, INT_MAX, V|D, "bug"},
+{"ump4", "(autodetected if FOURCC == UMP4)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_UMP4 }, INT_MIN, INT_MAX, V|D, "bug"},
 {"no_padding", "padding bug (autodetected)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_NO_PADDING }, INT_MIN, INT_MAX, V|D, "bug"},
 {"amv", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_AMV }, INT_MIN, INT_MAX, V|D, "bug"},
-{"ac_vlc", "illegal vlc bug (autodetected per fourcc)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_AC_VLC }, INT_MIN, INT_MAX, V|D, "bug"},
+{"ac_vlc", "illegal VLC bug (autodetected per FOURCC)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_AC_VLC }, INT_MIN, INT_MAX, V|D, "bug"},
 {"qpel_chroma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_QPEL_CHROMA }, INT_MIN, INT_MAX, V|D, "bug"},
-{"std_qpel", "old standard qpel (autodetected per fourcc/version)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_STD_QPEL }, INT_MIN, INT_MAX, V|D, "bug"},
+{"std_qpel", "old standard qpel (autodetected per FOURCC/version)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_STD_QPEL }, INT_MIN, INT_MAX, V|D, "bug"},
 {"qpel_chroma2", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_QPEL_CHROMA2 }, INT_MIN, INT_MAX, V|D, "bug"},
-{"direct_blocksize", "direct-qpel-blocksize bug (autodetected per fourcc/version)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_DIRECT_BLOCKSIZE }, INT_MIN, INT_MAX, V|D, "bug"},
-{"edge", "edge padding bug (autodetected per fourcc/version)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_EDGE }, INT_MIN, INT_MAX, V|D, "bug"},
+{"direct_blocksize", "direct-qpel-blocksize bug (autodetected per FOURCC/version)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_DIRECT_BLOCKSIZE }, INT_MIN, INT_MAX, V|D, "bug"},
+{"edge", "edge padding bug (autodetected per FOURCC/version)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_EDGE }, INT_MIN, INT_MAX, V|D, "bug"},
 {"hpel_chroma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_HPEL_CHROMA }, INT_MIN, INT_MAX, V|D, "bug"},
 {"dc_clip", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_DC_CLIP }, INT_MIN, INT_MAX, V|D, "bug"},
-{"ms", "workaround various bugs in microsofts broken decoders", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_MS }, INT_MIN, INT_MAX, V|D, "bug"},
-{"trunc", "trancated frames", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_TRUNCATED}, INT_MIN, INT_MAX, V|D, "bug"},
+{"ms", "work around various bugs in Microsoft's broken decoders", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_MS }, INT_MIN, INT_MAX, V|D, "bug"},
+{"trunc", "truncated frames", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_TRUNCATED}, INT_MIN, INT_MAX, V|D, "bug"},
 #if FF_API_MPV_GLOBAL_OPTS
-{"lelim", "single coefficient elimination threshold for luminance (negative values also consider dc coefficient)", OFFSET(luma_elim_threshold), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
-{"celim", "single coefficient elimination threshold for chrominance (negative values also consider dc coefficient)", OFFSET(chroma_elim_threshold), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
+{"lelim", "single coefficient elimination threshold for luminance (negative values also consider DC coefficient)", OFFSET(luma_elim_threshold), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
+{"celim", "single coefficient elimination threshold for chrominance (negative values also consider DC coefficient)", OFFSET(chroma_elim_threshold), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
 #endif
 {"strict", "how strictly to follow the standards", OFFSET(strict_std_compliance), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, A|V|D|E, "strict"},
 {"very", "strictly conform to a older more strict version of the spec or reference software", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_VERY_STRICT }, INT_MIN, INT_MAX, V|D|E, "strict"},
-{"strict", "strictly conform to all the things in the spec no matter what consequences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_STRICT }, INT_MIN, INT_MAX, V|D|E, "strict"},
+{"strict", "strictly conform to all the things in the spec no matter what the consequences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_STRICT }, INT_MIN, INT_MAX, V|D|E, "strict"},
 {"normal", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_NORMAL }, INT_MIN, INT_MAX, V|D|E, "strict"},
 {"unofficial", "allow unofficial extensions", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_UNOFFICIAL }, INT_MIN, INT_MAX, V|D|E, "strict"},
-{"experimental", "allow non standardized experimental things", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_EXPERIMENTAL }, INT_MIN, INT_MAX, V|D|E, "strict"},
-{"b_qoffset", "qp offset between P and B frames", OFFSET(b_quant_offset), AV_OPT_TYPE_FLOAT, {.dbl = 1.25 }, -FLT_MAX, FLT_MAX, V|E},
+{"experimental", "allow non-standardized experimental things", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_EXPERIMENTAL }, INT_MIN, INT_MAX, V|D|E, "strict"},
+{"b_qoffset", "QP offset between P- and B-frames", OFFSET(b_quant_offset), AV_OPT_TYPE_FLOAT, {.dbl = 1.25 }, -FLT_MAX, FLT_MAX, V|E},
 {"err_detect", "set error detection flags", OFFSET(err_recognition), AV_OPT_TYPE_FLAGS, {.i64 = AV_EF_CRCCHECK }, INT_MIN, INT_MAX, A|V|D, "err_detect"},
 {"crccheck", "verify embedded CRCs", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_CRCCHECK }, INT_MIN, INT_MAX, A|V|D, "err_detect"},
 {"bitstream", "detect bitstream specification deviations", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_BITSTREAM }, INT_MIN, INT_MAX, A|V|D, "err_detect"},
@@ -177,13 +178,13 @@
           "bits2qp(bits), qp2bits(qp). Also the following constants are available: iTex pTex tex mv "
           "fCode iCount mcVar var isI isP isB avgQP qComp avgIITex avgPITex avgPPTex avgBPTex avgTex.",
           OFFSET(rc_eq), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX, V|E},
-{"maxrate", "Set max bitrate tolerance (in bits/s). Requires bufsize to be set.", OFFSET(rc_max_rate), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|A|E},
-{"minrate", "Set min bitrate tolerance (in bits/s). Most useful in setting up a CBR encode. It is of little use elsewise.",
+{"maxrate", "Set maximum bitrate tolerance (in bits/s). Requires bufsize to be set.", OFFSET(rc_max_rate), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|A|E},
+{"minrate", "Set minimum bitrate tolerance (in bits/s). Most useful in setting up a CBR encode. It is of little use otherwise.",
             OFFSET(rc_min_rate), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|A|E},
 {"bufsize", "set ratecontrol buffer size (in bits)", OFFSET(rc_buffer_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, A|V|E},
 {"rc_buf_aggressivity", "currently useless", OFFSET(rc_buffer_aggressivity), AV_OPT_TYPE_FLOAT, {.dbl = 1.0 }, -FLT_MAX, FLT_MAX, V|E},
-{"i_qfactor", "qp factor between P and I frames", OFFSET(i_quant_factor), AV_OPT_TYPE_FLOAT, {.dbl = -0.8 }, -FLT_MAX, FLT_MAX, V|E},
-{"i_qoffset", "qp offset between P and I frames", OFFSET(i_quant_offset), AV_OPT_TYPE_FLOAT, {.dbl = 0.0 }, -FLT_MAX, FLT_MAX, V|E},
+{"i_qfactor", "QP factor between P- and I-frames", OFFSET(i_quant_factor), AV_OPT_TYPE_FLOAT, {.dbl = -0.8 }, -FLT_MAX, FLT_MAX, V|E},
+{"i_qoffset", "QP offset between P- and I-frames", OFFSET(i_quant_offset), AV_OPT_TYPE_FLOAT, {.dbl = 0.0 }, -FLT_MAX, FLT_MAX, V|E},
 {"rc_init_cplx", "initial complexity for 1-pass encoding", OFFSET(rc_initial_cplx), AV_OPT_TYPE_FLOAT, {.dbl = DEFAULT }, -FLT_MAX, FLT_MAX, V|E},
 {"dct", "DCT algorithm", OFFSET(dct_algo), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, V|E, "dct"},
 {"auto", "autoselect a good one (default)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_AUTO }, INT_MIN, INT_MAX, V|E, "dct"},
@@ -214,8 +215,10 @@
 {"simplearmv6", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARMV6 }, INT_MIN, INT_MAX, V|E|D, "idct"},
 {"simpleneon", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLENEON }, INT_MIN, INT_MAX, V|E|D, "idct"},
 {"simplealpha", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEALPHA }, INT_MIN, INT_MAX, V|E|D, "idct"},
+#if FF_API_IDCT
 {"h264", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_H264 }, INT_MIN, INT_MAX, V|E|D, "idct"},
 {"vp3", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_VP3 }, INT_MIN, INT_MAX, V|E|D, "idct"},
+#endif
 {"ipp", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_IPP }, INT_MIN, INT_MAX, V|E|D, "idct"},
 {"xvidmmx", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_XVIDMMX }, INT_MIN, INT_MAX, V|E|D, "idct"},
 {"faani", "floating point AAN IDCT", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_FAAN }, INT_MIN, INT_MAX, V|D|E, "idct"},
@@ -251,10 +254,10 @@
 {"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"},
 {"bb", "backward predicted MVs of B-frames", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_MV_B_BACK }, INT_MIN, INT_MAX, V|D, "debug_mv"},
-{"cmp", "full pel me compare function", OFFSET(me_cmp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-{"subcmp", "sub pel me compare function", OFFSET(me_sub_cmp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+{"cmp", "full-pel ME compare function", OFFSET(me_cmp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+{"subcmp", "sub-pel ME compare function", OFFSET(me_sub_cmp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"},
 {"mbcmp", "macroblock compare function", OFFSET(mb_cmp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-{"ildctcmp", "interlaced dct compare function", OFFSET(ildct_cmp), AV_OPT_TYPE_INT, {.i64 = FF_CMP_VSAD }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+{"ildctcmp", "interlaced DCT compare function", OFFSET(ildct_cmp), AV_OPT_TYPE_INT, {.i64 = FF_CMP_VSAD }, INT_MIN, INT_MAX, V|E, "cmp_func"},
 {"dia_size", "diamond type & size for motion estimation", OFFSET(dia_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
 {"last_pred", "amount of motion predictors from the previous frame", OFFSET(last_predictor_count), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
 {"preme", "pre motion estimation", OFFSET(pre_me), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
@@ -277,7 +280,7 @@
 {"dctmax", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_DCTMAX }, INT_MIN, INT_MAX, V|E, "cmp_func"},
 {"chroma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_CHROMA }, INT_MIN, INT_MAX, V|E, "cmp_func"},
 {"pre_dia_size", "diamond type & size for motion estimation pre-pass", OFFSET(pre_dia_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
-{"subq", "sub pel motion estimation quality", OFFSET(me_subpel_quality), AV_OPT_TYPE_INT, {.i64 = 8 }, INT_MIN, INT_MAX, V|E},
+{"subq", "sub-pel motion estimation quality", OFFSET(me_subpel_quality), AV_OPT_TYPE_INT, {.i64 = 8 }, INT_MIN, INT_MAX, V|E},
 {"dtg_active_format", NULL, OFFSET(dtg_active_format), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
 {"me_range", "limit motion vectors range (1023 for DivX player)", OFFSET(me_range), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
 {"ibias", "intra quant bias", OFFSET(intra_quant_bias), AV_OPT_TYPE_INT, {.i64 = FF_DEFAULT_QUANT_BIAS }, INT_MIN, INT_MAX, V|E},
@@ -287,7 +290,7 @@
 #endif
 {"global_quality", NULL, OFFSET(global_quality), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|A|E},
 {"coder", NULL, OFFSET(coder_type), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "coder"},
-{"vlc", "variable length coder / huffman coder", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CODER_TYPE_VLC }, INT_MIN, INT_MAX, V|E, "coder"},
+{"vlc", "variable length coder / Huffman coder", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CODER_TYPE_VLC }, INT_MIN, INT_MAX, V|E, "coder"},
 {"ac", "arithmetic coder", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CODER_TYPE_AC }, INT_MIN, INT_MAX, V|E, "coder"},
 {"raw", "raw (no encoding)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CODER_TYPE_RAW }, INT_MIN, INT_MAX, V|E, "coder"},
 {"rle", "run-length coder", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CODER_TYPE_RLE }, INT_MIN, INT_MAX, V|E, "coder"},
@@ -295,14 +298,14 @@
 {"context", "context model", OFFSET(context_model), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
 {"slice_flags", NULL, OFFSET(slice_flags), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
 {"xvmc_acceleration", NULL, OFFSET(xvmc_acceleration), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
-{"mbd", "macroblock decision algorithm (high quality mode)", OFFSET(mb_decision), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "mbd"},
+{"mbd", "macroblock decision algorithm (high quality mode)", OFFSET(mb_decision), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, 2, V|E, "mbd"},
 {"simple", "use mbcmp (default)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MB_DECISION_SIMPLE }, INT_MIN, INT_MAX, V|E, "mbd"},
 {"bits", "use fewest bits", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MB_DECISION_BITS }, INT_MIN, INT_MAX, V|E, "mbd"},
 {"rd", "use best rate distortion", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MB_DECISION_RD }, INT_MIN, INT_MAX, V|E, "mbd"},
 {"stream_codec_tag", NULL, OFFSET(stream_codec_tag), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
 {"sc_threshold", "scene change threshold", OFFSET(scenechange_threshold), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
-{"lmin", "min lagrange factor (VBR)", OFFSET(lmin), AV_OPT_TYPE_INT, {.i64 =  2*FF_QP2LAMBDA }, 0, INT_MAX, V|E},
-{"lmax", "max lagrange factor (VBR)", OFFSET(lmax), AV_OPT_TYPE_INT, {.i64 = 31*FF_QP2LAMBDA }, 0, INT_MAX, V|E},
+{"lmin", "minimum Lagrange factor (VBR)", OFFSET(lmin), AV_OPT_TYPE_INT, {.i64 =  2*FF_QP2LAMBDA }, 0, INT_MAX, V|E},
+{"lmax", "maximum Lagrange factor (VBR)", OFFSET(lmax), AV_OPT_TYPE_INT, {.i64 = 31*FF_QP2LAMBDA }, 0, INT_MAX, V|E},
 {"nr", "noise reduction", OFFSET(noise_reduction), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
 {"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},
 #if FF_API_INTER_THRESHOLD
@@ -314,8 +317,8 @@
 {"qns", "deprecated, use mpegvideo private options instead", OFFSET(quantizer_noise_shaping), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
 #endif
 {"threads", NULL, OFFSET(thread_count), AV_OPT_TYPE_INT, {.i64 = 1 }, 0, INT_MAX, V|E|D, "threads"},
-{"auto", "detect a good number of threads", 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, INT_MIN, INT_MAX, V|E|D, "threads"},
-{"me_threshold", "motion estimaton threshold", OFFSET(me_threshold), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
+{"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},
 {"dc", "intra_dc_precision", OFFSET(intra_dc_precision), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, V|E},
 {"nssew", "nsse weight", OFFSET(nsse_weight), AV_OPT_TYPE_INT, {.i64 = 8 }, INT_MIN, INT_MAX, V|E},
@@ -343,9 +346,9 @@
 {"skip_factor", "frame skip factor", OFFSET(frame_skip_factor), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
 {"skip_exp", "frame skip exponent", OFFSET(frame_skip_exp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
 {"skipcmp", "frame skip compare function", OFFSET(frame_skip_cmp), AV_OPT_TYPE_INT, {.i64 = FF_CMP_DCTMAX }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-{"border_mask", "increases the quantizer for macroblocks close to borders", OFFSET(border_masking), AV_OPT_TYPE_FLOAT, {.dbl = DEFAULT }, -FLT_MAX, FLT_MAX, V|E},
-{"mblmin", "min macroblock lagrange factor (VBR)", OFFSET(mb_lmin), AV_OPT_TYPE_INT, {.i64 = FF_QP2LAMBDA * 2 }, 1, FF_LAMBDA_MAX, V|E},
-{"mblmax", "max macroblock lagrange factor (VBR)", OFFSET(mb_lmax), AV_OPT_TYPE_INT, {.i64 = FF_QP2LAMBDA * 31 }, 1, FF_LAMBDA_MAX, V|E},
+{"border_mask", "increase the quantizer for macroblocks close to borders", OFFSET(border_masking), AV_OPT_TYPE_FLOAT, {.dbl = DEFAULT }, -FLT_MAX, FLT_MAX, V|E},
+{"mblmin", "minimum macroblock Lagrange factor (VBR)", OFFSET(mb_lmin), AV_OPT_TYPE_INT, {.i64 = FF_QP2LAMBDA * 2 }, 1, FF_LAMBDA_MAX, V|E},
+{"mblmax", "maximum macroblock Lagrange factor (VBR)", OFFSET(mb_lmax), AV_OPT_TYPE_INT, {.i64 = FF_QP2LAMBDA * 31 }, 1, FF_LAMBDA_MAX, V|E},
 {"mepc", "motion estimation bitrate penalty compensation (1.0 = 256)", OFFSET(me_penalty_compensation), AV_OPT_TYPE_INT, {.i64 = 256 }, INT_MIN, INT_MAX, V|E},
 {"skip_loop_filter", NULL, OFFSET(skip_loop_filter), AV_OPT_TYPE_INT, {.i64 = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, "avdiscard"},
 {"skip_idct"       , NULL, OFFSET(skip_idct)       , AV_OPT_TYPE_INT, {.i64 = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, "avdiscard"},
@@ -357,21 +360,21 @@
 {"nokey"           , NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_NONKEY  }, INT_MIN, INT_MAX, V|D, "avdiscard"},
 {"all"             , NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_ALL     }, INT_MIN, INT_MAX, V|D, "avdiscard"},
 {"bidir_refine", "refine the two motion vectors used in bidirectional macroblocks", OFFSET(bidir_refine), AV_OPT_TYPE_INT, {.i64 = 1 }, 0, 4, V|E},
-{"brd_scale", "downscales frames for dynamic B-frame decision", OFFSET(brd_scale), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, 10, V|E},
+{"brd_scale", "downscale frames for dynamic B-frame decision", OFFSET(brd_scale), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, 10, V|E},
 {"keyint_min", "minimum interval between IDR-frames", OFFSET(keyint_min), AV_OPT_TYPE_INT, {.i64 = 25 }, INT_MIN, INT_MAX, V|E},
 {"refs", "reference frames to consider for motion compensation", OFFSET(refs), AV_OPT_TYPE_INT, {.i64 = 1 }, INT_MIN, INT_MAX, V|E},
-{"chromaoffset", "chroma qp offset from luma", OFFSET(chromaoffset), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
+{"chromaoffset", "chroma QP offset from luma", OFFSET(chromaoffset), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
 {"trellis", "rate-distortion optimal quantization", OFFSET(trellis), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|A|E},
 #if FF_API_MPV_GLOBAL_OPTS
 {"skiprd", "Deprecated, use mpegvideo private options instead", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG2_SKIP_RD }, INT_MIN, INT_MAX, V|E, "flags2"},
 #endif
 {"sc_factor", "multiplied by qscale for each frame and added to scene_change_score", OFFSET(scenechange_factor), AV_OPT_TYPE_INT, {.i64 = 6 }, 0, INT_MAX, V|E},
 {"mv0_threshold", NULL, OFFSET(mv0_threshold), AV_OPT_TYPE_INT, {.i64 = 256 }, 0, INT_MAX, V|E},
-{"b_sensitivity", "adjusts sensitivity of b_frame_strategy 1", OFFSET(b_sensitivity), AV_OPT_TYPE_INT, {.i64 = 40 }, 1, INT_MAX, V|E},
+{"b_sensitivity", "adjust sensitivity of b_frame_strategy 1", OFFSET(b_sensitivity), AV_OPT_TYPE_INT, {.i64 = 40 }, 1, INT_MAX, V|E},
 {"compression_level", NULL, OFFSET(compression_level), AV_OPT_TYPE_INT, {.i64 = FF_COMPRESSION_DEFAULT }, INT_MIN, INT_MAX, V|A|E},
 {"min_prediction_order", NULL, OFFSET(min_prediction_order), AV_OPT_TYPE_INT, {.i64 = -1 }, INT_MIN, INT_MAX, A|E},
 {"max_prediction_order", NULL, OFFSET(max_prediction_order), AV_OPT_TYPE_INT, {.i64 = -1 }, INT_MIN, INT_MAX, A|E},
-{"timecode_frame_start", "GOP timecode frame start number, in non drop frame format", OFFSET(timecode_frame_start), AV_OPT_TYPE_INT64, {.i64 = 0 }, 0, INT64_MAX, V|E},
+{"timecode_frame_start", "GOP timecode frame start number, in non-drop-frame format", OFFSET(timecode_frame_start), AV_OPT_TYPE_INT64, {.i64 = 0 }, 0, INT64_MAX, V|E},
 #if FF_API_REQUEST_CHANNELS
 {"request_channels", "set desired number of audio channels", OFFSET(request_channels), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, A|D},
 #endif
@@ -403,6 +406,11 @@
 {"ka", "Karaoke",            0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_KARAOKE },           INT_MIN, INT_MAX, A|E, "audio_service_type"},
 {"request_sample_fmt", "sample format audio decoders should prefer", OFFSET(request_sample_fmt), AV_OPT_TYPE_SAMPLE_FMT, {.i64=AV_SAMPLE_FMT_NONE}, -1, AV_SAMPLE_FMT_NB-1, A|D, "request_sample_fmt"},
 {"pkt_timebase", NULL, OFFSET(pkt_timebase), AV_OPT_TYPE_RATIONAL, {.dbl = 0 }, 0, INT_MAX, 0},
+{"sub_charenc", "set input text subtitles character encoding", OFFSET(sub_charenc), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX, S|D},
+{"sub_charenc_mode", "set input text subtitles character encoding mode", OFFSET(sub_charenc_mode), AV_OPT_TYPE_FLAGS, {.i64 = FF_SUB_CHARENC_MODE_AUTOMATIC}, -1, INT_MAX, S|D, "sub_charenc_mode"},
+{"do_nothing",  NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_CHARENC_MODE_DO_NOTHING},  INT_MIN, INT_MAX, S|D, "sub_charenc_mode"},
+{"auto",        NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_CHARENC_MODE_AUTOMATIC},   INT_MIN, INT_MAX, S|D, "sub_charenc_mode"},
+{"pre_decoder", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_CHARENC_MODE_PRE_DECODER}, INT_MIN, INT_MAX, S|D, "sub_charenc_mode"},
 {NULL},
 };
 
@@ -414,4 +422,4 @@
 #undef DEFAULT
 #undef OFFSET
 
-#endif // AVCODEC_OPTIONS_TABLE
+#endif /* AVCODEC_OPTIONS_TABLE_H */
diff --git a/libavcodec/paf.c b/libavcodec/paf.c
index 877b170..78a5d97 100644
--- a/libavcodec/paf.c
+++ b/libavcodec/paf.c
@@ -20,10 +20,12 @@
  */
 
 #include "libavutil/intreadwrite.h"
-#include "libavcodec/dsputil.h"
 #include "libavcodec/paf.h"
 #include "bytestream.h"
 #include "avcodec.h"
+#include "copy_block.h"
+#include "internal.h"
+
 
 static const uint8_t block_sequences[16][8] =
 {
@@ -243,7 +245,7 @@
 }
 
 static int paf_vid_decode(AVCodecContext *avctx, void *data,
-                          int *data_size, AVPacket *pkt)
+                          int *got_frame, AVPacket *pkt)
 {
     PAFVideoDecContext *c = avctx->priv_data;
     uint8_t code, *dst, *src, *end;
@@ -355,7 +357,7 @@
 
     c->current_frame = (c->current_frame + 1) & 3;
 
-    *data_size       = sizeof(AVFrame);
+    *got_frame       = 1;
     *(AVFrame *)data = c->pic;
 
     return pkt->size;
@@ -375,22 +377,14 @@
     return 0;
 }
 
-typedef struct PAFAudioDecContext {
-    AVFrame frame;
-} PAFAudioDecContext;
-
 static av_cold int paf_aud_init(AVCodecContext *avctx)
 {
-    PAFAudioDecContext *c = avctx->priv_data;
-
     if (avctx->channels != 2) {
         av_log(avctx, AV_LOG_ERROR, "invalid number of channels\n");
         return AVERROR_INVALIDDATA;
     }
 
-    avcodec_get_frame_defaults(&c->frame);
     avctx->channel_layout = AV_CH_LAYOUT_STEREO;
-    avctx->coded_frame    = &c->frame;
     avctx->sample_fmt     = AV_SAMPLE_FMT_S16;
 
     return 0;
@@ -399,7 +393,7 @@
 static int paf_aud_decode(AVCodecContext *avctx, void *data,
                           int *got_frame_ptr, AVPacket *pkt)
 {
-    PAFAudioDecContext *c = avctx->priv_data;
+    AVFrame *frame = data;
     uint8_t *buf = pkt->data;
     int16_t *output_samples;
     const uint8_t *t;
@@ -409,11 +403,11 @@
     if (frames < 1)
         return AVERROR_INVALIDDATA;
 
-    c->frame.nb_samples = PAF_SOUND_SAMPLES * frames;
-    if ((ret = avctx->get_buffer(avctx, &c->frame)) < 0)
+    frame->nb_samples = PAF_SOUND_SAMPLES * frames;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0)
         return ret;
 
-    output_samples = (int16_t *)c->frame.data[0];
+    output_samples = (int16_t *)frame->data[0];
     for (i = 0; i < frames; i++) {
         t = buf + 256 * sizeof(uint16_t);
         for (j = 0; j < PAF_SOUND_SAMPLES; j++) {
@@ -426,7 +420,6 @@
     }
 
     *got_frame_ptr   = 1;
-    *(AVFrame *)data = c->frame;
 
     return pkt->size;
 }
@@ -447,7 +440,6 @@
     .name           = "paf_audio",
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_PAF_AUDIO,
-    .priv_data_size = sizeof(PAFAudioDecContext),
     .init           = paf_aud_init,
     .decode         = paf_aud_decode,
     .capabilities   = CODEC_CAP_DR1,
diff --git a/libavcodec/parser.c b/libavcodec/parser.c
index 2e204e2..f7cb5cf 100644
--- a/libavcodec/parser.c
+++ b/libavcodec/parser.c
@@ -95,7 +95,7 @@
         if (   s->cur_offset + off >= s->cur_frame_offset[i]
             && (s->frame_offset < s->cur_frame_offset[i] ||
               (!s->frame_offset && !s->next_frame_offset)) // first field/frame
-            //check is disabled because mpeg-ts doesn't send complete PES packets
+            // check disabled since MPEG-TS does not send complete PES packets
             && /*s->next_frame_offset + off <*/  s->cur_frame_end[i]){
             s->dts= s->cur_frame_dts[i];
             s->pts= s->cur_frame_pts[i];
@@ -253,8 +253,9 @@
         if(!new_buffer)
             return AVERROR(ENOMEM);
         pc->buffer = new_buffer;
-        if(FF_INPUT_BUFFER_PADDING_SIZE > -next)
-        memcpy(&pc->buffer[pc->index], *buf, next + FF_INPUT_BUFFER_PADDING_SIZE );
+        if (next > -FF_INPUT_BUFFER_PADDING_SIZE)
+            memcpy(&pc->buffer[pc->index], *buf,
+                   next + FF_INPUT_BUFFER_PADDING_SIZE);
         pc->index = 0;
         *buf= pc->buffer;
     }
diff --git a/libavcodec/pcm-mpeg.c b/libavcodec/pcm-mpeg.c
index 01a61c8..08aad95 100644
--- a/libavcodec/pcm-mpeg.c
+++ b/libavcodec/pcm-mpeg.c
@@ -27,6 +27,7 @@
 #include "libavutil/channel_layout.h"
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 
 /*
  * Channel Mapping according to
@@ -121,26 +122,12 @@
     return 0;
 }
 
-typedef struct PCMBRDecode {
-    AVFrame frame;
-} PCMBRDecode;
-
-static av_cold int pcm_bluray_decode_init(AVCodecContext * avctx)
-{
-    PCMBRDecode *s = avctx->priv_data;
-
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
-    return 0;
-}
-
 static int pcm_bluray_decode_frame(AVCodecContext *avctx, void *data,
                                    int *got_frame_ptr, AVPacket *avpkt)
 {
+    AVFrame *frame     = data;
     const uint8_t *src = avpkt->data;
     int buf_size = avpkt->size;
-    PCMBRDecode *s = avctx->priv_data;
     GetByteContext gb;
     int num_source_channels, channel, retval;
     int sample_size, samples;
@@ -165,13 +152,13 @@
     samples = buf_size / sample_size;
 
     /* get output buffer */
-    s->frame.nb_samples = samples;
-    if ((retval = avctx->get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = samples;
+    if ((retval = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return retval;
     }
-    dst16 = (int16_t *)s->frame.data[0];
-    dst32 = (int32_t *)s->frame.data[0];
+    dst16 = (int16_t *)frame->data[0];
+    dst32 = (int32_t *)frame->data[0];
 
     if (samples) {
         switch (avctx->channel_layout) {
@@ -305,8 +292,7 @@
         }
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
+    *got_frame_ptr = 1;
 
     retval = bytestream2_tell(&gb);
     if (avctx->debug & FF_DEBUG_BITSTREAM)
@@ -319,8 +305,6 @@
     .name           = "pcm_bluray",
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_PCM_BLURAY,
-    .priv_data_size = sizeof(PCMBRDecode),
-    .init           = pcm_bluray_decode_init,
     .decode         = pcm_bluray_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .sample_fmts    = (const enum AVSampleFormat[]){
diff --git a/libavcodec/pcm.c b/libavcodec/pcm.c
index d769fb1..bae338d 100644
--- a/libavcodec/pcm.c
+++ b/libavcodec/pcm.c
@@ -230,7 +230,6 @@
 }
 
 typedef struct PCMDecode {
-    AVFrame frame;
     short   table[256];
 } PCMDecode;
 
@@ -262,9 +261,6 @@
     if (avctx->sample_fmt == AV_SAMPLE_FMT_S32)
         avctx->bits_per_raw_sample = av_get_bits_per_sample(avctx->codec_id);
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     return 0;
 }
 
@@ -289,7 +285,7 @@
     n /= avctx->channels;                                               \
     for (c = 0; c < avctx->channels; c++) {                             \
         int i;                                                          \
-        dst = s->frame.extended_data[c];                                \
+        dst = frame->extended_data[c];                                \
         for (i = n; i > 0; i--) {                                       \
             uint ## size ## _t v = bytestream_get_ ## endian(&src);     \
             AV_WN ## size ## A(dst, (v - offset) << shift);             \
@@ -303,6 +299,7 @@
     const uint8_t *src = avpkt->data;
     int buf_size       = avpkt->size;
     PCMDecode *s       = avctx->priv_data;
+    AVFrame *frame     = data;
     int sample_size, c, n, ret, samples_per_block;
     uint8_t *samples;
     int32_t *dst_int32_t;
@@ -358,12 +355,12 @@
     n = buf_size / sample_size;
 
     /* get output buffer */
-    s->frame.nb_samples = n * samples_per_block / avctx->channels;
-    if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = n * samples_per_block / avctx->channels;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    samples = s->frame.data[0];
+    samples = frame->data[0];
 
     switch (avctx->codec_id) {
     case AV_CODEC_ID_PCM_U32LE:
@@ -410,7 +407,7 @@
         n /= avctx->channels;
         for (c = 0; c < avctx->channels; c++) {
             int i;
-            samples = s->frame.extended_data[c];
+            samples = frame->extended_data[c];
             for (i = n; i > 0; i--)
                 *samples++ = *src++ + 128;
         }
@@ -466,7 +463,7 @@
 #endif /* HAVE_BIGENDIAN */
         n /= avctx->channels;
         for (c = 0; c < avctx->channels; c++) {
-            samples = s->frame.extended_data[c];
+            samples = frame->extended_data[c];
             bytestream_get_buffer(&src, samples, n * sample_size);
         }
         break;
@@ -488,7 +485,7 @@
     case AV_CODEC_ID_PCM_DVD:
     {
         const uint8_t *src8;
-        dst_int32_t = (int32_t *)s->frame.data[0];
+        dst_int32_t = (int32_t *)frame->data[0];
         n /= avctx->channels;
         switch (avctx->bits_per_coded_sample) {
         case 20:
@@ -521,7 +518,7 @@
         int i;
         n /= avctx->channels;
         for (c = 0; c < avctx->channels; c++) {
-            dst_int32_t = (int32_t *)s->frame.extended_data[c];
+            dst_int32_t = (int32_t *)frame->extended_data[c];
             for (i = 0; i < n; i++) {
                 // extract low 20 bits and expand to 32 bits
                 *dst_int32_t++ =  (src[2]         << 28) |
@@ -544,8 +541,7 @@
         return -1;
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
+    *got_frame_ptr = 1;
 
     return buf_size;
 }
diff --git a/libavcodec/pcx.c b/libavcodec/pcx.c
index 722e89f..e7f9c24 100644
--- a/libavcodec/pcx.c
+++ b/libavcodec/pcx.c
@@ -26,6 +26,7 @@
 #include "avcodec.h"
 #include "bytestream.h"
 #include "get_bits.h"
+#include "internal.h"
 
 typedef struct PCXContext {
     AVFrame picture;
@@ -74,7 +75,7 @@
         memset(dst, 0, (256 - pallen) * sizeof(*dst));
 }
 
-static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                             AVPacket *avpkt)
 {
     PCXContext * const s = avctx->priv_data;
@@ -118,7 +119,7 @@
     bytes_per_line     = bytestream2_get_le16u(&gb);
     bytes_per_scanline = nplanes * bytes_per_line;
 
-    if (bytes_per_scanline < w * bits_per_pixel * nplanes / 8) {
+    if (bytes_per_scanline < (w * bits_per_pixel * nplanes + 7) / 8) {
         av_log(avctx, AV_LOG_ERROR, "PCX data is corrupted\n");
         return AVERROR_INVALIDDATA;
     }
@@ -146,11 +147,11 @@
     if (p->data[0])
         avctx->release_buffer(avctx, p);
 
-    if (av_image_check_size(w, h, 0, avctx))
-        return AVERROR_INVALIDDATA;
+    if ((ret = av_image_check_size(w, h, 0, avctx)) < 0)
+        return ret;
     if (w != avctx->width || h != avctx->height)
         avcodec_set_dimensions(avctx, w, h);
-    if ((ret = avctx->get_buffer(avctx, p)) < 0) {
+    if ((ret = ff_get_buffer(avctx, p)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -160,7 +161,7 @@
     ptr    = p->data[0];
     stride = p->linesize[0];
 
-    scanline = av_malloc(bytes_per_scanline);
+    scanline = av_malloc(bytes_per_scanline + FF_INPUT_BUFFER_PADDING_SIZE);
     if (!scanline)
         return AVERROR(ENOMEM);
 
@@ -199,7 +200,7 @@
         GetBitContext s;
 
         for (y=0; y<h; y++) {
-            init_get_bits(&s, scanline, bytes_per_scanline<<3);
+            init_get_bits8(&s, scanline, bytes_per_scanline);
 
             pcx_rle_decode(&gb, scanline, bytes_per_scanline, compressed);
 
@@ -239,7 +240,7 @@
     }
 
     *picture = s->picture;
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
 
 end:
     av_free(scanline);
diff --git a/libavcodec/pictordec.c b/libavcodec/pictordec.c
index 748d9b3..69d2382 100644
--- a/libavcodec/pictordec.c
+++ b/libavcodec/pictordec.c
@@ -28,6 +28,7 @@
 #include "avcodec.h"
 #include "bytestream.h"
 #include "cga_data.h"
+#include "internal.h"
 
 typedef struct PicContext {
     AVFrame frame;
@@ -105,7 +106,7 @@
 }
 
 static int decode_frame(AVCodecContext *avctx,
-                        void *data, int *data_size,
+                        void *data, int *got_frame,
                         AVPacket *avpkt)
 {
     PicContext *s = avctx->priv_data;
@@ -130,7 +131,7 @@
     bpp            = bits_per_plane * s->nb_planes;
     if (bits_per_plane > 8 || bpp < 1 || bpp > 32) {
         av_log_ask_for_sample(avctx, "unsupported bit depth\n");
-        return AVERROR_INVALIDDATA;
+        return AVERROR_PATCHWELCOME;
     }
 
     if (bytestream2_peek_byte(&s->g) == 0xFF || bpp == 1 || bpp == 4 || bpp == 8) {
@@ -154,7 +155,7 @@
             avctx->release_buffer(avctx, &s->frame);
     }
 
-    if (avctx->get_buffer(avctx, &s->frame) < 0){
+    if (ff_get_buffer(avctx, &s->frame) < 0){
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return -1;
     }
@@ -173,7 +174,7 @@
         npal = FFMIN(esize, 16);
         for (i = 0; i < npal; i++) {
             int pal_idx = bytestream2_get_byte(&s->g);
-            palette[i]  = ff_cga_palette[FFMIN(pal_idx, 16)];
+            palette[i]  = ff_cga_palette[FFMIN(pal_idx, 15)];
         }
     } else if (etype == 3) {
         npal = FFMIN(esize, 16);
@@ -257,7 +258,7 @@
         }
     }
 
-    *data_size = sizeof(AVFrame);
+    *got_frame      = 1;
     *(AVFrame*)data = s->frame;
     return avpkt->size;
 }
diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c
index c1b8b08..193e35e 100644
--- a/libavcodec/pngdec.c
+++ b/libavcodec/pngdec.c
@@ -25,6 +25,7 @@
 #include "libavutil/imgutils.h"
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 #include "png.h"
 #include "pngdsp.h"
 
@@ -95,12 +96,13 @@
     uint8_t *d;
     const uint8_t *s;
 
-    mask = png_pass_mask[pass];
+    mask     = png_pass_mask[pass];
     dsp_mask = png_pass_dsp_mask[pass];
-    switch(bits_per_pixel) {
+
+    switch (bits_per_pixel) {
     case 1:
         src_x = 0;
-        for(x = 0; x < width; x++) {
+        for (x = 0; x < width; x++) {
             j = (x & 7);
             if ((dsp_mask << j) & 0x80) {
                 b = (src[src_x >> 3] >> (7 - (src_x & 7))) & 1;
@@ -113,8 +115,8 @@
         break;
     case 2:
         src_x = 0;
-        for(x = 0; x < width; x++) {
-            int j2 = 2*(x&3);
+        for (x = 0; x < width; x++) {
+            int j2 = 2 * (x & 3);
             j = (x & 7);
             if ((dsp_mask << j) & 0x80) {
                 b = (src[src_x >> 2] >> (6 - 2*(src_x & 3))) & 3;
@@ -127,7 +129,7 @@
         break;
     case 4:
         src_x = 0;
-        for(x = 0; x < width; x++) {
+        for (x = 0; x < width; x++) {
             int j2 = 4*(x&1);
             j = (x & 7);
             if ((dsp_mask << j) & 0x80) {
@@ -141,9 +143,9 @@
         break;
     default:
         bpp = bits_per_pixel >> 3;
-        d = dst;
-        s = src;
-            for(x = 0; x < width; x++) {
+        d   = dst;
+        s   = src;
+            for (x = 0; x < width; x++) {
                 j = x & 7;
                 if ((dsp_mask << j) & 0x80) {
                     memcpy(d, s, bpp);
@@ -159,14 +161,14 @@
 void ff_add_png_paeth_prediction(uint8_t *dst, uint8_t *src, uint8_t *top, int w, int bpp)
 {
     int i;
-    for(i = 0; i < w; i++) {
+    for (i = 0; i < w; i++) {
         int a, b, c, p, pa, pb, pc;
 
         a = dst[i - bpp];
         b = top[i];
         c = top[i - bpp];
 
-        p = b - c;
+        p  = b - c;
         pc = a - c;
 
         pa = abs(p);
@@ -188,7 +190,7 @@
     if(bpp >= 2) g = dst[1];\
     if(bpp >= 3) b = dst[2];\
     if(bpp >= 4) a = dst[3];\
-    for(; i < size; i+=bpp) {\
+    for(; i <= size - bpp; i+=bpp) {\
         dst[i+0] = r = op(r, src[i+0], last[i+0]);\
         if(bpp == 1) continue;\
         dst[i+1] = g = op(g, src[i+1], last[i+1]);\
@@ -204,13 +206,9 @@
     else if(bpp == 2) UNROLL1(2, op)\
     else if(bpp == 3) UNROLL1(3, op)\
     else if(bpp == 4) UNROLL1(4, op)\
-    else {\
-        for (; i < size; i += bpp) {\
-            int j;\
-            for (j = 0; j < bpp; j++)\
-                dst[i+j] = op(dst[i+j-bpp], src[i+j], last[i+j]);\
-        }\
-    }
+    for (; i < size; i++) {\
+        dst[i] = op(dst[i-bpp], src[i], last[i]);\
+    }\
 
 /* NOTE: 'dst' can be equal to 'last' */
 static void png_filter_row(PNGDSPContext *dsp, uint8_t *dst, int filter_type,
@@ -218,20 +216,20 @@
 {
     int i, p, r, g, b, a;
 
-    switch(filter_type) {
+    switch (filter_type) {
     case PNG_FILTER_VALUE_NONE:
         memcpy(dst, src, size);
         break;
     case PNG_FILTER_VALUE_SUB:
-        for(i = 0; i < bpp; i++) {
+        for (i = 0; i < bpp; i++) {
             dst[i] = src[i];
         }
-        if(bpp == 4) {
+        if (bpp == 4) {
             p = *(int*)dst;
-            for(; i < size; i+=bpp) {
-                int s = *(int*)(src+i);
-                p = ((s&0x7f7f7f7f) + (p&0x7f7f7f7f)) ^ ((s^p)&0x80808080);
-                *(int*)(dst+i) = p;
+            for (; i < size; i += bpp) {
+                int s = *(int*)(src + i);
+                p = ((s & 0x7f7f7f7f) + (p & 0x7f7f7f7f)) ^ ((s ^ p) & 0x80808080);
+                *(int*)(dst + i) = p;
             }
         } else {
 #define OP_SUB(x,s,l) x+s
@@ -242,7 +240,7 @@
         dsp->add_bytes_l2(dst, src, last, size);
         break;
     case PNG_FILTER_VALUE_AVG:
-        for(i = 0; i < bpp; i++) {
+        for (i = 0; i < bpp; i++) {
             p = (last[i] >> 1);
             dst[i] = p + src[i];
         }
@@ -250,17 +248,17 @@
         UNROLL_FILTER(OP_AVG);
         break;
     case PNG_FILTER_VALUE_PAETH:
-        for(i = 0; i < bpp; i++) {
+        for (i = 0; i < bpp; i++) {
             p = last[i];
             dst[i] = p + src[i];
         }
-        if(bpp > 2 && size > 4) {
+        if (bpp > 2 && size > 4) {
             // would write off the end of the array if we let it process the last pixel with bpp=3
-            int w = bpp==4 ? size : size-3;
-            dsp->add_paeth_prediction(dst+i, src+i, last+i, w-i, bpp);
+            int w = bpp == 4 ? size : size - 3;
+            dsp->add_paeth_prediction(dst + i, src + i, last + i, w - i, bpp);
             i = w;
         }
-        ff_add_png_paeth_prediction(dst+i, src+i, last+i, size-i, bpp);
+        ff_add_png_paeth_prediction(dst + i, src + i, last + i, size - i, bpp);
         break;
     }
 }
@@ -321,7 +319,7 @@
         }
     } else {
         got_line = 0;
-        for(;;) {
+        for (;;) {
             ptr = s->image_buf + s->image_linesize * s->y;
             if ((ff_png_pass_ymask[s->pass] << (s->y & 7)) & 0x80) {
                 /* if we already read one row, it is time to stop to
@@ -340,7 +338,7 @@
             s->y++;
             if (s->y == s->height) {
                 memset(s->last_row, 0, s->row_size);
-                for(;;) {
+                for (;;) {
                     if (s->pass == NB_PASSES - 1) {
                         s->state |= PNG_ALLIMAGE;
                         goto the_end;
@@ -366,7 +364,7 @@
 {
     int ret;
     s->zstream.avail_in = FFMIN(length, bytestream2_get_bytes_left(&s->gb));
-    s->zstream.next_in = (unsigned char *)s->gb.buffer;
+    s->zstream.next_in  = (unsigned char *)s->gb.buffer;
     bytestream2_skip(&s->gb, length);
 
     /* decode one line if possible */
@@ -381,7 +379,7 @@
                 png_handle_row(s);
             }
             s->zstream.avail_out = s->crow_size;
-            s->zstream.next_out = s->crow_buf;
+            s->zstream.next_out  = s->crow_buf;
         }
     }
     return 0;
@@ -504,22 +502,22 @@
 }
 
 static int decode_frame(AVCodecContext *avctx,
-                        void *data, int *data_size,
+                        void *data, int *got_frame,
                         AVPacket *avpkt)
 {
-    const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
     PNGDecContext * const s = avctx->priv_data;
-    AVFrame *picture = data;
+    const uint8_t *buf      = avpkt->data;
+    int buf_size            = avpkt->size;
+    AVFrame *picture        = data;
+    AVDictionary *metadata  = NULL;
+    uint8_t *crow_buf_base  = NULL;
     AVFrame *p;
-    AVDictionary *metadata = NULL;
-    uint8_t *crow_buf_base = NULL;
     uint32_t tag, length;
     int64_t sig;
     int ret;
 
     FFSWAP(AVFrame *, s->current_picture, s->last_picture);
-    avctx->coded_frame= s->current_picture;
+    avctx->coded_frame = s->current_picture;
     p = s->current_picture;
 
     bytestream2_init(&s->gb, buf, buf_size);
@@ -532,19 +530,18 @@
         return -1;
     }
 
-    s->y=
-    s->state=0;
-//    memset(s, 0, sizeof(PNGDecContext));
+    s->y = s->state = 0;
+
     /* init the zlib */
     s->zstream.zalloc = ff_png_zalloc;
-    s->zstream.zfree = ff_png_zfree;
+    s->zstream.zfree  = ff_png_zfree;
     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;
     }
-    for(;;) {
+    for (;;) {
         if (bytestream2_get_bytes_left(&s->gb) <= 0) {
             av_log(avctx, AV_LOG_ERROR, "No bytes left\n");
             goto fail;
@@ -562,14 +559,14 @@
                 ((tag >> 8) & 0xff),
                 ((tag >> 16) & 0xff),
                 ((tag >> 24) & 0xff), length);
-        switch(tag) {
+        switch (tag) {
         case MKTAG('I', 'H', 'D', 'R'):
             if (length != 13)
                 goto fail;
             s->width  = bytestream2_get_be32(&s->gb);
             s->height = bytestream2_get_be32(&s->gb);
-            if(av_image_check_size(s->width, s->height, 0, avctx)){
-                s->width= s->height= 0;
+            if (av_image_check_size(s->width, s->height, 0, avctx)) {
+                s->width = s->height = 0;
                 av_log(avctx, AV_LOG_ERROR, "Invalid image size\n");
                 goto fail;
             }
@@ -581,7 +578,8 @@
             bytestream2_skip(&s->gb, 4); /* crc */
             s->state |= PNG_IHDR;
             if (avctx->debug & FF_DEBUG_PICT_INFO)
-                av_log(avctx, AV_LOG_DEBUG, "width=%d height=%d depth=%d color_type=%d compression_type=%d filter_type=%d interlace_type=%d\n",
+                av_log(avctx, AV_LOG_DEBUG, "width=%d height=%d depth=%d color_type=%d "
+                    "compression_type=%d filter_type=%d interlace_type=%d\n",
                     s->width, s->height, s->bit_depth, s->color_type,
                     s->compression_type, s->filter_type, s->interlace_type);
             break;
@@ -604,13 +602,13 @@
             }
             if (!(s->state & PNG_IDAT)) {
                 /* init image info */
-                avctx->width = s->width;
+                avctx->width  = s->width;
                 avctx->height = s->height;
 
-                s->channels = ff_png_get_nb_channels(s->color_type);
+                s->channels       = ff_png_get_nb_channels(s->color_type);
                 s->bits_per_pixel = s->bit_depth * s->channels;
-                s->bpp = (s->bits_per_pixel + 7) >> 3;
-                s->row_size = (avctx->width * s->bits_per_pixel + 7) >> 3;
+                s->bpp            = (s->bits_per_pixel + 7) >> 3;
+                s->row_size       = (avctx->width * s->bits_per_pixel + 7) >> 3;
 
                 if ((s->bit_depth == 2 || s->bit_depth == 4 || s->bit_depth == 8) &&
                     s->color_type == PNG_COLOR_TYPE_RGB) {
@@ -644,16 +642,16 @@
                                                  s->bit_depth, s->color_type);
                     goto fail;
                 }
-                if(p->data[0])
+                if (p->data[0])
                     avctx->release_buffer(avctx, p);
 
-                p->reference= 3;
-                if(avctx->get_buffer(avctx, p) < 0){
+                p->reference = 3;
+                if (ff_get_buffer(avctx, p) < 0) {
                     av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
                     goto fail;
                 }
-                p->pict_type= AV_PICTURE_TYPE_I;
-                p->key_frame= 1;
+                p->pict_type        = AV_PICTURE_TYPE_I;
+                p->key_frame        = 1;
                 p->interlaced_frame = !!s->interlace_type;
 
                 /* compute the compressed row size */
@@ -668,7 +666,7 @@
                 }
                 av_dlog(avctx, "row_size=%d crow_size =%d\n",
                         s->row_size, s->crow_size);
-                s->image_buf = p->data[0];
+                s->image_buf      = p->data[0];
                 s->image_linesize = p->linesize[0];
                 /* copy the palette if needed */
                 if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
@@ -689,9 +687,9 @@
                     goto fail;
 
                 /* we want crow_buf+1 to be 16-byte aligned */
-                s->crow_buf = crow_buf_base + 15;
+                s->crow_buf          = crow_buf_base + 15;
                 s->zstream.avail_out = s->crow_size;
-                s->zstream.next_out = s->crow_buf;
+                s->zstream.next_out  = s->crow_buf;
             }
             s->state |= PNG_IDAT;
             if (png_decode_idat(s, length) < 0)
@@ -706,13 +704,13 @@
                     goto skip_tag;
                 /* read the palette */
                 n = length / 3;
-                for(i=0;i<n;i++) {
+                for (i = 0; i < n; i++) {
                     r = bytestream2_get_byte(&s->gb);
                     g = bytestream2_get_byte(&s->gb);
                     b = bytestream2_get_byte(&s->gb);
                     s->palette[i] = (0xFFU << 24) | (r << 16) | (g << 8) | b;
                 }
-                for(;i<256;i++) {
+                for (; i < 256; i++) {
                     s->palette[i] = (0xFFU << 24);
                 }
                 s->state |= PNG_PLTE;
@@ -728,7 +726,7 @@
                     length > 256 ||
                     !(s->state & PNG_PLTE))
                     goto skip_tag;
-                for(i=0;i<length;i++) {
+                for (i = 0; i < length; i++) {
                     v = bytestream2_get_byte(&s->gb);
                     s->palette[i] = (s->palette[i] & 0x00ffffff) | (v << 24);
                 }
@@ -762,58 +760,72 @@
     }
  exit_loop:
 
-    if(s->bits_per_pixel == 1 && s->color_type == PNG_COLOR_TYPE_PALETTE){
-        int i, j;
+    if (s->bits_per_pixel == 1 && s->color_type == PNG_COLOR_TYPE_PALETTE){
+        int i, j, k;
         uint8_t *pd = s->current_picture->data[0];
-        for(j=0; j < s->height; j++) {
-            for(i=s->width/8-1; i>=0; i--) {
-                pd[8*i+7]=  pd[i]    &1;
-                pd[8*i+6]= (pd[i]>>1)&1;
-                pd[8*i+5]= (pd[i]>>2)&1;
-                pd[8*i+4]= (pd[i]>>3)&1;
-                pd[8*i+3]= (pd[i]>>4)&1;
-                pd[8*i+2]= (pd[i]>>5)&1;
-                pd[8*i+1]= (pd[i]>>6)&1;
-                pd[8*i+0]=  pd[i]>>7;
+        for (j = 0; j < s->height; j++) {
+            i = s->width / 8;
+            for (k = 7; k >= 1; k--)
+                if ((s->width&7) >= k)
+                    pd[8*i + k - 1] = (pd[i]>>8-k) & 1;
+            for (i--; i >= 0; i--) {
+                pd[8*i + 7]=  pd[i]     & 1;
+                pd[8*i + 6]= (pd[i]>>1) & 1;
+                pd[8*i + 5]= (pd[i]>>2) & 1;
+                pd[8*i + 4]= (pd[i]>>3) & 1;
+                pd[8*i + 3]= (pd[i]>>4) & 1;
+                pd[8*i + 2]= (pd[i]>>5) & 1;
+                pd[8*i + 1]= (pd[i]>>6) & 1;
+                pd[8*i + 0]=  pd[i]>>7;
             }
             pd += s->image_linesize;
         }
     }
-    if(s->bits_per_pixel == 2){
+    if (s->bits_per_pixel == 2){
         int i, j;
         uint8_t *pd = s->current_picture->data[0];
-        for(j=0; j < s->height; j++) {
+        for (j = 0; j < s->height; j++) {
+            i = s->width / 4;
             if (s->color_type == PNG_COLOR_TYPE_PALETTE){
-            for(i=s->width/4-1; i>=0; i--) {
-                pd[4*i+3]=  pd[i]    &3;
-                pd[4*i+2]= (pd[i]>>2)&3;
-                pd[4*i+1]= (pd[i]>>4)&3;
-                pd[4*i+0]=  pd[i]>>6;
-            }
+                if ((s->width&3) >= 3) pd[4*i + 2]= (pd[i] >> 2) & 3;
+                if ((s->width&3) >= 2) pd[4*i + 1]= (pd[i] >> 4) & 3;
+                if ((s->width&3) >= 1) pd[4*i + 0]=  pd[i] >> 6;
+                for (i--; i >= 0; i--) {
+                    pd[4*i + 3]=  pd[i]     & 3;
+                    pd[4*i + 2]= (pd[i]>>2) & 3;
+                    pd[4*i + 1]= (pd[i]>>4) & 3;
+                    pd[4*i + 0]=  pd[i]>>6;
+                }
             } else {
-                for(i=s->width/4-1; i>=0; i--) {
-                    pd[4*i+3]= ( pd[i]    &3)*0x55;
-                    pd[4*i+2]= ((pd[i]>>2)&3)*0x55;
-                    pd[4*i+1]= ((pd[i]>>4)&3)*0x55;
-                    pd[4*i+0]= ( pd[i]>>6   )*0x55;
+                if ((s->width&3) >= 3) pd[4*i + 2]= ((pd[i]>>2) & 3)*0x55;
+                if ((s->width&3) >= 2) pd[4*i + 1]= ((pd[i]>>4) & 3)*0x55;
+                if ((s->width&3) >= 1) pd[4*i + 0]= ( pd[i]>>6     )*0x55;
+                for (i--; i >= 0; i--) {
+                    pd[4*i + 3]= ( pd[i]     & 3)*0x55;
+                    pd[4*i + 2]= ((pd[i]>>2) & 3)*0x55;
+                    pd[4*i + 1]= ((pd[i]>>4) & 3)*0x55;
+                    pd[4*i + 0]= ( pd[i]>>6     )*0x55;
                 }
             }
             pd += s->image_linesize;
         }
     }
-    if(s->bits_per_pixel == 4){
+    if (s->bits_per_pixel == 4){
         int i, j;
         uint8_t *pd = s->current_picture->data[0];
-        for(j=0; j < s->height; j++) {
+        for (j = 0; j < s->height; j++) {
+            i = s->width/2;
             if (s->color_type == PNG_COLOR_TYPE_PALETTE){
-            for(i=s->width/2-1; i>=0; i--) {
-                pd[2*i+1]= pd[i]&15;
-                pd[2*i+0]= pd[i]>>4;
+                if (s->width&1) pd[2*i+0]= pd[i]>>4;
+                for (i--; i >= 0; i--) {
+                pd[2*i + 1] = pd[i] & 15;
+                pd[2*i + 0] = pd[i] >> 4;
             }
             } else {
-                for(i=s->width/2-1; i>=0; i--) {
-                    pd[2*i+1]= (pd[i]&15)*0x11;
-                    pd[2*i+0]= (pd[i]>>4)*0x11;
+                if (s->width & 1) pd[2*i + 0]= (pd[i] >> 4) * 0x11;
+                for (i--; i >= 0; i--) {
+                    pd[2*i + 1] = (pd[i] & 15) * 0x11;
+                    pd[2*i + 0] = (pd[i] >> 4) * 0x11;
                 }
             }
             pd += s->image_linesize;
@@ -821,30 +833,30 @@
     }
 
      /* handle p-frames only if a predecessor frame is available */
-     if(s->last_picture->data[0] != NULL) {
-         if(   !(avpkt->flags & AV_PKT_FLAG_KEY)
+     if (s->last_picture->data[0] != NULL) {
+         if (   !(avpkt->flags & AV_PKT_FLAG_KEY)
             && s->last_picture->width == s->current_picture->width
             && s->last_picture->height== s->current_picture->height
             && s->last_picture->format== s->current_picture->format
          ) {
             int i, j;
-            uint8_t *pd = s->current_picture->data[0];
+            uint8_t *pd      = s->current_picture->data[0];
             uint8_t *pd_last = s->last_picture->data[0];
 
-            for(j=0; j < s->height; j++) {
-                for(i=0; i < s->width * s->bpp; i++) {
+            for (j = 0; j < s->height; j++) {
+                for (i = 0; i < s->width * s->bpp; i++) {
                     pd[i] += pd_last[i];
                 }
-                pd += s->image_linesize;
+                pd      += s->image_linesize;
                 pd_last += s->image_linesize;
             }
         }
     }
 
     s->current_picture->metadata = metadata;
-    metadata = NULL;
-    *picture= *s->current_picture;
-    *data_size = sizeof(AVFrame);
+    metadata   = NULL;
+    *picture   = *s->current_picture;
+    *got_frame = 1;
 
     ret = bytestream2_tell(&s->gb);
  the_end:
@@ -865,7 +877,7 @@
     PNGDecContext *s = avctx->priv_data;
 
     s->current_picture = &s->picture1;
-    s->last_picture = &s->picture2;
+    s->last_picture    = &s->picture2;
     avcodec_get_frame_defaults(&s->picture1);
     avcodec_get_frame_defaults(&s->picture2);
 
diff --git a/libavcodec/pngenc.c b/libavcodec/pngenc.c
index c91f289..a401c78 100644
--- a/libavcodec/pngenc.c
+++ b/libavcodec/pngenc.c
@@ -244,12 +244,10 @@
         color_type = PNG_COLOR_TYPE_RGB;
         break;
     case AV_PIX_FMT_RGBA:
-        avctx->bits_per_coded_sample = 32;
         bit_depth = 8;
         color_type = PNG_COLOR_TYPE_RGB_ALPHA;
         break;
     case AV_PIX_FMT_RGB24:
-        avctx->bits_per_coded_sample = 24;
         bit_depth = 8;
         color_type = PNG_COLOR_TYPE_RGB;
         break;
@@ -258,7 +256,6 @@
         color_type = PNG_COLOR_TYPE_GRAY;
         break;
     case AV_PIX_FMT_GRAY8:
-        avctx->bits_per_coded_sample = 0x28;
         bit_depth = 8;
         color_type = PNG_COLOR_TYPE_GRAY;
         break;
@@ -267,12 +264,10 @@
         color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
         break;
     case AV_PIX_FMT_MONOBLACK:
-        avctx->bits_per_coded_sample =
         bit_depth = 1;
         color_type = PNG_COLOR_TYPE_GRAY;
         break;
     case AV_PIX_FMT_PAL8:
-        avctx->bits_per_coded_sample =
         bit_depth = 8;
         color_type = PNG_COLOR_TYPE_PALETTE;
         break;
@@ -372,7 +367,7 @@
         int pass;
 
         for(pass = 0; pass < NB_PASSES; pass++) {
-            /* NOTE: a pass is completely omited if no pixels would be
+            /* NOTE: a pass is completely omitted if no pixels would be
                output */
             pass_row_size = ff_png_pass_row_size(pass, bits_per_pixel, avctx->width);
             if (pass_row_size > 0) {
@@ -437,6 +432,23 @@
 static av_cold int png_enc_init(AVCodecContext *avctx){
     PNGEncContext *s = avctx->priv_data;
 
+    switch(avctx->pix_fmt) {
+    case AV_PIX_FMT_RGBA:
+        avctx->bits_per_coded_sample = 32;
+        break;
+    case AV_PIX_FMT_RGB24:
+        avctx->bits_per_coded_sample = 24;
+        break;
+    case AV_PIX_FMT_GRAY8:
+        avctx->bits_per_coded_sample = 0x28;
+        break;
+    case AV_PIX_FMT_MONOBLACK:
+        avctx->bits_per_coded_sample = 1;
+        break;
+    case AV_PIX_FMT_PAL8:
+        avctx->bits_per_coded_sample = 8;
+    }
+
     avcodec_get_frame_defaults(&s->picture);
     avctx->coded_frame= &s->picture;
     ff_dsputil_init(&s->dsp, avctx);
diff --git a/libavcodec/pnm.c b/libavcodec/pnm.c
index 13ecbb0..6d1eb6d 100644
--- a/libavcodec/pnm.c
+++ b/libavcodec/pnm.c
@@ -65,7 +65,7 @@
     pnm_get(s, buf1, sizeof(buf1));
     s->type= buf1[1]-'0';
     if(buf1[0] != 'P')
-        return -1;
+        return AVERROR_INVALIDDATA;
 
     if (s->type==1 || s->type==4) {
         avctx->pix_fmt = AV_PIX_FMT_MONOWHITE;
@@ -103,12 +103,12 @@
             } else if (!strcmp(buf1, "ENDHDR")) {
                 break;
             } else {
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
         }
         /* check that all tags are present */
         if (w <= 0 || h <= 0 || maxval <= 0 || depth <= 0 || tuple_type[0] == '\0' || av_image_check_size(w, h, 0, avctx) || s->bytestream >= s->bytestream_end)
-            return -1;
+            return AVERROR_INVALIDDATA;
 
         avctx->width  = w;
         avctx->height = h;
@@ -137,18 +137,18 @@
                 avctx->pix_fmt = AV_PIX_FMT_RGBA64BE;
             }
         } else {
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
         return 0;
     } else {
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     pnm_get(s, buf1, sizeof(buf1));
     w = atoi(buf1);
     pnm_get(s, buf1, sizeof(buf1));
     h = atoi(buf1);
     if(w <= 0 || h <= 0 || av_image_check_size(w, h, 0, avctx) || s->bytestream >= s->bytestream_end)
-        return -1;
+        return AVERROR_INVALIDDATA;
 
     avctx->width  = w;
     avctx->height = h;
@@ -165,21 +165,28 @@
                 avctx->pix_fmt = AV_PIX_FMT_GRAY16BE;
             } else if (avctx->pix_fmt == AV_PIX_FMT_RGB24) {
                 avctx->pix_fmt = AV_PIX_FMT_RGB48BE;
+            } else if (avctx->pix_fmt == AV_PIX_FMT_YUV420P && s->maxval < 65536) {
+                if (s->maxval < 512)
+                    avctx->pix_fmt = AV_PIX_FMT_YUV420P9BE;
+                else if (s->maxval < 1024)
+                    avctx->pix_fmt = AV_PIX_FMT_YUV420P10BE;
+                else
+                    avctx->pix_fmt = AV_PIX_FMT_YUV420P16;
             } else {
                 av_log(avctx, AV_LOG_ERROR, "Unsupported pixel format\n");
                 avctx->pix_fmt = AV_PIX_FMT_NONE;
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
         }
     }else
         s->maxval=1;
     /* more check if YUV420 */
-    if (avctx->pix_fmt == AV_PIX_FMT_YUV420P) {
+    if (av_pix_fmt_desc_get(avctx->pix_fmt)->flags & PIX_FMT_PLANAR) {
         if ((avctx->width & 1) != 0)
-            return -1;
+            return AVERROR_INVALIDDATA;
         h = (avctx->height * 2);
         if ((h % 3) != 0)
-            return -1;
+            return AVERROR_INVALIDDATA;
         h /= 3;
         avctx->height = h;
     }
diff --git a/libavcodec/pnm.h b/libavcodec/pnm.h
index ac4b108..bb2cc77 100644
--- a/libavcodec/pnm.h
+++ b/libavcodec/pnm.h
@@ -34,7 +34,7 @@
 } PNMContext;
 
 int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s);
-av_cold int ff_pnm_end(AVCodecContext *avctx);
-av_cold int ff_pnm_init(AVCodecContext *avctx);
+int ff_pnm_end(AVCodecContext *avctx);
+int ff_pnm_init(AVCodecContext *avctx);
 
 #endif /* AVCODEC_PNM_H */
diff --git a/libavcodec/pnmdec.c b/libavcodec/pnmdec.c
index 66fc9df..3280eef 100644
--- a/libavcodec/pnmdec.c
+++ b/libavcodec/pnmdec.c
@@ -20,12 +20,13 @@
  */
 
 #include "avcodec.h"
+#include "internal.h"
 #include "put_bits.h"
 #include "pnm.h"
 
 
 static int pnm_decode_frame(AVCodecContext *avctx, void *data,
-                            int *data_size, AVPacket *avpkt)
+                            int *got_frame, AVPacket *avpkt)
 {
     const uint8_t *buf   = avpkt->data;
     int buf_size         = avpkt->size;
@@ -40,14 +41,14 @@
     s->bytestream       = (uint8_t *)buf;
     s->bytestream_end   = (uint8_t *)buf + buf_size;
 
-    if (ff_pnm_decode_header(avctx, s) < 0)
-        return AVERROR_INVALIDDATA;
+    if ((ret = ff_pnm_decode_header(avctx, s)) < 0)
+        return ret;
 
     if (p->data[0])
         avctx->release_buffer(avctx, p);
 
     p->reference = 0;
-    if ((ret = avctx->get_buffer(avctx, p)) < 0) {
+    if ((ret = ff_get_buffer(avctx, p)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -56,7 +57,7 @@
 
     switch (avctx->pix_fmt) {
     default:
-        return AVERROR_INVALIDDATA;
+        return AVERROR(EINVAL);
     case AV_PIX_FMT_RGBA64BE:
         n = avctx->width * 8;
         components=4;
@@ -156,12 +157,16 @@
         }
         break;
     case AV_PIX_FMT_YUV420P:
+    case AV_PIX_FMT_YUV420P9BE:
+    case AV_PIX_FMT_YUV420P10BE:
         {
             unsigned char *ptr1, *ptr2;
 
             n        = avctx->width;
             ptr      = p->data[0];
             linesize = p->linesize[0];
+            if (s->maxval >= 256)
+                n *= 2;
             if (s->bytestream + n * avctx->height * 3 / 2 > s->bytestream_end)
                 return AVERROR_INVALIDDATA;
             for (i = 0; i < avctx->height; i++) {
@@ -183,9 +188,50 @@
             }
         }
         break;
+    case AV_PIX_FMT_YUV420P16:
+        {
+            uint16_t *ptr1, *ptr2;
+            const int f = (65535 * 32768 + s->maxval / 2) / s->maxval;
+            unsigned int j, v;
+
+            n        = avctx->width * 2;
+            ptr      = p->data[0];
+            linesize = p->linesize[0];
+            if (s->bytestream + n * avctx->height * 3 / 2 > s->bytestream_end)
+                return AVERROR_INVALIDDATA;
+            for (i = 0; i < avctx->height; i++) {
+                for (j = 0; j < n / 2; j++) {
+                    v = av_be2ne16(((uint16_t *)s->bytestream)[j]);
+                    ((uint16_t *)ptr)[j] = (v * f + 16384) >> 15;
+                }
+                s->bytestream += n;
+                ptr           += linesize;
+            }
+            ptr1 = (uint16_t*)p->data[1];
+            ptr2 = (uint16_t*)p->data[2];
+            n >>= 1;
+            h = avctx->height >> 1;
+            for (i = 0; i < h; i++) {
+                for (j = 0; j < n / 2; j++) {
+                    v = av_be2ne16(((uint16_t *)s->bytestream)[j]);
+                    ptr1[j] = (v * f + 16384) >> 15;
+                }
+                s->bytestream += n;
+
+                for (j = 0; j < n / 2; j++) {
+                    v = av_be2ne16(((uint16_t *)s->bytestream)[j]);
+                    ptr2[j] = (v * f + 16384) >> 15;
+                }
+                s->bytestream += n;
+
+                ptr1 += p->linesize[1] / 2;
+                ptr2 += p->linesize[2] / 2;
+            }
+        }
+        break;
     }
     *picture   = s->picture;
-    *data_size = sizeof(AVPicture);
+    *got_frame = 1;
 
     return s->bytestream - s->bytestream_start;
 }
diff --git a/libavcodec/pnmenc.c b/libavcodec/pnmenc.c
index ab20cf5..8cd96be 100644
--- a/libavcodec/pnmenc.c
+++ b/libavcodec/pnmenc.c
@@ -19,6 +19,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/pixdesc.h"
 #include "avcodec.h"
 #include "internal.h"
 #include "pnm.h"
@@ -77,6 +78,11 @@
         n  = avctx->width;
         h1 = (h * 3) / 2;
         break;
+    case AV_PIX_FMT_YUV420P16BE:
+        c  = '5';
+        n  = avctx->width * 2;
+        h1 = (h * 3) / 2;
+        break;
     default:
         return -1;
     }
@@ -84,8 +90,9 @@
              "P%c\n%d %d\n", c, avctx->width, h1);
     s->bytestream += strlen(s->bytestream);
     if (avctx->pix_fmt != AV_PIX_FMT_MONOWHITE) {
+        int maxdepth = (1 << (av_pix_fmt_desc_get(avctx->pix_fmt)->comp[0].depth_minus1 + 1)) - 1;
         snprintf(s->bytestream, s->bytestream_end - s->bytestream,
-                 "%d\n", (avctx->pix_fmt != AV_PIX_FMT_GRAY16BE && avctx->pix_fmt != AV_PIX_FMT_RGB48BE) ? 255 : 65535);
+                 "%d\n", maxdepth);
         s->bytestream += strlen(s->bytestream);
     }
 
@@ -97,7 +104,7 @@
         ptr           += linesize;
     }
 
-    if (avctx->pix_fmt == AV_PIX_FMT_YUV420P) {
+    if (avctx->pix_fmt == AV_PIX_FMT_YUV420P || avctx->pix_fmt == AV_PIX_FMT_YUV420P16BE) {
         h >>= 1;
         n >>= 1;
         ptr1 = p->data[1];
@@ -142,7 +149,9 @@
     .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_NONE },
+    .pix_fmts       = (const enum AVPixelFormat[]){
+        AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P16BE, AV_PIX_FMT_NONE
+    },
     .long_name      = NULL_IF_CONFIG_SMALL("PGMYUV (Portable GrayMap YUV) image"),
 };
 #endif
diff --git a/libavcodec/ppc/Makefile b/libavcodec/ppc/Makefile
index f7548e3..a2ce9eb 100644
--- a/libavcodec/ppc/Makefile
+++ b/libavcodec/ppc/Makefile
@@ -1,5 +1,9 @@
 OBJS                                   += ppc/dsputil_ppc.o             \
+                                          ppc/videodsp_ppc.o            \
 
+OBJS-$(CONFIG_H264CHROMA)              += ppc/h264chroma_init.o
+OBJS-$(CONFIG_H264QPEL)                += ppc/h264_qpel.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
@@ -13,7 +17,6 @@
 
 ALTIVEC-OBJS                           += ppc/dsputil_altivec.o         \
                                           ppc/fdct_altivec.o            \
-                                          ppc/float_altivec.o           \
                                           ppc/fmtconvert_altivec.o      \
                                           ppc/gmc_altivec.o             \
                                           ppc/idct_altivec.o            \
diff --git a/libavcodec/ppc/dsputil_altivec.c b/libavcodec/ppc/dsputil_altivec.c
index 5619c3f..75a6a6a 100644
--- a/libavcodec/ppc/dsputil_altivec.c
+++ b/libavcodec/ppc/dsputil_altivec.c
@@ -24,6 +24,7 @@
 #if HAVE_ALTIVEC_H
 #include <altivec.h>
 #endif
+#include "libavutil/attributes.h"
 #include "libavutil/ppc/types_altivec.h"
 #include "libavutil/ppc/util_altivec.h"
 #include "libavcodec/dsputil.h"
@@ -476,7 +477,7 @@
     return s;
 }
 
-static void get_pixels_altivec(DCTELEM *av_restrict block, const uint8_t *pixels, int line_size)
+static void get_pixels_altivec(int16_t *restrict block, const uint8_t *pixels, int line_size)
 {
     int i;
     vector unsigned char perm = vec_lvsl(0, pixels);
@@ -502,7 +503,7 @@
     }
 }
 
-static void diff_pixels_altivec(DCTELEM *av_restrict block, const uint8_t *s1,
+static void diff_pixels_altivec(int16_t *restrict block, const uint8_t *s1,
         const uint8_t *s2, int stride)
 {
     int i;
@@ -576,7 +577,7 @@
 }
 
 
-static void clear_block_altivec(DCTELEM *block) {
+static void clear_block_altivec(int16_t *block) {
     LOAD_ZERO;
     vec_st(zero_s16v,   0, block);
     vec_st(zero_s16v,  16, block);
@@ -607,7 +608,7 @@
 }
 
 /* next one assumes that ((line_size % 16) == 0) */
-void ff_put_pixels16_altivec(uint8_t *block, const uint8_t *pixels, int line_size, int h)
+void ff_put_pixels16_altivec(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
 {
     register vector unsigned char pixelsv1, pixelsv2;
     register vector unsigned char pixelsv1B, pixelsv2B;
@@ -616,9 +617,9 @@
 
     register vector unsigned char perm = vec_lvsl(0, pixels);
     int i;
-    register int line_size_2 = line_size << 1;
-    register int line_size_3 = line_size + line_size_2;
-    register int line_size_4 = line_size << 2;
+    register ptrdiff_t line_size_2 = line_size << 1;
+    register ptrdiff_t line_size_3 = line_size + line_size_2;
+    register ptrdiff_t line_size_4 = line_size << 2;
 
 // hand-unrolling the loop by 4 gains about 15%
 // mininum execution time goes from 74 to 60 cycles
@@ -649,7 +650,7 @@
 
 /* next one assumes that ((line_size % 16) == 0) */
 #define op_avg(a,b)  a = ( ((a)|(b)) - ((((a)^(b))&0xFEFEFEFEUL)>>1) )
-void ff_avg_pixels16_altivec(uint8_t *block, const uint8_t *pixels, int line_size, int h)
+void ff_avg_pixels16_altivec(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
 {
     register vector unsigned char pixelsv1, pixelsv2, pixelsv, blockv;
     register vector unsigned char perm = vec_lvsl(0, pixels);
@@ -668,7 +669,7 @@
 }
 
 /* next one assumes that ((line_size % 8) == 0) */
-static void avg_pixels8_altivec(uint8_t * block, const uint8_t * pixels, int line_size, int h)
+static void avg_pixels8_altivec(uint8_t * block, const uint8_t * pixels, ptrdiff_t line_size, int h)
 {
     register vector unsigned char pixelsv1, pixelsv2, pixelsv, blockv;
     int i;
@@ -699,7 +700,7 @@
 }
 
 /* next one assumes that ((line_size % 8) == 0) */
-static void put_pixels8_xy2_altivec(uint8_t *block, const uint8_t *pixels, int line_size, int h)
+static void put_pixels8_xy2_altivec(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
 {
     register int i;
     register vector unsigned char pixelsv1, pixelsv2, pixelsavg;
@@ -758,7 +759,7 @@
 }
 
 /* next one assumes that ((line_size % 8) == 0) */
-static void put_no_rnd_pixels8_xy2_altivec(uint8_t *block, const uint8_t *pixels, int line_size, int h)
+static void put_no_rnd_pixels8_xy2_altivec(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
 {
     register int i;
     register vector unsigned char pixelsv1, pixelsv2, pixelsavg;
@@ -818,7 +819,7 @@
 }
 
 /* next one assumes that ((line_size % 16) == 0) */
-static void put_pixels16_xy2_altivec(uint8_t * block, const uint8_t * pixels, int line_size, int h)
+static void put_pixels16_xy2_altivec(uint8_t * block, const uint8_t * pixels, ptrdiff_t line_size, int h)
 {
     register int i;
     register vector unsigned char pixelsv1, pixelsv2, pixelsv3, pixelsv4;
@@ -886,7 +887,7 @@
 }
 
 /* next one assumes that ((line_size % 16) == 0) */
-static void put_no_rnd_pixels16_xy2_altivec(uint8_t * block, const uint8_t * pixels, int line_size, int h)
+static void put_no_rnd_pixels16_xy2_altivec(uint8_t * block, const uint8_t * pixels, ptrdiff_t line_size, int h)
 {
     register int i;
     register vector unsigned char pixelsv1, pixelsv2, pixelsv3, pixelsv4;
@@ -1283,31 +1284,8 @@
     return score;
 }
 
-static void vorbis_inverse_coupling_altivec(float *mag, float *ang,
-                                            int blocksize)
-{
-    int i;
-    vector float m, a;
-    vector bool int t0, t1;
-    const vector unsigned int v_31 = //XXX
-        vec_add(vec_add(vec_splat_u32(15),vec_splat_u32(15)),vec_splat_u32(1));
-    for (i = 0; i < blocksize; i += 4) {
-        m = vec_ld(0, mag+i);
-        a = vec_ld(0, ang+i);
-        t0 = vec_cmple(m, (vector float)vec_splat_u32(0));
-        t1 = vec_cmple(a, (vector float)vec_splat_u32(0));
-        a = vec_xor(a, (vector float) vec_sl((vector unsigned int)t0, v_31));
-        t0 = (vector bool int)vec_and(a, t1);
-        t1 = (vector bool int)vec_andc(a, t1);
-        a = vec_sub(m, (vector float)t1);
-        m = vec_add(m, (vector float)t0);
-        vec_stl(a, 0, ang+i);
-        vec_stl(m, 0, mag+i);
-    }
-}
-
 /* next one assumes that ((line_size % 8) == 0) */
-static void avg_pixels8_xy2_altivec(uint8_t *block, const uint8_t *pixels, int line_size, int h)
+static void avg_pixels8_xy2_altivec(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
 {
     register int i;
     register vector unsigned char pixelsv1, pixelsv2, pixelsavg;
@@ -1369,7 +1347,7 @@
     }
 }
 
-void ff_dsputil_init_altivec(DSPContext* c, AVCodecContext *avctx)
+av_cold void ff_dsputil_init_altivec(DSPContext *c, AVCodecContext *avctx)
 {
     const int high_bit_depth = avctx->bits_per_raw_sample > 8;
 
@@ -1403,6 +1381,4 @@
 
     c->hadamard8_diff[0] = hadamard8_diff16_altivec;
     c->hadamard8_diff[1] = hadamard8_diff8x8_altivec;
-    if (CONFIG_VORBIS_DECODER)
-        c->vorbis_inverse_coupling = vorbis_inverse_coupling_altivec;
 }
diff --git a/libavcodec/ppc/dsputil_altivec.h b/libavcodec/ppc/dsputil_altivec.h
index 0b5e404..0e769ab 100644
--- a/libavcodec/ppc/dsputil_altivec.h
+++ b/libavcodec/ppc/dsputil_altivec.h
@@ -26,9 +26,9 @@
 #include <stdint.h>
 #include "libavcodec/dsputil.h"
 
-void ff_put_pixels16_altivec(uint8_t *block, const uint8_t *pixels, int line_size, int h);
+void ff_put_pixels16_altivec(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h);
 
-void ff_avg_pixels16_altivec(uint8_t *block, const uint8_t *pixels, int line_size, int h);
+void ff_avg_pixels16_altivec(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h);
 
 void ff_fdct_altivec(int16_t *block);
 void ff_gmc1_altivec(uint8_t *dst, uint8_t *src, int stride, int h,
@@ -36,8 +36,6 @@
 void ff_idct_put_altivec(uint8_t *dest, int line_size, int16_t *block);
 void ff_idct_add_altivec(uint8_t *dest, int line_size, int16_t *block);
 
-void ff_dsputil_h264_init_ppc(DSPContext* c, AVCodecContext *avctx);
-
 void ff_dsputil_init_altivec(DSPContext* c, AVCodecContext *avctx);
 void ff_float_init_altivec(DSPContext* c, AVCodecContext *avctx);
 void ff_int_init_altivec(DSPContext* c, AVCodecContext *avctx);
diff --git a/libavcodec/ppc/dsputil_ppc.c b/libavcodec/ppc/dsputil_ppc.c
index f827a2a..4b2bd60 100644
--- a/libavcodec/ppc/dsputil_ppc.c
+++ b/libavcodec/ppc/dsputil_ppc.c
@@ -22,9 +22,9 @@
 
 #include <string.h>
 
+#include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
 #include "libavutil/mem.h"
-#include "libavcodec/dsputil.h"
 #include "dsputil_altivec.h"
 
 /* ***** WARNING ***** WARNING ***** WARNING ***** */
@@ -47,7 +47,7 @@
 see <http://developer.apple.com/technotes/tn/tn2087.html>
 and <http://developer.apple.com/technotes/tn/tn2086.html>
 */
-static void clear_blocks_dcbz32_ppc(DCTELEM *blocks)
+static void clear_blocks_dcbz32_ppc(int16_t *blocks)
 {
     register int misal = ((unsigned long)blocks & 0x00000010);
     register int i = 0;
@@ -58,7 +58,7 @@
         ((unsigned long*)blocks)[3] = 0L;
         i += 16;
     }
-    for ( ; i < sizeof(DCTELEM)*6*64-31 ; i += 32) {
+    for ( ; i < sizeof(int16_t)*6*64-31 ; i += 32) {
         __asm__ volatile("dcbz %0,%1" : : "b" (blocks), "r" (i) : "memory");
     }
     if (misal) {
@@ -73,7 +73,7 @@
 /* same as above, when dcbzl clear a whole 128B cache line
    i.e. the PPC970 aka G5 */
 #if HAVE_DCBZL
-static void clear_blocks_dcbz128_ppc(DCTELEM *blocks)
+static void clear_blocks_dcbz128_ppc(int16_t *blocks)
 {
     register int misal = ((unsigned long)blocks & 0x0000007f);
     register int i = 0;
@@ -81,17 +81,17 @@
         // we could probably also optimize this case,
         // but there's not much point as the machines
         // aren't available yet (2003-06-26)
-        memset(blocks, 0, sizeof(DCTELEM)*6*64);
+        memset(blocks, 0, sizeof(int16_t)*6*64);
     }
     else
-        for ( ; i < sizeof(DCTELEM)*6*64 ; i += 128) {
+        for ( ; i < sizeof(int16_t)*6*64 ; i += 128) {
             __asm__ volatile("dcbzl %0,%1" : : "b" (blocks), "r" (i) : "memory");
         }
 }
 #else
-static void clear_blocks_dcbz128_ppc(DCTELEM *blocks)
+static void clear_blocks_dcbz128_ppc(int16_t *blocks)
 {
-    memset(blocks, 0, sizeof(DCTELEM)*6*64);
+    memset(blocks, 0, sizeof(int16_t)*6*64);
 }
 #endif
 
@@ -137,16 +137,7 @@
 }
 #endif
 
-static void prefetch_ppc(void *mem, int stride, int h)
-{
-    register const uint8_t *p = mem;
-    do {
-        __asm__ volatile ("dcbt 0,%0" : : "r" (p));
-        p+= stride;
-    } while(--h);
-}
-
-void ff_dsputil_init_ppc(DSPContext* c, AVCodecContext *avctx)
+av_cold void ff_dsputil_init_ppc(DSPContext *c, AVCodecContext *avctx)
 {
     const int high_bit_depth = avctx->bits_per_raw_sample > 8;
     int mm_flags = av_get_cpu_flags();
@@ -159,7 +150,6 @@
     }
 
     // Common optimizations whether AltiVec is available or not
-    c->prefetch = prefetch_ppc;
     if (!high_bit_depth) {
     switch (check_dcbzl_effect()) {
         case 32:
@@ -174,11 +164,8 @@
     }
 
 #if HAVE_ALTIVEC
-    if(CONFIG_H264_DECODER) ff_dsputil_h264_init_ppc(c, avctx);
-
     if (mm_flags & AV_CPU_FLAG_ALTIVEC) {
         ff_dsputil_init_altivec(c, avctx);
-        ff_float_init_altivec(c, avctx);
         ff_int_init_altivec(c, avctx);
         c->gmc1 = ff_gmc1_altivec;
 
diff --git a/libavcodec/ppc/fdct_altivec.c b/libavcodec/ppc/fdct_altivec.c
index 608dac4..acab127 100644
--- a/libavcodec/ppc/fdct_altivec.c
+++ b/libavcodec/ppc/fdct_altivec.c
@@ -23,7 +23,6 @@
 #include <altivec.h>
 #endif
 #include "libavutil/common.h"
-#include "libavcodec/dsputil.h"
 #include "dsputil_altivec.h"
 
 #define vs16(v) ((vector signed short)(v))
diff --git a/libavcodec/ppc/float_altivec.c b/libavcodec/ppc/float_altivec.c
deleted file mode 100644
index e7b04ec..0000000
--- a/libavcodec/ppc/float_altivec.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (c) 2006 Luca Barbato <lu_zero@gentoo.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/ppc/util_altivec.h"
-#include "libavcodec/dsputil.h"
-
-#include "dsputil_altivec.h"
-
-static void vector_fmul_reverse_altivec(float *dst, const float *src0,
-                                        const float *src1, int len)
-{
-    int i;
-    vector float d, s0, s1, h0, l0,
-                 s2, s3, zero = (vector float)vec_splat_u32(0);
-    src1 += len-4;
-    for(i=0; i<len-7; i+=8) {
-        s1 = vec_ld(0, src1-i);              // [a,b,c,d]
-        s0 = vec_ld(0, src0+i);
-        l0 = vec_mergel(s1, s1);             // [c,c,d,d]
-        s3 = vec_ld(-16, src1-i);
-        h0 = vec_mergeh(s1, s1);             // [a,a,b,b]
-        s2 = vec_ld(16, src0+i);
-        s1 = vec_mergeh(vec_mergel(l0,h0),   // [d,b,d,b]
-                        vec_mergeh(l0,h0));  // [c,a,c,a]
-                                             // [d,c,b,a]
-        l0 = vec_mergel(s3, s3);
-        d = vec_madd(s0, s1, zero);
-        h0 = vec_mergeh(s3, s3);
-        vec_st(d, 0, dst+i);
-        s3 = vec_mergeh(vec_mergel(l0,h0),
-                        vec_mergeh(l0,h0));
-        d = vec_madd(s2, s3, zero);
-        vec_st(d, 16, dst+i);
-    }
-}
-
-static void vector_fmul_add_altivec(float *dst, const float *src0,
-                                    const float *src1, const float *src2,
-                                    int len)
-{
-    int i;
-    vector float d, s0, s1, s2, t0, t1, edges;
-    vector unsigned char align = vec_lvsr(0,dst),
-                         mask = vec_lvsl(0, dst);
-
-    for (i=0; i<len-3; i+=4) {
-        t0 = vec_ld(0, dst+i);
-        t1 = vec_ld(15, dst+i);
-        s0 = vec_ld(0, src0+i);
-        s1 = vec_ld(0, src1+i);
-        s2 = vec_ld(0, src2+i);
-        edges = vec_perm(t1 ,t0, mask);
-        d = vec_madd(s0,s1,s2);
-        t1 = vec_perm(d, edges, align);
-        t0 = vec_perm(edges, d, align);
-        vec_st(t1, 15, dst+i);
-        vec_st(t0, 0, dst+i);
-    }
-}
-
-static void vector_fmul_window_altivec(float *dst, const float *src0, const float *src1, const float *win, int len)
-{
-    vector float zero, t0, t1, s0, s1, wi, wj;
-    const vector unsigned char reverse = vcprm(3,2,1,0);
-    int i,j;
-
-    dst += len;
-    win += len;
-    src0+= len;
-
-    zero = (vector float)vec_splat_u32(0);
-
-    for(i=-len*4, j=len*4-16; i<0; i+=16, j-=16) {
-        s0 = vec_ld(i, src0);
-        s1 = vec_ld(j, src1);
-        wi = vec_ld(i, win);
-        wj = vec_ld(j, win);
-
-        s1 = vec_perm(s1, s1, reverse);
-        wj = vec_perm(wj, wj, reverse);
-
-        t0 = vec_madd(s0, wj, zero);
-        t0 = vec_nmsub(s1, wi, t0);
-        t1 = vec_madd(s0, wi, zero);
-        t1 = vec_madd(s1, wj, t1);
-        t1 = vec_perm(t1, t1, reverse);
-
-        vec_st(t0, i, dst);
-        vec_st(t1, j, dst);
-    }
-}
-
-void ff_float_init_altivec(DSPContext* c, AVCodecContext *avctx)
-{
-    c->vector_fmul_reverse = vector_fmul_reverse_altivec;
-    c->vector_fmul_add = vector_fmul_add_altivec;
-    if(!(avctx->flags & CODEC_FLAG_BITEXACT)) {
-        c->vector_fmul_window = vector_fmul_window_altivec;
-    }
-}
diff --git a/libavcodec/ppc/fmtconvert_altivec.c b/libavcodec/ppc/fmtconvert_altivec.c
index d40ce07..b29c7d4 100644
--- a/libavcodec/ppc/fmtconvert_altivec.c
+++ b/libavcodec/ppc/fmtconvert_altivec.c
@@ -21,6 +21,7 @@
 #include "libavcodec/fmtconvert.h"
 
 #include "libavutil/ppc/util_altivec.h"
+#include "libavutil/attributes.h"
 #include "libavutil/mem.h"
 #include "dsputil_altivec.h"
 
@@ -93,7 +94,7 @@
                                           long len, int stride)
 {
     int i;
-    vector signed short d, s;
+    vector signed short d;
 
     for (i = 0; i < len - 7; i += 8) {
         d = float_to_int16_one_altivec(src + i);
@@ -155,7 +156,7 @@
     }
 }
 
-void ff_fmt_convert_init_altivec(FmtConvertContext *c, AVCodecContext *avctx)
+av_cold void ff_fmt_convert_init_altivec(FmtConvertContext *c, AVCodecContext *avctx)
 {
     c->int32_to_float_fmul_scalar = int32_to_float_fmul_scalar_altivec;
     if (!(avctx->flags & CODEC_FLAG_BITEXACT)) {
diff --git a/libavcodec/ppc/gmc_altivec.c b/libavcodec/ppc/gmc_altivec.c
index 4e36121..4db761d 100644
--- a/libavcodec/ppc/gmc_altivec.c
+++ b/libavcodec/ppc/gmc_altivec.c
@@ -23,7 +23,6 @@
 #include "libavutil/mem.h"
 #include "libavutil/ppc/types_altivec.h"
 #include "libavutil/ppc/util_altivec.h"
-#include "libavcodec/dsputil.h"
 #include "dsputil_altivec.h"
 
 /*
diff --git a/libavcodec/ppc/h264_altivec.c b/libavcodec/ppc/h264_altivec.c
index be54b48..3c2bb4d 100644
--- a/libavcodec/ppc/h264_altivec.c
+++ b/libavcodec/ppc/h264_altivec.c
@@ -18,262 +18,14 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/ppc/types_altivec.h"
 #include "libavutil/ppc/util_altivec.h"
-#include "libavcodec/dsputil.h"
 #include "libavcodec/h264data.h"
 #include "libavcodec/h264dsp.h"
 
-#include "dsputil_altivec.h"
-
-#define PUT_OP_U8_ALTIVEC(d, s, dst) d = s
-#define AVG_OP_U8_ALTIVEC(d, s, dst) d = vec_avg(dst, s)
-
-#define OP_U8_ALTIVEC                          PUT_OP_U8_ALTIVEC
-#define PREFIX_h264_chroma_mc8_altivec         put_h264_chroma_mc8_altivec
-#define PREFIX_h264_chroma_mc8_num             altivec_put_h264_chroma_mc8_num
-#define PREFIX_h264_qpel16_h_lowpass_altivec   put_h264_qpel16_h_lowpass_altivec
-#define PREFIX_h264_qpel16_h_lowpass_num       altivec_put_h264_qpel16_h_lowpass_num
-#define PREFIX_h264_qpel16_v_lowpass_altivec   put_h264_qpel16_v_lowpass_altivec
-#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_altivec_template.c"
-#undef OP_U8_ALTIVEC
-#undef PREFIX_h264_chroma_mc8_altivec
-#undef PREFIX_h264_chroma_mc8_num
-#undef PREFIX_h264_qpel16_h_lowpass_altivec
-#undef PREFIX_h264_qpel16_h_lowpass_num
-#undef PREFIX_h264_qpel16_v_lowpass_altivec
-#undef PREFIX_h264_qpel16_v_lowpass_num
-#undef PREFIX_h264_qpel16_hv_lowpass_altivec
-#undef PREFIX_h264_qpel16_hv_lowpass_num
-
-#define OP_U8_ALTIVEC                          AVG_OP_U8_ALTIVEC
-#define PREFIX_h264_chroma_mc8_altivec         avg_h264_chroma_mc8_altivec
-#define PREFIX_h264_chroma_mc8_num             altivec_avg_h264_chroma_mc8_num
-#define PREFIX_h264_qpel16_h_lowpass_altivec   avg_h264_qpel16_h_lowpass_altivec
-#define PREFIX_h264_qpel16_h_lowpass_num       altivec_avg_h264_qpel16_h_lowpass_num
-#define PREFIX_h264_qpel16_v_lowpass_altivec   avg_h264_qpel16_v_lowpass_altivec
-#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_altivec_template.c"
-#undef OP_U8_ALTIVEC
-#undef PREFIX_h264_chroma_mc8_altivec
-#undef PREFIX_h264_chroma_mc8_num
-#undef PREFIX_h264_qpel16_h_lowpass_altivec
-#undef PREFIX_h264_qpel16_h_lowpass_num
-#undef PREFIX_h264_qpel16_v_lowpass_altivec
-#undef PREFIX_h264_qpel16_v_lowpass_num
-#undef PREFIX_h264_qpel16_hv_lowpass_altivec
-#undef PREFIX_h264_qpel16_hv_lowpass_num
-
-#define H264_MC(OPNAME, SIZE, CODETYPE) \
-static void OPNAME ## h264_qpel ## SIZE ## _mc00_ ## CODETYPE (uint8_t *dst, uint8_t *src, int stride){\
-    ff_ ## OPNAME ## pixels ## SIZE ## _ ## CODETYPE(dst, src, stride, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc10_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){ \
-    DECLARE_ALIGNED(16, uint8_t, half)[SIZE*SIZE];\
-    put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(half, src, SIZE, stride);\
-    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, src, half, stride, stride, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc20_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\
-    OPNAME ## h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(dst, src, stride, stride);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc30_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\
-    DECLARE_ALIGNED(16, uint8_t, half)[SIZE*SIZE];\
-    put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(half, src, SIZE, stride);\
-    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, src+1, half, stride, stride, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc01_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\
-    DECLARE_ALIGNED(16, uint8_t, half)[SIZE*SIZE];\
-    put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(half, src, SIZE, stride);\
-    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, src, half, stride, stride, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc02_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\
-    OPNAME ## h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(dst, src, stride, stride);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc03_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\
-    DECLARE_ALIGNED(16, uint8_t, half)[SIZE*SIZE];\
-    put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(half, src, SIZE, stride);\
-    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, src+stride, half, stride, stride, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc11_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\
-    DECLARE_ALIGNED(16, uint8_t, halfH)[SIZE*SIZE];\
-    DECLARE_ALIGNED(16, uint8_t, halfV)[SIZE*SIZE];\
-    put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(halfH, src, SIZE, stride);\
-    put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(halfV, src, SIZE, stride);\
-    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfH, halfV, stride, SIZE, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc31_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\
-    DECLARE_ALIGNED(16, uint8_t, halfH)[SIZE*SIZE];\
-    DECLARE_ALIGNED(16, uint8_t, halfV)[SIZE*SIZE];\
-    put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(halfH, src, SIZE, stride);\
-    put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(halfV, src+1, SIZE, stride);\
-    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfH, halfV, stride, SIZE, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc13_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\
-    DECLARE_ALIGNED(16, uint8_t, halfH)[SIZE*SIZE];\
-    DECLARE_ALIGNED(16, uint8_t, halfV)[SIZE*SIZE];\
-    put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(halfH, src + stride, SIZE, stride);\
-    put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(halfV, src, SIZE, stride);\
-    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfH, halfV, stride, SIZE, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc33_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\
-    DECLARE_ALIGNED(16, uint8_t, halfH)[SIZE*SIZE];\
-    DECLARE_ALIGNED(16, uint8_t, halfV)[SIZE*SIZE];\
-    put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(halfH, src + stride, SIZE, stride);\
-    put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(halfV, src+1, SIZE, stride);\
-    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfH, halfV, stride, SIZE, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc22_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\
-    DECLARE_ALIGNED(16, int16_t, tmp)[SIZE*(SIZE+8)];\
-    OPNAME ## h264_qpel ## SIZE ## _hv_lowpass_ ## CODETYPE(dst, tmp, src, stride, SIZE, stride);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc21_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\
-    DECLARE_ALIGNED(16, uint8_t, halfH)[SIZE*SIZE];\
-    DECLARE_ALIGNED(16, uint8_t, halfHV)[SIZE*SIZE];\
-    DECLARE_ALIGNED(16, int16_t, tmp)[SIZE*(SIZE+8)];\
-    put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(halfH, src, SIZE, stride);\
-    put_h264_qpel ## SIZE ## _hv_lowpass_ ## CODETYPE(halfHV, tmp, src, SIZE, SIZE, stride);\
-    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfH, halfHV, stride, SIZE, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc23_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\
-    DECLARE_ALIGNED(16, uint8_t, halfH)[SIZE*SIZE];\
-    DECLARE_ALIGNED(16, uint8_t, halfHV)[SIZE*SIZE];\
-    DECLARE_ALIGNED(16, int16_t, tmp)[SIZE*(SIZE+8)];\
-    put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(halfH, src + stride, SIZE, stride);\
-    put_h264_qpel ## SIZE ## _hv_lowpass_ ## CODETYPE(halfHV, tmp, src, SIZE, SIZE, stride);\
-    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfH, halfHV, stride, SIZE, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc12_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\
-    DECLARE_ALIGNED(16, uint8_t, halfV)[SIZE*SIZE];\
-    DECLARE_ALIGNED(16, uint8_t, halfHV)[SIZE*SIZE];\
-    DECLARE_ALIGNED(16, int16_t, tmp)[SIZE*(SIZE+8)];\
-    put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(halfV, src, SIZE, stride);\
-    put_h264_qpel ## SIZE ## _hv_lowpass_ ## CODETYPE(halfHV, tmp, src, SIZE, SIZE, stride);\
-    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfV, halfHV, stride, SIZE, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc32_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\
-    DECLARE_ALIGNED(16, uint8_t, halfV)[SIZE*SIZE];\
-    DECLARE_ALIGNED(16, uint8_t, halfHV)[SIZE*SIZE];\
-    DECLARE_ALIGNED(16, int16_t, tmp)[SIZE*(SIZE+8)];\
-    put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(halfV, src+1, SIZE, stride);\
-    put_h264_qpel ## SIZE ## _hv_lowpass_ ## CODETYPE(halfHV, tmp, src, SIZE, SIZE, stride);\
-    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfV, halfHV, stride, SIZE, SIZE);\
-}\
-
-static inline void put_pixels16_l2_altivec( uint8_t * dst, const uint8_t * src1,
-                                    const uint8_t * src2, int dst_stride,
-                                    int src_stride1, int h)
-{
-    int i;
-    vec_u8 a, b, d, tmp1, tmp2, mask, mask_, edges, align;
-
-    mask_ = vec_lvsl(0, src2);
-
-    for (i = 0; i < h; i++) {
-
-        tmp1 = vec_ld(i * src_stride1, src1);
-        mask = vec_lvsl(i * src_stride1, src1);
-        tmp2 = vec_ld(i * src_stride1 + 15, src1);
-
-        a = vec_perm(tmp1, tmp2, mask);
-
-        tmp1 = vec_ld(i * 16, src2);
-        tmp2 = vec_ld(i * 16 + 15, src2);
-
-        b = vec_perm(tmp1, tmp2, mask_);
-
-        tmp1 = vec_ld(0, dst);
-        mask = vec_lvsl(0, dst);
-        tmp2 = vec_ld(15, dst);
-
-        d = vec_avg(a, b);
-
-        edges = vec_perm(tmp2, tmp1, mask);
-
-        align = vec_lvsr(0, dst);
-
-        tmp2 = vec_perm(d, edges, align);
-        tmp1 = vec_perm(edges, d, align);
-
-        vec_st(tmp2, 15, dst);
-        vec_st(tmp1, 0 , dst);
-
-        dst += dst_stride;
-    }
-}
-
-static inline void avg_pixels16_l2_altivec( uint8_t * dst, const uint8_t * src1,
-                                    const uint8_t * src2, int dst_stride,
-                                    int src_stride1, int h)
-{
-    int i;
-    vec_u8 a, b, d, tmp1, tmp2, mask, mask_, edges, align;
-
-    mask_ = vec_lvsl(0, src2);
-
-    for (i = 0; i < h; i++) {
-
-        tmp1 = vec_ld(i * src_stride1, src1);
-        mask = vec_lvsl(i * src_stride1, src1);
-        tmp2 = vec_ld(i * src_stride1 + 15, src1);
-
-        a = vec_perm(tmp1, tmp2, mask);
-
-        tmp1 = vec_ld(i * 16, src2);
-        tmp2 = vec_ld(i * 16 + 15, src2);
-
-        b = vec_perm(tmp1, tmp2, mask_);
-
-        tmp1 = vec_ld(0, dst);
-        mask = vec_lvsl(0, dst);
-        tmp2 = vec_ld(15, dst);
-
-        d = vec_avg(vec_perm(tmp1, tmp2, mask), vec_avg(a, b));
-
-        edges = vec_perm(tmp2, tmp1, mask);
-
-        align = vec_lvsr(0, dst);
-
-        tmp2 = vec_perm(d, edges, align);
-        tmp1 = vec_perm(edges, d, align);
-
-        vec_st(tmp2, 15, dst);
-        vec_st(tmp1, 0 , dst);
-
-        dst += dst_stride;
-    }
-}
-
-/* Implemented but could be faster
-#define put_pixels16_l2_altivec(d,s1,s2,ds,s1s,h) put_pixels16_l2(d,s1,s2,ds,s1s,16,h)
-#define avg_pixels16_l2_altivec(d,s1,s2,ds,s1s,h) avg_pixels16_l2(d,s1,s2,ds,s1s,16,h)
- */
-
-H264_MC(put_, 16, altivec)
-H264_MC(avg_, 16, altivec)
-
-
 /****************************************************************************
  * IDCT transform:
  ****************************************************************************/
@@ -315,7 +67,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, DCTELEM *block, int stride)
+static void ff_h264_idct_add_altivec(uint8_t *dst, int16_t *block, int stride)
 {
     vec_s16 va0, va1, va2, va3;
     vec_s16 vz0, vz1, vz2, vz3;
@@ -335,6 +87,7 @@
     vtmp1 = vec_sld(vtmp0, vtmp0, 8);
     vtmp2 = vec_ld(16,block);
     vtmp3 = vec_sld(vtmp2, vtmp2, 8);
+    memset(block, 0, 16 * sizeof(int16_t));
 
     VEC_1D_DCT(vtmp0,vtmp1,vtmp2,vtmp3,va0,va1,va2,va3);
     VEC_TRANSPOSE_4(va0,va1,va2,va3,vtmp0,vtmp1,vtmp2,vtmp3);
@@ -429,7 +182,7 @@
     vec_st( hv, 0, dest );                                     \
  }
 
-static void ff_h264_idct8_add_altivec( uint8_t *dst, DCTELEM *dct, int stride ) {
+static void ff_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;
@@ -454,6 +207,7 @@
     s5 = vec_ld(0x50, (int16_t*)dct);
     s6 = vec_ld(0x60, (int16_t*)dct);
     s7 = vec_ld(0x70, (int16_t*)dct);
+    memset(dct, 0, 64 * sizeof(int16_t));
 
     IDCT8_1D_ALTIVEC(s0, s1, s2, s3, s4, s5, s6, s7,
                      d0, d1, d2, d3, d4, d5, d6, d7);
@@ -473,7 +227,7 @@
     ALTIVEC_STORE_SUM_CLIP(&dst[7*stride], idct7, perm_ldv, perm_stv, sel);
 }
 
-static av_always_inline void h264_idct_dc_add_internal(uint8_t *dst, DCTELEM *block, int stride, int size)
+static av_always_inline void h264_idct_dc_add_internal(uint8_t *dst, int16_t *block, int stride, int size)
 {
     vec_s16 dc16;
     vec_u8 dcplus, dcminus, v0, v1, v2, v3, aligner;
@@ -482,6 +236,7 @@
     int i;
 
     dc = (block[0] + 32) >> 6;
+    block[0] = 0;
     dc16 = vec_splat((vec_s16) vec_lde(0, &dc), 1);
 
     if (size == 4)
@@ -518,17 +273,17 @@
     }
 }
 
-static void h264_idct_dc_add_altivec(uint8_t *dst, DCTELEM *block, int stride)
+static void h264_idct_dc_add_altivec(uint8_t *dst, int16_t *block, int stride)
 {
     h264_idct_dc_add_internal(dst, block, stride, 4);
 }
 
-static void ff_h264_idct8_dc_add_altivec(uint8_t *dst, DCTELEM *block, int stride)
+static void ff_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, DCTELEM *block, int stride, const uint8_t nnzc[15*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]){
     int i;
     for(i=0; i<16; i++){
         int nnz = nnzc[ scan8[i] ];
@@ -539,7 +294,7 @@
     }
 }
 
-static void ff_h264_idct_add16intra_altivec(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[15*8]){
+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]){
     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);
@@ -547,7 +302,7 @@
     }
 }
 
-static void ff_h264_idct8_add4_altivec(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[15*8]){
+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]){
     int i;
     for(i=0; i<16; i+=4){
         int nnz = nnzc[ scan8[i] ];
@@ -558,7 +313,7 @@
     }
 }
 
-static void ff_h264_idct_add8_altivec(uint8_t **dest, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[15*8]){
+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]){
     int i, j;
     for (j = 1; j < 3; j++) {
         for(i = j * 16; i < j * 16 + 4; i++){
@@ -967,40 +722,8 @@
 H264_WEIGHT(16)
 H264_WEIGHT( 8)
 
-void ff_dsputil_h264_init_ppc(DSPContext* c, AVCodecContext *avctx) {
-    const int high_bit_depth = avctx->bits_per_raw_sample > 8;
-
-    if (av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC) {
-    if (!high_bit_depth) {
-        c->put_h264_chroma_pixels_tab[0] = put_h264_chroma_mc8_altivec;
-        c->avg_h264_chroma_pixels_tab[0] = avg_h264_chroma_mc8_altivec;
-
-#define dspfunc(PFX, IDX, NUM) \
-        c->PFX ## _pixels_tab[IDX][ 0] = PFX ## NUM ## _mc00_altivec; \
-        c->PFX ## _pixels_tab[IDX][ 1] = PFX ## NUM ## _mc10_altivec; \
-        c->PFX ## _pixels_tab[IDX][ 2] = PFX ## NUM ## _mc20_altivec; \
-        c->PFX ## _pixels_tab[IDX][ 3] = PFX ## NUM ## _mc30_altivec; \
-        c->PFX ## _pixels_tab[IDX][ 4] = PFX ## NUM ## _mc01_altivec; \
-        c->PFX ## _pixels_tab[IDX][ 5] = PFX ## NUM ## _mc11_altivec; \
-        c->PFX ## _pixels_tab[IDX][ 6] = PFX ## NUM ## _mc21_altivec; \
-        c->PFX ## _pixels_tab[IDX][ 7] = PFX ## NUM ## _mc31_altivec; \
-        c->PFX ## _pixels_tab[IDX][ 8] = PFX ## NUM ## _mc02_altivec; \
-        c->PFX ## _pixels_tab[IDX][ 9] = PFX ## NUM ## _mc12_altivec; \
-        c->PFX ## _pixels_tab[IDX][10] = PFX ## NUM ## _mc22_altivec; \
-        c->PFX ## _pixels_tab[IDX][11] = PFX ## NUM ## _mc32_altivec; \
-        c->PFX ## _pixels_tab[IDX][12] = PFX ## NUM ## _mc03_altivec; \
-        c->PFX ## _pixels_tab[IDX][13] = PFX ## NUM ## _mc13_altivec; \
-        c->PFX ## _pixels_tab[IDX][14] = PFX ## NUM ## _mc23_altivec; \
-        c->PFX ## _pixels_tab[IDX][15] = PFX ## NUM ## _mc33_altivec
-
-        dspfunc(put_h264_qpel, 0, 16);
-        dspfunc(avg_h264_qpel, 0, 16);
-#undef dspfunc
-    }
-    }
-}
-
-void ff_h264dsp_init_ppc(H264DSPContext *c, const int bit_depth, const int chroma_format_idc)
+av_cold void ff_h264dsp_init_ppc(H264DSPContext *c, const int bit_depth,
+                                 const int chroma_format_idc)
 {
     if (av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC) {
     if (bit_depth == 8) {
diff --git a/libavcodec/ppc/h264_qpel.c b/libavcodec/ppc/h264_qpel.c
new file mode 100644
index 0000000..8938783
--- /dev/null
+++ b/libavcodec/ppc/h264_qpel.c
@@ -0,0 +1,301 @@
+/*
+ * Copyright (c) 2004 Romain Dolbeau <romain@dolbeau.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 "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 "dsputil_altivec.h"
+
+#define PUT_OP_U8_ALTIVEC(d, s, dst) d = s
+#define AVG_OP_U8_ALTIVEC(d, s, dst) d = vec_avg(dst, s)
+
+#define OP_U8_ALTIVEC                          PUT_OP_U8_ALTIVEC
+#define PREFIX_h264_qpel16_h_lowpass_altivec   put_h264_qpel16_h_lowpass_altivec
+#define PREFIX_h264_qpel16_h_lowpass_num       altivec_put_h264_qpel16_h_lowpass_num
+#define PREFIX_h264_qpel16_v_lowpass_altivec   put_h264_qpel16_v_lowpass_altivec
+#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"
+#undef OP_U8_ALTIVEC
+#undef PREFIX_h264_qpel16_h_lowpass_altivec
+#undef PREFIX_h264_qpel16_h_lowpass_num
+#undef PREFIX_h264_qpel16_v_lowpass_altivec
+#undef PREFIX_h264_qpel16_v_lowpass_num
+#undef PREFIX_h264_qpel16_hv_lowpass_altivec
+#undef PREFIX_h264_qpel16_hv_lowpass_num
+
+#define OP_U8_ALTIVEC                          AVG_OP_U8_ALTIVEC
+#define PREFIX_h264_qpel16_h_lowpass_altivec   avg_h264_qpel16_h_lowpass_altivec
+#define PREFIX_h264_qpel16_h_lowpass_num       altivec_avg_h264_qpel16_h_lowpass_num
+#define PREFIX_h264_qpel16_v_lowpass_altivec   avg_h264_qpel16_v_lowpass_altivec
+#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"
+#undef OP_U8_ALTIVEC
+#undef PREFIX_h264_qpel16_h_lowpass_altivec
+#undef PREFIX_h264_qpel16_h_lowpass_num
+#undef PREFIX_h264_qpel16_v_lowpass_altivec
+#undef PREFIX_h264_qpel16_v_lowpass_num
+#undef PREFIX_h264_qpel16_hv_lowpass_altivec
+#undef PREFIX_h264_qpel16_hv_lowpass_num
+
+#define H264_MC(OPNAME, SIZE, CODETYPE) \
+static void OPNAME ## h264_qpel ## SIZE ## _mc00_ ## CODETYPE (uint8_t *dst, uint8_t *src, int stride){\
+    ff_ ## OPNAME ## pixels ## SIZE ## _ ## CODETYPE(dst, src, stride, SIZE);\
+}\
+\
+static void OPNAME ## h264_qpel ## SIZE ## _mc10_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){ \
+    DECLARE_ALIGNED(16, uint8_t, half)[SIZE*SIZE];\
+    put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(half, src, SIZE, stride);\
+    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, src, half, stride, stride, SIZE);\
+}\
+\
+static void OPNAME ## h264_qpel ## SIZE ## _mc20_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\
+    OPNAME ## h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(dst, src, stride, stride);\
+}\
+\
+static void OPNAME ## h264_qpel ## SIZE ## _mc30_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\
+    DECLARE_ALIGNED(16, uint8_t, half)[SIZE*SIZE];\
+    put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(half, src, SIZE, stride);\
+    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, src+1, half, stride, stride, SIZE);\
+}\
+\
+static void OPNAME ## h264_qpel ## SIZE ## _mc01_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\
+    DECLARE_ALIGNED(16, uint8_t, half)[SIZE*SIZE];\
+    put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(half, src, SIZE, stride);\
+    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, src, half, stride, stride, SIZE);\
+}\
+\
+static void OPNAME ## h264_qpel ## SIZE ## _mc02_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\
+    OPNAME ## h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(dst, src, stride, stride);\
+}\
+\
+static void OPNAME ## h264_qpel ## SIZE ## _mc03_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\
+    DECLARE_ALIGNED(16, uint8_t, half)[SIZE*SIZE];\
+    put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(half, src, SIZE, stride);\
+    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, src+stride, half, stride, stride, SIZE);\
+}\
+\
+static void OPNAME ## h264_qpel ## SIZE ## _mc11_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\
+    DECLARE_ALIGNED(16, uint8_t, halfH)[SIZE*SIZE];\
+    DECLARE_ALIGNED(16, uint8_t, halfV)[SIZE*SIZE];\
+    put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(halfH, src, SIZE, stride);\
+    put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(halfV, src, SIZE, stride);\
+    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfH, halfV, stride, SIZE, SIZE);\
+}\
+\
+static void OPNAME ## h264_qpel ## SIZE ## _mc31_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\
+    DECLARE_ALIGNED(16, uint8_t, halfH)[SIZE*SIZE];\
+    DECLARE_ALIGNED(16, uint8_t, halfV)[SIZE*SIZE];\
+    put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(halfH, src, SIZE, stride);\
+    put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(halfV, src+1, SIZE, stride);\
+    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfH, halfV, stride, SIZE, SIZE);\
+}\
+\
+static void OPNAME ## h264_qpel ## SIZE ## _mc13_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\
+    DECLARE_ALIGNED(16, uint8_t, halfH)[SIZE*SIZE];\
+    DECLARE_ALIGNED(16, uint8_t, halfV)[SIZE*SIZE];\
+    put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(halfH, src + stride, SIZE, stride);\
+    put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(halfV, src, SIZE, stride);\
+    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfH, halfV, stride, SIZE, SIZE);\
+}\
+\
+static void OPNAME ## h264_qpel ## SIZE ## _mc33_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\
+    DECLARE_ALIGNED(16, uint8_t, halfH)[SIZE*SIZE];\
+    DECLARE_ALIGNED(16, uint8_t, halfV)[SIZE*SIZE];\
+    put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(halfH, src + stride, SIZE, stride);\
+    put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(halfV, src+1, SIZE, stride);\
+    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfH, halfV, stride, SIZE, SIZE);\
+}\
+\
+static void OPNAME ## h264_qpel ## SIZE ## _mc22_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\
+    DECLARE_ALIGNED(16, int16_t, tmp)[SIZE*(SIZE+8)];\
+    OPNAME ## h264_qpel ## SIZE ## _hv_lowpass_ ## CODETYPE(dst, tmp, src, stride, SIZE, stride);\
+}\
+\
+static void OPNAME ## h264_qpel ## SIZE ## _mc21_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\
+    DECLARE_ALIGNED(16, uint8_t, halfH)[SIZE*SIZE];\
+    DECLARE_ALIGNED(16, uint8_t, halfHV)[SIZE*SIZE];\
+    DECLARE_ALIGNED(16, int16_t, tmp)[SIZE*(SIZE+8)];\
+    put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(halfH, src, SIZE, stride);\
+    put_h264_qpel ## SIZE ## _hv_lowpass_ ## CODETYPE(halfHV, tmp, src, SIZE, SIZE, stride);\
+    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfH, halfHV, stride, SIZE, SIZE);\
+}\
+\
+static void OPNAME ## h264_qpel ## SIZE ## _mc23_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\
+    DECLARE_ALIGNED(16, uint8_t, halfH)[SIZE*SIZE];\
+    DECLARE_ALIGNED(16, uint8_t, halfHV)[SIZE*SIZE];\
+    DECLARE_ALIGNED(16, int16_t, tmp)[SIZE*(SIZE+8)];\
+    put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(halfH, src + stride, SIZE, stride);\
+    put_h264_qpel ## SIZE ## _hv_lowpass_ ## CODETYPE(halfHV, tmp, src, SIZE, SIZE, stride);\
+    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfH, halfHV, stride, SIZE, SIZE);\
+}\
+\
+static void OPNAME ## h264_qpel ## SIZE ## _mc12_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\
+    DECLARE_ALIGNED(16, uint8_t, halfV)[SIZE*SIZE];\
+    DECLARE_ALIGNED(16, uint8_t, halfHV)[SIZE*SIZE];\
+    DECLARE_ALIGNED(16, int16_t, tmp)[SIZE*(SIZE+8)];\
+    put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(halfV, src, SIZE, stride);\
+    put_h264_qpel ## SIZE ## _hv_lowpass_ ## CODETYPE(halfHV, tmp, src, SIZE, SIZE, stride);\
+    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfV, halfHV, stride, SIZE, SIZE);\
+}\
+\
+static void OPNAME ## h264_qpel ## SIZE ## _mc32_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\
+    DECLARE_ALIGNED(16, uint8_t, halfV)[SIZE*SIZE];\
+    DECLARE_ALIGNED(16, uint8_t, halfHV)[SIZE*SIZE];\
+    DECLARE_ALIGNED(16, int16_t, tmp)[SIZE*(SIZE+8)];\
+    put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(halfV, src+1, SIZE, stride);\
+    put_h264_qpel ## SIZE ## _hv_lowpass_ ## CODETYPE(halfHV, tmp, src, SIZE, SIZE, stride);\
+    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfV, halfHV, stride, SIZE, SIZE);\
+}\
+
+static inline void put_pixels16_l2_altivec( uint8_t * dst, const uint8_t * src1,
+                                    const uint8_t * src2, int dst_stride,
+                                    int src_stride1, int h)
+{
+    int i;
+    vec_u8 a, b, d, tmp1, tmp2, mask, mask_, edges, align;
+
+    mask_ = vec_lvsl(0, src2);
+
+    for (i = 0; i < h; i++) {
+
+        tmp1 = vec_ld(i * src_stride1, src1);
+        mask = vec_lvsl(i * src_stride1, src1);
+        tmp2 = vec_ld(i * src_stride1 + 15, src1);
+
+        a = vec_perm(tmp1, tmp2, mask);
+
+        tmp1 = vec_ld(i * 16, src2);
+        tmp2 = vec_ld(i * 16 + 15, src2);
+
+        b = vec_perm(tmp1, tmp2, mask_);
+
+        tmp1 = vec_ld(0, dst);
+        mask = vec_lvsl(0, dst);
+        tmp2 = vec_ld(15, dst);
+
+        d = vec_avg(a, b);
+
+        edges = vec_perm(tmp2, tmp1, mask);
+
+        align = vec_lvsr(0, dst);
+
+        tmp2 = vec_perm(d, edges, align);
+        tmp1 = vec_perm(edges, d, align);
+
+        vec_st(tmp2, 15, dst);
+        vec_st(tmp1, 0 , dst);
+
+        dst += dst_stride;
+    }
+}
+
+static inline void avg_pixels16_l2_altivec( uint8_t * dst, const uint8_t * src1,
+                                    const uint8_t * src2, int dst_stride,
+                                    int src_stride1, int h)
+{
+    int i;
+    vec_u8 a, b, d, tmp1, tmp2, mask, mask_, edges, align;
+
+    mask_ = vec_lvsl(0, src2);
+
+    for (i = 0; i < h; i++) {
+
+        tmp1 = vec_ld(i * src_stride1, src1);
+        mask = vec_lvsl(i * src_stride1, src1);
+        tmp2 = vec_ld(i * src_stride1 + 15, src1);
+
+        a = vec_perm(tmp1, tmp2, mask);
+
+        tmp1 = vec_ld(i * 16, src2);
+        tmp2 = vec_ld(i * 16 + 15, src2);
+
+        b = vec_perm(tmp1, tmp2, mask_);
+
+        tmp1 = vec_ld(0, dst);
+        mask = vec_lvsl(0, dst);
+        tmp2 = vec_ld(15, dst);
+
+        d = vec_avg(vec_perm(tmp1, tmp2, mask), vec_avg(a, b));
+
+        edges = vec_perm(tmp2, tmp1, mask);
+
+        align = vec_lvsr(0, dst);
+
+        tmp2 = vec_perm(d, edges, align);
+        tmp1 = vec_perm(edges, d, align);
+
+        vec_st(tmp2, 15, dst);
+        vec_st(tmp1, 0 , dst);
+
+        dst += dst_stride;
+    }
+}
+
+/* Implemented but could be faster
+#define put_pixels16_l2_altivec(d,s1,s2,ds,s1s,h) put_pixels16_l2(d,s1,s2,ds,s1s,16,h)
+#define avg_pixels16_l2_altivec(d,s1,s2,ds,s1s,h) avg_pixels16_l2(d,s1,s2,ds,s1s,16,h)
+ */
+
+H264_MC(put_, 16, altivec)
+H264_MC(avg_, 16, altivec)
+#endif /* HAVE_ALTIVEC */
+
+av_cold void ff_h264qpel_init_ppc(H264QpelContext *c, int bit_depth)
+{
+#if HAVE_ALTIVEC
+    const int high_bit_depth = bit_depth > 8;
+
+    if (av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC) {
+    if (!high_bit_depth) {
+#define dspfunc(PFX, IDX, NUM) \
+        c->PFX ## _pixels_tab[IDX][ 0] = PFX ## NUM ## _mc00_altivec; \
+        c->PFX ## _pixels_tab[IDX][ 1] = PFX ## NUM ## _mc10_altivec; \
+        c->PFX ## _pixels_tab[IDX][ 2] = PFX ## NUM ## _mc20_altivec; \
+        c->PFX ## _pixels_tab[IDX][ 3] = PFX ## NUM ## _mc30_altivec; \
+        c->PFX ## _pixels_tab[IDX][ 4] = PFX ## NUM ## _mc01_altivec; \
+        c->PFX ## _pixels_tab[IDX][ 5] = PFX ## NUM ## _mc11_altivec; \
+        c->PFX ## _pixels_tab[IDX][ 6] = PFX ## NUM ## _mc21_altivec; \
+        c->PFX ## _pixels_tab[IDX][ 7] = PFX ## NUM ## _mc31_altivec; \
+        c->PFX ## _pixels_tab[IDX][ 8] = PFX ## NUM ## _mc02_altivec; \
+        c->PFX ## _pixels_tab[IDX][ 9] = PFX ## NUM ## _mc12_altivec; \
+        c->PFX ## _pixels_tab[IDX][10] = PFX ## NUM ## _mc22_altivec; \
+        c->PFX ## _pixels_tab[IDX][11] = PFX ## NUM ## _mc32_altivec; \
+        c->PFX ## _pixels_tab[IDX][12] = PFX ## NUM ## _mc03_altivec; \
+        c->PFX ## _pixels_tab[IDX][13] = PFX ## NUM ## _mc13_altivec; \
+        c->PFX ## _pixels_tab[IDX][14] = PFX ## NUM ## _mc23_altivec; \
+        c->PFX ## _pixels_tab[IDX][15] = PFX ## NUM ## _mc33_altivec
+
+        dspfunc(put_h264_qpel, 0, 16);
+        dspfunc(avg_h264_qpel, 0, 16);
+#undef dspfunc
+    }
+    }
+#endif /* HAVE_ALTIVEC */
+}
diff --git a/libavcodec/ppc/h264_altivec_template.c b/libavcodec/ppc/h264_qpel_template.c
similarity index 66%
rename from libavcodec/ppc/h264_altivec_template.c
rename to libavcodec/ppc/h264_qpel_template.c
index 5a08e0e..cfc4560 100644
--- a/libavcodec/ppc/h264_altivec_template.c
+++ b/libavcodec/ppc/h264_qpel_template.c
@@ -26,274 +26,6 @@
 #define ASSERT_ALIGNED(ptr) ;
 #endif
 
-/* this code assume that stride % 16 == 0 */
-
-#define CHROMA_MC8_ALTIVEC_CORE(BIAS1, BIAS2) \
-        vsrc2ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc2uc);\
-        vsrc3ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc3uc);\
-\
-        psum = vec_mladd(vA, vsrc0ssH, BIAS1);\
-        psum = vec_mladd(vB, vsrc1ssH, psum);\
-        psum = vec_mladd(vC, vsrc2ssH, psum);\
-        psum = vec_mladd(vD, vsrc3ssH, psum);\
-        psum = BIAS2(psum);\
-        psum = vec_sr(psum, v6us);\
-\
-        vdst = vec_ld(0, dst);\
-        ppsum = (vec_u8)vec_pack(psum, psum);\
-        vfdst = vec_perm(vdst, ppsum, fperm);\
-\
-        OP_U8_ALTIVEC(fsum, vfdst, vdst);\
-\
-        vec_st(fsum, 0, dst);\
-\
-        vsrc0ssH = vsrc2ssH;\
-        vsrc1ssH = vsrc3ssH;\
-\
-        dst += stride;\
-        src += stride;
-
-#define CHROMA_MC8_ALTIVEC_CORE_SIMPLE \
-\
-        vsrc0ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc0uc);\
-        vsrc1ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc1uc);\
-\
-        psum = vec_mladd(vA, vsrc0ssH, v32ss);\
-        psum = vec_mladd(vE, vsrc1ssH, psum);\
-        psum = vec_sr(psum, v6us);\
-\
-        vdst = vec_ld(0, dst);\
-        ppsum = (vec_u8)vec_pack(psum, psum);\
-        vfdst = vec_perm(vdst, ppsum, fperm);\
-\
-        OP_U8_ALTIVEC(fsum, vfdst, vdst);\
-\
-        vec_st(fsum, 0, dst);\
-\
-        dst += stride;\
-        src += stride;
-
-#define noop(a) a
-#define add28(a) vec_add(v28ss, a)
-
-#ifdef PREFIX_h264_chroma_mc8_altivec
-static void PREFIX_h264_chroma_mc8_altivec(uint8_t * dst, uint8_t * src,
-                                    int stride, int h, int x, int y) {
-    DECLARE_ALIGNED(16, signed int, ABCD)[4] =
-                        {((8 - x) * (8 - y)),
-                         ((    x) * (8 - y)),
-                         ((8 - x) * (    y)),
-                         ((    x) * (    y))};
-    register int i;
-    vec_u8 fperm;
-    const vec_s32 vABCD = vec_ld(0, ABCD);
-    const vec_s16 vA = vec_splat((vec_s16)vABCD, 1);
-    const vec_s16 vB = vec_splat((vec_s16)vABCD, 3);
-    const vec_s16 vC = vec_splat((vec_s16)vABCD, 5);
-    const vec_s16 vD = vec_splat((vec_s16)vABCD, 7);
-    LOAD_ZERO;
-    const vec_s16 v32ss = vec_sl(vec_splat_s16(1),vec_splat_u16(5));
-    const vec_u16 v6us = vec_splat_u16(6);
-    register int loadSecond = (((unsigned long)src) % 16) <= 7 ? 0 : 1;
-    register int reallyBadAlign = (((unsigned long)src) % 16) == 15 ? 1 : 0;
-
-    vec_u8 vsrcAuc, av_uninit(vsrcBuc), vsrcperm0, vsrcperm1;
-    vec_u8 vsrc0uc, vsrc1uc;
-    vec_s16 vsrc0ssH, vsrc1ssH;
-    vec_u8 vsrcCuc, vsrc2uc, vsrc3uc;
-    vec_s16 vsrc2ssH, vsrc3ssH, psum;
-    vec_u8 vdst, ppsum, vfdst, fsum;
-
-    if (((unsigned long)dst) % 16 == 0) {
-        fperm = (vec_u8){0x10, 0x11, 0x12, 0x13,
-                         0x14, 0x15, 0x16, 0x17,
-                         0x08, 0x09, 0x0A, 0x0B,
-                         0x0C, 0x0D, 0x0E, 0x0F};
-    } else {
-        fperm = (vec_u8){0x00, 0x01, 0x02, 0x03,
-                         0x04, 0x05, 0x06, 0x07,
-                         0x18, 0x19, 0x1A, 0x1B,
-                         0x1C, 0x1D, 0x1E, 0x1F};
-    }
-
-    vsrcAuc = vec_ld(0, src);
-
-    if (loadSecond)
-        vsrcBuc = vec_ld(16, src);
-    vsrcperm0 = vec_lvsl(0, src);
-    vsrcperm1 = vec_lvsl(1, src);
-
-    vsrc0uc = vec_perm(vsrcAuc, vsrcBuc, vsrcperm0);
-    if (reallyBadAlign)
-        vsrc1uc = vsrcBuc;
-    else
-        vsrc1uc = vec_perm(vsrcAuc, vsrcBuc, vsrcperm1);
-
-    vsrc0ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc0uc);
-    vsrc1ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc1uc);
-
-    if (ABCD[3]) {
-        if (!loadSecond) {// -> !reallyBadAlign
-            for (i = 0 ; i < h ; i++) {
-                vsrcCuc = vec_ld(stride + 0, src);
-                vsrc2uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm0);
-                vsrc3uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm1);
-
-                CHROMA_MC8_ALTIVEC_CORE(v32ss, noop)
-            }
-        } else {
-            vec_u8 vsrcDuc;
-            for (i = 0 ; i < h ; i++) {
-                vsrcCuc = vec_ld(stride + 0, src);
-                vsrcDuc = vec_ld(stride + 16, src);
-                vsrc2uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm0);
-                if (reallyBadAlign)
-                    vsrc3uc = vsrcDuc;
-                else
-                    vsrc3uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm1);
-
-                CHROMA_MC8_ALTIVEC_CORE(v32ss, noop)
-            }
-        }
-    } else {
-        const vec_s16 vE = vec_add(vB, vC);
-        if (ABCD[2]) { // x == 0 B == 0
-            if (!loadSecond) {// -> !reallyBadAlign
-                for (i = 0 ; i < h ; i++) {
-                    vsrcCuc = vec_ld(stride + 0, src);
-                    vsrc1uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm0);
-                    CHROMA_MC8_ALTIVEC_CORE_SIMPLE
-
-                    vsrc0uc = vsrc1uc;
-                }
-            } else {
-                vec_u8 vsrcDuc;
-                for (i = 0 ; i < h ; i++) {
-                    vsrcCuc = vec_ld(stride + 0, src);
-                    vsrcDuc = vec_ld(stride + 15, src);
-                    vsrc1uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm0);
-                    CHROMA_MC8_ALTIVEC_CORE_SIMPLE
-
-                    vsrc0uc = vsrc1uc;
-                }
-            }
-        } else { // y == 0 C == 0
-            if (!loadSecond) {// -> !reallyBadAlign
-                for (i = 0 ; i < h ; i++) {
-                    vsrcCuc = vec_ld(0, src);
-                    vsrc0uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm0);
-                    vsrc1uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm1);
-
-                    CHROMA_MC8_ALTIVEC_CORE_SIMPLE
-                }
-            } else {
-                vec_u8 vsrcDuc;
-                for (i = 0 ; i < h ; i++) {
-                    vsrcCuc = vec_ld(0, src);
-                    vsrcDuc = vec_ld(15, src);
-                    vsrc0uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm0);
-                    if (reallyBadAlign)
-                        vsrc1uc = vsrcDuc;
-                    else
-                        vsrc1uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm1);
-
-                    CHROMA_MC8_ALTIVEC_CORE_SIMPLE
-                }
-            }
-        }
-    }
-}
-#endif
-
-/* this code assume that stride % 16 == 0 */
-#ifdef PREFIX_no_rnd_vc1_chroma_mc8_altivec
-static void PREFIX_no_rnd_vc1_chroma_mc8_altivec(uint8_t * dst, uint8_t * src, int stride, int h, int x, int y) {
-   DECLARE_ALIGNED(16, signed int, ABCD)[4] =
-                        {((8 - x) * (8 - y)),
-                         ((    x) * (8 - y)),
-                         ((8 - x) * (    y)),
-                         ((    x) * (    y))};
-    register int i;
-    vec_u8 fperm;
-    const vec_s32 vABCD = vec_ld(0, ABCD);
-    const vec_s16 vA = vec_splat((vec_s16)vABCD, 1);
-    const vec_s16 vB = vec_splat((vec_s16)vABCD, 3);
-    const vec_s16 vC = vec_splat((vec_s16)vABCD, 5);
-    const vec_s16 vD = vec_splat((vec_s16)vABCD, 7);
-    LOAD_ZERO;
-    const vec_s16 v28ss = vec_sub(vec_sl(vec_splat_s16(1),vec_splat_u16(5)),vec_splat_s16(4));
-    const vec_u16 v6us  = vec_splat_u16(6);
-    register int loadSecond     = (((unsigned long)src) % 16) <= 7 ? 0 : 1;
-    register int reallyBadAlign = (((unsigned long)src) % 16) == 15 ? 1 : 0;
-
-    vec_u8 vsrcAuc, av_uninit(vsrcBuc), vsrcperm0, vsrcperm1;
-    vec_u8 vsrc0uc, vsrc1uc;
-    vec_s16 vsrc0ssH, vsrc1ssH;
-    vec_u8 vsrcCuc, vsrc2uc, vsrc3uc;
-    vec_s16 vsrc2ssH, vsrc3ssH, psum;
-    vec_u8 vdst, ppsum, vfdst, fsum;
-
-    if (((unsigned long)dst) % 16 == 0) {
-        fperm = (vec_u8){0x10, 0x11, 0x12, 0x13,
-                         0x14, 0x15, 0x16, 0x17,
-                         0x08, 0x09, 0x0A, 0x0B,
-                         0x0C, 0x0D, 0x0E, 0x0F};
-    } else {
-        fperm = (vec_u8){0x00, 0x01, 0x02, 0x03,
-                         0x04, 0x05, 0x06, 0x07,
-                         0x18, 0x19, 0x1A, 0x1B,
-                         0x1C, 0x1D, 0x1E, 0x1F};
-    }
-
-    vsrcAuc = vec_ld(0, src);
-
-    if (loadSecond)
-        vsrcBuc = vec_ld(16, src);
-    vsrcperm0 = vec_lvsl(0, src);
-    vsrcperm1 = vec_lvsl(1, src);
-
-    vsrc0uc = vec_perm(vsrcAuc, vsrcBuc, vsrcperm0);
-    if (reallyBadAlign)
-        vsrc1uc = vsrcBuc;
-    else
-        vsrc1uc = vec_perm(vsrcAuc, vsrcBuc, vsrcperm1);
-
-    vsrc0ssH = (vec_s16)vec_mergeh(zero_u8v, (vec_u8)vsrc0uc);
-    vsrc1ssH = (vec_s16)vec_mergeh(zero_u8v, (vec_u8)vsrc1uc);
-
-    if (!loadSecond) {// -> !reallyBadAlign
-        for (i = 0 ; i < h ; i++) {
-
-
-            vsrcCuc = vec_ld(stride + 0, src);
-
-            vsrc2uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm0);
-            vsrc3uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm1);
-
-            CHROMA_MC8_ALTIVEC_CORE(vec_splat_s16(0), add28)
-        }
-    } else {
-        vec_u8 vsrcDuc;
-        for (i = 0 ; i < h ; i++) {
-            vsrcCuc = vec_ld(stride + 0, src);
-            vsrcDuc = vec_ld(stride + 16, src);
-
-            vsrc2uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm0);
-            if (reallyBadAlign)
-                vsrc3uc = vsrcDuc;
-            else
-                vsrc3uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm1);
-
-            CHROMA_MC8_ALTIVEC_CORE(vec_splat_s16(0), add28)
-        }
-    }
-}
-#endif
-
-#undef noop
-#undef add28
-#undef CHROMA_MC8_ALTIVEC_CORE
-
 /* this code assume stride % 16 == 0 */
 #ifdef PREFIX_h264_qpel16_h_lowpass_altivec
 static void PREFIX_h264_qpel16_h_lowpass_altivec(uint8_t * dst, uint8_t * src, int dstStride, int srcStride) {
diff --git a/libavcodec/ppc/h264chroma_init.c b/libavcodec/ppc/h264chroma_init.c
new file mode 100644
index 0000000..f9e2a76
--- /dev/null
+++ b/libavcodec/ppc/h264chroma_init.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2004 Romain Dolbeau <romain@dolbeau.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 "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 "dsputil_altivec.h"
+
+#define PUT_OP_U8_ALTIVEC(d, s, dst) d = s
+#define AVG_OP_U8_ALTIVEC(d, s, dst) d = vec_avg(dst, s)
+
+#define OP_U8_ALTIVEC                          PUT_OP_U8_ALTIVEC
+#define PREFIX_h264_chroma_mc8_altivec         put_h264_chroma_mc8_altivec
+#define PREFIX_h264_chroma_mc8_num             altivec_put_h264_chroma_mc8_num
+#include "h264chroma_template.c"
+#undef OP_U8_ALTIVEC
+#undef PREFIX_h264_chroma_mc8_altivec
+#undef PREFIX_h264_chroma_mc8_num
+
+#define OP_U8_ALTIVEC                          AVG_OP_U8_ALTIVEC
+#define PREFIX_h264_chroma_mc8_altivec         avg_h264_chroma_mc8_altivec
+#define PREFIX_h264_chroma_mc8_num             altivec_avg_h264_chroma_mc8_num
+#include "h264chroma_template.c"
+#undef OP_U8_ALTIVEC
+#undef PREFIX_h264_chroma_mc8_altivec
+#undef PREFIX_h264_chroma_mc8_num
+#endif /* HAVE_ALTIVEC */
+
+av_cold void ff_h264chroma_init_ppc(H264ChromaContext *c, int bit_depth)
+{
+#if HAVE_ALTIVEC
+    const int high_bit_depth = bit_depth > 8;
+
+    if (av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC) {
+    if (!high_bit_depth) {
+        c->put_h264_chroma_pixels_tab[0] = put_h264_chroma_mc8_altivec;
+        c->avg_h264_chroma_pixels_tab[0] = avg_h264_chroma_mc8_altivec;
+    }
+    }
+#endif /* HAVE_ALTIVEC */
+}
diff --git a/libavcodec/ppc/h264chroma_template.c b/libavcodec/ppc/h264chroma_template.c
new file mode 100644
index 0000000..7436e11
--- /dev/null
+++ b/libavcodec/ppc/h264chroma_template.c
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 2004 Romain Dolbeau <romain@dolbeau.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/mem.h"
+
+/* this code assume that stride % 16 == 0 */
+
+#define CHROMA_MC8_ALTIVEC_CORE(BIAS1, BIAS2) \
+        vsrc2ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc2uc);\
+        vsrc3ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc3uc);\
+\
+        psum = vec_mladd(vA, vsrc0ssH, BIAS1);\
+        psum = vec_mladd(vB, vsrc1ssH, psum);\
+        psum = vec_mladd(vC, vsrc2ssH, psum);\
+        psum = vec_mladd(vD, vsrc3ssH, psum);\
+        psum = BIAS2(psum);\
+        psum = vec_sr(psum, v6us);\
+\
+        vdst = vec_ld(0, dst);\
+        ppsum = (vec_u8)vec_pack(psum, psum);\
+        vfdst = vec_perm(vdst, ppsum, fperm);\
+\
+        OP_U8_ALTIVEC(fsum, vfdst, vdst);\
+\
+        vec_st(fsum, 0, dst);\
+\
+        vsrc0ssH = vsrc2ssH;\
+        vsrc1ssH = vsrc3ssH;\
+\
+        dst += stride;\
+        src += stride;
+
+#define CHROMA_MC8_ALTIVEC_CORE_SIMPLE \
+\
+        vsrc0ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc0uc);\
+        vsrc1ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc1uc);\
+\
+        psum = vec_mladd(vA, vsrc0ssH, v32ss);\
+        psum = vec_mladd(vE, vsrc1ssH, psum);\
+        psum = vec_sr(psum, v6us);\
+\
+        vdst = vec_ld(0, dst);\
+        ppsum = (vec_u8)vec_pack(psum, psum);\
+        vfdst = vec_perm(vdst, ppsum, fperm);\
+\
+        OP_U8_ALTIVEC(fsum, vfdst, vdst);\
+\
+        vec_st(fsum, 0, dst);\
+\
+        dst += stride;\
+        src += stride;
+
+#define noop(a) a
+#define add28(a) vec_add(v28ss, a)
+
+#ifdef PREFIX_h264_chroma_mc8_altivec
+static void PREFIX_h264_chroma_mc8_altivec(uint8_t * dst, uint8_t * src,
+                                    int stride, int h, int x, int y) {
+    DECLARE_ALIGNED(16, signed int, ABCD)[4] =
+                        {((8 - x) * (8 - y)),
+                         ((    x) * (8 - y)),
+                         ((8 - x) * (    y)),
+                         ((    x) * (    y))};
+    register int i;
+    vec_u8 fperm;
+    const vec_s32 vABCD = vec_ld(0, ABCD);
+    const vec_s16 vA = vec_splat((vec_s16)vABCD, 1);
+    const vec_s16 vB = vec_splat((vec_s16)vABCD, 3);
+    const vec_s16 vC = vec_splat((vec_s16)vABCD, 5);
+    const vec_s16 vD = vec_splat((vec_s16)vABCD, 7);
+    LOAD_ZERO;
+    const vec_s16 v32ss = vec_sl(vec_splat_s16(1),vec_splat_u16(5));
+    const vec_u16 v6us = vec_splat_u16(6);
+    register int loadSecond = (((unsigned long)src) % 16) <= 7 ? 0 : 1;
+    register int reallyBadAlign = (((unsigned long)src) % 16) == 15 ? 1 : 0;
+
+    vec_u8 vsrcAuc, av_uninit(vsrcBuc), vsrcperm0, vsrcperm1;
+    vec_u8 vsrc0uc, vsrc1uc;
+    vec_s16 vsrc0ssH, vsrc1ssH;
+    vec_u8 vsrcCuc, vsrc2uc, vsrc3uc;
+    vec_s16 vsrc2ssH, vsrc3ssH, psum;
+    vec_u8 vdst, ppsum, vfdst, fsum;
+
+    if (((unsigned long)dst) % 16 == 0) {
+        fperm = (vec_u8){0x10, 0x11, 0x12, 0x13,
+                         0x14, 0x15, 0x16, 0x17,
+                         0x08, 0x09, 0x0A, 0x0B,
+                         0x0C, 0x0D, 0x0E, 0x0F};
+    } else {
+        fperm = (vec_u8){0x00, 0x01, 0x02, 0x03,
+                         0x04, 0x05, 0x06, 0x07,
+                         0x18, 0x19, 0x1A, 0x1B,
+                         0x1C, 0x1D, 0x1E, 0x1F};
+    }
+
+    vsrcAuc = vec_ld(0, src);
+
+    if (loadSecond)
+        vsrcBuc = vec_ld(16, src);
+    vsrcperm0 = vec_lvsl(0, src);
+    vsrcperm1 = vec_lvsl(1, src);
+
+    vsrc0uc = vec_perm(vsrcAuc, vsrcBuc, vsrcperm0);
+    if (reallyBadAlign)
+        vsrc1uc = vsrcBuc;
+    else
+        vsrc1uc = vec_perm(vsrcAuc, vsrcBuc, vsrcperm1);
+
+    vsrc0ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc0uc);
+    vsrc1ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc1uc);
+
+    if (ABCD[3]) {
+        if (!loadSecond) {// -> !reallyBadAlign
+            for (i = 0 ; i < h ; i++) {
+                vsrcCuc = vec_ld(stride + 0, src);
+                vsrc2uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm0);
+                vsrc3uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm1);
+
+                CHROMA_MC8_ALTIVEC_CORE(v32ss, noop)
+            }
+        } else {
+            vec_u8 vsrcDuc;
+            for (i = 0 ; i < h ; i++) {
+                vsrcCuc = vec_ld(stride + 0, src);
+                vsrcDuc = vec_ld(stride + 16, src);
+                vsrc2uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm0);
+                if (reallyBadAlign)
+                    vsrc3uc = vsrcDuc;
+                else
+                    vsrc3uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm1);
+
+                CHROMA_MC8_ALTIVEC_CORE(v32ss, noop)
+            }
+        }
+    } else {
+        const vec_s16 vE = vec_add(vB, vC);
+        if (ABCD[2]) { // x == 0 B == 0
+            if (!loadSecond) {// -> !reallyBadAlign
+                for (i = 0 ; i < h ; i++) {
+                    vsrcCuc = vec_ld(stride + 0, src);
+                    vsrc1uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm0);
+                    CHROMA_MC8_ALTIVEC_CORE_SIMPLE
+
+                    vsrc0uc = vsrc1uc;
+                }
+            } else {
+                vec_u8 vsrcDuc;
+                for (i = 0 ; i < h ; i++) {
+                    vsrcCuc = vec_ld(stride + 0, src);
+                    vsrcDuc = vec_ld(stride + 15, src);
+                    vsrc1uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm0);
+                    CHROMA_MC8_ALTIVEC_CORE_SIMPLE
+
+                    vsrc0uc = vsrc1uc;
+                }
+            }
+        } else { // y == 0 C == 0
+            if (!loadSecond) {// -> !reallyBadAlign
+                for (i = 0 ; i < h ; i++) {
+                    vsrcCuc = vec_ld(0, src);
+                    vsrc0uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm0);
+                    vsrc1uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm1);
+
+                    CHROMA_MC8_ALTIVEC_CORE_SIMPLE
+                }
+            } else {
+                vec_u8 vsrcDuc;
+                for (i = 0 ; i < h ; i++) {
+                    vsrcCuc = vec_ld(0, src);
+                    vsrcDuc = vec_ld(15, src);
+                    vsrc0uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm0);
+                    if (reallyBadAlign)
+                        vsrc1uc = vsrcDuc;
+                    else
+                        vsrc1uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm1);
+
+                    CHROMA_MC8_ALTIVEC_CORE_SIMPLE
+                }
+            }
+        }
+    }
+}
+#endif
+
+/* this code assume that stride % 16 == 0 */
+#ifdef PREFIX_no_rnd_vc1_chroma_mc8_altivec
+static void PREFIX_no_rnd_vc1_chroma_mc8_altivec(uint8_t * dst, uint8_t * src, int stride, int h, int x, int y) {
+   DECLARE_ALIGNED(16, signed int, ABCD)[4] =
+                        {((8 - x) * (8 - y)),
+                         ((    x) * (8 - y)),
+                         ((8 - x) * (    y)),
+                         ((    x) * (    y))};
+    register int i;
+    vec_u8 fperm;
+    const vec_s32 vABCD = vec_ld(0, ABCD);
+    const vec_s16 vA = vec_splat((vec_s16)vABCD, 1);
+    const vec_s16 vB = vec_splat((vec_s16)vABCD, 3);
+    const vec_s16 vC = vec_splat((vec_s16)vABCD, 5);
+    const vec_s16 vD = vec_splat((vec_s16)vABCD, 7);
+    LOAD_ZERO;
+    const vec_s16 v28ss = vec_sub(vec_sl(vec_splat_s16(1),vec_splat_u16(5)),vec_splat_s16(4));
+    const vec_u16 v6us  = vec_splat_u16(6);
+    register int loadSecond     = (((unsigned long)src) % 16) <= 7 ? 0 : 1;
+    register int reallyBadAlign = (((unsigned long)src) % 16) == 15 ? 1 : 0;
+
+    vec_u8 vsrcAuc, av_uninit(vsrcBuc), vsrcperm0, vsrcperm1;
+    vec_u8 vsrc0uc, vsrc1uc;
+    vec_s16 vsrc0ssH, vsrc1ssH;
+    vec_u8 vsrcCuc, vsrc2uc, vsrc3uc;
+    vec_s16 vsrc2ssH, vsrc3ssH, psum;
+    vec_u8 vdst, ppsum, vfdst, fsum;
+
+    if (((unsigned long)dst) % 16 == 0) {
+        fperm = (vec_u8){0x10, 0x11, 0x12, 0x13,
+                         0x14, 0x15, 0x16, 0x17,
+                         0x08, 0x09, 0x0A, 0x0B,
+                         0x0C, 0x0D, 0x0E, 0x0F};
+    } else {
+        fperm = (vec_u8){0x00, 0x01, 0x02, 0x03,
+                         0x04, 0x05, 0x06, 0x07,
+                         0x18, 0x19, 0x1A, 0x1B,
+                         0x1C, 0x1D, 0x1E, 0x1F};
+    }
+
+    vsrcAuc = vec_ld(0, src);
+
+    if (loadSecond)
+        vsrcBuc = vec_ld(16, src);
+    vsrcperm0 = vec_lvsl(0, src);
+    vsrcperm1 = vec_lvsl(1, src);
+
+    vsrc0uc = vec_perm(vsrcAuc, vsrcBuc, vsrcperm0);
+    if (reallyBadAlign)
+        vsrc1uc = vsrcBuc;
+    else
+        vsrc1uc = vec_perm(vsrcAuc, vsrcBuc, vsrcperm1);
+
+    vsrc0ssH = (vec_s16)vec_mergeh(zero_u8v, (vec_u8)vsrc0uc);
+    vsrc1ssH = (vec_s16)vec_mergeh(zero_u8v, (vec_u8)vsrc1uc);
+
+    if (!loadSecond) {// -> !reallyBadAlign
+        for (i = 0 ; i < h ; i++) {
+
+
+            vsrcCuc = vec_ld(stride + 0, src);
+
+            vsrc2uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm0);
+            vsrc3uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm1);
+
+            CHROMA_MC8_ALTIVEC_CORE(vec_splat_s16(0), add28)
+        }
+    } else {
+        vec_u8 vsrcDuc;
+        for (i = 0 ; i < h ; i++) {
+            vsrcCuc = vec_ld(stride + 0, src);
+            vsrcDuc = vec_ld(stride + 16, src);
+
+            vsrc2uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm0);
+            if (reallyBadAlign)
+                vsrc3uc = vsrcDuc;
+            else
+                vsrc3uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm1);
+
+            CHROMA_MC8_ALTIVEC_CORE(vec_splat_s16(0), add28)
+        }
+    }
+}
+#endif
+
+#undef noop
+#undef add28
+#undef CHROMA_MC8_ALTIVEC_CORE
diff --git a/libavcodec/ppc/idct_altivec.c b/libavcodec/ppc/idct_altivec.c
index 9a8b917..c6f2cd8 100644
--- a/libavcodec/ppc/idct_altivec.c
+++ b/libavcodec/ppc/idct_altivec.c
@@ -42,7 +42,6 @@
 #include <altivec.h>
 #endif
 #include "libavutil/ppc/types_altivec.h"
-#include "libavcodec/dsputil.h"
 #include "dsputil_altivec.h"
 
 #define IDCT_HALF                                       \
diff --git a/libavcodec/ppc/int_altivec.c b/libavcodec/ppc/int_altivec.c
index 5a73876..4386b13 100644
--- a/libavcodec/ppc/int_altivec.c
+++ b/libavcodec/ppc/int_altivec.c
@@ -28,6 +28,7 @@
 #include <altivec.h>
 #endif
 
+#include "libavutil/attributes.h"
 #include "libavutil/ppc/types_altivec.h"
 #include "libavcodec/dsputil.h"
 
@@ -136,7 +137,7 @@
     return ires;
 }
 
-void ff_int_init_altivec(DSPContext* c, AVCodecContext *avctx)
+av_cold void ff_int_init_altivec(DSPContext *c, AVCodecContext *avctx)
 {
     c->ssd_int8_vs_int16 = ssd_int8_vs_int16_altivec;
     c->scalarproduct_int16 = scalarproduct_int16_altivec;
diff --git a/libavcodec/ppc/mpegaudiodec_altivec.c b/libavcodec/ppc/mpegaudiodec_altivec.c
index 7d829b8..1152fd7 100644
--- a/libavcodec/ppc/mpegaudiodec_altivec.c
+++ b/libavcodec/ppc/mpegaudiodec_altivec.c
@@ -20,8 +20,9 @@
  */
 
 #include "dsputil_altivec.h"
+#include "libavutil/attributes.h"
+#include "libavutil/internal.h"
 #include "libavutil/ppc/util_altivec.h"
-#include "libavcodec/dsputil.h"
 #include "libavcodec/mpegaudiodsp.h"
 
 #define MACS(rt, ra, rb) rt+=(ra)*(rb)
@@ -123,7 +124,7 @@
     *out = sum;
 }
 
-void ff_mpadsp_init_altivec(MPADSPContext *s)
+av_cold void ff_mpadsp_init_altivec(MPADSPContext *s)
 {
     s->apply_window_float = apply_window_mp3;
 }
diff --git a/libavcodec/ppc/mpegvideo_altivec.c b/libavcodec/ppc/mpegvideo_altivec.c
index bbc102b..bf490b0 100644
--- a/libavcodec/ppc/mpegvideo_altivec.c
+++ b/libavcodec/ppc/mpegvideo_altivec.c
@@ -24,10 +24,10 @@
 #include <stdlib.h>
 #include <stdio.h>
 
+#include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
 #include "libavutil/ppc/types_altivec.h"
 #include "libavutil/ppc/util_altivec.h"
-#include "libavcodec/dsputil.h"
 #include "libavcodec/mpegvideo.h"
 
 #include "dsputil_altivec.h"
@@ -35,7 +35,7 @@
 /* AltiVec version of dct_unquantize_h263
    this code assumes `block' is 16 bytes-aligned */
 static void dct_unquantize_h263_altivec(MpegEncContext *s,
-                                 DCTELEM *block, int n, int qscale)
+                                 int16_t *block, int n, int qscale)
 {
     int i, level, qmul, qadd;
     int nCoeffs;
@@ -112,7 +112,7 @@
 }
 
 
-void ff_MPV_common_init_altivec(MpegEncContext *s)
+av_cold void ff_MPV_common_init_altivec(MpegEncContext *s)
 {
     if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC)) return;
 
diff --git a/libavcodec/ppc/vc1dsp_altivec.c b/libavcodec/ppc/vc1dsp_altivec.c
index 33e87af..9c2ad70 100644
--- a/libavcodec/ppc/vc1dsp_altivec.c
+++ b/libavcodec/ppc/vc1dsp_altivec.c
@@ -19,9 +19,9 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/ppc/types_altivec.h"
 #include "libavutil/ppc/util_altivec.h"
-#include "libavcodec/dsputil.h"
 #include "libavcodec/vc1dsp.h"
 
 // main steps of 8x8 transform
@@ -129,7 +129,7 @@
 
 /** Do inverse transform on 8x8 block
 */
-static void vc1_inv_trans_8x8_altivec(DCTELEM block[64])
+static void vc1_inv_trans_8x8_altivec(int16_t block[64])
 {
     vector signed short src0, src1, src2, src3, src4, src5, src6, src7;
     vector signed int s0, s1, s2, s3, s4, s5, s6, s7;
@@ -224,7 +224,7 @@
 
 /** Do inverse transform on 8x4 part of block
 */
-static void vc1_inv_trans_8x4_altivec(uint8_t *dest, int stride, DCTELEM *block)
+static void vc1_inv_trans_8x4_altivec(uint8_t *dest, int stride, int16_t *block)
 {
     vector signed short src0, src1, src2, src3, src4, src5, src6, src7;
     vector signed int s0, s1, s2, s3, s4, s5, s6, s7;
@@ -325,17 +325,17 @@
 
 #define OP_U8_ALTIVEC                          PUT_OP_U8_ALTIVEC
 #define PREFIX_no_rnd_vc1_chroma_mc8_altivec   put_no_rnd_vc1_chroma_mc8_altivec
-#include "h264_altivec_template.c"
+#include "h264chroma_template.c"
 #undef OP_U8_ALTIVEC
 #undef PREFIX_no_rnd_vc1_chroma_mc8_altivec
 
 #define OP_U8_ALTIVEC                          AVG_OP_U8_ALTIVEC
 #define PREFIX_no_rnd_vc1_chroma_mc8_altivec   avg_no_rnd_vc1_chroma_mc8_altivec
-#include "h264_altivec_template.c"
+#include "h264chroma_template.c"
 #undef OP_U8_ALTIVEC
 #undef PREFIX_no_rnd_vc1_chroma_mc8_altivec
 
-void ff_vc1dsp_init_altivec(VC1DSPContext* dsp)
+av_cold void ff_vc1dsp_init_altivec(VC1DSPContext *dsp)
 {
     if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC))
         return;
diff --git a/libavcodec/x86/dwt.h b/libavcodec/ppc/videodsp_ppc.c
similarity index 64%
copy from libavcodec/x86/dwt.h
copy to libavcodec/ppc/videodsp_ppc.c
index 199f611..9157022 100644
--- a/libavcodec/x86/dwt.h
+++ b/libavcodec/ppc/videodsp_ppc.c
@@ -1,4 +1,6 @@
 /*
+ * Copyright (c) 2003-2004 Romain Dolbeau
+ *
  * This file is part of FFmpeg.
  *
  * FFmpeg is free software; you can redistribute it and/or
@@ -16,15 +18,19 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#ifndef AVCODEC_X86_DWT_H
-#define AVCODEC_X86_DWT_H
+#include "libavutil/attributes.h"
+#include "libavcodec/videodsp.h"
 
-#include "libavcodec/dwt.h"
+static void prefetch_ppc(uint8_t *mem, ptrdiff_t stride, int h)
+{
+    register const uint8_t *p = mem;
+    do {
+        __asm__ volatile ("dcbt 0,%0" : : "r" (p));
+        p += stride;
+    } while(--h);
+}
 
-void ff_horizontal_compose_dd97i_end_c(IDWTELEM *b, IDWTELEM *tmp, int w2, int x);
-void ff_horizontal_compose_haar1i_end_c(IDWTELEM *b, IDWTELEM *tmp, int w2, int x);
-void ff_horizontal_compose_haar0i_end_c(IDWTELEM *b, IDWTELEM *tmp, int w2, int x);
-
-void ff_spatial_idwt_init_mmx(DWTContext *d, enum dwt_type type);
-
-#endif
+av_cold void ff_videodsp_init_ppc(VideoDSPContext *ctx, int bpc)
+{
+    ctx->prefetch = prefetch_ppc;
+}
diff --git a/libavcodec/ppc/vorbisdsp_altivec.c b/libavcodec/ppc/vorbisdsp_altivec.c
new file mode 100644
index 0000000..08a2b26
--- /dev/null
+++ b/libavcodec/ppc/vorbisdsp_altivec.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2006 Luca Barbato <lu_zero@gentoo.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 "config.h"
+#if HAVE_ALTIVEC_H
+#include <altivec.h>
+#endif
+#include "libavutil/attributes.h"
+#include "libavutil/cpu.h"
+#include "libavcodec/vorbisdsp.h"
+
+#if HAVE_ALTIVEC
+static void vorbis_inverse_coupling_altivec(float *mag, float *ang,
+                                            intptr_t blocksize)
+{
+    int i;
+    vector float m, a;
+    vector bool int t0, t1;
+    const vector unsigned int v_31 = //XXX
+        vec_add(vec_add(vec_splat_u32(15),vec_splat_u32(15)),vec_splat_u32(1));
+    for (i = 0; i < blocksize; i += 4) {
+        m = vec_ld(0, mag+i);
+        a = vec_ld(0, ang+i);
+        t0 = vec_cmple(m, (vector float)vec_splat_u32(0));
+        t1 = vec_cmple(a, (vector float)vec_splat_u32(0));
+        a = vec_xor(a, (vector float) vec_sl((vector unsigned int)t0, v_31));
+        t0 = (vector bool int)vec_and(a, t1);
+        t1 = (vector bool int)vec_andc(a, t1);
+        a = vec_sub(m, (vector float)t1);
+        m = vec_add(m, (vector float)t0);
+        vec_stl(a, 0, ang+i);
+        vec_stl(m, 0, mag+i);
+    }
+}
+#endif /* HAVE_ALTIVEC */
+
+av_cold void ff_vorbisdsp_init_ppc(VorbisDSPContext *c)
+{
+#if HAVE_ALTIVEC
+    if (av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC) {
+      c->vorbis_inverse_coupling = vorbis_inverse_coupling_altivec;
+    }
+#endif /* HAVE_ALTIVEC */
+}
diff --git a/libavcodec/ppc/vp3dsp_altivec.c b/libavcodec/ppc/vp3dsp_altivec.c
index ac00c93..42ae00b 100644
--- a/libavcodec/ppc/vp3dsp_altivec.c
+++ b/libavcodec/ppc/vp3dsp_altivec.c
@@ -18,6 +18,8 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <string.h>
+
 #include "config.h"
 #include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
@@ -27,7 +29,6 @@
 
 #include "libavutil/ppc/types_altivec.h"
 #include "libavutil/ppc/util_altivec.h"
-#include "libavcodec/dsputil.h"
 #include "dsputil_altivec.h"
 
 static const vec_s16 constants =
@@ -114,7 +115,7 @@
 #define ADD8(a) vec_add(a, eight)
 #define SHIFT4(a) vec_sra(a, four)
 
-static void vp3_idct_put_altivec(uint8_t *dst, int stride, DCTELEM block[64])
+static void vp3_idct_put_altivec(uint8_t *dst, int stride, int16_t block[64])
 {
     vec_u8 t;
     IDCT_START
@@ -140,9 +141,10 @@
     PUT(b5)     dst += stride;
     PUT(b6)     dst += stride;
     PUT(b7)
+    memset(block, 0, sizeof(*block) * 64);
 }
 
-static void vp3_idct_add_altivec(uint8_t *dst, int stride, DCTELEM block[64])
+static void vp3_idct_add_altivec(uint8_t *dst, int stride, int16_t block[64])
 {
     LOAD_ZERO;
     vec_u8 t, vdst;
@@ -171,6 +173,7 @@
     ADD(b5)     dst += stride;
     ADD(b6)     dst += stride;
     ADD(b7)
+    memset(block, 0, sizeof(*block) * 64);
 }
 
 #endif /* HAVE_ALTIVEC */
diff --git a/libavcodec/proresdec2.c b/libavcodec/proresdec2.c
index e643c87..4634e70 100644
--- a/libavcodec/proresdec2.c
+++ b/libavcodec/proresdec2.c
@@ -30,6 +30,7 @@
 
 #include "avcodec.h"
 #include "get_bits.h"
+#include "internal.h"
 #include "simple_idct.h"
 #include "proresdec.h"
 
@@ -293,10 +294,10 @@
 
 static const uint8_t dc_codebook[7] = { 0x04, 0x28, 0x28, 0x4D, 0x4D, 0x70, 0x70};
 
-static av_always_inline void decode_dc_coeffs(GetBitContext *gb, DCTELEM *out,
+static av_always_inline void decode_dc_coeffs(GetBitContext *gb, int16_t *out,
                                               int blocks_per_slice)
 {
-    DCTELEM prev_dc;
+    int16_t prev_dc;
     int code, i, sign;
 
     OPEN_READER(re, gb);
@@ -324,7 +325,7 @@
 static const uint8_t lev_to_cb[10] = { 0x04, 0x0A, 0x05, 0x06, 0x04, 0x28, 0x28, 0x28, 0x28, 0x4C };
 
 static av_always_inline void decode_ac_coeffs(AVCodecContext *avctx, GetBitContext *gb,
-                                              DCTELEM *out, int blocks_per_slice)
+                                              int16_t *out, int blocks_per_slice)
 {
     ProresContext *ctx = avctx->priv_data;
     int block_mask, sign;
@@ -371,8 +372,8 @@
                               const int16_t *qmat)
 {
     ProresContext *ctx = avctx->priv_data;
-    LOCAL_ALIGNED_16(DCTELEM, blocks, [8*4*64]);
-    DCTELEM *block;
+    LOCAL_ALIGNED_16(int16_t, blocks, [8*4*64]);
+    int16_t *block;
     GetBitContext gb;
     int i, blocks_per_slice = slice->mb_count<<2;
 
@@ -401,8 +402,8 @@
                                 const int16_t *qmat, int log2_blocks_per_mb)
 {
     ProresContext *ctx = avctx->priv_data;
-    LOCAL_ALIGNED_16(DCTELEM, blocks, [8*4*64]);
-    DCTELEM *block;
+    LOCAL_ALIGNED_16(int16_t, blocks, [8*4*64]);
+    int16_t *block;
     GetBitContext gb;
     int i, j, blocks_per_slice = slice->mb_count << log2_blocks_per_mb;
 
@@ -521,7 +522,7 @@
     return 0;
 }
 
-static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         AVPacket *avpkt)
 {
     ProresContext *ctx = avctx->priv_data;
@@ -550,7 +551,7 @@
     if (frame->data[0])
         avctx->release_buffer(avctx, frame);
 
-    if (avctx->get_buffer(avctx, frame) < 0)
+    if (ff_get_buffer(avctx, frame) < 0)
         return -1;
 
  decode_picture:
@@ -573,7 +574,7 @@
         goto decode_picture;
     }
 
-    *data_size = sizeof(AVFrame);
+    *got_frame      = 1;
     *(AVFrame*)data = *frame;
 
     return avpkt->size;
diff --git a/libavcodec/proresdec_lgpl.c b/libavcodec/proresdec_lgpl.c
index d338649..5c53882 100644
--- a/libavcodec/proresdec_lgpl.c
+++ b/libavcodec/proresdec_lgpl.c
@@ -34,6 +34,8 @@
 
 #include "libavutil/intmath.h"
 #include "avcodec.h"
+#include "dsputil.h"
+#include "internal.h"
 #include "proresdata.h"
 #include "proresdsp.h"
 #include "get_bits.h"
@@ -44,7 +46,7 @@
     int x_pos, y_pos;
     int slice_width;
     int prev_slice_sf;               ///< scalefactor of the previous decoded slice
-    DECLARE_ALIGNED(16, DCTELEM, blocks)[8 * 4 * 64];
+    DECLARE_ALIGNED(16, int16_t, blocks)[8 * 4 * 64];
     DECLARE_ALIGNED(16, int16_t, qmat_luma_scaled)[64];
     DECLARE_ALIGNED(16, int16_t, qmat_chroma_scaled)[64];
 } ProresThreadData;
@@ -163,6 +165,8 @@
     if (ctx->frame_type) {      /* if interlaced */
         ctx->picture.interlaced_frame = 1;
         ctx->picture.top_field_first  = ctx->frame_type & 1;
+    } else {
+        ctx->picture.interlaced_frame = 0;
     }
 
     avctx->color_primaries = buf[14];
@@ -337,10 +341,10 @@
 /**
  * Decode DC coefficients for all blocks in a slice.
  */
-static inline void decode_dc_coeffs(GetBitContext *gb, DCTELEM *out,
+static inline void decode_dc_coeffs(GetBitContext *gb, int16_t *out,
                                     int nblocks)
 {
-    DCTELEM prev_dc;
+    int16_t prev_dc;
     int     i, sign;
     int16_t delta;
     unsigned int code;
@@ -365,7 +369,7 @@
 /**
  * Decode AC coefficients for all blocks in a slice.
  */
-static inline void decode_ac_coeffs(GetBitContext *gb, DCTELEM *out,
+static inline void decode_ac_coeffs(GetBitContext *gb, int16_t *out,
                                     int blocks_per_slice,
                                     int plane_size_factor,
                                     const uint8_t *scan)
@@ -418,7 +422,7 @@
                                const int16_t *qmat, int is_chroma)
 {
     GetBitContext gb;
-    DCTELEM *block_ptr;
+    int16_t *block_ptr;
     int mb_num, blocks_per_slice;
 
     blocks_per_slice = mbs_per_slice * blocks_per_mb;
@@ -598,7 +602,7 @@
 
 #define MOVE_DATA_PTR(nbytes) buf += (nbytes); buf_size -= (nbytes)
 
-static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         AVPacket *avpkt)
 {
     ProresContext *ctx = avctx->priv_data;
@@ -626,7 +630,7 @@
         avctx->release_buffer(avctx, picture);
 
     picture->reference = 0;
-    if (avctx->get_buffer(avctx, picture) < 0)
+    if (ff_get_buffer(avctx, picture) < 0)
         return -1;
 
     for (pic_num = 0; ctx->picture.interlaced_frame - pic_num + 1; pic_num++) {
@@ -640,7 +644,7 @@
         MOVE_DATA_PTR(pic_data_size);
     }
 
-    *data_size       = sizeof(AVPicture);
+    *got_frame       = 1;
     *(AVFrame*) data = *avctx->coded_frame;
 
     return avpkt->size;
diff --git a/libavcodec/proresdsp.c b/libavcodec/proresdsp.c
index 9e063b0..d73de46 100644
--- a/libavcodec/proresdsp.c
+++ b/libavcodec/proresdsp.c
@@ -20,6 +20,8 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "dct.h"
+#include "dsputil.h"
 #include "proresdsp.h"
 #include "simple_idct.h"
 #include "libavutil/common.h"
@@ -34,7 +36,7 @@
 /**
  * Add bias value, clamp and output pixels of a slice
  */
-static void put_pixels(uint16_t *dst, int stride, const DCTELEM *in)
+static void put_pixels(uint16_t *dst, int stride, const int16_t *in)
 {
     int x, y, src_offset, dst_offset;
 
@@ -47,7 +49,7 @@
     }
 }
 
-static void prores_idct_put_c(uint16_t *out, int linesize, DCTELEM *block, const int16_t *qmat)
+static void prores_idct_put_c(uint16_t *out, int linesize, int16_t *block, const int16_t *qmat)
 {
     ff_prores_idct(block, qmat);
     put_pixels(out, linesize >> 1, block);
@@ -55,7 +57,7 @@
 #endif
 
 #if CONFIG_PRORES_KOSTYA_ENCODER
-static void prores_fdct_c(const uint16_t *src, int linesize, DCTELEM *block)
+static void prores_fdct_c(const uint16_t *src, int linesize, int16_t *block)
 {
     int x, y;
     const uint16_t *tsrc = src;
diff --git a/libavcodec/proresdsp.h b/libavcodec/proresdsp.h
index 09541d9..706162a 100644
--- a/libavcodec/proresdsp.h
+++ b/libavcodec/proresdsp.h
@@ -23,6 +23,7 @@
 #ifndef AVCODEC_PRORESDSP_H
 #define AVCODEC_PRORESDSP_H
 
+#include <stdint.h>
 #include "dsputil.h"
 
 #define PRORES_BITS_PER_SAMPLE 10 ///< output precision of prores decoder
@@ -32,8 +33,8 @@
     uint8_t idct_permutation[64];
     int dct_permutation_type;
     uint8_t dct_permutation[64];
-    void (* idct_put) (uint16_t *out, int linesize, DCTELEM *block, const int16_t *qmat);
-    void (* fdct) (const uint16_t *src, int linesize, DCTELEM *block);
+    void (* idct_put) (uint16_t *out, int linesize, int16_t *block, const int16_t *qmat);
+    void (* fdct) (const uint16_t *src, int linesize, int16_t *block);
 } ProresDSPContext;
 
 void ff_proresdsp_init(ProresDSPContext *dsp, AVCodecContext *avctx);
diff --git a/libavcodec/proresenc_anatoliy.c b/libavcodec/proresenc_anatoliy.c
index 8c71ca5..7bf71a3 100644
--- a/libavcodec/proresenc_anatoliy.c
+++ b/libavcodec/proresenc_anatoliy.c
@@ -27,6 +27,7 @@
  */
 
 #include "avcodec.h"
+#include "dct.h"
 #include "internal.h"
 #include "put_bits.h"
 #include "bytestream.h"
@@ -198,7 +199,7 @@
 
 static const uint8_t dc_codebook[7] = { 0x04, 0x28, 0x28, 0x4D, 0x4D, 0x70, 0x70};
 
-static void encode_dc_coeffs(PutBitContext *pb, DCTELEM *in,
+static void encode_dc_coeffs(PutBitContext *pb, int16_t *in,
         int blocks_per_slice, int *qmat)
 {
     int prev_dc, code;
@@ -230,7 +231,7 @@
         0x28, 0x28, 0x28, 0x4C };
 
 static void encode_ac_coeffs(AVCodecContext *avctx, PutBitContext *pb,
-        DCTELEM *in, int blocks_per_slice, int *qmat)
+        int16_t *in, int blocks_per_slice, int *qmat)
 {
     int prev_run = 4;
     int prev_level = 2;
@@ -260,7 +261,7 @@
     }
 }
 
-static void get(uint8_t *pixels, int stride, DCTELEM* block)
+static void get(uint8_t *pixels, int stride, int16_t* block)
 {
     int16_t *p = (int16_t*)pixels;
     int i, j;
@@ -275,7 +276,7 @@
     }
 }
 
-static void fdct_get(uint8_t *pixels, int stride, DCTELEM* block)
+static void fdct_get(uint8_t *pixels, int stride, int16_t* block)
 {
     get(pixels, stride, block);
     ff_jpeg_fdct_islow_10(block);
@@ -285,7 +286,7 @@
         uint8_t *src, int src_stride, uint8_t *buf, unsigned buf_size,
         int *qmat, int chroma)
 {
-    DECLARE_ALIGNED(16, DCTELEM, blocks)[DEFAULT_SLICE_MB_WIDTH << 8], *block;
+    DECLARE_ALIGNED(16, int16_t, blocks)[DEFAULT_SLICE_MB_WIDTH << 8], *block;
     int i, blocks_per_slice;
     PutBitContext pb;
 
diff --git a/libavcodec/proresenc_kostya.c b/libavcodec/proresenc_kostya.c
index 0462c74..8da13ac 100644
--- a/libavcodec/proresenc_kostya.c
+++ b/libavcodec/proresenc_kostya.c
@@ -25,6 +25,7 @@
 
 #include "libavutil/opt.h"
 #include "avcodec.h"
+#include "dsputil.h"
 #include "put_bits.h"
 #include "bytestream.h"
 #include "internal.h"
@@ -170,7 +171,7 @@
 #define MAX_STORED_Q 16
 
 typedef struct ProresThreadData {
-    DECLARE_ALIGNED(16, DCTELEM, blocks)[MAX_PLANES][64 * 4 * MAX_MBS_PER_SLICE];
+    DECLARE_ALIGNED(16, int16_t, blocks)[MAX_PLANES][64 * 4 * MAX_MBS_PER_SLICE];
     DECLARE_ALIGNED(16, uint16_t, emu_buf)[16 * 16];
     int16_t custom_q[64];
     struct TrellisNode *nodes;
@@ -178,7 +179,7 @@
 
 typedef struct ProresContext {
     AVClass *class;
-    DECLARE_ALIGNED(16, DCTELEM, blocks)[MAX_PLANES][64 * 4 * MAX_MBS_PER_SLICE];
+    DECLARE_ALIGNED(16, int16_t, blocks)[MAX_PLANES][64 * 4 * MAX_MBS_PER_SLICE];
     DECLARE_ALIGNED(16, uint16_t, emu_buf)[16*16];
     int16_t quants[MAX_STORED_Q][64];
     int16_t custom_q[64];
@@ -213,7 +214,7 @@
 
 static void get_slice_data(ProresContext *ctx, const uint16_t *src,
                            int linesize, int x, int y, int w, int h,
-                           DCTELEM *blocks, uint16_t *emu_buf,
+                           int16_t *blocks, uint16_t *emu_buf,
                            int mbs_per_slice, int blocks_per_mb, int is_chroma)
 {
     const uint16_t *esrc;
@@ -317,7 +318,7 @@
 #define GET_SIGN(x)  ((x) >> 31)
 #define MAKE_CODE(x) (((x) << 1) ^ GET_SIGN(x))
 
-static void encode_dcs(PutBitContext *pb, DCTELEM *blocks,
+static void encode_dcs(PutBitContext *pb, int16_t *blocks,
                        int blocks_per_slice, int scale)
 {
     int i;
@@ -343,7 +344,7 @@
     }
 }
 
-static void encode_acs(PutBitContext *pb, DCTELEM *blocks,
+static void encode_acs(PutBitContext *pb, int16_t *blocks,
                        int blocks_per_slice,
                        int plane_size_factor,
                        const uint8_t *scan, const int16_t *qmat)
@@ -379,7 +380,7 @@
 
 static int encode_slice_plane(ProresContext *ctx, PutBitContext *pb,
                               const uint16_t *src, int linesize,
-                              int mbs_per_slice, DCTELEM *blocks,
+                              int mbs_per_slice, int16_t *blocks,
                               int blocks_per_mb, int plane_size_factor,
                               const int16_t *qmat)
 {
@@ -481,7 +482,7 @@
     }
 }
 
-static int estimate_dcs(int *error, DCTELEM *blocks, int blocks_per_slice,
+static int estimate_dcs(int *error, int16_t *blocks, int blocks_per_slice,
                         int scale)
 {
     int i;
@@ -512,7 +513,7 @@
     return bits;
 }
 
-static int estimate_acs(int *error, DCTELEM *blocks, int blocks_per_slice,
+static int estimate_acs(int *error, int16_t *blocks, int blocks_per_slice,
                         int plane_size_factor,
                         const uint8_t *scan, const int16_t *qmat)
 {
diff --git a/libavcodec/psymodel.h b/libavcodec/psymodel.h
index 37c8191..d1a126a 100644
--- a/libavcodec/psymodel.h
+++ b/libavcodec/psymodel.h
@@ -139,9 +139,9 @@
  *
  * @return zero if successful, a negative value if not
  */
-av_cold int ff_psy_init(FFPsyContext *ctx, AVCodecContext *avctx, int num_lens,
-                        const uint8_t **bands, const int* num_bands,
-                        int num_groups, const uint8_t *group_map);
+int ff_psy_init(FFPsyContext *ctx, AVCodecContext *avctx, int num_lens,
+                const uint8_t **bands, const int *num_bands,
+                int num_groups, const uint8_t *group_map);
 
 /**
  * Determine what group a channel belongs to.
@@ -158,7 +158,7 @@
  *
  * @param ctx model context
  */
-av_cold void ff_psy_end(FFPsyContext *ctx);
+void ff_psy_end(FFPsyContext *ctx);
 
 
 /**************************************************************************
@@ -170,7 +170,7 @@
 /**
  * psychoacoustic model audio preprocessing initialization
  */
-av_cold struct FFPsyPreprocessContext* ff_psy_preprocess_init(AVCodecContext *avctx);
+struct FFPsyPreprocessContext *ff_psy_preprocess_init(AVCodecContext *avctx);
 
 /**
  * Preprocess several channel in audio frame in order to compress it better.
@@ -184,6 +184,6 @@
 /**
  * Cleanup audio preprocessing module.
  */
-av_cold void ff_psy_preprocess_end(struct FFPsyPreprocessContext *ctx);
+void ff_psy_preprocess_end(struct FFPsyPreprocessContext *ctx);
 
 #endif /* AVCODEC_PSYMODEL_H */
diff --git a/libavcodec/pthread.c b/libavcodec/pthread.c
index 9a52924..1ca72b4 100644
--- a/libavcodec/pthread.c
+++ b/libavcodec/pthread.c
@@ -32,7 +32,9 @@
 #include "config.h"
 
 #if HAVE_SCHED_GETAFFINITY
-#define _GNU_SOURCE
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE
+#endif
 #include <sched.h>
 #endif
 #if HAVE_GETPROCESSAFFINITYMASK
@@ -587,7 +589,7 @@
                 pthread_cond_wait(&p->progress_cond, &p->progress_mutex);
 
             if (p->state == STATE_GET_BUFFER) {
-                p->result = p->avctx->get_buffer(p->avctx, p->requested_frame);
+                p->result = ff_get_buffer(p->avctx, p->requested_frame);
                 p->state  = STATE_SETTING_UP;
                 pthread_cond_signal(&p->progress_cond);
             }
@@ -752,7 +754,11 @@
     park_frame_worker_threads(fctx, thread_count);
 
     if (fctx->prev_thread && fctx->prev_thread != fctx->threads)
-        update_context_from_thread(fctx->threads->avctx, fctx->prev_thread->avctx, 0);
+        if (update_context_from_thread(fctx->threads->avctx, fctx->prev_thread->avctx, 0) < 0) {
+            av_log(avctx, AV_LOG_ERROR, "Final thread update failed\n");
+            fctx->prev_thread->avctx->internal->is_copy = fctx->threads->avctx->internal->is_copy;
+            fctx->threads->avctx->internal->is_copy = 1;
+        }
 
     fctx->die = 1;
 
@@ -962,7 +968,7 @@
 
     if (!(avctx->active_thread_type&FF_THREAD_FRAME)) {
         f->thread_opaque = NULL;
-        return avctx->get_buffer(avctx, f);
+        return ff_get_buffer(avctx, f);
     }
 
     if (p->state != STATE_SETTING_UP &&
@@ -985,7 +991,7 @@
 
     if (avctx->thread_safe_callbacks ||
         avctx->get_buffer == avcodec_default_get_buffer) {
-        err = avctx->get_buffer(avctx, f);
+        err = ff_get_buffer(avctx, f);
     } else {
         pthread_mutex_lock(&p->progress_mutex);
         p->requested_frame = f;
@@ -1017,6 +1023,9 @@
     PerThreadContext *p = avctx->thread_opaque;
     FrameThreadContext *fctx;
 
+    if (!f->data[0])
+        return;
+
     if (!(avctx->active_thread_type&FF_THREAD_FRAME)) {
         avctx->release_buffer(avctx, f);
         return;
diff --git a/libavcodec/ptx.c b/libavcodec/ptx.c
index c9adb6d..1a76c55 100644
--- a/libavcodec/ptx.c
+++ b/libavcodec/ptx.c
@@ -23,6 +23,7 @@
 #include "libavutil/intreadwrite.h"
 #include "libavutil/imgutils.h"
 #include "avcodec.h"
+#include "internal.h"
 
 typedef struct PTXContext {
     AVFrame picture;
@@ -37,7 +38,7 @@
     return 0;
 }
 
-static int ptx_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+static int ptx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                             AVPacket *avpkt) {
     const uint8_t *buf = avpkt->data;
     const uint8_t *buf_end = avpkt->data + avpkt->size;
@@ -45,6 +46,7 @@
     AVFrame *picture = data;
     AVFrame * const p = &s->picture;
     unsigned int offset, w, h, y, stride, bytes_per_pixel;
+    int ret;
     uint8_t *ptr;
 
     if (buf_end - buf < 14)
@@ -56,7 +58,7 @@
 
     if (bytes_per_pixel != 2) {
         av_log_ask_for_sample(avctx, "Image format is not RGB15.\n");
-        return -1;
+        return AVERROR_PATCHWELCOME;
     }
 
     avctx->pix_fmt = AV_PIX_FMT_BGR555LE;
@@ -71,13 +73,13 @@
     if (p->data[0])
         avctx->release_buffer(avctx, p);
 
-    if (av_image_check_size(w, h, 0, avctx))
-        return -1;
+    if ((ret = av_image_check_size(w, h, 0, avctx)) < 0)
+        return ret;
     if (w != avctx->width || h != avctx->height)
         avcodec_set_dimensions(avctx, w, h);
-    if (avctx->get_buffer(avctx, p) < 0) {
+    if ((ret = ff_get_buffer(avctx, p)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     p->pict_type = AV_PICTURE_TYPE_I;
@@ -92,7 +94,7 @@
     }
 
     *picture = s->picture;
-    *data_size = sizeof(AVPicture);
+    *got_frame = 1;
 
     if (y < h) {
         av_log(avctx, AV_LOG_WARNING, "incomplete packet\n");
diff --git a/libavcodec/put_bits.h b/libavcodec/put_bits.h
index f02965e..7320443 100644
--- a/libavcodec/put_bits.h
+++ b/libavcodec/put_bits.h
@@ -29,6 +29,7 @@
 #include <stdint.h>
 #include <stdlib.h>
 #include <assert.h>
+
 #include "libavutil/bswap.h"
 #include "libavutil/common.h"
 #include "libavutil/intreadwrite.h"
@@ -50,19 +51,20 @@
  * @param buffer the buffer where to put bits
  * @param buffer_size the size in bytes of buffer
  */
-static inline void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size)
+static inline void init_put_bits(PutBitContext *s, uint8_t *buffer,
+                                 int buffer_size)
 {
-    if(buffer_size < 0) {
+    if (buffer_size < 0) {
         buffer_size = 0;
-        buffer = NULL;
+        buffer      = NULL;
     }
 
-    s->size_in_bits= 8*buffer_size;
-    s->buf = buffer;
-    s->buf_end = s->buf + buffer_size;
-    s->buf_ptr = s->buf;
-    s->bit_left=32;
-    s->bit_buf=0;
+    s->size_in_bits = 8 * buffer_size;
+    s->buf          = buffer;
+    s->buf_end      = s->buf + buffer_size;
+    s->buf_ptr      = s->buf;
+    s->bit_left     = 32;
+    s->bit_buf      = 0;
 }
 
 /**
@@ -80,21 +82,21 @@
 {
 #ifndef BITSTREAM_WRITER_LE
     if (s->bit_left < 32)
-        s->bit_buf<<= s->bit_left;
+        s->bit_buf <<= s->bit_left;
 #endif
     while (s->bit_left < 32) {
         /* XXX: should test end of buffer */
 #ifdef BITSTREAM_WRITER_LE
-        *s->buf_ptr++=s->bit_buf;
-        s->bit_buf>>=8;
+        *s->buf_ptr++ = s->bit_buf;
+        s->bit_buf  >>= 8;
 #else
-        *s->buf_ptr++=s->bit_buf >> 24;
-        s->bit_buf<<=8;
+        *s->buf_ptr++ = s->bit_buf >> 24;
+        s->bit_buf  <<= 8;
 #endif
-        s->bit_left+=8;
+        s->bit_left  += 8;
     }
-    s->bit_left=32;
-    s->bit_buf=0;
+    s->bit_left = 32;
+    s->bit_buf  = 0;
 }
 
 #ifdef BITSTREAM_WRITER_LE
@@ -112,7 +114,8 @@
  *
  * @param terminate_string 0-terminates the written string if value is 1
  */
-void avpriv_put_string(PutBitContext *pb, const char *string, int terminate_string);
+void avpriv_put_string(PutBitContext *pb, const char *string,
+                       int terminate_string);
 
 /**
  * Copy the content of src to the bitstream.
@@ -133,7 +136,7 @@
 
     av_assert2(n <= 31 && value < (1U << n));
 
-    bit_buf = s->bit_buf;
+    bit_buf  = s->bit_buf;
     bit_left = s->bit_left;
 
     /* XXX: optimize */
@@ -142,27 +145,27 @@
     if (n >= bit_left) {
         av_assert2(s->buf_ptr+3<s->buf_end);
         AV_WL32(s->buf_ptr, bit_buf);
-        s->buf_ptr+=4;
-        bit_buf = (bit_left==32)?0:value >> bit_left;
-        bit_left+=32;
+        s->buf_ptr += 4;
+        bit_buf     = (bit_left == 32) ? 0 : value >> bit_left;
+        bit_left   += 32;
     }
-    bit_left-=n;
+    bit_left -= n;
 #else
     if (n < bit_left) {
-        bit_buf = (bit_buf<<n) | value;
-        bit_left-=n;
+        bit_buf     = (bit_buf << n) | value;
+        bit_left   -= n;
     } else {
-        bit_buf<<=bit_left;
-        bit_buf |= value >> (n - bit_left);
+        bit_buf   <<= bit_left;
+        bit_buf    |= value >> (n - bit_left);
         av_assert2(s->buf_ptr+3<s->buf_end);
         AV_WB32(s->buf_ptr, bit_buf);
-        s->buf_ptr+=4;
-        bit_left+=32 - n;
-        bit_buf = value;
+        s->buf_ptr += 4;
+        bit_left   += 32 - n;
+        bit_buf     = value;
     }
 #endif
 
-    s->bit_buf = bit_buf;
+    s->bit_buf  = bit_buf;
     s->bit_left = bit_left;
 }
 
@@ -170,7 +173,7 @@
 {
     av_assert2(n >= 0 && n <= 31);
 
-    put_bits(pb, n, value & ((1<<n)-1));
+    put_bits(pb, n, value & ((1 << n) - 1));
 }
 
 /**
@@ -193,9 +196,9 @@
  * Return the pointer to the byte where the bitstream writer will put
  * the next bit.
  */
-static inline uint8_t* put_bits_ptr(PutBitContext *s)
+static inline uint8_t *put_bits_ptr(PutBitContext *s)
 {
-        return s->buf_ptr;
+    return s->buf_ptr;
 }
 
 /**
@@ -204,9 +207,9 @@
  */
 static inline void skip_put_bytes(PutBitContext *s, int n)
 {
-        av_assert2((put_bits_count(s)&7)==0);
-        av_assert2(s->bit_left==32);
-        s->buf_ptr += n;
+    av_assert2((put_bits_count(s) & 7) == 0);
+    av_assert2(s->bit_left == 32);
+    s->buf_ptr += n;
 }
 
 /**
@@ -217,7 +220,7 @@
 static inline void skip_put_bits(PutBitContext *s, int n)
 {
     s->bit_left -= n;
-    s->buf_ptr-= 4*(s->bit_left>>5);
+    s->buf_ptr  -= 4 * (s->bit_left >> 5);
     s->bit_left &= 31;
 }
 
@@ -228,7 +231,7 @@
  */
 static inline void set_put_bits_buffer_size(PutBitContext *s, int size)
 {
-    s->buf_end= s->buf + size;
+    s->buf_end = s->buf + size;
 }
 
 #endif /* AVCODEC_PUT_BITS_H */
diff --git a/libavcodec/qcelpdata.h b/libavcodec/qcelpdata.h
index d58e9f8..7ddeed4 100644
--- a/libavcodec/qcelpdata.h
+++ b/libavcodec/qcelpdata.h
@@ -257,7 +257,7 @@
     QCELP_OF(lspv   [8], 0, 1), //  8
     QCELP_OF(cbsign[15], 0, 1), //  7
     QCELP_OF(lspv   [9], 0, 1), //  6
-    QCELP_OF(cbgain [0], 0, 2), //  7
+    QCELP_OF(cbgain [0], 0, 2), //  5
     QCELP_OF(reserved,   0, 4)  //  3
 };
 
diff --git a/libavcodec/qcelpdec.c b/libavcodec/qcelpdec.c
index e406049..76b51f8 100644
--- a/libavcodec/qcelpdec.c
+++ b/libavcodec/qcelpdec.c
@@ -30,10 +30,10 @@
 #include <stddef.h>
 
 #include "libavutil/channel_layout.h"
+#include "libavutil/float_dsp.h"
 #include "avcodec.h"
 #include "internal.h"
 #include "get_bits.h"
-#include "dsputil.h"
 #include "qcelpdata.h"
 #include "celp_filters.h"
 #include "acelp_filters.h"
@@ -53,7 +53,6 @@
 } qcelp_packet_rate;
 
 typedef struct {
-    AVFrame           avframe;
     GetBitContext     gb;
     qcelp_packet_rate bitrate;
     QCELPFrame        frame;    /**< unpacked data frame */
@@ -97,9 +96,6 @@
     for (i = 0; i < 10; i++)
         q->prev_lspf[i] = (i + 1) / 11.;
 
-    avcodec_get_frame_defaults(&q->avframe);
-    avctx->coded_frame = &q->avframe;
-
     return 0;
 }
 
@@ -400,12 +396,10 @@
 {
     int i;
 
-    for (i = 0; i < 160; i += 40)
-        ff_scale_vector_to_given_sum_of_squares(v_out + i, v_in + i,
-                                                ff_scalarproduct_float_c(v_ref + i,
-                                                                         v_ref + i,
-                                                                         40),
-                                                40);
+    for (i = 0; i < 160; i += 40) {
+        float res = avpriv_scalarproduct_float_c(v_ref + i, v_ref + i, 40);
+        ff_scale_vector_to_given_sum_of_squares(v_out + i, v_in + i, res, 40);
+    }
 }
 
 /**
@@ -680,8 +674,9 @@
     ff_tilt_compensation(&q->postfilter_tilt_mem, 0.3, pole_out + 10, 160);
 
     ff_adaptive_gain_control(samples, pole_out + 10,
-                             ff_scalarproduct_float_c(q->formant_mem + 10,
-                                                      q->formant_mem + 10, 160),
+                             avpriv_scalarproduct_float_c(q->formant_mem + 10,
+                                                          q->formant_mem + 10,
+                                                          160),
                              160, 0.9375, &q->postfilter_agc_mem);
 }
 
@@ -691,6 +686,7 @@
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
     QCELPContext *q    = avctx->priv_data;
+    AVFrame *frame     = data;
     float *outbuffer;
     int   i, ret;
     float quantized_lspf[10], lpc[10];
@@ -698,12 +694,12 @@
     float *formant_mem;
 
     /* get output buffer */
-    q->avframe.nb_samples = 160;
-    if ((ret = avctx->get_buffer(avctx, &q->avframe)) < 0) {
+    frame->nb_samples = 160;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    outbuffer = (float *)q->avframe.data[0];
+    outbuffer = (float *)frame->data[0];
 
     if ((q->bitrate = determine_bitrate(avctx, buf_size, &buf)) == I_F_Q) {
         warn_insufficient_frame_quality(avctx, "bitrate cannot be determined.");
@@ -786,8 +782,7 @@
     memcpy(q->prev_lspf, quantized_lspf, sizeof(q->prev_lspf));
     q->prev_bitrate  = q->bitrate;
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = q->avframe;
+    *got_frame_ptr = 1;
 
     return buf_size;
 }
diff --git a/libavcodec/qdm2.c b/libavcodec/qdm2.c
index 1dfb8d5..283d8e6 100644
--- a/libavcodec/qdm2.c
+++ b/libavcodec/qdm2.c
@@ -39,7 +39,7 @@
 #include "libavutil/channel_layout.h"
 #include "avcodec.h"
 #include "get_bits.h"
-#include "dsputil.h"
+#include "internal.h"
 #include "rdft.h"
 #include "mpegaudiodsp.h"
 #include "mpegaudio.h"
@@ -129,8 +129,6 @@
  * QDM2 decoder context
  */
 typedef struct {
-    AVFrame frame;
-
     /// Parameters from codec header, do not change during playback
     int nb_channels;         ///< number of channels
     int channels;            ///< number of channels
@@ -648,7 +646,8 @@
 
     if (!superblocktype_2_3) {
         /* This case is untested, no samples available */
-        SAMPLES_NEEDED
+        av_log_ask_for_sample(NULL, "!superblocktype_2_3");
+        return;
         for (ch = 0; ch < nb_channels; ch++)
             for (sb = 0; sb < 30; sb++) {
                 for (j = 1; j < 63; j++) {  // The loop only iterates to 63 so the code doesn't overflow the buffer
@@ -684,7 +683,7 @@
                     for (j = 0; j < 64; j++)
                         acc += tone_level_idx_temp[ch][sb][j];
 
-            multres = 0x66666667 * (acc * 10);
+            multres = 0x66666667LL * (acc * 10);
             esp_40 = (multres >> 32) / 8 + ((multres & 0xffffffff) >> 31);
             for (ch = 0;  ch < nb_channels; ch++)
                 for (sb = 0; sb < 30; sb++)
@@ -927,10 +926,10 @@
 
                 if (joined_stereo) {
                     float tmp[10][MPA_MAX_CHANNELS];
-
                     for (k = 0; k < run; k++) {
                         tmp[k][0] = samples[k];
-                        tmp[k][1] = (sign_bits[(j + k) / 8]) ? -samples[k] : samples[k];
+                        if ((j + k) < 128)
+                            tmp[k][1] = (sign_bits[(j + k) / 8]) ? -samples[k] : samples[k];
                     }
                     for (chs = 0; chs < q->nb_channels; chs++)
                         for (k = 0; k < run; k++)
@@ -1257,7 +1256,7 @@
     for (i = 0; packet_bytes > 0; i++) {
         int j;
 
-        if (i>=FF_ARRAY_ELEMS(q->sub_packet_list_A)) {
+        if (i >= FF_ARRAY_ELEMS(q->sub_packet_list_A)) {
             SAMPLES_NEEDED_2("too many packet bytes");
             return;
         }
@@ -1877,9 +1876,6 @@
 
     avctx->sample_fmt = AV_SAMPLE_FMT_S16;
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     return 0;
 }
 
@@ -1960,6 +1956,7 @@
 static int qdm2_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;
     QDM2Context *s = avctx->priv_data;
@@ -1972,12 +1969,12 @@
         return -1;
 
     /* get output buffer */
-    s->frame.nb_samples = 16 * s->frame_size;
-    if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = 16 * s->frame_size;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    out = (int16_t *)s->frame.data[0];
+    out = (int16_t *)frame->data[0];
 
     for (i = 0; i < 16; i++) {
         if (qdm2_decode(s, buf, out) < 0)
@@ -1985,8 +1982,7 @@
         out += s->channels * s->frame_size;
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
+    *got_frame_ptr = 1;
 
     return s->checksum_size;
 }
diff --git a/libavcodec/qdm2_tablegen.h b/libavcodec/qdm2_tablegen.h
index 585edfd..a90682f 100644
--- a/libavcodec/qdm2_tablegen.h
+++ b/libavcodec/qdm2_tablegen.h
@@ -37,7 +37,7 @@
 #include "libavcodec/qdm2_tables.h"
 #else
 static uint16_t softclip_table[HARDCLIP_THRESHOLD - SOFTCLIP_THRESHOLD + 1];
-static float noise_table[4096];
+static float noise_table[4096 + 20];
 static uint8_t random_dequant_index[256][5];
 static uint8_t random_dequant_type24[128][3];
 static float noise_samples[128];
diff --git a/libavcodec/qdrw.c b/libavcodec/qdrw.c
index ab4c6c1..4ad64aa 100644
--- a/libavcodec/qdrw.c
+++ b/libavcodec/qdrw.c
@@ -27,49 +27,50 @@
 #include "libavutil/common.h"
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
+#include "internal.h"
 
-typedef struct QdrawContext{
+typedef struct QdrawContext {
     AVCodecContext *avctx;
     AVFrame pic;
 } QdrawContext;
 
 static int decode_frame(AVCodecContext *avctx,
-                        void *data, int *data_size,
+                        void *data, int *got_frame,
                         AVPacket *avpkt)
 {
-    const uint8_t *buf = avpkt->data;
+    const uint8_t *buf     = avpkt->data;
     const uint8_t *buf_end = avpkt->data + avpkt->size;
-    int buf_size = avpkt->size;
+    int buf_size           = avpkt->size;
     QdrawContext * const a = avctx->priv_data;
-    AVFrame * const p = &a->pic;
+    AVFrame * const p      = &a->pic;
     uint8_t* outdata;
     int colors;
-    int i;
+    int i, ret;
     uint32_t *pal;
     int r, g, b;
 
-    if(p->data[0])
+    if (p->data[0])
         avctx->release_buffer(avctx, p);
 
-    p->reference= 0;
-    if(avctx->get_buffer(avctx, p) < 0){
+    p->reference = 0;
+    if ((ret = ff_get_buffer(avctx, p)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
-    p->pict_type= AV_PICTURE_TYPE_I;
-    p->key_frame= 1;
+    p->pict_type = AV_PICTURE_TYPE_I;
+    p->key_frame = 1;
 
     outdata = a->pic.data[0];
 
     if (buf_end - buf < 0x68 + 4)
         return AVERROR_INVALIDDATA;
-    buf += 0x68; /* jump to palette */
+    buf   += 0x68; /* jump to palette */
     colors = AV_RB32(buf);
-    buf += 4;
+    buf   += 4;
 
-    if(colors < 0 || colors > 256) {
+    if (colors < 0 || colors > 256) {
         av_log(avctx, AV_LOG_ERROR, "Error color count - %i(0x%X)\n", colors, colors);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     if (buf_end - buf < (colors + 1) * 8)
         return AVERROR_INVALIDDATA;
@@ -105,7 +106,7 @@
         int tsize = 0;
 
         /* decode line */
-        out = outdata;
+        out  = outdata;
         size = AV_RB16(buf); /* size of packed line */
         buf += 2;
         if (buf_end - buf < size)
@@ -120,18 +121,18 @@
                 if ((out + (257 - code)) > (outdata +  a->pic.linesize[0]))
                     break;
                 memset(out, pix, 257 - code);
-                out += 257 - code;
+                out   += 257 - code;
                 tsize += 257 - code;
-                left -= 2;
+                left  -= 2;
             } else { /* copy */
                 if ((out + code) > (outdata +  a->pic.linesize[0]))
                     break;
                 if (buf_end - buf < code + 1)
                     return AVERROR_INVALIDDATA;
                 memcpy(out, buf, code + 1);
-                out += code + 1;
-                buf += code + 1;
-                left -= 2 + code;
+                out   += code + 1;
+                buf   += code + 1;
+                left  -= 2 + code;
                 tsize += code + 1;
             }
         }
@@ -139,13 +140,14 @@
         outdata += a->pic.linesize[0];
     }
 
-    *data_size = sizeof(AVFrame);
+    *got_frame      = 1;
     *(AVFrame*)data = a->pic;
 
     return buf_size;
 }
 
-static av_cold int decode_init(AVCodecContext *avctx){
+static av_cold int decode_init(AVCodecContext *avctx)
+{
     QdrawContext * const a = avctx->priv_data;
 
     avcodec_get_frame_defaults(&a->pic);
@@ -154,7 +156,8 @@
     return 0;
 }
 
-static av_cold int decode_end(AVCodecContext *avctx){
+static av_cold int decode_end(AVCodecContext *avctx)
+{
     QdrawContext * const a = avctx->priv_data;
     AVFrame *pic = &a->pic;
 
diff --git a/libavcodec/qpeg.c b/libavcodec/qpeg.c
index 0a7c788..73d652e 100644
--- a/libavcodec/qpeg.c
+++ b/libavcodec/qpeg.c
@@ -26,6 +26,7 @@
 
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 
 typedef struct QpegContext{
     AVCodecContext *avctx;
@@ -249,7 +250,7 @@
 }
 
 static int decode_frame(AVCodecContext *avctx,
-                        void *data, int *data_size,
+                        void *data, int *got_frame,
                         AVPacket *avpkt)
 {
     uint8_t ctable[128];
@@ -257,7 +258,7 @@
     AVFrame *  p = &a->pic;
     AVFrame * ref= &a->ref;
     uint8_t* outdata;
-    int delta;
+    int delta, ret;
     const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);
 
     if (avpkt->size < 0x86) {
@@ -272,9 +273,9 @@
     FFSWAP(AVFrame, *ref, *p);
 
     p->reference= 3;
-    if(avctx->get_buffer(avctx, p) < 0){
+    if ((ret = ff_get_buffer(avctx, p)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
     outdata = a->pic.data[0];
     bytestream2_skip(&a->buffer, 4);
@@ -295,7 +296,7 @@
     }
     memcpy(a->pic.data[1], a->pal, AVPALETTE_SIZE);
 
-    *data_size = sizeof(AVFrame);
+    *got_frame      = 1;
     *(AVFrame*)data = a->pic;
 
     return avpkt->size;
diff --git a/libavcodec/qtrle.c b/libavcodec/qtrle.c
index d02dffa..1b92885 100644
--- a/libavcodec/qtrle.c
+++ b/libavcodec/qtrle.c
@@ -46,17 +46,17 @@
     uint32_t pal[256];
 } QtrleContext;
 
-#define CHECK_PIXEL_PTR(n) \
-  if ((pixel_ptr + n > pixel_limit) || (pixel_ptr + n < 0)) { \
-    av_log (s->avctx, AV_LOG_INFO, "Problem: pixel_ptr = %d, pixel_limit = %d\n", \
-      pixel_ptr + n, pixel_limit); \
-    return; \
-  } \
+#define CHECK_PIXEL_PTR(n)                                                            \
+    if ((pixel_ptr + n > pixel_limit) || (pixel_ptr + n < 0)) {                       \
+        av_log (s->avctx, AV_LOG_ERROR, "Problem: pixel_ptr = %d, pixel_limit = %d\n",\
+                pixel_ptr + n, pixel_limit);                                          \
+        return;                                                                       \
+    }                                                                                 \
 
 static void qtrle_decode_1bpp(QtrleContext *s, int row_ptr, int lines_to_change)
 {
     int rle_code;
-    int pixel_ptr = 0;
+    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];
@@ -69,9 +69,11 @@
      * would not be counted, so we count one more.
      * See: https://ffmpeg.org/trac/ffmpeg/ticket/226
      * In the following decoding loop, row_ptr will be the position of the
-     * _next_ row. */
-    lines_to_change++;
+     * current row. */
 
+    row_ptr  -= row_inc;
+    pixel_ptr = row_ptr;
+    lines_to_change++;
     while (lines_to_change) {
         skip     =              bytestream2_get_byte(&s->g);
         rle_code = (signed char)bytestream2_get_byte(&s->g);
@@ -79,8 +81,8 @@
             break;
         if(skip & 0x80) {
             lines_to_change--;
-            pixel_ptr = row_ptr + 2 * (skip & 0x7f);
             row_ptr += row_inc;
+            pixel_ptr = row_ptr + 2 * (skip & 0x7f);
         } else
             pixel_ptr += 2 * skip;
         CHECK_PIXEL_PTR(0);  /* make sure pixel_ptr is positive */
@@ -126,7 +128,7 @@
 
     while (lines_to_change--) {
         pixel_ptr = row_ptr + (num_pixels * (bytestream2_get_byte(&s->g) - 1));
-        CHECK_PIXEL_PTR(0);  /* make sure pixel_ptr is positive */
+        CHECK_PIXEL_PTR(0);
 
         while ((rle_code = (signed char)bytestream2_get_byte(&s->g)) != -1) {
             if (rle_code == 0) {
@@ -181,7 +183,7 @@
 
     while (lines_to_change--) {
         pixel_ptr = row_ptr + (4 * (bytestream2_get_byte(&s->g) - 1));
-        CHECK_PIXEL_PTR(0);  /* make sure pixel_ptr is positive */
+        CHECK_PIXEL_PTR(0);
 
         while ((rle_code = (signed char)bytestream2_get_byte(&s->g)) != -1) {
             if (rle_code == 0) {
@@ -231,7 +233,7 @@
 
     while (lines_to_change--) {
         pixel_ptr = row_ptr + (bytestream2_get_byte(&s->g) - 1) * 2;
-        CHECK_PIXEL_PTR(0);  /* make sure pixel_ptr is positive */
+        CHECK_PIXEL_PTR(0);
 
         while ((rle_code = (signed char)bytestream2_get_byte(&s->g)) != -1) {
             if (rle_code == 0) {
@@ -275,7 +277,7 @@
 
     while (lines_to_change--) {
         pixel_ptr = row_ptr + (bytestream2_get_byte(&s->g) - 1) * 3;
-        CHECK_PIXEL_PTR(0);  /* make sure pixel_ptr is positive */
+        CHECK_PIXEL_PTR(0);
 
         while ((rle_code = (signed char)bytestream2_get_byte(&s->g)) != -1) {
             if (rle_code == 0) {
@@ -322,7 +324,7 @@
 
     while (lines_to_change--) {
         pixel_ptr = row_ptr + (bytestream2_get_byte(&s->g) - 1) * 4;
-        CHECK_PIXEL_PTR(0);  /* make sure pixel_ptr is positive */
+        CHECK_PIXEL_PTR(0);
 
         while ((rle_code = (signed char)bytestream2_get_byte(&s->g)) != -1) {
             if (rle_code == 0) {
@@ -400,21 +402,22 @@
 }
 
 static int qtrle_decode_frame(AVCodecContext *avctx,
-                              void *data, int *data_size,
+                              void *data, int *got_frame,
                               AVPacket *avpkt)
 {
     QtrleContext *s = avctx->priv_data;
     int header, start_line;
     int height, row_ptr;
     int has_palette = 0;
+    int ret;
 
     bytestream2_init(&s->g, avpkt->data, avpkt->size);
     s->frame.reference = 3;
     s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE |
                             FF_BUFFER_HINTS_REUSABLE | FF_BUFFER_HINTS_READABLE;
-    if (avctx->reget_buffer(avctx, &s->frame)) {
+    if ((ret = avctx->reget_buffer(avctx, &s->frame)) < 0) {
         av_log (s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     /* check if this frame is even supposed to change */
@@ -498,7 +501,7 @@
     }
 
 done:
-    *data_size = sizeof(AVFrame);
+    *got_frame      = 1;
     *(AVFrame*)data = s->frame;
 
     /* always report that the buffer was completely consumed */
diff --git a/libavcodec/qtrleenc.c b/libavcodec/qtrleenc.c
index e151c9e..a25c45d 100644
--- a/libavcodec/qtrleenc.c
+++ b/libavcodec/qtrleenc.c
@@ -121,8 +121,6 @@
     int i;
     signed char rlecode;
 
-    /* We will use it to compute the best bulk copy sequence */
-    unsigned int av_uninit(bulkcount);
     /* This will be the number of pixels equal to the preivous frame one's
      * starting from the ith pixel */
     unsigned int skipcount;
@@ -131,12 +129,14 @@
     unsigned int av_uninit(repeatcount);
 
     /* The cost of the three different possibilities */
-    int total_bulk_cost;
     int total_skip_cost;
     int total_repeat_cost;
 
-    int temp_cost;
-    int j;
+    int base_bulk_cost;
+    int lowest_bulk_cost;
+    int lowest_bulk_cost_index;
+    int sec_lowest_bulk_cost;
+    int sec_lowest_bulk_cost_index;
 
     uint8_t *this_line = p->               data[0] + line*p->               linesize[0] +
         (width - 1)*s->pixel_size;
@@ -146,8 +146,57 @@
     s->length_table[width] = 0;
     skipcount = 0;
 
+    /* Initial values */
+    lowest_bulk_cost = INT_MAX / 2;
+    lowest_bulk_cost_index = width;
+    sec_lowest_bulk_cost = INT_MAX / 2;
+    sec_lowest_bulk_cost_index = width;
+
+    base_bulk_cost = 1 + s->pixel_size;
+
     for (i = width - 1; i >= 0; i--) {
 
+        int prev_bulk_cost;
+
+        /* If our lowest bulk cost index is too far away, replace it
+         * with the next lowest bulk cost */
+        if (FFMIN(width, i + MAX_RLE_BULK) < lowest_bulk_cost_index) {
+            lowest_bulk_cost = sec_lowest_bulk_cost;
+            lowest_bulk_cost_index = sec_lowest_bulk_cost_index;
+
+            sec_lowest_bulk_cost = INT_MAX / 2;
+            sec_lowest_bulk_cost_index = width;
+        }
+
+        /* Deal with the first pixel's bulk cost */
+        if (!i) {
+            base_bulk_cost++;
+            lowest_bulk_cost++;
+            sec_lowest_bulk_cost++;
+        }
+
+        /* Look at the bulk cost of the previous loop and see if it is
+         * a new lower bulk cost */
+        prev_bulk_cost = s->length_table[i + 1] + base_bulk_cost;
+        if (prev_bulk_cost <= sec_lowest_bulk_cost) {
+            /* If it's lower than the 2nd lowest, then it may be lower
+             * than the lowest */
+            if (prev_bulk_cost <= lowest_bulk_cost) {
+
+                /* If we have found a new lowest bulk cost,
+                 * then the 2nd lowest bulk cost is now farther than the
+                 * lowest bulk cost, and will never be used */
+                sec_lowest_bulk_cost = INT_MAX / 2;
+
+                lowest_bulk_cost = prev_bulk_cost;
+                lowest_bulk_cost_index = i + 1;
+            } else {
+                /* Then it must be the 2nd lowest bulk cost */
+                sec_lowest_bulk_cost = prev_bulk_cost;
+                sec_lowest_bulk_cost_index = i + 1;
+            }
+        }
+
         if (!s->frame.key_frame && !memcmp(this_line, prev_line, s->pixel_size))
             skipcount = FFMIN(skipcount + 1, MAX_RLE_SKIP);
         else
@@ -183,26 +232,17 @@
         }
         else {
             /* We cannot do neither skip nor repeat
-             * thus we search for the best bulk copy to do */
+             * thus we use the best bulk copy  */
 
-            int limit = FFMIN(width - i, MAX_RLE_BULK);
+            s->length_table[i]  = lowest_bulk_cost;
+            s->rlecode_table[i] = lowest_bulk_cost_index - i;
 
-            temp_cost = 1 + s->pixel_size + !i;
-            total_bulk_cost = INT_MAX;
-
-            for (j = 1; j <= limit; j++) {
-                if (s->length_table[i + j] + temp_cost < total_bulk_cost) {
-                    /* We have found a better bulk copy ... */
-                    total_bulk_cost = s->length_table[i + j] + temp_cost;
-                    bulkcount = j;
-                }
-                temp_cost += s->pixel_size;
-            }
-
-            s->length_table[i]  = total_bulk_cost;
-            s->rlecode_table[i] = bulkcount;
         }
 
+        /* These bulk costs increase every iteration */
+        lowest_bulk_cost += s->pixel_size;
+        sec_lowest_bulk_cost += s->pixel_size;
+
         this_line -= s->pixel_size;
         prev_line -= s->pixel_size;
     }
diff --git a/libavcodec/r210dec.c b/libavcodec/r210dec.c
index 4c78b53..b58f11f 100644
--- a/libavcodec/r210dec.c
+++ b/libavcodec/r210dec.c
@@ -21,6 +21,7 @@
  */
 
 #include "avcodec.h"
+#include "internal.h"
 #include "libavutil/bswap.h"
 #include "libavutil/common.h"
 
@@ -36,10 +37,10 @@
     return 0;
 }
 
-static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         AVPacket *avpkt)
 {
-    int h, w;
+    int h, w, ret;
     AVFrame *pic = avctx->coded_frame;
     const uint32_t *src = (const uint32_t *)avpkt->data;
     int aligned_width = FFALIGN(avctx->width,
@@ -51,12 +52,12 @@
 
     if (avpkt->size < 4 * aligned_width * avctx->height) {
         av_log(avctx, AV_LOG_ERROR, "packet too small\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     pic->reference = 0;
-    if (avctx->get_buffer(avctx, pic) < 0)
-        return -1;
+    if ((ret = ff_get_buffer(avctx, pic)) < 0)
+        return ret;
 
     pic->pict_type = AV_PICTURE_TYPE_I;
     pic->key_frame = 1;
@@ -89,7 +90,7 @@
         dst_line += pic->linesize[0];
     }
 
-    *data_size = sizeof(AVFrame);
+    *got_frame      = 1;
     *(AVFrame*)data = *avctx->coded_frame;
 
     return avpkt->size;
diff --git a/libavcodec/ra144.h b/libavcodec/ra144.h
index 331dc35..eb89398 100644
--- a/libavcodec/ra144.h
+++ b/libavcodec/ra144.h
@@ -35,7 +35,6 @@
 
 typedef struct RA144Context {
     AVCodecContext *avctx;
-    AVFrame frame;
     LPCContext lpc_ctx;
     AudioFrameQueue afq;
     int last_frame;
diff --git a/libavcodec/ra144dec.c b/libavcodec/ra144dec.c
index ad9e008..f12954b 100644
--- a/libavcodec/ra144dec.c
+++ b/libavcodec/ra144dec.c
@@ -23,9 +23,9 @@
  */
 
 #include "libavutil/channel_layout.h"
-#include "libavutil/intmath.h"
 #include "avcodec.h"
 #include "get_bits.h"
+#include "internal.h"
 #include "ra144.h"
 
 
@@ -42,9 +42,6 @@
     avctx->channel_layout = AV_CH_LAYOUT_MONO;
     avctx->sample_fmt     = AV_SAMPLE_FMT_S16;
 
-    avcodec_get_frame_defaults(&ractx->frame);
-    avctx->coded_frame = &ractx->frame;
-
     return 0;
 }
 
@@ -64,6 +61,7 @@
 static int ra144_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;
     static const uint8_t sizes[LPC_ORDER] = {6, 5, 5, 4, 4, 3, 3, 3, 3, 2};
@@ -79,12 +77,12 @@
     GetBitContext gb;
 
     /* get output buffer */
-    ractx->frame.nb_samples = NBLOCKS * BLOCKSIZE;
-    if ((ret = avctx->get_buffer(avctx, &ractx->frame)) < 0) {
+    frame->nb_samples = NBLOCKS * BLOCKSIZE;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    samples = (int16_t *)ractx->frame.data[0];
+    samples = (int16_t *)frame->data[0];
 
     if(buf_size < FRAMESIZE) {
         av_log(avctx, AV_LOG_ERROR,
@@ -123,8 +121,7 @@
 
     FFSWAP(unsigned int *, ractx->lpc_coef[0], ractx->lpc_coef[1]);
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = ractx->frame;
+    *got_frame_ptr = 1;
 
     return FRAMESIZE;
 }
diff --git a/libavcodec/ra144enc.c b/libavcodec/ra144enc.c
index 9a8ac2b..bbd7b68 100644
--- a/libavcodec/ra144enc.c
+++ b/libavcodec/ra144enc.c
@@ -208,8 +208,8 @@
 static int adaptive_cb_search(const int16_t *adapt_cb, float *work,
                               const float *coefs, float *data)
 {
-    int i, best_vect;
-    float score, gain, best_score, best_gain;
+    int i, av_uninit(best_vect);
+    float score, gain, best_score, av_uninit(best_gain);
     float exc[BLOCKSIZE];
 
     gain = best_score = 0;
@@ -536,7 +536,7 @@
         for (; i < frame->nb_samples; i++)
             ractx->curr_block[i] = samples[i] >> 2;
 
-        if ((ret = ff_af_queue_add(&ractx->afq, frame) < 0))
+        if ((ret = ff_af_queue_add(&ractx->afq, frame)) < 0)
             return ret;
     } else
         ractx->last_frame = 1;
diff --git a/libavcodec/ra288.c b/libavcodec/ra288.c
index cefc99c..dac8aa6 100644
--- a/libavcodec/ra288.c
+++ b/libavcodec/ra288.c
@@ -21,7 +21,9 @@
 
 #include "libavutil/channel_layout.h"
 #include "libavutil/float_dsp.h"
+#include "libavutil/internal.h"
 #include "avcodec.h"
+#include "internal.h"
 #define BITSTREAM_READER_LE
 #include "get_bits.h"
 #include "ra288.h"
@@ -36,8 +38,6 @@
 #define RA288_BLOCKS_PER_FRAME 32
 
 typedef struct {
-    AVFrame frame;
-    DSPContext dsp;
     AVFloatDSPContext fdsp;
     DECLARE_ALIGNED(32, float,   sp_lpc)[FFALIGN(36, 16)];   ///< LPC coefficients for speech data (spec: A)
     DECLARE_ALIGNED(32, float, gain_lpc)[FFALIGN(10, 16)];   ///< LPC coefficients for gain        (spec: GB)
@@ -74,16 +74,13 @@
 
     avpriv_float_dsp_init(&ractx->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
 
-    avcodec_get_frame_defaults(&ractx->frame);
-    avctx->coded_frame = &ractx->frame;
-
     return 0;
 }
 
 static void convolve(float *tgt, const float *src, int len, int n)
 {
     for (; n >= 0; n--)
-        tgt[n] = ff_scalarproduct_float_c(src, src - n, len);
+        tgt[n] = avpriv_scalarproduct_float_c(src, src - n, len);
 
 }
 
@@ -112,7 +109,7 @@
     for (i=0; i < 5; i++)
         buffer[i] = codetable[cb_coef][i] * sumsum;
 
-    sum = ff_scalarproduct_float_c(buffer, buffer, 5);
+    sum = avpriv_scalarproduct_float_c(buffer, buffer, 5);
 
     sum = FFMAX(sum, 5. / (1<<24));
 
@@ -184,6 +181,7 @@
 static int ra288_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;
     float *out;
@@ -199,12 +197,12 @@
     }
 
     /* get output buffer */
-    ractx->frame.nb_samples = RA288_BLOCK_SIZE * RA288_BLOCKS_PER_FRAME;
-    if ((ret = avctx->get_buffer(avctx, &ractx->frame)) < 0) {
+    frame->nb_samples = RA288_BLOCK_SIZE * RA288_BLOCKS_PER_FRAME;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    out = (float *)ractx->frame.data[0];
+    out = (float *)frame->data[0];
 
     init_get_bits(&gb, buf, avctx->block_align * 8);
 
@@ -226,8 +224,7 @@
         }
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = ractx->frame;
+    *got_frame_ptr = 1;
 
     return avctx->block_align;
 }
diff --git a/libavcodec/ra288.h b/libavcodec/ra288.h
index 0432bed..7323eea 100644
--- a/libavcodec/ra288.h
+++ b/libavcodec/ra288.h
@@ -23,7 +23,6 @@
 #define AVCODEC_RA288_H
 
 #include <stdint.h>
-#include "dsputil.h"
 #include "libavutil/common.h"
 
 static const float amptable[8]={
diff --git a/libavcodec/ralf.c b/libavcodec/ralf.c
index c9c8080..b163a89 100644
--- a/libavcodec/ralf.c
+++ b/libavcodec/ralf.c
@@ -30,6 +30,7 @@
 #include "avcodec.h"
 #include "get_bits.h"
 #include "golomb.h"
+#include "internal.h"
 #include "unary.h"
 #include "ralfdata.h"
 
@@ -48,8 +49,6 @@
 #define RALF_MAX_PKT_SIZE 8192
 
 typedef struct RALFContext {
-    AVFrame frame;
-
     int version;
     int max_frame_size;
     VLCSet sets[3];
@@ -153,9 +152,6 @@
     avctx->channel_layout = (avctx->channels == 2) ? AV_CH_LAYOUT_STEREO
                                                    : AV_CH_LAYOUT_MONO;
 
-    avcodec_get_frame_defaults(&ctx->frame);
-    avctx->coded_frame = &ctx->frame;
-
     ctx->max_frame_size = AV_RB32(avctx->extradata + 16);
     if (ctx->max_frame_size > (1 << 20) || !ctx->max_frame_size) {
         av_log(avctx, AV_LOG_ERROR, "invalid frame size %d\n",
@@ -425,6 +421,7 @@
                         AVPacket *avpkt)
 {
     RALFContext *ctx = avctx->priv_data;
+    AVFrame *frame   = data;
     int16_t *samples0;
     int16_t *samples1;
     int ret;
@@ -462,13 +459,13 @@
         src_size = avpkt->size;
     }
 
-    ctx->frame.nb_samples = ctx->max_frame_size;
-    if ((ret = avctx->get_buffer(avctx, &ctx->frame)) < 0) {
+    frame->nb_samples = ctx->max_frame_size;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "Me fail get_buffer()? That's unpossible!\n");
         return ret;
     }
-    samples0 = (int16_t *)ctx->frame.data[0];
-    samples1 = (int16_t *)ctx->frame.data[1];
+    samples0 = (int16_t *)frame->data[0];
+    samples1 = (int16_t *)frame->data[1];
 
     if (src_size < 5) {
         av_log(avctx, AV_LOG_ERROR, "too short packets are too short!\n");
@@ -510,9 +507,8 @@
         bytes_left    -= ctx->block_size[i];
     }
 
-    ctx->frame.nb_samples = ctx->sample_offset;
-    *got_frame_ptr  = ctx->sample_offset > 0;
-    *(AVFrame*)data = ctx->frame;
+    frame->nb_samples = ctx->sample_offset;
+    *got_frame_ptr    = ctx->sample_offset > 0;
 
     return avpkt->size;
 }
diff --git a/libavcodec/ratecontrol.c b/libavcodec/ratecontrol.c
index 59f69a2..5860423 100644
--- a/libavcodec/ratecontrol.c
+++ b/libavcodec/ratecontrol.c
@@ -25,9 +25,7 @@
  * Rate control for video encoders.
  */
 
-#include "libavutil/intmath.h"
 #include "avcodec.h"
-#include "dsputil.h"
 #include "ratecontrol.h"
 #include "mpegvideo.h"
 #include "libavutil/eval.h"
@@ -40,38 +38,56 @@
 #endif
 
 static int init_pass2(MpegEncContext *s);
-static double get_qscale(MpegEncContext *s, RateControlEntry *rce, double rate_factor, int frame_num);
+static double get_qscale(MpegEncContext *s, RateControlEntry *rce,
+                         double rate_factor, int frame_num);
 
-void ff_write_pass1_stats(MpegEncContext *s){
-    snprintf(s->avctx->stats_out, 256, "in:%d out:%d type:%d q:%d itex:%d ptex:%d mv:%d misc:%d fcode:%d bcode:%d mc-var:%d var:%d icount:%d skipcount:%d hbits:%d;\n",
-             s->current_picture_ptr->f.display_picture_number, s->current_picture_ptr->f.coded_picture_number, s->pict_type,
-             s->current_picture.f.quality, s->i_tex_bits, s->p_tex_bits, s->mv_bits, s->misc_bits,
-             s->f_code, s->b_code, s->current_picture.mc_mb_var_sum, s->current_picture.mb_var_sum, s->i_count, s->skip_count, s->header_bits);
+void ff_write_pass1_stats(MpegEncContext *s)
+{
+    snprintf(s->avctx->stats_out, 256,
+             "in:%d out:%d type:%d q:%d itex:%d ptex:%d mv:%d misc:%d "
+             "fcode:%d bcode:%d mc-var:%d var:%d icount:%d skipcount:%d hbits:%d;\n",
+             s->current_picture_ptr->f.display_picture_number,
+             s->current_picture_ptr->f.coded_picture_number,
+             s->pict_type,
+             s->current_picture.f.quality,
+             s->i_tex_bits,
+             s->p_tex_bits,
+             s->mv_bits,
+             s->misc_bits,
+             s->f_code,
+             s->b_code,
+             s->current_picture.mc_mb_var_sum,
+             s->current_picture.mb_var_sum,
+             s->i_count, s->skip_count,
+             s->header_bits);
 }
 
-static double get_fps(AVCodecContext *avctx){
+static double get_fps(AVCodecContext *avctx)
+{
     return 1.0 / av_q2d(avctx->time_base) / FFMAX(avctx->ticks_per_frame, 1);
 }
 
-static inline double qp2bits(RateControlEntry *rce, double qp){
-    if(qp<=0.0){
+static inline double qp2bits(RateControlEntry *rce, double qp)
+{
+    if (qp <= 0.0) {
         av_log(NULL, AV_LOG_ERROR, "qp<=0.0\n");
     }
-    return rce->qscale * (double)(rce->i_tex_bits + rce->p_tex_bits+1)/ qp;
+    return rce->qscale * (double)(rce->i_tex_bits + rce->p_tex_bits + 1) / qp;
 }
 
-static inline double bits2qp(RateControlEntry *rce, double bits){
-    if(bits<0.9){
+static inline double bits2qp(RateControlEntry *rce, double bits)
+{
+    if (bits < 0.9) {
         av_log(NULL, AV_LOG_ERROR, "bits<0.9\n");
     }
-    return rce->qscale * (double)(rce->i_tex_bits + rce->p_tex_bits+1)/ bits;
+    return rce->qscale * (double)(rce->i_tex_bits + rce->p_tex_bits + 1) / bits;
 }
 
 int ff_rate_control_init(MpegEncContext *s)
 {
-    RateControlContext *rcc= &s->rc_context;
+    RateControlContext *rcc = &s->rc_context;
     int i, res;
-    static const char * const const_names[]={
+    static const char * const const_names[] = {
         "PI",
         "E",
         "iTex",
@@ -87,10 +103,12 @@
         "isB",
         "avgQP",
         "qComp",
-/*        "lastIQP",
+#if 0
+        "lastIQP",
         "lastPQP",
         "lastBQP",
-        "nextNonBQP",*/
+        "nextNonBQP",
+#endif
         "avgIITex",
         "avgPITex",
         "avgPPTex",
@@ -98,12 +116,12 @@
         "avgTex",
         NULL
     };
-    static double (* const func1[])(void *, double)={
+    static double (* const func1[])(void *, double) = {
         (void *)bits2qp,
         (void *)qp2bits,
         NULL
     };
-    static const char * const func1_names[]={
+    static const char * const func1_names[] = {
         "bits2qp",
         "qp2bits",
         NULL
@@ -117,146 +135,162 @@
             s->avctx->rc_max_available_vbv_use = 1.0;
     }
 
-    res = av_expr_parse(&rcc->rc_eq_eval, s->avctx->rc_eq ? s->avctx->rc_eq : "tex^qComp", const_names, func1_names, func1, NULL, NULL, 0, s->avctx);
+    res = av_expr_parse(&rcc->rc_eq_eval,
+                        s->avctx->rc_eq ? s->avctx->rc_eq : "tex^qComp",
+                        const_names, func1_names, func1,
+                        NULL, NULL, 0, s->avctx);
     if (res < 0) {
         av_log(s->avctx, AV_LOG_ERROR, "Error parsing rc_eq \"%s\"\n", s->avctx->rc_eq);
         return res;
     }
 
-    for(i=0; i<5; i++){
-        rcc->pred[i].coeff= FF_QP2LAMBDA * 7.0;
-        rcc->pred[i].count= 1.0;
+    for (i = 0; i < 5; i++) {
+        rcc->pred[i].coeff = FF_QP2LAMBDA * 7.0;
+        rcc->pred[i].count = 1.0;
+        rcc->pred[i].decay = 0.4;
 
-        rcc->pred[i].decay= 0.4;
-        rcc->i_cplx_sum [i]=
-        rcc->p_cplx_sum [i]=
-        rcc->mv_bits_sum[i]=
-        rcc->qscale_sum [i]=
-        rcc->frame_count[i]= 1; // 1 is better because of 1/0 and such
-        rcc->last_qscale_for[i]=FF_QP2LAMBDA * 5;
+        rcc->i_cplx_sum [i] =
+        rcc->p_cplx_sum [i] =
+        rcc->mv_bits_sum[i] =
+        rcc->qscale_sum [i] =
+        rcc->frame_count[i] = 1; // 1 is better because of 1/0 and such
+
+        rcc->last_qscale_for[i] = FF_QP2LAMBDA * 5;
     }
-    rcc->buffer_index= s->avctx->rc_initial_buffer_occupancy;
+    rcc->buffer_index = s->avctx->rc_initial_buffer_occupancy;
     if (!rcc->buffer_index)
         rcc->buffer_index = s->avctx->rc_buffer_size * 3 / 4;
 
-    if(s->flags&CODEC_FLAG_PASS2){
+    if (s->flags & CODEC_FLAG_PASS2) {
         int i;
         char *p;
 
         /* find number of pics */
-        p= s->avctx->stats_in;
-        for(i=-1; p; i++){
-            p= strchr(p+1, ';');
-        }
-        i+= s->max_b_frames;
-        if(i<=0 || i>=INT_MAX / sizeof(RateControlEntry))
+        p = s->avctx->stats_in;
+        for (i = -1; p; i++)
+            p = strchr(p + 1, ';');
+        i += s->max_b_frames;
+        if (i <= 0 || i >= INT_MAX / sizeof(RateControlEntry))
             return -1;
-        rcc->entry = av_mallocz(i*sizeof(RateControlEntry));
-        rcc->num_entries= i;
+        rcc->entry       = av_mallocz(i * sizeof(RateControlEntry));
+        rcc->num_entries = i;
 
-        /* init all to skipped p frames (with b frames we might have a not encoded frame at the end FIXME) */
-        for(i=0; i<rcc->num_entries; i++){
-            RateControlEntry *rce= &rcc->entry[i];
-            rce->pict_type= rce->new_pict_type=AV_PICTURE_TYPE_P;
-            rce->qscale= rce->new_qscale=FF_QP2LAMBDA * 2;
-            rce->misc_bits= s->mb_num + 10;
-            rce->mb_var_sum= s->mb_num*100;
+        /* init all to skipped p frames
+         * (with b frames we might have a not encoded frame at the end FIXME) */
+        for (i = 0; i < rcc->num_entries; i++) {
+            RateControlEntry *rce = &rcc->entry[i];
+
+            rce->pict_type  = rce->new_pict_type = AV_PICTURE_TYPE_P;
+            rce->qscale     = rce->new_qscale    = FF_QP2LAMBDA * 2;
+            rce->misc_bits  = s->mb_num + 10;
+            rce->mb_var_sum = s->mb_num * 100;
         }
 
         /* read stats */
-        p= s->avctx->stats_in;
-        for(i=0; i<rcc->num_entries - s->max_b_frames; i++){
+        p = s->avctx->stats_in;
+        for (i = 0; i < rcc->num_entries - s->max_b_frames; i++) {
             RateControlEntry *rce;
             int picture_number;
             int e;
             char *next;
 
-            next= strchr(p, ';');
-            if(next){
-                (*next)=0; //sscanf in unbelievably slow on looong strings //FIXME copy / do not write
+            next = strchr(p, ';');
+            if (next) {
+                (*next) = 0; // sscanf in unbelievably slow on looong strings // FIXME copy / do not write
                 next++;
             }
-            e= sscanf(p, " in:%d ", &picture_number);
+            e = sscanf(p, " in:%d ", &picture_number);
 
             assert(picture_number >= 0);
             assert(picture_number < rcc->num_entries);
-            rce= &rcc->entry[picture_number];
+            rce = &rcc->entry[picture_number];
 
-            e+=sscanf(p, " in:%*d out:%*d type:%d q:%f itex:%d ptex:%d mv:%d misc:%d fcode:%d bcode:%d mc-var:%d var:%d icount:%d skipcount:%d hbits:%d",
-                   &rce->pict_type, &rce->qscale, &rce->i_tex_bits, &rce->p_tex_bits, &rce->mv_bits, &rce->misc_bits,
-                   &rce->f_code, &rce->b_code, &rce->mc_mb_var_sum, &rce->mb_var_sum, &rce->i_count, &rce->skip_count, &rce->header_bits);
-            if(e!=14){
-                av_log(s->avctx, AV_LOG_ERROR, "statistics are damaged at line %d, parser out=%d\n", i, e);
+            e += sscanf(p, " in:%*d out:%*d type:%d q:%f itex:%d ptex:%d mv:%d misc:%d fcode:%d bcode:%d mc-var:%d var:%d icount:%d skipcount:%d hbits:%d",
+                        &rce->pict_type, &rce->qscale, &rce->i_tex_bits, &rce->p_tex_bits,
+                        &rce->mv_bits, &rce->misc_bits,
+                        &rce->f_code, &rce->b_code,
+                        &rce->mc_mb_var_sum, &rce->mb_var_sum,
+                        &rce->i_count, &rce->skip_count, &rce->header_bits);
+            if (e != 14) {
+                av_log(s->avctx, AV_LOG_ERROR,
+                       "statistics are damaged at line %d, parser out=%d\n",
+                       i, e);
                 return -1;
             }
 
-            p= next;
+            p = next;
         }
 
-        if(init_pass2(s) < 0) return -1;
+        if (init_pass2(s) < 0)
+            return -1;
 
-        //FIXME maybe move to end
-        if((s->flags&CODEC_FLAG_PASS2) && s->avctx->rc_strategy == FF_RC_STRATEGY_XVID) {
+        // FIXME maybe move to end
+        if ((s->flags & CODEC_FLAG_PASS2) && s->avctx->rc_strategy == FF_RC_STRATEGY_XVID) {
 #if CONFIG_LIBXVID
             return ff_xvid_rate_control_init(s);
 #else
-            av_log(s->avctx, AV_LOG_ERROR, "Xvid ratecontrol requires libavcodec compiled with Xvid support.\n");
+            av_log(s->avctx, AV_LOG_ERROR,
+                   "Xvid ratecontrol requires libavcodec compiled with Xvid support.\n");
             return -1;
 #endif
         }
     }
 
-    if(!(s->flags&CODEC_FLAG_PASS2)){
+    if (!(s->flags & CODEC_FLAG_PASS2)) {
+        rcc->short_term_qsum   = 0.001;
+        rcc->short_term_qcount = 0.001;
 
-        rcc->short_term_qsum=0.001;
-        rcc->short_term_qcount=0.001;
+        rcc->pass1_rc_eq_output_sum = 0.001;
+        rcc->pass1_wanted_bits      = 0.001;
 
-        rcc->pass1_rc_eq_output_sum= 0.001;
-        rcc->pass1_wanted_bits=0.001;
-
-        if(s->avctx->qblur > 1.0){
+        if (s->avctx->qblur > 1.0) {
             av_log(s->avctx, AV_LOG_ERROR, "qblur too large\n");
             return -1;
         }
         /* init stuff with the user specified complexity */
-        if(s->avctx->rc_initial_cplx){
-            for(i=0; i<60*30; i++){
-                double bits= s->avctx->rc_initial_cplx * (i/10000.0 + 1.0)*s->mb_num;
+        if (s->avctx->rc_initial_cplx) {
+            for (i = 0; i < 60 * 30; i++) {
+                double bits = s->avctx->rc_initial_cplx * (i / 10000.0 + 1.0) * s->mb_num;
                 RateControlEntry rce;
 
-                if     (i%((s->gop_size+3)/4)==0) rce.pict_type= AV_PICTURE_TYPE_I;
-                else if(i%(s->max_b_frames+1))    rce.pict_type= AV_PICTURE_TYPE_B;
-                else                              rce.pict_type= AV_PICTURE_TYPE_P;
+                if (i % ((s->gop_size + 3) / 4) == 0)
+                    rce.pict_type = AV_PICTURE_TYPE_I;
+                else if (i % (s->max_b_frames + 1))
+                    rce.pict_type = AV_PICTURE_TYPE_B;
+                else
+                    rce.pict_type = AV_PICTURE_TYPE_P;
 
-                rce.new_pict_type= rce.pict_type;
-                rce.mc_mb_var_sum= bits*s->mb_num/100000;
-                rce.mb_var_sum   = s->mb_num;
-                rce.qscale   = FF_QP2LAMBDA * 2;
-                rce.f_code   = 2;
-                rce.b_code   = 1;
-                rce.misc_bits= 1;
+                rce.new_pict_type = rce.pict_type;
+                rce.mc_mb_var_sum = bits * s->mb_num / 100000;
+                rce.mb_var_sum    = s->mb_num;
 
-                if(s->pict_type== AV_PICTURE_TYPE_I){
-                    rce.i_count   = s->mb_num;
-                    rce.i_tex_bits= bits;
-                    rce.p_tex_bits= 0;
-                    rce.mv_bits= 0;
-                }else{
-                    rce.i_count   = 0; //FIXME we do know this approx
-                    rce.i_tex_bits= 0;
-                    rce.p_tex_bits= bits*0.9;
-                    rce.mv_bits= bits*0.1;
+                rce.qscale    = FF_QP2LAMBDA * 2;
+                rce.f_code    = 2;
+                rce.b_code    = 1;
+                rce.misc_bits = 1;
+
+                if (s->pict_type == AV_PICTURE_TYPE_I) {
+                    rce.i_count    = s->mb_num;
+                    rce.i_tex_bits = bits;
+                    rce.p_tex_bits = 0;
+                    rce.mv_bits    = 0;
+                } else {
+                    rce.i_count    = 0; // FIXME we do know this approx
+                    rce.i_tex_bits = 0;
+                    rce.p_tex_bits = bits * 0.9;
+                    rce.mv_bits    = bits * 0.1;
                 }
-                rcc->i_cplx_sum [rce.pict_type] += rce.i_tex_bits*rce.qscale;
-                rcc->p_cplx_sum [rce.pict_type] += rce.p_tex_bits*rce.qscale;
+                rcc->i_cplx_sum[rce.pict_type]  += rce.i_tex_bits * rce.qscale;
+                rcc->p_cplx_sum[rce.pict_type]  += rce.p_tex_bits * rce.qscale;
                 rcc->mv_bits_sum[rce.pict_type] += rce.mv_bits;
-                rcc->frame_count[rce.pict_type] ++;
+                rcc->frame_count[rce.pict_type]++;
 
-                get_qscale(s, &rce, rcc->pass1_wanted_bits/rcc->pass1_rc_eq_output_sum, i);
-                rcc->pass1_wanted_bits+= s->bit_rate/get_fps(s->avctx); //FIXME misbehaves a little for variable fps
+                get_qscale(s, &rce, rcc->pass1_wanted_bits / rcc->pass1_rc_eq_output_sum, i);
+
+                // FIXME misbehaves a little for variable fps
+                rcc->pass1_wanted_bits += s->bit_rate / get_fps(s->avctx);
             }
         }
-
     }
 
     return 0;
@@ -264,47 +298,49 @@
 
 void ff_rate_control_uninit(MpegEncContext *s)
 {
-    RateControlContext *rcc= &s->rc_context;
+    RateControlContext *rcc = &s->rc_context;
     emms_c();
 
     av_expr_free(rcc->rc_eq_eval);
     av_freep(&rcc->entry);
 
 #if CONFIG_LIBXVID
-    if((s->flags&CODEC_FLAG_PASS2) && s->avctx->rc_strategy == FF_RC_STRATEGY_XVID)
+    if ((s->flags & CODEC_FLAG_PASS2) && s->avctx->rc_strategy == FF_RC_STRATEGY_XVID)
         ff_xvid_rate_control_uninit(s);
 #endif
 }
 
-int ff_vbv_update(MpegEncContext *s, int frame_size){
-    RateControlContext *rcc= &s->rc_context;
-    const double fps= get_fps(s->avctx);
-    const int buffer_size= s->avctx->rc_buffer_size;
-    const double min_rate= s->avctx->rc_min_rate/fps;
-    const double max_rate= s->avctx->rc_max_rate/fps;
+int ff_vbv_update(MpegEncContext *s, int frame_size)
+{
+    RateControlContext *rcc = &s->rc_context;
+    const double fps        = get_fps(s->avctx);
+    const int buffer_size   = s->avctx->rc_buffer_size;
+    const double min_rate   = s->avctx->rc_min_rate / fps;
+    const double max_rate   = s->avctx->rc_max_rate / fps;
 
     av_dlog(s, "%d %f %d %f %f\n",
             buffer_size, rcc->buffer_index, frame_size, min_rate, max_rate);
-    if(buffer_size){
+
+    if (buffer_size) {
         int left;
 
-        rcc->buffer_index-= frame_size;
-        if(rcc->buffer_index < 0){
+        rcc->buffer_index -= frame_size;
+        if (rcc->buffer_index < 0) {
             av_log(s->avctx, AV_LOG_ERROR, "rc buffer underflow\n");
-            rcc->buffer_index= 0;
+            rcc->buffer_index = 0;
         }
 
-        left= buffer_size - rcc->buffer_index - 1;
+        left = buffer_size - rcc->buffer_index - 1;
         rcc->buffer_index += av_clip(left, min_rate, max_rate);
 
-        if(rcc->buffer_index > buffer_size){
-            int stuffing= ceil((rcc->buffer_index - buffer_size)/8);
+        if (rcc->buffer_index > buffer_size) {
+            int stuffing = ceil((rcc->buffer_index - buffer_size) / 8);
 
-            if(stuffing < 4 && s->codec_id == AV_CODEC_ID_MPEG4)
-                stuffing=4;
-            rcc->buffer_index -= 8*stuffing;
+            if (stuffing < 4 && s->codec_id == AV_CODEC_ID_MPEG4)
+                stuffing = 4;
+            rcc->buffer_index -= 8 * stuffing;
 
-            if(s->avctx->debug & FF_DEBUG_RC)
+            if (s->avctx->debug & FF_DEBUG_RC)
                 av_log(s->avctx, AV_LOG_DEBUG, "stuffing %d bytes\n", stuffing);
 
             return stuffing;
@@ -316,34 +352,38 @@
 /**
  * Modify the bitrate curve from pass1 for one frame.
  */
-static double get_qscale(MpegEncContext *s, RateControlEntry *rce, double rate_factor, int frame_num){
-    RateControlContext *rcc= &s->rc_context;
-    AVCodecContext *a= s->avctx;
+static double get_qscale(MpegEncContext *s, RateControlEntry *rce,
+                         double rate_factor, int frame_num)
+{
+    RateControlContext *rcc = &s->rc_context;
+    AVCodecContext *a       = s->avctx;
+    const int pict_type     = rce->new_pict_type;
+    const double mb_num     = s->mb_num;
     double q, bits;
-    const int pict_type= rce->new_pict_type;
-    const double mb_num= s->mb_num;
     int i;
 
-    double const_values[]={
+    double const_values[] = {
         M_PI,
         M_E,
-        rce->i_tex_bits*rce->qscale,
-        rce->p_tex_bits*rce->qscale,
-        (rce->i_tex_bits + rce->p_tex_bits)*(double)rce->qscale,
-        rce->mv_bits/mb_num,
-        rce->pict_type == AV_PICTURE_TYPE_B ? (rce->f_code + rce->b_code)*0.5 : rce->f_code,
-        rce->i_count/mb_num,
-        rce->mc_mb_var_sum/mb_num,
-        rce->mb_var_sum/mb_num,
+        rce->i_tex_bits * rce->qscale,
+        rce->p_tex_bits * rce->qscale,
+        (rce->i_tex_bits + rce->p_tex_bits) * (double)rce->qscale,
+        rce->mv_bits / mb_num,
+        rce->pict_type == AV_PICTURE_TYPE_B ? (rce->f_code + rce->b_code) * 0.5 : rce->f_code,
+        rce->i_count / mb_num,
+        rce->mc_mb_var_sum / mb_num,
+        rce->mb_var_sum / mb_num,
         rce->pict_type == AV_PICTURE_TYPE_I,
         rce->pict_type == AV_PICTURE_TYPE_P,
         rce->pict_type == AV_PICTURE_TYPE_B,
         rcc->qscale_sum[pict_type] / (double)rcc->frame_count[pict_type],
         a->qcompress,
-/*        rcc->last_qscale_for[AV_PICTURE_TYPE_I],
+#if 0
+        rcc->last_qscale_for[AV_PICTURE_TYPE_I],
         rcc->last_qscale_for[AV_PICTURE_TYPE_P],
         rcc->last_qscale_for[AV_PICTURE_TYPE_B],
-        rcc->next_non_b_qscale,*/
+        rcc->next_non_b_qscale,
+#endif
         rcc->i_cplx_sum[AV_PICTURE_TYPE_I] / (double)rcc->frame_count[AV_PICTURE_TYPE_I],
         rcc->i_cplx_sum[AV_PICTURE_TYPE_P] / (double)rcc->frame_count[AV_PICTURE_TYPE_P],
         rcc->p_cplx_sum[AV_PICTURE_TYPE_P] / (double)rcc->frame_count[AV_PICTURE_TYPE_P],
@@ -358,61 +398,71 @@
         return -1;
     }
 
-    rcc->pass1_rc_eq_output_sum+= bits;
-    bits*=rate_factor;
-    if(bits<0.0) bits=0.0;
-    bits+= 1.0; //avoid 1/0 issues
+    rcc->pass1_rc_eq_output_sum += bits;
+    bits *= rate_factor;
+    if (bits < 0.0)
+        bits = 0.0;
+    bits += 1.0; // avoid 1/0 issues
 
     /* user override */
-    for(i=0; i<s->avctx->rc_override_count; i++){
-        RcOverride *rco= s->avctx->rc_override;
-        if(rco[i].start_frame > frame_num) continue;
-        if(rco[i].end_frame   < frame_num) continue;
+    for (i = 0; i < s->avctx->rc_override_count; i++) {
+        RcOverride *rco = s->avctx->rc_override;
+        if (rco[i].start_frame > frame_num)
+            continue;
+        if (rco[i].end_frame < frame_num)
+            continue;
 
-        if(rco[i].qscale)
-            bits= qp2bits(rce, rco[i].qscale); //FIXME move at end to really force it?
+        if (rco[i].qscale)
+            bits = qp2bits(rce, rco[i].qscale);  // FIXME move at end to really force it?
         else
-            bits*= rco[i].quality_factor;
+            bits *= rco[i].quality_factor;
     }
 
-    q= bits2qp(rce, bits);
+    q = bits2qp(rce, bits);
 
     /* I/B difference */
-    if     (pict_type==AV_PICTURE_TYPE_I && s->avctx->i_quant_factor<0.0)
-        q= -q*s->avctx->i_quant_factor + s->avctx->i_quant_offset;
-    else if(pict_type==AV_PICTURE_TYPE_B && s->avctx->b_quant_factor<0.0)
-        q= -q*s->avctx->b_quant_factor + s->avctx->b_quant_offset;
-    if(q<1) q=1;
+    if (pict_type == AV_PICTURE_TYPE_I && s->avctx->i_quant_factor < 0.0)
+        q = -q * s->avctx->i_quant_factor + s->avctx->i_quant_offset;
+    else if (pict_type == AV_PICTURE_TYPE_B && s->avctx->b_quant_factor < 0.0)
+        q = -q * s->avctx->b_quant_factor + s->avctx->b_quant_offset;
+    if (q < 1)
+        q = 1;
 
     return q;
 }
 
-static double get_diff_limited_q(MpegEncContext *s, RateControlEntry *rce, double q){
-    RateControlContext *rcc= &s->rc_context;
-    AVCodecContext *a= s->avctx;
-    const int pict_type= rce->new_pict_type;
-    const double last_p_q    = rcc->last_qscale_for[AV_PICTURE_TYPE_P];
-    const double last_non_b_q= rcc->last_qscale_for[rcc->last_non_b_pict_type];
+static double get_diff_limited_q(MpegEncContext *s, RateControlEntry *rce, double q)
+{
+    RateControlContext *rcc   = &s->rc_context;
+    AVCodecContext *a         = s->avctx;
+    const int pict_type       = rce->new_pict_type;
+    const double last_p_q     = rcc->last_qscale_for[AV_PICTURE_TYPE_P];
+    const double last_non_b_q = rcc->last_qscale_for[rcc->last_non_b_pict_type];
 
-    if     (pict_type==AV_PICTURE_TYPE_I && (a->i_quant_factor>0.0 || rcc->last_non_b_pict_type==AV_PICTURE_TYPE_P))
-        q= last_p_q    *FFABS(a->i_quant_factor) + a->i_quant_offset;
-    else if(pict_type==AV_PICTURE_TYPE_B && a->b_quant_factor>0.0)
-        q= last_non_b_q*    a->b_quant_factor  + a->b_quant_offset;
-    if(q<1) q=1;
+    if (pict_type == AV_PICTURE_TYPE_I &&
+        (a->i_quant_factor > 0.0 || rcc->last_non_b_pict_type == AV_PICTURE_TYPE_P))
+        q = last_p_q * FFABS(a->i_quant_factor) + a->i_quant_offset;
+    else if (pict_type == AV_PICTURE_TYPE_B &&
+             a->b_quant_factor > 0.0)
+        q = last_non_b_q * a->b_quant_factor + a->b_quant_offset;
+    if (q < 1)
+        q = 1;
 
     /* last qscale / qdiff stuff */
-    if(rcc->last_non_b_pict_type==pict_type || pict_type!=AV_PICTURE_TYPE_I){
-        double last_q= rcc->last_qscale_for[pict_type];
-        const int maxdiff= FF_QP2LAMBDA * a->max_qdiff;
+    if (rcc->last_non_b_pict_type == pict_type || pict_type != AV_PICTURE_TYPE_I) {
+        double last_q     = rcc->last_qscale_for[pict_type];
+        const int maxdiff = FF_QP2LAMBDA * a->max_qdiff;
 
-        if     (q > last_q + maxdiff) q= last_q + maxdiff;
-        else if(q < last_q - maxdiff) q= last_q - maxdiff;
+        if (q > last_q + maxdiff)
+            q = last_q + maxdiff;
+        else if (q < last_q - maxdiff)
+            q = last_q - maxdiff;
     }
 
-    rcc->last_qscale_for[pict_type]= q; //Note we cannot do that after blurring
+    rcc->last_qscale_for[pict_type] = q; // Note we cannot do that after blurring
 
-    if(pict_type!=AV_PICTURE_TYPE_B)
-        rcc->last_non_b_pict_type= pict_type;
+    if (pict_type != AV_PICTURE_TYPE_B)
+        rcc->last_non_b_pict_type = pict_type;
 
     return q;
 }
@@ -420,239 +470,269 @@
 /**
  * Get the qmin & qmax for pict_type.
  */
-static void get_qminmax(int *qmin_ret, int *qmax_ret, MpegEncContext *s, int pict_type){
-    int qmin= s->avctx->lmin;
-    int qmax= s->avctx->lmax;
+static void get_qminmax(int *qmin_ret, int *qmax_ret, MpegEncContext *s, int pict_type)
+{
+    int qmin = s->avctx->lmin;
+    int qmax = s->avctx->lmax;
 
     assert(qmin <= qmax);
 
-    if(pict_type==AV_PICTURE_TYPE_B){
-        qmin= (int)(qmin*FFABS(s->avctx->b_quant_factor)+s->avctx->b_quant_offset + 0.5);
-        qmax= (int)(qmax*FFABS(s->avctx->b_quant_factor)+s->avctx->b_quant_offset + 0.5);
-    }else if(pict_type==AV_PICTURE_TYPE_I){
-        qmin= (int)(qmin*FFABS(s->avctx->i_quant_factor)+s->avctx->i_quant_offset + 0.5);
-        qmax= (int)(qmax*FFABS(s->avctx->i_quant_factor)+s->avctx->i_quant_offset + 0.5);
+    switch (pict_type) {
+    case AV_PICTURE_TYPE_B:
+        qmin = (int)(qmin * FFABS(s->avctx->b_quant_factor) + s->avctx->b_quant_offset + 0.5);
+        qmax = (int)(qmax * FFABS(s->avctx->b_quant_factor) + s->avctx->b_quant_offset + 0.5);
+        break;
+    case AV_PICTURE_TYPE_I:
+        qmin = (int)(qmin * FFABS(s->avctx->i_quant_factor) + s->avctx->i_quant_offset + 0.5);
+        qmax = (int)(qmax * FFABS(s->avctx->i_quant_factor) + s->avctx->i_quant_offset + 0.5);
+        break;
     }
 
-    qmin= av_clip(qmin, 1, FF_LAMBDA_MAX);
-    qmax= av_clip(qmax, 1, FF_LAMBDA_MAX);
+    qmin = av_clip(qmin, 1, FF_LAMBDA_MAX);
+    qmax = av_clip(qmax, 1, FF_LAMBDA_MAX);
 
-    if(qmax<qmin) qmax= qmin;
+    if (qmax < qmin)
+        qmax = qmin;
 
-    *qmin_ret= qmin;
-    *qmax_ret= qmax;
+    *qmin_ret = qmin;
+    *qmax_ret = qmax;
 }
 
-static double modify_qscale(MpegEncContext *s, RateControlEntry *rce, double q, int frame_num){
-    RateControlContext *rcc= &s->rc_context;
+static double modify_qscale(MpegEncContext *s, RateControlEntry *rce,
+                            double q, int frame_num)
+{
+    RateControlContext *rcc  = &s->rc_context;
+    const double buffer_size = s->avctx->rc_buffer_size;
+    const double fps         = get_fps(s->avctx);
+    const double min_rate    = s->avctx->rc_min_rate / fps;
+    const double max_rate    = s->avctx->rc_max_rate / fps;
+    const int pict_type      = rce->new_pict_type;
     int qmin, qmax;
-    const int pict_type= rce->new_pict_type;
-    const double buffer_size= s->avctx->rc_buffer_size;
-    const double fps= get_fps(s->avctx);
-    const double min_rate= s->avctx->rc_min_rate / fps;
-    const double max_rate= s->avctx->rc_max_rate / fps;
 
     get_qminmax(&qmin, &qmax, s, pict_type);
 
     /* modulation */
-    if(s->avctx->rc_qmod_freq && frame_num%s->avctx->rc_qmod_freq==0 && pict_type==AV_PICTURE_TYPE_P)
-        q*= s->avctx->rc_qmod_amp;
+    if (s->avctx->rc_qmod_freq &&
+        frame_num % s->avctx->rc_qmod_freq == 0 &&
+        pict_type == AV_PICTURE_TYPE_P)
+        q *= s->avctx->rc_qmod_amp;
 
     /* buffer overflow/underflow protection */
-    if(buffer_size){
-        double expected_size= rcc->buffer_index;
+    if (buffer_size) {
+        double expected_size = rcc->buffer_index;
         double q_limit;
 
-        if(min_rate){
-            double d= 2*(buffer_size - expected_size)/buffer_size;
-            if(d>1.0) d=1.0;
-            else if(d<0.0001) d=0.0001;
-            q*= pow(d, 1.0/s->avctx->rc_buffer_aggressivity);
+        if (min_rate) {
+            double d = 2 * (buffer_size - expected_size) / buffer_size;
+            if (d > 1.0)
+                d = 1.0;
+            else if (d < 0.0001)
+                d = 0.0001;
+            q *= pow(d, 1.0 / s->avctx->rc_buffer_aggressivity);
 
-            q_limit= bits2qp(rce, FFMAX((min_rate - buffer_size + rcc->buffer_index) * s->avctx->rc_min_vbv_overflow_use, 1));
-            if(q > q_limit){
-                if(s->avctx->debug&FF_DEBUG_RC){
-                    av_log(s->avctx, AV_LOG_DEBUG, "limiting QP %f -> %f\n", q, q_limit);
-                }
-                q= q_limit;
+            q_limit = bits2qp(rce,
+                              FFMAX((min_rate - buffer_size + rcc->buffer_index) *
+                                    s->avctx->rc_min_vbv_overflow_use, 1));
+
+            if (q > q_limit) {
+                if (s->avctx->debug & FF_DEBUG_RC)
+                    av_log(s->avctx, AV_LOG_DEBUG,
+                           "limiting QP %f -> %f\n", q, q_limit);
+                q = q_limit;
             }
         }
 
-        if(max_rate){
-            double d= 2*expected_size/buffer_size;
-            if(d>1.0) d=1.0;
-            else if(d<0.0001) d=0.0001;
-            q/= pow(d, 1.0/s->avctx->rc_buffer_aggressivity);
+        if (max_rate) {
+            double d = 2 * expected_size / buffer_size;
+            if (d > 1.0)
+                d = 1.0;
+            else if (d < 0.0001)
+                d = 0.0001;
+            q /= pow(d, 1.0 / s->avctx->rc_buffer_aggressivity);
 
-            q_limit= bits2qp(rce, FFMAX(rcc->buffer_index * s->avctx->rc_max_available_vbv_use, 1));
-            if(q < q_limit){
-                if(s->avctx->debug&FF_DEBUG_RC){
-                    av_log(s->avctx, AV_LOG_DEBUG, "limiting QP %f -> %f\n", q, q_limit);
-                }
-                q= q_limit;
+            q_limit = bits2qp(rce,
+                              FFMAX(rcc->buffer_index *
+                                    s->avctx->rc_max_available_vbv_use,
+                                    1));
+            if (q < q_limit) {
+                if (s->avctx->debug & FF_DEBUG_RC)
+                    av_log(s->avctx, AV_LOG_DEBUG,
+                           "limiting QP %f -> %f\n", q, q_limit);
+                q = q_limit;
             }
         }
     }
     av_dlog(s, "q:%f max:%f min:%f size:%f index:%f agr:%f\n",
             q, max_rate, min_rate, buffer_size, rcc->buffer_index,
             s->avctx->rc_buffer_aggressivity);
-    if(s->avctx->rc_qsquish==0.0 || qmin==qmax){
-        if     (q<qmin) q=qmin;
-        else if(q>qmax) q=qmax;
-    }else{
-        double min2= log(qmin);
-        double max2= log(qmax);
+    if (s->avctx->rc_qsquish == 0.0 || qmin == qmax) {
+        if (q < qmin)
+            q = qmin;
+        else if (q > qmax)
+            q = qmax;
+    } else {
+        double min2 = log(qmin);
+        double max2 = log(qmax);
 
-        q= log(q);
-        q= (q - min2)/(max2-min2) - 0.5;
-        q*= -4.0;
-        q= 1.0/(1.0 + exp(q));
-        q= q*(max2-min2) + min2;
+        q  = log(q);
+        q  = (q - min2) / (max2 - min2) - 0.5;
+        q *= -4.0;
+        q  = 1.0 / (1.0 + exp(q));
+        q  = q * (max2 - min2) + min2;
 
-        q= exp(q);
+        q = exp(q);
     }
 
     return q;
 }
 
-//----------------------------------
+// ----------------------------------
 // 1 Pass Code
 
 static double predict_size(Predictor *p, double q, double var)
 {
-     return p->coeff*var / (q*p->count);
+    return p->coeff * var / (q * p->count);
 }
 
 static void update_predictor(Predictor *p, double q, double var, double size)
 {
-    double new_coeff= size*q / (var + 1);
-    if(var<10) return;
+    double new_coeff = size * q / (var + 1);
+    if (var < 10)
+        return;
 
-    p->count*= p->decay;
-    p->coeff*= p->decay;
+    p->count *= p->decay;
+    p->coeff *= p->decay;
     p->count++;
-    p->coeff+= new_coeff;
+    p->coeff += new_coeff;
 }
 
-static void adaptive_quantization(MpegEncContext *s, double q){
+static void adaptive_quantization(MpegEncContext *s, double q)
+{
     int i;
-    const float lumi_masking= s->avctx->lumi_masking / (128.0*128.0);
-    const float dark_masking= s->avctx->dark_masking / (128.0*128.0);
-    const float temp_cplx_masking= s->avctx->temporal_cplx_masking;
+    const float lumi_masking         = s->avctx->lumi_masking / (128.0 * 128.0);
+    const float dark_masking         = s->avctx->dark_masking / (128.0 * 128.0);
+    const float temp_cplx_masking    = s->avctx->temporal_cplx_masking;
     const float spatial_cplx_masking = s->avctx->spatial_cplx_masking;
-    const float p_masking = s->avctx->p_masking;
-    const float border_masking = s->avctx->border_masking;
-    float bits_sum= 0.0;
-    float cplx_sum= 0.0;
-    float *cplx_tab = s->cplx_tab;
-    float *bits_tab = s->bits_tab;
-    const int qmin= s->avctx->mb_lmin;
-    const int qmax= s->avctx->mb_lmax;
-    Picture * const pic= &s->current_picture;
-    const int mb_width = s->mb_width;
-    const int mb_height = s->mb_height;
+    const float p_masking            = s->avctx->p_masking;
+    const float border_masking       = s->avctx->border_masking;
+    float bits_sum                   = 0.0;
+    float cplx_sum                   = 0.0;
+    float *cplx_tab                  = s->cplx_tab;
+    float *bits_tab                  = s->bits_tab;
+    const int qmin                   = s->avctx->mb_lmin;
+    const int qmax                   = s->avctx->mb_lmax;
+    Picture *const pic               = &s->current_picture;
+    const int mb_width               = s->mb_width;
+    const int mb_height              = s->mb_height;
 
-    for(i=0; i<s->mb_num; i++){
-        const int mb_xy= s->mb_index2xy[i];
-        float temp_cplx= sqrt(pic->mc_mb_var[mb_xy]); //FIXME merge in pow()
-        float spat_cplx= sqrt(pic->mb_var[mb_xy]);
-        const int lumi= pic->mb_mean[mb_xy];
+    for (i = 0; i < s->mb_num; i++) {
+        const int mb_xy = s->mb_index2xy[i];
+        float temp_cplx = sqrt(pic->mc_mb_var[mb_xy]); // FIXME merge in pow()
+        float spat_cplx = sqrt(pic->mb_var[mb_xy]);
+        const int lumi  = pic->mb_mean[mb_xy];
         float bits, cplx, factor;
         int mb_x = mb_xy % s->mb_stride;
         int mb_y = mb_xy / s->mb_stride;
         int mb_distance;
         float mb_factor = 0.0;
-        if(spat_cplx < 4) spat_cplx= 4; //FIXME finetune
-        if(temp_cplx < 4) temp_cplx= 4; //FIXME finetune
+        if (spat_cplx < 4)
+            spat_cplx = 4;              // FIXME finetune
+        if (temp_cplx < 4)
+            temp_cplx = 4;              // FIXME finetune
 
-        if((s->mb_type[mb_xy]&CANDIDATE_MB_TYPE_INTRA)){//FIXME hq mode
-            cplx= spat_cplx;
-            factor= 1.0 + p_masking;
-        }else{
-            cplx= temp_cplx;
-            factor= pow(temp_cplx, - temp_cplx_masking);
+        if ((s->mb_type[mb_xy] & CANDIDATE_MB_TYPE_INTRA)) { // FIXME hq mode
+            cplx   = spat_cplx;
+            factor = 1.0 + p_masking;
+        } else {
+            cplx   = temp_cplx;
+            factor = pow(temp_cplx, -temp_cplx_masking);
         }
-        factor*=pow(spat_cplx, - spatial_cplx_masking);
+        factor *= pow(spat_cplx, -spatial_cplx_masking);
 
-        if(lumi>127)
-            factor*= (1.0 - (lumi-128)*(lumi-128)*lumi_masking);
+        if (lumi > 127)
+            factor *= (1.0 - (lumi - 128) * (lumi - 128) * lumi_masking);
         else
-            factor*= (1.0 - (lumi-128)*(lumi-128)*dark_masking);
+            factor *= (1.0 - (lumi - 128) * (lumi - 128) * dark_masking);
 
-        if(mb_x < mb_width/5){
-            mb_distance = mb_width/5 - mb_x;
-            mb_factor = (float)mb_distance / (float)(mb_width/5);
-        }else if(mb_x > 4*mb_width/5){
-            mb_distance = mb_x - 4*mb_width/5;
-            mb_factor = (float)mb_distance / (float)(mb_width/5);
+        if (mb_x < mb_width / 5) {
+            mb_distance = mb_width / 5 - mb_x;
+            mb_factor   = (float)mb_distance / (float)(mb_width / 5);
+        } else if (mb_x > 4 * mb_width / 5) {
+            mb_distance = mb_x - 4 * mb_width / 5;
+            mb_factor   = (float)mb_distance / (float)(mb_width / 5);
         }
-        if(mb_y < mb_height/5){
-            mb_distance = mb_height/5 - mb_y;
-            mb_factor = FFMAX(mb_factor, (float)mb_distance / (float)(mb_height/5));
-        }else if(mb_y > 4*mb_height/5){
-            mb_distance = mb_y - 4*mb_height/5;
-            mb_factor = FFMAX(mb_factor, (float)mb_distance / (float)(mb_height/5));
+        if (mb_y < mb_height / 5) {
+            mb_distance = mb_height / 5 - mb_y;
+            mb_factor   = FFMAX(mb_factor,
+                                (float)mb_distance / (float)(mb_height / 5));
+        } else if (mb_y > 4 * mb_height / 5) {
+            mb_distance = mb_y - 4 * mb_height / 5;
+            mb_factor   = FFMAX(mb_factor,
+                                (float)mb_distance / (float)(mb_height / 5));
         }
 
-        factor*= 1.0 - border_masking*mb_factor;
+        factor *= 1.0 - border_masking * mb_factor;
 
-        if(factor<0.00001) factor= 0.00001;
+        if (factor < 0.00001)
+            factor = 0.00001;
 
-        bits= cplx*factor;
-        cplx_sum+= cplx;
-        bits_sum+= bits;
-        cplx_tab[i]= cplx;
-        bits_tab[i]= bits;
+        bits        = cplx * factor;
+        cplx_sum   += cplx;
+        bits_sum   += bits;
+        cplx_tab[i] = cplx;
+        bits_tab[i] = bits;
     }
 
     /* handle qmin/qmax clipping */
-    if(s->flags&CODEC_FLAG_NORMALIZE_AQP){
-        float factor= bits_sum/cplx_sum;
-        for(i=0; i<s->mb_num; i++){
-            float newq= q*cplx_tab[i]/bits_tab[i];
-            newq*= factor;
+    if (s->flags & CODEC_FLAG_NORMALIZE_AQP) {
+        float factor = bits_sum / cplx_sum;
+        for (i = 0; i < s->mb_num; i++) {
+            float newq = q * cplx_tab[i] / bits_tab[i];
+            newq *= factor;
 
-            if     (newq > qmax){
+            if (newq > qmax) {
                 bits_sum -= bits_tab[i];
-                cplx_sum -= cplx_tab[i]*q/qmax;
-            }
-            else if(newq < qmin){
+                cplx_sum -= cplx_tab[i] * q / qmax;
+            } else if (newq < qmin) {
                 bits_sum -= bits_tab[i];
-                cplx_sum -= cplx_tab[i]*q/qmin;
+                cplx_sum -= cplx_tab[i] * q / qmin;
             }
         }
-        if(bits_sum < 0.001) bits_sum= 0.001;
-        if(cplx_sum < 0.001) cplx_sum= 0.001;
+        if (bits_sum < 0.001)
+            bits_sum = 0.001;
+        if (cplx_sum < 0.001)
+            cplx_sum = 0.001;
     }
 
-    for(i=0; i<s->mb_num; i++){
-        const int mb_xy= s->mb_index2xy[i];
-        float newq= q*cplx_tab[i]/bits_tab[i];
+    for (i = 0; i < s->mb_num; i++) {
+        const int mb_xy = s->mb_index2xy[i];
+        float newq      = q * cplx_tab[i] / bits_tab[i];
         int intq;
 
-        if(s->flags&CODEC_FLAG_NORMALIZE_AQP){
-            newq*= bits_sum/cplx_sum;
+        if (s->flags & CODEC_FLAG_NORMALIZE_AQP) {
+            newq *= bits_sum / cplx_sum;
         }
 
-        intq= (int)(newq + 0.5);
+        intq = (int)(newq + 0.5);
 
-        if     (intq > qmax) intq= qmax;
-        else if(intq < qmin) intq= qmin;
-        s->lambda_table[mb_xy]= intq;
+        if (intq > qmax)
+            intq = qmax;
+        else if (intq < qmin)
+            intq = qmin;
+        s->lambda_table[mb_xy] = intq;
     }
 }
 
-void ff_get_2pass_fcode(MpegEncContext *s){
-    RateControlContext *rcc= &s->rc_context;
-    int picture_number= s->picture_number;
-    RateControlEntry *rce;
+void ff_get_2pass_fcode(MpegEncContext *s)
+{
+    RateControlContext *rcc = &s->rc_context;
+    RateControlEntry *rce   = &rcc->entry[s->picture_number];
 
-    rce= &rcc->entry[picture_number];
-    s->f_code= rce->f_code;
-    s->b_code= rce->b_code;
+    s->f_code = rce->f_code;
+    s->b_code = rce->b_code;
 }
 
-//FIXME rd or at least approx for dquant
+// FIXME rd or at least approx for dquant
 
 float ff_rate_estimate_qscale(MpegEncContext *s, int dry_run)
 {
@@ -662,259 +742,283 @@
     double diff;
     double short_term_q;
     double fps;
-    int picture_number= s->picture_number;
+    int picture_number = s->picture_number;
     int64_t wanted_bits;
-    RateControlContext *rcc= &s->rc_context;
-    AVCodecContext *a= s->avctx;
+    RateControlContext *rcc = &s->rc_context;
+    AVCodecContext *a       = s->avctx;
     RateControlEntry local_rce, *rce;
     double bits;
     double rate_factor;
     int var;
-    const int pict_type= s->pict_type;
-    Picture * const pic= &s->current_picture;
+    const int pict_type = s->pict_type;
+    Picture * const pic = &s->current_picture;
     emms_c();
 
 #if CONFIG_LIBXVID
-    if((s->flags&CODEC_FLAG_PASS2) && s->avctx->rc_strategy == FF_RC_STRATEGY_XVID)
+    if ((s->flags & CODEC_FLAG_PASS2) &&
+        s->avctx->rc_strategy == FF_RC_STRATEGY_XVID)
         return ff_xvid_rate_estimate_qscale(s, dry_run);
 #endif
 
     get_qminmax(&qmin, &qmax, s, pict_type);
 
-    fps= get_fps(s->avctx);
-        /* update predictors */
-    if(picture_number>2 && !dry_run){
-        const int last_var= s->last_pict_type == AV_PICTURE_TYPE_I ? rcc->last_mb_var_sum : rcc->last_mc_mb_var_sum;
+    fps = get_fps(s->avctx);
+    /* update predictors */
+    if (picture_number > 2 && !dry_run) {
+        const int last_var = s->last_pict_type == AV_PICTURE_TYPE_I ? rcc->last_mb_var_sum
+                                                                    : rcc->last_mc_mb_var_sum;
         av_assert1(s->frame_bits >= s->stuffing_bits);
-        update_predictor(&rcc->pred[s->last_pict_type], rcc->last_qscale, sqrt(last_var), s->frame_bits - s->stuffing_bits);
+        update_predictor(&rcc->pred[s->last_pict_type],
+                         rcc->last_qscale,
+                         sqrt(last_var),
+                         s->frame_bits - s->stuffing_bits);
     }
 
-    if(s->flags&CODEC_FLAG_PASS2){
-        assert(picture_number>=0);
-        if(picture_number >= rcc->num_entries) {
+    if (s->flags & CODEC_FLAG_PASS2) {
+        assert(picture_number >= 0);
+        if (picture_number >= rcc->num_entries) {
             av_log(s, AV_LOG_ERROR, "Input is longer than 2-pass log file\n");
             return -1;
         }
-        rce= &rcc->entry[picture_number];
-        wanted_bits= rce->expected_bits;
-    }else{
+        rce         = &rcc->entry[picture_number];
+        wanted_bits = rce->expected_bits;
+    } else {
         Picture *dts_pic;
-        rce= &local_rce;
+        rce = &local_rce;
 
-        //FIXME add a dts field to AVFrame and ensure its set and use it here instead of reordering
-        //but the reordering is simpler for now until h.264 b pyramid must be handeld
-        if(s->pict_type == AV_PICTURE_TYPE_B || s->low_delay)
-            dts_pic= s->current_picture_ptr;
+        /* FIXME add a dts field to AVFrame and ensure it is set and use it
+         * here instead of reordering but the reordering is simpler for now
+         * until H.264 B-pyramid must be handled. */
+        if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay)
+            dts_pic = s->current_picture_ptr;
         else
-            dts_pic= s->last_picture_ptr;
+            dts_pic = s->last_picture_ptr;
 
         if (!dts_pic || dts_pic->f.pts == AV_NOPTS_VALUE)
-            wanted_bits= (uint64_t)(s->bit_rate*(double)picture_number/fps);
+            wanted_bits = (uint64_t)(s->bit_rate * (double)picture_number / fps);
         else
-            wanted_bits = (uint64_t)(s->bit_rate*(double)dts_pic->f.pts / fps);
+            wanted_bits = (uint64_t)(s->bit_rate * (double)dts_pic->f.pts / fps);
     }
 
-    diff= s->total_bits - wanted_bits;
-    br_compensation= (a->bit_rate_tolerance - diff)/a->bit_rate_tolerance;
-    if(br_compensation<=0.0) br_compensation=0.001;
+    diff = s->total_bits - wanted_bits;
+    br_compensation = (a->bit_rate_tolerance - diff) / a->bit_rate_tolerance;
+    if (br_compensation <= 0.0)
+        br_compensation = 0.001;
 
-    var= pict_type == AV_PICTURE_TYPE_I ? pic->mb_var_sum : pic->mc_mb_var_sum;
+    var = pict_type == AV_PICTURE_TYPE_I ? pic->mb_var_sum : pic->mc_mb_var_sum;
 
     short_term_q = 0; /* avoid warning */
-    if(s->flags&CODEC_FLAG_PASS2){
-        if(pict_type!=AV_PICTURE_TYPE_I)
+    if (s->flags & CODEC_FLAG_PASS2) {
+        if (pict_type != AV_PICTURE_TYPE_I)
             assert(pict_type == rce->new_pict_type);
 
-        q= rce->new_qscale / br_compensation;
+        q = rce->new_qscale / br_compensation;
         av_dlog(s, "%f %f %f last:%d var:%d type:%d//\n", q, rce->new_qscale,
                 br_compensation, s->frame_bits, var, pict_type);
-    }else{
-        rce->pict_type=
-        rce->new_pict_type= pict_type;
-        rce->mc_mb_var_sum= pic->mc_mb_var_sum;
-        rce->mb_var_sum   = pic->   mb_var_sum;
-        rce->qscale   = FF_QP2LAMBDA * 2;
-        rce->f_code   = s->f_code;
-        rce->b_code   = s->b_code;
-        rce->misc_bits= 1;
+    } else {
+        rce->pict_type     =
+        rce->new_pict_type = pict_type;
+        rce->mc_mb_var_sum = pic->mc_mb_var_sum;
+        rce->mb_var_sum    = pic->mb_var_sum;
+        rce->qscale        = FF_QP2LAMBDA * 2;
+        rce->f_code        = s->f_code;
+        rce->b_code        = s->b_code;
+        rce->misc_bits     = 1;
 
-        bits= predict_size(&rcc->pred[pict_type], rce->qscale, sqrt(var));
-        if(pict_type== AV_PICTURE_TYPE_I){
-            rce->i_count   = s->mb_num;
-            rce->i_tex_bits= bits;
-            rce->p_tex_bits= 0;
-            rce->mv_bits= 0;
-        }else{
-            rce->i_count   = 0; //FIXME we do know this approx
-            rce->i_tex_bits= 0;
-            rce->p_tex_bits= bits*0.9;
-
-            rce->mv_bits= bits*0.1;
+        bits = predict_size(&rcc->pred[pict_type], rce->qscale, sqrt(var));
+        if (pict_type == AV_PICTURE_TYPE_I) {
+            rce->i_count    = s->mb_num;
+            rce->i_tex_bits = bits;
+            rce->p_tex_bits = 0;
+            rce->mv_bits    = 0;
+        } else {
+            rce->i_count    = 0;    // FIXME we do know this approx
+            rce->i_tex_bits = 0;
+            rce->p_tex_bits = bits * 0.9;
+            rce->mv_bits    = bits * 0.1;
         }
-        rcc->i_cplx_sum [pict_type] += rce->i_tex_bits*rce->qscale;
-        rcc->p_cplx_sum [pict_type] += rce->p_tex_bits*rce->qscale;
+        rcc->i_cplx_sum[pict_type]  += rce->i_tex_bits * rce->qscale;
+        rcc->p_cplx_sum[pict_type]  += rce->p_tex_bits * rce->qscale;
         rcc->mv_bits_sum[pict_type] += rce->mv_bits;
-        rcc->frame_count[pict_type] ++;
+        rcc->frame_count[pict_type]++;
 
-        bits= rce->i_tex_bits + rce->p_tex_bits;
-        rate_factor= rcc->pass1_wanted_bits/rcc->pass1_rc_eq_output_sum * br_compensation;
+        bits        = rce->i_tex_bits + rce->p_tex_bits;
+        rate_factor = rcc->pass1_wanted_bits /
+                      rcc->pass1_rc_eq_output_sum * br_compensation;
 
-        q= get_qscale(s, rce, rate_factor, picture_number);
+        q = get_qscale(s, rce, rate_factor, picture_number);
         if (q < 0)
             return -1;
 
-        assert(q>0.0);
-        q= get_diff_limited_q(s, rce, q);
-        assert(q>0.0);
+        assert(q > 0.0);
+        q = get_diff_limited_q(s, rce, q);
+        assert(q > 0.0);
 
-        if(pict_type==AV_PICTURE_TYPE_P || s->intra_only){ //FIXME type dependent blur like in 2-pass
-            rcc->short_term_qsum*=a->qblur;
-            rcc->short_term_qcount*=a->qblur;
+        // FIXME type dependent blur like in 2-pass
+        if (pict_type == AV_PICTURE_TYPE_P || s->intra_only) {
+            rcc->short_term_qsum   *= a->qblur;
+            rcc->short_term_qcount *= a->qblur;
 
-            rcc->short_term_qsum+= q;
+            rcc->short_term_qsum += q;
             rcc->short_term_qcount++;
-            q= short_term_q= rcc->short_term_qsum/rcc->short_term_qcount;
+            q = short_term_q = rcc->short_term_qsum / rcc->short_term_qcount;
         }
-        assert(q>0.0);
+        assert(q > 0.0);
 
-        q= modify_qscale(s, rce, q, picture_number);
+        q = modify_qscale(s, rce, q, picture_number);
 
-        rcc->pass1_wanted_bits+= s->bit_rate/fps;
+        rcc->pass1_wanted_bits += s->bit_rate / fps;
 
-        assert(q>0.0);
+        assert(q > 0.0);
     }
 
-    if(s->avctx->debug&FF_DEBUG_RC){
-        av_log(s->avctx, AV_LOG_DEBUG, "%c qp:%d<%2.1f<%d %d want:%d total:%d comp:%f st_q:%2.2f size:%d var:%d/%d br:%d fps:%d\n",
-        av_get_picture_type_char(pict_type), qmin, q, qmax, picture_number, (int)wanted_bits/1000, (int)s->total_bits/1000,
-        br_compensation, short_term_q, s->frame_bits, pic->mb_var_sum, pic->mc_mb_var_sum, s->bit_rate/1000, (int)fps
-        );
+    if (s->avctx->debug & FF_DEBUG_RC) {
+        av_log(s->avctx, AV_LOG_DEBUG,
+               "%c qp:%d<%2.1f<%d %d want:%d total:%d comp:%f st_q:%2.2f "
+               "size:%d var:%d/%d br:%d fps:%d\n",
+               av_get_picture_type_char(pict_type),
+               qmin, q, qmax, picture_number,
+               (int)wanted_bits / 1000, (int)s->total_bits / 1000,
+               br_compensation, short_term_q, s->frame_bits,
+               pic->mb_var_sum, pic->mc_mb_var_sum,
+               s->bit_rate / 1000, (int)fps);
     }
 
-    if     (q<qmin) q=qmin;
-    else if(q>qmax) q=qmax;
+    if (q < qmin)
+        q = qmin;
+    else if (q > qmax)
+        q = qmax;
 
-    if(s->adaptive_quant)
+    if (s->adaptive_quant)
         adaptive_quantization(s, q);
     else
-        q= (int)(q + 0.5);
+        q = (int)(q + 0.5);
 
-    if(!dry_run){
-        rcc->last_qscale= q;
-        rcc->last_mc_mb_var_sum= pic->mc_mb_var_sum;
-        rcc->last_mb_var_sum= pic->mb_var_sum;
+    if (!dry_run) {
+        rcc->last_qscale        = q;
+        rcc->last_mc_mb_var_sum = pic->mc_mb_var_sum;
+        rcc->last_mb_var_sum    = pic->mb_var_sum;
     }
     return q;
 }
 
-//----------------------------------------------
+// ----------------------------------------------
 // 2-Pass code
 
 static int init_pass2(MpegEncContext *s)
 {
-    RateControlContext *rcc= &s->rc_context;
-    AVCodecContext *a= s->avctx;
+    RateControlContext *rcc = &s->rc_context;
+    AVCodecContext *a       = s->avctx;
     int i, toobig;
-    double fps= get_fps(s->avctx);
-    double complexity[5]={0,0,0,0,0};   // aproximate bits at quant=1
-    uint64_t const_bits[5]={0,0,0,0,0}; // quantizer independent bits
+    double fps             = get_fps(s->avctx);
+    double complexity[5]   = { 0 }; // approximate bits at quant=1
+    uint64_t const_bits[5] = { 0 }; // quantizer independent bits
     uint64_t all_const_bits;
-    uint64_t all_available_bits= (uint64_t)(s->bit_rate*(double)rcc->num_entries/fps);
-    double rate_factor=0;
+    uint64_t all_available_bits = (uint64_t)(s->bit_rate *
+                                             (double)rcc->num_entries / fps);
+    double rate_factor          = 0;
     double step;
-    //int last_i_frame=-10000000;
-    const int filter_size= (int)(a->qblur*4) | 1;
+    const int filter_size = (int)(a->qblur * 4) | 1;
     double expected_bits;
     double *qscale, *blurred_qscale, qscale_sum;
 
     /* find complexity & const_bits & decide the pict_types */
-    for(i=0; i<rcc->num_entries; i++){
-        RateControlEntry *rce= &rcc->entry[i];
+    for (i = 0; i < rcc->num_entries; i++) {
+        RateControlEntry *rce = &rcc->entry[i];
 
-        rce->new_pict_type= rce->pict_type;
-        rcc->i_cplx_sum [rce->pict_type] += rce->i_tex_bits*rce->qscale;
-        rcc->p_cplx_sum [rce->pict_type] += rce->p_tex_bits*rce->qscale;
+        rce->new_pict_type                = rce->pict_type;
+        rcc->i_cplx_sum[rce->pict_type]  += rce->i_tex_bits * rce->qscale;
+        rcc->p_cplx_sum[rce->pict_type]  += rce->p_tex_bits * rce->qscale;
         rcc->mv_bits_sum[rce->pict_type] += rce->mv_bits;
-        rcc->frame_count[rce->pict_type] ++;
+        rcc->frame_count[rce->pict_type]++;
 
-        complexity[rce->new_pict_type]+= (rce->i_tex_bits+ rce->p_tex_bits)*(double)rce->qscale;
-        const_bits[rce->new_pict_type]+= rce->mv_bits + rce->misc_bits;
+        complexity[rce->new_pict_type] += (rce->i_tex_bits + rce->p_tex_bits) *
+                                          (double)rce->qscale;
+        const_bits[rce->new_pict_type] += rce->mv_bits + rce->misc_bits;
     }
-    all_const_bits= const_bits[AV_PICTURE_TYPE_I] + const_bits[AV_PICTURE_TYPE_P] + const_bits[AV_PICTURE_TYPE_B];
 
-    if(all_available_bits < all_const_bits){
+    all_const_bits = const_bits[AV_PICTURE_TYPE_I] +
+                     const_bits[AV_PICTURE_TYPE_P] +
+                     const_bits[AV_PICTURE_TYPE_B];
+
+    if (all_available_bits < all_const_bits) {
         av_log(s->avctx, AV_LOG_ERROR, "requested bitrate is too low\n");
         return -1;
     }
 
-    qscale= av_malloc(sizeof(double)*rcc->num_entries);
-    blurred_qscale= av_malloc(sizeof(double)*rcc->num_entries);
+    qscale         = av_malloc(sizeof(double) * rcc->num_entries);
+    blurred_qscale = av_malloc(sizeof(double) * rcc->num_entries);
     toobig = 0;
 
-    for(step=256*256; step>0.0000001; step*=0.5){
-        expected_bits=0;
-        rate_factor+= step;
+    for (step = 256 * 256; step > 0.0000001; step *= 0.5) {
+        expected_bits = 0;
+        rate_factor  += step;
 
-        rcc->buffer_index= s->avctx->rc_buffer_size/2;
+        rcc->buffer_index = s->avctx->rc_buffer_size / 2;
 
         /* find qscale */
-        for(i=0; i<rcc->num_entries; i++){
-            RateControlEntry *rce= &rcc->entry[i];
-            qscale[i]= get_qscale(s, &rcc->entry[i], rate_factor, i);
+        for (i = 0; i < rcc->num_entries; i++) {
+            RateControlEntry *rce = &rcc->entry[i];
+
+            qscale[i] = get_qscale(s, &rcc->entry[i], rate_factor, i);
             rcc->last_qscale_for[rce->pict_type] = qscale[i];
         }
-        assert(filter_size%2==1);
+        assert(filter_size % 2 == 1);
 
         /* fixed I/B QP relative to P mode */
-        for(i=FFMAX(0, rcc->num_entries-300); i<rcc->num_entries; i++){
-            RateControlEntry *rce= &rcc->entry[i];
+        for (i = FFMAX(0, rcc->num_entries - 300); i < rcc->num_entries; i++) {
+            RateControlEntry *rce = &rcc->entry[i];
 
-            qscale[i]= get_diff_limited_q(s, rce, qscale[i]);
+            qscale[i] = get_diff_limited_q(s, rce, qscale[i]);
         }
 
-        for(i=rcc->num_entries-1; i>=0; i--){
-            RateControlEntry *rce= &rcc->entry[i];
+        for (i = rcc->num_entries - 1; i >= 0; i--) {
+            RateControlEntry *rce = &rcc->entry[i];
 
-            qscale[i]= get_diff_limited_q(s, rce, qscale[i]);
+            qscale[i] = get_diff_limited_q(s, rce, qscale[i]);
         }
 
         /* smooth curve */
-        for(i=0; i<rcc->num_entries; i++){
-            RateControlEntry *rce= &rcc->entry[i];
-            const int pict_type= rce->new_pict_type;
+        for (i = 0; i < rcc->num_entries; i++) {
+            RateControlEntry *rce = &rcc->entry[i];
+            const int pict_type   = rce->new_pict_type;
             int j;
-            double q=0.0, sum=0.0;
+            double q = 0.0, sum = 0.0;
 
-            for(j=0; j<filter_size; j++){
-                int index= i+j-filter_size/2;
-                double d= index-i;
-                double coeff= a->qblur==0 ? 1.0 : exp(-d*d/(a->qblur * a->qblur));
+            for (j = 0; j < filter_size; j++) {
+                int index    = i + j - filter_size / 2;
+                double d     = index - i;
+                double coeff = a->qblur == 0 ? 1.0 : exp(-d * d / (a->qblur * a->qblur));
 
-                if(index < 0 || index >= rcc->num_entries) continue;
-                if(pict_type != rcc->entry[index].new_pict_type) continue;
-                q+= qscale[index] * coeff;
-                sum+= coeff;
+                if (index < 0 || index >= rcc->num_entries)
+                    continue;
+                if (pict_type != rcc->entry[index].new_pict_type)
+                    continue;
+                q   += qscale[index] * coeff;
+                sum += coeff;
             }
-            blurred_qscale[i]= q/sum;
+            blurred_qscale[i] = q / sum;
         }
 
         /* find expected bits */
-        for(i=0; i<rcc->num_entries; i++){
-            RateControlEntry *rce= &rcc->entry[i];
+        for (i = 0; i < rcc->num_entries; i++) {
+            RateControlEntry *rce = &rcc->entry[i];
             double bits;
-            rce->new_qscale= modify_qscale(s, rce, blurred_qscale[i], i);
-            bits= qp2bits(rce, rce->new_qscale) + rce->mv_bits + rce->misc_bits;
-            bits += 8*ff_vbv_update(s, bits);
 
-            rce->expected_bits= expected_bits;
-            expected_bits += bits;
+            rce->new_qscale = modify_qscale(s, rce, blurred_qscale[i], i);
+
+            bits  = qp2bits(rce, rce->new_qscale) + rce->mv_bits + rce->misc_bits;
+            bits += 8 * ff_vbv_update(s, bits);
+
+            rce->expected_bits = expected_bits;
+            expected_bits     += bits;
         }
 
         av_dlog(s->avctx,
                 "expected_bits: %f all_available_bits: %d rate_factor: %f\n",
                 expected_bits, (int)all_available_bits, rate_factor);
-        if(expected_bits > all_available_bits) {
-            rate_factor-= step;
+        if (expected_bits > all_available_bits) {
+            rate_factor -= step;
             ++toobig;
         }
     }
@@ -923,33 +1027,34 @@
 
     /* check bitrate calculations and print info */
     qscale_sum = 0.0;
-    for(i=0; i<rcc->num_entries; i++){
+    for (i = 0; i < rcc->num_entries; i++) {
         av_dlog(s, "[lavc rc] entry[%d].new_qscale = %.3f  qp = %.3f\n",
                 i,
                 rcc->entry[i].new_qscale,
                 rcc->entry[i].new_qscale / FF_QP2LAMBDA);
-        qscale_sum += av_clip(rcc->entry[i].new_qscale / FF_QP2LAMBDA, s->avctx->qmin, s->avctx->qmax);
+        qscale_sum += av_clip(rcc->entry[i].new_qscale / FF_QP2LAMBDA,
+                              s->avctx->qmin, s->avctx->qmax);
     }
     assert(toobig <= 40);
     av_log(s->avctx, AV_LOG_DEBUG,
-        "[lavc rc] requested bitrate: %d bps  expected bitrate: %d bps\n",
-        s->bit_rate,
-        (int)(expected_bits / ((double)all_available_bits/s->bit_rate)));
+           "[lavc rc] requested bitrate: %d bps  expected bitrate: %d bps\n",
+           s->bit_rate,
+           (int)(expected_bits / ((double)all_available_bits / s->bit_rate)));
     av_log(s->avctx, AV_LOG_DEBUG,
-        "[lavc rc] estimated target average qp: %.3f\n",
-        (float)qscale_sum / rcc->num_entries);
+           "[lavc rc] estimated target average qp: %.3f\n",
+           (float)qscale_sum / rcc->num_entries);
     if (toobig == 0) {
         av_log(s->avctx, AV_LOG_INFO,
-            "[lavc rc] Using all of requested bitrate is not "
-            "necessary for this video with these parameters.\n");
+               "[lavc rc] Using all of requested bitrate is not "
+               "necessary for this video with these parameters.\n");
     } else if (toobig == 40) {
         av_log(s->avctx, AV_LOG_ERROR,
-            "[lavc rc] Error: bitrate too low for this video "
-            "with these parameters.\n");
+               "[lavc rc] Error: bitrate too low for this video "
+               "with these parameters.\n");
         return -1;
-    } else if (fabs(expected_bits/all_available_bits - 1.0) > 0.01) {
+    } else if (fabs(expected_bits / all_available_bits - 1.0) > 0.01) {
         av_log(s->avctx, AV_LOG_ERROR,
-            "[lavc rc] Error: 2pass curve failed to converge\n");
+               "[lavc rc] Error: 2pass curve failed to converge\n");
         return -1;
     }
 
diff --git a/libavcodec/raw.h b/libavcodec/raw.h
index 87b6c90..3e59f28 100644
--- a/libavcodec/raw.h
+++ b/libavcodec/raw.h
@@ -36,6 +36,9 @@
 } PixelFormatTag;
 
 extern av_export const PixelFormatTag ff_raw_pix_fmt_tags[];
+#if LIBAVCODEC_VERSION_MAJOR < 55
 enum AVPixelFormat ff_find_pix_fmt(const PixelFormatTag *tags, unsigned int fourcc);
+#endif
+enum AVPixelFormat avpriv_find_pix_fmt(const PixelFormatTag *tags, unsigned int fourcc);
 
 #endif /* AVCODEC_RAW_H */
diff --git a/libavcodec/rawdec.c b/libavcodec/rawdec.c
index f60f5e4..a8b70ee 100644
--- a/libavcodec/rawdec.c
+++ b/libavcodec/rawdec.c
@@ -35,8 +35,8 @@
 typedef struct RawVideoContext {
     AVClass *av_class;
     uint32_t palette[AVPALETTE_COUNT];
-    unsigned char * buffer;  /* block of memory for holding one frame */
-    int             length;  /* number of bytes in buffer */
+    unsigned char *buffer;  /* block of memory for holding one frame */
+    int            length;  /* number of bytes in buffer */
     int flip;
     AVFrame pic;             ///< AVCodecContext.coded_frame
     int tff;
@@ -58,12 +58,12 @@
     { AV_PIX_FMT_PAL8,    2 },
     { AV_PIX_FMT_PAL8,    4 },
     { AV_PIX_FMT_PAL8,    8 },
-    { AV_PIX_FMT_RGB444, 12 },
-    { AV_PIX_FMT_RGB555, 15 },
-    { AV_PIX_FMT_RGB555, 16 },
+    { AV_PIX_FMT_RGB444LE, 12 },
+    { AV_PIX_FMT_RGB555LE, 15 },
+    { AV_PIX_FMT_RGB555LE, 16 },
     { AV_PIX_FMT_BGR24,  24 },
     { AV_PIX_FMT_BGRA,   32 },
-    { AV_PIX_FMT_NONE, 0 },
+    { AV_PIX_FMT_NONE,    0 },
 };
 
 static const PixelFormatTag pix_fmt_bps_mov[] = {
@@ -77,31 +77,43 @@
     { AV_PIX_FMT_RGB24,    24 },
     { AV_PIX_FMT_ARGB,     32 },
     { AV_PIX_FMT_MONOWHITE,33 },
-    { AV_PIX_FMT_NONE, 0 },
+    { AV_PIX_FMT_NONE,      0 },
 };
 
-enum AVPixelFormat ff_find_pix_fmt(const PixelFormatTag *tags, unsigned int fourcc)
+enum AVPixelFormat avpriv_find_pix_fmt(const PixelFormatTag *tags,
+                                       unsigned int fourcc)
 {
     while (tags->pix_fmt >= 0) {
         if (tags->fourcc == fourcc)
             return tags->pix_fmt;
         tags++;
     }
-    return AV_PIX_FMT_YUV420P;
+    return AV_PIX_FMT_NONE;
 }
 
+#if LIBAVCODEC_VERSION_MAJOR < 55
+enum AVPixelFormat ff_find_pix_fmt(const PixelFormatTag *tags, unsigned int fourcc)
+{
+    return avpriv_find_pix_fmt(tags, fourcc);
+}
+#endif
+
 static av_cold int raw_init_decoder(AVCodecContext *avctx)
 {
     RawVideoContext *context = avctx->priv_data;
 
-    if (avctx->codec_tag == MKTAG('r','a','w',' ') || avctx->codec_tag == MKTAG('N','O','1','6'))
-        avctx->pix_fmt = ff_find_pix_fmt(pix_fmt_bps_mov, avctx->bits_per_coded_sample);
-    else if (avctx->codec_tag == MKTAG('W','R','A','W'))
-        avctx->pix_fmt = ff_find_pix_fmt(pix_fmt_bps_avi, avctx->bits_per_coded_sample);
+    if (   avctx->codec_tag == MKTAG('r','a','w',' ')
+        || avctx->codec_tag == MKTAG('N','O','1','6'))
+        avctx->pix_fmt = avpriv_find_pix_fmt(pix_fmt_bps_mov,
+                                      avctx->bits_per_coded_sample);
+    else if (avctx->codec_tag == MKTAG('W', 'R', 'A', 'W'))
+        avctx->pix_fmt = avpriv_find_pix_fmt(pix_fmt_bps_avi,
+                                      avctx->bits_per_coded_sample);
     else if (avctx->codec_tag)
-        avctx->pix_fmt = ff_find_pix_fmt(ff_raw_pix_fmt_tags, avctx->codec_tag);
+        avctx->pix_fmt = avpriv_find_pix_fmt(ff_raw_pix_fmt_tags, avctx->codec_tag);
     else if (avctx->pix_fmt == AV_PIX_FMT_NONE && avctx->bits_per_coded_sample)
-        avctx->pix_fmt = ff_find_pix_fmt(pix_fmt_bps_avi, avctx->bits_per_coded_sample);
+        avctx->pix_fmt = avpriv_find_pix_fmt(pix_fmt_bps_avi,
+                                      avctx->bits_per_coded_sample);
 
     if (avctx->pix_fmt == AV_PIX_FMT_NONE) {
         av_log(avctx, AV_LOG_ERROR, "Pixel format was not specified and cannot be detected\n");
@@ -109,10 +121,12 @@
     }
 
     avpriv_set_systematic_pal2(context->palette, avctx->pix_fmt);
-    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',' '))){
-        context->length = avpicture_get_size(avctx->pix_fmt, FFALIGN(avctx->width, 16), 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',' '))) {
+        context->length = avpicture_get_size(avctx->pix_fmt,
+                                             FFALIGN(avctx->width, 16),
+                                             avctx->height);
         if (context->length < 0)
             return context->length;
         context->buffer = av_malloc(context->length);
@@ -126,12 +140,14 @@
     context->pic.pict_type = AV_PICTURE_TYPE_I;
     context->pic.key_frame = 1;
 
-    avctx->coded_frame= &context->pic;
+    avctx->coded_frame = &context->pic;
 
-    if((avctx->extradata_size >= 9 && !memcmp(avctx->extradata + avctx->extradata_size - 9, "BottomUp", 9)) ||
+    if ((avctx->extradata_size >= 9 &&
+         !memcmp(avctx->extradata + avctx->extradata_size - 9, "BottomUp", 9)) ||
         avctx->codec_tag == MKTAG('c','y','u','v') ||
-        avctx->codec_tag == MKTAG(3, 0, 0, 0) || avctx->codec_tag == MKTAG('W','R','A','W'))
-        context->flip=1;
+        avctx->codec_tag == MKTAG(3, 0, 0, 0) ||
+        avctx->codec_tag == MKTAG('W','R','A','W'))
+        context->flip = 1;
 
     if (avctx->field_order > AV_FIELD_PROGRESSIVE) { /*we have interlaced material flagged in container */
         avctx->coded_frame->interlaced_frame = 1;
@@ -143,20 +159,20 @@
     return 0;
 }
 
-static void flip(AVCodecContext *avctx, AVPicture * picture){
-    picture->data[0] += picture->linesize[0] * (avctx->height-1);
+static void flip(AVCodecContext *avctx, AVPicture *picture)
+{
+    picture->data[0]     += picture->linesize[0] * (avctx->height - 1);
     picture->linesize[0] *= -1;
 }
 
-static int raw_decode(AVCodecContext *avctx,
-                            void *data, int *data_size,
-                            AVPacket *avpkt)
+static int raw_decode(AVCodecContext *avctx, void *data, int *got_frame,
+                      AVPacket *avpkt)
 {
-    const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
-    int linesize_align = 4;
-    RawVideoContext *context = avctx->priv_data;
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
+    RawVideoContext *context       = avctx->priv_data;
+    const uint8_t *buf             = avpkt->data;
+    int buf_size                   = avpkt->size;
+    int linesize_align             = 4;
     int res, len;
 
     AVFrame   *frame   = data;
@@ -164,13 +180,13 @@
 
     frame->pict_type        = avctx->coded_frame->pict_type;
     frame->interlaced_frame = avctx->coded_frame->interlaced_frame;
-    frame->top_field_first = avctx->coded_frame->top_field_first;
+    frame->top_field_first  = avctx->coded_frame->top_field_first;
     frame->reordered_opaque = avctx->reordered_opaque;
     frame->pkt_pts          = avctx->pkt->pts;
     frame->pkt_pos          = avctx->pkt->pos;
     frame->pkt_duration     = avctx->pkt->duration;
 
-    if(context->tff>=0){
+    if (context->tff >= 0) {
         frame->interlaced_frame = 1;
         frame->top_field_first  = context->tff;
     }
@@ -183,27 +199,27 @@
         int i;
         uint8_t *dst = context->buffer;
         buf_size = context->length - AVPALETTE_SIZE;
-        if (avctx->bits_per_coded_sample == 4){
-            for(i=0; 2*i+1 < buf_size && i<avpkt->size; i++){
-                dst[2*i+0]= buf[i]>>4;
-                dst[2*i+1]= buf[i]&15;
+        if (avctx->bits_per_coded_sample == 4) {
+            for (i = 0; 2 * i + 1 < buf_size && i<avpkt->size; i++) {
+                dst[2 * i + 0] = buf[i] >> 4;
+                dst[2 * i + 1] = buf[i] & 15;
             }
             linesize_align = 8;
         } else {
             av_assert0(avctx->bits_per_coded_sample == 2);
-            for(i=0; 4*i+3 < buf_size && i<avpkt->size; i++){
-                dst[4*i+0]= buf[i]>>6;
-                dst[4*i+1]= buf[i]>>4&3;
-                dst[4*i+2]= buf[i]>>2&3;
-                dst[4*i+3]= buf[i]   &3;
+            for (i = 0; 4 * i + 3 < buf_size && i<avpkt->size; i++) {
+                dst[4 * i + 0] = buf[i] >> 6;
+                dst[4 * i + 1] = buf[i] >> 4 & 3;
+                dst[4 * i + 2] = buf[i] >> 2 & 3;
+                dst[4 * i + 3] = buf[i]      & 3;
             }
             linesize_align = 16;
         }
-        buf= dst;
+        buf = dst;
     }
 
-    if(avctx->codec_tag == MKTAG('A', 'V', '1', 'x') ||
-       avctx->codec_tag == MKTAG('A', 'V', 'u', 'p'))
+    if (avctx->codec_tag == MKTAG('A', 'V', '1', 'x') ||
+        avctx->codec_tag == MKTAG('A', 'V', 'u', 'p'))
         buf += buf_size - context->length;
 
     len = context->length - (avctx->pix_fmt==AV_PIX_FMT_PAL8 ? AVPALETTE_SIZE : 0);
@@ -215,49 +231,64 @@
     if ((res = avpicture_fill(picture, buf, avctx->pix_fmt,
                               avctx->width, avctx->height)) < 0)
         return res;
-    if((avctx->pix_fmt==AV_PIX_FMT_PAL8 && buf_size < context->length) ||
-       (desc->flags & PIX_FMT_PSEUDOPAL)) {
-        frame->data[1]= (uint8_t*)context->palette;
+    if ((avctx->pix_fmt == AV_PIX_FMT_PAL8 && buf_size < context->length) ||
+        (desc->flags & PIX_FMT_PSEUDOPAL)) {
+        frame->data[1] = (uint8_t*)context->palette;
     }
     if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
-        const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);
+        const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE,
+                                                     NULL);
 
         if (pal) {
             memcpy(frame->data[1], pal, AVPALETTE_SIZE);
             frame->palette_has_changed = 1;
         }
     }
-    if((avctx->pix_fmt==AV_PIX_FMT_BGR24    ||
+    if ((avctx->pix_fmt==AV_PIX_FMT_BGR24    ||
         avctx->pix_fmt==AV_PIX_FMT_GRAY8    ||
         avctx->pix_fmt==AV_PIX_FMT_RGB555LE ||
         avctx->pix_fmt==AV_PIX_FMT_RGB555BE ||
         avctx->pix_fmt==AV_PIX_FMT_RGB565LE ||
         avctx->pix_fmt==AV_PIX_FMT_MONOWHITE ||
         avctx->pix_fmt==AV_PIX_FMT_PAL8) &&
-        FFALIGN(frame->linesize[0], linesize_align)*avctx->height <= buf_size)
+        FFALIGN(frame->linesize[0], linesize_align) * avctx->height <= buf_size)
         frame->linesize[0] = FFALIGN(frame->linesize[0], linesize_align);
 
-    if(context->flip)
+    if (avctx->pix_fmt == AV_PIX_FMT_NV12 && avctx->codec_tag == MKTAG('N', 'V', '1', '2') &&
+        FFALIGN(frame->linesize[0], linesize_align) * avctx->height +
+        FFALIGN(frame->linesize[1], linesize_align) * ((avctx->height + 1) / 2) <= buf_size) {
+        int la0 = FFALIGN(frame->linesize[0], linesize_align);
+        frame->data[1] += (la0 - frame->linesize[0]) * avctx->height;
+        frame->linesize[0] = la0;
+        frame->linesize[1] = FFALIGN(frame->linesize[1], linesize_align);
+    }
+
+    if (context->flip)
         flip(avctx, picture);
 
-    if (   avctx->codec_tag == MKTAG('Y', 'V', '1', '2')
-        || avctx->codec_tag == MKTAG('Y', 'V', '1', '6')
-        || avctx->codec_tag == MKTAG('Y', 'V', '2', '4')
-        || avctx->codec_tag == MKTAG('Y', 'V', 'U', '9'))
+    if (avctx->codec_tag == MKTAG('Y', 'V', '1', '2') ||
+        avctx->codec_tag == MKTAG('Y', 'V', '1', '6') ||
+        avctx->codec_tag == MKTAG('Y', 'V', '2', '4') ||
+        avctx->codec_tag == MKTAG('Y', 'V', 'U', '9'))
         FFSWAP(uint8_t *, picture->data[1], picture->data[2]);
 
-    if(avctx->codec_tag == AV_RL32("yuv2") &&
-       avctx->pix_fmt   == AV_PIX_FMT_YUYV422) {
+    if (avctx->codec_tag == AV_RL32("I420") && (avctx->width+1)*(avctx->height+1) * 3/2 == buf_size) {
+        picture->data[1] = picture->data[1] +  (avctx->width+1)*(avctx->height+1) -avctx->width*avctx->height;
+        picture->data[2] = picture->data[2] + ((avctx->width+1)*(avctx->height+1) -avctx->width*avctx->height)*5/4;
+    }
+
+    if (avctx->codec_tag == AV_RL32("yuv2") &&
+        avctx->pix_fmt   == AV_PIX_FMT_YUYV422) {
         int x, y;
         uint8_t *line = picture->data[0];
-        for(y = 0; y < avctx->height; y++) {
-            for(x = 0; x < avctx->width; x++)
-                line[2*x + 1] ^= 0x80;
+        for (y = 0; y < avctx->height; y++) {
+            for (x = 0; x < avctx->width; x++)
+                line[2 * x + 1] ^= 0x80;
             line += picture->linesize[0];
         }
     }
-    if(avctx->codec_tag == AV_RL32("YVYU") &&
-       avctx->pix_fmt   == AV_PIX_FMT_YUYV422) {
+    if (avctx->codec_tag == AV_RL32("YVYU") &&
+        avctx->pix_fmt   == AV_PIX_FMT_YUYV422) {
         int x, y;
         uint8_t *line = picture->data[0];
         for(y = 0; y < avctx->height; y++) {
@@ -267,7 +298,7 @@
         }
     }
 
-    *data_size = sizeof(AVPicture);
+    *got_frame = 1;
     return buf_size;
 }
 
diff --git a/libavcodec/rectangle.h b/libavcodec/rectangle.h
index 43f89c9..594a760 100644
--- a/libavcodec/rectangle.h
+++ b/libavcodec/rectangle.h
@@ -31,7 +31,6 @@
 #include "config.h"
 #include "libavutil/common.h"
 #include "libavutil/avassert.h"
-#include "dsputil.h"
 
 /**
  * fill a rectangle.
@@ -47,7 +46,7 @@
     w      *= size;
     stride *= size;
 
-    av_assert2((((long)vp)&(FFMIN(w, STRIDE_ALIGN)-1)) == 0);
+    av_assert2((((long)vp)&(FFMIN(w, 8<<(HAVE_NEON|ARCH_PPC|HAVE_MMX))-1)) == 0);
     av_assert2((stride&(w-1))==0);
     if(w==2){
         const uint16_t v= size==4 ? val : val*0x0101;
diff --git a/libavcodec/resample.c b/libavcodec/resample.c
index dfaad66..f950288 100644
--- a/libavcodec/resample.c
+++ b/libavcodec/resample.c
@@ -406,7 +406,7 @@
         if (av_audio_convert(s->convert_ctx[1], obuf, ostride,
                              ibuf, istride, nb_samples1 * s->output_channels) < 0) {
             av_log(s->resample_context, AV_LOG_ERROR,
-                   "Audio sample format convertion failed\n");
+                   "Audio sample format conversion failed\n");
             return 0;
         }
     }
diff --git a/libavcodec/resample2.c b/libavcodec/resample2.c
index 3a3cd13..9b63b53 100644
--- a/libavcodec/resample2.c
+++ b/libavcodec/resample2.c
@@ -27,7 +27,6 @@
 
 #include "libavutil/avassert.h"
 #include "avcodec.h"
-#include "dsputil.h"
 #include "libavutil/common.h"
 
 #if FF_API_AVCODEC_RESAMPLE
@@ -313,13 +312,6 @@
         c->dst_incr= dst_incr_frac + c->src_incr*dst_incr;
         c->compensation_distance= compensation_distance;
     }
-#if 0
-    if(update_ctx && !c->compensation_distance){
-#undef rand
-        av_resample_compensate(c, rand() % (8000*2) - 8000, 8000*2);
-av_log(NULL, AV_LOG_DEBUG, "%d %d %d\n", c->dst_incr, c->ideal_dst_incr, c->compensation_distance);
-    }
-#endif
 
     return dst_index;
 }
diff --git a/libavcodec/rl2.c b/libavcodec/rl2.c
index c51fbd5..b908a83 100644
--- a/libavcodec/rl2.c
+++ b/libavcodec/rl2.c
@@ -34,6 +34,7 @@
 #include "libavutil/intreadwrite.h"
 #include "libavutil/mem.h"
 #include "avcodec.h"
+#include "internal.h"
 
 
 #define EXTRADATA1_SIZE (6 + 256 * 3) ///< video base, clr count, palette
@@ -42,10 +43,10 @@
     AVCodecContext *avctx;
     AVFrame frame;
 
-    unsigned short video_base; ///< initial drawing offset
-    unsigned int clr_count;    ///< number of used colors (currently unused)
-    unsigned char* back_frame; ///< background frame
-    unsigned int palette[AVPALETTE_COUNT];
+    uint16_t video_base;  ///< initial drawing offset
+    uint32_t clr_count;   ///< number of used colors (currently unused)
+    uint8_t *back_frame;  ///< background frame
+    uint32_t palette[AVPALETTE_COUNT];
 } Rl2Context;
 
 /**
@@ -57,67 +58,68 @@
  * @param stride stride of the output buffer
  * @param video_base offset of the rle data inside the frame
  */
-static void rl2_rle_decode(Rl2Context *s,const unsigned char* in,int size,
-                               unsigned char* out,int stride,int video_base){
+static void rl2_rle_decode(Rl2Context *s, const uint8_t *in, int size,
+                               uint8_t *out, int stride, int video_base)
+{
     int base_x = video_base % s->avctx->width;
     int base_y = video_base / s->avctx->width;
     int stride_adj = stride - s->avctx->width;
     int i;
-    const unsigned char* back_frame = s->back_frame;
-    const unsigned char* in_end = in + size;
-    const unsigned char* out_end = out + stride * s->avctx->height;
-    unsigned char* line_end;
+    const uint8_t *back_frame = s->back_frame;
+    const uint8_t *in_end     = in + size;
+    const uint8_t *out_end    = out + stride * s->avctx->height;
+    uint8_t *line_end;
 
     /** copy start of the background frame */
-    for(i=0;i<=base_y;i++){
-        if(s->back_frame)
-            memcpy(out,back_frame,s->avctx->width);
-        out += stride;
+    for (i = 0; i <= base_y; i++) {
+        if (s->back_frame)
+            memcpy(out, back_frame, s->avctx->width);
+        out        += stride;
         back_frame += s->avctx->width;
     }
     back_frame += base_x - s->avctx->width;
-    line_end = out - stride_adj;
-    out += base_x - stride;
+    line_end    = out - stride_adj;
+    out        += base_x - stride;
 
     /** decode the variable part of the frame */
-    while(in < in_end){
-        unsigned char val = *in++;
-        int len = 1;
-        if(val >= 0x80){
-            if(in >= in_end)
+    while (in < in_end) {
+        uint8_t val = *in++;
+        int len     = 1;
+        if (val >= 0x80) {
+            if (in >= in_end)
                 break;
             len = *in++;
-            if(!len)
+            if (!len)
                 break;
         }
 
-        if(len >= out_end - out)
+        if (len >= out_end - out)
             break;
 
-        if(s->back_frame)
+        if (s->back_frame)
             val |= 0x80;
         else
             val &= ~0x80;
 
-        while(len--){
-            *out++ = (val == 0x80)? *back_frame:val;
+        while (len--) {
+            *out++ = (val == 0x80) ? *back_frame : val;
             back_frame++;
-            if(out == line_end){
-                 out += stride_adj;
+            if (out == line_end) {
+                 out      += stride_adj;
                  line_end += stride;
-                 if(len >= out_end - out)
+                 if (len >= out_end - out)
                      break;
             }
         }
     }
 
     /** copy the rest from the background frame */
-    if(s->back_frame){
-        while(out < out_end){
+    if (s->back_frame) {
+        while (out < out_end) {
             memcpy(out, back_frame, line_end - out);
             back_frame += line_end - out;
-            out = line_end + stride_adj;
-            line_end += stride;
+            out         = line_end + stride_adj;
+            line_end   += stride;
         }
     }
 }
@@ -133,38 +135,39 @@
     Rl2Context *s = avctx->priv_data;
     int back_size;
     int i;
-    s->avctx = avctx;
+
+    s->avctx       = avctx;
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
     avcodec_get_frame_defaults(&s->frame);
 
     /** parse extra data */
-    if(!avctx->extradata || avctx->extradata_size < EXTRADATA1_SIZE){
+    if (!avctx->extradata || avctx->extradata_size < EXTRADATA1_SIZE) {
         av_log(avctx, AV_LOG_ERROR, "invalid extradata size\n");
-        return AVERROR_INVALIDDATA;
+        return AVERROR(EINVAL);
     }
 
     /** get frame_offset */
     s->video_base = AV_RL16(&avctx->extradata[0]);
-    s->clr_count = AV_RL32(&avctx->extradata[2]);
+    s->clr_count  = AV_RL32(&avctx->extradata[2]);
 
-    if(s->video_base >= avctx->width * avctx->height){
+    if (s->video_base >= avctx->width * avctx->height) {
         av_log(avctx, AV_LOG_ERROR, "invalid video_base\n");
         return AVERROR_INVALIDDATA;
     }
 
     /** initialize palette */
-    for(i=0;i<AVPALETTE_COUNT;i++)
+    for (i = 0; i < AVPALETTE_COUNT; i++)
         s->palette[i] = 0xFFU << 24 | AV_RB24(&avctx->extradata[6 + i * 3]);
 
     /** decode background frame if present */
     back_size = avctx->extradata_size - EXTRADATA1_SIZE;
 
-    if(back_size > 0){
-        unsigned char* back_frame = av_mallocz(avctx->width*avctx->height);
-        if(!back_frame)
+    if (back_size > 0) {
+        uint8_t *back_frame = av_mallocz(avctx->width*avctx->height);
+        if (!back_frame)
             return AVERROR(ENOMEM);
-        rl2_rle_decode(s,avctx->extradata + EXTRADATA1_SIZE,back_size,
-                           back_frame,avctx->width,0);
+        rl2_rle_decode(s, avctx->extradata + EXTRADATA1_SIZE, back_size,
+                       back_frame, avctx->width, 0);
         s->back_frame = back_frame;
     }
     return 0;
@@ -172,31 +175,31 @@
 
 
 static int rl2_decode_frame(AVCodecContext *avctx,
-                              void *data, int *data_size,
-                              AVPacket *avpkt)
+                            void *data, int *got_frame,
+                            AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
+    int ret, buf_size  = avpkt->size;
     Rl2Context *s = avctx->priv_data;
-    int ret;
 
-    if(s->frame.data[0])
+    if (s->frame.data[0])
         avctx->release_buffer(avctx, &s->frame);
 
     /** get buffer */
-    s->frame.reference= 0;
-    if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+    s->frame.reference = 0;
+    if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) {
         av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
 
     /** run length decode */
-    rl2_rle_decode(s,buf,buf_size,s->frame.data[0],s->frame.linesize[0],s->video_base);
+    rl2_rle_decode(s, buf, buf_size, s->frame.data[0], s->frame.linesize[0],
+                   s->video_base);
 
     /** make the palette available on the way out */
     memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE);
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*)data = s->frame;
 
     /** report that the buffer was completely consumed */
@@ -213,7 +216,7 @@
 {
     Rl2Context *s = avctx->priv_data;
 
-    if(s->frame.data[0])
+    if (s->frame.data[0])
         avctx->release_buffer(avctx, &s->frame);
 
     av_free(s->back_frame);
diff --git a/libavcodec/rnd_avg.h b/libavcodec/rnd_avg.h
new file mode 100644
index 0000000..bc663ef
--- /dev/null
+++ b/libavcodec/rnd_avg.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2001-2003 BERO <bero@geocities.co.jp>
+ * Copyright (c) 2011 Oskar Arvidsson
+ *
+ * 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_RND_AVG_H
+#define AVCODEC_RND_AVG_H
+
+#include <stdint.h>
+
+#define         BYTE_VEC32(c)   ((c)*0x01010101UL)
+#define         BYTE_VEC64(c)   ((c)*0x0001000100010001UL)
+
+static inline uint32_t rnd_avg32(uint32_t a, uint32_t b)
+{
+    return (a | b) - (((a ^ b) & ~BYTE_VEC32(0x01)) >> 1);
+}
+
+static inline uint32_t no_rnd_avg32(uint32_t a, uint32_t b)
+{
+    return (a & b) + (((a ^ b) & ~BYTE_VEC32(0x01)) >> 1);
+}
+
+static inline uint64_t rnd_avg64(uint64_t a, uint64_t b)
+{
+    return (a | b) - (((a ^ b) & ~BYTE_VEC64(0x01)) >> 1);
+}
+
+static inline uint64_t no_rnd_avg64(uint64_t a, uint64_t b)
+{
+    return (a & b) + (((a ^ b) & ~BYTE_VEC64(0x01)) >> 1);
+}
+
+#endif /* AVCODEC_RND_AVG_H */
diff --git a/libavcodec/roqvideo.h b/libavcodec/roqvideo.h
index 2f9493d..3834897 100644
--- a/libavcodec/roqvideo.h
+++ b/libavcodec/roqvideo.h
@@ -25,7 +25,6 @@
 #include "libavutil/lfg.h"
 #include "avcodec.h"
 #include "bytestream.h"
-#include "dsputil.h"
 
 typedef struct roq_cell {
     unsigned char y[4];
diff --git a/libavcodec/roqvideodec.c b/libavcodec/roqvideodec.c
index 3a8e904..6812f9a 100644
--- a/libavcodec/roqvideodec.c
+++ b/libavcodec/roqvideodec.c
@@ -171,9 +171,10 @@
 
     s->avctx = avctx;
 
-    if (avctx->width%16 || avctx->height%16) {
-         av_log_ask_for_sample(avctx, "dimensions not being a multiple of 16 are unsupported\n");
-         return AVERROR_PATCHWELCOME;
+    if (avctx->width % 16 || avctx->height % 16) {
+        av_log(avctx, AV_LOG_ERROR,
+               "Dimensions must be a multiple of 16\n");
+        return AVERROR_PATCHWELCOME;
     }
 
     s->width = avctx->width;
@@ -188,7 +189,7 @@
 }
 
 static int roq_decode_frame(AVCodecContext *avctx,
-                            void *data, int *data_size,
+                            void *data, int *got_frame,
                             AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
@@ -210,7 +211,7 @@
     bytestream2_init(&s->gb, buf, buf_size);
     roqvideo_decode_frame(s);
 
-    *data_size = sizeof(AVFrame);
+    *got_frame      = 1;
     *(AVFrame*)data = *s->current_frame;
 
     /* shuffle frames */
diff --git a/libavcodec/roqvideoenc.c b/libavcodec/roqvideoenc.c
index b38ecab..02f1a45 100644
--- a/libavcodec/roqvideoenc.c
+++ b/libavcodec/roqvideoenc.c
@@ -1031,8 +1031,8 @@
     if (enc->first_frame) {
         /* Alloc memory for the reconstruction data (we must know the stride
          for that) */
-        if (avctx->get_buffer(avctx, enc->current_frame) ||
-            avctx->get_buffer(avctx, enc->last_frame)) {
+        if (ff_get_buffer(avctx, enc->current_frame) ||
+            ff_get_buffer(avctx, enc->last_frame)) {
             av_log(avctx, AV_LOG_ERROR, "  RoQ: get_buffer() failed\n");
             return -1;
         }
diff --git a/libavcodec/rpza.c b/libavcodec/rpza.c
index 498c36e..a5da967 100644
--- a/libavcodec/rpza.c
+++ b/libavcodec/rpza.c
@@ -245,26 +245,27 @@
 }
 
 static int rpza_decode_frame(AVCodecContext *avctx,
-                             void *data, int *data_size,
+                             void *data, int *got_frame,
                              AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     RpzaContext *s = avctx->priv_data;
+    int ret;
 
     s->buf = buf;
     s->size = buf_size;
 
     s->frame.reference = 3;
     s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if (avctx->reget_buffer(avctx, &s->frame)) {
+    if ((ret = avctx->reget_buffer(avctx, &s->frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     rpza_decode_stream(s);
 
-    *data_size = sizeof(AVFrame);
+    *got_frame      = 1;
     *(AVFrame*)data = s->frame;
 
     /* always report that the buffer was completely consumed */
diff --git a/libavcodec/rtjpeg.c b/libavcodec/rtjpeg.c
index 7797a65..fe781ce 100644
--- a/libavcodec/rtjpeg.c
+++ b/libavcodec/rtjpeg.c
@@ -20,7 +20,6 @@
  */
 #include "libavutil/common.h"
 #include "get_bits.h"
-#include "dsputil.h"
 #include "rtjpeg.h"
 
 #define PUT_COEFF(c) \
@@ -44,7 +43,7 @@
  * aligned this could be done faster in a different way, e.g. as it is done
  * in MPlayer libmpcodecs/native/rtjpegn.c.
  */
-static inline int get_block(GetBitContext *gb, DCTELEM *block, const uint8_t *scan,
+static inline int get_block(GetBitContext *gb, int16_t *block, const uint8_t *scan,
                             const uint32_t *quant) {
     int coeff, i, n;
     int8_t ac;
@@ -61,7 +60,7 @@
 
     // 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
-    memset(block, 0, 64 * sizeof(DCTELEM));
+    memset(block, 0, 64 * sizeof(int16_t));
 
     // 2 bits per coefficient
     while (coeff) {
@@ -121,7 +120,7 @@
     if (res > 0) \
         c->dsp->idct_put(dst, stride, block); \
 } while (0)
-            DCTELEM *block = c->block;
+            int16_t *block = c->block;
             BLOCK(c->lquant, y1, f->linesize[0]);
             y1 += 8;
             BLOCK(c->lquant, y1, f->linesize[0]);
diff --git a/libavcodec/rtjpeg.h b/libavcodec/rtjpeg.h
index 0fd24a3..294b06c 100644
--- a/libavcodec/rtjpeg.h
+++ b/libavcodec/rtjpeg.h
@@ -35,7 +35,7 @@
     uint8_t scan[64];
     uint32_t lquant[64];
     uint32_t cquant[64];
-    DECLARE_ALIGNED(16, DCTELEM, block)[64];
+    DECLARE_ALIGNED(16, int16_t, block)[64];
 } RTJpegContext;
 
 void ff_rtjpeg_decode_init(RTJpegContext *c, DSPContext *dsp,
diff --git a/libavcodec/rv10.c b/libavcodec/rv10.c
index d06a2fe..1528780 100644
--- a/libavcodec/rv10.c
+++ b/libavcodec/rv10.c
@@ -27,7 +27,6 @@
 
 #include "libavutil/imgutils.h"
 #include "avcodec.h"
-#include "dsputil.h"
 #include "mpegvideo.h"
 #include "mpeg4video.h"
 #include "h263.h"
@@ -415,13 +414,15 @@
         }else{
             s->time= seq;
             s->pb_time= s->pp_time - (s->last_non_b_time - s->time);
-            if(s->pp_time <=s->pb_time || s->pp_time <= s->pp_time - s->pb_time || s->pp_time<=0){
-                av_log(s->avctx, AV_LOG_DEBUG, "messed up order, possible from seeking? skipping current b frame\n");
-                return FRAME_SKIPPED;
-            }
-            ff_mpeg4_init_direct_mv(s);
         }
     }
+    if (s->pict_type==AV_PICTURE_TYPE_B) {
+        if(s->pp_time <=s->pb_time || s->pp_time <= s->pp_time - s->pb_time || s->pp_time<=0){
+            av_log(s->avctx, AV_LOG_DEBUG, "messed up order, possible from seeking? skipping current b frame\n");
+            return FRAME_SKIPPED;
+        }
+        ff_mpeg4_init_direct_mv(s);
+    }
 
     s->no_rounding= get_bits1(&s->gb);
 
@@ -495,7 +496,7 @@
     }
 
     if(avctx->debug & FF_DEBUG_PICT_INFO){
-        av_log(avctx, AV_LOG_DEBUG, "ver:%X ver0:%X\n", rv->sub_id, avctx->extradata_size >= 4 ? ((uint32_t*)avctx->extradata)[0] : -1);
+        av_log(avctx, AV_LOG_DEBUG, "ver:%X ver0:%X\n", rv->sub_id, ((uint32_t*)avctx->extradata)[0]);
     }
 
     avctx->pix_fmt = AV_PIX_FMT_YUV420P;
@@ -503,7 +504,7 @@
     if (ff_MPV_common_init(s) < 0)
         return -1;
 
-    ff_h263_decode_init_vlc(s);
+    ff_h263_decode_init_vlc();
 
     /* init rv vlc */
     if (!done) {
@@ -559,13 +560,13 @@
 
     if ((s->mb_x == 0 && s->mb_y == 0) || s->current_picture_ptr==NULL) {
         if(s->current_picture_ptr){ //FIXME write parser so we always have complete frames?
-            ff_er_frame_end(s);
+            ff_er_frame_end(&s->er);
             ff_MPV_frame_end(s);
             s->mb_x= s->mb_y = s->resync_mb_x = s->resync_mb_y= 0;
         }
         if(ff_MPV_frame_start(s, avctx) < 0)
             return -1;
-        ff_er_frame_start(s);
+        ff_mpeg_er_frame_start(s);
     } else {
         if (s->current_picture_ptr->f.pict_type != s->pict_type) {
             av_log(s->avctx, AV_LOG_ERROR, "Slice type mismatch\n");
@@ -658,7 +659,7 @@
         if(ret == SLICE_END) break;
     }
 
-    ff_er_add_slice(s, start_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_END);
+    ff_er_add_slice(&s->er, start_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_END);
 
     return active_bits_size;
 }
@@ -670,7 +671,7 @@
 }
 
 static int rv10_decode_frame(AVCodecContext *avctx,
-                             void *data, int *data_size,
+                             void *data, int *got_frame,
                              AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
@@ -693,11 +694,15 @@
     if(!avctx->slice_count){
         slice_count = (*buf++) + 1;
         buf_size--;
+
+        if (!slice_count || buf_size <= 8 * slice_count) {
+            av_log(avctx, AV_LOG_ERROR, "Invalid slice count: %d.\n", slice_count);
+            return AVERROR_INVALIDDATA;
+        }
+
         slices_hdr = buf + 4;
         buf += 8 * slice_count;
         buf_size -= 8 * slice_count;
-        if (buf_size <= 0)
-            return AVERROR_INVALIDDATA;
     }else
         slice_count = avctx->slice_count;
 
@@ -727,7 +732,7 @@
     }
 
     if(s->current_picture_ptr != NULL && s->mb_y>=s->mb_height){
-        ff_er_frame_end(s);
+        ff_er_frame_end(&s->er);
         ff_MPV_frame_end(s);
 
         if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {
@@ -737,10 +742,10 @@
         }
 
         if(s->last_picture_ptr || s->low_delay){
-            *data_size = sizeof(AVFrame);
+            *got_frame = 1;
             ff_print_debug_info(s, pict);
         }
-        s->current_picture_ptr= NULL; //so we can detect if frame_end wasnt called (find some nicer solution...)
+        s->current_picture_ptr= NULL; // so we can detect if frame_end was not called (find some nicer solution...)
     }
 
     return avpkt->size;
diff --git a/libavcodec/rv30.c b/libavcodec/rv30.c
index df2160a..7f8f8cb 100644
--- a/libavcodec/rv30.c
+++ b/libavcodec/rv30.c
@@ -25,7 +25,6 @@
  */
 
 #include "avcodec.h"
-#include "dsputil.h"
 #include "mpegvideo.h"
 #include "golomb.h"
 
@@ -78,8 +77,8 @@
 
     for(i = 0; i < 4; i++, dst += r->intra_types_stride - 4){
         for(j = 0; j < 4; j+= 2){
-            int code = svq3_get_ue_golomb(gb) << 1;
-            if(code > 80U*2U){
+            unsigned code = svq3_get_ue_golomb(gb) << 1;
+            if (code > 80U*2U) {
                 av_log(r->s.avctx, AV_LOG_ERROR, "Incorrect intra prediction code\n");
                 return -1;
             }
@@ -106,9 +105,9 @@
     static const int rv30_b_types[6] = { RV34_MB_SKIP, RV34_MB_B_DIRECT, RV34_MB_B_FORWARD, RV34_MB_B_BACKWARD, RV34_MB_TYPE_INTRA, RV34_MB_TYPE_INTRA16x16 };
     MpegEncContext *s = &r->s;
     GetBitContext *gb = &s->gb;
-    int code = svq3_get_ue_golomb(gb);
+    unsigned code     = svq3_get_ue_golomb(gb);
 
-    if(code > 11U){
+    if (code > 11) {
         av_log(s->avctx, AV_LOG_ERROR, "Incorrect MB type code\n");
         return -1;
     }
@@ -187,7 +186,7 @@
                 for(i = !mb_x; i < 2; i++, C += 4){
                     int ij = i + (j >> 1);
                     loc_lim = 0;
-                    if(cur_cbp && (1 << ij))
+                    if (cur_cbp & (1 << ij))
                         loc_lim = cur_lim;
                     else if(!i && left_cbp & (1 << (ij + 1)))
                         loc_lim = left_lim;
@@ -229,7 +228,7 @@
                 for(i = 0; i < 2; i++, C += 4){
                     int ij = i + (j >> 1);
                     loc_lim = 0;
-                    if(r->cbp_chroma[mb_pos] && (1 << ij))
+                    if (r->cbp_chroma[mb_pos] & (1 << ij))
                         loc_lim = cur_lim;
                     else if(!j && top_cbp & (1 << (ij + 2)))
                         loc_lim = top_lim;
diff --git a/libavcodec/rv30dsp.c b/libavcodec/rv30dsp.c
index 8343960..d13a2d8 100644
--- a/libavcodec/rv30dsp.c
+++ b/libavcodec/rv30dsp.c
@@ -25,7 +25,8 @@
  */
 
 #include "avcodec.h"
-#include "dsputil.h"
+#include "h264chroma.h"
+#include "h264qpel.h"
 #include "rv34dsp.h"
 
 #define RV30_LOWPASS(OPNAME, OP) \
@@ -252,11 +253,16 @@
 RV30_MC(avg_, 8)
 RV30_MC(avg_, 16)
 
-av_cold void ff_rv30dsp_init(RV34DSPContext *c, DSPContext* dsp) {
+av_cold void ff_rv30dsp_init(RV34DSPContext *c)
+{
+    H264ChromaContext h264chroma;
+    H264QpelContext qpel;
 
-    ff_rv34dsp_init(c, dsp);
+    ff_rv34dsp_init(c);
+    ff_h264chroma_init(&h264chroma, 8);
+    ff_h264qpel_init(&qpel, 8);
 
-    c->put_pixels_tab[0][ 0] = dsp->put_h264_qpel_pixels_tab[0][0];
+    c->put_pixels_tab[0][ 0] = qpel.put_h264_qpel_pixels_tab[0][0];
     c->put_pixels_tab[0][ 1] = put_rv30_tpel16_mc10_c;
     c->put_pixels_tab[0][ 2] = put_rv30_tpel16_mc20_c;
     c->put_pixels_tab[0][ 4] = put_rv30_tpel16_mc01_c;
@@ -265,7 +271,7 @@
     c->put_pixels_tab[0][ 8] = put_rv30_tpel16_mc02_c;
     c->put_pixels_tab[0][ 9] = put_rv30_tpel16_mc12_c;
     c->put_pixels_tab[0][10] = put_rv30_tpel16_mc22_c;
-    c->avg_pixels_tab[0][ 0] = dsp->avg_h264_qpel_pixels_tab[0][0];
+    c->avg_pixels_tab[0][ 0] = qpel.avg_h264_qpel_pixels_tab[0][0];
     c->avg_pixels_tab[0][ 1] = avg_rv30_tpel16_mc10_c;
     c->avg_pixels_tab[0][ 2] = avg_rv30_tpel16_mc20_c;
     c->avg_pixels_tab[0][ 4] = avg_rv30_tpel16_mc01_c;
@@ -274,7 +280,7 @@
     c->avg_pixels_tab[0][ 8] = avg_rv30_tpel16_mc02_c;
     c->avg_pixels_tab[0][ 9] = avg_rv30_tpel16_mc12_c;
     c->avg_pixels_tab[0][10] = avg_rv30_tpel16_mc22_c;
-    c->put_pixels_tab[1][ 0] = dsp->put_h264_qpel_pixels_tab[1][0];
+    c->put_pixels_tab[1][ 0] = qpel.put_h264_qpel_pixels_tab[1][0];
     c->put_pixels_tab[1][ 1] = put_rv30_tpel8_mc10_c;
     c->put_pixels_tab[1][ 2] = put_rv30_tpel8_mc20_c;
     c->put_pixels_tab[1][ 4] = put_rv30_tpel8_mc01_c;
@@ -283,7 +289,7 @@
     c->put_pixels_tab[1][ 8] = put_rv30_tpel8_mc02_c;
     c->put_pixels_tab[1][ 9] = put_rv30_tpel8_mc12_c;
     c->put_pixels_tab[1][10] = put_rv30_tpel8_mc22_c;
-    c->avg_pixels_tab[1][ 0] = dsp->avg_h264_qpel_pixels_tab[1][0];
+    c->avg_pixels_tab[1][ 0] = qpel.avg_h264_qpel_pixels_tab[1][0];
     c->avg_pixels_tab[1][ 1] = avg_rv30_tpel8_mc10_c;
     c->avg_pixels_tab[1][ 2] = avg_rv30_tpel8_mc20_c;
     c->avg_pixels_tab[1][ 4] = avg_rv30_tpel8_mc01_c;
@@ -293,8 +299,8 @@
     c->avg_pixels_tab[1][ 9] = avg_rv30_tpel8_mc12_c;
     c->avg_pixels_tab[1][10] = avg_rv30_tpel8_mc22_c;
 
-    c->put_chroma_pixels_tab[0] = dsp->put_h264_chroma_pixels_tab[0];
-    c->put_chroma_pixels_tab[1] = dsp->put_h264_chroma_pixels_tab[1];
-    c->avg_chroma_pixels_tab[0] = dsp->avg_h264_chroma_pixels_tab[0];
-    c->avg_chroma_pixels_tab[1] = dsp->avg_h264_chroma_pixels_tab[1];
+    c->put_chroma_pixels_tab[0] = h264chroma.put_h264_chroma_pixels_tab[0];
+    c->put_chroma_pixels_tab[1] = h264chroma.put_h264_chroma_pixels_tab[1];
+    c->avg_chroma_pixels_tab[0] = h264chroma.avg_h264_chroma_pixels_tab[0];
+    c->avg_chroma_pixels_tab[1] = h264chroma.avg_h264_chroma_pixels_tab[1];
 }
diff --git a/libavcodec/rv34.c b/libavcodec/rv34.c
index 6527252..d71c71a 100644
--- a/libavcodec/rv34.c
+++ b/libavcodec/rv34.c
@@ -28,7 +28,6 @@
 #include "libavutil/internal.h"
 
 #include "avcodec.h"
-#include "dsputil.h"
 #include "mpegvideo.h"
 #include "golomb.h"
 #include "internal.h"
@@ -215,9 +214,9 @@
 }
 
 /**
- * Get one coefficient value from the bistream and store it.
+ * Get one coefficient value from the bitstream and store it.
  */
-static inline void decode_coeff(DCTELEM *dst, int coef, int esc, GetBitContext *gb, VLC* vlc, int q)
+static inline void decode_coeff(int16_t *dst, int coef, int esc, GetBitContext *gb, VLC* vlc, int q)
 {
     if(coef){
         if(coef == esc){
@@ -237,7 +236,7 @@
 /**
  * Decode 2x2 subblock of coefficients.
  */
-static inline void decode_subblock(DCTELEM *dst, int code, const int is_block2, GetBitContext *gb, VLC *vlc, int q)
+static inline void decode_subblock(int16_t *dst, int code, const int is_block2, GetBitContext *gb, VLC *vlc, int q)
 {
     int flags = modulo_three_table[code];
 
@@ -255,13 +254,13 @@
 /**
  * Decode a single coefficient.
  */
-static inline void decode_subblock1(DCTELEM *dst, int code, GetBitContext *gb, VLC *vlc, int q)
+static inline void decode_subblock1(int16_t *dst, int code, GetBitContext *gb, VLC *vlc, int q)
 {
     int coeff = modulo_three_table[code] >> 6;
     decode_coeff(dst, coeff, 3, gb, vlc, q);
 }
 
-static inline void decode_subblock3(DCTELEM *dst, int code, GetBitContext *gb, VLC *vlc,
+static inline void decode_subblock3(int16_t *dst, int code, GetBitContext *gb, VLC *vlc,
                                     int q_dc, int q_ac1, int q_ac2)
 {
     int flags = modulo_three_table[code];
@@ -283,7 +282,7 @@
  *  o--o
  */
 
-static int rv34_decode_block(DCTELEM *dst, GetBitContext *gb, RV34VLC *rvlc, int fc, int sc, int q_dc, int q_ac1, int q_ac2)
+static int rv34_decode_block(int16_t *dst, GetBitContext *gb, RV34VLC *rvlc, int fc, int sc, int q_dc, int q_ac1, int q_ac2)
 {
     int code, pattern, has_ac = 1;
 
@@ -726,12 +725,12 @@
         uint8_t *uvbuf = s->edge_emu_buffer + 22 * s->linesize;
 
         srcY -= 2 + 2*s->linesize;
-        s->dsp.emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, (width<<3)+6, (height<<3)+6,
+        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, (width<<3)+6, (height<<3)+6,
                             src_x - 2, src_y - 2, s->h_edge_pos, s->v_edge_pos);
         srcY = s->edge_emu_buffer + 2 + 2*s->linesize;
-        s->dsp.emulated_edge_mc(uvbuf     , srcU, s->uvlinesize, (width<<2)+1, (height<<2)+1,
+        s->vdsp.emulated_edge_mc(uvbuf     , srcU, s->uvlinesize, (width<<2)+1, (height<<2)+1,
                             uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
-        s->dsp.emulated_edge_mc(uvbuf + 16, srcV, s->uvlinesize, (width<<2)+1, (height<<2)+1,
+        s->vdsp.emulated_edge_mc(uvbuf + 16, srcV, s->uvlinesize, (width<<2)+1, (height<<2)+1,
                             uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
         srcU = uvbuf;
         srcV = uvbuf + 16;
@@ -995,7 +994,7 @@
                                       int fc, int sc, int q_dc, int q_ac)
 {
     MpegEncContext *s = &r->s;
-    DCTELEM *ptr = s->block[0];
+    int16_t *ptr = s->block[0];
     int has_ac = rv34_decode_block(ptr, &s->gb, r->cur_vlcs,
                                    fc, sc, q_dc, q_ac, q_ac);
     if(has_ac){
@@ -1008,13 +1007,13 @@
 
 static void rv34_output_i16x16(RV34DecContext *r, int8_t *intra_types, int cbp)
 {
-    LOCAL_ALIGNED_16(DCTELEM, block16, [16]);
+    LOCAL_ALIGNED_16(int16_t, block16, [16]);
     MpegEncContext *s    = &r->s;
     GetBitContext  *gb   = &s->gb;
     int             q_dc = rv34_qscale_tab[ r->luma_dc_quant_i[s->qscale] ],
                     q_ac = rv34_qscale_tab[s->qscale];
     uint8_t        *dst  = s->dest[0];
-    DCTELEM        *ptr  = s->block[0];
+    int16_t        *ptr  = s->block[0];
     int i, j, itype, has_ac;
 
     memset(block16, 0, 16 * sizeof(*block16));
@@ -1180,7 +1179,7 @@
     MpegEncContext *s   = &r->s;
     GetBitContext  *gb  = &s->gb;
     uint8_t        *dst = s->dest[0];
-    DCTELEM        *ptr = s->block[0];
+    int16_t        *ptr = s->block[0];
     int          mb_pos = s->mb_x + s->mb_y * s->mb_stride;
     int cbp, cbp2;
     int q_dc, q_ac, has_ac;
@@ -1220,7 +1219,7 @@
 
     if(r->is16){
         // Only for RV34_MB_P_MIX16x16
-        LOCAL_ALIGNED_16(DCTELEM, block16, [16]);
+        LOCAL_ALIGNED_16(int16_t, block16, [16]);
         memset(block16, 0, 16 * sizeof(*block16));
         q_dc = rv34_qscale_tab[ r->luma_dc_quant_p[s->qscale] ];
         q_ac = rv34_qscale_tab[s->qscale];
@@ -1434,7 +1433,7 @@
         else
             res = rv34_decode_intra_macroblock(r, r->intra_types + s->mb_x * 4 + 4);
         if(res < 0){
-            ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_ERROR);
+            ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_ERROR);
             return -1;
         }
         if (++s->mb_x == s->mb_width) {
@@ -1457,7 +1456,7 @@
             s->first_slice_line=0;
         s->mb_num_left--;
     }
-    ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_END);
+    ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_END);
 
     return s->mb_y == s->mb_height;
 }
@@ -1495,11 +1494,11 @@
 
 #if CONFIG_RV30_DECODER
     if (avctx->codec_id == AV_CODEC_ID_RV30)
-        ff_rv30dsp_init(&r->rdsp, &r->s.dsp);
+        ff_rv30dsp_init(&r->rdsp);
 #endif
 #if CONFIG_RV40_DECODER
     if (avctx->codec_id == AV_CODEC_ID_RV40)
-        ff_rv40dsp_init(&r->rdsp, &r->s.dsp);
+        ff_rv40dsp_init(&r->rdsp);
 #endif
 
     if ((ret = rv34_decoder_alloc(r)) < 0)
@@ -1570,7 +1569,7 @@
     MpegEncContext *s = &r->s;
     int got_picture = 0;
 
-    ff_er_frame_end(s);
+    ff_er_frame_end(&s->er);
     ff_MPV_frame_end(s);
     s->mb_num_left = 0;
 
@@ -1652,7 +1651,7 @@
         if (s->mb_num_left > 0) {
             av_log(avctx, AV_LOG_ERROR, "New frame but still %d MB left.\n",
                    s->mb_num_left);
-            ff_er_frame_end(s);
+            ff_er_frame_end(&s->er);
             ff_MPV_frame_end(s);
         }
 
@@ -1676,7 +1675,7 @@
         s->pict_type = si.type ? si.type : AV_PICTURE_TYPE_I;
         if (ff_MPV_frame_start(s, s->avctx) < 0)
             return -1;
-        ff_er_frame_start(s);
+        ff_mpeg_er_frame_start(s);
         if (!r->tmp_b_block_base) {
             int i;
 
@@ -1775,7 +1774,7 @@
             av_log(avctx, AV_LOG_INFO, "marking unfished frame as finished\n");
             /* always mark the current frame as finished, frame-mt supports
              * only complete frames */
-            ff_er_frame_end(s);
+            ff_er_frame_end(&s->er);
             ff_MPV_frame_end(s);
             s->mb_num_left = 0;
             ff_thread_report_progress(&s->current_picture_ptr->f, INT_MAX, 0);
diff --git a/libavcodec/rv34.h b/libavcodec/rv34.h
index 6b8d365..475f17a 100644
--- a/libavcodec/rv34.h
+++ b/libavcodec/rv34.h
@@ -28,7 +28,6 @@
 #define AVCODEC_RV34_H
 
 #include "avcodec.h"
-#include "dsputil.h"
 #include "mpegvideo.h"
 
 #include "h264pred.h"
@@ -133,7 +132,7 @@
  */
 int ff_rv34_get_start_offset(GetBitContext *gb, int blocks);
 int ff_rv34_decode_init(AVCodecContext *avctx);
-int ff_rv34_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt);
+int ff_rv34_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt);
 int ff_rv34_decode_end(AVCodecContext *avctx);
 int ff_rv34_decode_init_thread_copy(AVCodecContext *avctx);
 int ff_rv34_decode_update_thread_context(AVCodecContext *dst, const AVCodecContext *src);
diff --git a/libavcodec/rv34dsp.c b/libavcodec/rv34dsp.c
index 86a2ffd..7234ee8 100644
--- a/libavcodec/rv34dsp.c
+++ b/libavcodec/rv34dsp.c
@@ -24,7 +24,7 @@
  * @file
  * RV30/40 decoder common dsp functions
  */
-#include "dsputil.h"
+
 #include "rv34dsp.h"
 #include "libavutil/common.h"
 
@@ -33,7 +33,7 @@
  * @{
  */
 
-static av_always_inline void rv34_row_transform(int temp[16], DCTELEM *block)
+static av_always_inline void rv34_row_transform(int temp[16], int16_t *block)
 {
     int i;
 
@@ -54,12 +54,12 @@
  * Real Video 3.0/4.0 inverse transform + sample reconstruction
  * Code is almost the same as in SVQ3, only scaling is different.
  */
-static void rv34_idct_add_c(uint8_t *dst, ptrdiff_t stride, DCTELEM *block){
+static void rv34_idct_add_c(uint8_t *dst, ptrdiff_t stride, int16_t *block){
     int      temp[16];
     int      i;
 
     rv34_row_transform(temp, block);
-    memset(block, 0, 16*sizeof(DCTELEM));
+    memset(block, 0, 16*sizeof(int16_t));
 
     for(i = 0; i < 4; i++){
         const int z0 = 13*(temp[4*0+i] +    temp[4*2+i]) + 0x200;
@@ -82,7 +82,7 @@
  * Code is almost the same as rv34_inv_transform()
  * but final coefficients are multiplied by 1.5 and have no rounding.
  */
-static void rv34_inv_transform_noround_c(DCTELEM *block){
+static void rv34_inv_transform_noround_c(int16_t *block){
     int temp[16];
     int i;
 
@@ -115,9 +115,9 @@
     }
 }
 
-static void rv34_inv_transform_dc_noround_c(DCTELEM *block)
+static void rv34_inv_transform_dc_noround_c(int16_t *block)
 {
-    DCTELEM dc = (13 * 13 * 3 * block[0]) >> 11;
+    int16_t dc = (13 * 13 * 3 * block[0]) >> 11;
     int i, j;
 
     for (i = 0; i < 4; i++, block += 4)
@@ -128,7 +128,8 @@
 /** @} */ // transform
 
 
-av_cold void ff_rv34dsp_init(RV34DSPContext *c, DSPContext* dsp) {
+av_cold void ff_rv34dsp_init(RV34DSPContext *c)
+{
     c->rv34_inv_transform    = rv34_inv_transform_noround_c;
     c->rv34_inv_transform_dc = rv34_inv_transform_dc_noround_c;
 
@@ -136,7 +137,7 @@
     c->rv34_idct_dc_add = rv34_idct_dc_add_c;
 
     if (ARCH_ARM)
-        ff_rv34dsp_init_arm(c, dsp);
+        ff_rv34dsp_init_arm(c);
     if (ARCH_X86)
-        ff_rv34dsp_init_x86(c, dsp);
+        ff_rv34dsp_init_x86(c);
 }
diff --git a/libavcodec/rv34dsp.h b/libavcodec/rv34dsp.h
index f0263b1..c5d4e39 100644
--- a/libavcodec/rv34dsp.h
+++ b/libavcodec/rv34dsp.h
@@ -28,15 +28,16 @@
 #define AVCODEC_RV34DSP_H
 
 #include "dsputil.h"
+#include "h264chroma.h"
 
 typedef void (*rv40_weight_func)(uint8_t *dst/*align width (8 or 16)*/,
                                  uint8_t *src1/*align width (8 or 16)*/,
                                  uint8_t *src2/*align width (8 or 16)*/,
                                  int w1, int w2, ptrdiff_t stride);
 
-typedef void (*rv34_inv_transform_func)(DCTELEM *block);
+typedef void (*rv34_inv_transform_func)(int16_t *block);
 
-typedef void (*rv34_idct_add_func)(uint8_t *dst, ptrdiff_t stride, DCTELEM *block);
+typedef void (*rv34_idct_add_func)(uint8_t *dst, ptrdiff_t stride, int16_t *block);
 typedef void (*rv34_idct_dc_add_func)(uint8_t *dst, ptrdiff_t stride,
                                       int   dc);
 
@@ -73,14 +74,14 @@
     rv40_loop_filter_strength_func rv40_loop_filter_strength[2];
 } RV34DSPContext;
 
-void ff_rv30dsp_init(RV34DSPContext *c, DSPContext* dsp);
-void ff_rv34dsp_init(RV34DSPContext *c, DSPContext* dsp);
-void ff_rv40dsp_init(RV34DSPContext *c, DSPContext* dsp);
+void ff_rv30dsp_init(RV34DSPContext *c);
+void ff_rv34dsp_init(RV34DSPContext *c);
+void ff_rv40dsp_init(RV34DSPContext *c);
 
-void ff_rv34dsp_init_arm(RV34DSPContext *c, DSPContext *dsp);
-void ff_rv34dsp_init_x86(RV34DSPContext *c, DSPContext *dsp);
+void ff_rv34dsp_init_arm(RV34DSPContext *c);
+void ff_rv34dsp_init_x86(RV34DSPContext *c);
 
-void ff_rv40dsp_init_x86(RV34DSPContext *c, DSPContext *dsp);
-void ff_rv40dsp_init_arm(RV34DSPContext *c, DSPContext *dsp);
+void ff_rv40dsp_init_x86(RV34DSPContext *c);
+void ff_rv40dsp_init_arm(RV34DSPContext *c);
 
 #endif /* AVCODEC_RV34DSP_H */
diff --git a/libavcodec/rv40.c b/libavcodec/rv40.c
index ff0ef91..fe3608e 100644
--- a/libavcodec/rv40.c
+++ b/libavcodec/rv40.c
@@ -27,7 +27,6 @@
 #include "libavutil/imgutils.h"
 
 #include "avcodec.h"
-#include "dsputil.h"
 #include "mpegvideo.h"
 #include "golomb.h"
 
diff --git a/libavcodec/rv40dsp.c b/libavcodec/rv40dsp.c
index 944a628..cea4552 100644
--- a/libavcodec/rv40dsp.c
+++ b/libavcodec/rv40dsp.c
@@ -25,7 +25,7 @@
  */
 
 #include "avcodec.h"
-#include "dsputil.h"
+#include "h264qpel.h"
 #include "rv34dsp.h"
 #include "libavutil/avassert.h"
 #include "libavutil/common.h"
@@ -518,19 +518,22 @@
     return rv40_loop_filter_strength(src, 1, stride, beta, beta2, edge, p1, q1);
 }
 
-av_cold void ff_rv40dsp_init(RV34DSPContext *c, DSPContext* dsp) {
+av_cold void ff_rv40dsp_init(RV34DSPContext *c)
+{
+    H264QpelContext qpel;
 
-    ff_rv34dsp_init(c, dsp);
+    ff_rv34dsp_init(c);
+    ff_h264qpel_init(&qpel, 8);
 
-    c->put_pixels_tab[0][ 0] = dsp->put_h264_qpel_pixels_tab[0][0];
+    c->put_pixels_tab[0][ 0] = qpel.put_h264_qpel_pixels_tab[0][0];
     c->put_pixels_tab[0][ 1] = put_rv40_qpel16_mc10_c;
-    c->put_pixels_tab[0][ 2] = dsp->put_h264_qpel_pixels_tab[0][2];
+    c->put_pixels_tab[0][ 2] = qpel.put_h264_qpel_pixels_tab[0][2];
     c->put_pixels_tab[0][ 3] = put_rv40_qpel16_mc30_c;
     c->put_pixels_tab[0][ 4] = put_rv40_qpel16_mc01_c;
     c->put_pixels_tab[0][ 5] = put_rv40_qpel16_mc11_c;
     c->put_pixels_tab[0][ 6] = put_rv40_qpel16_mc21_c;
     c->put_pixels_tab[0][ 7] = put_rv40_qpel16_mc31_c;
-    c->put_pixels_tab[0][ 8] = dsp->put_h264_qpel_pixels_tab[0][8];
+    c->put_pixels_tab[0][ 8] = qpel.put_h264_qpel_pixels_tab[0][8];
     c->put_pixels_tab[0][ 9] = put_rv40_qpel16_mc12_c;
     c->put_pixels_tab[0][10] = put_rv40_qpel16_mc22_c;
     c->put_pixels_tab[0][11] = put_rv40_qpel16_mc32_c;
@@ -538,15 +541,15 @@
     c->put_pixels_tab[0][13] = put_rv40_qpel16_mc13_c;
     c->put_pixels_tab[0][14] = put_rv40_qpel16_mc23_c;
     c->put_pixels_tab[0][15] = ff_put_rv40_qpel16_mc33_c;
-    c->avg_pixels_tab[0][ 0] = dsp->avg_h264_qpel_pixels_tab[0][0];
+    c->avg_pixels_tab[0][ 0] = qpel.avg_h264_qpel_pixels_tab[0][0];
     c->avg_pixels_tab[0][ 1] = avg_rv40_qpel16_mc10_c;
-    c->avg_pixels_tab[0][ 2] = dsp->avg_h264_qpel_pixels_tab[0][2];
+    c->avg_pixels_tab[0][ 2] = qpel.avg_h264_qpel_pixels_tab[0][2];
     c->avg_pixels_tab[0][ 3] = avg_rv40_qpel16_mc30_c;
     c->avg_pixels_tab[0][ 4] = avg_rv40_qpel16_mc01_c;
     c->avg_pixels_tab[0][ 5] = avg_rv40_qpel16_mc11_c;
     c->avg_pixels_tab[0][ 6] = avg_rv40_qpel16_mc21_c;
     c->avg_pixels_tab[0][ 7] = avg_rv40_qpel16_mc31_c;
-    c->avg_pixels_tab[0][ 8] = dsp->avg_h264_qpel_pixels_tab[0][8];
+    c->avg_pixels_tab[0][ 8] = qpel.avg_h264_qpel_pixels_tab[0][8];
     c->avg_pixels_tab[0][ 9] = avg_rv40_qpel16_mc12_c;
     c->avg_pixels_tab[0][10] = avg_rv40_qpel16_mc22_c;
     c->avg_pixels_tab[0][11] = avg_rv40_qpel16_mc32_c;
@@ -554,15 +557,15 @@
     c->avg_pixels_tab[0][13] = avg_rv40_qpel16_mc13_c;
     c->avg_pixels_tab[0][14] = avg_rv40_qpel16_mc23_c;
     c->avg_pixels_tab[0][15] = ff_avg_rv40_qpel16_mc33_c;
-    c->put_pixels_tab[1][ 0] = dsp->put_h264_qpel_pixels_tab[1][0];
+    c->put_pixels_tab[1][ 0] = qpel.put_h264_qpel_pixels_tab[1][0];
     c->put_pixels_tab[1][ 1] = put_rv40_qpel8_mc10_c;
-    c->put_pixels_tab[1][ 2] = dsp->put_h264_qpel_pixels_tab[1][2];
+    c->put_pixels_tab[1][ 2] = qpel.put_h264_qpel_pixels_tab[1][2];
     c->put_pixels_tab[1][ 3] = put_rv40_qpel8_mc30_c;
     c->put_pixels_tab[1][ 4] = put_rv40_qpel8_mc01_c;
     c->put_pixels_tab[1][ 5] = put_rv40_qpel8_mc11_c;
     c->put_pixels_tab[1][ 6] = put_rv40_qpel8_mc21_c;
     c->put_pixels_tab[1][ 7] = put_rv40_qpel8_mc31_c;
-    c->put_pixels_tab[1][ 8] = dsp->put_h264_qpel_pixels_tab[1][8];
+    c->put_pixels_tab[1][ 8] = qpel.put_h264_qpel_pixels_tab[1][8];
     c->put_pixels_tab[1][ 9] = put_rv40_qpel8_mc12_c;
     c->put_pixels_tab[1][10] = put_rv40_qpel8_mc22_c;
     c->put_pixels_tab[1][11] = put_rv40_qpel8_mc32_c;
@@ -570,15 +573,15 @@
     c->put_pixels_tab[1][13] = put_rv40_qpel8_mc13_c;
     c->put_pixels_tab[1][14] = put_rv40_qpel8_mc23_c;
     c->put_pixels_tab[1][15] = ff_put_rv40_qpel8_mc33_c;
-    c->avg_pixels_tab[1][ 0] = dsp->avg_h264_qpel_pixels_tab[1][0];
+    c->avg_pixels_tab[1][ 0] = qpel.avg_h264_qpel_pixels_tab[1][0];
     c->avg_pixels_tab[1][ 1] = avg_rv40_qpel8_mc10_c;
-    c->avg_pixels_tab[1][ 2] = dsp->avg_h264_qpel_pixels_tab[1][2];
+    c->avg_pixels_tab[1][ 2] = qpel.avg_h264_qpel_pixels_tab[1][2];
     c->avg_pixels_tab[1][ 3] = avg_rv40_qpel8_mc30_c;
     c->avg_pixels_tab[1][ 4] = avg_rv40_qpel8_mc01_c;
     c->avg_pixels_tab[1][ 5] = avg_rv40_qpel8_mc11_c;
     c->avg_pixels_tab[1][ 6] = avg_rv40_qpel8_mc21_c;
     c->avg_pixels_tab[1][ 7] = avg_rv40_qpel8_mc31_c;
-    c->avg_pixels_tab[1][ 8] = dsp->avg_h264_qpel_pixels_tab[1][8];
+    c->avg_pixels_tab[1][ 8] = qpel.avg_h264_qpel_pixels_tab[1][8];
     c->avg_pixels_tab[1][ 9] = avg_rv40_qpel8_mc12_c;
     c->avg_pixels_tab[1][10] = avg_rv40_qpel8_mc22_c;
     c->avg_pixels_tab[1][11] = avg_rv40_qpel8_mc32_c;
@@ -605,7 +608,7 @@
     c->rv40_loop_filter_strength[1] = rv40_v_loop_filter_strength;
 
     if (ARCH_X86)
-        ff_rv40dsp_init_x86(c, dsp);
+        ff_rv40dsp_init_x86(c);
     if (ARCH_ARM)
-        ff_rv40dsp_init_arm(c, dsp);
+        ff_rv40dsp_init_arm(c);
 }
diff --git a/libavcodec/s302m.c b/libavcodec/s302m.c
index 5058ba0..d641c2e 100644
--- a/libavcodec/s302m.c
+++ b/libavcodec/s302m.c
@@ -23,14 +23,11 @@
 #include "libavutil/intreadwrite.h"
 #include "libavutil/log.h"
 #include "avcodec.h"
+#include "internal.h"
 #include "mathops.h"
 
 #define AES3_HEADER_LEN 4
 
-typedef struct S302MDecodeContext {
-    AVFrame frame;
-} S302MDecodeContext;
-
 static int s302m_parse_frame_header(AVCodecContext *avctx, const uint8_t *buf,
                                     int buf_size)
 {
@@ -94,7 +91,7 @@
 static int s302m_decode_frame(AVCodecContext *avctx, void *data,
                               int *got_frame_ptr, AVPacket *avpkt)
 {
-    S302MDecodeContext *s = avctx->priv_data;
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
     int block_size, ret;
@@ -108,16 +105,16 @@
 
     /* get output buffer */
     block_size = (avctx->bits_per_coded_sample + 4) / 4;
-    s->frame.nb_samples = 2 * (buf_size / block_size) / avctx->channels;
-    if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = 2 * (buf_size / block_size) / avctx->channels;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
 
-    buf_size = (s->frame.nb_samples * avctx->channels / 2) * block_size;
+    buf_size = (frame->nb_samples * avctx->channels / 2) * block_size;
 
     if (avctx->bits_per_coded_sample == 24) {
-        uint32_t *o = (uint32_t *)s->frame.data[0];
+        uint32_t *o = (uint32_t *)frame->data[0];
         for (; buf_size > 6; buf_size -= 7) {
             *o++ = (ff_reverse[buf[2]]        << 24) |
                    (ff_reverse[buf[1]]        << 16) |
@@ -129,7 +126,7 @@
             buf += 7;
         }
     } else if (avctx->bits_per_coded_sample == 20) {
-        uint32_t *o = (uint32_t *)s->frame.data[0];
+        uint32_t *o = (uint32_t *)frame->data[0];
         for (; buf_size > 5; buf_size -= 6) {
             *o++ = (ff_reverse[buf[2] & 0xf0] << 28) |
                    (ff_reverse[buf[1]]        << 20) |
@@ -140,7 +137,7 @@
             buf += 6;
         }
     } else {
-        uint16_t *o = (uint16_t *)s->frame.data[0];
+        uint16_t *o = (uint16_t *)frame->data[0];
         for (; buf_size > 4; buf_size -= 5) {
             *o++ = (ff_reverse[buf[1]]        <<  8) |
                     ff_reverse[buf[0]];
@@ -151,29 +148,15 @@
         }
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
+    *got_frame_ptr = 1;
 
     return avpkt->size;
 }
 
-static int s302m_decode_init(AVCodecContext *avctx)
-{
-    S302MDecodeContext *s = avctx->priv_data;
-
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
-    return 0;
-}
-
-
 AVCodec ff_s302m_decoder = {
     .name           = "s302m",
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_S302M,
-    .priv_data_size = sizeof(S302MDecodeContext),
-    .init           = s302m_decode_init,
     .decode         = s302m_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("SMPTE 302M"),
diff --git a/libavcodec/sanm.c b/libavcodec/sanm.c
index 766ac68..caeaa36 100644
--- a/libavcodec/sanm.c
+++ b/libavcodec/sanm.c
@@ -23,10 +23,13 @@
 // #define DEBUG 1
 
 #include "avcodec.h"
+#include "copy_block.h"
 #include "bytestream.h"
+#include "internal.h"
 #include "libavutil/bswap.h"
-#include "libavcodec/dsputil.h"
+#include "libavutil/imgutils.h"
 #include "sanm_data.h"
+#include "libavutil/avassert.h"
 
 #define NGLYPHS 256
 
@@ -228,6 +231,9 @@
     av_freep(&ctx->frm2);
     av_freep(&ctx->stored_frame);
     av_freep(&ctx->rle_buf);
+    ctx->frm0_size =
+    ctx->frm1_size =
+    ctx->frm2_size = 0;
 }
 
 static av_cold int init_buffers(SANMVideoContext *ctx)
@@ -414,6 +420,11 @@
     flags        = bytestream2_get_byte(&ctx->gb);
     bytestream2_skip(&ctx->gb, 3);
 
+    if (decoded_size > ctx->height * stride - left - top * stride) {
+        decoded_size = ctx->height * stride - left - top * stride;
+        av_log(ctx->avctx, AV_LOG_WARNING, "decoded size is too large\n");
+    }
+
     ctx->rotate_code = 0;
 
     if (((seq & 1) || !(flags & 1)) && (compr && compr != 2))
@@ -611,6 +622,16 @@
     } else {
         int mx = motion_vectors[code][0];
         int my = motion_vectors[code][1];
+        int index = prev2 - (const uint8_t*)ctx->frm2;
+
+        av_assert2(index >= 0 && index < (ctx->buf_size>>1));
+
+        if (index < - mx - my*stride ||
+            (ctx->buf_size>>1) - index < mx + size + (my + size - 1)*stride) {
+            av_log(ctx->avctx, AV_LOG_ERROR, "MV is invalid \n");
+            return AVERROR_INVALIDDATA;
+        }
+
         for (k = 0; k < size; k++)
             memcpy(dst + k * stride, prev2 + mx + (my + k) * stride, size);
     }
@@ -637,6 +658,11 @@
     decoded_size = bytestream2_get_le32(&ctx->gb);
     bytestream2_skip(&ctx->gb, 8);
 
+    if (decoded_size > ctx->height * stride - left - top * stride) {
+        decoded_size = ctx->height * stride - left - top * stride;
+        av_log(ctx->avctx, AV_LOG_WARNING, "decoded size is too large\n");
+    }
+
     if (skip & 1)
         bytestream2_skip(&ctx->gb, 0x8080);
     if (!seq) {
@@ -650,8 +676,7 @@
         if (bytestream2_get_bytes_left(&ctx->gb) < width * height)
             return AVERROR_INVALIDDATA;
         for (j = 0; j < height; j++) {
-            for (i = 0; i < width; i++)
-                bytestream2_get_bufferu(&ctx->gb, dst, width);
+            bytestream2_get_bufferu(&ctx->gb, dst, width);
             dst += stride;
         }
         break;
@@ -715,9 +740,13 @@
     h     = bytestream2_get_le16u(&ctx->gb);
 
     if (ctx->width < left + w || ctx->height < top + h) {
-        ctx->avctx->width  = FFMAX(left + w, ctx->width);
-        ctx->avctx->height = FFMAX(top + h, ctx->height);
-        init_sizes(ctx, left + w, top + h);
+        if (av_image_check_size(FFMAX(left + w, ctx->width),
+                                FFMAX(top  + h, ctx->height), 0, ctx->avctx) < 0)
+            return AVERROR_INVALIDDATA;
+        avcodec_set_dimensions(ctx->avctx, FFMAX(left + w, ctx->width),
+                                           FFMAX(top  + h, ctx->height));
+        init_sizes(ctx, FFMAX(left + w, ctx->width),
+                        FFMAX(top  + h, ctx->height));
         if (init_buffers(ctx)) {
             av_log(ctx->avctx, AV_LOG_ERROR, "error resizing buffers\n");
             return AVERROR(ENOMEM);
@@ -1122,7 +1151,7 @@
     int ret, dstpitch, height = ctx->height;
     int srcpitch = ctx->pitch * (hdr ? sizeof(ctx->frm0[0]) : 1);
 
-    if ((ret = ctx->avctx->get_buffer(ctx->avctx, ctx->output)) < 0) {
+    if ((ret = ff_get_buffer(ctx->avctx, ctx->output)) < 0) {
         av_log(ctx->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
diff --git a/libavcodec/sbr.h b/libavcodec/sbr.h
index 1e41396..e28fccd 100644
--- a/libavcodec/sbr.h
+++ b/libavcodec/sbr.h
@@ -34,6 +34,8 @@
 #include "aacps.h"
 #include "sbrdsp.h"
 
+typedef struct AACContext AACContext;
+
 /**
  * Spectral Band Replication header - spectrum parameters that invoke a reset if they differ from the previous header.
  */
@@ -108,10 +110,31 @@
     /** @} */
 } SBRData;
 
+typedef struct SpectralBandReplication SpectralBandReplication;
+
+/**
+ * aacsbr functions pointers
+ */
+typedef struct AACSBRContext {
+    int (*sbr_lf_gen)(AACContext *ac, SpectralBandReplication *sbr,
+                      float X_low[32][40][2], const float W[2][32][32][2],
+                      int buf_idx);
+    void (*sbr_hf_assemble)(float Y1[38][64][2],
+                            const float X_high[64][40][2],
+                            SpectralBandReplication *sbr, SBRData *ch_data,
+                            const int e_a[2]);
+    int (*sbr_x_gen)(SpectralBandReplication *sbr, float X[2][38][64],
+                     const float Y0[38][64][2], const float Y1[38][64][2],
+                     const float X_low[32][40][2], int ch);
+    void (*sbr_hf_inverse_filter)(SBRDSPContext *dsp,
+                                  float (*alpha0)[2], float (*alpha1)[2],
+                                  const float X_low[32][40][2], int k0);
+} AACSBRContext;
+
 /**
  * Spectral Band Replication
  */
-typedef struct SpectralBandReplication {
+struct SpectralBandReplication {
     int                sample_rate;
     int                start;
     int                reset;
@@ -184,6 +207,7 @@
     FFTContext         mdct_ana;
     FFTContext         mdct;
     SBRDSPContext      dsp;
-} SpectralBandReplication;
+    AACSBRContext      c;
+};
 
 #endif /* AVCODEC_SBR_H */
diff --git a/libavcodec/sbrdsp.c b/libavcodec/sbrdsp.c
index 781ec83..6fede79 100644
--- a/libavcodec/sbrdsp.c
+++ b/libavcodec/sbrdsp.c
@@ -245,4 +245,6 @@
         ff_sbrdsp_init_arm(s);
     if (ARCH_X86)
         ff_sbrdsp_init_x86(s);
+    if (ARCH_MIPS)
+        ff_sbrdsp_init_mips(s);
 }
diff --git a/libavcodec/sbrdsp.h b/libavcodec/sbrdsp.h
index 07235c6..3831135 100644
--- a/libavcodec/sbrdsp.h
+++ b/libavcodec/sbrdsp.h
@@ -47,5 +47,6 @@
 void ff_sbrdsp_init(SBRDSPContext *s);
 void ff_sbrdsp_init_arm(SBRDSPContext *s);
 void ff_sbrdsp_init_x86(SBRDSPContext *s);
+void ff_sbrdsp_init_mips(SBRDSPContext *s);
 
 #endif /* AVCODEC_SBRDSP_H */
diff --git a/libavcodec/sgidec.c b/libavcodec/sgidec.c
index bf6e572..51bd5d6 100644
--- a/libavcodec/sgidec.c
+++ b/libavcodec/sgidec.c
@@ -23,6 +23,7 @@
 #include "libavutil/avassert.h"
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 #include "sgi.h"
 
 typedef struct SgiState {
@@ -151,7 +152,7 @@
 }
 
 static int decode_frame(AVCodecContext *avctx,
-                        void *data, int *data_size,
+                        void *data, int *got_frame,
                         AVPacket *avpkt)
 {
     SgiState *s = avctx->priv_data;
@@ -168,17 +169,17 @@
     }
 
     /* Test for SGI magic. */
-    if (bytestream2_get_be16(&s->g) != SGI_MAGIC) {
+    if (bytestream2_get_be16u(&s->g) != SGI_MAGIC) {
         av_log(avctx, AV_LOG_ERROR, "bad magic number\n");
         return AVERROR_INVALIDDATA;
     }
 
-    rle                  = bytestream2_get_byte(&s->g);
-    s->bytes_per_channel = bytestream2_get_byte(&s->g);
-    dimension            = bytestream2_get_be16(&s->g);
-    s->width             = bytestream2_get_be16(&s->g);
-    s->height            = bytestream2_get_be16(&s->g);
-    s->depth             = bytestream2_get_be16(&s->g);
+    rle                  = bytestream2_get_byteu(&s->g);
+    s->bytes_per_channel = bytestream2_get_byteu(&s->g);
+    dimension            = bytestream2_get_be16u(&s->g);
+    s->width             = bytestream2_get_be16u(&s->g);
+    s->height            = bytestream2_get_be16u(&s->g);
+    s->depth             = bytestream2_get_be16u(&s->g);
 
     if (s->bytes_per_channel != 1 && (s->bytes_per_channel != 2 || rle)) {
         av_log(avctx, AV_LOG_ERROR, "wrong channel number\n");
@@ -210,7 +211,7 @@
         avctx->release_buffer(avctx, p);
 
     p->reference = 0;
-    if (avctx->get_buffer(avctx, p) < 0) {
+    if (ff_get_buffer(avctx, p) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed.\n");
         return -1;
     }
@@ -233,7 +234,7 @@
 
     if (ret == 0) {
         *picture   = s->picture;
-        *data_size = sizeof(AVPicture);
+        *got_frame = 1;
         return avpkt->size;
     } else {
         return ret;
diff --git a/libavcodec/sgirledec.c b/libavcodec/sgirledec.c
new file mode 100644
index 0000000..0ce6afd
--- /dev/null
+++ b/libavcodec/sgirledec.c
@@ -0,0 +1,148 @@
+/*
+ * SGI RLE 8-bit decoder
+ * Copyright (c) 2012 Peter Ross
+ *
+ * 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
+ * SGI RLE 8-bit decoder
+ */
+
+#include "libavutil/intreadwrite.h"
+#include "avcodec.h"
+#include "bytestream.h"
+
+static av_cold int sgirle_decode_init(AVCodecContext *avctx)
+{
+    avctx->pix_fmt = AV_PIX_FMT_BGR8;
+    avctx->coded_frame = avcodec_alloc_frame();
+    if (!avctx->coded_frame)
+        return AVERROR(ENOMEM);
+    return 0;
+}
+
+/**
+ * Convert SGI RGB332 pixel into 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))
+
+static av_always_inline void memcpy_rgb332_to_bgr8(uint8_t *dst, const uint8_t *src, int size)
+{
+    int i;
+    for (i = 0; i < size; i++)
+        dst[i] = RGB332_TO_BGR8(src[i]);
+}
+
+/**
+ * @param[out] dst Destination buffer
+ * @param[in] src Source buffer
+ * @param src_size Source buffer size (bytes)
+ * @param width Width of destination buffer (pixels)
+ * @param height Height of destination buffer (pixels)
+ * @param linesize Line size of destination buffer (bytes)
+ * @return <0 on error
+ */
+static int decode_sgirle8(AVCodecContext *avctx, uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize)
+{
+    const uint8_t *src_end = src + src_size;
+    int x = 0, y = 0;
+
+#define INC_XY(n) \
+    x += n; \
+    if (x >= width) { \
+        y++; \
+        if (y >= height) \
+            return 0; \
+        x = 0; \
+    }
+
+    while (src_end - src >= 2) {
+        uint8_t v = *src++;
+        if (v > 0 && v < 0xC0) {
+            do {
+                int length = FFMIN(v, width - x);
+                memset(dst + y*linesize + x, RGB332_TO_BGR8(*src), length);
+                INC_XY(length);
+                v   -= length;
+            } while (v > 0);
+            src++;
+        } else if (v >= 0xC1) {
+            v -= 0xC0;
+            do {
+                int length = FFMIN3(v, width - x, src_end - src);
+                if (src_end - src < length)
+                    break;
+                memcpy_rgb332_to_bgr8(dst + y*linesize + x, src, length);
+                INC_XY(length);
+                src += length;
+                v   -= length;
+            } while (v > 0);
+        } else {
+            av_log_ask_for_sample(avctx, "unknown opcode\n");
+            return AVERROR_PATCHWELCOME;
+        }
+    }
+    return 0;
+}
+
+static int sgirle_decode_frame(AVCodecContext *avctx,
+                            void *data, int *got_frame,
+                            AVPacket *avpkt)
+{
+    AVFrame *frame = avctx->coded_frame;
+    int ret;
+
+    frame->reference = 3;
+    frame->buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE |
+                          FF_BUFFER_HINTS_REUSABLE | FF_BUFFER_HINTS_READABLE;
+    ret = avctx->reget_buffer(avctx, frame);
+    if (ret < 0) {
+        av_log (avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
+        return ret;
+    }
+
+    ret = decode_sgirle8(avctx, frame->data[0], avpkt->data, avpkt->size, avctx->width, avctx->height, frame->linesize[0]);
+    if (ret < 0)
+        return ret;
+
+    *got_frame      = 1;
+    *(AVFrame*)data = *frame;
+
+    return avpkt->size;
+}
+
+static av_cold int sgirle_decode_end(AVCodecContext *avctx)
+{
+    if (avctx->coded_frame->data[0])
+        avctx->release_buffer(avctx, avctx->coded_frame);
+    av_freep(&avctx->coded_frame);
+    return 0;
+}
+
+AVCodec ff_sgirle_decoder = {
+    .name           = "sgirle",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_SGIRLE,
+    .init           = sgirle_decode_init,
+    .close          = sgirle_decode_end,
+    .decode         = sgirle_decode_frame,
+    .capabilities   = CODEC_CAP_DR1,
+    .long_name      = NULL_IF_CONFIG_SMALL("SGI RLE 8-bit"),
+};
diff --git a/libavcodec/sh4/Makefile b/libavcodec/sh4/Makefile
index aa17eab..f907408 100644
--- a/libavcodec/sh4/Makefile
+++ b/libavcodec/sh4/Makefile
@@ -1,3 +1,5 @@
 OBJS += sh4/dsputil_align.o                                             \
         sh4/dsputil_sh4.o                                               \
         sh4/idct_sh4.o                                                  \
+
+OBJS-$(CONFIG_H264CHROMA)               += sh4/h264chroma_init.o        \
diff --git a/libavcodec/sh4/dsputil_align.c b/libavcodec/sh4/dsputil_align.c
index a545e55..46981f6 100644
--- a/libavcodec/sh4/dsputil_align.c
+++ b/libavcodec/sh4/dsputil_align.c
@@ -20,9 +20,10 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-
+#include "libavutil/attributes.h"
 #include "libavcodec/avcodec.h"
 #include "libavcodec/dsputil.h"
+#include "libavcodec/rnd_avg.h"
 #include "dsputil_sh4.h"
 
 
@@ -38,7 +39,7 @@
 #define         rnd_PACK(ph,pl,nph,npl) ph + nph + (((pl + npl + BYTE_VEC32(0x02))>>2) & BYTE_VEC32(0x03))
 #define         no_rnd_PACK(ph,pl,nph,npl)      ph + nph + (((pl + npl + BYTE_VEC32(0x01))>>2) & BYTE_VEC32(0x03))
 
-/* little endian */
+/* little-endian */
 #define         MERGE1(a,b,ofs) (ofs==0)?a:( ((a)>>(8*ofs))|((b)<<(32-8*ofs)) )
 #define         MERGE2(a,b,ofs) (ofs==3)?b:( ((a)>>(8*(ofs+1)))|((b)<<(32-8*(ofs+1))) )
 /* big
@@ -65,34 +66,6 @@
                 dest+=stride; \
         } while(--height)
 
-
-#define         OP      put
-
-static void put_pixels4_c(uint8_t *dest,const uint8_t *ref, const int stride,int height)
-{
-        switch((int)ref&3){
-        case 0: OP_C40(); return;
-        case 1: OP_C4(1); return;
-        case 2: OP_C4(2); return;
-        case 3: OP_C4(3); return;
-        }
-}
-
-#undef          OP
-#define         OP      avg
-
-static void avg_pixels4_c(uint8_t *dest,const uint8_t *ref, const int stride,int height)
-{
-        switch((int)ref&3){
-        case 0: OP_C40(); return;
-        case 1: OP_C4(1); return;
-        case 2: OP_C4(2); return;
-        case 3: OP_C4(3); return;
-        }
-}
-
-#undef          OP
-
 #define         OP_C(ofs,sz,avg2) \
 { \
         ref-=ofs; \
@@ -262,7 +235,7 @@
 
 #define         DEFFUNC(op,rnd,xy,sz,OP_N,avgfunc) \
 static void op##_##rnd##_pixels##sz##_##xy (uint8_t * dest, const uint8_t * ref, \
-                                const int stride, int height) \
+                                const ptrdiff_t stride, int height) \
 { \
         switch((int)ref&3) { \
         case 0:OP_N##0(sz,rnd##_##avgfunc); return; \
@@ -294,11 +267,8 @@
 
 DEFFUNC(avg,   rnd,o,8,OP_C,avg32)
 DEFFUNC(avg,   rnd,x,8,OP_X,avg32)
-DEFFUNC(avg,no_rnd,x,8,OP_X,avg32)
 DEFFUNC(avg,   rnd,y,8,OP_Y,avg32)
-DEFFUNC(avg,no_rnd,y,8,OP_Y,avg32)
 DEFFUNC(avg,   rnd,xy,8,OP_XY,PACK)
-DEFFUNC(avg,no_rnd,xy,8,OP_XY,PACK)
 DEFFUNC(avg,   rnd,o,16,OP_C,avg32)
 DEFFUNC(avg,   rnd,x,16,OP_X,avg32)
 DEFFUNC(avg,no_rnd,x,16,OP_X,avg32)
@@ -311,7 +281,6 @@
 
 #define         put_no_rnd_pixels8_o     put_rnd_pixels8_o
 #define         put_no_rnd_pixels16_o    put_rnd_pixels16_o
-#define         avg_no_rnd_pixels8_o     avg_rnd_pixels8_o
 #define         avg_no_rnd_pixels16_o    avg_rnd_pixels16_o
 
 #define         put_pixels8_c            put_rnd_pixels8_o
@@ -320,7 +289,6 @@
 #define         avg_pixels16_c           avg_rnd_pixels16_o
 #define         put_no_rnd_pixels8_c     put_rnd_pixels8_o
 #define         put_no_rnd_pixels16_c    put_rnd_pixels16_o
-#define         avg_no_rnd_pixels8_c     avg_rnd_pixels8_o
 #define         avg_no_rnd_pixels16_c    avg_rnd_pixels16_o
 
 #define         QPEL
@@ -331,7 +299,7 @@
 
 #endif
 
-void ff_dsputil_init_align(DSPContext* c, AVCodecContext *avctx)
+av_cold void ff_dsputil_init_align(DSPContext *c, AVCodecContext *avctx)
 {
         const int high_bit_depth = avctx->bits_per_raw_sample > 8;
 
@@ -363,14 +331,10 @@
         c->avg_pixels_tab[1][2] = avg_rnd_pixels8_y;
         c->avg_pixels_tab[1][3] = avg_rnd_pixels8_xy;
 
-        c->avg_no_rnd_pixels_tab[0][0] = avg_no_rnd_pixels16_o;
-        c->avg_no_rnd_pixels_tab[0][1] = avg_no_rnd_pixels16_x;
-        c->avg_no_rnd_pixels_tab[0][2] = avg_no_rnd_pixels16_y;
-        c->avg_no_rnd_pixels_tab[0][3] = avg_no_rnd_pixels16_xy;
-        c->avg_no_rnd_pixels_tab[1][0] = avg_no_rnd_pixels8_o;
-        c->avg_no_rnd_pixels_tab[1][1] = avg_no_rnd_pixels8_x;
-        c->avg_no_rnd_pixels_tab[1][2] = avg_no_rnd_pixels8_y;
-        c->avg_no_rnd_pixels_tab[1][3] = avg_no_rnd_pixels8_xy;
+        c->avg_no_rnd_pixels_tab[0] = avg_no_rnd_pixels16_o;
+        c->avg_no_rnd_pixels_tab[1] = avg_no_rnd_pixels16_x;
+        c->avg_no_rnd_pixels_tab[2] = avg_no_rnd_pixels16_y;
+        c->avg_no_rnd_pixels_tab[3] = avg_no_rnd_pixels16_xy;
         }
 
 #ifdef QPEL
@@ -405,24 +369,7 @@
     dspfunc(avg_qpel, 1, 8);
     /* dspfunc(avg_no_rnd_qpel, 1, 8); */
 
-    if (!high_bit_depth) {
-    dspfunc(put_h264_qpel, 0, 16);
-    dspfunc(put_h264_qpel, 1, 8);
-    dspfunc(put_h264_qpel, 2, 4);
-    dspfunc(avg_h264_qpel, 0, 16);
-    dspfunc(avg_h264_qpel, 1, 8);
-    dspfunc(avg_h264_qpel, 2, 4);
-    }
-
 #undef dspfunc
-    if (!high_bit_depth) {
-    c->put_h264_chroma_pixels_tab[0]= put_h264_chroma_mc8_sh4;
-    c->put_h264_chroma_pixels_tab[1]= put_h264_chroma_mc4_sh4;
-    c->put_h264_chroma_pixels_tab[2]= put_h264_chroma_mc2_sh4;
-    c->avg_h264_chroma_pixels_tab[0]= avg_h264_chroma_mc8_sh4;
-    c->avg_h264_chroma_pixels_tab[1]= avg_h264_chroma_mc4_sh4;
-    c->avg_h264_chroma_pixels_tab[2]= avg_h264_chroma_mc2_sh4;
-    }
 
     c->put_mspel_pixels_tab[0]= put_mspel8_mc00_sh4;
     c->put_mspel_pixels_tab[1]= put_mspel8_mc10_sh4;
@@ -434,7 +381,6 @@
     c->put_mspel_pixels_tab[7]= put_mspel8_mc32_sh4;
 
     c->gmc1 = gmc1_c;
-    c->gmc = gmc_c;
 
 #endif
 }
diff --git a/libavcodec/sh4/dsputil_sh4.c b/libavcodec/sh4/dsputil_sh4.c
index 7deab41..6e19fa0 100644
--- a/libavcodec/sh4/dsputil_sh4.c
+++ b/libavcodec/sh4/dsputil_sh4.c
@@ -20,6 +20,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavcodec/avcodec.h"
 #include "libavcodec/dsputil.h"
 #include "dsputil_sh4.h"
@@ -47,12 +48,12 @@
         fp_single_leave(fpscr);
 }
 
-static void clear_blocks_sh4(DCTELEM *blocks)
+static void clear_blocks_sh4(int16_t *blocks)
 {
-        memzero_align8(blocks,sizeof(DCTELEM)*6*64);
+        memzero_align8(blocks,sizeof(int16_t)*6*64);
 }
 
-static void idct_put(uint8_t *dest, int line_size, DCTELEM *block)
+static void idct_put(uint8_t *dest, int line_size, int16_t *block)
 {
         int i;
         uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
@@ -70,7 +71,7 @@
                 block+=8;
         }
 }
-static void idct_add(uint8_t *dest, int line_size, DCTELEM *block)
+static void idct_add(uint8_t *dest, int line_size, int16_t *block)
 {
         int i;
         uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
@@ -89,7 +90,7 @@
         }
 }
 
-void ff_dsputil_init_sh4(DSPContext* c, AVCodecContext *avctx)
+av_cold void ff_dsputil_init_sh4(DSPContext *c, AVCodecContext *avctx)
 {
         const int idct_algo= avctx->idct_algo;
         const int high_bit_depth = avctx->bits_per_raw_sample > 8;
diff --git a/libavcodec/sh4/dsputil_sh4.h b/libavcodec/sh4/dsputil_sh4.h
index f2cb11e..1c041ae 100644
--- a/libavcodec/sh4/dsputil_sh4.h
+++ b/libavcodec/sh4/dsputil_sh4.h
@@ -22,7 +22,7 @@
 #include "libavcodec/avcodec.h"
 #include "libavcodec/dsputil.h"
 
-void ff_idct_sh4(DCTELEM *block);
+void ff_idct_sh4(int16_t *block);
 void ff_dsputil_init_align(DSPContext* c, AVCodecContext *avctx);
 
 #endif /* AVCODEC_SH4_DSPUTIL_SH4_H */
diff --git a/libavcodec/sh4/h264chroma_init.c b/libavcodec/sh4/h264chroma_init.c
new file mode 100644
index 0000000..d15f0ae
--- /dev/null
+++ b/libavcodec/sh4/h264chroma_init.c
@@ -0,0 +1,132 @@
+/*
+ * aligned/packed access motion
+ *
+ * Copyright (c) 2001-2003 BERO <bero@geocities.co.jp>
+ *
+ * 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 <assert.h>
+#include <stdint.h>
+
+#include "libavutil/attributes.h"
+#include "libavcodec/h264chroma.h"
+
+#define H264_CHROMA_MC(OPNAME, OP)\
+static void OPNAME ## h264_chroma_mc2_sh4(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);\
+    \
+    assert(x<8 && y<8 && x>=0 && y>=0);\
+\
+    do {\
+        int t0,t1,t2,t3; \
+        uint8_t *s0 = src; \
+        uint8_t *s1 = src+stride; \
+        t0 = *s0++; t2 = *s1++; \
+        t1 = *s0++; t3 = *s1++; \
+        OP(dst[0], (A*t0 + B*t1 + C*t2 + D*t3));\
+        t0 = *s0++; t2 = *s1++; \
+        OP(dst[1], (A*t1 + B*t0 + C*t3 + D*t2));\
+        dst+= stride;\
+        src+= stride;\
+    }while(--h);\
+}\
+\
+static void OPNAME ## h264_chroma_mc4_sh4(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);\
+    \
+    assert(x<8 && y<8 && x>=0 && y>=0);\
+\
+    do {\
+        int t0,t1,t2,t3; \
+        uint8_t *s0 = src; \
+        uint8_t *s1 = src+stride; \
+        t0 = *s0++; t2 = *s1++; \
+        t1 = *s0++; t3 = *s1++; \
+        OP(dst[0], (A*t0 + B*t1 + C*t2 + D*t3));\
+        t0 = *s0++; t2 = *s1++; \
+        OP(dst[1], (A*t1 + B*t0 + C*t3 + D*t2));\
+        t1 = *s0++; t3 = *s1++; \
+        OP(dst[2], (A*t0 + B*t1 + C*t2 + D*t3));\
+        t0 = *s0++; t2 = *s1++; \
+        OP(dst[3], (A*t1 + B*t0 + C*t3 + D*t2));\
+        dst+= stride;\
+        src+= stride;\
+    }while(--h);\
+}\
+\
+static void OPNAME ## h264_chroma_mc8_sh4(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);\
+    \
+    assert(x<8 && y<8 && x>=0 && y>=0);\
+\
+    do {\
+        int t0,t1,t2,t3; \
+        uint8_t *s0 = src; \
+        uint8_t *s1 = src+stride; \
+        t0 = *s0++; t2 = *s1++; \
+        t1 = *s0++; t3 = *s1++; \
+        OP(dst[0], (A*t0 + B*t1 + C*t2 + D*t3));\
+        t0 = *s0++; t2 = *s1++; \
+        OP(dst[1], (A*t1 + B*t0 + C*t3 + D*t2));\
+        t1 = *s0++; t3 = *s1++; \
+        OP(dst[2], (A*t0 + B*t1 + C*t2 + D*t3));\
+        t0 = *s0++; t2 = *s1++; \
+        OP(dst[3], (A*t1 + B*t0 + C*t3 + D*t2));\
+        t1 = *s0++; t3 = *s1++; \
+        OP(dst[4], (A*t0 + B*t1 + C*t2 + D*t3));\
+        t0 = *s0++; t2 = *s1++; \
+        OP(dst[5], (A*t1 + B*t0 + C*t3 + D*t2));\
+        t1 = *s0++; t3 = *s1++; \
+        OP(dst[6], (A*t0 + B*t1 + C*t2 + D*t3));\
+        t0 = *s0++; t2 = *s1++; \
+        OP(dst[7], (A*t1 + B*t0 + C*t3 + D*t2));\
+        dst+= stride;\
+        src+= stride;\
+    }while(--h);\
+}
+
+#define op_avg(a, b) a = (((a)+(((b) + 32)>>6)+1)>>1)
+#define op_put(a, b) a = (((b) + 32)>>6)
+
+H264_CHROMA_MC(put_       , op_put)
+H264_CHROMA_MC(avg_       , op_avg)
+#undef op_avg
+#undef op_put
+
+av_cold void ff_h264chroma_init_sh4(H264ChromaContext *c, int bit_depth)
+{
+    const int high_bit_depth = bit_depth > 8;
+
+    if (!high_bit_depth) {
+    c->put_h264_chroma_pixels_tab[0]= put_h264_chroma_mc8_sh4;
+    c->put_h264_chroma_pixels_tab[1]= put_h264_chroma_mc4_sh4;
+    c->put_h264_chroma_pixels_tab[2]= put_h264_chroma_mc2_sh4;
+    c->avg_h264_chroma_pixels_tab[0]= avg_h264_chroma_mc8_sh4;
+    c->avg_h264_chroma_pixels_tab[1]= avg_h264_chroma_mc4_sh4;
+    c->avg_h264_chroma_pixels_tab[2]= avg_h264_chroma_mc2_sh4;
+    }
+}
diff --git a/libavcodec/sh4/idct_sh4.c b/libavcodec/sh4/idct_sh4.c
index e54c330..d4e8711 100644
--- a/libavcodec/sh4/idct_sh4.c
+++ b/libavcodec/sh4/idct_sh4.c
@@ -20,7 +20,6 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavcodec/dsputil.h"
 #include "dsputil_sh4.h"
 #include "sh4.h"
 
@@ -89,7 +88,7 @@
 
 //optimized
 
-void ff_idct_sh4(DCTELEM *block)
+void ff_idct_sh4(int16_t *block)
 {
         DEFREG;
 
diff --git a/libavcodec/sh4/qpel.c b/libavcodec/sh4/qpel.c
index 5ad0290..1a5a4cd 100644
--- a/libavcodec/sh4/qpel.c
+++ b/libavcodec/sh4/qpel.c
@@ -22,6 +22,8 @@
  */
 
 #include "libavutil/common.h"
+#include "libavcodec/copy_block.h"
+#include "libavcodec/rnd_avg.h"
 
 #define PIXOP2(OPNAME, OP) \
 \
@@ -359,154 +361,6 @@
     }while(--h);
 }
 
-static void gmc_c(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)
-{
-    int y, vx, vy;
-    const int s= 1<<shift;
-
-    width--;
-    height--;
-
-    for(y=0; y<h; y++){
-        int x;
-
-        vx= ox;
-        vy= oy;
-        for(x=0; x<8; x++){ //XXX FIXME optimize
-            int src_x, src_y, frac_x, frac_y, index;
-
-            src_x= vx>>16;
-            src_y= vy>>16;
-            frac_x= src_x&(s-1);
-            frac_y= src_y&(s-1);
-            src_x>>=shift;
-            src_y>>=shift;
-
-            if((unsigned)src_x < width){
-                if((unsigned)src_y < height){
-                    index= src_x + src_y*stride;
-                    dst[y*stride + x]= (  (  src[index         ]*(s-frac_x)
-                                           + src[index       +1]*   frac_x )*(s-frac_y)
-                                        + (  src[index+stride  ]*(s-frac_x)
-                                           + src[index+stride+1]*   frac_x )*   frac_y
-                                        + r)>>(shift*2);
-                }else{
-                    index= src_x + av_clip(src_y, 0, height)*stride;
-                    dst[y*stride + x]= ( (  src[index         ]*(s-frac_x)
-                                          + src[index       +1]*   frac_x )*s
-                                        + r)>>(shift*2);
-                }
-            }else{
-                if((unsigned)src_y < height){
-                    index= av_clip(src_x, 0, width) + src_y*stride;
-                    dst[y*stride + x]= (  (  src[index         ]*(s-frac_y)
-                                           + src[index+stride  ]*   frac_y )*s
-                                        + r)>>(shift*2);
-                }else{
-                    index= av_clip(src_x, 0, width) + av_clip(src_y, 0, height)*stride;
-                    dst[y*stride + x]=    src[index         ];
-                }
-            }
-
-            vx+= dxx;
-            vy+= dyx;
-        }
-        ox += dxy;
-        oy += dyy;
-    }
-}
-#define H264_CHROMA_MC(OPNAME, OP)\
-static void OPNAME ## h264_chroma_mc2_sh4(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);\
-    \
-    assert(x<8 && y<8 && x>=0 && y>=0);\
-\
-    do {\
-        int t0,t1,t2,t3; \
-        uint8_t *s0 = src; \
-        uint8_t *s1 = src+stride; \
-        t0 = *s0++; t2 = *s1++; \
-        t1 = *s0++; t3 = *s1++; \
-        OP(dst[0], (A*t0 + B*t1 + C*t2 + D*t3));\
-        t0 = *s0++; t2 = *s1++; \
-        OP(dst[1], (A*t1 + B*t0 + C*t3 + D*t2));\
-        dst+= stride;\
-        src+= stride;\
-    }while(--h);\
-}\
-\
-static void OPNAME ## h264_chroma_mc4_sh4(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);\
-    \
-    assert(x<8 && y<8 && x>=0 && y>=0);\
-\
-    do {\
-        int t0,t1,t2,t3; \
-        uint8_t *s0 = src; \
-        uint8_t *s1 = src+stride; \
-        t0 = *s0++; t2 = *s1++; \
-        t1 = *s0++; t3 = *s1++; \
-        OP(dst[0], (A*t0 + B*t1 + C*t2 + D*t3));\
-        t0 = *s0++; t2 = *s1++; \
-        OP(dst[1], (A*t1 + B*t0 + C*t3 + D*t2));\
-        t1 = *s0++; t3 = *s1++; \
-        OP(dst[2], (A*t0 + B*t1 + C*t2 + D*t3));\
-        t0 = *s0++; t2 = *s1++; \
-        OP(dst[3], (A*t1 + B*t0 + C*t3 + D*t2));\
-        dst+= stride;\
-        src+= stride;\
-    }while(--h);\
-}\
-\
-static void OPNAME ## h264_chroma_mc8_sh4(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);\
-    \
-    assert(x<8 && y<8 && x>=0 && y>=0);\
-\
-    do {\
-        int t0,t1,t2,t3; \
-        uint8_t *s0 = src; \
-        uint8_t *s1 = src+stride; \
-        t0 = *s0++; t2 = *s1++; \
-        t1 = *s0++; t3 = *s1++; \
-        OP(dst[0], (A*t0 + B*t1 + C*t2 + D*t3));\
-        t0 = *s0++; t2 = *s1++; \
-        OP(dst[1], (A*t1 + B*t0 + C*t3 + D*t2));\
-        t1 = *s0++; t3 = *s1++; \
-        OP(dst[2], (A*t0 + B*t1 + C*t2 + D*t3));\
-        t0 = *s0++; t2 = *s1++; \
-        OP(dst[3], (A*t1 + B*t0 + C*t3 + D*t2));\
-        t1 = *s0++; t3 = *s1++; \
-        OP(dst[4], (A*t0 + B*t1 + C*t2 + D*t3));\
-        t0 = *s0++; t2 = *s1++; \
-        OP(dst[5], (A*t1 + B*t0 + C*t3 + D*t2));\
-        t1 = *s0++; t3 = *s1++; \
-        OP(dst[6], (A*t0 + B*t1 + C*t2 + D*t3));\
-        t0 = *s0++; t2 = *s1++; \
-        OP(dst[7], (A*t1 + B*t0 + C*t3 + D*t2));\
-        dst+= stride;\
-        src+= stride;\
-    }while(--h);\
-}
-
-#define op_avg(a, b) a = (((a)+(((b) + 32)>>6)+1)>>1)
-#define op_put(a, b) a = (((b) + 32)>>6)
-
-H264_CHROMA_MC(put_       , op_put)
-H264_CHROMA_MC(avg_       , op_avg)
-#undef op_avg
-#undef op_put
-
 #define QPEL_MC(r, OPNAME, RND, OP) \
 static void OPNAME ## mpeg4_qpel8_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h){\
     uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
@@ -899,407 +753,6 @@
 #undef op_put
 #undef op_put_no_rnd
 
-#define H264_LOWPASS(OPNAME, OP, OP2) \
-static inline void OPNAME ## h264_qpel_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride,int w,int h){\
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
-    do {\
-        int srcB,srcA,src0,src1,src2,src3,src4,src5,src6;\
-        uint8_t *s = src-2;\
-        srcB = *s++;\
-        srcA = *s++;\
-        src0 = *s++;\
-        src1 = *s++;\
-        src2 = *s++;\
-        src3 = *s++;\
-        OP(dst[0], (src0+src1)*20 - (srcA+src2)*5 + (srcB+src3));\
-        src4 = *s++;\
-        OP(dst[1], (src1+src2)*20 - (src0+src3)*5 + (srcA+src4));\
-        src5 = *s++;\
-        OP(dst[2], (src2+src3)*20 - (src1+src4)*5 + (src0+src5));\
-        src6 = *s++;\
-        OP(dst[3], (src3+src4)*20 - (src2+src5)*5 + (src1+src6));\
-      if (w>4) { /* it optimized */ \
-        int src7,src8,src9,src10; \
-        src7 = *s++;\
-        OP(dst[4], (src4+src5)*20 - (src3+src6)*5 + (src2+src7));\
-        src8 = *s++;\
-        OP(dst[5], (src5+src6)*20 - (src4+src7)*5 + (src3+src8));\
-        src9 = *s++;\
-        OP(dst[6], (src6+src7)*20 - (src5+src8)*5 + (src4+src9));\
-        src10 = *s++;\
-        OP(dst[7], (src7+src8)*20 - (src6+src9)*5 + (src5+src10));\
-       if (w>8) { \
-        int src11,src12,src13,src14,src15,src16,src17,src18; \
-        src11 = *s++;\
-        OP(dst[8] , (src8 +src9 )*20 - (src7 +src10)*5 + (src6 +src11));\
-        src12 = *s++;\
-        OP(dst[9] , (src9 +src10)*20 - (src8 +src11)*5 + (src7 +src12));\
-        src13 = *s++;\
-        OP(dst[10], (src10+src11)*20 - (src9 +src12)*5 + (src8 +src13));\
-        src14 = *s++;\
-        OP(dst[11], (src11+src12)*20 - (src10+src13)*5 + (src9 +src14));\
-        src15 = *s++;\
-        OP(dst[12], (src12+src13)*20 - (src11+src14)*5 + (src10+src15));\
-        src16 = *s++;\
-        OP(dst[13], (src13+src14)*20 - (src12+src15)*5 + (src11+src16));\
-        src17 = *s++;\
-        OP(dst[14], (src14+src15)*20 - (src13+src16)*5 + (src12+src17));\
-        src18 = *s++;\
-        OP(dst[15], (src15+src16)*20 - (src14+src17)*5 + (src13+src18));\
-       } \
-      } \
-        dst+=dstStride;\
-        src+=srcStride;\
-    }while(--h);\
-}\
-\
-static inline void OPNAME ## h264_qpel_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride,int w,int h){\
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
-    do{\
-        int srcB,srcA,src0,src1,src2,src3,src4,src5,src6;\
-        uint8_t *s = src-2*srcStride,*d=dst;\
-        srcB = *s; s+=srcStride;\
-        srcA = *s; s+=srcStride;\
-        src0 = *s; s+=srcStride;\
-        src1 = *s; s+=srcStride;\
-        src2 = *s; s+=srcStride;\
-        src3 = *s; s+=srcStride;\
-        OP(*d, (src0+src1)*20 - (srcA+src2)*5 + (srcB+src3));d+=dstStride;\
-        src4 = *s; s+=srcStride;\
-        OP(*d, (src1+src2)*20 - (src0+src3)*5 + (srcA+src4));d+=dstStride;\
-        src5 = *s; s+=srcStride;\
-        OP(*d, (src2+src3)*20 - (src1+src4)*5 + (src0+src5));d+=dstStride;\
-        src6 = *s; s+=srcStride;\
-        OP(*d, (src3+src4)*20 - (src2+src5)*5 + (src1+src6));d+=dstStride;\
-      if (h>4) { \
-        int src7,src8,src9,src10; \
-        src7 = *s; s+=srcStride;\
-        OP(*d, (src4+src5)*20 - (src3+src6)*5 + (src2+src7));d+=dstStride;\
-        src8 = *s; s+=srcStride;\
-        OP(*d, (src5+src6)*20 - (src4+src7)*5 + (src3+src8));d+=dstStride;\
-        src9 = *s; s+=srcStride;\
-        OP(*d, (src6+src7)*20 - (src5+src8)*5 + (src4+src9));d+=dstStride;\
-        src10 = *s; s+=srcStride;\
-        OP(*d, (src7+src8)*20 - (src6+src9)*5 + (src5+src10));d+=dstStride;\
-       if (h>8) { \
-        int src11,src12,src13,src14,src15,src16,src17,src18; \
-        src11 = *s; s+=srcStride;\
-        OP(*d , (src8 +src9 )*20 - (src7 +src10)*5 + (src6 +src11));d+=dstStride;\
-        src12 = *s; s+=srcStride;\
-        OP(*d , (src9 +src10)*20 - (src8 +src11)*5 + (src7 +src12));d+=dstStride;\
-        src13 = *s; s+=srcStride;\
-        OP(*d, (src10+src11)*20 - (src9 +src12)*5 + (src8 +src13));d+=dstStride;\
-        src14 = *s; s+=srcStride;\
-        OP(*d, (src11+src12)*20 - (src10+src13)*5 + (src9 +src14));d+=dstStride;\
-        src15 = *s; s+=srcStride;\
-        OP(*d, (src12+src13)*20 - (src11+src14)*5 + (src10+src15));d+=dstStride;\
-        src16 = *s; s+=srcStride;\
-        OP(*d, (src13+src14)*20 - (src12+src15)*5 + (src11+src16));d+=dstStride;\
-        src17 = *s; s+=srcStride;\
-        OP(*d, (src14+src15)*20 - (src13+src16)*5 + (src12+src17));d+=dstStride;\
-        src18 = *s; s+=srcStride;\
-        OP(*d, (src15+src16)*20 - (src14+src17)*5 + (src13+src18));d+=dstStride;\
-       } \
-      } \
-        dst++;\
-        src++;\
-    }while(--w);\
-}\
-\
-static inline void OPNAME ## h264_qpel_hv_lowpass(uint8_t *dst, int16_t *tmp, uint8_t *src, int dstStride, int tmpStride, int srcStride,int w,int h){\
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
-    int i;\
-    src -= 2*srcStride;\
-    i= h+5; \
-    do {\
-        int srcB,srcA,src0,src1,src2,src3,src4,src5,src6;\
-        uint8_t *s = src-2;\
-        srcB = *s++;\
-        srcA = *s++;\
-        src0 = *s++;\
-        src1 = *s++;\
-        src2 = *s++;\
-        src3 = *s++;\
-        tmp[0] = ((src0+src1)*20 - (srcA+src2)*5 + (srcB+src3));\
-        src4 = *s++;\
-        tmp[1] = ((src1+src2)*20 - (src0+src3)*5 + (srcA+src4));\
-        src5 = *s++;\
-        tmp[2] = ((src2+src3)*20 - (src1+src4)*5 + (src0+src5));\
-        src6 = *s++;\
-        tmp[3] = ((src3+src4)*20 - (src2+src5)*5 + (src1+src6));\
-      if (w>4) { /* it optimized */ \
-        int src7,src8,src9,src10; \
-        src7 = *s++;\
-        tmp[4] = ((src4+src5)*20 - (src3+src6)*5 + (src2+src7));\
-        src8 = *s++;\
-        tmp[5] = ((src5+src6)*20 - (src4+src7)*5 + (src3+src8));\
-        src9 = *s++;\
-        tmp[6] = ((src6+src7)*20 - (src5+src8)*5 + (src4+src9));\
-        src10 = *s++;\
-        tmp[7] = ((src7+src8)*20 - (src6+src9)*5 + (src5+src10));\
-       if (w>8) { \
-        int src11,src12,src13,src14,src15,src16,src17,src18; \
-        src11 = *s++;\
-        tmp[8] = ((src8 +src9 )*20 - (src7 +src10)*5 + (src6 +src11));\
-        src12 = *s++;\
-        tmp[9] = ((src9 +src10)*20 - (src8 +src11)*5 + (src7 +src12));\
-        src13 = *s++;\
-        tmp[10] = ((src10+src11)*20 - (src9 +src12)*5 + (src8 +src13));\
-        src14 = *s++;\
-        tmp[11] = ((src11+src12)*20 - (src10+src13)*5 + (src9 +src14));\
-        src15 = *s++;\
-        tmp[12] = ((src12+src13)*20 - (src11+src14)*5 + (src10+src15));\
-        src16 = *s++;\
-        tmp[13] = ((src13+src14)*20 - (src12+src15)*5 + (src11+src16));\
-        src17 = *s++;\
-        tmp[14] = ((src14+src15)*20 - (src13+src16)*5 + (src12+src17));\
-        src18 = *s++;\
-        tmp[15] = ((src15+src16)*20 - (src14+src17)*5 + (src13+src18));\
-       } \
-      } \
-        tmp+=tmpStride;\
-        src+=srcStride;\
-    }while(--i);\
-    tmp -= tmpStride*(h+5-2);\
-    i = w; \
-    do {\
-        int tmpB,tmpA,tmp0,tmp1,tmp2,tmp3,tmp4,tmp5,tmp6;\
-        int16_t *s = tmp-2*tmpStride; \
-        uint8_t *d=dst;\
-        tmpB = *s; s+=tmpStride;\
-        tmpA = *s; s+=tmpStride;\
-        tmp0 = *s; s+=tmpStride;\
-        tmp1 = *s; s+=tmpStride;\
-        tmp2 = *s; s+=tmpStride;\
-        tmp3 = *s; s+=tmpStride;\
-        OP2(*d, (tmp0+tmp1)*20 - (tmpA+tmp2)*5 + (tmpB+tmp3));d+=dstStride;\
-        tmp4 = *s; s+=tmpStride;\
-        OP2(*d, (tmp1+tmp2)*20 - (tmp0+tmp3)*5 + (tmpA+tmp4));d+=dstStride;\
-        tmp5 = *s; s+=tmpStride;\
-        OP2(*d, (tmp2+tmp3)*20 - (tmp1+tmp4)*5 + (tmp0+tmp5));d+=dstStride;\
-        tmp6 = *s; s+=tmpStride;\
-        OP2(*d, (tmp3+tmp4)*20 - (tmp2+tmp5)*5 + (tmp1+tmp6));d+=dstStride;\
-      if (h>4) { \
-        int tmp7,tmp8,tmp9,tmp10; \
-        tmp7 = *s; s+=tmpStride;\
-        OP2(*d, (tmp4+tmp5)*20 - (tmp3+tmp6)*5 + (tmp2+tmp7));d+=dstStride;\
-        tmp8 = *s; s+=tmpStride;\
-        OP2(*d, (tmp5+tmp6)*20 - (tmp4+tmp7)*5 + (tmp3+tmp8));d+=dstStride;\
-        tmp9 = *s; s+=tmpStride;\
-        OP2(*d, (tmp6+tmp7)*20 - (tmp5+tmp8)*5 + (tmp4+tmp9));d+=dstStride;\
-        tmp10 = *s; s+=tmpStride;\
-        OP2(*d, (tmp7+tmp8)*20 - (tmp6+tmp9)*5 + (tmp5+tmp10));d+=dstStride;\
-       if (h>8) { \
-        int tmp11,tmp12,tmp13,tmp14,tmp15,tmp16,tmp17,tmp18; \
-        tmp11 = *s; s+=tmpStride;\
-        OP2(*d , (tmp8 +tmp9 )*20 - (tmp7 +tmp10)*5 + (tmp6 +tmp11));d+=dstStride;\
-        tmp12 = *s; s+=tmpStride;\
-        OP2(*d , (tmp9 +tmp10)*20 - (tmp8 +tmp11)*5 + (tmp7 +tmp12));d+=dstStride;\
-        tmp13 = *s; s+=tmpStride;\
-        OP2(*d, (tmp10+tmp11)*20 - (tmp9 +tmp12)*5 + (tmp8 +tmp13));d+=dstStride;\
-        tmp14 = *s; s+=tmpStride;\
-        OP2(*d, (tmp11+tmp12)*20 - (tmp10+tmp13)*5 + (tmp9 +tmp14));d+=dstStride;\
-        tmp15 = *s; s+=tmpStride;\
-        OP2(*d, (tmp12+tmp13)*20 - (tmp11+tmp14)*5 + (tmp10+tmp15));d+=dstStride;\
-        tmp16 = *s; s+=tmpStride;\
-        OP2(*d, (tmp13+tmp14)*20 - (tmp12+tmp15)*5 + (tmp11+tmp16));d+=dstStride;\
-        tmp17 = *s; s+=tmpStride;\
-        OP2(*d, (tmp14+tmp15)*20 - (tmp13+tmp16)*5 + (tmp12+tmp17));d+=dstStride;\
-        tmp18 = *s; s+=tmpStride;\
-        OP2(*d, (tmp15+tmp16)*20 - (tmp14+tmp17)*5 + (tmp13+tmp18));d+=dstStride;\
-       } \
-      } \
-        dst++;\
-        tmp++;\
-    }while(--i);\
-}\
-\
-static void OPNAME ## h264_qpel4_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\
-    OPNAME ## h264_qpel_h_lowpass(dst,src,dstStride,srcStride,4,4); \
-}\
-static void OPNAME ## h264_qpel8_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\
-   OPNAME ## h264_qpel_h_lowpass(dst,src,dstStride,srcStride,8,8); \
-}\
-static void OPNAME ## h264_qpel16_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\
-   OPNAME ## h264_qpel_h_lowpass(dst,src,dstStride,srcStride,16,16); \
-}\
-\
-static void OPNAME ## h264_qpel4_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\
-   OPNAME ## h264_qpel_v_lowpass(dst,src,dstStride,srcStride,4,4); \
-}\
-static void OPNAME ## h264_qpel8_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\
-   OPNAME ## h264_qpel_v_lowpass(dst,src,dstStride,srcStride,8,8); \
-}\
-static void OPNAME ## h264_qpel16_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\
-   OPNAME ## h264_qpel_v_lowpass(dst,src,dstStride,srcStride,16,16); \
-}\
-static void OPNAME ## h264_qpel4_hv_lowpass(uint8_t *dst, int16_t *tmp, uint8_t *src, int dstStride, int tmpStride, int srcStride){\
-   OPNAME ## h264_qpel_hv_lowpass(dst,tmp,src,dstStride,tmpStride,srcStride,4,4); \
-}\
-static void OPNAME ## h264_qpel8_hv_lowpass(uint8_t *dst, int16_t *tmp, uint8_t *src, int dstStride, int tmpStride, int srcStride){\
-   OPNAME ## h264_qpel_hv_lowpass(dst,tmp,src,dstStride,tmpStride,srcStride,8,8); \
-}\
-static void OPNAME ## h264_qpel16_hv_lowpass(uint8_t *dst, int16_t *tmp, uint8_t *src, int dstStride, int tmpStride, int srcStride){\
-   OPNAME ## h264_qpel_hv_lowpass(dst,tmp,src,dstStride,tmpStride,srcStride,16,16); \
-}\
-
-#define H264_MC(OPNAME, SIZE) \
-static void OPNAME ## h264_qpel ## SIZE ## _mc00_sh4 (uint8_t *dst, uint8_t *src, int stride){\
-    OPNAME ## pixels ## SIZE ## _c(dst, src, stride, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc10_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t half[SIZE*SIZE];\
-    put_h264_qpel ## SIZE ## _h_lowpass(half, src, SIZE, stride);\
-    OPNAME ## pixels ## SIZE ## _l2_aligned2(dst, src, half, stride, stride, SIZE, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc20_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    OPNAME ## h264_qpel ## SIZE ## _h_lowpass(dst, src, stride, stride);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc30_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t half[SIZE*SIZE];\
-    put_h264_qpel ## SIZE ## _h_lowpass(half, src, SIZE, stride);\
-    OPNAME ## pixels ## SIZE ## _l2_aligned2(dst, src+1, half, stride, stride, SIZE, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc01_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[SIZE*(SIZE+5)];\
-    uint8_t * const full_mid= full + SIZE*2;\
-    uint8_t half[SIZE*SIZE];\
-    copy_block ## SIZE (full, src - stride*2, SIZE,  stride, SIZE + 5);\
-    put_h264_qpel ## SIZE ## _v_lowpass(half, full_mid, SIZE, SIZE);\
-    OPNAME ## pixels ## SIZE ## _l2_aligned(dst, full_mid, half, stride, SIZE, SIZE, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc02_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[SIZE*(SIZE+5)];\
-    uint8_t * const full_mid= full + SIZE*2;\
-    copy_block ## SIZE (full, src - stride*2, SIZE,  stride, SIZE + 5);\
-    OPNAME ## h264_qpel ## SIZE ## _v_lowpass(dst, full_mid, stride, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc03_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[SIZE*(SIZE+5)];\
-    uint8_t * const full_mid= full + SIZE*2;\
-    uint8_t half[SIZE*SIZE];\
-    copy_block ## SIZE (full, src - stride*2, SIZE,  stride, SIZE + 5);\
-    put_h264_qpel ## SIZE ## _v_lowpass(half, full_mid, SIZE, SIZE);\
-    OPNAME ## pixels ## SIZE ## _l2_aligned(dst, full_mid+SIZE, half, stride, SIZE, SIZE, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc11_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[SIZE*(SIZE+5)];\
-    uint8_t * const full_mid= full + SIZE*2;\
-    uint8_t halfH[SIZE*SIZE];\
-    uint8_t halfV[SIZE*SIZE];\
-    put_h264_qpel ## SIZE ## _h_lowpass(halfH, src, SIZE, stride);\
-    copy_block ## SIZE (full, src - stride*2, SIZE,  stride, SIZE + 5);\
-    put_h264_qpel ## SIZE ## _v_lowpass(halfV, full_mid, SIZE, SIZE);\
-    OPNAME ## pixels ## SIZE ## _l2_aligned(dst, halfH, halfV, stride, SIZE, SIZE, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc31_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[SIZE*(SIZE+5)];\
-    uint8_t * const full_mid= full + SIZE*2;\
-    uint8_t halfH[SIZE*SIZE];\
-    uint8_t halfV[SIZE*SIZE];\
-    put_h264_qpel ## SIZE ## _h_lowpass(halfH, src, SIZE, stride);\
-    copy_block ## SIZE (full, src - stride*2 + 1, SIZE,  stride, SIZE + 5);\
-    put_h264_qpel ## SIZE ## _v_lowpass(halfV, full_mid, SIZE, SIZE);\
-    OPNAME ## pixels ## SIZE ## _l2_aligned(dst, halfH, halfV, stride, SIZE, SIZE, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc13_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[SIZE*(SIZE+5)];\
-    uint8_t * const full_mid= full + SIZE*2;\
-    uint8_t halfH[SIZE*SIZE];\
-    uint8_t halfV[SIZE*SIZE];\
-    put_h264_qpel ## SIZE ## _h_lowpass(halfH, src + stride, SIZE, stride);\
-    copy_block ## SIZE (full, src - stride*2, SIZE,  stride, SIZE + 5);\
-    put_h264_qpel ## SIZE ## _v_lowpass(halfV, full_mid, SIZE, SIZE);\
-    OPNAME ## pixels ## SIZE ## _l2_aligned(dst, halfH, halfV, stride, SIZE, SIZE, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc33_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[SIZE*(SIZE+5)];\
-    uint8_t * const full_mid= full + SIZE*2;\
-    uint8_t halfH[SIZE*SIZE];\
-    uint8_t halfV[SIZE*SIZE];\
-    put_h264_qpel ## SIZE ## _h_lowpass(halfH, src + stride, SIZE, stride);\
-    copy_block ## SIZE (full, src - stride*2 + 1, SIZE,  stride, SIZE + 5);\
-    put_h264_qpel ## SIZE ## _v_lowpass(halfV, full_mid, SIZE, SIZE);\
-    OPNAME ## pixels ## SIZE ## _l2_aligned(dst, halfH, halfV, stride, SIZE, SIZE, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc22_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    int16_t tmp[SIZE*(SIZE+5)];\
-    OPNAME ## h264_qpel ## SIZE ## _hv_lowpass(dst, tmp, src, stride, SIZE, stride);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc21_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    int16_t tmp[SIZE*(SIZE+5)];\
-    uint8_t halfH[SIZE*SIZE];\
-    uint8_t halfHV[SIZE*SIZE];\
-    put_h264_qpel ## SIZE ## _h_lowpass(halfH, src, SIZE, stride);\
-    put_h264_qpel ## SIZE ## _hv_lowpass(halfHV, tmp, src, SIZE, SIZE, stride);\
-    OPNAME ## pixels ## SIZE ## _l2_aligned(dst, halfH, halfHV, stride, SIZE, SIZE, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc23_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    int16_t tmp[SIZE*(SIZE+5)];\
-    uint8_t halfH[SIZE*SIZE];\
-    uint8_t halfHV[SIZE*SIZE];\
-    put_h264_qpel ## SIZE ## _h_lowpass(halfH, src + stride, SIZE, stride);\
-    put_h264_qpel ## SIZE ## _hv_lowpass(halfHV, tmp, src, SIZE, SIZE, stride);\
-    OPNAME ## pixels ## SIZE ## _l2_aligned(dst, halfH, halfHV, stride, SIZE, SIZE, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc12_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[SIZE*(SIZE+5)];\
-    uint8_t * const full_mid= full + SIZE*2;\
-    int16_t tmp[SIZE*(SIZE+5)];\
-    uint8_t halfV[SIZE*SIZE];\
-    uint8_t halfHV[SIZE*SIZE];\
-    copy_block ## SIZE (full, src - stride*2, SIZE,  stride, SIZE + 5);\
-    put_h264_qpel ## SIZE ## _v_lowpass(halfV, full_mid, SIZE, SIZE);\
-    put_h264_qpel ## SIZE ## _hv_lowpass(halfHV, tmp, src, SIZE, SIZE, stride);\
-    OPNAME ## pixels ## SIZE ## _l2_aligned(dst, halfV, halfHV, stride, SIZE, SIZE, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc32_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[SIZE*(SIZE+5)];\
-    uint8_t * const full_mid= full + SIZE*2;\
-    int16_t tmp[SIZE*(SIZE+5)];\
-    uint8_t halfV[SIZE*SIZE];\
-    uint8_t halfHV[SIZE*SIZE];\
-    copy_block ## SIZE (full, src - stride*2 + 1, SIZE,  stride, SIZE + 5);\
-    put_h264_qpel ## SIZE ## _v_lowpass(halfV, full_mid, SIZE, SIZE);\
-    put_h264_qpel ## SIZE ## _hv_lowpass(halfHV, tmp, src, SIZE, SIZE, stride);\
-    OPNAME ## pixels ## SIZE ## _l2_aligned(dst, halfV, halfHV, stride, SIZE, SIZE, SIZE);\
-}\
-
-#define op_avg(a, b)  a = (((a)+cm[((b) + 16)>>5]+1)>>1)
-//#define op_avg2(a, b) a = (((a)*w1+cm[((b) + 16)>>5]*w2 + o + 64)>>7)
-#define op_put(a, b)  a = cm[((b) + 16)>>5]
-#define op2_avg(a, b)  a = (((a)+cm[((b) + 512)>>10]+1)>>1)
-#define op2_put(a, b)  a = cm[((b) + 512)>>10]
-
-H264_LOWPASS(put_       , op_put, op2_put)
-H264_LOWPASS(avg_       , op_avg, op2_avg)
-H264_MC(put_, 4)
-H264_MC(put_, 8)
-H264_MC(put_, 16)
-H264_MC(avg_, 4)
-H264_MC(avg_, 8)
-H264_MC(avg_, 16)
-
-#undef op_avg
-#undef op_put
-#undef op2_avg
-#undef op2_put
-
 static void wmv2_mspel8_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h){
     uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
 
diff --git a/libavcodec/shorten.c b/libavcodec/shorten.c
index da5a2b4..648df68 100644
--- a/libavcodec/shorten.c
+++ b/libavcodec/shorten.c
@@ -31,6 +31,7 @@
 #include "bytestream.h"
 #include "get_bits.h"
 #include "golomb.h"
+#include "internal.h"
 
 #define MAX_CHANNELS 8
 #define MAX_BLOCKSIZE 65535
@@ -83,7 +84,6 @@
 
 typedef struct ShortenContext {
     AVCodecContext *avctx;
-    AVFrame frame;
     GetBitContext gb;
 
     int min_framesize, max_framesize;
@@ -117,9 +117,6 @@
     ShortenContext *s = avctx->priv_data;
     s->avctx = avctx;
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     return 0;
 }
 
@@ -342,6 +339,7 @@
     s->channels = get_uint(s, CHANSIZE);
     if (s->channels <= 0 || s->channels > MAX_CHANNELS) {
         av_log(s->avctx, AV_LOG_ERROR, "too many channels: %d\n", s->channels);
+        s->channels = 0;
         return AVERROR_INVALIDDATA;
     }
     s->avctx->channels = s->channels;
@@ -351,7 +349,7 @@
         int skip_bytes, blocksize;
 
         blocksize = get_uint(s, av_log2(DEFAULT_BLOCK_SIZE));
-        if (!blocksize || blocksize > MAX_BLOCKSIZE) {
+        if (!blocksize || blocksize > (unsigned)MAX_BLOCKSIZE) {
             av_log(s->avctx, AV_LOG_ERROR, "invalid or unsupported block size: %d\n",
                    blocksize);
             return AVERROR(EINVAL);
@@ -405,6 +403,7 @@
 static int shorten_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;
     ShortenContext *s = avctx->priv_data;
@@ -466,7 +465,7 @@
 
     s->cur_chan = 0;
     while (s->cur_chan < s->channels) {
-        unsigned int cmd;
+        unsigned cmd;
         int len;
 
         if (get_bits_left(&s->gb) < 3+FNSIZE) {
@@ -500,7 +499,7 @@
                         av_log(avctx, AV_LOG_ERROR, "Increasing block size is not supported\n");
                         return AVERROR_PATCHWELCOME;
                     }
-                    if (!blocksize || blocksize > MAX_BLOCKSIZE) {
+                    if (!blocksize || blocksize > (unsigned)MAX_BLOCKSIZE) {
                         av_log(avctx, AV_LOG_ERROR, "invalid or unsupported "
                                "block size: %d\n", blocksize);
                         return AVERROR(EINVAL);
@@ -525,7 +524,8 @@
             /* get Rice code for residual decoding */
             if (cmd != FN_ZERO) {
                 residual_size = get_ur_golomb_shorten(&s->gb, ENERGYSIZE);
-                /* this is a hack as version 0 differed in definition of get_sr_golomb_shorten */
+                /* This is a hack as version 0 differed in the definition
+                 * of get_sr_golomb_shorten(). */
                 if (s->version == 0)
                     residual_size--;
             }
@@ -582,15 +582,15 @@
                 int chan;
 
                 /* get output buffer */
-                s->frame.nb_samples = s->blocksize;
-                if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+                frame->nb_samples = s->blocksize;
+                if ((ret = ff_get_buffer(avctx, frame)) < 0) {
                     av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
                     return ret;
                 }
 
                 for (chan = 0; chan < s->channels; chan++) {
-                    samples_u8  = ((uint8_t **)s->frame.extended_data)[chan];
-                    samples_s16 = ((int16_t **)s->frame.extended_data)[chan];
+                    samples_u8  = ((uint8_t **)frame->extended_data)[chan];
+                    samples_s16 = ((int16_t **)frame->extended_data)[chan];
                     for (i = 0; i < s->blocksize; i++) {
                         switch (s->internal_ftype) {
                         case TYPE_U8:
@@ -604,9 +604,7 @@
                     }
                 }
 
-
-                *got_frame_ptr   = 1;
-                *(AVFrame *)data = s->frame;
+                *got_frame_ptr = 1;
             }
         }
     }
diff --git a/libavcodec/simple_idct.c b/libavcodec/simple_idct.c
index 2931850..d204565 100644
--- a/libavcodec/simple_idct.c
+++ b/libavcodec/simple_idct.c
@@ -27,7 +27,6 @@
 
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
-#include "dsputil.h"
 #include "mathops.h"
 #include "simple_idct.h"
 
@@ -50,7 +49,7 @@
    and the butterfly must be multiplied by 0.5 * sqrt(2.0) */
 #define C_SHIFT (4+1+12)
 
-static inline void idct4col_put(uint8_t *dest, int line_size, const DCTELEM *col)
+static inline void idct4col_put(uint8_t *dest, int line_size, const int16_t *col)
 {
     int c0, c1, c2, c3, a0, a1, a2, a3;
 
@@ -86,10 +85,10 @@
 /* XXX: I think a 1.0/sqrt(2) normalization should be needed to
    compensate the extra butterfly stage - I don't have the full DV
    specification */
-void ff_simple_idct248_put(uint8_t *dest, int line_size, DCTELEM *block)
+void ff_simple_idct248_put(uint8_t *dest, int line_size, int16_t *block)
 {
     int i;
-    DCTELEM *ptr;
+    int16_t *ptr;
 
     /* butterfly */
     ptr = block;
@@ -129,7 +128,7 @@
 #define C2 C_FIX(0.2705980501)
 #define C3 C_FIX(0.5)
 #define C_SHIFT (4+1+12)
-static inline void idct4col_add(uint8_t *dest, int line_size, const DCTELEM *col)
+static inline void idct4col_add(uint8_t *dest, int line_size, const int16_t *col)
 {
     int c0, c1, c2, c3, a0, a1, a2, a3;
 
@@ -156,7 +155,7 @@
 #define R2 R_FIX(0.2705980501)
 #define R3 R_FIX(0.5)
 #define R_SHIFT 11
-static inline void idct4row(DCTELEM *row)
+static inline void idct4row(int16_t *row)
 {
     int c0, c1, c2, c3, a0, a1, a2, a3;
 
@@ -174,7 +173,7 @@
     row[3]= (c0 - c1) >> R_SHIFT;
 }
 
-void ff_simple_idct84_add(uint8_t *dest, int line_size, DCTELEM *block)
+void ff_simple_idct84_add(uint8_t *dest, int line_size, int16_t *block)
 {
     int i;
 
@@ -189,7 +188,7 @@
     }
 }
 
-void ff_simple_idct48_add(uint8_t *dest, int line_size, DCTELEM *block)
+void ff_simple_idct48_add(uint8_t *dest, int line_size, int16_t *block)
 {
     int i;
 
@@ -204,7 +203,7 @@
     }
 }
 
-void ff_simple_idct44_add(uint8_t *dest, int line_size, DCTELEM *block)
+void ff_simple_idct44_add(uint8_t *dest, int line_size, int16_t *block)
 {
     int i;
 
@@ -219,7 +218,7 @@
     }
 }
 
-void ff_prores_idct(DCTELEM *block, const int16_t *qmat)
+void ff_prores_idct(int16_t *block, const int16_t *qmat)
 {
     int i;
 
diff --git a/libavcodec/simple_idct.h b/libavcodec/simple_idct.h
index 64d3c2a..3fec5e0 100644
--- a/libavcodec/simple_idct.h
+++ b/libavcodec/simple_idct.h
@@ -29,30 +29,29 @@
 #define AVCODEC_SIMPLE_IDCT_H
 
 #include <stdint.h>
-#include "dsputil.h"
 
-void ff_simple_idct_put_8(uint8_t *dest, int line_size, DCTELEM *block);
-void ff_simple_idct_add_8(uint8_t *dest, int line_size, DCTELEM *block);
-void ff_simple_idct_8(DCTELEM *block);
+void ff_simple_idct_put_8(uint8_t *dest, int line_size, int16_t *block);
+void ff_simple_idct_add_8(uint8_t *dest, int line_size, int16_t *block);
+void ff_simple_idct_8(int16_t *block);
 
-void ff_simple_idct_put_10(uint8_t *dest, int line_size, DCTELEM *block);
-void ff_simple_idct_add_10(uint8_t *dest, int line_size, DCTELEM *block);
-void ff_simple_idct_10(DCTELEM *block);
+void ff_simple_idct_put_10(uint8_t *dest, int line_size, int16_t *block);
+void ff_simple_idct_add_10(uint8_t *dest, int line_size, int16_t *block);
+void ff_simple_idct_10(int16_t *block);
 /**
  * Special version of ff_simple_idct_10() which does dequantization
  * and scales by a factor of 2 more between the two IDCTs to account
  * for larger scale of input coefficients.
  */
-void ff_prores_idct(DCTELEM *block, const int16_t *qmat);
+void ff_prores_idct(int16_t *block, const int16_t *qmat);
 
 void ff_simple_idct_mmx(int16_t *block);
 void ff_simple_idct_add_mmx(uint8_t *dest, int line_size, int16_t *block);
 void ff_simple_idct_put_mmx(uint8_t *dest, int line_size, int16_t *block);
 
-void ff_simple_idct248_put(uint8_t *dest, int line_size, DCTELEM *block);
+void ff_simple_idct248_put(uint8_t *dest, int line_size, int16_t *block);
 
-void ff_simple_idct84_add(uint8_t *dest, int line_size, DCTELEM *block);
-void ff_simple_idct48_add(uint8_t *dest, int line_size, DCTELEM *block);
-void ff_simple_idct44_add(uint8_t *dest, int line_size, DCTELEM *block);
+void ff_simple_idct84_add(uint8_t *dest, int line_size, int16_t *block);
+void ff_simple_idct48_add(uint8_t *dest, int line_size, int16_t *block);
+void ff_simple_idct44_add(uint8_t *dest, int line_size, int16_t *block);
 
 #endif /* AVCODEC_SIMPLE_IDCT_H */
diff --git a/libavcodec/simple_idct_template.c b/libavcodec/simple_idct_template.c
index b67893c..dabfbda 100644
--- a/libavcodec/simple_idct_template.c
+++ b/libavcodec/simple_idct_template.c
@@ -85,7 +85,7 @@
 
 #endif
 
-static inline void FUNC(idctRowCondDC)(DCTELEM *row, int extra_shift)
+static inline void FUNC(idctRowCondDC)(int16_t *row, int extra_shift)
 {
     int a0, a1, a2, a3, b0, b1, b2, b3;
 
@@ -221,7 +221,7 @@
     } while (0)
 
 static inline void FUNC(idctSparseColPut)(pixel *dest, int line_size,
-                                          DCTELEM *col)
+                                          int16_t *col)
 {
     int a0, a1, a2, a3, b0, b1, b2, b3;
 
@@ -245,7 +245,7 @@
 }
 
 static inline void FUNC(idctSparseColAdd)(pixel *dest, int line_size,
-                                          DCTELEM *col)
+                                          int16_t *col)
 {
     int a0, a1, a2, a3, b0, b1, b2, b3;
 
@@ -268,7 +268,7 @@
     dest[0] = av_clip_pixel(dest[0] + ((a0 - b0) >> COL_SHIFT));
 }
 
-static inline void FUNC(idctSparseCol)(DCTELEM *col)
+static inline void FUNC(idctSparseCol)(int16_t *col)
 {
     int a0, a1, a2, a3, b0, b1, b2, b3;
 
@@ -284,7 +284,7 @@
     col[56] = ((a0 - b0) >> COL_SHIFT);
 }
 
-void FUNC(ff_simple_idct_put)(uint8_t *dest_, int line_size, DCTELEM *block)
+void FUNC(ff_simple_idct_put)(uint8_t *dest_, int line_size, int16_t *block)
 {
     pixel *dest = (pixel *)dest_;
     int i;
@@ -298,7 +298,7 @@
         FUNC(idctSparseColPut)(dest + i, line_size, block + i);
 }
 
-void FUNC(ff_simple_idct_add)(uint8_t *dest_, int line_size, DCTELEM *block)
+void FUNC(ff_simple_idct_add)(uint8_t *dest_, int line_size, int16_t *block)
 {
     pixel *dest = (pixel *)dest_;
     int i;
@@ -312,7 +312,7 @@
         FUNC(idctSparseColAdd)(dest + i, line_size, block + i);
 }
 
-void FUNC(ff_simple_idct)(DCTELEM *block)
+void FUNC(ff_simple_idct)(int16_t *block)
 {
     int i;
 
diff --git a/libavcodec/sipr.c b/libavcodec/sipr.c
index d8bfdd2..dc16936 100644
--- a/libavcodec/sipr.c
+++ b/libavcodec/sipr.c
@@ -26,11 +26,12 @@
 #include <string.h>
 
 #include "libavutil/channel_layout.h"
+#include "libavutil/float_dsp.h"
 #include "libavutil/mathematics.h"
 #include "avcodec.h"
 #define BITSTREAM_READER_LE
 #include "get_bits.h"
-#include "dsputil.h"
+#include "internal.h"
 
 #include "lsp.h"
 #include "acelp_vectors.h"
@@ -410,9 +411,10 @@
         convolute_with_sparse(fixed_vector, &fixed_cb, impulse_response,
                               SUBFR_SIZE);
 
-        avg_energy =
-            (0.01 + ff_scalarproduct_float_c(fixed_vector, fixed_vector, SUBFR_SIZE)) /
-                SUBFR_SIZE;
+        avg_energy = (0.01 + avpriv_scalarproduct_float_c(fixed_vector,
+                                                          fixed_vector,
+                                                          SUBFR_SIZE)) /
+                     SUBFR_SIZE;
 
         ctx->past_pitch_gain = pitch_gain = gain_cb[params->gc_index[i]][0];
 
@@ -453,9 +455,9 @@
 
     if (ctx->mode == MODE_5k0) {
         for (i = 0; i < subframe_count; i++) {
-            float energy = ff_scalarproduct_float_c(ctx->postfilter_syn5k0 + LP_FILTER_ORDER + i * SUBFR_SIZE,
-                                                    ctx->postfilter_syn5k0 + LP_FILTER_ORDER + i * SUBFR_SIZE,
-                                                    SUBFR_SIZE);
+            float energy = avpriv_scalarproduct_float_c(ctx->postfilter_syn5k0 + LP_FILTER_ORDER + i * SUBFR_SIZE,
+                                                        ctx->postfilter_syn5k0 + LP_FILTER_ORDER + i * SUBFR_SIZE,
+                                                        SUBFR_SIZE);
             ff_adaptive_gain_control(&synth[i * SUBFR_SIZE],
                                      &synth[i * SUBFR_SIZE], energy,
                                      SUBFR_SIZE, 0.9, &ctx->postfilter_agc);
@@ -514,9 +516,6 @@
     avctx->channel_layout = AV_CH_LAYOUT_MONO;
     avctx->sample_fmt     = AV_SAMPLE_FMT_FLT;
 
-    avcodec_get_frame_defaults(&ctx->frame);
-    avctx->coded_frame = &ctx->frame;
-
     return 0;
 }
 
@@ -524,6 +523,7 @@
                              int *got_frame_ptr, AVPacket *avpkt)
 {
     SiprContext *ctx = avctx->priv_data;
+    AVFrame *frame   = data;
     const uint8_t *buf=avpkt->data;
     SiprParameters parm;
     const SiprModeParam *mode_par = &modes[ctx->mode];
@@ -541,13 +541,13 @@
     }
 
     /* get output buffer */
-    ctx->frame.nb_samples = mode_par->frames_per_packet * subframe_size *
-                            mode_par->subframe_count;
-    if ((ret = avctx->get_buffer(avctx, &ctx->frame)) < 0) {
+    frame->nb_samples = mode_par->frames_per_packet * subframe_size *
+                        mode_par->subframe_count;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    samples = (float *)ctx->frame.data[0];
+    samples = (float *)frame->data[0];
 
     init_get_bits(&gb, buf, mode_par->bits_per_frame);
 
@@ -559,8 +559,7 @@
         samples += subframe_size * mode_par->subframe_count;
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = ctx->frame;
+    *got_frame_ptr = 1;
 
     return mode_par->bits_per_frame >> 3;
 }
diff --git a/libavcodec/sipr.h b/libavcodec/sipr.h
index 8872fa3..34f7f99 100644
--- a/libavcodec/sipr.h
+++ b/libavcodec/sipr.h
@@ -25,7 +25,6 @@
 #define AVCODEC_SIPR_H
 
 #include "avcodec.h"
-#include "dsputil.h"
 #include "acelp_pitch_delay.h"
 #include "libavutil/mem.h"
 
@@ -65,7 +64,6 @@
 
 typedef struct SiprContext {
     AVCodecContext *avctx;
-    AVFrame frame;
 
     SiprMode mode;
 
diff --git a/libavcodec/sipr16k.c b/libavcodec/sipr16k.c
index c2e090b..fbf7497 100644
--- a/libavcodec/sipr16k.c
+++ b/libavcodec/sipr16k.c
@@ -25,8 +25,8 @@
 
 #include "sipr.h"
 #include "libavutil/common.h"
+#include "libavutil/float_dsp.h"
 #include "libavutil/mathematics.h"
-#include "dsputil.h"
 #include "lsp.h"
 #include "celp_filters.h"
 #include "acelp_vectors.h"
@@ -163,11 +163,11 @@
                                      const float *ma_prediction_coeff,
                                      int subframe_size, int ma_pred_order)
 {
-    mr_energy +=
-        ff_scalarproduct_float_c(quant_energy, ma_prediction_coeff, ma_pred_order);
+    mr_energy += avpriv_scalarproduct_float_c(quant_energy, ma_prediction_coeff,
+                                              ma_pred_order);
 
     mr_energy = gain_corr_factor * exp(M_LN10 / 20. * mr_energy) /
-        sqrt((0.01 + ff_scalarproduct_float_c(fc_v, fc_v, subframe_size)));
+        sqrt((0.01 + avpriv_scalarproduct_float_c(fc_v, fc_v, subframe_size)));
     return mr_energy;
 }
 
diff --git a/libavcodec/smacker.c b/libavcodec/smacker.c
index e1e67da..ad1d4c3 100644
--- a/libavcodec/smacker.c
+++ b/libavcodec/smacker.c
@@ -33,6 +33,7 @@
 
 #include "libavutil/channel_layout.h"
 #include "avcodec.h"
+#include "internal.h"
 #include "mathops.h"
 
 #define BITSTREAM_READER_LE
@@ -364,7 +365,8 @@
     return v;
 }
 
-static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt)
+static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
+                        AVPacket *avpkt)
 {
     SmackVContext * const smk = avctx->priv_data;
     uint8_t *out;
@@ -511,7 +513,7 @@
 
     }
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*)data = smk->pic;
 
     /* always report that the buffer was completely consumed */
@@ -570,14 +572,8 @@
 }
 
 
-typedef struct SmackerAudioContext {
-    AVFrame frame;
-} SmackerAudioContext;
-
 static av_cold int smka_decode_init(AVCodecContext *avctx)
 {
-    SmackerAudioContext *s = avctx->priv_data;
-
     if (avctx->channels < 1 || avctx->channels > 2) {
         av_log(avctx, AV_LOG_ERROR, "invalid number of channels\n");
         return AVERROR(EINVAL);
@@ -585,9 +581,6 @@
     avctx->channel_layout = (avctx->channels==2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO;
     avctx->sample_fmt = avctx->bits_per_coded_sample == 8 ? AV_SAMPLE_FMT_U8 : AV_SAMPLE_FMT_S16;
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     return 0;
 }
 
@@ -597,7 +590,7 @@
 static int smka_decode_frame(AVCodecContext *avctx, void *data,
                              int *got_frame_ptr, AVPacket *avpkt)
 {
-    SmackerAudioContext *s = avctx->priv_data;
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     GetBitContext gb;
@@ -642,13 +635,13 @@
     }
 
     /* get output buffer */
-    s->frame.nb_samples = unp_size / (avctx->channels * (bits + 1));
-    if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = unp_size / (avctx->channels * (bits + 1));
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    samples  = (int16_t *)s->frame.data[0];
-    samples8 =            s->frame.data[0];
+    samples  = (int16_t *)frame->data[0];
+    samples8 =            frame->data[0];
 
     // Initialize
     for(i = 0; i < (1 << (bits + stereo)); i++) {
@@ -767,8 +760,7 @@
         av_free(h[i].values);
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
+    *got_frame_ptr = 1;
 
     return buf_size;
 }
@@ -789,7 +781,6 @@
     .name           = "smackaud",
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_SMACKAUDIO,
-    .priv_data_size = sizeof(SmackerAudioContext),
     .init           = smka_decode_init,
     .decode         = smka_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
diff --git a/libavcodec/smc.c b/libavcodec/smc.c
index 402c804..6294f09 100644
--- a/libavcodec/smc.c
+++ b/libavcodec/smc.c
@@ -423,7 +423,7 @@
 }
 
 static int smc_decode_frame(AVCodecContext *avctx,
-                             void *data, int *data_size,
+                             void *data, int *got_frame,
                              AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
@@ -448,7 +448,7 @@
 
     smc_decode_stream(s);
 
-    *data_size = sizeof(AVFrame);
+    *got_frame      = 1;
     *(AVFrame*)data = s->frame;
 
     /* always report that the buffer was completely consumed */
diff --git a/libavcodec/snow.c b/libavcodec/snow.c
index 2f3ddbe..b2c6714 100644
--- a/libavcodec/snow.c
+++ b/libavcodec/snow.c
@@ -23,7 +23,8 @@
 #include "libavutil/opt.h"
 #include "avcodec.h"
 #include "dsputil.h"
-#include "dwt.h"
+#include "snow_dwt.h"
+#include "internal.h"
 #include "snow.h"
 #include "snowdata.h"
 
@@ -345,7 +346,7 @@
         src += sx + sy*stride;
         if(   (unsigned)sx >= FFMAX(w - b_w - (HTAPS_MAX-2), 0)
            || (unsigned)sy >= FFMAX(h - b_h - (HTAPS_MAX-2), 0)){
-            s->dsp.emulated_edge_mc(tmp + MB_SIZE, src, stride, b_w+HTAPS_MAX-1, b_h+HTAPS_MAX-1, sx, sy, w, h);
+            s->vdsp.emulated_edge_mc(tmp + MB_SIZE, src, stride, b_w+HTAPS_MAX-1, b_h+HTAPS_MAX-1, sx, sy, w, h);
             src= tmp + MB_SIZE;
         }
 
@@ -360,24 +361,24 @@
         else if(b_w==32){
             int y;
             for(y=0; y<b_h; y+=16){
-                s->dsp.put_h264_qpel_pixels_tab[0][dy+(dx>>2)](dst + y*stride, src + 3 + (y+3)*stride,stride);
-                s->dsp.put_h264_qpel_pixels_tab[0][dy+(dx>>2)](dst + 16 + y*stride, src + 19 + (y+3)*stride,stride);
+                s->h264qpel.put_h264_qpel_pixels_tab[0][dy+(dx>>2)](dst + y*stride, src + 3 + (y+3)*stride,stride);
+                s->h264qpel.put_h264_qpel_pixels_tab[0][dy+(dx>>2)](dst + 16 + y*stride, src + 19 + (y+3)*stride,stride);
             }
         }else if(b_w==b_h)
-            s->dsp.put_h264_qpel_pixels_tab[tab_index  ][dy+(dx>>2)](dst,src + 3 + 3*stride,stride);
+            s->h264qpel.put_h264_qpel_pixels_tab[tab_index  ][dy+(dx>>2)](dst,src + 3 + 3*stride,stride);
         else if(b_w==2*b_h){
-            s->dsp.put_h264_qpel_pixels_tab[tab_index+1][dy+(dx>>2)](dst    ,src + 3       + 3*stride,stride);
-            s->dsp.put_h264_qpel_pixels_tab[tab_index+1][dy+(dx>>2)](dst+b_h,src + 3 + b_h + 3*stride,stride);
+            s->h264qpel.put_h264_qpel_pixels_tab[tab_index+1][dy+(dx>>2)](dst    ,src + 3       + 3*stride,stride);
+            s->h264qpel.put_h264_qpel_pixels_tab[tab_index+1][dy+(dx>>2)](dst+b_h,src + 3 + b_h + 3*stride,stride);
         }else{
             av_assert2(2*b_w==b_h);
-            s->dsp.put_h264_qpel_pixels_tab[tab_index  ][dy+(dx>>2)](dst           ,src + 3 + 3*stride           ,stride);
-            s->dsp.put_h264_qpel_pixels_tab[tab_index  ][dy+(dx>>2)](dst+b_w*stride,src + 3 + 3*stride+b_w*stride,stride);
+            s->h264qpel.put_h264_qpel_pixels_tab[tab_index  ][dy+(dx>>2)](dst           ,src + 3 + 3*stride           ,stride);
+            s->h264qpel.put_h264_qpel_pixels_tab[tab_index  ][dy+(dx>>2)](dst+b_w*stride,src + 3 + 3*stride+b_w*stride,stride);
         }
     }
 }
 
 #define mca(dx,dy,b_w)\
-static void mc_block_hpel ## dx ## dy ## b_w(uint8_t *dst, const uint8_t *src, int stride, int h){\
+static void mc_block_hpel ## dx ## dy ## b_w(uint8_t *dst, const uint8_t *src, ptrdiff_t stride, int h){\
     av_assert2(h==b_w);\
     mc_block(NULL, dst, src-(HTAPS_MAX/2-1)-(HTAPS_MAX/2-1)*stride, stride, b_w, b_w, dx, dy);\
 }
@@ -397,18 +398,20 @@
     int i, j;
 
     s->avctx= avctx;
-    s->max_ref_frames=1; //just make sure its not an invalid value in case of no initial keyframe
+    s->max_ref_frames=1; //just make sure it's not an invalid value in case of no initial keyframe
 
     ff_dsputil_init(&s->dsp, avctx);
+    ff_videodsp_init(&s->vdsp, 8);
     ff_dwt_init(&s->dwt);
+    ff_h264qpel_init(&s->h264qpel, 8);
 
 #define mcf(dx,dy)\
     s->dsp.put_qpel_pixels_tab       [0][dy+dx/4]=\
     s->dsp.put_no_rnd_qpel_pixels_tab[0][dy+dx/4]=\
-        s->dsp.put_h264_qpel_pixels_tab[0][dy+dx/4];\
+        s->h264qpel.put_h264_qpel_pixels_tab[0][dy+dx/4];\
     s->dsp.put_qpel_pixels_tab       [1][dy+dx/4]=\
     s->dsp.put_no_rnd_qpel_pixels_tab[1][dy+dx/4]=\
-        s->dsp.put_h264_qpel_pixels_tab[1][dy+dx/4];
+        s->h264qpel.put_h264_qpel_pixels_tab[1][dy+dx/4];
 
     mcf( 0, 0)
     mcf( 4, 0)
@@ -468,7 +471,7 @@
     int ret, emu_buf_size;
 
     if(!s->scratchbuf) {
-        if ((ret = s->avctx->get_buffer(s->avctx, &s->mconly_picture)) < 0) {
+        if ((ret = ff_get_buffer(s->avctx, &s->mconly_picture)) < 0) {
             av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
             return ret;
         }
@@ -632,7 +635,7 @@
     }
 
     s->current_picture.reference= 3;
-    if(s->avctx->get_buffer(s->avctx, &s->current_picture) < 0){
+    if(ff_get_buffer(s->avctx, &s->current_picture) < 0){
         av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return -1;
     }
diff --git a/libavcodec/snow.h b/libavcodec/snow.h
index 6d6b086..a3b0512 100644
--- a/libavcodec/snow.h
+++ b/libavcodec/snow.h
@@ -23,11 +23,12 @@
 #define AVCODEC_SNOW_H
 
 #include "dsputil.h"
-#include "dwt.h"
+#include "snow_dwt.h"
 
 #include "rangecoder.h"
 #include "mathops.h"
 #include "mpegvideo.h"
+#include "h264qpel.h"
 
 #define MID_STATE 128
 
@@ -108,7 +109,9 @@
     AVCodecContext *avctx;
     RangeCoder c;
     DSPContext dsp;
-    DWTContext dwt;
+    VideoDSPContext vdsp;
+    H264QpelContext h264qpel;
+    SnowDWTContext dwt;
     AVFrame new_picture;
     AVFrame input_picture;              ///< new_picture with the internal linesizes
     AVFrame current_picture;
diff --git a/libavcodec/dwt.c b/libavcodec/snow_dwt.c
similarity index 61%
rename from libavcodec/dwt.c
rename to libavcodec/snow_dwt.c
index d36d25d..28edf6a 100644
--- a/libavcodec/dwt.c
+++ b/libavcodec/snow_dwt.c
@@ -23,8 +23,7 @@
 #include "libavutil/avassert.h"
 #include "libavutil/common.h"
 #include "dsputil.h"
-#include "dwt.h"
-#include "libavcodec/x86/dwt.h"
+#include "snow_dwt.h"
 
 int ff_slice_buffer_init(slice_buffer *buf, int line_count,
                          int max_allocated_lines, int line_width,
@@ -566,7 +565,7 @@
     cs->y  = -3;
 }
 
-static void spatial_compose97i_dy_buffered(DWTContext *dsp, DWTCompose *cs,
+static void spatial_compose97i_dy_buffered(SnowDWTContext *dsp, DWTCompose *cs,
                                            slice_buffer * sb, IDWTELEM *temp,
                                            int width, int height,
                                            int stride_line)
@@ -661,7 +660,7 @@
     }
 }
 
-void ff_spatial_idwt_buffered_slice(DWTContext *dsp, DWTCompose *cs,
+void ff_spatial_idwt_buffered_slice(SnowDWTContext *dsp, DWTCompose *cs,
                                     slice_buffer *slice_buf, IDWTELEM *temp,
                                     int width, int height, int stride_line,
                                     int type, int decomposition_count, int y)
@@ -853,7 +852,7 @@
     c->w97[1] = w97_8_c;
 }
 
-void ff_dwt_init(DWTContext *c)
+void ff_dwt_init(SnowDWTContext *c)
 {
     c->vertical_compose97i   = ff_snow_vertical_compose97i;
     c->horizontal_compose97i = ff_snow_horizontal_compose97i;
@@ -864,539 +863,3 @@
 }
 
 
-static av_always_inline
-void interleave(IDWTELEM *dst, IDWTELEM *src0, IDWTELEM *src1, int w2, int add, int shift)
-{
-    int i;
-    for (i = 0; i < w2; i++) {
-        dst[2*i  ] = (src0[i] + add) >> shift;
-        dst[2*i+1] = (src1[i] + add) >> shift;
-    }
-}
-
-static void horizontal_compose_dirac53i(IDWTELEM *b, IDWTELEM *temp, int w)
-{
-    const int w2 = w >> 1;
-    int x;
-
-    temp[0] = COMPOSE_53iL0(b[w2], b[0], b[w2]);
-    for (x = 1; x < w2; x++) {
-        temp[x     ] = COMPOSE_53iL0     (b[x+w2-1], b[x     ], b[x+w2]);
-        temp[x+w2-1] = COMPOSE_DIRAC53iH0(temp[x-1], b[x+w2-1], temp[x]);
-    }
-    temp[w-1] = COMPOSE_DIRAC53iH0(temp[w2-1], b[w-1], temp[w2-1]);
-
-    interleave(b, temp, temp+w2, w2, 1, 1);
-}
-
-static void horizontal_compose_dd97i(IDWTELEM *b, IDWTELEM *tmp, int w)
-{
-    const int w2 = w >> 1;
-    int x;
-
-    tmp[0] = COMPOSE_53iL0(b[w2], b[0], b[w2]);
-    for (x = 1; x < w2; x++)
-        tmp[x] = COMPOSE_53iL0(b[x+w2-1], b[x], b[x+w2]);
-
-    // extend the edges
-    tmp[-1]   = tmp[0];
-    tmp[w2+1] = tmp[w2] = tmp[w2-1];
-
-    for (x = 0; x < w2; x++) {
-        b[2*x  ] = (tmp[x] + 1)>>1;
-        b[2*x+1] = (COMPOSE_DD97iH0(tmp[x-1], tmp[x], b[x+w2], tmp[x+1], tmp[x+2]) + 1)>>1;
-    }
-}
-
-static void horizontal_compose_dd137i(IDWTELEM *b, IDWTELEM *tmp, int w)
-{
-    const int w2 = w >> 1;
-    int x;
-
-    tmp[0] = COMPOSE_DD137iL0(b[w2], b[w2], b[0], b[w2  ], b[w2+1]);
-    tmp[1] = COMPOSE_DD137iL0(b[w2], b[w2], b[1], b[w2+1], b[w2+2]);
-    for (x = 2; x < w2-1; x++)
-        tmp[x] = COMPOSE_DD137iL0(b[x+w2-2], b[x+w2-1], b[x], b[x+w2], b[x+w2+1]);
-    tmp[w2-1] = COMPOSE_DD137iL0(b[w-3], b[w-2], b[w2-1], b[w-1], b[w-1]);
-
-    // extend the edges
-    tmp[-1]   = tmp[0];
-    tmp[w2+1] = tmp[w2] = tmp[w2-1];
-
-    for (x = 0; x < w2; x++) {
-        b[2*x  ] = (tmp[x] + 1)>>1;
-        b[2*x+1] = (COMPOSE_DD97iH0(tmp[x-1], tmp[x], b[x+w2], tmp[x+1], tmp[x+2]) + 1)>>1;
-    }
-}
-
-static av_always_inline
-void horizontal_compose_haari(IDWTELEM *b, IDWTELEM *temp, int w, int shift)
-{
-    const int w2 = w >> 1;
-    int x;
-
-    for (x = 0; x < w2; x++) {
-        temp[x   ] = COMPOSE_HAARiL0(b[x   ], b[x+w2]);
-        temp[x+w2] = COMPOSE_HAARiH0(b[x+w2], temp[x]);
-    }
-
-    interleave(b, temp, temp+w2, w2, shift, shift);
-}
-
-static void horizontal_compose_haar0i(IDWTELEM *b, IDWTELEM *temp, int w)
-{
-    horizontal_compose_haari(b, temp, w, 0);
-}
-
-static void horizontal_compose_haar1i(IDWTELEM *b, IDWTELEM *temp, int w)
-{
-    horizontal_compose_haari(b, temp, w, 1);
-}
-
-static void horizontal_compose_fidelityi(IDWTELEM *b, IDWTELEM *tmp, int w)
-{
-    const int w2 = w >> 1;
-    int i, x;
-    IDWTELEM v[8];
-
-    for (x = 0; x < w2; x++) {
-        for (i = 0; i < 8; i++)
-            v[i] = b[av_clip(x-3+i, 0, w2-1)];
-        tmp[x] = COMPOSE_FIDELITYiH0(v[0], v[1], v[2], v[3], b[x+w2], v[4], v[5], v[6], v[7]);
-    }
-
-    for (x = 0; x < w2; x++) {
-        for (i = 0; i < 8; i++)
-            v[i] = tmp[av_clip(x-4+i, 0, w2-1)];
-        tmp[x+w2] = COMPOSE_FIDELITYiL0(v[0], v[1], v[2], v[3], b[x], v[4], v[5], v[6], v[7]);
-    }
-
-    interleave(b, tmp+w2, tmp, w2, 0, 0);
-}
-
-static void horizontal_compose_daub97i(IDWTELEM *b, IDWTELEM *temp, int w)
-{
-    const int w2 = w >> 1;
-    int x, b0, b1, b2;
-
-    temp[0] = COMPOSE_DAUB97iL1(b[w2], b[0], b[w2]);
-    for (x = 1; x < w2; x++) {
-        temp[x     ] = COMPOSE_DAUB97iL1(b[x+w2-1], b[x     ], b[x+w2]);
-        temp[x+w2-1] = COMPOSE_DAUB97iH1(temp[x-1], b[x+w2-1], temp[x]);
-    }
-    temp[w-1] = COMPOSE_DAUB97iH1(temp[w2-1], b[w-1], temp[w2-1]);
-
-    // second stage combined with interleave and shift
-    b0 = b2 = COMPOSE_DAUB97iL0(temp[w2], temp[0], temp[w2]);
-    b[0] = (b0 + 1) >> 1;
-    for (x = 1; x < w2; x++) {
-        b2 = COMPOSE_DAUB97iL0(temp[x+w2-1], temp[x     ], temp[x+w2]);
-        b1 = COMPOSE_DAUB97iH0(          b0, temp[x+w2-1], b2        );
-        b[2*x-1] = (b1 + 1) >> 1;
-        b[2*x  ] = (b2 + 1) >> 1;
-        b0 = b2;
-    }
-    b[w-1] = (COMPOSE_DAUB97iH0(b2, temp[w-1], b2) + 1) >> 1;
-}
-
-static void vertical_compose_dirac53iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width)
-{
-    int i;
-
-    for(i=0; i<width; i++){
-        b1[i] = COMPOSE_DIRAC53iH0(b0[i], b1[i], b2[i]);
-    }
-}
-
-static void vertical_compose_dd97iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
-                                  IDWTELEM *b3, IDWTELEM *b4, int width)
-{
-    int i;
-
-    for(i=0; i<width; i++){
-        b2[i] = COMPOSE_DD97iH0(b0[i], b1[i], b2[i], b3[i], b4[i]);
-    }
-}
-
-static void vertical_compose_dd137iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
-                                      IDWTELEM *b3, IDWTELEM *b4, int width)
-{
-    int i;
-
-    for(i=0; i<width; i++){
-        b2[i] = COMPOSE_DD137iL0(b0[i], b1[i], b2[i], b3[i], b4[i]);
-    }
-}
-
-static void vertical_compose_haar(IDWTELEM *b0, IDWTELEM *b1, int width)
-{
-    int i;
-
-    for (i = 0; i < width; i++) {
-        b0[i] = COMPOSE_HAARiL0(b0[i], b1[i]);
-        b1[i] = COMPOSE_HAARiH0(b1[i], b0[i]);
-    }
-}
-
-static void vertical_compose_fidelityiH0(IDWTELEM *dst, IDWTELEM *b[8], int width)
-{
-    int i;
-
-    for(i=0; i<width; i++){
-        dst[i] = COMPOSE_FIDELITYiH0(b[0][i], b[1][i], b[2][i], b[3][i], dst[i], b[4][i], b[5][i], b[6][i], b[7][i]);
-    }
-}
-
-static void vertical_compose_fidelityiL0(IDWTELEM *dst, IDWTELEM *b[8], int width)
-{
-    int i;
-
-    for(i=0; i<width; i++){
-        dst[i] = COMPOSE_FIDELITYiL0(b[0][i], b[1][i], b[2][i], b[3][i], dst[i], b[4][i], b[5][i], b[6][i], b[7][i]);
-    }
-}
-
-static void vertical_compose_daub97iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width)
-{
-    int i;
-
-    for(i=0; i<width; i++){
-        b1[i] = COMPOSE_DAUB97iH0(b0[i], b1[i], b2[i]);
-    }
-}
-
-static void vertical_compose_daub97iH1(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width)
-{
-    int i;
-
-    for(i=0; i<width; i++){
-        b1[i] = COMPOSE_DAUB97iH1(b0[i], b1[i], b2[i]);
-    }
-}
-
-static void vertical_compose_daub97iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width)
-{
-    int i;
-
-    for(i=0; i<width; i++){
-        b1[i] = COMPOSE_DAUB97iL0(b0[i], b1[i], b2[i]);
-    }
-}
-
-static void vertical_compose_daub97iL1(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width)
-{
-    int i;
-
-    for(i=0; i<width; i++){
-        b1[i] = COMPOSE_DAUB97iL1(b0[i], b1[i], b2[i]);
-    }
-}
-
-
-static void spatial_compose_dd97i_dy(DWTContext *d, int level, int width, int height, int stride)
-{
-    vertical_compose_3tap vertical_compose_l0 = (void*)d->vertical_compose_l0;
-    vertical_compose_5tap vertical_compose_h0 = (void*)d->vertical_compose_h0;
-    DWTCompose *cs = d->cs + level;
-
-    int i, y = cs->y;
-    IDWTELEM *b[8];
-    for (i = 0; i < 6; i++)
-        b[i] = cs->b[i];
-    b[6] = d->buffer + av_clip(y+5, 0, height-2)*stride;
-    b[7] = d->buffer + av_clip(y+6, 1, height-1)*stride;
-
-        if(y+5<(unsigned)height) vertical_compose_l0(      b[5], b[6], b[7],       width);
-        if(y+1<(unsigned)height) vertical_compose_h0(b[0], b[2], b[3], b[4], b[6], width);
-
-        if(y-1<(unsigned)height) d->horizontal_compose(b[0], d->temp, width);
-        if(y+0<(unsigned)height) d->horizontal_compose(b[1], d->temp, width);
-
-    for (i = 0; i < 6; i++)
-        cs->b[i] = b[i+2];
-    cs->y += 2;
-}
-
-static void spatial_compose_dirac53i_dy(DWTContext *d, int level, int width, int height, int stride)
-{
-    vertical_compose_3tap vertical_compose_l0 = (void*)d->vertical_compose_l0;
-    vertical_compose_3tap vertical_compose_h0 = (void*)d->vertical_compose_h0;
-    DWTCompose *cs = d->cs + level;
-
-    int y= cs->y;
-    IDWTELEM *b[4] = { cs->b[0], cs->b[1] };
-    b[2] = d->buffer + mirror(y+1, height-1)*stride;
-    b[3] = d->buffer + mirror(y+2, height-1)*stride;
-
-        if(y+1<(unsigned)height) vertical_compose_l0(b[1], b[2], b[3], width);
-        if(y+0<(unsigned)height) vertical_compose_h0(b[0], b[1], b[2], width);
-
-        if(y-1<(unsigned)height) d->horizontal_compose(b[0], d->temp, width);
-        if(y+0<(unsigned)height) d->horizontal_compose(b[1], d->temp, width);
-
-    cs->b[0] = b[2];
-    cs->b[1] = b[3];
-    cs->y += 2;
-}
-
-
-static void spatial_compose_dd137i_dy(DWTContext *d, int level, int width, int height, int stride)
-{
-    vertical_compose_5tap vertical_compose_l0 = (void*)d->vertical_compose_l0;
-    vertical_compose_5tap vertical_compose_h0 = (void*)d->vertical_compose_h0;
-    DWTCompose *cs = d->cs + level;
-
-    int i, y = cs->y;
-    IDWTELEM *b[10];
-    for (i = 0; i < 8; i++)
-        b[i] = cs->b[i];
-    b[8] = d->buffer + av_clip(y+7, 0, height-2)*stride;
-    b[9] = d->buffer + av_clip(y+8, 1, height-1)*stride;
-
-        if(y+5<(unsigned)height) vertical_compose_l0(b[3], b[5], b[6], b[7], b[9], width);
-        if(y+1<(unsigned)height) vertical_compose_h0(b[0], b[2], b[3], b[4], b[6], width);
-
-        if(y-1<(unsigned)height) d->horizontal_compose(b[0], d->temp, width);
-        if(y+0<(unsigned)height) d->horizontal_compose(b[1], d->temp, width);
-
-    for (i = 0; i < 8; i++)
-        cs->b[i] = b[i+2];
-    cs->y += 2;
-}
-
-// haar makes the assumption that height is even (always true for dirac)
-static void spatial_compose_haari_dy(DWTContext *d, int level, int width, int height, int stride)
-{
-    vertical_compose_2tap vertical_compose = (void*)d->vertical_compose;
-    int y = d->cs[level].y;
-    IDWTELEM *b0 = d->buffer + (y-1)*stride;
-    IDWTELEM *b1 = d->buffer + (y  )*stride;
-
-    vertical_compose(b0, b1, width);
-    d->horizontal_compose(b0, d->temp, width);
-    d->horizontal_compose(b1, d->temp, width);
-
-    d->cs[level].y += 2;
-}
-
-// Don't do sliced idwt for fidelity; the 9 tap filter makes it a bit annoying
-// Fortunately, this filter isn't used in practice.
-static void spatial_compose_fidelity(DWTContext *d, int level, int width, int height, int stride)
-{
-    vertical_compose_9tap vertical_compose_l0 = (void*)d->vertical_compose_l0;
-    vertical_compose_9tap vertical_compose_h0 = (void*)d->vertical_compose_h0;
-    int i, y;
-    IDWTELEM *b[8];
-
-    for (y = 1; y < height; y += 2) {
-        for (i = 0; i < 8; i++)
-            b[i] = d->buffer + av_clip((y-7 + 2*i), 0, height-2)*stride;
-        vertical_compose_h0(d->buffer + y*stride, b, width);
-    }
-
-    for (y = 0; y < height; y += 2) {
-        for (i = 0; i < 8; i++)
-            b[i] = d->buffer + av_clip((y-7 + 2*i), 1, height-1)*stride;
-        vertical_compose_l0(d->buffer + y*stride, b, width);
-    }
-
-    for (y = 0; y < height; y++)
-        d->horizontal_compose(d->buffer + y*stride, d->temp, width);
-
-    d->cs[level].y = height+1;
-}
-
-static void spatial_compose_daub97i_dy(DWTContext *d, int level, int width, int height, int stride)
-{
-    vertical_compose_3tap vertical_compose_l0 = (void*)d->vertical_compose_l0;
-    vertical_compose_3tap vertical_compose_h0 = (void*)d->vertical_compose_h0;
-    vertical_compose_3tap vertical_compose_l1 = (void*)d->vertical_compose_l1;
-    vertical_compose_3tap vertical_compose_h1 = (void*)d->vertical_compose_h1;
-    DWTCompose *cs = d->cs + level;
-
-    int i, y = cs->y;
-    IDWTELEM *b[6];
-    for (i = 0; i < 4; i++)
-        b[i] = cs->b[i];
-    b[4] = d->buffer + mirror(y+3, height-1)*stride;
-    b[5] = d->buffer + mirror(y+4, height-1)*stride;
-
-        if(y+3<(unsigned)height) vertical_compose_l1(b[3], b[4], b[5], width);
-        if(y+2<(unsigned)height) vertical_compose_h1(b[2], b[3], b[4], width);
-        if(y+1<(unsigned)height) vertical_compose_l0(b[1], b[2], b[3], width);
-        if(y+0<(unsigned)height) vertical_compose_h0(b[0], b[1], b[2], width);
-
-        if(y-1<(unsigned)height) d->horizontal_compose(b[0], d->temp, width);
-        if(y+0<(unsigned)height) d->horizontal_compose(b[1], d->temp, width);
-
-    for (i = 0; i < 4; i++)
-        cs->b[i] = b[i+2];
-    cs->y += 2;
-}
-
-
-static void spatial_compose97i_init2(DWTCompose *cs, IDWTELEM *buffer, int height, int stride)
-{
-    cs->b[0] = buffer + mirror(-3-1, height-1)*stride;
-    cs->b[1] = buffer + mirror(-3  , height-1)*stride;
-    cs->b[2] = buffer + mirror(-3+1, height-1)*stride;
-    cs->b[3] = buffer + mirror(-3+2, height-1)*stride;
-    cs->y = -3;
-}
-
-static void spatial_compose53i_init2(DWTCompose *cs, IDWTELEM *buffer, int height, int stride)
-{
-    cs->b[0] = buffer + mirror(-1-1, height-1)*stride;
-    cs->b[1] = buffer + mirror(-1  , height-1)*stride;
-    cs->y = -1;
-}
-
-static void spatial_compose_dd97i_init(DWTCompose *cs, IDWTELEM *buffer, int height, int stride)
-{
-    cs->b[0] = buffer + av_clip(-5-1, 0, height-2)*stride;
-    cs->b[1] = buffer + av_clip(-5  , 1, height-1)*stride;
-    cs->b[2] = buffer + av_clip(-5+1, 0, height-2)*stride;
-    cs->b[3] = buffer + av_clip(-5+2, 1, height-1)*stride;
-    cs->b[4] = buffer + av_clip(-5+3, 0, height-2)*stride;
-    cs->b[5] = buffer + av_clip(-5+4, 1, height-1)*stride;
-    cs->y = -5;
-}
-
-static void spatial_compose_dd137i_init(DWTCompose *cs, IDWTELEM *buffer, int height, int stride)
-{
-    cs->b[0] = buffer + av_clip(-5-1, 0, height-2)*stride;
-    cs->b[1] = buffer + av_clip(-5  , 1, height-1)*stride;
-    cs->b[2] = buffer + av_clip(-5+1, 0, height-2)*stride;
-    cs->b[3] = buffer + av_clip(-5+2, 1, height-1)*stride;
-    cs->b[4] = buffer + av_clip(-5+3, 0, height-2)*stride;
-    cs->b[5] = buffer + av_clip(-5+4, 1, height-1)*stride;
-    cs->b[6] = buffer + av_clip(-5+5, 0, height-2)*stride;
-    cs->b[7] = buffer + av_clip(-5+6, 1, height-1)*stride;
-    cs->y = -5;
-}
-
-int ff_spatial_idwt_init2(DWTContext *d, IDWTELEM *buffer, int width, int height,
-                          int stride, enum dwt_type type, int decomposition_count,
-                          IDWTELEM *temp)
-{
-    int level;
-
-    d->buffer = buffer;
-    d->width = width;
-    d->height = height;
-    d->stride = stride;
-    d->decomposition_count = decomposition_count;
-    d->temp = temp + 8;
-
-    for(level=decomposition_count-1; level>=0; level--){
-        int hl = height >> level;
-        int stride_l = stride << level;
-
-        switch(type){
-        case DWT_DIRAC_DD9_7:
-            spatial_compose_dd97i_init(d->cs+level, buffer, hl, stride_l);
-            break;
-        case DWT_DIRAC_LEGALL5_3:
-            spatial_compose53i_init2(d->cs+level, buffer, hl, stride_l);
-            break;
-        case DWT_DIRAC_DD13_7:
-            spatial_compose_dd137i_init(d->cs+level, buffer, hl, stride_l);
-            break;
-        case DWT_DIRAC_HAAR0:
-        case DWT_DIRAC_HAAR1:
-            d->cs[level].y = 1;
-            break;
-        case DWT_DIRAC_DAUB9_7:
-            spatial_compose97i_init2(d->cs+level, buffer, hl, stride_l);
-            break;
-        default:
-            d->cs[level].y = 0;
-            break;
-        }
-    }
-
-    switch (type) {
-    case DWT_DIRAC_DD9_7:
-        d->spatial_compose = spatial_compose_dd97i_dy;
-        d->vertical_compose_l0 = (void*)vertical_compose53iL0;
-        d->vertical_compose_h0 = (void*)vertical_compose_dd97iH0;
-        d->horizontal_compose = horizontal_compose_dd97i;
-        d->support = 7;
-        break;
-    case DWT_DIRAC_LEGALL5_3:
-        d->spatial_compose = spatial_compose_dirac53i_dy;
-        d->vertical_compose_l0 = (void*)vertical_compose53iL0;
-        d->vertical_compose_h0 = (void*)vertical_compose_dirac53iH0;
-        d->horizontal_compose = horizontal_compose_dirac53i;
-        d->support = 3;
-        break;
-    case DWT_DIRAC_DD13_7:
-        d->spatial_compose = spatial_compose_dd137i_dy;
-        d->vertical_compose_l0 = (void*)vertical_compose_dd137iL0;
-        d->vertical_compose_h0 = (void*)vertical_compose_dd97iH0;
-        d->horizontal_compose = horizontal_compose_dd137i;
-        d->support = 7;
-        break;
-    case DWT_DIRAC_HAAR0:
-    case DWT_DIRAC_HAAR1:
-        d->spatial_compose = spatial_compose_haari_dy;
-        d->vertical_compose = (void*)vertical_compose_haar;
-        if (type == DWT_DIRAC_HAAR0)
-            d->horizontal_compose = horizontal_compose_haar0i;
-        else
-            d->horizontal_compose = horizontal_compose_haar1i;
-        d->support = 1;
-        break;
-    case DWT_DIRAC_FIDELITY:
-        d->spatial_compose = spatial_compose_fidelity;
-        d->vertical_compose_l0 = (void*)vertical_compose_fidelityiL0;
-        d->vertical_compose_h0 = (void*)vertical_compose_fidelityiH0;
-        d->horizontal_compose = horizontal_compose_fidelityi;
-        break;
-    case DWT_DIRAC_DAUB9_7:
-        d->spatial_compose = spatial_compose_daub97i_dy;
-        d->vertical_compose_l0 = (void*)vertical_compose_daub97iL0;
-        d->vertical_compose_h0 = (void*)vertical_compose_daub97iH0;
-        d->vertical_compose_l1 = (void*)vertical_compose_daub97iL1;
-        d->vertical_compose_h1 = (void*)vertical_compose_daub97iH1;
-        d->horizontal_compose = horizontal_compose_daub97i;
-        d->support = 5;
-        break;
-    default:
-        av_log(NULL, AV_LOG_ERROR, "Unknown wavelet type %d\n", type);
-        return -1;
-    }
-
-    if (HAVE_MMX) ff_spatial_idwt_init_mmx(d, type);
-
-    return 0;
-}
-
-void ff_spatial_idwt_slice2(DWTContext *d, int y)
-{
-    int level, support = d->support;
-
-    for (level = d->decomposition_count-1; level >= 0; level--) {
-        int wl = d->width  >> level;
-        int hl = d->height >> level;
-        int stride_l = d->stride << level;
-
-        while (d->cs[level].y <= FFMIN((y>>level)+support, hl))
-            d->spatial_compose(d, level, wl, hl, stride_l);
-    }
-}
-
-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/snow_dwt.h b/libavcodec/snow_dwt.h
new file mode 100644
index 0000000..0806b38
--- /dev/null
+++ b/libavcodec/snow_dwt.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2004-2010 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
+ */
+
+#ifndef AVCODEC_SNOW_DWT_H
+#define AVCODEC_SNOW_DWT_H
+
+#include <stdint.h>
+
+typedef int DWTELEM;
+typedef short IDWTELEM;
+
+#define MAX_DECOMPOSITIONS 8
+
+typedef struct DWTCompose {
+    IDWTELEM *b0;
+    IDWTELEM *b1;
+    IDWTELEM *b2;
+    IDWTELEM *b3;
+    int y;
+} DWTCompose;
+
+/** Used to minimize the amount of memory used in order to
+ *  optimize cache performance. **/
+typedef struct slice_buffer_s {
+    IDWTELEM **line;   ///< For use by idwt and predict_slices.
+    IDWTELEM **data_stack;   ///< Used for internal purposes.
+    int data_stack_top;
+    int line_count;
+    int line_width;
+    int data_count;
+    IDWTELEM *base_buffer;  ///< Buffer that this structure is caching.
+} slice_buffer;
+
+struct SnowDWTContext;
+
+typedef struct SnowDWTContext {
+    void (*vertical_compose97i)(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
+                                IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5,
+                                int width);
+    void (*horizontal_compose97i)(IDWTELEM *b, IDWTELEM *temp, int width);
+    void (*inner_add_yblock)(const uint8_t *obmc, const int obmc_stride,
+                             uint8_t **block, int b_w, int b_h, int src_x,
+                             int src_y, int src_stride, slice_buffer *sb,
+                             int add, uint8_t *dst8);
+} SnowDWTContext;
+
+
+#define DWT_97 0
+#define DWT_53 1
+
+#define liftS lift
+#define W_AM 3
+#define W_AO 0
+#define W_AS 1
+
+#undef liftS
+#define W_BM 1
+#define W_BO 8
+#define W_BS 4
+
+#define W_CM 1
+#define W_CO 0
+#define W_CS 0
+
+#define W_DM 3
+#define W_DO 4
+#define W_DS 3
+
+#define slice_buffer_get_line(slice_buf, line_num)                          \
+    ((slice_buf)->line[line_num] ? (slice_buf)->line[line_num]              \
+                                 : ff_slice_buffer_load_line((slice_buf),   \
+                                                             (line_num)))
+
+int ff_slice_buffer_init(slice_buffer *buf, int line_count,
+                         int max_allocated_lines, int line_width,
+                         IDWTELEM *base_buffer);
+void ff_slice_buffer_release(slice_buffer *buf, int line);
+void ff_slice_buffer_flush(slice_buffer *buf);
+void ff_slice_buffer_destroy(slice_buffer *buf);
+IDWTELEM *ff_slice_buffer_load_line(slice_buffer *buf, int line);
+
+void ff_snow_vertical_compose97i(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
+                                 IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5,
+                                 int width);
+void ff_snow_horizontal_compose97i(IDWTELEM *b, IDWTELEM *temp, int width);
+void ff_snow_inner_add_yblock(const uint8_t *obmc, const int obmc_stride,
+                              uint8_t **block, int b_w, int b_h, int src_x,
+                              int src_y, int src_stride, slice_buffer *sb,
+                              int add, uint8_t *dst8);
+
+int ff_w53_32_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h);
+int ff_w97_32_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h);
+
+void ff_spatial_dwt(int *buffer, int *temp, int width, int height, int stride,
+                    int type, int decomposition_count);
+
+void ff_spatial_idwt_buffered_init(DWTCompose *cs, slice_buffer *sb, int width,
+                                   int height, int stride_line, int type,
+                                   int decomposition_count);
+void ff_spatial_idwt_buffered_slice(SnowDWTContext *dsp, DWTCompose *cs,
+                                    slice_buffer *slice_buf, IDWTELEM *temp,
+                                    int width, int height, int stride_line,
+                                    int type, int decomposition_count, int y);
+void ff_spatial_idwt(IDWTELEM *buffer, IDWTELEM *temp, int width, int height,
+                     int stride, int type, int decomposition_count);
+
+void ff_dwt_init(SnowDWTContext *c);
+void ff_dwt_init_x86(SnowDWTContext *c);
+
+#endif /* AVCODEC_DWT_H */
diff --git a/libavcodec/snowdec.c b/libavcodec/snowdec.c
index f377409..e211506 100644
--- a/libavcodec/snowdec.c
+++ b/libavcodec/snowdec.c
@@ -23,7 +23,8 @@
 #include "libavutil/opt.h"
 #include "avcodec.h"
 #include "dsputil.h"
-#include "dwt.h"
+#include "snow_dwt.h"
+#include "internal.h"
 #include "snow.h"
 
 #include "rangecoder.h"
@@ -390,7 +391,9 @@
     return 0;
 }
 
-static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt){
+static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
+                        AVPacket *avpkt)
+{
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     SnowContext *s = avctx->priv_data;
@@ -552,7 +555,7 @@
     else
         *picture= s->mconly_picture;
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
 
     bytes_read= c->bytestream - c->bytestream_start;
     if(bytes_read ==0) av_log(s->avctx, AV_LOG_ERROR, "error at end of frame\n"); //FIXME
diff --git a/libavcodec/snowenc.c b/libavcodec/snowenc.c
index 23d8d81..1831cf6 100644
--- a/libavcodec/snowenc.c
+++ b/libavcodec/snowenc.c
@@ -24,7 +24,8 @@
 #include "avcodec.h"
 #include "internal.h"
 #include "dsputil.h"
-#include "dwt.h"
+#include "internal.h"
+#include "snow_dwt.h"
 #include "snow.h"
 
 #include "rangecoder.h"
@@ -238,7 +239,8 @@
     ff_set_cmp(&s->dsp, s->dsp.me_cmp, s->avctx->me_cmp);
     ff_set_cmp(&s->dsp, s->dsp.me_sub_cmp, s->avctx->me_sub_cmp);
 
-    s->avctx->get_buffer(s->avctx, &s->input_picture);
+    if ((ret = ff_get_buffer(s->avctx, &s->input_picture)) < 0)
+        return ret;
 
     if(s->avctx->me_method == ME_ITER){
         int i;
@@ -285,6 +287,30 @@
     return s;
 }
 
+static inline int get_penalty_factor(int lambda, int lambda2, int type){
+    switch(type&0xFF){
+    default:
+    case FF_CMP_SAD:
+        return lambda>>FF_LAMBDA_SHIFT;
+    case FF_CMP_DCT:
+        return (3*lambda)>>(FF_LAMBDA_SHIFT+1);
+    case FF_CMP_W53:
+        return (4*lambda)>>(FF_LAMBDA_SHIFT);
+    case FF_CMP_W97:
+        return (2*lambda)>>(FF_LAMBDA_SHIFT);
+    case FF_CMP_SATD:
+    case FF_CMP_DCT264:
+        return (2*lambda)>>FF_LAMBDA_SHIFT;
+    case FF_CMP_RD:
+    case FF_CMP_PSNR:
+    case FF_CMP_SSE:
+    case FF_CMP_NSSE:
+        return lambda2>>FF_LAMBDA_SHIFT;
+    case FF_CMP_BIT:
+        return 1;
+    }
+}
+
 //FIXME copy&paste
 #define P_LEFT P[1]
 #define P_TOP P[2]
diff --git a/libavcodec/sonic.c b/libavcodec/sonic.c
index b7caf48..0bc8428 100644
--- a/libavcodec/sonic.c
+++ b/libavcodec/sonic.c
@@ -877,7 +877,7 @@
     if (buf_size == 0) return 0;
 
     s->frame.nb_samples = s->frame_size;
-    if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
diff --git a/libavcodec/sp5xdec.c b/libavcodec/sp5xdec.c
index 7216088..b083015 100644
--- a/libavcodec/sp5xdec.c
+++ b/libavcodec/sp5xdec.c
@@ -31,7 +31,7 @@
 
 
 static int sp5x_decode_frame(AVCodecContext *avctx,
-                              void *data, int *data_size,
+                              void *data, int *got_frame,
                               AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
@@ -86,7 +86,7 @@
     av_init_packet(&avpkt_recoded);
     avpkt_recoded.data = recoded;
     avpkt_recoded.size = j;
-    i = ff_mjpeg_decode_frame(avctx, data, data_size, &avpkt_recoded);
+    i = ff_mjpeg_decode_frame(avctx, data, got_frame, &avpkt_recoded);
 
     av_free(recoded);
 
diff --git a/libavcodec/sparc/dsputil_vis.c b/libavcodec/sparc/dsputil_vis.c
index 5b5b96e..0ade237 100644
--- a/libavcodec/sparc/dsputil_vis.c
+++ b/libavcodec/sparc/dsputil_vis.c
@@ -26,6 +26,7 @@
 
 #include <inttypes.h>
 
+#include "libavutil/attributes.h"
 #include "libavcodec/dsputil.h"
 #include "libavutil/mem.h"
 #include "dsputil_vis.h"
@@ -120,7 +121,7 @@
 #define TMP32           58
 
 static void MC_put_o_16_vis (uint8_t * dest, const uint8_t * ref,
-                             const int stride, int height)
+                             const ptrdiff_t stride, int height)
 {
         ref = vis_alignaddr(ref);
         do {    /* 5 cycles */
@@ -141,7 +142,7 @@
 }
 
 static void MC_put_o_8_vis (uint8_t * dest, const uint8_t * ref,
-                            const int stride, int height)
+                            const ptrdiff_t stride, int height)
 {
         ref = vis_alignaddr(ref);
         do {    /* 4 cycles */
@@ -160,7 +161,7 @@
 
 
 static void MC_avg_o_16_vis (uint8_t * dest, const uint8_t * ref,
-                             const int stride, int height)
+                             const ptrdiff_t stride, int height)
 {
         int stride_8 = stride + 8;
 
@@ -320,7 +321,7 @@
 }
 
 static void MC_avg_o_8_vis (uint8_t * dest, const uint8_t * ref,
-                            const int stride, int height)
+                            const ptrdiff_t stride, int height)
 {
         ref = vis_alignaddr(ref);
 
@@ -412,7 +413,7 @@
 }
 
 static void MC_put_x_16_vis (uint8_t * dest, const uint8_t * ref,
-                             const int stride, int height)
+                             const ptrdiff_t stride, int height)
 {
         unsigned long off = (unsigned long) ref & 0x7;
         unsigned long off_plus_1 = off + 1;
@@ -604,7 +605,7 @@
 }
 
 static void MC_put_x_8_vis (uint8_t * dest, const uint8_t * ref,
-                            const int stride, int height)
+                            const ptrdiff_t stride, int height)
 {
         unsigned long off = (unsigned long) ref & 0x7;
         unsigned long off_plus_1 = off + 1;
@@ -727,7 +728,7 @@
 }
 
 static void MC_avg_x_16_vis (uint8_t * dest, const uint8_t * ref,
-                             const int stride, int height)
+                             const ptrdiff_t stride, int height)
 {
         unsigned long off = (unsigned long) ref & 0x7;
         unsigned long off_plus_1 = off + 1;
@@ -817,7 +818,7 @@
 }
 
 static void MC_avg_x_8_vis (uint8_t * dest, const uint8_t * ref,
-                            const int stride, int height)
+                            const ptrdiff_t stride, int height)
 {
         unsigned long off = (unsigned long) ref & 0x7;
         unsigned long off_plus_1 = off + 1;
@@ -982,7 +983,7 @@
 }
 
 static void MC_put_y_16_vis (uint8_t * dest, const uint8_t * ref,
-                             const int stride, int height)
+                             const ptrdiff_t stride, int height)
 {
         ref = vis_alignaddr(ref);
         vis_ld64(ref[0], TMP0);
@@ -1136,7 +1137,7 @@
 }
 
 static void MC_put_y_8_vis (uint8_t * dest, const uint8_t * ref,
-                            const int stride, int height)
+                            const ptrdiff_t stride, int height)
 {
         ref = vis_alignaddr(ref);
         vis_ld64(ref[0], TMP0);
@@ -1226,7 +1227,7 @@
 }
 
 static void MC_avg_y_16_vis (uint8_t * dest, const uint8_t * ref,
-                             const int stride, int height)
+                             const ptrdiff_t stride, int height)
 {
         int stride_8 = stride + 8;
         int stride_16 = stride + 16;
@@ -1354,7 +1355,7 @@
 }
 
 static void MC_avg_y_8_vis (uint8_t * dest, const uint8_t * ref,
-                            const int stride, int height)
+                            const ptrdiff_t stride, int height)
 {
         int stride_8 = stride + 8;
 
@@ -1433,7 +1434,7 @@
 }
 
 static void MC_put_xy_16_vis (uint8_t * dest, const uint8_t * ref,
-                              const int stride, int height)
+                              const ptrdiff_t stride, int height)
 {
         unsigned long off = (unsigned long) ref & 0x7;
         unsigned long off_plus_1 = off + 1;
@@ -1597,7 +1598,7 @@
 }
 
 static void MC_put_xy_8_vis (uint8_t * dest, const uint8_t * ref,
-                             const int stride, int height)
+                             const ptrdiff_t stride, int height)
 {
         unsigned long off = (unsigned long) ref & 0x7;
         unsigned long off_plus_1 = off + 1;
@@ -1701,7 +1702,7 @@
 }
 
 static void MC_avg_xy_16_vis (uint8_t * dest, const uint8_t * ref,
-                              const int stride, int height)
+                              const ptrdiff_t stride, int height)
 {
         unsigned long off = (unsigned long) ref & 0x7;
         unsigned long off_plus_1 = off + 1;
@@ -1897,7 +1898,7 @@
 }
 
 static void MC_avg_xy_8_vis (uint8_t * dest, const uint8_t * ref,
-                             const int stride, int height)
+                             const ptrdiff_t stride, int height)
 {
         unsigned long off = (unsigned long) ref & 0x7;
         unsigned long off_plus_1 = off + 1;
@@ -2040,7 +2041,7 @@
  */
 
 static void MC_put_no_round_o_16_vis (uint8_t * dest, const uint8_t * ref,
-                                      const int stride, int height)
+                                      const ptrdiff_t stride, int height)
 {
         ref = vis_alignaddr(ref);
         do {    /* 5 cycles */
@@ -2061,7 +2062,7 @@
 }
 
 static void MC_put_no_round_o_8_vis (uint8_t * dest, const uint8_t * ref,
-                            const int stride, int height)
+                                     const ptrdiff_t stride, int height)
 {
         ref = vis_alignaddr(ref);
         do {    /* 4 cycles */
@@ -2080,7 +2081,7 @@
 
 
 static void MC_avg_no_round_o_16_vis (uint8_t * dest, const uint8_t * ref,
-                             const int stride, int height)
+                                      const ptrdiff_t stride, int height)
 {
         int stride_8 = stride + 8;
 
@@ -2239,100 +2240,8 @@
         vis_st64_2(TMP22, dest, 8);
 }
 
-static void MC_avg_no_round_o_8_vis (uint8_t * dest, const uint8_t * ref,
-                            const int stride, int height)
-{
-        ref = vis_alignaddr(ref);
-
-        vis_ld64(ref[0], TMP0);
-
-        vis_ld64(ref[8], TMP2);
-
-        vis_ld64(dest[0], DST_0);
-
-        vis_ld64(constants_fe[0], MASK_fe);
-
-        vis_ld64(constants_7f[0], MASK_7f);
-        vis_faligndata(TMP0, TMP2, REF_0);
-
-        vis_ld64(constants128[0], CONST_128);
-
-        ref += stride;
-        height = (height >> 1) - 1;
-
-        do {    /* 12 cycles */
-                vis_ld64(ref[0], TMP0);
-                vis_xor(DST_0, REF_0, TMP4);
-
-                vis_ld64(ref[8], TMP2);
-                vis_and(TMP4, MASK_fe, TMP4);
-
-                vis_and(DST_0, REF_0, TMP6);
-                vis_ld64_2(dest, stride, DST_0);
-                ref += stride;
-                vis_mul8x16(CONST_128, TMP4, TMP4);
-
-                vis_ld64(ref[0], TMP12);
-                vis_faligndata(TMP0, TMP2, REF_0);
-
-                vis_ld64(ref[8], TMP2);
-                vis_xor(DST_0, REF_0, TMP0);
-                ref += stride;
-
-                vis_and(TMP0, MASK_fe, TMP0);
-
-                vis_and(TMP4, MASK_7f, TMP4);
-
-                vis_padd16(TMP6, TMP4, TMP4);
-                vis_st64(TMP4, dest[0]);
-                dest += stride;
-                vis_mul8x16(CONST_128, TMP0, TMP0);
-
-                vis_and(DST_0, REF_0, TMP6);
-                vis_ld64_2(dest, stride, DST_0);
-
-                vis_faligndata(TMP12, TMP2, REF_0);
-
-                vis_and(TMP0, MASK_7f, TMP0);
-
-                vis_padd16(TMP6, TMP0, TMP4);
-                vis_st64(TMP4, dest[0]);
-                dest += stride;
-        } while (--height);
-
-        vis_ld64(ref[0], TMP0);
-        vis_xor(DST_0, REF_0, TMP4);
-
-        vis_ld64(ref[8], TMP2);
-        vis_and(TMP4, MASK_fe, TMP4);
-
-        vis_and(DST_0, REF_0, TMP6);
-        vis_ld64_2(dest, stride, DST_0);
-        vis_mul8x16(CONST_128, TMP4, TMP4);
-
-        vis_faligndata(TMP0, TMP2, REF_0);
-
-        vis_xor(DST_0, REF_0, TMP0);
-
-        vis_and(TMP0, MASK_fe, TMP0);
-
-        vis_and(TMP4, MASK_7f, TMP4);
-
-        vis_padd16(TMP6, TMP4, TMP4);
-        vis_st64(TMP4, dest[0]);
-        dest += stride;
-        vis_mul8x16(CONST_128, TMP0, TMP0);
-
-        vis_and(DST_0, REF_0, TMP6);
-
-        vis_and(TMP0, MASK_7f, TMP0);
-
-        vis_padd16(TMP6, TMP0, TMP4);
-        vis_st64(TMP4, dest[0]);
-}
-
 static void MC_put_no_round_x_16_vis (uint8_t * dest, const uint8_t * ref,
-                             const int stride, int height)
+                                      const ptrdiff_t stride, int height)
 {
         unsigned long off = (unsigned long) ref & 0x7;
         unsigned long off_plus_1 = off + 1;
@@ -2524,7 +2433,7 @@
 }
 
 static void MC_put_no_round_x_8_vis (uint8_t * dest, const uint8_t * ref,
-                            const int stride, int height)
+                                     const ptrdiff_t stride, int height)
 {
         unsigned long off = (unsigned long) ref & 0x7;
         unsigned long off_plus_1 = off + 1;
@@ -2647,7 +2556,7 @@
 }
 
 static void MC_avg_no_round_x_16_vis (uint8_t * dest, const uint8_t * ref,
-                             const int stride, int height)
+                                      const ptrdiff_t stride, int height)
 {
         unsigned long off = (unsigned long) ref & 0x7;
         unsigned long off_plus_1 = off + 1;
@@ -2736,173 +2645,8 @@
         } while (--height);
 }
 
-static void MC_avg_no_round_x_8_vis (uint8_t * dest, const uint8_t * ref,
-                            const int stride, int height)
-{
-        unsigned long off = (unsigned long) ref & 0x7;
-        unsigned long off_plus_1 = off + 1;
-        int stride_times_2 = stride << 1;
-
-        vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT);
-
-        vis_ld64(constants3[0], CONST_3);
-        vis_fzero(ZERO);
-        vis_ld64(constants256_512[0], CONST_256);
-
-        ref = vis_alignaddr(ref);
-        height >>= 2;
-        do {    /* 47 cycles */
-                vis_ld64(ref[0],   TMP0);
-
-                vis_ld64_2(ref, 8, TMP2);
-                ref += stride;
-
-                vis_alignaddr_g0((void *)off);
-
-                vis_ld64(ref[0],   TMP4);
-                vis_faligndata(TMP0, TMP2, REF_0);
-
-                vis_ld64_2(ref, 8, TMP6);
-                ref += stride;
-
-                vis_ld64(ref[0],   TMP8);
-
-                vis_ld64_2(ref, 8, TMP10);
-                ref += stride;
-                vis_faligndata(TMP4, TMP6, REF_4);
-
-                vis_ld64(ref[0],   TMP12);
-
-                vis_ld64_2(ref, 8, TMP14);
-                ref += stride;
-                vis_faligndata(TMP8, TMP10, REF_S0);
-
-                vis_faligndata(TMP12, TMP14, REF_S4);
-
-                if (off != 0x7) {
-                        vis_alignaddr_g0((void *)off_plus_1);
-
-                        vis_ld64(dest[0], DST_0);
-                        vis_faligndata(TMP0, TMP2, REF_2);
-
-                        vis_ld64_2(dest, stride, DST_2);
-                        vis_faligndata(TMP4, TMP6, REF_6);
-
-                        vis_faligndata(TMP8, TMP10, REF_S2);
-
-                        vis_faligndata(TMP12, TMP14, REF_S6);
-                } else {
-                        vis_ld64(dest[0], DST_0);
-                        vis_src1(TMP2, REF_2);
-
-                        vis_ld64_2(dest, stride, DST_2);
-                        vis_src1(TMP6, REF_6);
-
-                        vis_src1(TMP10, REF_S2);
-
-                        vis_src1(TMP14, REF_S6);
-                }
-
-                vis_pmerge(ZERO,     REF_0,     TMP0);
-                vis_mul8x16au(REF_0_1, CONST_256, TMP2);
-
-                vis_pmerge(ZERO,     REF_2,     TMP4);
-                vis_mul8x16au(REF_2_1, CONST_256, TMP6);
-
-                vis_padd16(TMP0, CONST_3, TMP0);
-                vis_mul8x16al(DST_0,   CONST_512, TMP16);
-
-                vis_padd16(TMP2, CONST_3, TMP2);
-                vis_mul8x16al(DST_1,   CONST_512, TMP18);
-
-                vis_padd16(TMP0, TMP4, TMP0);
-                vis_mul8x16au(REF_4, CONST_256, TMP8);
-
-                vis_padd16(TMP2, TMP6, TMP2);
-                vis_mul8x16au(REF_4_1, CONST_256, TMP10);
-
-                vis_padd16(TMP0, TMP16, TMP0);
-                vis_mul8x16au(REF_6, CONST_256, TMP12);
-
-                vis_padd16(TMP2, TMP18, TMP2);
-                vis_mul8x16au(REF_6_1, CONST_256, TMP14);
-
-                vis_padd16(TMP8, CONST_3, TMP8);
-                vis_mul8x16al(DST_2, CONST_512, TMP16);
-
-                vis_padd16(TMP8, TMP12, TMP8);
-                vis_mul8x16al(DST_3, CONST_512, TMP18);
-
-                vis_padd16(TMP10, TMP14, TMP10);
-                vis_pack16(TMP0, DST_0);
-
-                vis_pack16(TMP2, DST_1);
-                vis_st64(DST_0, dest[0]);
-                dest += stride;
-                vis_padd16(TMP10, CONST_3, TMP10);
-
-                vis_ld64_2(dest, stride, DST_0);
-                vis_padd16(TMP8, TMP16, TMP8);
-
-                vis_ld64_2(dest, stride_times_2, TMP4/*DST_2*/);
-                vis_padd16(TMP10, TMP18, TMP10);
-                vis_pack16(TMP8, DST_2);
-
-                vis_pack16(TMP10, DST_3);
-                vis_st64(DST_2, dest[0]);
-                dest += stride;
-
-                vis_mul8x16au(REF_S0_1, CONST_256, TMP2);
-                vis_pmerge(ZERO,     REF_S0,     TMP0);
-
-                vis_pmerge(ZERO,     REF_S2,     TMP24);
-                vis_mul8x16au(REF_S2_1, CONST_256, TMP6);
-
-                vis_padd16(TMP0, CONST_3, TMP0);
-                vis_mul8x16au(REF_S4, CONST_256, TMP8);
-
-                vis_padd16(TMP2, CONST_3, TMP2);
-                vis_mul8x16au(REF_S4_1, CONST_256, TMP10);
-
-                vis_padd16(TMP0, TMP24, TMP0);
-                vis_mul8x16au(REF_S6, CONST_256, TMP12);
-
-                vis_padd16(TMP2, TMP6, TMP2);
-                vis_mul8x16au(REF_S6_1, CONST_256, TMP14);
-
-                vis_padd16(TMP8, CONST_3, TMP8);
-                vis_mul8x16al(DST_0,   CONST_512, TMP16);
-
-                vis_padd16(TMP10, CONST_3, TMP10);
-                vis_mul8x16al(DST_1,   CONST_512, TMP18);
-
-                vis_padd16(TMP8, TMP12, TMP8);
-                vis_mul8x16al(TMP4/*DST_2*/, CONST_512, TMP20);
-
-                vis_mul8x16al(TMP5/*DST_3*/, CONST_512, TMP22);
-                vis_padd16(TMP0, TMP16, TMP0);
-
-                vis_padd16(TMP2, TMP18, TMP2);
-                vis_pack16(TMP0, DST_0);
-
-                vis_padd16(TMP10, TMP14, TMP10);
-                vis_pack16(TMP2, DST_1);
-                vis_st64(DST_0, dest[0]);
-                dest += stride;
-
-                vis_padd16(TMP8, TMP20, TMP8);
-
-                vis_padd16(TMP10, TMP22, TMP10);
-                vis_pack16(TMP8, DST_2);
-
-                vis_pack16(TMP10, DST_3);
-                vis_st64(DST_2, dest[0]);
-                dest += stride;
-        } while (--height);
-}
-
 static void MC_put_no_round_y_16_vis (uint8_t * dest, const uint8_t * ref,
-                             const int stride, int height)
+                                      const ptrdiff_t stride, int height)
 {
         ref = vis_alignaddr(ref);
         vis_ld64(ref[0], TMP0);
@@ -3056,7 +2800,7 @@
 }
 
 static void MC_put_no_round_y_8_vis (uint8_t * dest, const uint8_t * ref,
-                            const int stride, int height)
+                                     const ptrdiff_t stride, int height)
 {
         ref = vis_alignaddr(ref);
         vis_ld64(ref[0], TMP0);
@@ -3146,7 +2890,7 @@
 }
 
 static void MC_avg_no_round_y_16_vis (uint8_t * dest, const uint8_t * ref,
-                             const int stride, int height)
+                                      const ptrdiff_t stride, int height)
 {
         int stride_8 = stride + 8;
         int stride_16 = stride + 16;
@@ -3273,87 +3017,8 @@
         } while (--height);
 }
 
-static void MC_avg_no_round_y_8_vis (uint8_t * dest, const uint8_t * ref,
-                            const int stride, int height)
-{
-        int stride_8 = stride + 8;
-
-        vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT);
-
-        ref = vis_alignaddr(ref);
-
-        vis_ld64(ref[ 0], TMP0);
-        vis_fzero(ZERO);
-
-        vis_ld64(ref[ 8], TMP2);
-
-        vis_ld64(constants3[0], CONST_3);
-        vis_faligndata(TMP0, TMP2, REF_2);
-
-        vis_ld64(constants256_512[0], CONST_256);
-
-        height >>= 1;
-        do {    /* 20 cycles */
-                vis_ld64_2(ref, stride, TMP0);
-                vis_pmerge(ZERO,       REF_2,     TMP8);
-                vis_mul8x16au(REF_2_1, CONST_256, TMP10);
-
-                vis_ld64_2(ref, stride_8, TMP2);
-                ref += stride;
-
-                vis_ld64(dest[0], DST_0);
-
-                vis_ld64_2(dest, stride, DST_2);
-                vis_faligndata(TMP0, TMP2, REF_0);
-
-                vis_ld64_2(ref, stride, TMP4);
-                vis_mul8x16al(DST_0,   CONST_512, TMP16);
-                vis_pmerge(ZERO,       REF_0,     TMP12);
-
-                vis_ld64_2(ref, stride_8, TMP6);
-                ref += stride;
-                vis_mul8x16al(DST_1,   CONST_512, TMP18);
-                vis_pmerge(ZERO,       REF_0_1,   TMP14);
-
-                vis_padd16(TMP12, CONST_3, TMP12);
-                vis_mul8x16al(DST_2,   CONST_512, TMP24);
-
-                vis_padd16(TMP14, CONST_3, TMP14);
-                vis_mul8x16al(DST_3,   CONST_512, TMP26);
-
-                vis_faligndata(TMP4, TMP6, REF_2);
-
-                vis_padd16(TMP8, TMP12, TMP8);
-
-                vis_padd16(TMP10, TMP14, TMP10);
-                vis_mul8x16au(REF_2,   CONST_256, TMP20);
-
-                vis_padd16(TMP8, TMP16, TMP0);
-                vis_mul8x16au(REF_2_1, CONST_256, TMP22);
-
-                vis_padd16(TMP10, TMP18, TMP2);
-                vis_pack16(TMP0, DST_0);
-
-                vis_pack16(TMP2, DST_1);
-                vis_st64(DST_0, dest[0]);
-                dest += stride;
-                vis_padd16(TMP12, TMP20, TMP12);
-
-                vis_padd16(TMP14, TMP22, TMP14);
-
-                vis_padd16(TMP12, TMP24, TMP0);
-
-                vis_padd16(TMP14, TMP26, TMP2);
-                vis_pack16(TMP0, DST_2);
-
-                vis_pack16(TMP2, DST_3);
-                vis_st64(DST_2, dest[0]);
-                dest += stride;
-        } while (--height);
-}
-
 static void MC_put_no_round_xy_16_vis (uint8_t * dest, const uint8_t * ref,
-                                       const int stride, int height)
+                                       const ptrdiff_t stride, int height)
 {
         unsigned long off = (unsigned long) ref & 0x7;
         unsigned long off_plus_1 = off + 1;
@@ -3517,7 +3182,7 @@
 }
 
 static void MC_put_no_round_xy_8_vis (uint8_t * dest, const uint8_t * ref,
-                                      const int stride, int height)
+                                      const ptrdiff_t stride, int height)
 {
         unsigned long off = (unsigned long) ref & 0x7;
         unsigned long off_plus_1 = off + 1;
@@ -3621,7 +3286,7 @@
 }
 
 static void MC_avg_no_round_xy_16_vis (uint8_t * dest, const uint8_t * ref,
-                                       const int stride, int height)
+                                       const ptrdiff_t stride, int height)
 {
         unsigned long off = (unsigned long) ref & 0x7;
         unsigned long off_plus_1 = off + 1;
@@ -3816,126 +3481,6 @@
         } while (--height);
 }
 
-static void MC_avg_no_round_xy_8_vis (uint8_t * dest, const uint8_t * ref,
-                                      const int stride, int height)
-{
-        unsigned long off = (unsigned long) ref & 0x7;
-        unsigned long off_plus_1 = off + 1;
-        int stride_8 = stride + 8;
-
-        vis_set_gsr(4 << VIS_GSR_SCALEFACT_SHIFT);
-
-        ref = vis_alignaddr(ref);
-
-        vis_ld64(ref[0], TMP0);
-        vis_fzero(ZERO);
-
-        vis_ld64_2(ref, 8, TMP2);
-
-        vis_ld64(constants6[0], CONST_6);
-
-        vis_ld64(constants256_1024[0], CONST_256);
-        vis_faligndata(TMP0, TMP2, REF_S0);
-
-        if (off != 0x7) {
-                vis_alignaddr_g0((void *)off_plus_1);
-                vis_faligndata(TMP0, TMP2, REF_S2);
-        } else {
-                vis_src1(TMP2, REF_S2);
-        }
-
-        height >>= 1;
-        do {    /* 31 cycles */
-                vis_ld64_2(ref, stride, TMP0);
-                vis_mul8x16au(REF_S0, CONST_256, TMP8);
-                vis_pmerge(ZERO,      REF_S0_1,  TMP10);
-
-                vis_ld64_2(ref, stride_8, TMP2);
-                ref += stride;
-                vis_mul8x16au(REF_S2, CONST_256, TMP12);
-                vis_pmerge(ZERO,      REF_S2_1,  TMP14);
-
-                vis_alignaddr_g0((void *)off);
-
-                vis_ld64_2(ref, stride, TMP4);
-                vis_faligndata(TMP0, TMP2, REF_S4);
-
-                vis_ld64_2(ref, stride_8, TMP6);
-                ref += stride;
-
-                vis_ld64(dest[0], DST_0);
-                vis_faligndata(TMP4, TMP6, REF_S0);
-
-                vis_ld64_2(dest, stride, DST_2);
-
-                if (off != 0x7) {
-                        vis_alignaddr_g0((void *)off_plus_1);
-                        vis_faligndata(TMP0, TMP2, REF_S6);
-                        vis_faligndata(TMP4, TMP6, REF_S2);
-                } else {
-                        vis_src1(TMP2, REF_S6);
-                        vis_src1(TMP6, REF_S2);
-                }
-
-                vis_mul8x16al(DST_0,   CONST_1024, TMP30);
-                vis_pmerge(ZERO, REF_S4, TMP22);
-
-                vis_mul8x16al(DST_1,   CONST_1024, TMP32);
-                vis_pmerge(ZERO,      REF_S4_1,  TMP24);
-
-                vis_mul8x16au(REF_S6, CONST_256, TMP26);
-                vis_pmerge(ZERO,      REF_S6_1,  TMP28);
-
-                vis_mul8x16au(REF_S0, CONST_256, REF_S4);
-                vis_padd16(TMP22, CONST_6, TMP22);
-
-                vis_mul8x16au(REF_S0_1, CONST_256, REF_S6);
-                vis_padd16(TMP24, CONST_6, TMP24);
-
-                vis_mul8x16al(DST_2,   CONST_1024, REF_0);
-                vis_padd16(TMP22, TMP26, TMP22);
-
-                vis_mul8x16al(DST_3,   CONST_1024, REF_2);
-                vis_padd16(TMP24, TMP28, TMP24);
-
-                vis_mul8x16au(REF_S2, CONST_256, TMP26);
-                vis_padd16(TMP8, TMP22, TMP8);
-
-                vis_mul8x16au(REF_S2_1, CONST_256, TMP28);
-                vis_padd16(TMP10, TMP24, TMP10);
-
-                vis_padd16(TMP8, TMP12, TMP8);
-
-                vis_padd16(TMP10, TMP14, TMP10);
-
-                vis_padd16(TMP8, TMP30, TMP8);
-
-                vis_padd16(TMP10, TMP32, TMP10);
-                vis_pack16(TMP8, DST_0);
-
-                vis_pack16(TMP10, DST_1);
-                vis_st64(DST_0, dest[0]);
-                dest += stride;
-
-                vis_padd16(REF_S4, TMP22, TMP12);
-
-                vis_padd16(REF_S6, TMP24, TMP14);
-
-                vis_padd16(TMP12, TMP26, TMP12);
-
-                vis_padd16(TMP14, TMP28, TMP14);
-
-                vis_padd16(TMP12, REF_0, TMP12);
-
-                vis_padd16(TMP14, REF_2, TMP14);
-                vis_pack16(TMP12, DST_2);
-
-                vis_pack16(TMP14, DST_3);
-                vis_st64(DST_2, dest[0]);
-                dest += stride;
-        } while (--height);
-}
-
 /* End of no rounding code */
 
 #define ACCEL_SPARC_VIS 1
@@ -3950,22 +3495,20 @@
 }
 
 /* libavcodec initialization code */
-void ff_dsputil_init_vis(DSPContext* c, AVCodecContext *avctx)
+av_cold void ff_dsputil_init_vis(DSPContext *c, AVCodecContext *avctx)
 {
   /* VIS-specific optimizations */
   int accel = vis_level ();
   const int high_bit_depth = avctx->bits_per_raw_sample > 8;
 
-  if (accel & ACCEL_SPARC_VIS) {
-      if (avctx->bits_per_raw_sample <= 8 &&
-          avctx->idct_algo == FF_IDCT_SIMPLEVIS) {
+  if (accel & ACCEL_SPARC_VIS && !high_bit_depth) {
+      if (avctx->idct_algo == FF_IDCT_SIMPLEVIS) {
           c->idct_put = ff_simple_idct_put_vis;
           c->idct_add = ff_simple_idct_add_vis;
           c->idct     = ff_simple_idct_vis;
           c->idct_permutation_type = FF_TRANSPOSE_IDCT_PERM;
       }
 
-      if (!high_bit_depth) {
       c->put_pixels_tab[0][0] = MC_put_o_16_vis;
       c->put_pixels_tab[0][1] = MC_put_x_16_vis;
       c->put_pixels_tab[0][2] = MC_put_y_16_vis;
@@ -3996,15 +3539,9 @@
       c->put_no_rnd_pixels_tab[1][2] = MC_put_no_round_y_8_vis;
       c->put_no_rnd_pixels_tab[1][3] = MC_put_no_round_xy_8_vis;
 
-      c->avg_no_rnd_pixels_tab[0][0] = MC_avg_no_round_o_16_vis;
-      c->avg_no_rnd_pixels_tab[0][1] = MC_avg_no_round_x_16_vis;
-      c->avg_no_rnd_pixels_tab[0][2] = MC_avg_no_round_y_16_vis;
-      c->avg_no_rnd_pixels_tab[0][3] = MC_avg_no_round_xy_16_vis;
-
-      c->avg_no_rnd_pixels_tab[1][0] = MC_avg_no_round_o_8_vis;
-      c->avg_no_rnd_pixels_tab[1][1] = MC_avg_no_round_x_8_vis;
-      c->avg_no_rnd_pixels_tab[1][2] = MC_avg_no_round_y_8_vis;
-      c->avg_no_rnd_pixels_tab[1][3] = MC_avg_no_round_xy_8_vis;
-      }
+      c->avg_no_rnd_pixels_tab[0] = MC_avg_no_round_o_16_vis;
+      c->avg_no_rnd_pixels_tab[1] = MC_avg_no_round_x_16_vis;
+      c->avg_no_rnd_pixels_tab[2] = MC_avg_no_round_y_16_vis;
+      c->avg_no_rnd_pixels_tab[3] = MC_avg_no_round_xy_16_vis;
   }
 }
diff --git a/libavcodec/sparc/dsputil_vis.h b/libavcodec/sparc/dsputil_vis.h
index e1cbcb4..d7e2e63 100644
--- a/libavcodec/sparc/dsputil_vis.h
+++ b/libavcodec/sparc/dsputil_vis.h
@@ -20,10 +20,9 @@
 #define AVCODEC_SPARC_DSPUTIL_VIS_H
 
 #include <stdint.h>
-#include "libavcodec/dsputil.h"
 
-void ff_simple_idct_put_vis(uint8_t *dest, int line_size, DCTELEM *data);
-void ff_simple_idct_add_vis(uint8_t *dest, int line_size, DCTELEM *data);
-void ff_simple_idct_vis(DCTELEM *data);
+void ff_simple_idct_put_vis(uint8_t *dest, int line_size, int16_t *data);
+void ff_simple_idct_add_vis(uint8_t *dest, int line_size, int16_t *data);
+void ff_simple_idct_vis(int16_t *data);
 
 #endif /* AVCODEC_SPARC_DSPUTIL_VIS_H */
diff --git a/libavcodec/sparc/simple_idct_vis.c b/libavcodec/sparc/simple_idct_vis.c
index 45ca010..c9923e0 100644
--- a/libavcodec/sparc/simple_idct_vis.c
+++ b/libavcodec/sparc/simple_idct_vis.c
@@ -24,7 +24,6 @@
 
 #include <stdint.h>
 
-#include "libavcodec/dsputil.h"
 #include "dsputil_vis.h"
 #include "libavutil/mem.h"
 
@@ -388,7 +387,7 @@
         "st %%f14, [%12+" dest "] \n\t"\
 
 
-void ff_simple_idct_vis(DCTELEM *data) {
+void ff_simple_idct_vis(int16_t *data) {
     int out1, out2, out3, out4;
     DECLARE_ALIGNED(8, int16_t, temp)[8*8];
 
@@ -428,7 +427,7 @@
     );
 }
 
-void ff_simple_idct_put_vis(uint8_t *dest, int line_size, DCTELEM *data) {
+void ff_simple_idct_put_vis(uint8_t *dest, int line_size, int16_t *data) {
     int out1, out2, out3, out4, out5;
     int r1, r2, r3, r4, r5, r6, r7;
 
@@ -478,7 +477,7 @@
     );
 }
 
-void ff_simple_idct_add_vis(uint8_t *dest, int line_size, DCTELEM *data) {
+void ff_simple_idct_add_vis(uint8_t *dest, int line_size, int16_t *data) {
     int out1, out2, out3, out4, out5, out6;
     int r1, r2, r3, r4, r5, r6, r7;
 
diff --git a/libavcodec/srtdec.c b/libavcodec/srtdec.c
index ddeabd2..267561c 100644
--- a/libavcodec/srtdec.c
+++ b/libavcodec/srtdec.c
@@ -50,7 +50,7 @@
 static const char *srt_to_ass(AVCodecContext *avctx, char *out, char *out_end,
                               const char *in, int x1, int y1, int x2, int y2)
 {
-    char c, *param, buffer[128], tmp[128];
+    char *param, buffer[128], tmp[128];
     int len, tag_close, sptr = 1, line_start = 1, an = 0, end = 0;
     SrtStack stack[16];
 
@@ -89,16 +89,18 @@
             break;
         case '{':    /* skip all {\xxx} substrings except for {\an%d}
                         and all microdvd like styles such as {Y:xxx} */
-            an += sscanf(in, "{\\an%*1u}%c", &c) == 1;
-            if ((an != 1 && sscanf(in, "{\\%*[^}]}%n%c", &len, &c) > 0) ||
-                sscanf(in, "{%*1[CcFfoPSsYy]:%*[^}]}%n%c", &len, &c) > 0) {
+            len = 0;
+            an += sscanf(in, "{\\an%*1u}%n", &len) >= 0 && len > 0;
+            if ((an != 1 && (len = 0, sscanf(in, "{\\%*[^}]}%n", &len) >= 0 && len > 0)) ||
+                (len = 0, sscanf(in, "{%*1[CcFfoPSsYy]:%*[^}]}%n", &len) >= 0 && len > 0)) {
                 in += len - 1;
             } else
                 *out++ = *in;
             break;
         case '<':
             tag_close = in[1] == '/';
-            if (sscanf(in+tag_close+1, "%127[^>]>%n%c", buffer, &len,&c) >= 2) {
+            len = 0;
+            if (sscanf(in+tag_close+1, "%127[^>]>%n", buffer, &len) >= 1 && len > 0) {
                 if ((param = strchr(buffer, ' ')))
                     *param++ = 0;
                 if ((!tag_close && sptr < FF_ARRAY_ELEMS(stack)) ||
@@ -234,7 +236,7 @@
         return avpkt->size;
 
     while (ptr < end && *ptr) {
-        if (avctx->codec->id == CODEC_ID_SRT) {
+        if (avctx->codec->id == AV_CODEC_ID_SRT) {
             ptr = read_ts(ptr, &ts_start, &ts_end, &x1, &y1, &x2, &y2);
             if (!ptr)
                 break;
diff --git a/libavcodec/srtenc.c b/libavcodec/srtenc.c
index 56f29e9..3036a7f 100644
--- a/libavcodec/srtenc.c
+++ b/libavcodec/srtenc.c
@@ -204,7 +204,7 @@
 {
     SRTContext *s = priv;
 
-    if (s->avctx->codec->id == CODEC_ID_SRT) {
+    if (s->avctx->codec->id == AV_CODEC_ID_SRT) {
     char buffer[32];
     int len = snprintf(buffer, sizeof(buffer),
                        "  X1:%03u X2:%03u Y1:%03u Y2:%03u", x1, x2, y1, y2);
@@ -218,8 +218,11 @@
 
 static void srt_end_cb(void *priv)
 {
+    SRTContext *s = priv;
+
     srt_stack_push_pop(priv, 0, 1);
-    srt_print(priv, "\r\n\r\n");
+    if (s->avctx->codec->id == AV_CODEC_ID_SRT)
+        srt_print(priv, "\r\n\r\n");
 }
 
 static const ASSCodesCallbacks srt_callbacks = {
@@ -254,7 +257,7 @@
 
         dialog = ff_ass_split_dialog(s->ass_ctx, sub->rects[i]->ass, 0, &num);
         for (; dialog && num--; dialog++) {
-            if (avctx->codec->id == CODEC_ID_SRT) {
+            if (avctx->codec->id == AV_CODEC_ID_SRT) {
                 int sh, sm, ss, sc = 10 * dialog->start;
                 int eh, em, es, ec = 10 * dialog->end;
                 sh = sc/3600000;  sc -= 3600000*sh;
@@ -294,6 +297,7 @@
 }
 
 #if CONFIG_SRT_ENCODER
+/* deprecated encoder */
 AVCodec ff_srt_encoder = {
     .name           = "srt",
     .long_name      = NULL_IF_CONFIG_SMALL("SubRip subtitle with embedded timing"),
diff --git a/libavcodec/subviewerdec.c b/libavcodec/subviewerdec.c
index 0e8be90..63be418 100644
--- a/libavcodec/subviewerdec.c
+++ b/libavcodec/subviewerdec.c
@@ -31,17 +31,13 @@
 static int subviewer_event_to_ass(AVBPrint *buf, const char *p)
 {
     while (*p) {
-        char c;
-
-        if (sscanf(p, "%*u:%*u:%*u.%*u,%*u:%*u:%*u.%*u%c", &c) == 1)
-            p += strcspn(p, "\n") + 1;
         if (!strncmp(p, "[br]", 4)) {
             av_bprintf(buf, "\\N");
             p += 4;
         } else {
             if (p[0] == '\n' && p[1])
                 av_bprintf(buf, "\\N");
-            else if (*p != '\r')
+            else if (*p != '\n' && *p != '\r')
                 av_bprint_chars(buf, *p, 1);
             p++;
         }
@@ -54,10 +50,19 @@
 static int subviewer_decode_frame(AVCodecContext *avctx,
                                   void *data, int *got_sub_ptr, AVPacket *avpkt)
 {
+    char c;
     AVSubtitle *sub = data;
     const char *ptr = avpkt->data;
     AVBPrint buf;
 
+    /* To be removed later */
+    if (ptr && sscanf(ptr, "%*u:%*u:%*u.%*u,%*u:%*u:%*u.%*u%c", &c) == 1) {
+        av_log(avctx, AV_LOG_ERROR, "AVPacket is not clean (contains timing "
+               "information). You need to upgrade your libavformat or "
+               "sanitize your packet.\n");
+        return AVERROR_INVALIDDATA;
+    }
+
     av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
     // note: no need to rescale pts & duration since they are in the same
     // timebase as ASS (1/100)
diff --git a/libavcodec/sunrast.c b/libavcodec/sunrast.c
index eb245da..bfdf2b7 100644
--- a/libavcodec/sunrast.c
+++ b/libavcodec/sunrast.c
@@ -23,6 +23,7 @@
 #include "libavutil/intreadwrite.h"
 #include "libavutil/imgutils.h"
 #include "avcodec.h"
+#include "internal.h"
 #include "sunrast.h"
 
 typedef struct SUNRASTContext {
@@ -39,7 +40,8 @@
 }
 
 static int sunrast_decode_frame(AVCodecContext *avctx, void *data,
-                                int *data_size, AVPacket *avpkt) {
+                                int *got_frame, AVPacket *avpkt)
+{
     const uint8_t *buf       = avpkt->data;
     const uint8_t *buf_end   = avpkt->data + avpkt->size;
     SUNRASTContext * const s = avctx->priv_data;
@@ -118,7 +120,7 @@
 
     if (w != avctx->width || h != avctx->height)
         avcodec_set_dimensions(avctx, w, h);
-    if ((ret = avctx->get_buffer(avctx, p)) < 0) {
+    if ((ret = ff_get_buffer(avctx, p)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -221,7 +223,7 @@
     }
 
     *picture   = s->picture;
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
 
     return buf - bufstart;
 }
diff --git a/libavcodec/svq1.c b/libavcodec/svq1.c
index 0c19a6d..c219f22 100644
--- a/libavcodec/svq1.c
+++ b/libavcodec/svq1.c
@@ -37,7 +37,7 @@
 #include "svq1_vlc.h"
 
 /* standard video sizes */
-const struct svq1_frame_size ff_svq1_frame_size_table[7] = {
+const uint16_t ff_svq1_frame_size_table[7][2] = {
     { 160, 120 }, { 128,  96 }, { 176, 144 }, { 352, 288 },
     { 704, 576 }, { 240, 180 }, { 320, 240 }
 };
diff --git a/libavcodec/svq1.h b/libavcodec/svq1.h
index 9b132e2..8380f22 100644
--- a/libavcodec/svq1.h
+++ b/libavcodec/svq1.h
@@ -42,11 +42,6 @@
 #define SVQ1_BLOCK_INTER_4V     2
 #define SVQ1_BLOCK_INTRA        3
 
-struct svq1_frame_size {
-    uint16_t width;
-    uint16_t height;
-};
-
 uint16_t ff_svq1_packet_checksum(const uint8_t *data,
                                  const int length, int value);
 
@@ -59,6 +54,6 @@
 extern const uint16_t ff_svq1_intra_mean_vlc[256][2];
 extern const uint16_t ff_svq1_inter_mean_vlc[512][2];
 
-extern const struct svq1_frame_size ff_svq1_frame_size_table[7];
+extern const uint16_t ff_svq1_frame_size_table[7][2];
 
 #endif /* AVCODEC_SVQ1_H */
diff --git a/libavcodec/svq1dec.c b/libavcodec/svq1dec.c
index 27e9606..5b9a620 100644
--- a/libavcodec/svq1dec.c
+++ b/libavcodec/svq1dec.c
@@ -34,7 +34,8 @@
 
 #include "avcodec.h"
 #include "dsputil.h"
-#include "mpegvideo.h"
+#include "get_bits.h"
+#include "internal.h"
 #include "mathops.h"
 #include "svq1.h"
 
@@ -56,6 +57,16 @@
     int y;
 } svq1_pmv;
 
+typedef struct SVQ1Context {
+    DSPContext dsp;
+    GetBitContext gb;
+    AVFrame *cur, *prev;
+    int width;
+    int height;
+    int frame_code;
+    int nonref;         // 1 if the current frame won't be referenced
+} SVQ1Context;
+
 static const uint8_t string_table[256] = {
     0x00, 0xD5, 0x7F, 0xAA, 0xFE, 0x2B, 0x81, 0x54,
     0x29, 0xFC, 0x56, 0x83, 0xD7, 0x02, 0xA8, 0x7D,
@@ -130,32 +141,6 @@
         n2 &= n3 & 0x00FF00FF;                                          \
     }
 
-#define SVQ1_DO_CODEBOOK_INTRA()                                        \
-    for (y = 0; y < height; y++) {                                      \
-        for (x = 0; x < width / 4; x++, codebook++) {                   \
-            n1 = n4;                                                    \
-            n2 = n4;                                                    \
-            SVQ1_ADD_CODEBOOK()                                         \
-            /* store result */                                          \
-            dst[x] = n1 << 8 | n2;                                      \
-        }                                                               \
-        dst += pitch / 4;                                               \
-    }
-
-#define SVQ1_DO_CODEBOOK_NONINTRA()                                     \
-    for (y = 0; y < height; y++) {                                      \
-        for (x = 0; x < width / 4; x++, codebook++) {                   \
-            n3 = dst[x];                                                \
-            /* add mean value to vector */                              \
-            n1 = n4 + ((n3 & 0xFF00FF00) >> 8);                         \
-            n2 = n4 +  (n3 & 0x00FF00FF);                               \
-            SVQ1_ADD_CODEBOOK()                                         \
-            /* store result */                                          \
-            dst[x] = n1 << 8 | n2;                                      \
-        }                                                               \
-        dst += pitch / 4;                                               \
-    }
-
 #define SVQ1_CALC_CODEBOOK_ENTRIES(cbook)                               \
     codebook = (const uint32_t *)cbook[level];                          \
     if (stages > 0)                                                     \
@@ -216,7 +201,17 @@
                 memset(&dst[y * (pitch / 4)], mean, width);
         } else {
             SVQ1_CALC_CODEBOOK_ENTRIES(ff_svq1_intra_codebooks);
-            SVQ1_DO_CODEBOOK_INTRA()
+
+            for (y = 0; y < height; y++) {
+                for (x = 0; x < width / 4; x++, codebook++) {
+                    n1 = n4;
+                    n2 = n4;
+                    SVQ1_ADD_CODEBOOK()
+                    /* store result */
+                    dst[x] = n1 << 8 | n2;
+                }
+                dst += pitch / 4;
+            }
         }
     }
 
@@ -264,7 +259,19 @@
         mean = get_vlc2(bitbuf, svq1_inter_mean.table, 9, 3) - 256;
 
         SVQ1_CALC_CODEBOOK_ENTRIES(ff_svq1_inter_codebooks);
-        SVQ1_DO_CODEBOOK_NONINTRA()
+
+        for (y = 0; y < height; y++) {
+            for (x = 0; x < width / 4; x++, codebook++) {
+                n3 = dst[x];
+                /* add mean value to vector */
+                n1 = n4 + ((n3 & 0xFF00FF00) >> 8);
+                n2 = n4 +  (n3 & 0x00FF00FF);
+                SVQ1_ADD_CODEBOOK()
+                /* store result */
+                dst[x] = n1 << 8 | n2;
+            }
+            dst += pitch / 4;
+        }
     }
     return 0;
 }
@@ -312,7 +319,7 @@
     }
 }
 
-static int svq1_motion_inter_block(MpegEncContext *s, GetBitContext *bitbuf,
+static int svq1_motion_inter_block(DSPContext *dsp, GetBitContext *bitbuf,
                                    uint8_t *current, uint8_t *previous,
                                    int pitch, svq1_pmv *motion, int x, int y)
 {
@@ -351,12 +358,12 @@
     src = &previous[(x + (mv.x >> 1)) + (y + (mv.y >> 1)) * pitch];
     dst = current;
 
-    s->dsp.put_pixels_tab[0][(mv.y & 1) << 1 | (mv.x & 1)](dst, src, pitch, 16);
+    dsp->put_pixels_tab[0][(mv.y & 1) << 1 | (mv.x & 1)](dst, src, pitch, 16);
 
     return 0;
 }
 
-static int svq1_motion_inter_4v_block(MpegEncContext *s, GetBitContext *bitbuf,
+static int svq1_motion_inter_4v_block(DSPContext *dsp, GetBitContext *bitbuf,
                                       uint8_t *current, uint8_t *previous,
                                       int pitch, svq1_pmv *motion, int x, int y)
 {
@@ -422,7 +429,7 @@
         src = &previous[(x + (mvx >> 1)) + (y + (mvy >> 1)) * pitch];
         dst = current;
 
-        s->dsp.put_pixels_tab[1][((mvy & 1) << 1) | (mvx & 1)](dst, src, pitch, 8);
+        dsp->put_pixels_tab[1][((mvy & 1) << 1) | (mvx & 1)](dst, src, pitch, 8);
 
         /* select next block */
         if (i & 1)
@@ -434,7 +441,8 @@
     return 0;
 }
 
-static int svq1_decode_delta_block(MpegEncContext *s, GetBitContext *bitbuf,
+static int svq1_decode_delta_block(AVCodecContext *avctx, DSPContext *dsp,
+                                   GetBitContext *bitbuf,
                                    uint8_t *current, uint8_t *previous,
                                    int pitch, svq1_pmv *motion, int x, int y)
 {
@@ -460,21 +468,22 @@
         break;
 
     case SVQ1_BLOCK_INTER:
-        result = svq1_motion_inter_block(s, bitbuf, current, previous,
+        result = svq1_motion_inter_block(dsp, bitbuf, current, previous,
                                          pitch, motion, x, y);
-        if (result) {
-            av_dlog(s->avctx, "Error in svq1_motion_inter_block %i\n", result);
+
+        if (result != 0) {
+            av_dlog(avctx, "Error in svq1_motion_inter_block %i\n", result);
             break;
         }
         result = svq1_decode_block_non_intra(bitbuf, current, pitch);
         break;
 
     case SVQ1_BLOCK_INTER_4V:
-        result = svq1_motion_inter_4v_block(s, bitbuf, current, previous,
+        result = svq1_motion_inter_4v_block(dsp, bitbuf, current, previous,
                                             pitch, motion, x, y);
-        if (result) {
-            av_dlog(s->avctx,
-                    "Error in svq1_motion_inter_4v_block %i\n", result);
+
+        if (result != 0) {
+            av_dlog(avctx, "Error in svq1_motion_inter_4v_block %i\n", result);
             break;
         }
         result = svq1_decode_block_non_intra(bitbuf, current, pitch);
@@ -502,8 +511,10 @@
     }
 }
 
-static int svq1_decode_frame_header(GetBitContext *bitbuf, MpegEncContext *s)
+static int svq1_decode_frame_header(AVCodecContext *avctx, AVFrame *frame)
 {
+    SVQ1Context *s = avctx->priv_data;
+    GetBitContext *bitbuf = &s->gb;
     int frame_size_code;
     int width  = s->width;
     int height = s->height;
@@ -511,29 +522,40 @@
     skip_bits(bitbuf, 8); /* temporal_reference */
 
     /* frame type */
-    s->pict_type = get_bits(bitbuf, 2) + 1;
-    if (s->pict_type == 4)
+    s->nonref = 0;
+    switch (get_bits(bitbuf, 2)) {
+    case 0:
+        frame->pict_type = AV_PICTURE_TYPE_I;
+        break;
+    case 2:
+        s->nonref = 1;
+    case 1:
+        frame->pict_type = AV_PICTURE_TYPE_P;
+        break;
+    default:
+        av_log(avctx, AV_LOG_ERROR, "Invalid frame type.\n");
         return AVERROR_INVALIDDATA;
+    }
 
-    if (s->pict_type == AV_PICTURE_TYPE_I) {
+    if (frame->pict_type == AV_PICTURE_TYPE_I) {
         /* unknown fields */
-        if (s->f_code == 0x50 || s->f_code == 0x60) {
+        if (s->frame_code == 0x50 || s->frame_code == 0x60) {
             int csum = get_bits(bitbuf, 16);
 
             csum = ff_svq1_packet_checksum(bitbuf->buffer,
                                            bitbuf->size_in_bits >> 3,
                                            csum);
 
-            av_dlog(s->avctx, "%s checksum (%02x) for packet data\n",
+            av_dlog(avctx, "%s checksum (%02x) for packet data\n",
                     (csum == 0) ? "correct" : "incorrect", csum);
         }
 
-        if ((s->f_code ^ 0x10) >= 0x50) {
+        if ((s->frame_code ^ 0x10) >= 0x50) {
             uint8_t msg[256];
 
             svq1_parse_string(bitbuf, msg);
 
-            av_log(s->avctx, AV_LOG_INFO,
+            av_log(avctx, AV_LOG_INFO,
                    "embedded message: \"%s\"\n", (char *)msg);
         }
 
@@ -553,8 +575,8 @@
                 return AVERROR_INVALIDDATA;
         } else {
             /* get width, height from table */
-            width  = ff_svq1_frame_size_table[frame_size_code].width;
-            height = ff_svq1_frame_size_table[frame_size_code].height;
+            width  = ff_svq1_frame_size_table[frame_size_code][0];
+            height = ff_svq1_frame_size_table[frame_size_code][1];
         }
     }
 
@@ -583,27 +605,30 @@
 }
 
 static int svq1_decode_frame(AVCodecContext *avctx, void *data,
-                             int *data_size, AVPacket *avpkt)
+                             int *got_frame, AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
-    MpegEncContext *s  = avctx->priv_data;
-    uint8_t *current, *previous;
+    SVQ1Context     *s = avctx->priv_data;
+    AVFrame       *cur = s->cur;
+    uint8_t *current;
     int result, i, x, y, width, height;
-    AVFrame *pict = data;
     svq1_pmv *pmv;
 
+    if (cur->data[0])
+        avctx->release_buffer(avctx, cur);
+
     /* initialize bit buffer */
     init_get_bits(&s->gb, buf, buf_size * 8);
 
     /* decode frame header */
-    s->f_code = get_bits(&s->gb, 22);
+    s->frame_code = get_bits(&s->gb, 22);
 
-    if ((s->f_code & ~0x70) || !(s->f_code & 0x60))
+    if ((s->frame_code & ~0x70) || !(s->frame_code & 0x60))
         return AVERROR_INVALIDDATA;
 
     /* swap some header bytes (why?) */
-    if (s->f_code != 0x20) {
+    if (s->frame_code != 0x20) {
         uint32_t *src = (uint32_t *)(buf + 4);
 
         if (buf_size < 36)
@@ -613,27 +638,21 @@
             src[i] = ((src[i] << 16) | (src[i] >> 16)) ^ src[7 - i];
     }
 
-    result = svq1_decode_frame_header(&s->gb, s);
-    if (result) {
-        av_dlog(s->avctx, "Error in svq1_decode_frame_header %i\n", result);
+    result = svq1_decode_frame_header(avctx, cur);
+    if (result != 0) {
+        av_dlog(avctx, "Error in svq1_decode_frame_header %i\n", result);
         return result;
     }
     avcodec_set_dimensions(avctx, s->width, s->height);
 
-    /* FIXME: This avoids some confusion for "B frames" without 2 references.
-     * This should be removed after libavcodec can handle more flexible
-     * picture types & ordering */
-    if (s->pict_type == AV_PICTURE_TYPE_B && s->last_picture_ptr == NULL)
-        return buf_size;
-
-    if ((avctx->skip_frame >= AVDISCARD_NONREF &&
-         s->pict_type == AV_PICTURE_TYPE_B)    ||
+    if ((avctx->skip_frame >= AVDISCARD_NONREF && s->nonref) ||
         (avctx->skip_frame >= AVDISCARD_NONKEY &&
-         s->pict_type != AV_PICTURE_TYPE_I)    ||
+         cur->pict_type != AV_PICTURE_TYPE_I) ||
         avctx->skip_frame >= AVDISCARD_ALL)
         return buf_size;
 
-    if ((result = ff_MPV_frame_start(s, avctx)) < 0)
+    result = ff_get_buffer(avctx, cur);
+    if (result < 0)
         return result;
 
     pmv = av_malloc((FFALIGN(s->width, 16) / 8 + 3) * sizeof(*pmv));
@@ -642,34 +661,27 @@
 
     /* decode y, u and v components */
     for (i = 0; i < 3; i++) {
-        int linesize;
+        int linesize = cur->linesize[i];
         if (i == 0) {
             width    = FFALIGN(s->width,  16);
             height   = FFALIGN(s->height, 16);
-            linesize = s->linesize;
         } else {
-            if (s->flags & CODEC_FLAG_GRAY)
+            if (avctx->flags & CODEC_FLAG_GRAY)
                 break;
             width    = FFALIGN(s->width  / 4, 16);
             height   = FFALIGN(s->height / 4, 16);
-            linesize = s->uvlinesize;
         }
 
-        current = s->current_picture.f.data[i];
+        current = cur->data[i];
 
-        if (s->pict_type == AV_PICTURE_TYPE_B)
-            previous = s->next_picture.f.data[i];
-        else
-            previous = s->last_picture.f.data[i];
-
-        if (s->pict_type == AV_PICTURE_TYPE_I) {
+        if (cur->pict_type == AV_PICTURE_TYPE_I) {
             /* keyframe */
             for (y = 0; y < height; y += 16) {
                 for (x = 0; x < width; x += 16) {
                     result = svq1_decode_block_intra(&s->gb, &current[x],
                                                      linesize);
                     if (result) {
-                        av_log(s->avctx, AV_LOG_ERROR,
+                        av_log(avctx, AV_LOG_ERROR,
                                "Error in svq1_decode_block %i (keyframe)\n",
                                result);
                         goto err;
@@ -679,15 +691,23 @@
             }
         } else {
             /* delta frame */
+            uint8_t *previous = s->prev->data[i];
+            if (!previous || s->prev->width != s->cur->width || s->prev->height != s->cur->height) {
+                av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n");
+                result = AVERROR_INVALIDDATA;
+                goto err;
+            }
+
             memset(pmv, 0, ((width / 8) + 3) * sizeof(svq1_pmv));
 
             for (y = 0; y < height; y += 16) {
                 for (x = 0; x < width; x += 16) {
-                    result = svq1_decode_delta_block(s, &s->gb, &current[x],
+                    result = svq1_decode_delta_block(avctx, &s->dsp,
+                                                     &s->gb, &current[x],
                                                      previous, linesize,
                                                      pmv, x, y);
                     if (result) {
-                        av_dlog(s->avctx,
+                        av_dlog(avctx,
                                 "Error in svq1_decode_delta_block %i\n",
                                 result);
                         goto err;
@@ -702,12 +722,12 @@
         }
     }
 
-    *pict = s->current_picture.f;
-    pict->qscale_table = NULL;
+    *(AVFrame*)data = *cur;
+    cur->qscale_table = NULL;
+    if (!s->nonref)
+        FFSWAP(AVFrame*, s->cur, s->prev);
 
-    ff_MPV_frame_end(s);
-
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     result     = buf_size;
 
 err:
@@ -717,22 +737,23 @@
 
 static av_cold int svq1_decode_init(AVCodecContext *avctx)
 {
-    MpegEncContext *s = avctx->priv_data;
+    SVQ1Context *s = avctx->priv_data;
     int i;
     int offset = 0;
 
-    ff_MPV_decode_defaults(s);
+    s->cur  = avcodec_alloc_frame();
+    s->prev = avcodec_alloc_frame();
+    if (!s->cur || !s->prev) {
+        avcodec_free_frame(&s->cur);
+        avcodec_free_frame(&s->prev);
+        return AVERROR(ENOMEM);
+    }
 
-    s->avctx            = avctx;
     s->width            = avctx->width  + 3 & ~3;
     s->height           = avctx->height + 3 & ~3;
-    s->codec_id         = avctx->codec->id;
     avctx->pix_fmt      = AV_PIX_FMT_YUV410P;
-    /* Not true, but DP frames and these behave like unidirectional B-frames. */
-    avctx->has_b_frames = 1;
-    s->flags            = avctx->flags;
-    if (ff_MPV_common_init(s) < 0)
-        return -1;
+
+    ff_dsputil_init(&s->dsp, avctx);
 
     INIT_VLC_STATIC(&svq1_block_type, 2, 4,
                     &ff_svq1_block_type_vlc[0][1], 2, 1,
@@ -775,23 +796,39 @@
 
 static av_cold int svq1_decode_end(AVCodecContext *avctx)
 {
-    MpegEncContext *s = avctx->priv_data;
+    SVQ1Context *s = avctx->priv_data;
 
-    ff_MPV_common_end(s);
+    if (s->cur->data[0])
+        avctx->release_buffer(avctx, s->cur);
+    if (s->prev->data[0])
+        avctx->release_buffer(avctx, s->prev);
+    avcodec_free_frame(&s->cur);
+    avcodec_free_frame(&s->prev);
+
     return 0;
 }
 
+static void svq1_flush(AVCodecContext *avctx)
+{
+    SVQ1Context *s = avctx->priv_data;
+
+    if (s->cur->data[0])
+        avctx->release_buffer(avctx, s->cur);
+    if (s->prev->data[0])
+        avctx->release_buffer(avctx, s->prev);
+}
+
 AVCodec ff_svq1_decoder = {
     .name           = "svq1",
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_SVQ1,
-    .priv_data_size = sizeof(MpegEncContext),
+    .priv_data_size = sizeof(SVQ1Context),
     .init           = svq1_decode_init,
     .close          = svq1_decode_end,
     .decode         = svq1_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .flush          = ff_mpeg_flush,
-    .pix_fmts       = (const enum PixelFormat[]) { AV_PIX_FMT_YUV410P,
-                                                   AV_PIX_FMT_NONE },
+    .flush          = svq1_flush,
+    .pix_fmts       = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV410P,
+                                                     AV_PIX_FMT_NONE },
     .long_name      = NULL_IF_CONFIG_SMALL("Sorenson Vector Quantizer 1 / Sorenson Video 1 / SVQ1"),
 };
diff --git a/libavcodec/svq1enc.c b/libavcodec/svq1enc.c
index 0877795..d12dfcd 100644
--- a/libavcodec/svq1enc.c
+++ b/libavcodec/svq1enc.c
@@ -27,7 +27,6 @@
  */
 
 #include "avcodec.h"
-#include "dsputil.h"
 #include "mpegvideo.h"
 #include "h263.h"
 #include "internal.h"
@@ -538,7 +537,7 @@
     int i, ret;
 
     if ((ret = ff_alloc_packet2(avctx, pkt, s->y_block_width * s->y_block_height *
-                             MAX_MB_BYTES*3 + FF_MIN_BUFFER_SIZE) < 0))
+                             MAX_MB_BYTES*3 + FF_MIN_BUFFER_SIZE)) < 0)
         return ret;
 
     if (avctx->pix_fmt != AV_PIX_FMT_YUV410P) {
@@ -547,8 +546,10 @@
     }
 
     if (!s->current_picture.data[0]) {
-        avctx->get_buffer(avctx, &s->current_picture);
-        avctx->get_buffer(avctx, &s->last_picture);
+        if ((ret = ff_get_buffer(avctx, &s->current_picture))< 0 ||
+            (ret = ff_get_buffer(avctx, &s->last_picture))   < 0) {
+            return ret;
+        }
         s->scratchbuf = av_malloc(s->current_picture.linesize[0] * 16 * 2);
     }
 
diff --git a/libavcodec/svq3.c b/libavcodec/svq3.c
index e195422..0481c80 100644
--- a/libavcodec/svq3.c
+++ b/libavcodec/svq3.c
@@ -40,7 +40,6 @@
  *  http://samples.mplayerhq.hu/V-codecs/SVQ3/Vertical400kbit.sorenson3.mov
  */
 #include "internal.h"
-#include "dsputil.h"
 #include "avcodec.h"
 #include "mpegvideo.h"
 #include "h264.h"
@@ -57,6 +56,7 @@
 #endif
 
 #include "svq1.h"
+#include "svq3.h"
 
 /**
  * @file
@@ -65,6 +65,9 @@
 
 typedef struct {
     H264Context h;
+    Picture *cur_pic;
+    Picture *next_pic;
+    Picture *last_pic;
     int halfpel_flag;
     int thirdpel_flag;
     int unknown_flag;
@@ -72,6 +75,11 @@
     uint32_t watermark_key;
     uint8_t *buf;
     int buf_size;
+    int adaptive_quant;
+    int next_p_frame_damaged;
+    int h_edge_pos;
+    int v_edge_pos;
+    int last_frame_output;
 } SVQ3Context;
 
 #define FULLPEL_MODE  1
@@ -139,7 +147,7 @@
     61694, 68745, 77615, 89113, 100253, 109366, 126635, 141533
 };
 
-void ff_svq3_luma_dc_dequant_idct_c(DCTELEM *output, DCTELEM *input, int qp)
+void ff_svq3_luma_dc_dequant_idct_c(int16_t *output, int16_t *input, int qp)
 {
     const int qmul = svq3_dequant_coeff[qp];
 #define stride 16
@@ -174,7 +182,7 @@
 }
 #undef stride
 
-void ff_svq3_add_idct_c(uint8_t *dst, DCTELEM *block,
+void ff_svq3_add_idct_c(uint8_t *dst, int16_t *block,
                         int stride, int qp, int dc)
 {
     const int qmul = svq3_dequant_coeff[qp];
@@ -210,25 +218,28 @@
         dst[i + stride * 2] = av_clip_uint8(dst[i + stride * 2] + ((z1 - z2) * qmul + rr >> 20));
         dst[i + stride * 3] = av_clip_uint8(dst[i + stride * 3] + ((z0 - z3) * qmul + rr >> 20));
     }
+
+    memset(block, 0, 16 * sizeof(int16_t));
 }
 
-static inline int svq3_decode_block(GetBitContext *gb, DCTELEM *block,
+static inline int svq3_decode_block(GetBitContext *gb, int16_t *block,
                                     int index, const int type)
 {
     static const uint8_t *const scan_patterns[4] =
     { luma_dc_zigzag_scan, zigzag_scan, svq3_scan, chroma_dc_scan };
 
-    int run, level, sign, vlc, limit;
+    int run, level, sign, limit;
+    unsigned vlc;
     const int intra           = 3 * type >> 2;
     const uint8_t *const scan = scan_patterns[type];
 
     for (limit = (16 >> intra); index < 16; index = limit, limit += 8) {
         for (; (vlc = svq3_get_ue_golomb(gb)) != 0; index++) {
-            if (vlc < 0)
+            if ((int32_t)vlc < 0)
                 return -1;
 
-            sign = (vlc & 0x1) - 1;
-            vlc  = vlc + 1 >> 1;
+            sign     = (vlc & 1) ? 0 : -1;
+            vlc      = vlc + 1 >> 1;
 
             if (type == 3) {
                 if (vlc < 3) {
@@ -269,12 +280,13 @@
     return 0;
 }
 
-static inline void svq3_mc_dir_part(MpegEncContext *s,
+static inline void svq3_mc_dir_part(SVQ3Context *s,
                                     int x, int y, int width, int height,
                                     int mx, int my, int dxy,
                                     int thirdpel, int dir, int avg)
 {
-    const Picture *pic = (dir == 0) ? &s->last_picture : &s->next_picture;
+    H264Context *h     = &s->h;
+    const Picture *pic = (dir == 0) ? s->last_pic : s->next_pic;
     uint8_t *src, *dest;
     int i, emu = 0;
     int blocksize = 2 - (width >> 3); // 16->0, 8->1, 4->2
@@ -284,33 +296,31 @@
 
     if (mx < 0 || mx >= s->h_edge_pos - width  - 1 ||
         my < 0 || my >= s->v_edge_pos - height - 1) {
-        if ((s->flags & CODEC_FLAG_EMU_EDGE))
-            emu = 1;
-
+        emu = 1;
         mx = av_clip(mx, -16, s->h_edge_pos - width  + 15);
         my = av_clip(my, -16, s->v_edge_pos - height + 15);
     }
 
     /* form component predictions */
-    dest = s->current_picture.f.data[0] + x + y * s->linesize;
-    src  = pic->f.data[0] + mx + my * s->linesize;
+    dest = h->cur_pic.f.data[0] + x + y * h->linesize;
+    src  = pic->f.data[0] + mx + my * h->linesize;
 
     if (emu) {
-        s->dsp.emulated_edge_mc(s->edge_emu_buffer, src, s->linesize,
-                                width + 1, height + 1,
-                                mx, my, s->h_edge_pos, s->v_edge_pos);
-        src = s->edge_emu_buffer;
+        h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src, h->linesize,
+                                 width + 1, height + 1,
+                                 mx, my, s->h_edge_pos, s->v_edge_pos);
+        src = h->edge_emu_buffer;
     }
     if (thirdpel)
-        (avg ? s->dsp.avg_tpel_pixels_tab
-             : s->dsp.put_tpel_pixels_tab)[dxy](dest, src, s->linesize,
+        (avg ? h->dsp.avg_tpel_pixels_tab
+             : h->dsp.put_tpel_pixels_tab)[dxy](dest, src, h->linesize,
                                                 width, height);
     else
-        (avg ? s->dsp.avg_pixels_tab
-             : s->dsp.put_pixels_tab)[blocksize][dxy](dest, src, s->linesize,
+        (avg ? h->dsp.avg_pixels_tab
+             : h->dsp.put_pixels_tab)[blocksize][dxy](dest, src, h->linesize,
                                                       height);
 
-    if (!(s->flags & CODEC_FLAG_GRAY)) {
+    if (!(h->flags & CODEC_FLAG_GRAY)) {
         mx     = mx + (mx < (int) x) >> 1;
         my     = my + (my < (int) y) >> 1;
         width  = width  >> 1;
@@ -318,35 +328,35 @@
         blocksize++;
 
         for (i = 1; i < 3; i++) {
-            dest = s->current_picture.f.data[i] + (x >> 1) + (y >> 1) * s->uvlinesize;
-            src  = pic->f.data[i] + mx + my * s->uvlinesize;
+            dest = h->cur_pic.f.data[i] + (x >> 1) + (y >> 1) * h->uvlinesize;
+            src  = pic->f.data[i] + mx + my * h->uvlinesize;
 
             if (emu) {
-                s->dsp.emulated_edge_mc(s->edge_emu_buffer, src, s->uvlinesize,
-                                        width + 1, height + 1,
-                                        mx, my, (s->h_edge_pos >> 1),
-                                        s->v_edge_pos >> 1);
-                src = s->edge_emu_buffer;
+                h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src, h->uvlinesize,
+                                         width + 1, height + 1,
+                                         mx, my, (s->h_edge_pos >> 1),
+                                         s->v_edge_pos >> 1);
+                src = h->edge_emu_buffer;
             }
             if (thirdpel)
-                (avg ? s->dsp.avg_tpel_pixels_tab
-                     : s->dsp.put_tpel_pixels_tab)[dxy](dest, src,
-                                                        s->uvlinesize,
+                (avg ? h->dsp.avg_tpel_pixels_tab
+                     : h->dsp.put_tpel_pixels_tab)[dxy](dest, src,
+                                                        h->uvlinesize,
                                                         width, height);
             else
-                (avg ? s->dsp.avg_pixels_tab
-                     : s->dsp.put_pixels_tab)[blocksize][dxy](dest, src,
-                                                              s->uvlinesize,
+                (avg ? h->dsp.avg_pixels_tab
+                     : h->dsp.put_pixels_tab)[blocksize][dxy](dest, src,
+                                                              h->uvlinesize,
                                                               height);
         }
     }
 }
 
-static inline int svq3_mc_dir(H264Context *h, int size, int mode,
+static inline int svq3_mc_dir(SVQ3Context *s, int size, int mode,
                               int dir, int avg)
 {
     int i, j, k, mx, my, dx, dy, x, y;
-    MpegEncContext *const s = (MpegEncContext *)h;
+    H264Context *h          = &s->h;
     const int part_width    = ((size & 5) == 4) ? 4 : 16 >> (size & 1);
     const int part_height   = 16 >> ((unsigned)(size + 1) / 3);
     const int extra_width   = (mode == PREDICT_MODE) ? -16 * 6 : 0;
@@ -355,19 +365,19 @@
 
     for (i = 0; i < 16; i += part_height)
         for (j = 0; j < 16; j += part_width) {
-            const int b_xy = (4 * s->mb_x + (j >> 2)) +
-                             (4 * s->mb_y + (i >> 2)) * h->b_stride;
+            const int b_xy = (4 * h->mb_x + (j >> 2)) +
+                             (4 * h->mb_y + (i >> 2)) * h->b_stride;
             int dxy;
-            x = 16 * s->mb_x + j;
-            y = 16 * s->mb_y + i;
+            x = 16 * h->mb_x + j;
+            y = 16 * h->mb_y + i;
             k = (j >> 2 & 1) + (i >> 1 & 2) +
                 (j >> 1 & 4) + (i      & 8);
 
             if (mode != PREDICT_MODE) {
                 pred_motion(h, k, part_width >> 2, dir, 1, &mx, &my);
             } else {
-                mx = s->next_picture.f.motion_val[0][b_xy][0] << 1;
-                my = s->next_picture.f.motion_val[0][b_xy][1] << 1;
+                mx = s->next_pic->f.motion_val[0][b_xy][0] << 1;
+                my = s->next_pic->f.motion_val[0][b_xy][1] << 1;
 
                 if (dir == 0) {
                     mx = mx * h->frame_num_offset /
@@ -390,11 +400,11 @@
             if (mode == PREDICT_MODE) {
                 dx = dy = 0;
             } else {
-                dy = svq3_get_se_golomb(&s->gb);
-                dx = svq3_get_se_golomb(&s->gb);
+                dy = svq3_get_se_golomb(&h->gb);
+                dx = svq3_get_se_golomb(&h->gb);
 
                 if (dx == INVALID_VLC || dy == INVALID_VLC) {
-                    av_log(h->s.avctx, AV_LOG_ERROR, "invalid MV vlc\n");
+                    av_log(h->avctx, AV_LOG_ERROR, "invalid MV vlc\n");
                     return -1;
                 }
             }
@@ -448,7 +458,7 @@
             }
 
             /* write back motion vectors */
-            fill_rectangle(s->current_picture.f.motion_val[dir][b_xy],
+            fill_rectangle(h->cur_pic.f.motion_val[dir][b_xy],
                            part_width >> 2, part_height >> 2, h->b_stride,
                            pack16to32(mx, my), 4);
         }
@@ -456,46 +466,45 @@
     return 0;
 }
 
-static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type)
+static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type)
 {
-    H264Context *h = &svq3->h;
+    H264Context *h = &s->h;
     int i, j, k, m, dir, mode;
     int cbp = 0;
     uint32_t vlc;
     int8_t *top, *left;
-    MpegEncContext *const s = (MpegEncContext *)h;
     const int mb_xy         = h->mb_xy;
-    const int b_xy          = 4 * s->mb_x + 4 * s->mb_y * h->b_stride;
+    const int b_xy          = 4 * h->mb_x + 4 * h->mb_y * h->b_stride;
 
-    h->top_samples_available      = (s->mb_y == 0) ? 0x33FF : 0xFFFF;
-    h->left_samples_available     = (s->mb_x == 0) ? 0x5F5F : 0xFFFF;
+    h->top_samples_available      = (h->mb_y == 0) ? 0x33FF : 0xFFFF;
+    h->left_samples_available     = (h->mb_x == 0) ? 0x5F5F : 0xFFFF;
     h->topright_samples_available = 0xFFFF;
 
     if (mb_type == 0) {           /* SKIP */
-        if (s->pict_type == AV_PICTURE_TYPE_P ||
-            s->next_picture.f.mb_type[mb_xy] == -1) {
-            svq3_mc_dir_part(s, 16 * s->mb_x, 16 * s->mb_y, 16, 16,
+        if (h->pict_type == AV_PICTURE_TYPE_P ||
+            s->next_pic->f.mb_type[mb_xy] == -1) {
+            svq3_mc_dir_part(s, 16 * h->mb_x, 16 * h->mb_y, 16, 16,
                              0, 0, 0, 0, 0, 0);
 
-            if (s->pict_type == AV_PICTURE_TYPE_B)
-                svq3_mc_dir_part(s, 16 * s->mb_x, 16 * s->mb_y, 16, 16,
+            if (h->pict_type == AV_PICTURE_TYPE_B)
+                svq3_mc_dir_part(s, 16 * h->mb_x, 16 * h->mb_y, 16, 16,
                                  0, 0, 0, 0, 1, 1);
 
             mb_type = MB_TYPE_SKIP;
         } else {
-            mb_type = FFMIN(s->next_picture.f.mb_type[mb_xy], 6);
-            if (svq3_mc_dir(h, mb_type, PREDICT_MODE, 0, 0) < 0)
+            mb_type = FFMIN(s->next_pic->f.mb_type[mb_xy], 6);
+            if (svq3_mc_dir(s, mb_type, PREDICT_MODE, 0, 0) < 0)
                 return -1;
-            if (svq3_mc_dir(h, mb_type, PREDICT_MODE, 1, 1) < 0)
+            if (svq3_mc_dir(s, mb_type, PREDICT_MODE, 1, 1) < 0)
                 return -1;
 
             mb_type = MB_TYPE_16x16;
         }
     } else if (mb_type < 8) {     /* INTER */
-        if (svq3->thirdpel_flag && svq3->halfpel_flag == !get_bits1(&s->gb))
+        if (s->thirdpel_flag && s->halfpel_flag == !get_bits1(&h->gb))
             mode = THIRDPEL_MODE;
-        else if (svq3->halfpel_flag &&
-                 svq3->thirdpel_flag == !get_bits1(&s->gb))
+        else if (s->halfpel_flag &&
+                 s->thirdpel_flag == !get_bits1(&h->gb))
             mode = HALFPEL_MODE;
         else
             mode = FULLPEL_MODE;
@@ -510,63 +519,63 @@
          */
 
         for (m = 0; m < 2; m++) {
-            if (s->mb_x > 0 && h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - 1] + 6] != -1) {
+            if (h->mb_x > 0 && h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - 1] + 6] != -1) {
                 for (i = 0; i < 4; i++)
                     AV_COPY32(h->mv_cache[m][scan8[0] - 1 + i * 8],
-                              s->current_picture.f.motion_val[m][b_xy - 1 + i * h->b_stride]);
+                              h->cur_pic.f.motion_val[m][b_xy - 1 + i * h->b_stride]);
             } else {
                 for (i = 0; i < 4; i++)
                     AV_ZERO32(h->mv_cache[m][scan8[0] - 1 + i * 8]);
             }
-            if (s->mb_y > 0) {
+            if (h->mb_y > 0) {
                 memcpy(h->mv_cache[m][scan8[0] - 1 * 8],
-                       s->current_picture.f.motion_val[m][b_xy - h->b_stride],
+                       h->cur_pic.f.motion_val[m][b_xy - h->b_stride],
                        4 * 2 * sizeof(int16_t));
                 memset(&h->ref_cache[m][scan8[0] - 1 * 8],
-                       (h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - s->mb_stride]] == -1) ? PART_NOT_AVAILABLE : 1, 4);
+                       (h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride]] == -1) ? PART_NOT_AVAILABLE : 1, 4);
 
-                if (s->mb_x < s->mb_width - 1) {
+                if (h->mb_x < h->mb_width - 1) {
                     AV_COPY32(h->mv_cache[m][scan8[0] + 4 - 1 * 8],
-                              s->current_picture.f.motion_val[m][b_xy - h->b_stride + 4]);
+                              h->cur_pic.f.motion_val[m][b_xy - h->b_stride + 4]);
                     h->ref_cache[m][scan8[0] + 4 - 1 * 8] =
-                        (h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - s->mb_stride + 1] + 6] == -1 ||
-                         h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - s->mb_stride]] == -1) ? PART_NOT_AVAILABLE : 1;
+                        (h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride + 1] + 6] == -1 ||
+                         h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride]] == -1) ? PART_NOT_AVAILABLE : 1;
                 } else
                     h->ref_cache[m][scan8[0] + 4 - 1 * 8] = PART_NOT_AVAILABLE;
-                if (s->mb_x > 0) {
+                if (h->mb_x > 0) {
                     AV_COPY32(h->mv_cache[m][scan8[0] - 1 - 1 * 8],
-                              s->current_picture.f.motion_val[m][b_xy - h->b_stride - 1]);
+                              h->cur_pic.f.motion_val[m][b_xy - h->b_stride - 1]);
                     h->ref_cache[m][scan8[0] - 1 - 1 * 8] =
-                        (h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - s->mb_stride - 1] + 3] == -1) ? PART_NOT_AVAILABLE : 1;
+                        (h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride - 1] + 3] == -1) ? PART_NOT_AVAILABLE : 1;
                 } else
                     h->ref_cache[m][scan8[0] - 1 - 1 * 8] = PART_NOT_AVAILABLE;
             } else
                 memset(&h->ref_cache[m][scan8[0] - 1 * 8 - 1],
                        PART_NOT_AVAILABLE, 8);
 
-            if (s->pict_type != AV_PICTURE_TYPE_B)
+            if (h->pict_type != AV_PICTURE_TYPE_B)
                 break;
         }
 
         /* decode motion vector(s) and form prediction(s) */
-        if (s->pict_type == AV_PICTURE_TYPE_P) {
-            if (svq3_mc_dir(h, mb_type - 1, mode, 0, 0) < 0)
+        if (h->pict_type == AV_PICTURE_TYPE_P) {
+            if (svq3_mc_dir(s, mb_type - 1, mode, 0, 0) < 0)
                 return -1;
         } else {        /* AV_PICTURE_TYPE_B */
             if (mb_type != 2) {
-                if (svq3_mc_dir(h, 0, mode, 0, 0) < 0)
+                if (svq3_mc_dir(s, 0, mode, 0, 0) < 0)
                     return -1;
             } else {
                 for (i = 0; i < 4; i++)
-                    memset(s->current_picture.f.motion_val[0][b_xy + i * h->b_stride],
+                    memset(h->cur_pic.f.motion_val[0][b_xy + i * h->b_stride],
                            0, 4 * 2 * sizeof(int16_t));
             }
             if (mb_type != 1) {
-                if (svq3_mc_dir(h, 0, mode, 1, mb_type == 3) < 0)
+                if (svq3_mc_dir(s, 0, mode, 1, mb_type == 3) < 0)
                     return -1;
             } else {
                 for (i = 0; i < 4; i++)
-                    memset(s->current_picture.f.motion_val[1][b_xy + i * h->b_stride],
+                    memset(h->cur_pic.f.motion_val[1][b_xy + i * h->b_stride],
                            0, 4 * 2 * sizeof(int16_t));
             }
         }
@@ -576,17 +585,17 @@
         memset(h->intra4x4_pred_mode_cache, -1, 8 * 5 * sizeof(int8_t));
 
         if (mb_type == 8) {
-            if (s->mb_x > 0) {
+            if (h->mb_x > 0) {
                 for (i = 0; i < 4; i++)
                     h->intra4x4_pred_mode_cache[scan8[0] - 1 + i * 8] = h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - 1] + 6 - i];
                 if (h->intra4x4_pred_mode_cache[scan8[0] - 1] == -1)
                     h->left_samples_available = 0x5F5F;
             }
-            if (s->mb_y > 0) {
-                h->intra4x4_pred_mode_cache[4 + 8 * 0] = h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - s->mb_stride] + 0];
-                h->intra4x4_pred_mode_cache[5 + 8 * 0] = h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - s->mb_stride] + 1];
-                h->intra4x4_pred_mode_cache[6 + 8 * 0] = h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - s->mb_stride] + 2];
-                h->intra4x4_pred_mode_cache[7 + 8 * 0] = h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - s->mb_stride] + 3];
+            if (h->mb_y > 0) {
+                h->intra4x4_pred_mode_cache[4 + 8 * 0] = h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride] + 0];
+                h->intra4x4_pred_mode_cache[5 + 8 * 0] = h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride] + 1];
+                h->intra4x4_pred_mode_cache[6 + 8 * 0] = h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride] + 2];
+                h->intra4x4_pred_mode_cache[7 + 8 * 0] = h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride] + 3];
 
                 if (h->intra4x4_pred_mode_cache[4 + 8 * 0] == -1)
                     h->top_samples_available = 0x33FF;
@@ -594,10 +603,10 @@
 
             /* decode prediction codes for luma blocks */
             for (i = 0; i < 16; i += 2) {
-                vlc = svq3_get_ue_golomb(&s->gb);
+                vlc = svq3_get_ue_golomb(&h->gb);
 
                 if (vlc >= 25U) {
-                    av_log(h->s.avctx, AV_LOG_ERROR, "luma prediction:%d\n", vlc);
+                    av_log(h->avctx, AV_LOG_ERROR, "luma prediction:%d\n", vlc);
                     return -1;
                 }
 
@@ -608,7 +617,7 @@
                 left[2] = svq3_pred_1[top[1] + 1][left[1] + 1][svq3_pred_0[vlc][1]];
 
                 if (left[1] == -1 || left[2] == -1) {
-                    av_log(h->s.avctx, AV_LOG_ERROR, "weird prediction\n");
+                    av_log(h->avctx, AV_LOG_ERROR, "weird prediction\n");
                     return -1;
                 }
             }
@@ -622,8 +631,8 @@
         if (mb_type == 8) {
             ff_h264_check_intra4x4_pred_mode(h);
 
-            h->top_samples_available  = (s->mb_y == 0) ? 0x33FF : 0xFFFF;
-            h->left_samples_available = (s->mb_x == 0) ? 0x5F5F : 0xFFFF;
+            h->top_samples_available  = (h->mb_y == 0) ? 0x33FF : 0xFFFF;
+            h->left_samples_available = (h->mb_x == 0) ? 0x5F5F : 0xFFFF;
         } else {
             for (i = 0; i < 4; i++)
                 memset(&h->intra4x4_pred_mode_cache[scan8[0] + 8 * i], DC_128_PRED, 4);
@@ -638,7 +647,7 @@
         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->s.avctx, AV_LOG_ERROR, "check_intra_pred_mode = -1\n");
+            av_log(h->avctx, AV_LOG_ERROR, "check_intra_pred_mode = -1\n");
             return -1;
         }
 
@@ -646,29 +655,27 @@
         mb_type = MB_TYPE_INTRA16x16;
     }
 
-    if (!IS_INTER(mb_type) && s->pict_type != AV_PICTURE_TYPE_I) {
+    if (!IS_INTER(mb_type) && h->pict_type != AV_PICTURE_TYPE_I) {
         for (i = 0; i < 4; i++)
-            memset(s->current_picture.f.motion_val[0][b_xy + i * h->b_stride],
+            memset(h->cur_pic.f.motion_val[0][b_xy + i * h->b_stride],
                    0, 4 * 2 * sizeof(int16_t));
-        if (s->pict_type == AV_PICTURE_TYPE_B) {
+        if (h->pict_type == AV_PICTURE_TYPE_B) {
             for (i = 0; i < 4; i++)
-                memset(s->current_picture.f.motion_val[1][b_xy + i * h->b_stride],
+                memset(h->cur_pic.f.motion_val[1][b_xy + i * h->b_stride],
                        0, 4 * 2 * sizeof(int16_t));
         }
     }
     if (!IS_INTRA4x4(mb_type)) {
         memset(h->intra4x4_pred_mode + h->mb2br_xy[mb_xy], DC_PRED, 8);
     }
-    if (!IS_SKIP(mb_type) || s->pict_type == AV_PICTURE_TYPE_B) {
+    if (!IS_SKIP(mb_type) || h->pict_type == AV_PICTURE_TYPE_B) {
         memset(h->non_zero_count_cache + 8, 0, 14 * 8 * sizeof(uint8_t));
-        s->dsp.clear_blocks(h->mb +   0);
-        s->dsp.clear_blocks(h->mb + 384);
     }
 
     if (!IS_INTRA16x16(mb_type) &&
-        (!IS_SKIP(mb_type) || s->pict_type == AV_PICTURE_TYPE_B)) {
-        if ((vlc = svq3_get_ue_golomb(&s->gb)) >= 48U){
-            av_log(h->s.avctx, AV_LOG_ERROR, "cbp_vlc=%d\n", vlc);
+        (!IS_SKIP(mb_type) || h->pict_type == AV_PICTURE_TYPE_B)) {
+        if ((vlc = svq3_get_ue_golomb(&h->gb)) >= 48U){
+            av_log(h->avctx, AV_LOG_ERROR, "cbp_vlc=%d\n", vlc);
             return -1;
         }
 
@@ -676,19 +683,19 @@
                                 : golomb_to_inter_cbp[vlc];
     }
     if (IS_INTRA16x16(mb_type) ||
-        (s->pict_type != AV_PICTURE_TYPE_I && s->adaptive_quant && cbp)) {
-        s->qscale += svq3_get_se_golomb(&s->gb);
+        (h->pict_type != AV_PICTURE_TYPE_I && s->adaptive_quant && cbp)) {
+        h->qscale += svq3_get_se_golomb(&h->gb);
 
-        if (s->qscale > 31u) {
-            av_log(h->s.avctx, AV_LOG_ERROR, "qscale:%d\n", s->qscale);
+        if (h->qscale > 31u) {
+            av_log(h->avctx, AV_LOG_ERROR, "qscale:%d\n", h->qscale);
             return -1;
         }
     }
     if (IS_INTRA16x16(mb_type)) {
         AV_ZERO128(h->mb_luma_dc[0] + 0);
         AV_ZERO128(h->mb_luma_dc[0] + 8);
-        if (svq3_decode_block(&s->gb, h->mb_luma_dc[0], 0, 1)) {
-            av_log(h->s.avctx, AV_LOG_ERROR,
+        if (svq3_decode_block(&h->gb, h->mb_luma_dc[0], 0, 1)) {
+            av_log(h->avctx, AV_LOG_ERROR,
                    "error while decoding intra luma dc\n");
             return -1;
         }
@@ -696,7 +703,7 @@
 
     if (cbp) {
         const int index = IS_INTRA16x16(mb_type) ? 1 : 0;
-        const int type  = ((s->qscale < 24 && IS_INTRA4x4(mb_type)) ? 2 : 1);
+        const int type  = ((h->qscale < 24 && IS_INTRA4x4(mb_type)) ? 2 : 1);
 
         for (i = 0; i < 4; i++)
             if ((cbp & (1 << i))) {
@@ -706,8 +713,8 @@
                               : (4 * i + j);
                     h->non_zero_count_cache[scan8[k]] = 1;
 
-                    if (svq3_decode_block(&s->gb, &h->mb[16 * k], index, type)) {
-                        av_log(h->s.avctx, AV_LOG_ERROR,
+                    if (svq3_decode_block(&h->gb, &h->mb[16 * k], index, type)) {
+                        av_log(h->avctx, AV_LOG_ERROR,
                                "error while decoding block\n");
                         return -1;
                     }
@@ -716,8 +723,8 @@
 
         if ((cbp & 0x30)) {
             for (i = 1; i < 3; ++i)
-                if (svq3_decode_block(&s->gb, &h->mb[16 * 16 * i], 0, 3)) {
-                    av_log(h->s.avctx, AV_LOG_ERROR,
+                if (svq3_decode_block(&h->gb, &h->mb[16 * 16 * i], 0, 3)) {
+                    av_log(h->avctx, AV_LOG_ERROR,
                            "error while decoding chroma dc block\n");
                     return -1;
                 }
@@ -728,8 +735,8 @@
                         k                                 = 16 * i + j;
                         h->non_zero_count_cache[scan8[k]] = 1;
 
-                        if (svq3_decode_block(&s->gb, &h->mb[16 * k], 1, 1)) {
-                            av_log(h->s.avctx, AV_LOG_ERROR,
+                        if (svq3_decode_block(&h->gb, &h->mb[16 * k], 1, 1)) {
+                            av_log(h->avctx, AV_LOG_ERROR,
                                    "error while decoding chroma ac block\n");
                             return -1;
                         }
@@ -740,7 +747,7 @@
     }
 
     h->cbp                              = cbp;
-    s->current_picture.f.mb_type[mb_xy] = mb_type;
+    h->cur_pic.f.mb_type[mb_xy] = mb_type;
 
     if (IS_INTRA(mb_type))
         h->chroma_pred_mode = ff_h264_check_intra_pred_mode(h, DC_PRED8x8, 1);
@@ -750,13 +757,13 @@
 
 static int svq3_decode_slice_header(AVCodecContext *avctx)
 {
-    SVQ3Context *svq3 = avctx->priv_data;
-    H264Context *h    = &svq3->h;
-    MpegEncContext *s = &h->s;
+    SVQ3Context *s = avctx->priv_data;
+    H264Context *h    = &s->h;
     const int mb_xy   = h->mb_xy;
     int i, header;
+    unsigned slice_id;
 
-    header = get_bits(&s->gb, 8);
+    header = get_bits(&h->gb, 8);
 
     if (((header & 0x9F) != 1 && (header & 0x9F) != 2) || (header & 0x60) == 0) {
         /* TODO: what? */
@@ -765,75 +772,75 @@
     } else {
         int length = header >> 5 & 3;
 
-        svq3->next_slice_index = get_bits_count(&s->gb) +
-                                 8 * show_bits(&s->gb, 8 * length) +
-                                 8 * length;
+        s->next_slice_index = get_bits_count(&h->gb) +
+                              8 * show_bits(&h->gb, 8 * length) +
+                              8 * length;
 
-        if (svq3->next_slice_index > s->gb.size_in_bits) {
+        if (s->next_slice_index > h->gb.size_in_bits) {
             av_log(avctx, AV_LOG_ERROR, "slice after bitstream end\n");
             return -1;
         }
 
-        s->gb.size_in_bits = svq3->next_slice_index - 8 * (length - 1);
-        skip_bits(&s->gb, 8);
+        h->gb.size_in_bits = s->next_slice_index - 8 * (length - 1);
+        skip_bits(&h->gb, 8);
 
-        if (svq3->watermark_key) {
-            uint32_t header = AV_RL32(&s->gb.buffer[(get_bits_count(&s->gb) >> 3) + 1]);
-            AV_WL32(&s->gb.buffer[(get_bits_count(&s->gb) >> 3) + 1],
-                    header ^ svq3->watermark_key);
+        if (s->watermark_key) {
+            uint32_t header = AV_RL32(&h->gb.buffer[(get_bits_count(&h->gb) >> 3) + 1]);
+            AV_WL32(&h->gb.buffer[(get_bits_count(&h->gb) >> 3) + 1],
+                    header ^ s->watermark_key);
         }
         if (length > 0) {
-            memcpy((uint8_t *) &s->gb.buffer[get_bits_count(&s->gb) >> 3],
-                   &s->gb.buffer[s->gb.size_in_bits >> 3], length - 1);
+            memcpy((uint8_t *) &h->gb.buffer[get_bits_count(&h->gb) >> 3],
+                   &h->gb.buffer[h->gb.size_in_bits >> 3], length - 1);
         }
-        skip_bits_long(&s->gb, 0);
+        skip_bits_long(&h->gb, 0);
     }
 
-    if ((i = svq3_get_ue_golomb(&s->gb)) >= 3U) {
-        av_log(h->s.avctx, AV_LOG_ERROR, "illegal slice type %d \n", i);
+    if ((slice_id = svq3_get_ue_golomb(&h->gb)) >= 3) {
+        av_log(h->avctx, AV_LOG_ERROR, "illegal slice type %d \n", slice_id);
         return -1;
     }
 
-    h->slice_type = golomb_to_pict_type[i];
+    h->slice_type = golomb_to_pict_type[slice_id];
 
     if ((header & 0x9F) == 2) {
-        i              = (s->mb_num < 64) ? 6 : (1 + av_log2(s->mb_num - 1));
-        s->mb_skip_run = get_bits(&s->gb, i) -
-                         (s->mb_y * s->mb_width + s->mb_x);
+        i              = (h->mb_num < 64) ? 6 : (1 + av_log2(h->mb_num - 1));
+        h->mb_skip_run = get_bits(&h->gb, i) -
+                         (h->mb_y * h->mb_width + h->mb_x);
     } else {
-        skip_bits1(&s->gb);
-        s->mb_skip_run = 0;
+        skip_bits1(&h->gb);
+        h->mb_skip_run = 0;
     }
 
-    h->slice_num      = get_bits(&s->gb, 8);
-    s->qscale         = get_bits(&s->gb, 5);
-    s->adaptive_quant = get_bits1(&s->gb);
+    h->slice_num      = get_bits(&h->gb, 8);
+    h->qscale         = get_bits(&h->gb, 5);
+    s->adaptive_quant = get_bits1(&h->gb);
 
     /* unknown fields */
-    skip_bits1(&s->gb);
+    skip_bits1(&h->gb);
 
-    if (svq3->unknown_flag)
-        skip_bits1(&s->gb);
+    if (s->unknown_flag)
+        skip_bits1(&h->gb);
 
-    skip_bits1(&s->gb);
-    skip_bits(&s->gb, 2);
+    skip_bits1(&h->gb);
+    skip_bits(&h->gb, 2);
 
-    while (get_bits1(&s->gb))
-        skip_bits(&s->gb, 8);
+    while (get_bits1(&h->gb))
+        skip_bits(&h->gb, 8);
 
     /* reset intra predictors and invalidate motion vector references */
-    if (s->mb_x > 0) {
+    if (h->mb_x > 0) {
         memset(h->intra4x4_pred_mode + h->mb2br_xy[mb_xy - 1] + 3,
                -1, 4 * sizeof(int8_t));
-        memset(h->intra4x4_pred_mode + h->mb2br_xy[mb_xy - s->mb_x],
-               -1, 8 * sizeof(int8_t) * s->mb_x);
+        memset(h->intra4x4_pred_mode + h->mb2br_xy[mb_xy - h->mb_x],
+               -1, 8 * sizeof(int8_t) * h->mb_x);
     }
-    if (s->mb_y > 0) {
-        memset(h->intra4x4_pred_mode + h->mb2br_xy[mb_xy - s->mb_stride],
-               -1, 8 * sizeof(int8_t) * (s->mb_width - s->mb_x));
+    if (h->mb_y > 0) {
+        memset(h->intra4x4_pred_mode + h->mb2br_xy[mb_xy - h->mb_stride],
+               -1, 8 * sizeof(int8_t) * (h->mb_width - h->mb_x));
 
-        if (s->mb_x > 0)
-            h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - s->mb_stride - 1] + 3] = -1;
+        if (h->mb_x > 0)
+            h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride - 1] + 3] = -1;
     }
 
     return 0;
@@ -841,250 +848,343 @@
 
 static av_cold int svq3_decode_init(AVCodecContext *avctx)
 {
-    SVQ3Context *svq3 = avctx->priv_data;
-    H264Context *h    = &svq3->h;
-    MpegEncContext *s = &h->s;
+    SVQ3Context *s = avctx->priv_data;
+    H264Context *h = &s->h;
     int m;
     unsigned char *extradata;
     unsigned char *extradata_end;
     unsigned int size;
     int marker_found = 0;
 
+    s->cur_pic  = av_mallocz(sizeof(*s->cur_pic));
+    s->last_pic = av_mallocz(sizeof(*s->last_pic));
+    s->next_pic = av_mallocz(sizeof(*s->next_pic));
+    if (!s->next_pic || !s->last_pic || !s->cur_pic) {
+        av_freep(&s->cur_pic);
+        av_freep(&s->last_pic);
+        av_freep(&s->next_pic);
+        return AVERROR(ENOMEM);
+    }
+
     if (ff_h264_decode_init(avctx) < 0)
         return -1;
 
-    s->flags           = avctx->flags;
-    s->flags2          = avctx->flags2;
-    s->unrestricted_mv = 1;
+    h->flags           = avctx->flags;
     h->is_complex      = 1;
     h->sps.chroma_format_idc = 1;
+    h->picture_structure = PICT_FRAME;
     avctx->pix_fmt     = avctx->codec->pix_fmts[0];
 
-    if (!s->context_initialized) {
-        h->chroma_qp[0] = h->chroma_qp[1] = 4;
+    h->chroma_qp[0] = h->chroma_qp[1] = 4;
+    h->chroma_x_shift = h->chroma_y_shift = 1;
 
-        svq3->halfpel_flag  = 1;
-        svq3->thirdpel_flag = 1;
-        svq3->unknown_flag  = 0;
+    s->halfpel_flag  = 1;
+    s->thirdpel_flag = 1;
+    s->unknown_flag  = 0;
 
-
-        /* prowl for the "SEQH" marker in the extradata */
-        extradata     = (unsigned char *)avctx->extradata;
-        extradata_end = avctx->extradata + avctx->extradata_size;
-        if (extradata) {
-            for (m = 0; m + 8 < avctx->extradata_size; m++) {
-                if (!memcmp(extradata, "SEQH", 4)) {
-                    marker_found = 1;
-                    break;
-                }
-                extradata++;
+    /* prowl for the "SEQH" marker in the extradata */
+    extradata     = (unsigned char *)avctx->extradata;
+    extradata_end = avctx->extradata + avctx->extradata_size;
+    if (extradata) {
+        for (m = 0; m + 8 < avctx->extradata_size; m++) {
+            if (!memcmp(extradata, "SEQH", 4)) {
+                marker_found = 1;
+                break;
             }
+            extradata++;
+        }
+    }
+
+    /* if a match was found, parse the extra data */
+    if (marker_found) {
+        GetBitContext gb;
+        int frame_size_code;
+
+        size = AV_RB32(&extradata[4]);
+        if (size > extradata_end - extradata - 8)
+            return AVERROR_INVALIDDATA;
+        init_get_bits(&gb, extradata + 8, size * 8);
+
+        /* 'frame size code' and optional 'width, height' */
+        frame_size_code = get_bits(&gb, 3);
+        switch (frame_size_code) {
+        case 0:
+            avctx->width  = 160;
+            avctx->height = 120;
+            break;
+        case 1:
+            avctx->width  = 128;
+            avctx->height =  96;
+            break;
+        case 2:
+            avctx->width  = 176;
+            avctx->height = 144;
+            break;
+        case 3:
+            avctx->width  = 352;
+            avctx->height = 288;
+            break;
+        case 4:
+            avctx->width  = 704;
+            avctx->height = 576;
+            break;
+        case 5:
+            avctx->width  = 240;
+            avctx->height = 180;
+            break;
+        case 6:
+            avctx->width  = 320;
+            avctx->height = 240;
+            break;
+        case 7:
+            avctx->width  = get_bits(&gb, 12);
+            avctx->height = get_bits(&gb, 12);
+            break;
         }
 
-        /* if a match was found, parse the extra data */
-        if (marker_found) {
-            GetBitContext gb;
-            int frame_size_code;
+        s->halfpel_flag  = get_bits1(&gb);
+        s->thirdpel_flag = get_bits1(&gb);
 
-            size = AV_RB32(&extradata[4]);
-            if (size > extradata_end - extradata - 8)
-                return AVERROR_INVALIDDATA;
-            init_get_bits(&gb, extradata + 8, size * 8);
+        /* unknown fields */
+        skip_bits1(&gb);
+        skip_bits1(&gb);
+        skip_bits1(&gb);
+        skip_bits1(&gb);
 
-            /* 'frame size code' and optional 'width, height' */
-            frame_size_code = get_bits(&gb, 3);
-            switch (frame_size_code) {
-            case 0:
-                avctx->width  = 160;
-                avctx->height = 120;
-                break;
-            case 1:
-                avctx->width  = 128;
-                avctx->height =  96;
-                break;
-            case 2:
-                avctx->width  = 176;
-                avctx->height = 144;
-                break;
-            case 3:
-                avctx->width  = 352;
-                avctx->height = 288;
-                break;
-            case 4:
-                avctx->width  = 704;
-                avctx->height = 576;
-                break;
-            case 5:
-                avctx->width  = 240;
-                avctx->height = 180;
-                break;
-            case 6:
-                avctx->width  = 320;
-                avctx->height = 240;
-                break;
-            case 7:
-                avctx->width  = get_bits(&gb, 12);
-                avctx->height = get_bits(&gb, 12);
-                break;
-            }
+        h->low_delay = get_bits1(&gb);
 
-            svq3->halfpel_flag  = get_bits1(&gb);
-            svq3->thirdpel_flag = get_bits1(&gb);
+        /* unknown field */
+        skip_bits1(&gb);
 
-            /* unknown fields */
-            skip_bits1(&gb);
-            skip_bits1(&gb);
-            skip_bits1(&gb);
-            skip_bits1(&gb);
+        while (get_bits1(&gb))
+            skip_bits(&gb, 8);
 
-            s->low_delay = get_bits1(&gb);
-
-            /* unknown field */
-            skip_bits1(&gb);
-
-            while (get_bits1(&gb))
-                skip_bits(&gb, 8);
-
-            svq3->unknown_flag  = get_bits1(&gb);
-            avctx->has_b_frames = !s->low_delay;
-            if (svq3->unknown_flag) {
+        s->unknown_flag  = get_bits1(&gb);
+        avctx->has_b_frames = !h->low_delay;
+        if (s->unknown_flag) {
 #if CONFIG_ZLIB
-                unsigned watermark_width  = svq3_get_ue_golomb(&gb);
-                unsigned watermark_height = svq3_get_ue_golomb(&gb);
-                int u1                    = svq3_get_ue_golomb(&gb);
-                int u2                    = get_bits(&gb, 8);
-                int u3                    = get_bits(&gb, 2);
-                int u4                    = svq3_get_ue_golomb(&gb);
-                unsigned long buf_len     = watermark_width *
-                                            watermark_height * 4;
-                int offset                = get_bits_count(&gb) + 7 >> 3;
-                uint8_t *buf;
+            unsigned watermark_width  = svq3_get_ue_golomb(&gb);
+            unsigned watermark_height = svq3_get_ue_golomb(&gb);
+            int u1                    = svq3_get_ue_golomb(&gb);
+            int u2                    = get_bits(&gb, 8);
+            int u3                    = get_bits(&gb, 2);
+            int u4                    = svq3_get_ue_golomb(&gb);
+            unsigned long buf_len     = watermark_width *
+                                        watermark_height * 4;
+            int offset                = get_bits_count(&gb) + 7 >> 3;
+            uint8_t *buf;
 
-                if (watermark_height <= 0 || (uint64_t)watermark_width*4 > UINT_MAX/watermark_height)
-                    return -1;
-
-                buf = av_malloc(buf_len);
-                av_log(avctx, AV_LOG_DEBUG, "watermark size: %dx%d\n",
-                       watermark_width, watermark_height);
-                av_log(avctx, AV_LOG_DEBUG,
-                       "u1: %x u2: %x u3: %x compressed data size: %d offset: %d\n",
-                       u1, u2, u3, u4, offset);
-                if (uncompress(buf, &buf_len, extradata + 8 + offset,
-                               size - offset) != Z_OK) {
-                    av_log(avctx, AV_LOG_ERROR,
-                           "could not uncompress watermark logo\n");
-                    av_free(buf);
-                    return -1;
-                }
-                svq3->watermark_key = ff_svq1_packet_checksum(buf, buf_len, 0);
-                svq3->watermark_key = svq3->watermark_key << 16 |
-                                      svq3->watermark_key;
-                av_log(avctx, AV_LOG_DEBUG,
-                       "watermark key %#x\n", svq3->watermark_key);
-                av_free(buf);
-#else
-                av_log(avctx, AV_LOG_ERROR,
-                       "this svq3 file contains watermark which need zlib support compiled in\n");
+            if (watermark_height <= 0 || (uint64_t)watermark_width*4 > UINT_MAX/watermark_height)
                 return -1;
-#endif
+
+            buf = av_malloc(buf_len);
+            av_log(avctx, AV_LOG_DEBUG, "watermark size: %dx%d\n",
+                   watermark_width, watermark_height);
+            av_log(avctx, AV_LOG_DEBUG,
+                   "u1: %x u2: %x u3: %x compressed data size: %d offset: %d\n",
+                   u1, u2, u3, u4, offset);
+            if (uncompress(buf, &buf_len, extradata + 8 + offset,
+                           size - offset) != Z_OK) {
+                av_log(avctx, AV_LOG_ERROR,
+                       "could not uncompress watermark logo\n");
+                av_free(buf);
+                return -1;
             }
-        }
-
-        s->width  = avctx->width;
-        s->height = avctx->height;
-
-        if (ff_MPV_common_init(s) < 0)
+            s->watermark_key = ff_svq1_packet_checksum(buf, buf_len, 0);
+            s->watermark_key = s->watermark_key << 16 | s->watermark_key;
+            av_log(avctx, AV_LOG_DEBUG,
+                   "watermark key %#x\n", s->watermark_key);
+            av_free(buf);
+#else
+            av_log(avctx, AV_LOG_ERROR,
+                   "this svq3 file contains watermark which need zlib support compiled in\n");
             return -1;
-
-        h->b_stride = 4 * s->mb_width;
-
-        if (ff_h264_alloc_tables(h) < 0) {
-            av_log(avctx, AV_LOG_ERROR, "svq3 memory allocation failed\n");
-            return AVERROR(ENOMEM);
+#endif
         }
     }
 
+    h->width  = avctx->width;
+    h->height = avctx->height;
+    h->mb_width  = (h->width + 15) / 16;
+    h->mb_height = (h->height + 15) / 16;
+    h->mb_stride = h->mb_width + 1;
+    h->mb_num    = h->mb_width * h->mb_height;
+    h->b_stride = 4 * h->mb_width;
+    s->h_edge_pos = h->mb_width * 16;
+    s->v_edge_pos = h->mb_height * 16;
+
+    if (ff_h264_alloc_tables(h) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "svq3 memory allocation failed\n");
+        return AVERROR(ENOMEM);
+    }
+
     return 0;
 }
 
-static int svq3_decode_frame(AVCodecContext *avctx, void *data,
-                             int *data_size, AVPacket *avpkt)
+static int get_buffer(AVCodecContext *avctx, Picture *pic)
 {
-    SVQ3Context *svq3  = avctx->priv_data;
-    H264Context *h     = &svq3->h;
-    MpegEncContext *s  = &h->s;
+    SVQ3Context *s = avctx->priv_data;
+    H264Context *h = &s->h;
+    const int big_mb_num    = h->mb_stride * (h->mb_height + 1) + 1;
+    const int mb_array_size = h->mb_stride * h->mb_height;
+    const int b4_stride     = h->mb_width * 4 + 1;
+    const int b4_array_size = b4_stride * h->mb_height * 4;
+    int ret;
+
+    if (!pic->motion_val_base[0]) {
+        int i;
+
+        pic->mb_type_base = av_mallocz((big_mb_num + h->mb_stride) * sizeof(uint32_t));
+        if (!pic->mb_type_base)
+            return AVERROR(ENOMEM);
+        pic->f.mb_type = pic->mb_type_base + 2 * h->mb_stride + 1;
+
+        for (i = 0; i < 2; i++) {
+            pic->motion_val_base[i] = av_mallocz(2 * (b4_array_size + 4) * sizeof(int16_t));
+            pic->f.ref_index[i]     = av_mallocz(4 * mb_array_size);
+            if (!pic->motion_val_base[i] || !pic->f.ref_index[i])
+                return AVERROR(ENOMEM);
+
+            pic->f.motion_val[i] = pic->motion_val_base[i] + 4;
+        }
+    }
+    pic->f.motion_subsample_log2 = 2;
+    pic->f.reference = !(h->pict_type == AV_PICTURE_TYPE_B);
+
+    ret = ff_get_buffer(avctx, &pic->f);
+    if (!h->edge_emu_buffer) {
+        h->edge_emu_buffer = av_mallocz(pic->f.linesize[0] * 17);
+        if (!h->edge_emu_buffer)
+            return AVERROR(ENOMEM);
+    }
+
+    h->linesize   = pic->f.linesize[0];
+    h->uvlinesize = pic->f.linesize[1];
+
+    return ret;
+}
+
+static int svq3_decode_frame(AVCodecContext *avctx, void *data,
+                             int *got_frame, AVPacket *avpkt)
+{
+    SVQ3Context *s     = avctx->priv_data;
+    H264Context *h     = &s->h;
     int buf_size       = avpkt->size;
-    int m, mb_type, left;
+    int left;
     uint8_t *buf;
+    int ret, m, i;
 
     /* special case for last picture */
     if (buf_size == 0) {
-        if (s->next_picture_ptr && !s->low_delay) {
-            *(AVFrame *) data   = s->next_picture.f;
-            s->next_picture_ptr = NULL;
-            *data_size          = sizeof(AVFrame);
+        if (s->next_pic->f.data[0] && !h->low_delay && !s->last_frame_output) {
+            *(AVFrame *) data   = s->next_pic->f;
+            s->last_frame_output = 1;
+            *got_frame          = 1;
         }
         return 0;
     }
 
-    s->mb_x = s->mb_y = h->mb_xy = 0;
+    h->mb_x = h->mb_y = h->mb_xy = 0;
 
-    if (svq3->watermark_key) {
-        av_fast_malloc(&svq3->buf, &svq3->buf_size,
+    if (s->watermark_key) {
+        av_fast_malloc(&s->buf, &s->buf_size,
                        buf_size+FF_INPUT_BUFFER_PADDING_SIZE);
-        if (!svq3->buf)
+        if (!s->buf)
             return AVERROR(ENOMEM);
-        memcpy(svq3->buf, avpkt->data, buf_size);
-        buf = svq3->buf;
+        memcpy(s->buf, avpkt->data, buf_size);
+        buf = s->buf;
     } else {
         buf = avpkt->data;
     }
 
-    init_get_bits(&s->gb, buf, 8 * buf_size);
+    init_get_bits(&h->gb, buf, 8 * buf_size);
 
     if (svq3_decode_slice_header(avctx))
         return -1;
 
-    s->pict_type      = h->slice_type;
-    s->picture_number = h->slice_num;
+    h->pict_type = h->slice_type;
 
-    if (avctx->debug & FF_DEBUG_PICT_INFO)
-        av_log(h->s.avctx, AV_LOG_DEBUG,
-               "%c hpel:%d, tpel:%d aqp:%d qp:%d, slice_num:%02X\n",
-               av_get_picture_type_char(s->pict_type),
-               svq3->halfpel_flag, svq3->thirdpel_flag,
-               s->adaptive_quant, s->qscale, h->slice_num);
+    if (h->pict_type != AV_PICTURE_TYPE_B)
+        FFSWAP(Picture*, s->next_pic, s->last_pic);
+
+    if (s->cur_pic->f.data[0])
+        avctx->release_buffer(avctx, &s->cur_pic->f);
 
     /* for skipping the frame */
-    s->current_picture.f.pict_type = s->pict_type;
-    s->current_picture.f.key_frame = (s->pict_type == AV_PICTURE_TYPE_I);
+    s->cur_pic->f.pict_type = h->pict_type;
+    s->cur_pic->f.key_frame = (h->pict_type == AV_PICTURE_TYPE_I);
 
-    /* Skip B-frames if we do not have reference frames. */
-    if (s->last_picture_ptr == NULL && s->pict_type == AV_PICTURE_TYPE_B)
-        return 0;
-    if (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type == AV_PICTURE_TYPE_B ||
-        avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type != AV_PICTURE_TYPE_I ||
+    ret = get_buffer(avctx, s->cur_pic);
+    if (ret < 0)
+        return ret;
+
+    h->cur_pic_ptr = s->cur_pic;
+    h->cur_pic     = *s->cur_pic;
+
+    for (i = 0; i < 16; i++) {
+        h->block_offset[i]           = (4 * ((scan8[i] - scan8[0]) & 7)) + 4 * h->linesize * ((scan8[i] - scan8[0]) >> 3);
+        h->block_offset[48 + i]      = (4 * ((scan8[i] - scan8[0]) & 7)) + 8 * h->linesize * ((scan8[i] - scan8[0]) >> 3);
+    }
+    for (i = 0; i < 16; i++) {
+        h->block_offset[16 + i]      =
+        h->block_offset[32 + i]      = (4 * ((scan8[i] - scan8[0]) & 7)) + 4 * h->uvlinesize * ((scan8[i] - scan8[0]) >> 3);
+        h->block_offset[48 + 16 + i] =
+        h->block_offset[48 + 32 + i] = (4 * ((scan8[i] - scan8[0]) & 7)) + 8 * h->uvlinesize * ((scan8[i] - scan8[0]) >> 3);
+    }
+
+    if (h->pict_type != AV_PICTURE_TYPE_I) {
+        if (!s->last_pic->f.data[0]) {
+            av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n");
+            ret = get_buffer(avctx, s->last_pic);
+            if (ret < 0)
+                return ret;
+            memset(s->last_pic->f.data[0], 0, avctx->height * s->last_pic->f.linesize[0]);
+            memset(s->last_pic->f.data[1], 0x80, (avctx->height / 2) *
+                   s->last_pic->f.linesize[1]);
+            memset(s->last_pic->f.data[2], 0x80, (avctx->height / 2) *
+                   s->last_pic->f.linesize[2]);
+        }
+
+        if (h->pict_type == AV_PICTURE_TYPE_B && !s->next_pic->f.data[0]) {
+            av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n");
+            ret = get_buffer(avctx, s->next_pic);
+            if (ret < 0)
+                return ret;
+            memset(s->next_pic->f.data[0], 0, avctx->height * s->next_pic->f.linesize[0]);
+            memset(s->next_pic->f.data[1], 0x80, (avctx->height / 2) *
+                   s->next_pic->f.linesize[1]);
+            memset(s->next_pic->f.data[2], 0x80, (avctx->height / 2) *
+                   s->next_pic->f.linesize[2]);
+        }
+    }
+
+    if (avctx->debug & FF_DEBUG_PICT_INFO)
+        av_log(h->avctx, AV_LOG_DEBUG,
+               "%c hpel:%d, tpel:%d aqp:%d qp:%d, slice_num:%02X\n",
+               av_get_picture_type_char(h->pict_type),
+               s->halfpel_flag, s->thirdpel_flag,
+               s->adaptive_quant, h->qscale, h->slice_num);
+
+    if (avctx->skip_frame >= AVDISCARD_NONREF && h->pict_type == AV_PICTURE_TYPE_B ||
+        avctx->skip_frame >= AVDISCARD_NONKEY && h->pict_type != AV_PICTURE_TYPE_I ||
         avctx->skip_frame >= AVDISCARD_ALL)
         return 0;
 
     if (s->next_p_frame_damaged) {
-        if (s->pict_type == AV_PICTURE_TYPE_B)
+        if (h->pict_type == AV_PICTURE_TYPE_B)
             return 0;
         else
             s->next_p_frame_damaged = 0;
     }
 
-    if (ff_h264_frame_start(h) < 0)
-        return -1;
-
-    if (s->pict_type == AV_PICTURE_TYPE_B) {
+    if (h->pict_type == AV_PICTURE_TYPE_B) {
         h->frame_num_offset = h->slice_num - h->prev_frame_num;
 
         if (h->frame_num_offset < 0)
             h->frame_num_offset += 256;
         if (h->frame_num_offset == 0 ||
             h->frame_num_offset >= h->prev_frame_num_offset) {
-            av_log(h->s.avctx, AV_LOG_ERROR, "error in B-frame picture id\n");
+            av_log(h->avctx, AV_LOG_ERROR, "error in B-frame picture id\n");
             return -1;
         }
     } else {
@@ -1107,15 +1207,16 @@
         }
     }
 
-    for (s->mb_y = 0; s->mb_y < s->mb_height; s->mb_y++) {
-        for (s->mb_x = 0; s->mb_x < s->mb_width; s->mb_x++) {
-            h->mb_xy = s->mb_x + s->mb_y * s->mb_stride;
+    for (h->mb_y = 0; h->mb_y < h->mb_height; h->mb_y++) {
+        for (h->mb_x = 0; h->mb_x < h->mb_width; h->mb_x++) {
+            unsigned mb_type;
+            h->mb_xy = h->mb_x + h->mb_y * h->mb_stride;
 
-            if ((get_bits_count(&s->gb) + 7) >= s->gb.size_in_bits &&
-                ((get_bits_count(&s->gb) & 7) == 0 ||
-                 show_bits(&s->gb, -get_bits_count(&s->gb) & 7) == 0)) {
-                skip_bits(&s->gb, svq3->next_slice_index - get_bits_count(&s->gb));
-                s->gb.size_in_bits = 8 * buf_size;
+            if ((get_bits_count(&h->gb) + 7) >= h->gb.size_in_bits &&
+                ((get_bits_count(&h->gb) & 7) == 0 ||
+                 show_bits(&h->gb, -get_bits_count(&h->gb) & 7) == 0)) {
+                skip_bits(&h->gb, s->next_slice_index - get_bits_count(&h->gb));
+                h->gb.size_in_bits = 8 * buf_size;
 
                 if (svq3_decode_slice_header(avctx))
                     return -1;
@@ -1123,33 +1224,35 @@
                 /* TODO: support s->mb_skip_run */
             }
 
-            mb_type = svq3_get_ue_golomb(&s->gb);
+            mb_type = svq3_get_ue_golomb(&h->gb);
 
-            if (s->pict_type == AV_PICTURE_TYPE_I)
+            if (h->pict_type == AV_PICTURE_TYPE_I)
                 mb_type += 8;
-            else if (s->pict_type == AV_PICTURE_TYPE_B && mb_type >= 4)
+            else if (h->pict_type == AV_PICTURE_TYPE_B && mb_type >= 4)
                 mb_type += 4;
-            if ((unsigned)mb_type > 33 || svq3_decode_mb(svq3, mb_type)) {
-                av_log(h->s.avctx, AV_LOG_ERROR,
-                       "error while decoding MB %d %d\n", s->mb_x, s->mb_y);
+            if (mb_type > 33 || svq3_decode_mb(s, mb_type)) {
+                av_log(h->avctx, AV_LOG_ERROR,
+                       "error while decoding MB %d %d\n", h->mb_x, h->mb_y);
                 return -1;
             }
 
-            if (mb_type != 0)
+            if (mb_type != 0 || h->cbp)
                 ff_h264_hl_decode_mb(h);
 
-            if (s->pict_type != AV_PICTURE_TYPE_B && !s->low_delay)
-                s->current_picture.f.mb_type[s->mb_x + s->mb_y * s->mb_stride] =
-                    (s->pict_type == AV_PICTURE_TYPE_P && mb_type < 8) ? (mb_type - 1) : -1;
+            if (h->pict_type != AV_PICTURE_TYPE_B && !h->low_delay)
+                h->cur_pic.f.mb_type[h->mb_x + h->mb_y * h->mb_stride] =
+                    (h->pict_type == AV_PICTURE_TYPE_P && mb_type < 8) ? (mb_type - 1) : -1;
         }
 
-        ff_draw_horiz_band(s, 16 * s->mb_y, 16);
+        ff_draw_horiz_band(avctx, NULL, s->cur_pic, s->last_pic->f.data[0] ? s->last_pic : NULL,
+                           16 * h->mb_y, 16, h->picture_structure, 0, 0,
+                           h->low_delay, h->mb_height * 16, h->mb_width * 16);
     }
 
-    left = buf_size*8 - get_bits_count(&s->gb);
+    left = buf_size*8 - get_bits_count(&h->gb);
 
-    if (s->mb_y != s->mb_height || s->mb_x != s->mb_width) {
-        av_log(avctx, AV_LOG_INFO, "frame num %d incomplete pic x %d y %d left %d\n", avctx->frame_number, s->mb_y, s->mb_x, left);
+    if (h->mb_y != h->mb_height || h->mb_x != h->mb_width) {
+        av_log(avctx, AV_LOG_INFO, "frame num %d incomplete pic x %d y %d left %d\n", avctx->frame_number, h->mb_y, h->mb_x, left);
         //av_hex_dump(stderr, buf+buf_size-8, 8);
     }
 
@@ -1158,32 +1261,50 @@
         return -1;
     }
 
-    ff_MPV_frame_end(s);
-
-    if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay)
-        *(AVFrame *)data = s->current_picture.f;
+    if (h->pict_type == AV_PICTURE_TYPE_B || h->low_delay)
+        *(AVFrame *)data = s->cur_pic->f;
     else
-        *(AVFrame *)data = s->last_picture.f;
+        *(AVFrame *)data = s->last_pic->f;
 
     /* Do not output the last pic after seeking. */
-    if (s->last_picture_ptr || s->low_delay)
-        *data_size = sizeof(AVFrame);
+    if (s->last_pic->f.data[0] || h->low_delay)
+        *got_frame = 1;
+
+    if (h->pict_type != AV_PICTURE_TYPE_B) {
+        FFSWAP(Picture*, s->cur_pic, s->next_pic);
+    }
 
     return buf_size;
 }
 
+static void free_picture(AVCodecContext *avctx, Picture *pic)
+{
+    int i;
+    for (i = 0; i < 2; i++) {
+        av_freep(&pic->motion_val_base[i]);
+        av_freep(&pic->f.ref_index[i]);
+    }
+    av_freep(&pic->mb_type_base);
+
+    if (pic->f.data[0])
+        avctx->release_buffer(avctx, &pic->f);
+    av_freep(&pic);
+}
+
 static int svq3_decode_end(AVCodecContext *avctx)
 {
-    SVQ3Context *svq3 = avctx->priv_data;
-    H264Context *h    = &svq3->h;
-    MpegEncContext *s = &h->s;
+    SVQ3Context *s = avctx->priv_data;
+    H264Context *h = &s->h;
+
+    free_picture(avctx, s->cur_pic);
+    free_picture(avctx, s->next_pic);
+    free_picture(avctx, s->last_pic);
 
     ff_h264_free_context(h);
 
-    ff_MPV_common_end(s);
-
-    av_freep(&svq3->buf);
-    svq3->buf_size = 0;
+    av_freep(&s->buf);
+    s->buf_size = 0;
+    av_freep(&h->edge_emu_buffer);
 
     return 0;
 }
diff --git a/libavcodec/arm/dsputil_init_vfp.c b/libavcodec/svq3.h
similarity index 66%
copy from libavcodec/arm/dsputil_init_vfp.c
copy to libavcodec/svq3.h
index 5713c71..7a57d8a 100644
--- a/libavcodec/arm/dsputil_init_vfp.c
+++ b/libavcodec/svq3.h
@@ -1,6 +1,4 @@
 /*
- * Copyright (c) 2008 Siarhei Siamashka <ssvb@users.sourceforge.net>
- *
  * This file is part of FFmpeg.
  *
  * FFmpeg is free software; you can redistribute it and/or
@@ -18,13 +16,12 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavcodec/dsputil.h"
-#include "dsputil_arm.h"
+#ifndef AVCODEC_SVQ3_H
+#define AVCODEC_SVQ3_H
 
-void ff_vector_fmul_reverse_vfp(float *dst, const float *src0,
-                                const float *src1, int len);
+#include <stdint.h>
 
-void ff_dsputil_init_vfp(DSPContext* c, AVCodecContext *avctx)
-{
-    c->vector_fmul_reverse = ff_vector_fmul_reverse_vfp;
-}
+void ff_svq3_luma_dc_dequant_idct_c(int16_t *output, int16_t *input, int qp);
+void ff_svq3_add_idct_c(uint8_t *dst, int16_t *block, int stride, int qp, int dc);
+
+#endif /* AVCODEC_DSPUTIL_H */
diff --git a/libavcodec/tak.c b/libavcodec/tak.c
index 7e1a047..92dc44c 100644
--- a/libavcodec/tak.c
+++ b/libavcodec/tak.c
@@ -19,10 +19,10 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "tak.h"
+#include "libavutil/bswap.h"
 #include "libavutil/crc.h"
 #include "libavutil/intreadwrite.h"
-#include "libavutil/bswap.h"
+#include "tak.h"
 
 static const int64_t tak_channel_layouts[] = {
     0,
@@ -56,12 +56,13 @@
 
     if (type <= TAK_FST_250ms) {
         nb_samples     = sample_rate * frame_duration_type_quants[type] >>
-                                       TAK_FRAME_DURATION_QUANT_SHIFT;
+                         TAK_FRAME_DURATION_QUANT_SHIFT;
         max_nb_samples = 16384;
     } else if (type < FF_ARRAY_ELEMS(frame_duration_type_quants)) {
         nb_samples     = frame_duration_type_quants[type];
-        max_nb_samples = sample_rate * frame_duration_type_quants[TAK_FST_250ms] >>
-                                       TAK_FRAME_DURATION_QUANT_SHIFT;
+        max_nb_samples = sample_rate *
+                         frame_duration_type_quants[TAK_FST_250ms] >>
+                         TAK_FRAME_DURATION_QUANT_SHIFT;
     } else {
         return AVERROR_INVALIDDATA;
     }
@@ -113,12 +114,15 @@
     skip_bits(gb, TAK_ENCODER_PROFILE_BITS);
 
     frame_type = get_bits(gb, TAK_SIZE_FRAME_DURATION_BITS);
-    s->samples = get_bits_longlong(gb, TAK_SIZE_SAMPLES_NUM_BITS);
+    s->samples = get_bits64(gb, TAK_SIZE_SAMPLES_NUM_BITS);
 
     s->data_type   = get_bits(gb, TAK_FORMAT_DATA_TYPE_BITS);
-    s->sample_rate = get_bits(gb, TAK_FORMAT_SAMPLE_RATE_BITS) + TAK_SAMPLE_RATE_MIN;
-    s->bps         = get_bits(gb, TAK_FORMAT_BPS_BITS) + TAK_BPS_MIN;
-    s->channels    = get_bits(gb, TAK_FORMAT_CHANNEL_BITS) + TAK_CHANNELS_MIN;
+    s->sample_rate = get_bits(gb, TAK_FORMAT_SAMPLE_RATE_BITS) +
+                     TAK_SAMPLE_RATE_MIN;
+    s->bps         = get_bits(gb, TAK_FORMAT_BPS_BITS) +
+                     TAK_BPS_MIN;
+    s->channels    = get_bits(gb, TAK_FORMAT_CHANNEL_BITS) +
+                     TAK_CHANNELS_MIN;
 
     if (get_bits1(gb)) {
         skip_bits(gb, TAK_FORMAT_VALID_BITS);
@@ -136,31 +140,25 @@
     s->frame_samples = tak_get_nb_samples(s->sample_rate, frame_type);
 }
 
-#define FRAME_IS_LAST       1
-#define FRAME_HAVE_INFO     2
-#define FRAME_HAVE_METADATA 4
-
 int ff_tak_decode_frame_header(AVCodecContext *avctx, GetBitContext *gb,
                                TAKStreamInfo *ti, int log_level_offset)
 {
-    int flags;
-
     if (get_bits(gb, TAK_FRAME_HEADER_SYNC_ID_BITS) != TAK_FRAME_HEADER_SYNC_ID) {
         av_log(avctx, AV_LOG_ERROR + log_level_offset, "missing sync id\n");
         return AVERROR_INVALIDDATA;
     }
 
-    flags = get_bits(gb, TAK_FRAME_HEADER_FLAGS_BITS);
+    ti->flags     = get_bits(gb, TAK_FRAME_HEADER_FLAGS_BITS);
     ti->frame_num = get_bits(gb, TAK_FRAME_HEADER_NO_BITS);
 
-    if (flags & FRAME_IS_LAST) {
+    if (ti->flags & TAK_FRAME_FLAG_IS_LAST) {
         ti->last_frame_samples = get_bits(gb, TAK_FRAME_HEADER_SAMPLE_COUNT_BITS) + 1;
         skip_bits(gb, 2);
     } else {
         ti->last_frame_samples = 0;
     }
 
-    if (flags & FRAME_HAVE_INFO) {
+    if (ti->flags & TAK_FRAME_FLAG_HAS_INFO) {
         avpriv_tak_parse_streaminfo(gb, ti);
 
         if (get_bits(gb, 6))
@@ -168,7 +166,7 @@
         align_get_bits(gb);
     }
 
-    if (flags & FRAME_HAVE_METADATA)
+    if (ti->flags & TAK_FRAME_FLAG_HAS_METADATA)
         return AVERROR_INVALIDDATA;
 
     skip_bits(gb, 24);
diff --git a/libavcodec/tak.h b/libavcodec/tak.h
index cfa074d..876468d 100644
--- a/libavcodec/tak.h
+++ b/libavcodec/tak.h
@@ -27,68 +27,80 @@
 #ifndef AVCODEC_TAK_H
 #define AVCODEC_TAK_H
 
+#include <stdint.h>
+
 #define BITSTREAM_READER_LE
 #include "get_bits.h"
 #include "avcodec.h"
 
-#define TAK_FORMAT_DATA_TYPE_BITS    3
-#define TAK_FORMAT_SAMPLE_RATE_BITS  18
-#define TAK_FORMAT_BPS_BITS          5
-#define TAK_FORMAT_CHANNEL_BITS      4
-#define TAK_FORMAT_VALID_BITS        5
-#define TAK_FORMAT_CH_LAYOUT_BITS    6
-#define TAK_SIZE_FRAME_DURATION_BITS 4
-#define TAK_SIZE_SAMPLES_NUM_BITS    35
-#define TAK_LAST_FRAME_POS_BITS      40
-#define TAK_LAST_FRAME_SIZE_BITS     24
-#define TAK_ENCODER_CODEC_BITS       6
-#define TAK_ENCODER_PROFILE_BITS     4
-#define TAK_ENCODER_VERSION_BITS     24
-#define TAK_SAMPLE_RATE_MIN          6000
-#define TAK_CHANNELS_MIN             1
-#define TAK_BPS_MIN                  8
-#define TAK_FRAME_HEADER_FLAGS_BITS         3
-#define TAK_FRAME_HEADER_SYNC_ID            0xA0FF
-#define TAK_FRAME_HEADER_SYNC_ID_BITS       16
-#define TAK_FRAME_HEADER_SAMPLE_COUNT_BITS  14
-#define TAK_FRAME_HEADER_NO_BITS            21
-#define TAK_FRAME_DURATION_QUANT_SHIFT      5
-#define TAK_CRC24_BITS                      24
+#define TAK_FORMAT_DATA_TYPE_BITS               3
+#define TAK_FORMAT_SAMPLE_RATE_BITS            18
+#define TAK_FORMAT_BPS_BITS                     5
+#define TAK_FORMAT_CHANNEL_BITS                 4
+#define TAK_FORMAT_VALID_BITS                   5
+#define TAK_FORMAT_CH_LAYOUT_BITS               6
+#define TAK_SIZE_FRAME_DURATION_BITS            4
+#define TAK_SIZE_SAMPLES_NUM_BITS              35
+#define TAK_LAST_FRAME_POS_BITS                40
+#define TAK_LAST_FRAME_SIZE_BITS               24
+#define TAK_ENCODER_CODEC_BITS                  6
+#define TAK_ENCODER_PROFILE_BITS                4
+#define TAK_ENCODER_VERSION_BITS               24
+#define TAK_SAMPLE_RATE_MIN                  6000
+#define TAK_CHANNELS_MIN                        1
+#define TAK_BPS_MIN                             8
+#define TAK_FRAME_HEADER_FLAGS_BITS             3
+#define TAK_FRAME_HEADER_SYNC_ID           0xA0FF
+#define TAK_FRAME_HEADER_SYNC_ID_BITS          16
+#define TAK_FRAME_HEADER_SAMPLE_COUNT_BITS     14
+#define TAK_FRAME_HEADER_NO_BITS               21
+#define TAK_FRAME_DURATION_QUANT_SHIFT          5
+#define TAK_CRC24_BITS                         24
 
-#define TAK_MAX_CHANNELS                  ( 1 << TAK_FORMAT_CHANNEL_BITS )
 
-#define TAK_MIN_FRAME_HEADER_BITS         ( TAK_FRAME_HEADER_SYNC_ID_BITS + \
-                                            TAK_FRAME_HEADER_FLAGS_BITS   + \
-                                            TAK_FRAME_HEADER_NO_BITS      + \
-                                            TAK_CRC24_BITS )
+#define TAK_FRAME_FLAG_IS_LAST                0x1
+#define TAK_FRAME_FLAG_HAS_INFO               0x2
+#define TAK_FRAME_FLAG_HAS_METADATA           0x4
 
-#define TAK_MIN_FRAME_HEADER_LAST_BITS    ( TAK_MIN_FRAME_HEADER_BITS + 2 + \
-                                            TAK_FRAME_HEADER_SAMPLE_COUNT_BITS )
+#define TAK_MAX_CHANNELS               (1 << TAK_FORMAT_CHANNEL_BITS)
 
-#define TAK_ENCODER_BITS         ( TAK_ENCODER_CODEC_BITS        + \
-                                   TAK_ENCODER_PROFILE_BITS )
+#define TAK_MIN_FRAME_HEADER_BITS      (TAK_FRAME_HEADER_SYNC_ID_BITS + \
+                                        TAK_FRAME_HEADER_FLAGS_BITS   + \
+                                        TAK_FRAME_HEADER_NO_BITS      + \
+                                        TAK_CRC24_BITS)
 
-#define TAK_SIZE_BITS            ( TAK_SIZE_SAMPLES_NUM_BITS     + \
-                                   TAK_SIZE_FRAME_DURATION_BITS )
+#define TAK_MIN_FRAME_HEADER_LAST_BITS (TAK_MIN_FRAME_HEADER_BITS + 2 + \
+                                        TAK_FRAME_HEADER_SAMPLE_COUNT_BITS)
 
-#define TAK_FORMAT_BITS          ( TAK_FORMAT_DATA_TYPE_BITS     + \
-                                   TAK_FORMAT_SAMPLE_RATE_BITS   + \
-                                   TAK_FORMAT_BPS_BITS           + \
-                                   TAK_FORMAT_CHANNEL_BITS + 1   + \
-                                   TAK_FORMAT_VALID_BITS   + 1   + \
-                                   TAK_FORMAT_CH_LAYOUT_BITS     * \
-                                   TAK_MAX_CHANNELS )
+#define TAK_ENCODER_BITS               (TAK_ENCODER_CODEC_BITS + \
+                                        TAK_ENCODER_PROFILE_BITS)
 
-#define TAK_STREAMINFO_BITS      ( TAK_ENCODER_BITS              + \
-                                   TAK_SIZE_BITS                 + \
-                                   TAK_FORMAT_BITS )
+#define TAK_SIZE_BITS                  (TAK_SIZE_SAMPLES_NUM_BITS + \
+                                        TAK_SIZE_FRAME_DURATION_BITS)
 
-#define TAK_MAX_FRAME_HEADER_BITS  ( TAK_MIN_FRAME_HEADER_LAST_BITS + \
-                                     TAK_STREAMINFO_BITS + 31 )
+#define TAK_FORMAT_BITS                (TAK_FORMAT_DATA_TYPE_BITS   + \
+                                        TAK_FORMAT_SAMPLE_RATE_BITS + \
+                                        TAK_FORMAT_BPS_BITS         + \
+                                        TAK_FORMAT_CHANNEL_BITS + 1 + \
+                                        TAK_FORMAT_VALID_BITS   + 1 + \
+                                        TAK_FORMAT_CH_LAYOUT_BITS   * \
+                                        TAK_MAX_CHANNELS)
 
-#define TAK_STREAMINFO_BYTES        (( TAK_STREAMINFO_BITS + 7 ) / 8)
-#define TAK_MAX_FRAME_HEADER_BYTES  (( TAK_MAX_FRAME_HEADER_BITS + 7 ) / 8)
-#define TAK_MIN_FRAME_HEADER_BYTES  (( TAK_MIN_FRAME_HEADER_BITS + 7 ) / 8)
+#define TAK_STREAMINFO_BITS            (TAK_ENCODER_BITS + \
+                                        TAK_SIZE_BITS    + \
+                                        TAK_FORMAT_BITS)
+
+#define TAK_MAX_FRAME_HEADER_BITS      (TAK_MIN_FRAME_HEADER_LAST_BITS + \
+                                        TAK_STREAMINFO_BITS + 31)
+
+#define TAK_STREAMINFO_BYTES           ((TAK_STREAMINFO_BITS       + 7) / 8)
+#define TAK_MAX_FRAME_HEADER_BYTES     ((TAK_MAX_FRAME_HEADER_BITS + 7) / 8)
+#define TAK_MIN_FRAME_HEADER_BYTES     ((TAK_MIN_FRAME_HEADER_BITS + 7) / 8)
+
+enum TAKCodecType {
+    TAK_CODEC_MONO_STEREO  = 2,
+    TAK_CODEC_MULTICHANNEL = 4,
+};
 
 enum TAKMetaDataType {
     TAK_METADATA_END = 0,
@@ -115,16 +127,17 @@
 };
 
 typedef struct TAKStreamInfo {
-    int      codec;
-    int      data_type;
-    int      sample_rate;
-    int      channels;
-    int      bps;
-    int      frame_num;
-    int      frame_samples;
-    int      last_frame_samples;
-    uint64_t ch_layout;
-    int64_t  samples;
+    int               flags;
+    enum TAKCodecType codec;
+    int               data_type;
+    int               sample_rate;
+    int               channels;
+    int               bps;
+    int               frame_num;
+    int               frame_samples;
+    int               last_frame_samples;
+    uint64_t          ch_layout;
+    int64_t           samples;
 } TAKStreamInfo;
 
 void ff_tak_init_crc(void);
@@ -132,19 +145,20 @@
 int ff_tak_check_crc(const uint8_t *buf, unsigned int buf_size);
 
 /**
- * Parse the Streaminfo metadata block
- * @param[in]  gb      pointer to GetBitContext
- * @param[out] s       where parsed information is stored
+ * Parse the Streaminfo metadata block.
+ * @param[in]  gb pointer to GetBitContext
+ * @param[out] s  storage for parsed information
  */
 void avpriv_tak_parse_streaminfo(GetBitContext *gb, TAKStreamInfo *s);
 
 /**
  * Validate and decode a frame header.
- * @param      avctx AVCodecContext to use as av_log() context
- * @param[in]  gb    GetBitContext from which to read frame header
- * @param[out] s     frame information
- * @param      log_level_offset  log level offset. can be used to silence error messages.
- * @return non-zero on error, 0 if ok
+ * @param      avctx             AVCodecContext to use as av_log() context
+ * @param[in]  gb                GetBitContext from which to read frame header
+ * @param[out] s                 frame information
+ * @param      log_level_offset  log level offset, can be used to silence
+ *                               error messages.
+ * @return non-zero on error, 0 if OK
  */
 int ff_tak_decode_frame_header(AVCodecContext *avctx, GetBitContext *gb,
                                TAKStreamInfo *s, int log_level_offset);
diff --git a/libavcodec/tak_parser.c b/libavcodec/tak_parser.c
index 55766a4..0f2fbc2 100644
--- a/libavcodec/tak_parser.c
+++ b/libavcodec/tak_parser.c
@@ -24,13 +24,13 @@
  * TAK parser
  **/
 
-#include "parser.h"
 #include "tak.h"
+#include "parser.h"
 
 typedef struct TAKParseContext {
     ParseContext  pc;
     TAKStreamInfo ti;
-    int index;
+    int           index;
 } TAKParseContext;
 
 static av_cold int tak_init(AVCodecParserContext *s)
@@ -44,18 +44,18 @@
                      const uint8_t *buf, int buf_size)
 {
     TAKParseContext *t = s->priv_data;
-    ParseContext *pc = &t->pc;
-    int next = END_NOT_FOUND;
+    ParseContext *pc   = &t->pc;
+    int next           = END_NOT_FOUND;
     GetBitContext gb;
     int consumed = 0;
-    int needed = buf_size ? TAK_MAX_FRAME_HEADER_BYTES : 8;
+    int needed   = buf_size ? TAK_MAX_FRAME_HEADER_BYTES : 8;
 
     if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
         TAKStreamInfo ti;
         init_get_bits(&gb, buf, buf_size);
         if (!ff_tak_decode_frame_header(avctx, &gb, &ti, 127))
-            s->duration = t->ti.last_frame_samples ? t->ti.last_frame_samples :
-                                                     t->ti.frame_samples;
+            s->duration = t->ti.last_frame_samples ? t->ti.last_frame_samples
+                                                   : t->ti.frame_samples;
         *poutbuf      = buf;
         *poutbuf_size = buf_size;
         return buf_size;
@@ -63,7 +63,8 @@
 
     while (buf_size || t->index + needed <= pc->index) {
         if (buf_size && t->index + TAK_MAX_FRAME_HEADER_BYTES > pc->index) {
-            int tmp_buf_size = FFMIN(2 * TAK_MAX_FRAME_HEADER_BYTES, buf_size);
+            int tmp_buf_size       = FFMIN(2 * TAK_MAX_FRAME_HEADER_BYTES,
+                                           buf_size);
             const uint8_t *tmp_buf = buf;
 
             if (ff_combine_frame(pc, END_NOT_FOUND, &tmp_buf, &tmp_buf_size) != -1)
@@ -86,13 +87,13 @@
                                       get_bits_count(&gb) / 8)) {
                     if (!pc->frame_start_found) {
                         pc->frame_start_found = 1;
-                        s->duration = t->ti.last_frame_samples ?
-                                      t->ti.last_frame_samples :
-                                      t->ti.frame_samples;
+                        s->duration           = t->ti.last_frame_samples ?
+                                                t->ti.last_frame_samples :
+                                                t->ti.frame_samples;
                     } else {
                         pc->frame_start_found = 0;
-                        next = t->index - pc->index;
-                        t->index = 0;
+                        next                  = t->index - pc->index;
+                        t->index              = 0;
                         goto found;
                     }
                 }
@@ -109,7 +110,7 @@
     }
 
     if (next != END_NOT_FOUND) {
-        next += consumed;
+        next        += consumed;
         pc->overread = FFMAX(0, -next);
     }
 
diff --git a/libavcodec/takdec.c b/libavcodec/takdec.c
index 1120296..ae751fe 100644
--- a/libavcodec/takdec.c
+++ b/libavcodec/takdec.c
@@ -25,74 +25,64 @@
  * @author Paul B Mahol
  */
 
+#include "libavutil/internal.h"
+#include "libavutil/samplefmt.h"
 #include "tak.h"
 #include "avcodec.h"
-#include "unary.h"
 #include "dsputil.h"
+#include "internal.h"
+#include "unary.h"
 
-#define MAX_SUBFRAMES   8                       ///< max number of subframes per channel
+#define MAX_SUBFRAMES     8                         ///< max number of subframes per channel
 #define MAX_PREDICTORS  256
 
 typedef struct MCDParam {
-    int8_t     present;                         ///< is decorrelation parameters available for this channel
-    int8_t     index;                           ///< index into array of decorrelation types
-    int8_t     chan1;
-    int8_t     chan2;
+    int8_t present;                                 ///< decorrelation parameter availability for this channel
+    int8_t index;                                   ///< index into array of decorrelation types
+    int8_t chan1;
+    int8_t chan2;
 } MCDParam;
 
 typedef struct TAKDecContext {
-    AVCodecContext *avctx;                      ///< parent AVCodecContext
-    AVFrame        frame;                       ///< AVFrame for decoded output
-    DSPContext     dsp;
-    TAKStreamInfo  ti;
-    GetBitContext  gb;                          ///< bitstream reader initialized to start at the current frame
+    AVCodecContext *avctx;                          ///< parent AVCodecContext
+    DSPContext      dsp;
+    TAKStreamInfo   ti;
+    GetBitContext   gb;                             ///< bitstream reader initialized to start at the current frame
 
-    int            nb_samples;                  ///< number of samples in the current frame
-    int32_t        *decode_buffer;
-    int            decode_buffer_size;
-    int32_t        *decoded[TAK_MAX_CHANNELS];  ///< decoded samples for each channel
+    int             uval;
+    int             nb_samples;                     ///< number of samples in the current frame
+    uint8_t        *decode_buffer;
+    unsigned int    decode_buffer_size;
+    int32_t        *decoded[TAK_MAX_CHANNELS];      ///< decoded samples for each channel
 
-    int8_t         lpc_mode[TAK_MAX_CHANNELS];
-    int8_t         sample_shift[TAK_MAX_CHANNELS];  ///< shift applied to every sample in the channel
-    int32_t        xred;
-    int            size;
-    int            ared;
-    int            filter_order;
-    int16_t        predictors[MAX_PREDICTORS];
-    int            nb_subframes;                ///< number of subframes in the current frame
-    int16_t        subframe_len[MAX_SUBFRAMES]; ///< subframe length in samples
-    int            subframe_scale;
+    int8_t          lpc_mode[TAK_MAX_CHANNELS];
+    int8_t          sample_shift[TAK_MAX_CHANNELS]; ///< shift applied to every sample in the channel
+    int16_t         predictors[MAX_PREDICTORS];
+    int             nb_subframes;                   ///< number of subframes in the current frame
+    int16_t         subframe_len[MAX_SUBFRAMES];    ///< subframe length in samples
+    int             subframe_scale;
 
-    int8_t         dmode;                       ///< channel decorrelation type in the current frame
-    int8_t         dshift;
-    int16_t        dfactor;
-    int8_t         dval1;
-    int8_t         dval2;
+    int8_t          dmode;                          ///< channel decorrelation type in the current frame
 
-    MCDParam       mcdparams[TAK_MAX_CHANNELS]; ///< multichannel decorrelation parameters
+    MCDParam        mcdparams[TAK_MAX_CHANNELS];    ///< multichannel decorrelation parameters
 
-    int            wlength;
-    int            uval;
-    int            rval;
-    int8_t         coding_mode[128];
+    int8_t          coding_mode[128];
     DECLARE_ALIGNED(16, int16_t, filter)[MAX_PREDICTORS];
     DECLARE_ALIGNED(16, int16_t, residues)[544];
 } TAKDecContext;
 
-static const int8_t mc_dmodes[] = {
-    1, 3, 4, 6,
-};
+static const int8_t mc_dmodes[] = { 1, 3, 4, 6, };
 
 static const uint16_t predictor_sizes[] = {
     4, 8, 12, 16, 24, 32, 48, 64, 80, 96, 128, 160, 192, 224, 256, 0,
 };
 
 static const struct CParam {
-    int        init;
-    int        escape;
-    int        scale;
-    int        aescape;
-    int        bias;
+    int init;
+    int escape;
+    int scale;
+    int aescape;
+    int bias;
 } xcodes[50] = {
     { 0x01, 0x0000001, 0x0000001, 0x0000003, 0x0000008 },
     { 0x02, 0x0000003, 0x0000001, 0x0000007, 0x0000006 },
@@ -146,9 +136,9 @@
     { 0x1A, 0x1800000, 0x1800000, 0x6800000, 0xC000000 },
 };
 
-static int tak_set_bps(AVCodecContext *avctx, int bps)
+static int set_bps_params(AVCodecContext *avctx)
 {
-    switch (bps) {
+    switch (avctx->bits_per_raw_sample) {
     case 8:
         avctx->sample_fmt = AV_SAMPLE_FMT_U8P;
         break;
@@ -159,113 +149,86 @@
         avctx->sample_fmt = AV_SAMPLE_FMT_S32P;
         break;
     default:
-        av_log(avctx, AV_LOG_ERROR, "invalid/unsupported bits per sample\n");
+        av_log(avctx, AV_LOG_ERROR, "invalid/unsupported bits per sample: %d\n",
+               avctx->bits_per_raw_sample);
         return AVERROR_INVALIDDATA;
     }
 
     return 0;
 }
 
-static int get_shift(int sample_rate)
+static void set_sample_rate_params(AVCodecContext *avctx)
 {
-    int shift;
-
-    if (sample_rate < 11025)
-        shift = 3;
-    else if (sample_rate < 22050)
-        shift = 2;
-    else if (sample_rate < 44100)
-        shift = 1;
-    else
-        shift = 0;
-
-    return shift;
-}
-
-static int get_scale(int sample_rate, int shift)
-{
-    return FFALIGN(sample_rate + 511 >> 9, 4) << shift;
+    TAKDecContext *s  = avctx->priv_data;
+    int shift         = 3 - (avctx->sample_rate / 11025);
+    shift             = FFMAX(0, shift);
+    s->uval           = FFALIGN(avctx->sample_rate + 511 >> 9, 4) << shift;
+    s->subframe_scale = FFALIGN(avctx->sample_rate + 511 >> 9, 4) << 1;
 }
 
 static av_cold int tak_decode_init(AVCodecContext *avctx)
 {
     TAKDecContext *s = avctx->priv_data;
-    int ret;
 
     ff_tak_init_crc();
     ff_dsputil_init(&s->dsp, avctx);
 
     s->avctx = avctx;
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
+    avctx->bits_per_raw_sample = avctx->bits_per_coded_sample;
 
-    s->uval = get_scale(avctx->sample_rate, get_shift(avctx->sample_rate));
-    s->subframe_scale = get_scale(avctx->sample_rate, 1);
+    set_sample_rate_params(avctx);
 
-    if ((ret = tak_set_bps(avctx, avctx->bits_per_coded_sample)) < 0)
-        return ret;
-
-    return 0;
-}
-
-static int get_code(GetBitContext *gb, int nbits)
-{
-    if (nbits == 1) {
-        skip_bits1(gb);
-        return 0;
-    } else {
-        return get_sbits(gb, nbits);
-    }
+    return set_bps_params(avctx);
 }
 
 static void decode_lpc(int32_t *coeffs, int mode, int length)
 {
-    int i, a1, a2, a3, a4, a5;
+    int i;
 
     if (length < 2)
         return;
 
     if (mode == 1) {
-        a1 = *coeffs++;
-        for (i = 0; i < (length - 1 >> 1); i++) {
+        int a1 = *coeffs++;
+        for (i = 0; i < length - 1 >> 1; i++) {
             *coeffs   += a1;
             coeffs[1] += *coeffs;
-            a1      = coeffs[1];
+            a1         = coeffs[1];
             coeffs    += 2;
         }
-        if ((length - 1) & 1)
+        if (length - 1 & 1)
             *coeffs += a1;
     } else if (mode == 2) {
-        a1     = coeffs[1];
-        a2     = a1 + *coeffs;
+        int a1    = coeffs[1];
+        int a2    = a1 + *coeffs;
         coeffs[1] = a2;
         if (length > 2) {
             coeffs += 2;
-            for (i = 0; i < (length - 2 >> 1); i++) {
-                a3     = *coeffs + a1;
-                a4     = a3 + a2;
+            for (i = 0; i < length - 2 >> 1; i++) {
+                int a3    = *coeffs + a1;
+                int a4    = a3 + a2;
                 *coeffs   = a4;
-                a1     = coeffs[1] + a3;
-                a2     = a1 + a4;
+                a1        = coeffs[1] + a3;
+                a2        = a1 + a4;
                 coeffs[1] = a2;
                 coeffs   += 2;
             }
             if (length & 1)
-                *coeffs  += a1 + a2;
+                *coeffs += a1 + a2;
         }
     } else if (mode == 3) {
-        a1     = coeffs[1];
-        a2     = a1 + *coeffs;
+        int a1    = coeffs[1];
+        int a2    = a1 + *coeffs;
         coeffs[1] = a2;
         if (length > 2) {
-            a3   = coeffs[2];
-            a4   = a3 + a1;
-            a5   = a4 + a2;
+            int a3  = coeffs[2];
+            int a4  = a3 + a1;
+            int a5  = a4 + a2;
             coeffs += 3;
             for (i = 0; i < length - 3; i++) {
-                a3  += *coeffs;
-                a4  += a3;
-                a5  += a4;
+                a3     += *coeffs;
+                a4     += a3;
+                a5     += a4;
                 *coeffs = a5;
                 coeffs++;
             }
@@ -273,147 +236,130 @@
     }
 }
 
-static int decode_segment(TAKDecContext *s, int8_t value, int32_t *dst, int len)
+static int decode_segment(TAKDecContext *s, int8_t mode, int32_t *decoded, int len)
 {
+    struct CParam code;
     GetBitContext *gb = &s->gb;
+    int i;
 
-    if (!value) {
-        memset(dst, 0, len * 4);
-    } else {
-        int x, y, z, i = 0;
+    if (!mode) {
+        memset(decoded, 0, len * sizeof(*decoded));
+        return 0;
+    }
 
-        value--;
-        do {
-            while (1) {
-                x = get_bits_long(gb, xcodes[value].init);
-                if (x >= xcodes[value].escape)
-                    break;
-                dst[i++] = (x >> 1) ^ -(x & 1);
-                if (i >= len)
-                    return 0;
-            }
+    if (mode > FF_ARRAY_ELEMS(xcodes))
+        return AVERROR_INVALIDDATA;
+    code = xcodes[mode - 1];
 
-            y = get_bits1(gb);
-            x = (y << xcodes[value].init) | x;
-            if (x >= xcodes[value].aescape) {
-                int c = get_unary(gb, 1, 9);
-
-                if (c == 9) {
-                    int d;
-
-                    z = x + xcodes[value].bias;
-                    d = get_bits(gb, 3);
-                    if (d == 7) {
-                        d = get_bits(gb, 5) + 7;
-                        if (d > 29)
-                            return AVERROR_INVALIDDATA;
+    for (i = 0; i < len; i++) {
+        int x = get_bits_long(gb, code.init);
+        if (x >= code.escape && get_bits1(gb)) {
+            x |= 1 << code.init;
+            if (x >= code.aescape) {
+                int scale = get_unary(gb, 1, 9);
+                if (scale == 9) {
+                    int scale_bits = get_bits(gb, 3);
+                    if (scale_bits > 0) {
+                        if (scale_bits == 7) {
+                            scale_bits += get_bits(gb, 5);
+                            if (scale_bits > 29)
+                                return AVERROR_INVALIDDATA;
+                        }
+                        scale = get_bits_long(gb, scale_bits) + 1;
+                        x    += code.scale * scale;
                     }
-                    if (d)
-                        z += xcodes[value].scale * (get_bits_long(gb, d) + 1);
-                } else {
-                    z = xcodes[value].scale * c + x - xcodes[value].escape;
-                }
-            } else {
-                z = x - (xcodes[value].escape & -y);
-            }
-            dst[i++] = (z >> 1) ^ -(z & 1);
-        } while (i < len);
+                    x += code.bias;
+                } else
+                    x += code.scale * scale - code.escape;
+            } else
+                x -= code.escape;
+        }
+        decoded[i] = (x >> 1) ^ -(x & 1);
     }
 
     return 0;
 }
 
-static int xget(TAKDecContext *s, int d, int q)
-{
-    int x;
-
-    x = d / q;
-
-    s->rval = d - (x * q);
-
-    if (s->rval < q / 2) {
-        s->rval += q;
-    } else {
-        x++;
-    }
-
-    if (x <= 1 || x > 128)
-        return -1;
-
-    return x;
-}
-
-static int get_len(TAKDecContext *s, int b)
-{
-    if (b >= s->wlength - 1)
-        return s->rval;
-    else
-        return s->uval;
-}
-
-static int decode_coeffs(TAKDecContext *s, int32_t *dst, int length)
+static int decode_residues(TAKDecContext *s, int32_t *decoded, int length)
 {
     GetBitContext *gb = &s->gb;
-    int i, v, ret;
+    int i, mode, ret;
 
     if (length > s->nb_samples)
         return AVERROR_INVALIDDATA;
 
     if (get_bits1(gb)) {
-        if ((s->wlength = xget(s, length, s->uval)) < 0)
+        int wlength, rval;
+
+        wlength = length / s->uval;
+
+        rval = length - (wlength * s->uval);
+
+        if (rval < s->uval / 2)
+            rval += s->uval;
+        else
+            wlength++;
+
+        if (wlength <= 1 || wlength > 128)
             return AVERROR_INVALIDDATA;
 
-        s->coding_mode[0] = v = get_bits(gb, 6);
-        if (s->coding_mode[0] > FF_ARRAY_ELEMS(xcodes))
-            return AVERROR_INVALIDDATA;
+        s->coding_mode[0] = mode = get_bits(gb, 6);
 
-        for (i = 1; i < s->wlength; i++) {
+        for (i = 1; i < wlength; i++) {
             int c = get_unary(gb, 1, 6);
 
-            if (c > 5) {
-                v = get_bits(gb, 6);
-            } else if (c > 2) {
-                int t = get_bits1(gb);
-
-                v += (-t ^ (c - 1)) + t;
-            } else {
-                v += (-(c & 1) ^ (((c & 1) + c) >> 1)) + (c & 1);
+            switch (c) {
+            case 6:
+                mode = get_bits(gb, 6);
+                break;
+            case 5:
+            case 4:
+            case 3: {
+                /* mode += sign ? (1 - c) : (c - 1) */
+                int sign = get_bits1(gb);
+                mode    += (-sign ^ (c - 1)) + sign;
+                break;
             }
-
-            if (v > FF_ARRAY_ELEMS(xcodes))
-                return AVERROR_INVALIDDATA;
-            s->coding_mode[i] = v;
+            case 2:
+                mode++;
+                break;
+            case 1:
+                mode--;
+                break;
+            }
+            s->coding_mode[i] = mode;
         }
 
         i = 0;
-        while (i < s->wlength) {
+        while (i < wlength) {
             int len = 0;
 
-            v = s->coding_mode[i];
+            mode = s->coding_mode[i];
             do {
-                len += get_len(s, i);
+                if (i >= wlength - 1)
+                    len += rval;
+                else
+                    len += s->uval;
                 i++;
 
-                if (i == s->wlength)
+                if (i == wlength)
                     break;
-            } while (v == s->coding_mode[i]);
+            } while (s->coding_mode[i] == mode);
 
-            if ((ret = decode_segment(s, v, dst, len)) < 0)
+            if ((ret = decode_segment(s, mode, decoded, len)) < 0)
                 return ret;
-            dst += len;
+            decoded += len;
         }
     } else {
-        v = get_bits(gb, 6);
-        if (v > FF_ARRAY_ELEMS(xcodes))
-            return AVERROR_INVALIDDATA;
-        if ((ret = decode_segment(s, v, dst, length)) < 0)
+        mode = get_bits(gb, 6);
+        if ((ret = decode_segment(s, mode, decoded, length)) < 0)
             return ret;
     }
 
     return 0;
 }
 
-static int get_b(GetBitContext *gb)
+static int get_bits_esc4(GetBitContext *gb)
 {
     if (get_bits1(gb))
         return get_bits(gb, 4) + 1;
@@ -421,160 +367,157 @@
         return 0;
 }
 
-static int decode_subframe(TAKDecContext *s, int32_t *ptr, int subframe_size,
-                           int prev_subframe_size)
+static int decode_subframe(TAKDecContext *s, int32_t *decoded,
+                           int subframe_size, int prev_subframe_size)
 {
-    GetBitContext  *gb = &s->gb;
+    GetBitContext *gb = &s->gb;
     int tmp, x, y, i, j, ret = 0;
+    int dshift, size, filter_quant, filter_order;
     int tfilter[MAX_PREDICTORS];
 
-    if (get_bits1(gb)) {
-        s->filter_order = predictor_sizes[get_bits(gb, 4)];
+    if (!get_bits1(gb))
+        return decode_residues(s, decoded, subframe_size);
 
-        if (prev_subframe_size > 0 && get_bits1(gb)) {
-            if (s->filter_order > prev_subframe_size)
-                return AVERROR_INVALIDDATA;
+    filter_order = predictor_sizes[get_bits(gb, 4)];
 
-            ptr           -= s->filter_order;
-            subframe_size += s->filter_order;
+    if (prev_subframe_size > 0 && get_bits1(gb)) {
+        if (filter_order > prev_subframe_size)
+            return AVERROR_INVALIDDATA;
 
-            if (s->filter_order > subframe_size)
-                return AVERROR_INVALIDDATA;
-        } else {
-            int lpc;
+        decoded       -= filter_order;
+        subframe_size += filter_order;
 
-            if (s->filter_order > subframe_size)
-                return AVERROR_INVALIDDATA;
+        if (filter_order > subframe_size)
+            return AVERROR_INVALIDDATA;
+    } else {
+        int lpc_mode;
 
-            lpc = get_bits(gb, 2);
-            if (lpc > 2)
-                return AVERROR_INVALIDDATA;
+        if (filter_order > subframe_size)
+            return AVERROR_INVALIDDATA;
 
-            if ((ret = decode_coeffs(s, ptr, s->filter_order)) < 0)
-                return ret;
+        lpc_mode = get_bits(gb, 2);
+        if (lpc_mode > 2)
+            return AVERROR_INVALIDDATA;
 
-            decode_lpc(ptr, lpc, s->filter_order);
-        }
-
-        s->xred = get_b(gb);
-        s->size = get_bits1(gb) + 5;
-
-        if (get_bits1(gb)) {
-            s->ared = get_bits(gb, 3) + 1;
-            if (s->ared > 7)
-                return AVERROR_INVALIDDATA;
-        } else {
-            s->ared = 0;
-        }
-        s->predictors[0] = get_code(gb, 10);
-        s->predictors[1] = get_code(gb, 10);
-        s->predictors[2] = get_code(gb, s->size + 1) << (9 - s->size);
-        s->predictors[3] = get_code(gb, s->size + 1) << (9 - s->size);
-        if (s->filter_order > 4) {
-            tmp = s->size + 1 - get_bits1(gb);
-
-            for (i = 4; i < s->filter_order; i++) {
-                if (!(i & 3))
-                    x = tmp - get_bits(gb, 2);
-                s->predictors[i] = get_code(gb, x) << (9 - s->size);
-            }
-        }
-
-        tfilter[0] = s->predictors[0] << 6;
-        for (i = 1; i < s->filter_order; i++) {
-            int32_t *p1 = &tfilter[0];
-            int32_t *p2 = &tfilter[i - 1];
-
-            for (j = 0; j < (i + 1) / 2; j++) {
-                x     = *p1 + (s->predictors[i] * *p2 + 256 >> 9);
-                *p2  += s->predictors[i] * *p1 + 256 >> 9;
-                *p1++ = x;
-                p2--;
-            }
-
-            tfilter[i] = s->predictors[i] << 6;
-        }
-
-        x = -1 << (32 - (s->ared + 5));
-        y =  1 << ((s->ared + 5) - 1);
-        for (i = 0, j = s->filter_order - 1; i < s->filter_order / 2; i++, j--) {
-            tmp = y + tfilter[j];
-            s->filter[j] = -(x & -(y + tfilter[i] >> 31) |
-                            (y + tfilter[i]) >> (s->ared + 5));
-            s->filter[i] = -(x & -(tmp >> 31) | (tmp >> s->ared + 5));
-        }
-
-        if ((ret = decode_coeffs(s, &ptr[s->filter_order],
-                                 subframe_size - s->filter_order)) < 0)
+        if ((ret = decode_residues(s, decoded, filter_order)) < 0)
             return ret;
 
-        for (i = 0; i < s->filter_order; i++)
-            s->residues[i] = *ptr++ >> s->xred;
-
-        y    = FF_ARRAY_ELEMS(s->residues) - s->filter_order;
-        x    = subframe_size - s->filter_order;
-        while (x > 0) {
-            tmp = FFMIN(y, x);
-
-            for (i = 0; i < tmp; i++) {
-                int v, w, m;
-
-                v = 1 << (10 - s->ared - 1);
-                if (!(s->filter_order & 15)) {
-                    v += s->dsp.scalarproduct_int16(&s->residues[i], s->filter,
-                                                    s->filter_order);
-                } else if (s->filter_order & 4) {
-                    for (j = 0; j < s->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 < s->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    ];
-                    }
-                }
-                m = (-1 << (32 - (10 - s->ared))) & -(v >> 31) | (v >> 10 - s->ared);
-                m = av_clip(m, -8192, 8191);
-                w = (m << s->xred) - *ptr;
-                *ptr++ = w;
-                s->residues[s->filter_order + i] = w >> s->xred;
-            }
-
-            x -= tmp;
-            if (x > 0)
-                memcpy(s->residues, &s->residues[y], 2 * s->filter_order);
-        }
-
-        emms_c();
-    } else {
-        ret = decode_coeffs(s, ptr, subframe_size);
+        if (lpc_mode)
+            decode_lpc(decoded, lpc_mode, filter_order);
     }
 
-    return ret;
+    dshift = get_bits_esc4(gb);
+    size   = get_bits1(gb) + 6;
+
+    filter_quant = 10;
+    if (get_bits1(gb)) {
+        filter_quant -= get_bits(gb, 3) + 1;
+        if (filter_quant < 3)
+            return AVERROR_INVALIDDATA;
+    }
+
+    s->predictors[0] = get_sbits(gb, 10);
+    s->predictors[1] = get_sbits(gb, 10);
+    s->predictors[2] = get_sbits(gb, size) << (10 - size);
+    s->predictors[3] = get_sbits(gb, size) << (10 - size);
+    if (filter_order > 4) {
+        tmp = size - get_bits1(gb);
+
+        for (i = 4; i < filter_order; i++) {
+            if (!(i & 3))
+                x = tmp - get_bits(gb, 2);
+            s->predictors[i] = get_sbits(gb, x) << (10 - size);
+        }
+    }
+
+    tfilter[0] = s->predictors[0] << 6;
+    for (i = 1; i < filter_order; i++) {
+        int32_t *p1 = &tfilter[0];
+        int32_t *p2 = &tfilter[i - 1];
+
+        for (j = 0; j < (i + 1) / 2; j++) {
+            x     = *p1 + (s->predictors[i] * *p2 + 256 >> 9);
+            *p2  += s->predictors[i] * *p1 + 256 >> 9;
+            *p1++ = x;
+            p2--;
+        }
+
+        tfilter[i] = s->predictors[i] << 6;
+    }
+
+    x = 1 << (32 - (15 - filter_quant));
+    y = 1 << ((15 - filter_quant) - 1);
+    for (i = 0, j = filter_order - 1; i < filter_order / 2; i++, j--) {
+        tmp = y + tfilter[j];
+        s->filter[j] = x - ((tfilter[i] + y) >> (15 - filter_quant));
+        s->filter[i] = x - ((tfilter[j] + y) >> (15 - filter_quant));
+    }
+
+    if ((ret = decode_residues(s, &decoded[filter_order],
+                               subframe_size - filter_order)) < 0)
+        return ret;
+
+    for (i = 0; i < filter_order; i++)
+        s->residues[i] = *decoded++ >> dshift;
+
+    y    = FF_ARRAY_ELEMS(s->residues) - filter_order;
+    x    = subframe_size - filter_order;
+    while (x > 0) {
+        tmp = FFMIN(y, x);
+
+        for (i = 0; i < tmp; i++) {
+            int v = 1 << (filter_quant - 1);
+
+            if (!(filter_order & 15)) {
+                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    ];
+                }
+            }
+            v = (av_clip(v >> filter_quant, -8192, 8191) << dshift) - *decoded;
+            *decoded++ = v;
+            s->residues[filter_order + i] = v >> dshift;
+        }
+
+        x -= tmp;
+        if (x > 0)
+            memcpy(s->residues, &s->residues[y], 2 * filter_order);
+    }
+
+    emms_c();
+
+    return 0;
 }
 
 static int decode_channel(TAKDecContext *s, int chan)
 {
     AVCodecContext *avctx = s->avctx;
-    GetBitContext  *gb = &s->gb;
-    int32_t *dst = s->decoded[chan];
+    GetBitContext *gb     = &s->gb;
+    int32_t *decoded      = s->decoded[chan];
+    int left              = s->nb_samples - 1;
     int i = 0, ret, prev = 0;
-    int left = s->nb_samples - 1;
 
-    s->sample_shift[chan] = get_b(gb);
+    s->sample_shift[chan] = get_bits_esc4(gb);
     if (s->sample_shift[chan] >= avctx->bits_per_raw_sample)
         return AVERROR_INVALIDDATA;
 
-    *dst++ = get_code(gb, avctx->bits_per_raw_sample - s->sample_shift[chan]);
+    *decoded++ = get_sbits(gb, avctx->bits_per_raw_sample - s->sample_shift[chan]);
     s->lpc_mode[chan] = get_bits(gb, 2);
     s->nb_subframes   = get_bits(gb, 3) + 1;
 
@@ -596,14 +539,14 @@
         if (left <= 0)
             return AVERROR_INVALIDDATA;
     }
-
     s->subframe_len[i] = left;
+
     prev = 0;
     for (i = 0; i < s->nb_subframes; i++) {
-        if ((ret = decode_subframe(s, dst, s->subframe_len[i], prev)) < 0)
+        if ((ret = decode_subframe(s, decoded, s->subframe_len[i], prev)) < 0)
             return ret;
-        dst += s->subframe_len[i];
-        prev = s->subframe_len[i];
+        decoded += s->subframe_len[i];
+        prev     = s->subframe_len[i];
     }
 
     return 0;
@@ -611,102 +554,107 @@
 
 static int decorrelate(TAKDecContext *s, int c1, int c2, int length)
 {
-    GetBitContext  *gb = &s->gb;
-    uint32_t *p1 = s->decoded[c1] + 1;
-    uint32_t *p2 = s->decoded[c2] + 1;
-    int a, b, i, x, tmp;
-
-    if (s->dmode > 3) {
-        s->dshift = get_b(gb);
-        if (s->dmode > 5) {
-            if (get_bits1(gb))
-                s->filter_order = 16;
-            else
-                s->filter_order = 8;
-
-            s->dval1 = get_bits1(gb);
-            s->dval2 = get_bits1(gb);
-
-            for (i = 0; i < s->filter_order; i++) {
-                if (!(i & 3))
-                    x = 14 - get_bits(gb, 3);
-                s->filter[i] = get_code(gb, x);
-            }
-        } else {
-            s->dfactor = get_code(gb, 10);
-        }
-    }
+    GetBitContext *gb = &s->gb;
+    int32_t *p1       = s->decoded[c1] + 1;
+    int32_t *p2       = s->decoded[c2] + 1;
+    int i;
+    int dshift, dfactor;
 
     switch (s->dmode) {
-    case 1:
-        for (i = 0; i < length; i++, p1++, p2++)
-            *p2 += *p1;
-        break;
-    case 2:
-        for (i = 0; i < length; i++, p1++, p2++)
-            *p1 = *p2 - *p1;
-        break;
-    case 3:
-        for (i = 0; i < length; i++, p1++, p2++) {
-            x   = (*p2 & 1) + 2 * *p1;
-            a   = -*p2 + x;
-            b   =  *p2 + x;
-            *p1 = a & 0x80000000 | (a >> 1);
-            *p2 = b & 0x80000000 | (b >> 1);
+    case 1: /* left/side */
+        for (i = 0; i < length; i++) {
+            int32_t a = p1[i];
+            int32_t b = p2[i];
+            p2[i]     = a + b;
         }
         break;
-    case 4:
-        FFSWAP(uint32_t *, p1, p2);
-    case 5:
-        if (s->dshift)
-            tmp = -1 << (32 - s->dshift);
-        else
-            tmp = 0;
-
-        for (i = 0; i < length; i++, p1++, p2++) {
-            x   = s->dfactor * (tmp & -(*p2 >> 31) | (*p2 >> s->dshift)) + 128;
-            *p1 = ((-(x >> 31) & 0xFF000000 | (x >> 8)) << s->dshift) - *p1;
+    case 2: /* side/right */
+        for (i = 0; i < length; i++) {
+            int32_t a = p1[i];
+            int32_t b = p2[i];
+            p1[i]     = b - a;
+        }
+        break;
+    case 3: /* side/mid */
+        for (i = 0; i < length; i++) {
+            int32_t a = p1[i];
+            int32_t b = p2[i];
+            a        -= b >> 1;
+            p1[i]     = a;
+            p2[i]     = a + b;
+        }
+        break;
+    case 4: /* side/left with scale factor */
+        FFSWAP(int32_t*, p1, p2);
+    case 5: /* side/right with scale factor */
+        dshift  = get_bits_esc4(gb);
+        dfactor = get_sbits(gb, 10);
+        for (i = 0; i < length; i++) {
+            int32_t a = p1[i];
+            int32_t b = p2[i];
+            b         = dfactor * (b >> dshift) + 128 >> 8 << dshift;
+            p1[i]     = b - a;
         }
         break;
     case 6:
-        FFSWAP(uint32_t *, p1, p2);
-    case 7:
+        FFSWAP(int32_t*, p1, p2);
+    case 7: {
+        int length2, order_half, filter_order, dval1, dval2;
+        int tmp, x, code_size;
+
         if (length < 256)
             return AVERROR_INVALIDDATA;
 
-        a = s->filter_order / 2;
-        b = length - (s->filter_order - 1);
+        dshift       = get_bits_esc4(gb);
+        filter_order = 8 << get_bits1(gb);
+        dval1        = get_bits1(gb);
+        dval2        = get_bits1(gb);
 
-        if (s->dval1) {
-            for (i = 0; i < a; i++)
-                p1[i] += p2[i];
+        for (i = 0; i < filter_order; i++) {
+            if (!(i & 3))
+                code_size = 14 - get_bits(gb, 3);
+            s->filter[i] = get_sbits(gb, code_size);
         }
 
-        if (s->dval2) {
-            x = a + b;
-            for (i = 0; i < length - x; i++)
-                p1[x + i] += p2[x + i];
+        order_half = filter_order / 2;
+        length2    = length - (filter_order - 1);
+
+        /* decorrelate beginning samples */
+        if (dval1) {
+            for (i = 0; i < order_half; i++) {
+                int32_t a = p1[i];
+                int32_t b = p2[i];
+                p1[i]     = a + b;
+            }
         }
 
-        for (i = 0; i < s->filter_order; i++)
-            s->residues[i] = *p2++ >> s->dshift;
+        /* decorrelate ending samples */
+        if (dval2) {
+            for (i = length2 + order_half; i < length; i++) {
+                int32_t a = p1[i];
+                int32_t b = p2[i];
+                p1[i]     = a + b;
+            }
+        }
 
-        p1 += a;
-        x = FF_ARRAY_ELEMS(s->residues) - s->filter_order;
-        for (; b > 0; b -= tmp) {
-            tmp = FFMIN(b, x);
+
+        for (i = 0; i < filter_order; i++)
+            s->residues[i] = *p2++ >> dshift;
+
+        p1 += order_half;
+        x = FF_ARRAY_ELEMS(s->residues) - filter_order;
+        for (; length2 > 0; length2 -= tmp) {
+            tmp = FFMIN(length2, x);
 
             for (i = 0; i < tmp; i++)
-                s->residues[s->filter_order + i] = *p2++ >> s->dshift;
+                s->residues[filter_order + i] = *p2++ >> dshift;
 
             for (i = 0; i < tmp; i++) {
-                int v, w, m;
+                int v = 1 << 9;
 
-                v = 1 << 9;
-
-                if (s->filter_order == 16) {
+                if (filter_order == 16) {
                     v += s->dsp.scalarproduct_int16(&s->residues[i], s->filter,
-                                                    s->filter_order);
+                                                    filter_order);
                 } else {
                     v += s->residues[i + 7] * s->filter[7] +
                          s->residues[i + 6] * s->filter[6] +
@@ -718,18 +666,17 @@
                          s->residues[i    ] * s->filter[0];
                 }
 
-                m = (-1 << 22) & -(v >> 31) | (v >> 10);
-                m = av_clip(m, -8192, 8191);
-                w = (m << s->dshift) - *p1;
-                *p1++ = w;
+                v = (av_clip(v >> 10, -8192, 8191) << dshift) - *p1;
+                *p1++ = v;
             }
 
-            memcpy(s->residues, &s->residues[tmp], 2 * s->filter_order);
+            memcpy(s->residues, &s->residues[tmp], 2 * filter_order);
         }
 
         emms_c();
         break;
     }
+    }
 
     return 0;
 }
@@ -737,15 +684,16 @@
 static int tak_decode_frame(AVCodecContext *avctx, void *data,
                             int *got_frame_ptr, AVPacket *pkt)
 {
-    TAKDecContext  *s = avctx->priv_data;
+    TAKDecContext *s  = avctx->priv_data;
+    AVFrame *frame    = data;
     GetBitContext *gb = &s->gb;
     int chan, i, ret, hsize;
-    int32_t *p;
 
     if (pkt->size < TAK_MIN_FRAME_HEADER_BYTES)
         return AVERROR_INVALIDDATA;
 
-    init_get_bits(gb, pkt->data, pkt->size * 8);
+    if ((ret = init_get_bits8(gb, pkt->data, pkt->size)) < 0)
+        return ret;
 
     if ((ret = ff_tak_decode_frame_header(avctx, gb, &s->ti, 0)) < 0)
         return ret;
@@ -758,20 +706,24 @@
         }
     }
 
-    if (s->ti.codec != 2 && s->ti.codec != 4) {
+    if (s->ti.codec != TAK_CODEC_MONO_STEREO &&
+        s->ti.codec != TAK_CODEC_MULTICHANNEL) {
         av_log(avctx, AV_LOG_ERROR, "unsupported codec: %d\n", s->ti.codec);
         return AVERROR_PATCHWELCOME;
     }
     if (s->ti.data_type) {
-        av_log(avctx, AV_LOG_ERROR, "unsupported data type: %d\n", s->ti.data_type);
+        av_log(avctx, AV_LOG_ERROR,
+               "unsupported data type: %d\n", s->ti.data_type);
         return AVERROR_INVALIDDATA;
     }
-    if (s->ti.codec == 2 && s->ti.channels > 2) {
-        av_log(avctx, AV_LOG_ERROR, "invalid number of channels: %d\n", s->ti.channels);
+    if (s->ti.codec == TAK_CODEC_MONO_STEREO && s->ti.channels > 2) {
+        av_log(avctx, AV_LOG_ERROR,
+               "invalid number of channels: %d\n", s->ti.channels);
         return AVERROR_INVALIDDATA;
     }
     if (s->ti.channels > 6) {
-        av_log(avctx, AV_LOG_ERROR, "unsupported number of channels: %d\n", s->ti.channels);
+        av_log(avctx, AV_LOG_ERROR,
+               "unsupported number of channels: %d\n", s->ti.channels);
         return AVERROR_INVALIDDATA;
     }
 
@@ -782,62 +734,64 @@
 
     if (s->ti.bps != avctx->bits_per_raw_sample) {
         avctx->bits_per_raw_sample = s->ti.bps;
-        if ((ret = tak_set_bps(avctx, avctx->bits_per_raw_sample)) < 0)
+        if ((ret = set_bps_params(avctx)) < 0)
             return ret;
     }
     if (s->ti.sample_rate != avctx->sample_rate) {
         avctx->sample_rate = s->ti.sample_rate;
-        s->uval = get_scale(avctx->sample_rate, get_shift(avctx->sample_rate));
-        s->subframe_scale = get_scale(avctx->sample_rate, 1);
+        set_sample_rate_params(avctx);
     }
     if (s->ti.ch_layout)
         avctx->channel_layout = s->ti.ch_layout;
     avctx->channels = s->ti.channels;
 
-    s->nb_samples = s->ti.last_frame_samples ? s->ti.last_frame_samples :
-                                               s->ti.frame_samples;
+    s->nb_samples = s->ti.last_frame_samples ? s->ti.last_frame_samples
+                                             : s->ti.frame_samples;
 
-    s->frame.nb_samples = s->nb_samples;
-    if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0)
+    frame->nb_samples = s->nb_samples;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0)
         return ret;
 
     if (avctx->bits_per_raw_sample <= 16) {
-        av_fast_malloc(&s->decode_buffer, &s->decode_buffer_size,
-                       sizeof(*s->decode_buffer) * FFALIGN(s->nb_samples, 8) *
-                       avctx->channels + FF_INPUT_BUFFER_PADDING_SIZE);
+        int buf_size = av_samples_get_buffer_size(NULL, avctx->channels,
+                                                  s->nb_samples,
+                                                  AV_SAMPLE_FMT_S32P, 0);
+        av_fast_malloc(&s->decode_buffer, &s->decode_buffer_size, buf_size);
         if (!s->decode_buffer)
             return AVERROR(ENOMEM);
-        for (chan = 0; chan < avctx->channels; chan++)
-            s->decoded[chan] = s->decode_buffer +
-                               chan * FFALIGN(s->nb_samples, 8);
+        ret = av_samples_fill_arrays((uint8_t **)s->decoded, NULL,
+                                     s->decode_buffer, avctx->channels,
+                                     s->nb_samples, AV_SAMPLE_FMT_S32P, 0);
+        if (ret < 0)
+            return ret;
     } else {
         for (chan = 0; chan < avctx->channels; chan++)
-            s->decoded[chan] = (int32_t *)s->frame.data[chan];
+            s->decoded[chan] = (int32_t *)frame->extended_data[chan];
     }
 
     if (s->nb_samples < 16) {
         for (chan = 0; chan < avctx->channels; chan++) {
-            p = s->decoded[chan];
+            int32_t *decoded = s->decoded[chan];
             for (i = 0; i < s->nb_samples; i++)
-                *p++ = get_code(gb, avctx->bits_per_raw_sample);
+                decoded[i] = get_sbits(gb, avctx->bits_per_raw_sample);
         }
     } else {
-        if (s->ti.codec == 2) {
-            for (chan = 0; chan < avctx->channels; chan++) {
+        if (s->ti.codec == TAK_CODEC_MONO_STEREO) {
+            for (chan = 0; chan < avctx->channels; chan++)
                 if (ret = decode_channel(s, chan))
                     return ret;
-            }
 
             if (avctx->channels == 2) {
                 s->nb_subframes = get_bits(gb, 1) + 1;
-                if (s->nb_subframes > 1)
+                if (s->nb_subframes > 1) {
                     s->subframe_len[1] = get_bits(gb, 6);
+                }
 
                 s->dmode = get_bits(gb, 3);
                 if (ret = decorrelate(s, 0, 1, s->nb_samples - 1))
                     return ret;
             }
-        } else if (s->ti.codec == 4) {
+        } else if (s->ti.codec == TAK_CODEC_MULTICHANNEL) {
             if (get_bits1(gb)) {
                 int ch_mask = 0;
 
@@ -881,32 +835,33 @@
             }
 
             for (i = 0; i < chan; i++) {
-                if (s->mcdparams[i].present && s->mcdparams[i].index == 1) {
+                if (s->mcdparams[i].present && s->mcdparams[i].index == 1)
                     if (ret = decode_channel(s, s->mcdparams[i].chan2))
                         return ret;
-                }
 
                 if (ret = decode_channel(s, s->mcdparams[i].chan1))
                     return ret;
 
                 if (s->mcdparams[i].present) {
                     s->dmode = mc_dmodes[s->mcdparams[i].index];
-                    if (ret = decorrelate(s, s->mcdparams[i].chan2,
-                                             s->mcdparams[i].chan1,
-                                             s->nb_samples - 1))
+                    if (ret = decorrelate(s,
+                                          s->mcdparams[i].chan2,
+                                          s->mcdparams[i].chan1,
+                                          s->nb_samples - 1))
                         return ret;
                 }
             }
         }
 
         for (chan = 0; chan < avctx->channels; chan++) {
-            p = s->decoded[chan];
-            decode_lpc(p, s->lpc_mode[chan], s->nb_samples);
+            int32_t *decoded = s->decoded[chan];
 
-            if (s->sample_shift[chan] > 0) {
+            if (s->lpc_mode[chan])
+                decode_lpc(decoded, s->lpc_mode[chan], s->nb_samples);
+
+            if (s->sample_shift[chan] > 0)
                 for (i = 0; i < s->nb_samples; i++)
-                    *p++ <<= s->sample_shift[chan];
-            }
+                    decoded[i] <<= s->sample_shift[chan];
         }
     }
 
@@ -925,35 +880,34 @@
         }
     }
 
-    // convert to output buffer
-    switch (avctx->bits_per_raw_sample) {
-    case 8:
+    /* convert to output buffer */
+    switch (avctx->sample_fmt) {
+    case AV_SAMPLE_FMT_U8P:
         for (chan = 0; chan < avctx->channels; chan++) {
-            uint8_t *samples = (uint8_t *)s->frame.data[chan];
-            p = s->decoded[chan];
-            for (i = 0; i < s->nb_samples; i++, p++)
-                *samples++ = *p + 0x80;
-        }
-        break;
-    case 16:
-        for (chan = 0; chan < avctx->channels; chan++) {
-            int16_t *samples = (int16_t *)s->frame.data[chan];
-            p = s->decoded[chan];
-            for (i = 0; i < s->nb_samples; i++, p++)
-                *samples++ = *p;
-        }
-        break;
-    case 24:
-        for (chan = 0; chan < avctx->channels; chan++) {
-            int32_t *samples = (int32_t *)s->frame.data[chan];
+            uint8_t *samples = (uint8_t *)frame->extended_data[chan];
+            int32_t *decoded = s->decoded[chan];
             for (i = 0; i < s->nb_samples; i++)
-                *samples++ <<= 8;
+                samples[i] = decoded[i] + 0x80;
+        }
+        break;
+    case AV_SAMPLE_FMT_S16P:
+        for (chan = 0; chan < avctx->channels; chan++) {
+            int16_t *samples = (int16_t *)frame->extended_data[chan];
+            int32_t *decoded = s->decoded[chan];
+            for (i = 0; i < s->nb_samples; i++)
+                samples[i] = decoded[i];
+        }
+        break;
+    case AV_SAMPLE_FMT_S32P:
+        for (chan = 0; chan < avctx->channels; chan++) {
+            int32_t *samples = (int32_t *)frame->extended_data[chan];
+            for (i = 0; i < s->nb_samples; i++)
+                samples[i] <<= 8;
         }
         break;
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
+    *got_frame_ptr = 1;
 
     return pkt->size;
 }
@@ -968,17 +922,17 @@
 }
 
 AVCodec ff_tak_decoder = {
-    .name           = "tak",
-    .type           = AVMEDIA_TYPE_AUDIO,
-    .id             = AV_CODEC_ID_TAK,
-    .priv_data_size = sizeof(TAKDecContext),
-    .init           = tak_decode_init,
-    .close          = tak_decode_close,
-    .decode         = tak_decode_frame,
-    .capabilities   = CODEC_CAP_DR1,
-    .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,
-                                                      AV_SAMPLE_FMT_S32P,
-                                                      AV_SAMPLE_FMT_NONE },
+    .name             = "tak",
+    .type             = AVMEDIA_TYPE_AUDIO,
+    .id               = AV_CODEC_ID_TAK,
+    .priv_data_size   = sizeof(TAKDecContext),
+    .init             = tak_decode_init,
+    .close            = tak_decode_close,
+    .decode           = tak_decode_frame,
+    .capabilities     = CODEC_CAP_DR1,
+    .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,
+                                                        AV_SAMPLE_FMT_S32P,
+                                                        AV_SAMPLE_FMT_NONE },
 };
diff --git a/libavcodec/targa.c b/libavcodec/targa.c
index d761078..2d1d3df 100644
--- a/libavcodec/targa.c
+++ b/libavcodec/targa.c
@@ -23,6 +23,7 @@
 #include "libavutil/imgutils.h"
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 #include "targa.h"
 
 typedef struct TargaContext {
@@ -39,7 +40,7 @@
         return line + interleave * stride;
     } else {
         *y = (*y + 1) & (interleave - 1);
-        if (*y) {
+        if (*y && *y < h) {
             return start + *y * stride;
         } else {
             return NULL;
@@ -107,7 +108,7 @@
 }
 
 static int decode_frame(AVCodecContext *avctx,
-                        void *data, int *data_size,
+                        void *data, int *got_frame,
                         AVPacket *avpkt)
 {
     TargaContext * const s = avctx->priv_data;
@@ -177,11 +178,11 @@
         return AVERROR_INVALIDDATA;
     }
 
-    if ((ret = av_image_check_size(w, h, 0, avctx)))
+    if ((ret = av_image_check_size(w, h, 0, avctx)) < 0)
         return ret;
     if (w != avctx->width || h != avctx->height)
         avcodec_set_dimensions(avctx, w, h);
-    if ((ret = avctx->get_buffer(avctx, p)) < 0) {
+    if ((ret = ff_get_buffer(avctx, p)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -199,6 +200,7 @@
 
     if (colors) {
         int pal_size, pal_sample_size;
+
         switch (csize) {
         case 32: pal_sample_size = 4; break;
         case 24: pal_sample_size = 3; break;
@@ -266,7 +268,7 @@
             line = dst;
             y = 0;
             do {
-                bytestream2_get_bufferu(&s->gb, line, img_size);
+                bytestream2_get_buffer(&s->gb, line, img_size);
                 line = advance_line(dst, line, stride, &y, h, interleave);
             } while (line);
         }
@@ -297,7 +299,7 @@
     }
 
     *picture   = s->picture;
-    *data_size = sizeof(AVPicture);
+    *got_frame = 1;
 
     return avpkt->size;
 }
diff --git a/libavcodec/targa_y216dec.c b/libavcodec/targa_y216dec.c
index bac5aee..3b97000 100644
--- a/libavcodec/targa_y216dec.c
+++ b/libavcodec/targa_y216dec.c
@@ -20,6 +20,7 @@
  */
 
 #include "avcodec.h"
+#include "internal.h"
 
 static av_cold int y216_decode_init(AVCodecContext *avctx)
 {
@@ -37,7 +38,7 @@
 }
 
 static int y216_decode_frame(AVCodecContext *avctx, void *data,
-                             int *data_size, AVPacket *avpkt)
+                             int *got_frame, AVPacket *avpkt)
 {
     AVFrame *pic = avctx->coded_frame;
     const uint16_t *src = (uint16_t *)avpkt->data;
@@ -54,7 +55,7 @@
 
     pic->reference = 0;
 
-    if (avctx->get_buffer(avctx, pic) < 0) {
+    if (ff_get_buffer(avctx, pic) < 0) {
         av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
         return AVERROR(ENOMEM);
     }
@@ -80,7 +81,7 @@
         src += aligned_width << 1;
     }
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame *)data = *pic;
 
     return avpkt->size;
diff --git a/libavcodec/textdec.c b/libavcodec/textdec.c
index 4b3a4ad..f3e6117 100644
--- a/libavcodec/textdec.c
+++ b/libavcodec/textdec.c
@@ -30,25 +30,17 @@
 
 typedef struct {
     AVClass *class;
-    char *linebreaks;
+    const char *linebreaks;
     int keep_ass_markup;
 } TextContext;
 
 #define OFFSET(x) offsetof(TextContext, x)
 #define SD AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_DECODING_PARAM
 static const AVOption options[] = {
-    { "linebreaks",      "Extra line breaks characters",    OFFSET(linebreaks),      AV_OPT_TYPE_STRING, {.str=NULL},    .flags=SD },
     { "keep_ass_markup", "Set if ASS tags must be escaped", OFFSET(keep_ass_markup), AV_OPT_TYPE_INT,    {.i64=0}, 0, 1, .flags=SD },
     { NULL }
 };
 
-static const AVClass text_decoder_class = {
-    .class_name = "text decoder",
-    .item_name  = av_default_item_name,
-    .option     = options,
-    .version    = LIBAVUTIL_VERSION_INT,
-};
-
 static int text_event_to_ass(const AVCodecContext *avctx, AVBPrint *buf,
                              const char *p, const char *p_end)
 {
@@ -113,6 +105,17 @@
     return avpkt->size;
 }
 
+#define DECLARE_CLASS(decname) static const AVClass decname ## _decoder_class = {   \
+    .class_name = #decname " decoder",      \
+    .item_name  = av_default_item_name,     \
+    .option     = decname ## _options,      \
+    .version    = LIBAVUTIL_VERSION_INT,    \
+}
+
+#if CONFIG_TEXT_DECODER
+#define text_options options
+DECLARE_CLASS(text);
+
 AVCodec ff_text_decoder = {
     .name           = "text",
     .priv_data_size = sizeof(TextContext),
@@ -123,3 +126,63 @@
     .init           = ff_ass_subtitle_header_default,
     .priv_class     = &text_decoder_class,
 };
+#endif
+
+#if CONFIG_VPLAYER_DECODER || CONFIG_PJS_DECODER || CONFIG_SUBVIEWER1_DECODER
+
+static int linebreak_init(AVCodecContext *avctx)
+{
+    TextContext *text = avctx->priv_data;
+    text->linebreaks = "|";
+    return ff_ass_subtitle_header_default(avctx);
+}
+
+#if CONFIG_VPLAYER_DECODER
+#define vplayer_options options
+DECLARE_CLASS(vplayer);
+
+AVCodec ff_vplayer_decoder = {
+    .name           = "vplayer",
+    .priv_data_size = sizeof(TextContext),
+    .long_name      = NULL_IF_CONFIG_SMALL("VPlayer subtitle"),
+    .type           = AVMEDIA_TYPE_SUBTITLE,
+    .id             = AV_CODEC_ID_VPLAYER,
+    .decode         = text_decode_frame,
+    .init           = linebreak_init,
+    .priv_class     = &vplayer_decoder_class,
+};
+#endif
+
+#if CONFIG_PJS_DECODER
+#define pjs_options options
+DECLARE_CLASS(pjs);
+
+AVCodec ff_pjs_decoder = {
+    .name           = "pjs",
+    .priv_data_size = sizeof(TextContext),
+    .long_name      = NULL_IF_CONFIG_SMALL("PJS subtitle"),
+    .type           = AVMEDIA_TYPE_SUBTITLE,
+    .id             = AV_CODEC_ID_PJS,
+    .decode         = text_decode_frame,
+    .init           = linebreak_init,
+    .priv_class     = &pjs_decoder_class,
+};
+#endif
+
+#if CONFIG_SUBVIEWER1_DECODER
+#define subviewer1_options options
+DECLARE_CLASS(subviewer1);
+
+AVCodec ff_subviewer1_decoder = {
+    .name           = "subviewer1",
+    .priv_data_size = sizeof(TextContext),
+    .long_name      = NULL_IF_CONFIG_SMALL("SubViewer1 subtitle"),
+    .type           = AVMEDIA_TYPE_SUBTITLE,
+    .id             = AV_CODEC_ID_SUBVIEWER1,
+    .decode         = text_decode_frame,
+    .init           = linebreak_init,
+    .priv_class     = &subviewer1_decoder_class,
+};
+#endif
+
+#endif /* text subtitles with '|' line break */
diff --git a/libavcodec/thread.h b/libavcodec/thread.h
index 6de28a5..e838030 100644
--- a/libavcodec/thread.h
+++ b/libavcodec/thread.h
@@ -89,7 +89,7 @@
 
 /**
  * Wrapper around get_buffer() for frame-multithreaded codecs.
- * Call this function instead of avctx->get_buffer(f).
+ * Call this function instead of ff_get_buffer(f).
  * Cannot be called after the codec has called ff_thread_finish_setup().
  *
  * @param avctx The current context.
diff --git a/libavcodec/tiertexseqv.c b/libavcodec/tiertexseqv.c
index 62b7eeb..3ae7c88 100644
--- a/libavcodec/tiertexseqv.c
+++ b/libavcodec/tiertexseqv.c
@@ -223,7 +223,7 @@
 }
 
 static int seqvideo_decode_frame(AVCodecContext *avctx,
-                                 void *data, int *data_size,
+                                 void *data, int *got_frame,
                                  AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
@@ -241,7 +241,7 @@
     if (seqvideo_decode(seq, buf, buf_size))
         return AVERROR_INVALIDDATA;
 
-    *data_size = sizeof(AVFrame);
+    *got_frame       = 1;
     *(AVFrame *)data = seq->frame;
 
     return buf_size;
diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index 34fb109..77706c0 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -34,6 +34,7 @@
 #include "tiff.h"
 #include "tiff_data.h"
 #include "faxcompr.h"
+#include "internal.h"
 #include "mathops.h"
 #include "libavutil/attributes.h"
 #include "libavutil/intreadwrite.h"
@@ -61,6 +62,9 @@
     int stripsizesoff, stripsize, stripoff, strippos;
     LZWState *lzw;
 
+    uint8_t *deinvert_buf;
+    int deinvert_buf_size;
+
     int geotag_count;
     TiffGeoTag *geotags;
 } TiffContext;
@@ -135,7 +139,11 @@
 
 static const char *search_keyval(const TiffGeoTagKeyName *keys, int n, int id)
 {
-    return ((TiffGeoTagKeyName*)bsearch(&id, keys, n, sizeof(keys[0]), cmp_id_key))->name;
+    TiffGeoTagKeyName *r = bsearch(&id, keys, n, sizeof(keys[0]), cmp_id_key);
+    if(r)
+        return r->name;
+
+    return NULL;
 }
 
 static char *get_geokey_val(int key, int val)
@@ -183,10 +191,12 @@
         RET_GEOKEY_VAL(PRIME_MERIDIAN, prime_meridian);
         break;
     case TIFF_PROJECTED_CS_TYPE_GEOKEY:
-        return av_strdup(search_keyval(ff_tiff_proj_cs_type_codes, FF_ARRAY_ELEMS(ff_tiff_proj_cs_type_codes), val));
+        ap = av_strdup(search_keyval(ff_tiff_proj_cs_type_codes, FF_ARRAY_ELEMS(ff_tiff_proj_cs_type_codes), val));
+        if(ap) return ap;
         break;
     case TIFF_PROJECTION_GEOKEY:
-        return av_strdup(search_keyval(ff_tiff_projection_codes, FF_ARRAY_ELEMS(ff_tiff_projection_codes), val));
+        ap = av_strdup(search_keyval(ff_tiff_projection_codes, FF_ARRAY_ELEMS(ff_tiff_projection_codes), val));
+        if(ap) return ap;
         break;
     case TIFF_PROJ_COORD_TRANS_GEOKEY:
         RET_GEOKEY_VAL(COORD_TRANS, coord_trans);
@@ -208,10 +218,12 @@
 {
     int i;
     char *ap, *ap0;
-    int component_len;
+    uint64_t component_len;
     if (!sep) sep = ", ";
-    component_len = 15 + strlen(sep);
-    ap = av_malloc(component_len * count);
+    component_len = 15LL + strlen(sep);
+    if (count >= (INT_MAX - 1)/component_len)
+        return NULL;
+    ap = av_malloc(component_len * count + 1);
     if (!ap)
         return NULL;
     ap0   = ap;
@@ -232,14 +244,22 @@
 {
     int i;
     char *ap, *ap0;
+    uint64_t component_len;
     if (!sep) sep = ", ";
-    ap = av_malloc((5 + strlen(sep)) * count);
+    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++) {
-        int l = snprintf(ap, 5 + strlen(sep), "%d%s", sp[i], sep);
+        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';
@@ -304,7 +324,7 @@
 {
     char *value;
 
-    if (bytestream2_get_bytes_left(&s->gb) < count)
+    if (bytestream2_get_bytes_left(&s->gb) < count || count < 0)
         return AVERROR_INVALIDDATA;
 
     value = av_malloc(count + 1);
@@ -395,7 +415,7 @@
 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;
+    int c, line, pixels, code, ret;
     const uint8_t *ssrc = src;
     int width = ((s->width * s->bpp) + 7) >> 3;
 
@@ -404,20 +424,33 @@
 
 #if CONFIG_ZLIB
     if (s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE) {
-        uint8_t *zbuf;
+        uint8_t *src2 = NULL, *zbuf;
         unsigned long outlen;
-        int ret;
+        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 -1;
+            return AVERROR_UNKNOWN;
         }
         src = zbuf;
         for (line = 0; line < lines; line++) {
@@ -429,14 +462,28 @@
             dst += stride;
             src += width;
         }
+        av_free(src2);
         av_free(zbuf);
         return 0;
     }
 #endif
     if (s->compr == TIFF_LZW) {
-        if (ff_lzw_decode_init(s->lzw, 8, src, size, FF_LZW_TIFF) < 0) {
+        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 (size > 1 && !src[0] && (src[1]&1)) {
+            av_log(s->avctx, AV_LOG_ERROR, "Old style LZW is unsupported\n");
+        }
+        if ((ret = ff_lzw_decode_init(s->lzw, 8, src, size, FF_LZW_TIFF)) < 0) {
             av_log(s->avctx, AV_LOG_ERROR, "Error initializing LZW decoder\n");
-            return -1;
+            return ret;
         }
     }
     if (s->compr == TIFF_CCITT_RLE || s->compr == TIFF_G3
@@ -454,7 +501,7 @@
             av_log(s->avctx, AV_LOG_ERROR,
                    "Uncompressed fax mode is not supported (yet)\n");
             av_free(src2);
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
         if (!s->fill_order) {
             memcpy(src2, src, size);
@@ -482,7 +529,7 @@
     for (line = 0; line < lines; line++) {
         if (src - ssrc > size) {
             av_log(s->avctx, AV_LOG_ERROR, "Source data overread\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
         switch (s->compr) {
         case TIFF_RAW:
@@ -510,7 +557,7 @@
                     if (pixels + code > width) {
                         av_log(s->avctx, AV_LOG_ERROR,
                                "Copy went out of bounds\n");
-                        return -1;
+                        return AVERROR_INVALIDDATA;
                     }
                     if (ssrc + size - src < code) {
                         av_log(s->avctx, AV_LOG_ERROR, "Read went out of bounds\n");
@@ -525,7 +572,7 @@
                     if (pixels + code > width) {
                         av_log(s->avctx, AV_LOG_ERROR,
                                "Run went out of bounds\n");
-                        return -1;
+                        return AVERROR_INVALIDDATA;
                     }
                     c = *src++;
                     horizontal_fill(s->bpp * (s->avctx->pix_fmt == AV_PIX_FMT_PAL8),
@@ -539,7 +586,7 @@
             if (pixels < width) {
                 av_log(s->avctx, AV_LOG_ERROR, "Decoded only %i bytes of %i\n",
                        pixels, width);
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
             if (s->bpp < 8 && s->avctx->pix_fmt == AV_PIX_FMT_PAL8)
                 horizontal_fill(s->bpp, dst, 1, dst, 0, width, 0);
@@ -597,7 +644,7 @@
     }
     if (s->picture.data[0])
         s->avctx->release_buffer(s->avctx, &s->picture);
-    if ((ret = s->avctx->get_buffer(s->avctx, &s->picture)) < 0) {
+    if ((ret = ff_get_buffer(s->avctx, &s->picture)) < 0) {
         av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -674,7 +721,7 @@
             av_log(s->avctx, AV_LOG_ERROR,
                    "This format is not supported (bpp=%d, %d components)\n",
                    s->bpp, count);
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
         if (count == 1)
             s->bpp = value;
@@ -688,7 +735,7 @@
             case TIFF_LONG:
                 s->bpp = 0;
                 if (bytestream2_get_bytes_left(&s->gb) < type_sizes[type] * count)
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 for (i = 0; i < count; i++)
                     s->bpp += tget(&s->gb, type, s->le);
                 break;
@@ -703,6 +750,11 @@
                    "Samples per pixel requires a single value, many provided\n");
             return AVERROR_INVALIDDATA;
         }
+        if (value > 4U) {
+            av_log(s->avctx, AV_LOG_ERROR,
+                   "Samples per pixel %d is too large\n", value);
+            return AVERROR_INVALIDDATA;
+        }
         if (s->bppcount == 1)
             s->bpp *= value;
         s->bppcount = value;
@@ -726,26 +778,26 @@
             break;
 #else
             av_log(s->avctx, AV_LOG_ERROR, "Deflate: ZLib not compiled in\n");
-            return -1;
+            return AVERROR(ENOSYS);
 #endif
         case TIFF_JPEG:
         case TIFF_NEWJPEG:
             av_log(s->avctx, AV_LOG_ERROR,
                    "JPEG compression is not supported\n");
-            return -1;
+            return AVERROR_PATCHWELCOME;
         default:
             av_log(s->avctx, AV_LOG_ERROR, "Unknown compression method %i\n",
                    s->compr);
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
         break;
     case TIFF_ROWSPERSTRIP:
         if (type == TIFF_LONG && value == UINT_MAX)
-            value = s->avctx->height;
+            value = s->height;
         if (value < 1) {
             av_log(s->avctx, AV_LOG_ERROR,
                    "Incorrect value of rows per strip\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
         s->rps = value;
         break;
@@ -762,7 +814,7 @@
         if (s->strippos > bytestream2_size(&s->gb)) {
             av_log(s->avctx, AV_LOG_ERROR,
                    "Tag referencing position outside the image\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
         break;
     case TIFF_STRIP_SIZE:
@@ -778,7 +830,7 @@
         if (s->stripsizesoff > bytestream2_size(&s->gb)) {
             av_log(s->avctx, AV_LOG_ERROR,
                    "Tag referencing position outside the image\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
         break;
     case TIFF_TILE_BYTE_COUNTS:
@@ -805,7 +857,7 @@
         default:
             av_log(s->avctx, AV_LOG_ERROR, "Color mode %d is not supported\n",
                    value);
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
         break;
     case TIFF_FILL_ORDER:
@@ -820,7 +872,7 @@
         pal = (uint32_t *) s->palette;
         off = type_sizes[type];
         if (count / 3 > 256 || bytestream2_get_bytes_left(&s->gb) < count / 3 * off * 3)
-            return -1;
+            return AVERROR_INVALIDDATA;
         off = (type_sizes[type] - 1) << 3;
         for (k = 2; k >= 0; k--) {
             for (i = 0; i < count / 3; i++) {
@@ -835,7 +887,7 @@
     case TIFF_PLANAR:
         if (value == 2) {
             av_log(s->avctx, AV_LOG_ERROR, "Planar format is not supported\n");
-            return -1;
+            return AVERROR_PATCHWELCOME;
         }
         break;
     case TIFF_T4OPTIONS:
@@ -847,7 +899,7 @@
             s->fax_opts = value;
         break;
 #define ADD_METADATA(count, name, sep)\
-    if (ret = add_metadata(count, type, name, sep, s) < 0) {\
+    if ((ret = add_metadata(count, type, name, sep, s)) < 0) {\
         av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n");\
         return ret;\
     }
@@ -868,11 +920,14 @@
             s->geotag_count = count / 4 - 1;
             av_log(s->avctx, AV_LOG_WARNING, "GeoTIFF key directory buffer shorter than specified\n");
         }
-        if (bytestream2_get_bytes_left(&s->gb) < s->geotag_count * sizeof(int16_t) * 4)
+        if (bytestream2_get_bytes_left(&s->gb) < s->geotag_count * sizeof(int16_t) * 4) {
+            s->geotag_count = 0;
             return -1;
+        }
         s->geotags = av_mallocz(sizeof(TiffGeoTag) * s->geotag_count);
         if (!s->geotags) {
             av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n");
+            s->geotag_count = 0;
             return AVERROR(ENOMEM);
         }
         for (i = 0; i < s->geotag_count; i++) {
@@ -928,7 +983,7 @@
 
                     bytestream2_seek(&s->gb, pos + s->geotags[i].offset, SEEK_SET);
                     if (bytestream2_get_bytes_left(&s->gb) < s->geotags[i].count)
-                        return -1;
+                        return AVERROR_INVALIDDATA;
                     ap = av_malloc(s->geotags[i].count);
                     if (!ap) {
                         av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n");
@@ -983,7 +1038,7 @@
 }
 
 static int decode_frame(AVCodecContext *avctx,
-                        void *data, int *data_size, AVPacket *avpkt)
+                        void *data, int *got_frame, AVPacket *avpkt)
 {
     TiffContext *const s = avctx->priv_data;
     AVFrame *picture = data;
@@ -1009,7 +1064,7 @@
         le = 0;
     else {
         av_log(avctx, AV_LOG_ERROR, "TIFF header not found\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     s->le = le;
     // TIFF_BPP is not a required tag and defaults to 1
@@ -1027,7 +1082,7 @@
     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 -1;
+        return AVERROR_INVALIDDATA;
     }
     // Reset these offsets so we can tell if they were set this frame
     s->stripsizesoff = s->strippos = 0;
@@ -1042,8 +1097,8 @@
     if (bytestream2_get_bytes_left(&s->gb) < entries * 12)
         return AVERROR_INVALIDDATA;
     for (i = 0; i < entries; i++) {
-        if (tiff_decode_tag(s) < 0)
-            return -1;
+        if ((ret = tiff_decode_tag(s)) < 0)
+            return ret;
     }
 
     for (i = 0; i<s->geotag_count; i++) {
@@ -1065,7 +1120,7 @@
 
     if (!s->strippos && !s->stripoff) {
         av_log(avctx, AV_LOG_ERROR, "Image data is missing\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     /* now we have the data and may start decoding */
     if ((ret = init_image(s)) < 0)
@@ -1107,7 +1162,7 @@
 
         if (soff > avpkt->size || ssize > avpkt->size - soff) {
             av_log(avctx, AV_LOG_ERROR, "Invalid strip size/offset\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
         if (tiff_unpack_strip(s, dst, stride, avpkt->data + soff, ssize,
                               FFMIN(s->rps, s->height - i)) < 0)
@@ -1150,7 +1205,7 @@
         }
     }
     *picture   = s->picture;
-    *data_size = sizeof(AVPicture);
+    *got_frame = 1;
 
     return avpkt->size;
 }
@@ -1177,6 +1232,7 @@
     free_geotags(s);
 
     ff_lzw_decode_close(&s->lzw);
+    av_freep(&s->deinvert_buf);
     if (s->picture.data[0])
         avctx->release_buffer(avctx, &s->picture);
     return 0;
diff --git a/libavcodec/tmv.c b/libavcodec/tmv.c
index a0b3f36..f8d7969 100644
--- a/libavcodec/tmv.c
+++ b/libavcodec/tmv.c
@@ -29,6 +29,7 @@
 #include <string.h>
 
 #include "avcodec.h"
+#include "internal.h"
 #include "libavutil/internal.h"
 #include "libavutil/xga_font_data.h"
 
@@ -39,7 +40,7 @@
 } TMVContext;
 
 static int tmv_decode_frame(AVCodecContext *avctx, void *data,
-                            int *data_size, AVPacket *avpkt)
+                            int *got_frame, AVPacket *avpkt)
 {
     TMVContext *tmv    = avctx->priv_data;
     const uint8_t *src = avpkt->data;
@@ -47,20 +48,21 @@
     unsigned char_cols = avctx->width >> 3;
     unsigned char_rows = avctx->height >> 3;
     unsigned x, y, fg, bg, c;
+    int ret;
 
     if (tmv->pic.data[0])
         avctx->release_buffer(avctx, &tmv->pic);
 
-    if (avctx->get_buffer(avctx, &tmv->pic) < 0) {
+    if ((ret = ff_get_buffer(avctx, &tmv->pic)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     if (avpkt->size < 2*char_rows*char_cols) {
         av_log(avctx, AV_LOG_ERROR,
                "Input buffer too small, truncated sample?\n");
-        *data_size = 0;
-        return -1;
+        *got_frame = 0;
+        return AVERROR_INVALIDDATA;
     }
 
     tmv->pic.pict_type = AV_PICTURE_TYPE_I;
@@ -69,6 +71,7 @@
 
     tmv->pic.palette_has_changed = 1;
     memcpy(tmv->pic.data[1], ff_cga_palette, 16 * 4);
+    memset(tmv->pic.data[1] + 16 * 4, 0, AVPALETTE_SIZE - 16 * 4);
 
     for (y = 0; y < char_rows; y++) {
         for (x = 0; x < char_cols; x++) {
@@ -81,7 +84,7 @@
         dst += tmv->pic.linesize[0] * 8;
     }
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame *)data = tmv->pic;
     return avpkt->size;
 }
diff --git a/libavcodec/truemotion1.c b/libavcodec/truemotion1.c
index b46366b..ed6b5d9 100644
--- a/libavcodec/truemotion1.c
+++ b/libavcodec/truemotion1.c
@@ -34,9 +34,9 @@
 #include <string.h>
 
 #include "avcodec.h"
-#include "dsputil.h"
 #include "libavutil/imgutils.h"
 #include "libavutil/internal.h"
+#include "libavutil/intreadwrite.h"
 #include "libavutil/mem.h"
 
 #include "truemotion1data.h"
@@ -308,7 +308,7 @@
  * there was an error while decoding the header */
 static int truemotion1_decode_header(TrueMotion1Context *s)
 {
-    int i;
+    int i, ret;
     int width_shift = 0;
     int new_pix_fmt;
     struct frame_header header;
@@ -319,7 +319,7 @@
     if (s->buf[0] < 0x10 || header.header_size >= s->size)
     {
         av_log(s->avctx, AV_LOG_ERROR, "invalid header size (%d)\n", s->buf[0]);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     /* unscramble the header bytes with a XOR operation */
@@ -343,7 +343,7 @@
         if (header.header_type > 3)
         {
             av_log(s->avctx, AV_LOG_ERROR, "invalid header type (%d)\n", header.header_type);
-            return -1;
+            return AVERROR_INVALIDDATA;
         } else if ((header.header_type == 2) || (header.header_type == 3)) {
             s->flags = header.flags;
             if (!(s->flags & FLAG_INTERFRAME))
@@ -356,7 +356,7 @@
     if (s->flags & FLAG_SPRITE) {
         av_log_ask_for_sample(s->avctx, "SPRITE frame found.\n");
         /* FIXME header.width, height, xoffset and yoffset aren't initialized */
-        return -1;
+        return AVERROR_PATCHWELCOME;
     } else {
         s->w = header.xsize;
         s->h = header.ysize;
@@ -371,7 +371,7 @@
 
     if (header.compression >= 17) {
         av_log(s->avctx, AV_LOG_ERROR, "invalid compression type (%d)\n", header.compression);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     if ((header.deltaset != s->last_deltaset) ||
@@ -385,7 +385,7 @@
             sel_vector_table = tables[header.vectable - 1];
         else {
             av_log(s->avctx, AV_LOG_ERROR, "invalid vector table id (%d)\n", header.vectable);
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
     }
 
@@ -396,8 +396,8 @@
         new_pix_fmt = AV_PIX_FMT_RGB555; // RGB565 is supported as well
 
     s->w >>= width_shift;
-    if (av_image_check_size(s->w, s->h, 0, s->avctx) < 0)
-        return -1;
+    if ((ret = av_image_check_size(s->w, s->h, 0, s->avctx)) < 0)
+        return ret;
 
     if (s->w != s->avctx->width || s->h != s->avctx->height ||
         new_pix_fmt != s->avctx->pix_fmt) {
@@ -856,25 +856,25 @@
 
 
 static int truemotion1_decode_frame(AVCodecContext *avctx,
-                                    void *data, int *data_size,
+                                    void *data, int *got_frame,
                                     AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
+    int ret, buf_size = avpkt->size;
     TrueMotion1Context *s = avctx->priv_data;
 
     s->buf = buf;
     s->size = buf_size;
 
-    if (truemotion1_decode_header(s) == -1)
-        return -1;
+    if ((ret = truemotion1_decode_header(s)) < 0)
+        return ret;
 
     s->frame.reference = 3;
     s->frame.buffer_hints = FF_BUFFER_HINTS_VALID |
         FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if (avctx->reget_buffer(avctx, &s->frame) < 0) {
+    if ((ret = avctx->reget_buffer(avctx, &s->frame)) < 0) {
         av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     if (compression_types[s->compression].algorithm == ALGO_RGB24H) {
@@ -883,7 +883,7 @@
         truemotion1_decode_16bit(s);
     }
 
-    *data_size = sizeof(AVFrame);
+    *got_frame      = 1;
     *(AVFrame*)data = s->frame;
 
     /* report that the buffer was completely consumed */
diff --git a/libavcodec/truemotion2.c b/libavcodec/truemotion2.c
index f1e24b7..eacd728 100644
--- a/libavcodec/truemotion2.c
+++ b/libavcodec/truemotion2.c
@@ -31,14 +31,31 @@
 
 #define TM2_ESCAPE 0x80000000
 #define TM2_DELTAS 64
-/* Huffman-coded streams of different types of blocks */
-enum TM2_STREAMS{ TM2_C_HI = 0, TM2_C_LO, TM2_L_HI, TM2_L_LO,
-     TM2_UPD, TM2_MOT, TM2_TYPE, TM2_NUM_STREAMS};
-/* Block types */
-enum TM2_BLOCKS{ TM2_HI_RES = 0, TM2_MED_RES, TM2_LOW_RES, TM2_NULL_RES,
-                 TM2_UPDATE, TM2_STILL, TM2_MOTION};
 
-typedef struct TM2Context{
+/* Huffman-coded streams of different types of blocks */
+enum TM2_STREAMS {
+    TM2_C_HI = 0,
+    TM2_C_LO,
+    TM2_L_HI,
+    TM2_L_LO,
+    TM2_UPD,
+    TM2_MOT,
+    TM2_TYPE,
+    TM2_NUM_STREAMS
+};
+
+/* Block types */
+enum TM2_BLOCKS {
+    TM2_HI_RES = 0,
+    TM2_MED_RES,
+    TM2_LOW_RES,
+    TM2_NULL_RES,
+    TM2_UPDATE,
+    TM2_STILL,
+    TM2_MOTION
+};
+
+typedef struct TM2Context {
     AVCodecContext *avctx;
     AVFrame pic;
 
@@ -69,7 +86,7 @@
 /**
 * Huffman codes for each of streams
 */
-typedef struct TM2Codes{
+typedef struct TM2Codes {
     VLC vlc; ///< table for FFmpeg bitstream reader
     int bits;
     int *recode; ///< table for converting from code indexes to values
@@ -79,7 +96,7 @@
 /**
 * structure for gathering Huffman codes information
 */
-typedef struct TM2Huff{
+typedef struct TM2Huff {
     int val_bits; ///< length of literal
     int max_bits; ///< maximum length of code
     int min_bits; ///< minimum length of code
@@ -93,18 +110,20 @@
 
 static int tm2_read_tree(TM2Context *ctx, uint32_t prefix, int length, TM2Huff *huff)
 {
-    if(length > huff->max_bits) {
-        av_log(ctx->avctx, AV_LOG_ERROR, "Tree exceeded its given depth (%i)\n", huff->max_bits);
-        return -1;
+    int ret;
+    if (length > huff->max_bits) {
+        av_log(ctx->avctx, AV_LOG_ERROR, "Tree exceeded its given depth (%i)\n",
+               huff->max_bits);
+        return AVERROR_INVALIDDATA;
     }
 
-    if(!get_bits1(&ctx->gb)) { /* literal */
+    if (!get_bits1(&ctx->gb)) { /* literal */
         if (length == 0) {
             length = 1;
         }
-        if(huff->num >= huff->max_num) {
+        if (huff->num >= huff->max_num) {
             av_log(ctx->avctx, AV_LOG_DEBUG, "Too many literals\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
         huff->nums[huff->num] = get_bits_long(&ctx->gb, huff->val_bits);
         huff->bits[huff->num] = prefix;
@@ -112,10 +131,10 @@
         huff->num++;
         return 0;
     } else { /* non-terminal node */
-        if(tm2_read_tree(ctx, prefix << 1, length + 1, huff) == -1)
-            return -1;
-        if(tm2_read_tree(ctx, (prefix << 1) | 1, length + 1, huff) == -1)
-            return -1;
+        if ((ret = tm2_read_tree(ctx, prefix << 1, length + 1, huff)) < 0)
+            return ret;
+        if ((ret = tm2_read_tree(ctx, (prefix << 1) | 1, length + 1, huff)) < 0)
+            return ret;
     }
     return 0;
 }
@@ -128,56 +147,53 @@
     huff.val_bits = get_bits(&ctx->gb, 5);
     huff.max_bits = get_bits(&ctx->gb, 5);
     huff.min_bits = get_bits(&ctx->gb, 5);
-    huff.nodes = get_bits_long(&ctx->gb, 17);
-    huff.num = 0;
+    huff.nodes    = get_bits_long(&ctx->gb, 17);
+    huff.num      = 0;
 
     /* check for correct codes parameters */
-    if((huff.val_bits < 1) || (huff.val_bits > 32) ||
-       (huff.max_bits < 0) || (huff.max_bits > 25)) {
-        av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect tree parameters - literal length: %i, max code length: %i\n",
-               huff.val_bits, huff.max_bits);
-        return -1;
+    if ((huff.val_bits < 1) || (huff.val_bits > 32) ||
+        (huff.max_bits < 0) || (huff.max_bits > 25)) {
+        av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect tree parameters - literal "
+               "length: %i, max code length: %i\n", huff.val_bits, huff.max_bits);
+        return AVERROR_INVALIDDATA;
     }
-    if((huff.nodes <= 0) || (huff.nodes > 0x10000)) {
-        av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect number of Huffman tree nodes: %i\n", huff.nodes);
-        return -1;
+    if ((huff.nodes <= 0) || (huff.nodes > 0x10000)) {
+        av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect number of Huffman tree "
+               "nodes: %i\n", huff.nodes);
+        return AVERROR_INVALIDDATA;
     }
     /* one-node tree */
-    if(huff.max_bits == 0)
+    if (huff.max_bits == 0)
         huff.max_bits = 1;
 
     /* allocate space for codes - it is exactly ceil(nodes / 2) entries */
     huff.max_num = (huff.nodes + 1) >> 1;
-    huff.nums = av_mallocz(huff.max_num * sizeof(int));
-    huff.bits = av_mallocz(huff.max_num * sizeof(uint32_t));
-    huff.lens = av_mallocz(huff.max_num * sizeof(int));
+    huff.nums    = av_mallocz(huff.max_num * sizeof(int));
+    huff.bits    = av_mallocz(huff.max_num * sizeof(uint32_t));
+    huff.lens    = av_mallocz(huff.max_num * sizeof(int));
 
-    if(tm2_read_tree(ctx, 0, 0, &huff) == -1)
-        res = -1;
+    res = tm2_read_tree(ctx, 0, 0, &huff);
 
-    if(huff.num != huff.max_num) {
+    if (huff.num != huff.max_num) {
         av_log(ctx->avctx, AV_LOG_ERROR, "Got less codes than expected: %i of %i\n",
                huff.num, huff.max_num);
-        res = -1;
+        res = AVERROR_INVALIDDATA;
     }
 
     /* convert codes to vlc_table */
-    if(res != -1) {
+    if (res >= 0) {
         int i;
 
         res = init_vlc(&code->vlc, huff.max_bits, huff.max_num,
-                    huff.lens, sizeof(int), sizeof(int),
-                    huff.bits, sizeof(uint32_t), sizeof(uint32_t), 0);
-        if(res < 0) {
+                       huff.lens, sizeof(int), sizeof(int),
+                       huff.bits, sizeof(uint32_t), sizeof(uint32_t), 0);
+        if (res < 0)
             av_log(ctx->avctx, AV_LOG_ERROR, "Cannot build VLC table\n");
-            res = -1;
-        } else
-            res = 0;
-        if(res != -1) {
+        else {
             code->bits = huff.max_bits;
             code->length = huff.max_num;
             code->recode = av_malloc(code->length * sizeof(int));
-            for(i = 0; i < code->length; i++)
+            for (i = 0; i < code->length; i++)
                 code->recode[i] = huff.nums[i];
         }
     }
@@ -192,7 +208,7 @@
 static void tm2_free_codes(TM2Codes *code)
 {
     av_free(code->recode);
-    if(code->vlc.table)
+    if (code->vlc.table)
         ff_free_vlc(&code->vlc);
 }
 
@@ -205,44 +221,46 @@
     return code->recode[val];
 }
 
+#define TM2_OLD_HEADER_MAGIC 0x00000100
+#define TM2_NEW_HEADER_MAGIC 0x00000101
+
 static inline int tm2_read_header(TM2Context *ctx, const uint8_t *buf)
 {
-    uint32_t magic;
+    uint32_t magic = AV_RL32(buf);
 
-    magic = AV_RL32(buf);
-    buf += 4;
-
-    if(magic == 0x00000100) { /* old header */
+    switch (magic) {
+    case TM2_OLD_HEADER_MAGIC:
         av_log_missing_feature(ctx->avctx, "TM2 old header", 1);
-        return 40;
-    } else if(magic == 0x00000101) { /* new header */
-        return 40;
-    } else {
-        av_log (ctx->avctx, AV_LOG_ERROR, "Not a TM2 header: 0x%08X\n", magic);
-        return -1;
+        return 0;
+    case TM2_NEW_HEADER_MAGIC:
+        return 0;
+    default:
+        av_log(ctx->avctx, AV_LOG_ERROR, "Not a TM2 header: 0x%08X\n", magic);
+        return AVERROR_INVALIDDATA;
     }
 }
 
-static int tm2_read_deltas(TM2Context *ctx, int stream_id) {
+static int tm2_read_deltas(TM2Context *ctx, int stream_id)
+{
     int d, mb;
     int i, v;
 
-    d = get_bits(&ctx->gb, 9);
+    d  = get_bits(&ctx->gb, 9);
     mb = get_bits(&ctx->gb, 5);
 
-    if((d < 1) || (d > TM2_DELTAS) || (mb < 1) || (mb > 32)) {
+    if ((d < 1) || (d > TM2_DELTAS) || (mb < 1) || (mb > 32)) {
         av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect delta table: %i deltas x %i bits\n", d, mb);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
-    for(i = 0; i < d; i++) {
+    for (i = 0; i < d; i++) {
         v = get_bits_long(&ctx->gb, mb);
-        if(v & (1 << (mb - 1)))
+        if (v & (1 << (mb - 1)))
             ctx->deltas[stream_id][i] = v - (1 << mb);
         else
             ctx->deltas[stream_id][i] = v;
     }
-    for(; i < TM2_DELTAS; i++)
+    for (; i < TM2_DELTAS; i++)
         ctx->deltas[stream_id][i] = 0;
 
     return 0;
@@ -250,7 +268,7 @@
 
 static int tm2_read_stream(TM2Context *ctx, const uint8_t *buf, int stream_id, int buf_size)
 {
-    int i;
+    int i, ret;
     int skip = 0;
     int len, toks, pos;
     TM2Codes codes;
@@ -266,7 +284,7 @@
     len  = bytestream2_get_be32(&gb);
     skip = len * 4 + 4;
 
-    if(len == 0)
+    if (len == 0)
         return 4;
 
     if (len >= INT_MAX/4-1 || len < 0 || skip > buf_size) {
@@ -275,24 +293,24 @@
     }
 
     toks = bytestream2_get_be32(&gb);
-    if(toks & 1) {
+    if (toks & 1) {
         len = bytestream2_get_be32(&gb);
-        if(len == TM2_ESCAPE) {
+        if (len == TM2_ESCAPE) {
             len = bytestream2_get_be32(&gb);
         }
-        if(len > 0) {
+        if (len > 0) {
             pos = bytestream2_tell(&gb);
             if (skip <= pos)
                 return AVERROR_INVALIDDATA;
             init_get_bits(&ctx->gb, buf + pos, (skip - pos) * 8);
-            if(tm2_read_deltas(ctx, stream_id) == -1)
-                return AVERROR_INVALIDDATA;
+            if ((ret = tm2_read_deltas(ctx, stream_id)) < 0)
+                return ret;
             bytestream2_skip(&gb, ((get_bits_count(&ctx->gb) + 31) >> 5) << 2);
         }
     }
     /* skip unused fields */
     len = bytestream2_get_be32(&gb);
-    if(len == TM2_ESCAPE) { /* some unknown length - could be escaped too */
+    if (len == TM2_ESCAPE) { /* some unknown length - could be escaped too */
         bytestream2_skip(&gb, 8); /* unused by decoder */
     } else {
         bytestream2_skip(&gb, 4); /* unused by decoder */
@@ -302,26 +320,26 @@
     if (skip <= pos)
         return AVERROR_INVALIDDATA;
     init_get_bits(&ctx->gb, buf + pos, (skip - pos) * 8);
-    if(tm2_build_huff_table(ctx, &codes) == -1)
-        return AVERROR_INVALIDDATA;
+    if ((ret = tm2_build_huff_table(ctx, &codes)) < 0)
+        return ret;
     bytestream2_skip(&gb, ((get_bits_count(&ctx->gb) + 31) >> 5) << 2);
 
     toks >>= 1;
     /* check if we have sane number of tokens */
-    if((toks < 0) || (toks > 0xFFFFFF)){
+    if ((toks < 0) || (toks > 0xFFFFFF)) {
         av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect number of tokens: %i\n", toks);
         tm2_free_codes(&codes);
         return AVERROR_INVALIDDATA;
     }
-    ctx->tokens[stream_id] = av_realloc(ctx->tokens[stream_id], toks * sizeof(int));
+    ctx->tokens[stream_id]   = av_realloc(ctx->tokens[stream_id], toks * sizeof(int));
     ctx->tok_lens[stream_id] = toks;
     len = bytestream2_get_be32(&gb);
-    if(len > 0) {
+    if (len > 0) {
         pos = bytestream2_tell(&gb);
         if (skip <= pos)
             return AVERROR_INVALIDDATA;
         init_get_bits(&ctx->gb, buf + pos, (skip - pos) * 8);
-        for(i = 0; i < toks; i++) {
+        for (i = 0; i < toks; i++) {
             if (get_bits_left(&ctx->gb) <= 0) {
                 av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect number of tokens: %i\n", toks);
                 return AVERROR_INVALIDDATA;
@@ -334,7 +352,7 @@
             }
         }
     } else {
-        for(i = 0; i < toks; i++) {
+        for (i = 0; i < toks; i++) {
             ctx->tokens[stream_id][i] = codes.recode[0];
             if (stream_id <= TM2_MOT && ctx->tokens[stream_id][i] >= TM2_DELTAS) {
                 av_log(ctx->avctx, AV_LOG_ERROR, "Invalid delta token index %d for type %d, n=%d\n",
@@ -348,12 +366,13 @@
     return skip;
 }
 
-static inline int GET_TOK(TM2Context *ctx,int type) {
-    if(ctx->tok_ptrs[type] >= ctx->tok_lens[type]) {
+static inline int GET_TOK(TM2Context *ctx,int type)
+{
+    if (ctx->tok_ptrs[type] >= ctx->tok_lens[type]) {
         av_log(ctx->avctx, AV_LOG_ERROR, "Read token from stream %i out of bounds (%i>=%i)\n", type, ctx->tok_ptrs[type], ctx->tok_lens[type]);
         return 0;
     }
-    if(type <= TM2_MOT) {
+    if (type <= TM2_MOT) {
         if (ctx->tokens[type][ctx->tok_ptrs[type]] >= TM2_DELTAS) {
             av_log(ctx->avctx, AV_LOG_ERROR, "token %d is too large\n", ctx->tokens[type][ctx->tok_ptrs[type]]);
             return 0;
@@ -405,15 +424,15 @@
     int ct, d;
     int i, j;
 
-    for(j = 0; j < 4; j++){
+    for (j = 0; j < 4; j++){
         ct = ctx->D[j];
-        for(i = 0; i < 4; i++){
-            d = deltas[i + j * 4];
-            ct += d;
+        for (i = 0; i < 4; i++){
+            d        = deltas[i + j * 4];
+            ct      += d;
             last[i] += ct;
-            Y[i] = av_clip_uint8(last[i]);
+            Y[i]     = av_clip_uint8(last[i]);
         }
-        Y += stride;
+        Y        += stride;
         ctx->D[j] = ct;
     }
 }
@@ -421,11 +440,11 @@
 static inline void tm2_high_chroma(int *data, int stride, int *last, int *CD, int *deltas)
 {
     int i, j;
-    for(j = 0; j < 2; j++){
-        for(i = 0; i < 2; i++){
-            CD[j] += deltas[i + j * 2];
+    for (j = 0; j < 2; j++) {
+        for (i = 0; i < 2; i++)  {
+            CD[j]   += deltas[i + j * 2];
             last[i] += CD[j];
-            data[i] = last[i];
+            data[i]  = last[i];
         }
         data += stride;
     }
@@ -437,14 +456,14 @@
     int l;
     int prev;
 
-    if(bx > 0)
+    if (bx > 0)
         prev = clast[-3];
     else
         prev = 0;
-    t = (CD[0] + CD[1]) >> 1;
-    l = (prev - CD[0] - CD[1] + clast[1]) >> 1;
-    CD[1] = CD[0] + CD[1] - t;
-    CD[0] = t;
+    t        = (CD[0] + CD[1]) >> 1;
+    l        = (prev - CD[0] - CD[1] + clast[1]) >> 1;
+    CD[1]    = CD[0] + CD[1] - t;
+    CD[0]    = t;
     clast[0] = l;
 
     tm2_high_chroma(data, stride, clast, CD, deltas);
@@ -457,15 +476,15 @@
     TM2_INIT_POINTERS();
 
     /* hi-res chroma */
-    for(i = 0; i < 4; i++) {
-        deltas[i] = GET_TOK(ctx, TM2_C_HI);
+    for (i = 0; i < 4; i++) {
+        deltas[i]     = GET_TOK(ctx, TM2_C_HI);
         deltas[i + 4] = GET_TOK(ctx, TM2_C_HI);
     }
-    tm2_high_chroma(U, Ustride, clast, ctx->CD, deltas);
+    tm2_high_chroma(U, Ustride, clast,     ctx->CD,     deltas);
     tm2_high_chroma(V, Vstride, clast + 2, ctx->CD + 2, deltas + 4);
 
     /* hi-res luma */
-    for(i = 0; i < 16; i++)
+    for (i = 0; i < 16; i++)
         deltas[i] = GET_TOK(ctx, TM2_L_HI);
 
     tm2_apply_deltas(ctx, Y, Ystride, deltas, last);
@@ -487,7 +506,7 @@
     tm2_low_chroma(V, Vstride, clast + 2, ctx->CD + 2, deltas, bx);
 
     /* hi-res luma */
-    for(i = 0; i < 16; i++)
+    for (i = 0; i < 16; i++)
         deltas[i] = GET_TOK(ctx, TM2_L_HI);
 
     tm2_apply_deltas(ctx, Y, Ystride, deltas, last);
@@ -510,7 +529,7 @@
     tm2_low_chroma(V, Vstride, clast + 2, ctx->CD + 2, deltas, bx);
 
     /* low-res luma */
-    for(i = 0; i < 16; i++)
+    for (i = 0; i < 16; i++)
         deltas[i] = 0;
 
     deltas[ 0] = GET_TOK(ctx, TM2_L_LO);
@@ -518,7 +537,7 @@
     deltas[ 8] = GET_TOK(ctx, TM2_L_LO);
     deltas[10] = GET_TOK(ctx, TM2_L_LO);
 
-    if(bx > 0)
+    if (bx > 0)
         last[0] = (last[-1] - ctx->D[0] - ctx->D[1] - ctx->D[2] - ctx->D[3] + last[1]) >> 1;
     else
         last[0] = (last[1]  - ctx->D[0] - ctx->D[1] - ctx->D[2] - ctx->D[3])>> 1;
@@ -550,18 +569,18 @@
     tm2_low_chroma(V, Vstride, clast + 2, ctx->CD + 2, deltas, bx);
 
     /* null luma */
-    for(i = 0; i < 16; i++)
+    for (i = 0; i < 16; i++)
         deltas[i] = 0;
 
     ct = ctx->D[0] + ctx->D[1] + ctx->D[2] + ctx->D[3];
 
-    if(bx > 0)
+    if (bx > 0)
         left = last[-1] - ct;
     else
         left = 0;
 
-    right = last[3];
-    diff = right - left;
+    right   = last[3];
+    diff    = right - left;
     last[0] = left + (diff >> 2);
     last[1] = left + (diff >> 1);
     last[2] = right - (diff >> 2);
@@ -570,11 +589,11 @@
         int tp = left;
 
         ctx->D[0] = (tp + (ct >> 2)) - left;
-        left += ctx->D[0];
+        left     += ctx->D[0];
         ctx->D[1] = (tp + (ct >> 1)) - left;
-        left += ctx->D[1];
+        left     += ctx->D[1];
         ctx->D[2] = ((tp + ct) - (ct >> 2)) - left;
-        left += ctx->D[2];
+        left     += ctx->D[2];
         ctx->D[3] = (tp + ct) - left;
     }
     tm2_apply_deltas(ctx, Y, Ystride, deltas, last);
@@ -586,12 +605,12 @@
     TM2_INIT_POINTERS_2();
 
     /* update chroma */
-    for(j = 0; j < 2; j++){
-        for(i = 0; i < 2; i++){
+    for (j = 0; j < 2; j++) {
+        for (i = 0; i < 2; i++){
             U[i] = Uo[i];
             V[i] = Vo[i];
         }
-        U += Ustride; V += Vstride;
+        U  += Ustride; V += Vstride;
         Uo += oUstride; Vo += oVstride;
     }
     U -= Ustride * 2;
@@ -605,12 +624,12 @@
     ctx->D[2] = Yo[3 + oYstride * 2] - Yo[3 + oYstride];
     ctx->D[3] = Yo[3 + oYstride * 3] - Yo[3 + oYstride * 2];
 
-    for(j = 0; j < 4; j++){
-        for(i = 0; i < 4; i++){
-            Y[i] = Yo[i];
+    for (j = 0; j < 4; j++) {
+        for (i = 0; i < 4; i++) {
+            Y[i]    = Yo[i];
             last[i] = Yo[i];
         }
-        Y += Ystride;
+        Y  += Ystride;
         Yo += oYstride;
     }
 }
@@ -622,13 +641,15 @@
     TM2_INIT_POINTERS_2();
 
     /* update chroma */
-    for(j = 0; j < 2; j++){
-        for(i = 0; i < 2; i++){
+    for (j = 0; j < 2; j++) {
+        for (i = 0; i < 2; i++) {
             U[i] = Uo[i] + GET_TOK(ctx, TM2_UPD);
             V[i] = Vo[i] + GET_TOK(ctx, TM2_UPD);
         }
-        U += Ustride; V += Vstride;
-        Uo += oUstride; Vo += oVstride;
+        U  += Ustride;
+        V  += Vstride;
+        Uo += oUstride;
+        Vo += oVstride;
     }
     U -= Ustride * 2;
     V -= Vstride * 2;
@@ -641,14 +662,14 @@
     ctx->D[2] = Yo[3 + oYstride * 2] - Yo[3 + oYstride];
     ctx->D[3] = Yo[3 + oYstride * 3] - Yo[3 + oYstride * 2];
 
-    for(j = 0; j < 4; j++){
+    for (j = 0; j < 4; j++) {
         d = last[3];
-        for(i = 0; i < 4; i++){
-            Y[i] = Yo[i] + GET_TOK(ctx, TM2_UPD);
+        for (i = 0; i < 4; i++) {
+            Y[i]    = Yo[i] + GET_TOK(ctx, TM2_UPD);
             last[i] = Y[i];
         }
         ctx->D[j] = last[3] - d;
-        Y += Ystride;
+        Y  += Ystride;
         Yo += oYstride;
     }
 }
@@ -674,13 +695,15 @@
     Vo += (my >> 1) * oVstride + (mx >> 1);
 
     /* copy chroma */
-    for(j = 0; j < 2; j++){
-        for(i = 0; i < 2; i++){
+    for (j = 0; j < 2; j++) {
+        for (i = 0; i < 2; i++) {
             U[i] = Uo[i];
             V[i] = Vo[i];
         }
-        U += Ustride; V += Vstride;
-        Uo += oUstride; Vo += oVstride;
+        U  += Ustride;
+        V  += Vstride;
+        Uo += oUstride;
+        Vo += oVstride;
     }
     U -= Ustride * 2;
     V -= Vstride * 2;
@@ -688,11 +711,11 @@
     TM2_RECALC_BLOCK(V, Vstride, (clast + 2), (ctx->CD + 2));
 
     /* copy luma */
-    for(j = 0; j < 4; j++){
-        for(i = 0; i < 4; i++){
+    for (j = 0; j < 4; j++) {
+        for (i = 0; i < 4; i++) {
             Y[i] = Yo[i];
         }
-        Y += Ystride;
+        Y  += Ystride;
         Yo += oYstride;
     }
     /* calculate deltas */
@@ -701,7 +724,7 @@
     ctx->D[1] = Y[3 + Ystride] - Y[3];
     ctx->D[2] = Y[3 + Ystride * 2] - Y[3 + Ystride];
     ctx->D[3] = Y[3 + Ystride * 3] - Y[3 + Ystride * 2];
-    for(i = 0; i < 4; i++)
+    for (i = 0; i < 4; i++)
         last[i] = Y[i + Ystride * 3];
 }
 
@@ -714,21 +737,21 @@
     int *Y, *U, *V;
     uint8_t *dst;
 
-    for(i = 0; i < TM2_NUM_STREAMS; i++)
+    for (i = 0; i < TM2_NUM_STREAMS; i++)
         ctx->tok_ptrs[i] = 0;
 
-    if (ctx->tok_lens[TM2_TYPE]<bw*bh){
+    if (ctx->tok_lens[TM2_TYPE]<bw*bh) {
         av_log(ctx->avctx,AV_LOG_ERROR,"Got %i tokens for %i blocks\n",ctx->tok_lens[TM2_TYPE],bw*bh);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     memset(ctx->last, 0, 4 * bw * sizeof(int));
     memset(ctx->clast, 0, 4 * bw * sizeof(int));
 
-    for(j = 0; j < bh; j++) {
+    for (j = 0; j < bh; j++) {
         memset(ctx->D, 0, 4 * sizeof(int));
         memset(ctx->CD, 0, 4 * sizeof(int));
-        for(i = 0; i < bw; i++) {
+        for (i = 0; i < bw; i++) {
             type = GET_TOK(ctx, TM2_TYPE);
             switch(type) {
             case TM2_HI_RES:
@@ -766,8 +789,8 @@
     U = (ctx->cur?ctx->U2:ctx->U1);
     V = (ctx->cur?ctx->V2:ctx->V1);
     dst = p->data[0];
-    for(j = 0; j < h; j++){
-        for(i = 0; i < w; i++){
+    for (j = 0; j < h; j++) {
+        for (i = 0; i < w; i++) {
             int y = Y[i], u = U[i >> 1], v = V[i >> 1];
             dst[3*i+0] = av_clip_uint8(y + v);
             dst[3*i+1] = av_clip_uint8(y);
@@ -825,71 +848,77 @@
     TM2_C_HI, TM2_C_LO, TM2_L_HI, TM2_L_LO, TM2_UPD, TM2_MOT, TM2_TYPE
 };
 
+#define TM2_HEADER_SIZE 40
+
 static int decode_frame(AVCodecContext *avctx,
-                        void *data, int *data_size,
+                        void *data, int *got_frame,
                         AVPacket *avpkt)
 {
-    const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size & ~3;
     TM2Context * const l = avctx->priv_data;
-    AVFrame * const p = &l->pic;
-    int i, ret, skip, t;
+    const uint8_t *buf   = avpkt->data;
+    int buf_size         = avpkt->size & ~3;
+    AVFrame * const p    = &l->pic;
+    int offset           = TM2_HEADER_SIZE;
+    int i, t, ret;
 
     av_fast_padded_malloc(&l->buffer, &l->buffer_size, buf_size);
-    if(!l->buffer){
+    if (!l->buffer) {
         av_log(avctx, AV_LOG_ERROR, "Cannot allocate temporary buffer\n");
         return AVERROR(ENOMEM);
     }
     p->reference = 3;
     p->buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if((ret = avctx->reget_buffer(avctx, p)) < 0){
+    if ((ret = avctx->reget_buffer(avctx, p)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
 
     l->dsp.bswap_buf((uint32_t*)l->buffer, (const uint32_t*)buf, buf_size >> 2);
-    skip = tm2_read_header(l, l->buffer);
 
-    if(skip == -1){
-        return AVERROR_INVALIDDATA;
+    if ((ret = tm2_read_header(l, l->buffer)) < 0) {
+        return ret;
     }
 
-    for(i = 0; i < TM2_NUM_STREAMS; i++){
-        if (skip >= buf_size) {
+    for (i = 0; i < TM2_NUM_STREAMS; i++) {
+        if (offset >= buf_size) {
             av_log(avctx, AV_LOG_ERROR, "no space for tm2_read_stream\n");
             return AVERROR_INVALIDDATA;
         }
 
-        t = tm2_read_stream(l, l->buffer + skip, tm2_stream_order[i], buf_size - skip);
-        if(t < 0){
+        t = tm2_read_stream(l, l->buffer + offset, tm2_stream_order[i],
+                            buf_size - offset);
+        if (t < 0) {
+            int j = tm2_stream_order[i];
+            memset(l->tokens[j], 0, sizeof(**l->tokens) * l->tok_lens[j]);
             return t;
         }
-        skip += t;
+        offset += t;
     }
     p->key_frame = tm2_decode_blocks(l, p);
-    if(p->key_frame)
+    if (p->key_frame)
         p->pict_type = AV_PICTURE_TYPE_I;
     else
         p->pict_type = AV_PICTURE_TYPE_P;
 
     l->cur = !l->cur;
-    *data_size = sizeof(AVFrame);
+    *got_frame      = 1;
     *(AVFrame*)data = l->pic;
 
     return buf_size;
 }
 
-static av_cold int decode_init(AVCodecContext *avctx){
+static av_cold int decode_init(AVCodecContext *avctx)
+{
     TM2Context * const l = avctx->priv_data;
     int i, w = avctx->width, h = avctx->height;
 
-    if((avctx->width & 3) || (avctx->height & 3)){
+    if ((avctx->width & 3) || (avctx->height & 3)) {
         av_log(avctx, AV_LOG_ERROR, "Width and height must be multiple of 4\n");
-        return AVERROR_INVALIDDATA;
+        return AVERROR(EINVAL);
     }
 
-    l->avctx = avctx;
-    l->pic.data[0]=NULL;
+    l->avctx       = avctx;
+    l->pic.data[0] = NULL;
     avctx->pix_fmt = AV_PIX_FMT_BGR24;
     avcodec_get_frame_defaults(&l->pic);
 
@@ -898,22 +927,22 @@
     l->last  = av_malloc(4 * sizeof(*l->last)  * (w >> 2));
     l->clast = av_malloc(4 * sizeof(*l->clast) * (w >> 2));
 
-    for(i = 0; i < TM2_NUM_STREAMS; i++) {
+    for (i = 0; i < TM2_NUM_STREAMS; i++) {
         l->tokens[i] = NULL;
         l->tok_lens[i] = 0;
     }
 
     w += 8;
     h += 8;
-    l->Y1_base = av_malloc(sizeof(*l->Y1_base) * w * h);
-    l->Y2_base = av_malloc(sizeof(*l->Y2_base) * w * h);
+    l->Y1_base = av_mallocz(sizeof(*l->Y1_base) * w * h);
+    l->Y2_base = av_mallocz(sizeof(*l->Y2_base) * w * h);
     l->y_stride = w;
     w = (w + 1) >> 1;
     h = (h + 1) >> 1;
-    l->U1_base = av_malloc(sizeof(*l->U1_base) * w * h);
-    l->V1_base = av_malloc(sizeof(*l->V1_base) * w * h);
-    l->U2_base = av_malloc(sizeof(*l->U2_base) * w * h);
-    l->V2_base = av_malloc(sizeof(*l->V1_base) * w * h);
+    l->U1_base = av_mallocz(sizeof(*l->U1_base) * w * h);
+    l->V1_base = av_mallocz(sizeof(*l->V1_base) * w * h);
+    l->U2_base = av_mallocz(sizeof(*l->U2_base) * w * h);
+    l->V2_base = av_mallocz(sizeof(*l->V1_base) * w * h);
     l->uv_stride = w;
     l->cur = 0;
     if (!l->Y1_base || !l->Y2_base || !l->U1_base ||
@@ -939,16 +968,17 @@
     return 0;
 }
 
-static av_cold int decode_end(AVCodecContext *avctx){
+static av_cold int decode_end(AVCodecContext *avctx)
+{
     TM2Context * const l = avctx->priv_data;
     AVFrame *pic = &l->pic;
     int i;
 
     av_free(l->last);
     av_free(l->clast);
-    for(i = 0; i < TM2_NUM_STREAMS; i++)
+    for (i = 0; i < TM2_NUM_STREAMS; i++)
         av_free(l->tokens[i]);
-    if(l->Y1){
+    if (l->Y1) {
         av_free(l->Y1_base);
         av_free(l->U1_base);
         av_free(l->V1_base);
diff --git a/libavcodec/truespeech.c b/libavcodec/truespeech.c
index d523bdd..fea9ae4 100644
--- a/libavcodec/truespeech.c
+++ b/libavcodec/truespeech.c
@@ -24,6 +24,7 @@
 #include "avcodec.h"
 #include "dsputil.h"
 #include "get_bits.h"
+#include "internal.h"
 
 #include "truespeech_data.h"
 /**
@@ -35,7 +36,6 @@
  * TrueSpeech decoder context
  */
 typedef struct {
-    AVFrame frame;
     DSPContext dsp;
     /* input data */
     DECLARE_ALIGNED(16, uint8_t, buffer)[32];
@@ -64,7 +64,7 @@
 
     if (avctx->channels != 1) {
         av_log_ask_for_sample(avctx, "Unsupported channel count: %d\n", avctx->channels);
-        return AVERROR(EINVAL);
+        return AVERROR_PATCHWELCOME;
     }
 
     avctx->channel_layout = AV_CH_LAYOUT_MONO;
@@ -72,9 +72,6 @@
 
     ff_dsputil_init(&c->dsp, avctx);
 
-    avcodec_get_frame_defaults(&c->frame);
-    avctx->coded_frame = &c->frame;
-
     return 0;
 }
 
@@ -309,6 +306,7 @@
 static int truespeech_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;
     TSContext *c = avctx->priv_data;
@@ -326,12 +324,12 @@
     }
 
     /* get output buffer */
-    c->frame.nb_samples = iterations * 240;
-    if ((ret = avctx->get_buffer(avctx, &c->frame)) < 0) {
+    frame->nb_samples = iterations * 240;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    samples = (int16_t *)c->frame.data[0];
+    samples = (int16_t *)frame->data[0];
 
     memset(samples, 0, iterations * 240 * sizeof(*samples));
 
@@ -353,8 +351,7 @@
         truespeech_save_prevvec(c);
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = c->frame;
+    *got_frame_ptr = 1;
 
     return buf_size;
 }
diff --git a/libavcodec/tscc.c b/libavcodec/tscc.c
index 1ba3bb9..7c2d231 100644
--- a/libavcodec/tscc.c
+++ b/libavcodec/tscc.c
@@ -39,14 +39,11 @@
 #include <stdlib.h>
 
 #include "avcodec.h"
+#include "internal.h"
 #include "msrledec.h"
 
 #include <zlib.h>
 
-
-/*
- * Decoder context
- */
 typedef struct TsccContext {
 
     AVCodecContext *avctx;
@@ -65,12 +62,8 @@
     uint32_t pal[256];
 } CamtasiaContext;
 
-/*
- *
- * Decode a frame
- *
- */
-static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt)
+static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
+                        AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
@@ -81,7 +74,7 @@
 
     c->pic.reference = 3;
     c->pic.buffer_hints = FF_BUFFER_HINTS_VALID;
-    if((ret = avctx->reget_buffer(avctx, &c->pic)) < 0){
+    if ((ret = avctx->reget_buffer(avctx, &c->pic)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -89,7 +82,7 @@
     zret = inflateReset(&c->zstream);
     if (zret != Z_OK) {
         av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret);
-        return AVERROR(EINVAL);
+        return AVERROR_UNKNOWN;
     }
     c->zstream.next_in = (uint8_t*)encoded;
     c->zstream.avail_in = len;
@@ -99,7 +92,7 @@
     // Z_DATA_ERROR means empty picture
     if ((zret != Z_OK) && (zret != Z_STREAM_END) && (zret != Z_DATA_ERROR)) {
         av_log(avctx, AV_LOG_ERROR, "Inflate error: %d\n", zret);
-        return AVERROR(EINVAL);
+        return AVERROR_UNKNOWN;
     }
 
 
@@ -120,20 +113,13 @@
         memcpy(c->pic.data[1], c->pal, AVPALETTE_SIZE);
     }
 
-    *data_size = sizeof(AVFrame);
+    *got_frame      = 1;
     *(AVFrame*)data = c->pic;
 
     /* always report that the buffer was completely consumed */
     return buf_size;
 }
 
-
-
-/*
- *
- * Init tscc decoder
- *
- */
 static av_cold int decode_init(AVCodecContext *avctx)
 {
     CamtasiaContext * const c = avctx->priv_data;
@@ -174,19 +160,12 @@
     zret = inflateInit(&c->zstream);
     if (zret != Z_OK) {
         av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
-        return AVERROR(ENOMEM);
+        return AVERROR_UNKNOWN;
     }
 
     return 0;
 }
 
-
-
-/*
- *
- * Uninit tscc decoder
- *
- */
 static av_cold int decode_end(AVCodecContext *avctx)
 {
     CamtasiaContext * const c = avctx->priv_data;
diff --git a/libavcodec/tscc2.c b/libavcodec/tscc2.c
index 8692819..b71e7fa 100644
--- a/libavcodec/tscc2.c
+++ b/libavcodec/tscc2.c
@@ -211,7 +211,7 @@
 }
 
 static int tscc2_decode_frame(AVCodecContext *avctx, void *data,
-                              int *data_size, AVPacket *avpkt)
+                              int *got_frame, AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
@@ -238,7 +238,7 @@
     }
 
     if (frame_type == 0) {
-        *data_size      = sizeof(AVFrame);
+        *got_frame      = 1;
         *(AVFrame*)data = c->pic;
 
         return buf_size;
@@ -322,7 +322,7 @@
         bytestream2_skip(&gb, size);
     }
 
-    *data_size      = sizeof(AVFrame);
+    *got_frame      = 1;
     *(AVFrame*)data = c->pic;
 
     /* always report that the buffer was completely consumed */
diff --git a/libavcodec/tta.c b/libavcodec/tta.c
index b0e538f..4240946 100644
--- a/libavcodec/tta.c
+++ b/libavcodec/tta.c
@@ -32,7 +32,10 @@
 #include <limits.h>
 #include "avcodec.h"
 #include "get_bits.h"
+#include "internal.h"
 #include "libavutil/crc.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/opt.h"
 
 #define FORMAT_SIMPLE    1
 #define FORMAT_ENCRYPTED 2
@@ -56,17 +59,19 @@
 } TTAChannel;
 
 typedef struct TTAContext {
+    AVClass *class;
     AVCodecContext *avctx;
-    AVFrame frame;
     GetBitContext gb;
     const AVCRC *crc_table;
 
     int format, channels, bps;
     unsigned data_length;
-    int frame_length, last_frame_length, total_frames;
+    int frame_length, last_frame_length;
 
     int32_t *decode_buffer;
 
+    uint8_t crc_pass[8];
+    uint8_t *pass;
     TTAChannel *ch_ctx;
 } TTAContext;
 
@@ -92,8 +97,13 @@
     12
 };
 
-static void ttafilter_init(TTAFilter *c, int32_t shift) {
+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);
@@ -172,9 +182,25 @@
     return 0;
 }
 
+static uint64_t tta_check_crc64(uint8_t *pass)
+{
+    uint64_t crc = UINT64_MAX, poly = 0x42F0E1EBA9EA3693U;
+    uint8_t *end = pass + strlen(pass);
+    int i;
+
+    while (pass < end) {
+        crc ^= (uint64_t)*pass++ << 56;
+        for (i = 0; i < 8; i++)
+            crc = (crc << 1) ^ (poly & (((int64_t) crc) >> 63));
+    }
+
+    return crc ^ UINT64_MAX;
+}
+
 static av_cold int tta_decode_init(AVCodecContext * avctx)
 {
     TTAContext *s = avctx->priv_data;
+    int total_frames;
 
     s->avctx = avctx;
 
@@ -195,12 +221,15 @@
 
         s->format = get_bits(&s->gb, 16);
         if (s->format > 2) {
-            av_log(s->avctx, AV_LOG_ERROR, "Invalid format\n");
+            av_log(avctx, AV_LOG_ERROR, "Invalid format\n");
             return AVERROR_INVALIDDATA;
         }
         if (s->format == FORMAT_ENCRYPTED) {
-            av_log_missing_feature(s->avctx, "Encrypted TTA", 0);
-            return AVERROR_PATCHWELCOME;
+            if (!s->pass) {
+                av_log(avctx, AV_LOG_ERROR, "Missing password for encrypted stream. Please use the -password option\n");
+                return AVERROR(EINVAL);
+            }
+            AV_WL64(s->crc_pass, tta_check_crc64(s->pass));
         }
         avctx->channels = s->channels = get_bits(&s->gb, 16);
         if (s->channels > 1 && s->channels < 9)
@@ -212,10 +241,10 @@
         skip_bits_long(&s->gb, 32); // CRC32 of header
 
         if (s->channels == 0) {
-            av_log(s->avctx, AV_LOG_ERROR, "Invalid number of channels\n");
+            av_log(avctx, AV_LOG_ERROR, "Invalid number of channels\n");
             return AVERROR_INVALIDDATA;
         } else if (avctx->sample_rate == 0) {
-            av_log(s->avctx, AV_LOG_ERROR, "Invalid samplerate\n");
+            av_log(avctx, AV_LOG_ERROR, "Invalid samplerate\n");
             return AVERROR_INVALIDDATA;
         }
 
@@ -241,27 +270,24 @@
         s->frame_length = 256 * avctx->sample_rate / 245;
 
         s->last_frame_length = s->data_length % s->frame_length;
-        s->total_frames = s->data_length / s->frame_length +
-                        (s->last_frame_length ? 1 : 0);
+        total_frames = s->data_length / s->frame_length +
+                       (s->last_frame_length ? 1 : 0);
 
-        av_log(s->avctx, AV_LOG_DEBUG, "format: %d chans: %d bps: %d rate: %d block: %d\n",
+        av_log(avctx, AV_LOG_DEBUG, "format: %d chans: %d bps: %d rate: %d block: %d\n",
             s->format, avctx->channels, avctx->bits_per_coded_sample, avctx->sample_rate,
             avctx->block_align);
-        av_log(s->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, s->total_frames);
-
-        if (s->total_frames < 0)
-            return AVERROR_INVALIDDATA;
+        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 || s->total_frames > INT_MAX / 4 ||
-            avctx->extradata_size - 26 < s->total_frames * 4)
+        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 (avctx->extradata_size < 26 + s->total_frames * 4 || tta_check_crc(s, avctx->extradata + 22, s->total_frames * 4))
+            if (tta_check_crc(s, avctx->extradata + 22, total_frames * 4))
                 return AVERROR_INVALIDDATA;
         }
-        skip_bits_long(&s->gb, 32 * s->total_frames);
+        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))){
@@ -285,15 +311,13 @@
         return AVERROR_INVALIDDATA;
     }
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     return 0;
 }
 
 static int tta_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;
     TTAContext *s = avctx->priv_data;
@@ -308,29 +332,25 @@
 
     init_get_bits(&s->gb, buf, buf_size*8);
 
-    // FIXME: seeking
-    s->total_frames--;
-    if (!s->total_frames && s->last_frame_length)
-        framelen = s->last_frame_length;
-
     /* get output buffer */
-    s->frame.nb_samples = framelen;
-    if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = framelen;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
 
     // decode directly to output buffer for 24-bit sample format
     if (s->bps == 3)
-        s->decode_buffer = (int32_t *)s->frame.data[0];
+        s->decode_buffer = (int32_t *)frame->data[0];
 
     // init per channel states
     for (i = 0; i < s->channels; i++) {
         s->ch_ctx[i].predictor = 0;
-        ttafilter_init(&s->ch_ctx[i].filter, ttafilter_configs[s->bps-1]);
+        ttafilter_init(s, &s->ch_ctx[i].filter, ttafilter_configs[s->bps-1]);
         rice_init(&s->ch_ctx[i].rice, 10, 10);
     }
 
+    i = 0;
     for (p = s->decode_buffer; p < s->decode_buffer + (framelen * s->channels); p++) {
         int32_t *predictor = &s->ch_ctx[cur_chan].predictor;
         TTAFilter *filter = &s->ch_ctx[cur_chan].filter;
@@ -407,9 +427,16 @@
                     *r = *(r + 1) - *r;
             }
             cur_chan = 0;
+            i++;
+            // check for last frame
+            if (i == s->last_frame_length && get_bits_left(&s->gb) / 8 == 4) {
+                frame->nb_samples = framelen = s->last_frame_length;
+                break;
+            }
         }
     }
 
+    align_get_bits(&s->gb);
     if (get_bits_left(&s->gb) < 32) {
         ret = AVERROR_INVALIDDATA;
         goto error;
@@ -419,20 +446,20 @@
     // convert to output buffer
     switch (s->bps) {
     case 1: {
-        uint8_t *samples = (uint8_t *)s->frame.data[0];
+        uint8_t *samples = (uint8_t *)frame->data[0];
         for (p = s->decode_buffer; p < s->decode_buffer + (framelen * s->channels); p++)
             *samples++ = *p + 0x80;
         break;
         }
     case 2: {
-        int16_t *samples = (int16_t *)s->frame.data[0];
+        int16_t *samples = (int16_t *)frame->data[0];
         for (p = s->decode_buffer; p < s->decode_buffer + (framelen * s->channels); p++)
             *samples++ = *p;
         break;
         }
     case 3: {
         // shift samples for 24-bit sample format
-        int32_t *samples = (int32_t *)s->frame.data[0];
+        int32_t *samples = (int32_t *)frame->data[0];
         for (p = s->decode_buffer; p < s->decode_buffer + (framelen * s->channels); p++)
             *samples++ <<= 8;
         // reset decode buffer
@@ -441,8 +468,7 @@
         }
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
+    *got_frame_ptr = 1;
 
     return buf_size;
 error:
@@ -463,6 +489,20 @@
     return 0;
 }
 
+#define OFFSET(x) offsetof(TTAContext, x)
+#define DEC (AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM)
+static const AVOption options[] = {
+    { "password", "Set decoding password", OFFSET(pass), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, DEC },
+    { NULL },
+};
+
+static const AVClass tta_decoder_class = {
+    .class_name = "TTA Decoder",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 AVCodec ff_tta_decoder = {
     .name           = "tta",
     .type           = AVMEDIA_TYPE_AUDIO,
@@ -473,4 +513,5 @@
     .decode         = tta_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("TTA (True Audio)"),
+    .priv_class     = &tta_decoder_class,
 };
diff --git a/libavcodec/twinvq.c b/libavcodec/twinvq.c
index d7a3726..e9d206e 100644
--- a/libavcodec/twinvq.c
+++ b/libavcodec/twinvq.c
@@ -23,8 +23,8 @@
 #include "libavutil/float_dsp.h"
 #include "avcodec.h"
 #include "get_bits.h"
-#include "dsputil.h"
 #include "fft.h"
+#include "internal.h"
 #include "lsp.h"
 #include "sinewin.h"
 
@@ -176,8 +176,6 @@
 
 typedef struct TwinContext {
     AVCodecContext *avctx;
-    AVFrame frame;
-    DSPContext      dsp;
     AVFloatDSPContext fdsp;
     FFTContext mdct_ctx[3];
 
@@ -649,11 +647,10 @@
 
         mdct->imdct_half(mdct, buf1 + bsize*j, in + bsize*j);
 
-        tctx->dsp.vector_fmul_window(out2,
-                                     prev_buf + (bsize-wsize)/2,
-                                     buf1 + bsize*j,
-                                     ff_sine_windows[av_log2(wsize)],
-                                     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));
@@ -693,7 +690,7 @@
     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]));
-        tctx->dsp.butterflies_float(out[0], out[1], mtab->size);
+        tctx->fdsp.butterflies_float(out[0], out[1], mtab->size);
     }
 }
 
@@ -812,6 +809,7 @@
 static int twin_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;
@@ -833,12 +831,12 @@
 
     /* get output buffer */
     if (tctx->discarded_packets >= 2) {
-        tctx->frame.nb_samples = mtab->size;
-        if ((ret = avctx->get_buffer(avctx, &tctx->frame)) < 0) {
+        frame->nb_samples = mtab->size;
+        if ((ret = ff_get_buffer(avctx, frame)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
             return ret;
         }
-        out = (float **)tctx->frame.extended_data;
+        out = (float **)frame->extended_data;
     }
 
     init_get_bits(&gb, buf, buf_size * 8);
@@ -864,8 +862,7 @@
         return buf_size;
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = tctx->frame;
+    *got_frame_ptr = 1;
 
     return buf_size;
 }
@@ -1162,7 +1159,6 @@
         return -1;
     }
 
-    ff_dsputil_init(&tctx->dsp, avctx);
     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");
@@ -1173,9 +1169,6 @@
 
     memset_float(tctx->bark_hist[0][0], 0.1, FF_ARRAY_ELEMS(tctx->bark_hist));
 
-    avcodec_get_frame_defaults(&tctx->frame);
-    avctx->coded_frame = &tctx->frame;
-
     return 0;
 }
 
diff --git a/libavcodec/txd.c b/libavcodec/txd.c
index a526035..b5b34ac 100644
--- a/libavcodec/txd.c
+++ b/libavcodec/txd.c
@@ -25,6 +25,7 @@
 #include "libavutil/imgutils.h"
 #include "bytestream.h"
 #include "avcodec.h"
+#include "internal.h"
 #include "s3tc.h"
 
 typedef struct TXDContext {
@@ -40,7 +41,7 @@
     return 0;
 }
 
-static int txd_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+static int txd_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                             AVPacket *avpkt) {
     TXDContext * const s = avctx->priv_data;
     GetByteContext gb;
@@ -50,6 +51,7 @@
     unsigned int y, v;
     uint8_t *ptr;
     uint32_t *pal;
+    int ret;
 
     bytestream2_init(&gb, avpkt->data, avpkt->size);
     version         = bytestream2_get_le32(&gb);
@@ -64,7 +66,7 @@
     if (version < 8 || version > 9) {
         av_log(avctx, AV_LOG_ERROR, "texture data version %i is unsupported\n",
                                                                     version);
-        return -1;
+        return AVERROR_PATCHWELCOME;
     }
 
     if (depth == 8) {
@@ -73,19 +75,19 @@
         avctx->pix_fmt = AV_PIX_FMT_RGB32;
     } else {
         av_log(avctx, AV_LOG_ERROR, "depth of %i is unsupported\n", depth);
-        return -1;
+        return AVERROR_PATCHWELCOME;
     }
 
     if (p->data[0])
         avctx->release_buffer(avctx, p);
 
-    if (av_image_check_size(w, h, 0, avctx))
-        return -1;
+    if ((ret = av_image_check_size(w, h, 0, avctx)) < 0)
+        return ret;
     if (w != avctx->width || h != avctx->height)
         avcodec_set_dimensions(avctx, w, h);
-    if (avctx->get_buffer(avctx, p) < 0) {
+    if ((ret = ff_get_buffer(avctx, p)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     p->pict_type = AV_PICTURE_TYPE_I;
@@ -142,13 +144,13 @@
     }
 
     *picture   = s->picture;
-    *data_size = sizeof(AVPicture);
+    *got_frame = 1;
 
     return avpkt->size;
 
 unsupported:
     av_log(avctx, AV_LOG_ERROR, "unsupported d3d format (%08x)\n", d3d_format);
-    return -1;
+    return AVERROR_PATCHWELCOME;
 }
 
 static av_cold int txd_end(AVCodecContext *avctx) {
diff --git a/libavcodec/ulti.c b/libavcodec/ulti.c
index f6d6418..a9413ad 100644
--- a/libavcodec/ulti.c
+++ b/libavcodec/ulti.c
@@ -210,7 +210,7 @@
 }
 
 static int ulti_decode_frame(AVCodecContext *avctx,
-                             void *data, int *data_size,
+                             void *data, int *got_frame,
                              AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
@@ -407,7 +407,7 @@
         }
     }
 
-    *data_size=sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*)data= s->frame;
 
     return buf_size;
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index 48ef679..e364b7e 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -25,8 +25,10 @@
  * utils.
  */
 
+#include "config.h"
 #include "libavutil/avassert.h"
 #include "libavutil/avstring.h"
+#include "libavutil/bprint.h"
 #include "libavutil/channel_layout.h"
 #include "libavutil/crc.h"
 #include "libavutil/mathematics.h"
@@ -46,7 +48,11 @@
 #include <stdarg.h>
 #include <limits.h>
 #include <float.h>
+#if CONFIG_ICONV
+# include <iconv.h>
+#endif
 
+volatile int ff_avcodec_locked;
 static int volatile entangled_thread_counter = 0;
 static int (*ff_lockmgr_cb)(void **mutex, enum AVLockOp op);
 static void *codec_mutex;
@@ -175,6 +181,12 @@
 
 #define INTERNAL_BUFFER_SIZE (32 + 1)
 
+#if (ARCH_ARM && HAVE_NEON) || ARCH_PPC || HAVE_MMX
+#   define STRIDE_ALIGN 16
+#else
+#   define STRIDE_ALIGN 8
+#endif
+
 void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height,
                                int linesize_align[AV_NUM_DATA_POINTERS])
 {
@@ -255,7 +267,8 @@
     case AV_PIX_FMT_PAL8:
     case AV_PIX_FMT_BGR8:
     case AV_PIX_FMT_RGB8:
-        if (s->codec_id == AV_CODEC_ID_SMC) {
+        if (s->codec_id == AV_CODEC_ID_SMC ||
+            s->codec_id == AV_CODEC_ID_CINEPAK) {
             w_align = 4;
             h_align = 4;
         }
@@ -267,6 +280,12 @@
             h_align = 4;
         }
         break;
+    case AV_PIX_FMT_RGB24:
+        if (s->codec_id == AV_CODEC_ID_CINEPAK) {
+            w_align = 4;
+            h_align = 4;
+        }
+        break;
     default:
         w_align = 1;
         h_align = 1;
@@ -303,35 +322,6 @@
     *width              = FFALIGN(*width, align);
 }
 
-void ff_init_buffer_info(AVCodecContext *s, AVFrame *frame)
-{
-    if (s->pkt) {
-        frame->pkt_pts = s->pkt->pts;
-        frame->pkt_pos = s->pkt->pos;
-        frame->pkt_duration = s->pkt->duration;
-    } else {
-        frame->pkt_pts = AV_NOPTS_VALUE;
-        frame->pkt_pos = -1;
-        frame->pkt_duration = 0;
-    }
-    frame->reordered_opaque = s->reordered_opaque;
-
-    switch (s->codec->type) {
-    case AVMEDIA_TYPE_VIDEO:
-        frame->width               = s->width;
-        frame->height              = s->height;
-        frame->format              = s->pix_fmt;
-        frame->sample_aspect_ratio = s->sample_aspect_ratio;
-        break;
-    case AVMEDIA_TYPE_AUDIO:
-        frame->sample_rate    = s->sample_rate;
-        frame->format         = s->sample_fmt;
-        frame->channel_layout = s->channel_layout;
-        frame->channels       = s->channels;
-        break;
-    }
-}
-
 int avcodec_fill_audio_frame(AVFrame *frame, int nb_channels,
                              enum AVSampleFormat sample_fmt, const uint8_t *buf,
                              int buf_size, int align)
@@ -371,73 +361,27 @@
 static int audio_get_buffer(AVCodecContext *avctx, AVFrame *frame)
 {
     AVCodecInternal *avci = avctx->internal;
-    InternalBuffer *buf;
     int buf_size, ret;
 
+    av_freep(&avci->audio_data);
     buf_size = av_samples_get_buffer_size(NULL, avctx->channels,
                                           frame->nb_samples, avctx->sample_fmt,
                                           0);
     if (buf_size < 0)
         return AVERROR(EINVAL);
 
-    /* allocate InternalBuffer if needed */
-    if (!avci->buffer) {
-        avci->buffer = av_mallocz(sizeof(InternalBuffer));
-        if (!avci->buffer)
-            return AVERROR(ENOMEM);
-    }
-    buf = avci->buffer;
+    frame->data[0] = av_mallocz(buf_size);
+    if (!frame->data[0])
+        return AVERROR(ENOMEM);
 
-    /* if there is a previously-used internal buffer, check its size and
-     * channel count to see if we can reuse it */
-    if (buf->extended_data) {
-        /* if current buffer is too small, free it */
-        if (buf->extended_data[0] && buf_size > buf->audio_data_size) {
-            av_free(buf->extended_data[0]);
-            if (buf->extended_data != buf->data)
-                av_free(buf->extended_data);
-            buf->extended_data = NULL;
-            buf->data[0]       = NULL;
-        }
-        /* if number of channels has changed, reset and/or free extended data
-         * pointers but leave data buffer in buf->data[0] for reuse */
-        if (buf->nb_channels != avctx->channels) {
-            if (buf->extended_data != buf->data)
-                av_free(buf->extended_data);
-            buf->extended_data = NULL;
-        }
+    ret = avcodec_fill_audio_frame(frame, avctx->channels, avctx->sample_fmt,
+                                   frame->data[0], buf_size, 0);
+    if (ret < 0) {
+        av_freep(&frame->data[0]);
+        return ret;
     }
 
-    /* if there is no previous buffer or the previous buffer cannot be used
-     * as-is, allocate a new buffer and/or rearrange the channel pointers */
-    if (!buf->extended_data) {
-        if (!buf->data[0]) {
-            if (!(buf->data[0] = av_mallocz(buf_size)))
-                return AVERROR(ENOMEM);
-            buf->audio_data_size = buf_size;
-        }
-        if ((ret = avcodec_fill_audio_frame(frame, avctx->channels,
-                                            avctx->sample_fmt, buf->data[0],
-                                            buf->audio_data_size, 0)) < 0)
-            return ret;
-
-        if (frame->extended_data == frame->data)
-            buf->extended_data = buf->data;
-        else
-            buf->extended_data = frame->extended_data;
-        memcpy(buf->data, frame->data, sizeof(frame->data));
-        buf->linesize[0] = frame->linesize[0];
-        buf->nb_channels = avctx->channels;
-    } else {
-        /* copy InternalBuffer info to the AVFrame */
-        frame->extended_data = buf->extended_data;
-        frame->linesize[0]   = buf->linesize[0];
-        memcpy(frame->data, buf->data, sizeof(frame->data));
-    }
-
-    frame->type = FF_BUFFER_TYPE_INTERNAL;
-    ff_init_buffer_info(avctx, frame);
-
+    avci->audio_data = frame->data[0];
     if (avctx->debug & FF_DEBUG_BUFFERS)
         av_log(avctx, AV_LOG_DEBUG, "default_get_buffer called on frame %p, "
                                     "internal audio buffer used\n", frame);
@@ -533,7 +477,6 @@
             buf->base[i] = av_malloc(size[i] + 16); //FIXME 16
             if (buf->base[i] == NULL)
                 return AVERROR(ENOMEM);
-            memset(buf->base[i], 128, size[i]);
 
             // no edge if EDGE EMU or not planar YUV
             if ((s->flags & CODEC_FLAG_EMU_EDGE) || !size[2])
@@ -551,7 +494,6 @@
         buf->height  = s->height;
         buf->pix_fmt = s->pix_fmt;
     }
-    pic->type = FF_BUFFER_TYPE_INTERNAL;
 
     for (i = 0; i < AV_NUM_DATA_POINTERS; i++) {
         pic->base[i]     = buf->base[i];
@@ -560,11 +502,6 @@
     }
     pic->extended_data = pic->data;
     avci->buffer_count++;
-    pic->width               = buf->width;
-    pic->height              = buf->height;
-    pic->format              = buf->pix_fmt;
-
-    ff_init_buffer_info(s, pic);
 
     if (s->debug & FF_DEBUG_BUFFERS)
         av_log(s, AV_LOG_DEBUG, "default_get_buffer called on pic %p, %d "
@@ -573,8 +510,31 @@
     return 0;
 }
 
+void avpriv_color_frame(AVFrame *frame, const int c[4])
+{
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format);
+    int p, y, x;
+
+    av_assert0(desc->flags & PIX_FMT_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++){
+            if (desc->comp[0].depth_minus1 >= 8) {
+                for (x = 0; x<bytes; x++)
+                    ((uint16_t*)dst)[x] = c[p];
+            }else
+                memset(dst, c[p], bytes);
+            dst += frame->linesize[p];
+        }
+    }
+}
+
 int avcodec_default_get_buffer(AVCodecContext *avctx, AVFrame *frame)
 {
+    frame->type = FF_BUFFER_TYPE_INTERNAL;
     switch (avctx->codec_type) {
     case AVMEDIA_TYPE_VIDEO:
         return video_get_buffer(avctx, frame);
@@ -585,6 +545,44 @@
     }
 }
 
+void ff_init_buffer_info(AVCodecContext *s, AVFrame *frame)
+{
+    if (s->pkt) {
+        frame->pkt_pts = s->pkt->pts;
+        frame->pkt_pos = s->pkt->pos;
+        frame->pkt_duration = s->pkt->duration;
+        frame->pkt_size = s->pkt->size;
+    } else {
+        frame->pkt_pts = AV_NOPTS_VALUE;
+        frame->pkt_pos = -1;
+        frame->pkt_duration = 0;
+        frame->pkt_size = -1;
+    }
+    frame->reordered_opaque = s->reordered_opaque;
+
+    switch (s->codec->type) {
+    case AVMEDIA_TYPE_VIDEO:
+        frame->width               = s->width;
+        frame->height              = s->height;
+        frame->format              = s->pix_fmt;
+        frame->sample_aspect_ratio = s->sample_aspect_ratio;
+        break;
+    case AVMEDIA_TYPE_AUDIO:
+        frame->sample_rate    = s->sample_rate;
+        frame->format         = s->sample_fmt;
+        frame->channel_layout = s->channel_layout;
+        frame->channels       = s->channels;
+        break;
+    }
+}
+
+int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame)
+{
+    ff_init_buffer_info(avctx, frame);
+
+    return avctx->get_buffer(avctx, frame);
+}
+
 void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic)
 {
     int i;
@@ -639,7 +637,7 @@
     if (pic->data[0] == NULL) {
         /* We will copy from buffer, so must be readable */
         pic->buffer_hints |= FF_BUFFER_HINTS_READABLE;
-        return s->get_buffer(s, pic);
+        return ff_get_buffer(s, pic);
     }
 
     assert(s->pix_fmt == pic->format);
@@ -657,7 +655,7 @@
         pic->data[i] = pic->base[i] = NULL;
     pic->opaque = NULL;
     /* Allocate new frame */
-    if ((ret = s->get_buffer(s, pic)))
+    if ((ret = ff_get_buffer(s, pic)))
         return ret;
     /* Copy image data from old buffer to new buffer */
     av_picture_copy((AVPicture *)pic, (AVPicture *)&temp_pic, s->pix_fmt, s->width,
@@ -720,6 +718,7 @@
     frame->best_effort_timestamp = AV_NOPTS_VALUE;
     frame->pkt_duration        = 0;
     frame->pkt_pos             = -1;
+    frame->pkt_size            = -1;
     frame->key_frame           = 1;
     frame->sample_aspect_ratio = (AVRational) {0, 1 };
     frame->format              = -1; /* unknown */
@@ -766,6 +765,7 @@
 MAKE_ACCESSORS(AVFrame, frame, int,     sample_rate)
 MAKE_ACCESSORS(AVFrame, frame, AVDictionary *, metadata)
 MAKE_ACCESSORS(AVFrame, frame, int,     decode_error_flags)
+MAKE_ACCESSORS(AVFrame, frame, int,     pkt_size)
 
 MAKE_ACCESSORS(AVCodecContext, codec, AVRational, pkt_timebase)
 MAKE_ACCESSORS(AVCodecContext, codec, const AVCodecDescriptor *, codec_descriptor)
@@ -810,20 +810,11 @@
 {
     int ret = 0;
 
-    entangled_thread_counter--;
-    /* Release any user-supplied mutex. */
-    if (ff_lockmgr_cb) {
-        (*ff_lockmgr_cb)(&codec_mutex, AV_LOCK_RELEASE);
-    }
+    ff_unlock_avcodec();
 
     ret = avcodec_open2(avctx, codec, options);
 
-    /* If there is a user-supplied mutex locking routine, call it. */
-    if (ff_lockmgr_cb) {
-        if ((*ff_lockmgr_cb)(&codec_mutex, AV_LOCK_OBTAIN))
-            return -1;
-    }
-    entangled_thread_counter++;
+    ff_lock_avcodec(avctx);
     return ret;
 }
 
@@ -853,18 +844,9 @@
     if (options)
         av_dict_copy(&tmp, *options, 0);
 
-    /* If there is a user-supplied mutex locking routine, call it. */
-    if (ff_lockmgr_cb) {
-        if ((ret = (*ff_lockmgr_cb)(&codec_mutex, AV_LOCK_OBTAIN)) < 0)
-            return ret;
-    }
-
-    entangled_thread_counter++;
-    if (entangled_thread_counter != 1) {
-        av_log(avctx, AV_LOG_ERROR, "Insufficient thread locking around avcodec_open/close()\n");
-        ret = AVERROR(EINVAL);
-        goto end;
-    }
+    ret = ff_lock_avcodec(avctx);
+    if (ret < 0)
+        return ret;
 
     avctx->internal = av_mallocz(sizeof(AVCodecInternal));
     if (!avctx->internal) {
@@ -959,9 +941,9 @@
         av_log(avctx, AV_LOG_WARNING, "Warning: not compiled with thread support, using thread emulation\n");
 
     if (HAVE_THREADS) {
-        entangled_thread_counter--; //we will instanciate a few encoders thus kick the counter to prevent false detection of a problem
+        ff_unlock_avcodec(); //we will instanciate a few encoders thus kick the counter to prevent false detection of a problem
         ret = ff_frame_thread_encoder_init(avctx, options ? *options : NULL);
-        entangled_thread_counter++;
+        ff_lock_avcodec(avctx);
         if (ret < 0)
             goto free_and_end;
     }
@@ -1061,6 +1043,22 @@
         } else if (avctx->channel_layout) {
             avctx->channels = av_get_channel_layout_nb_channels(avctx->channel_layout);
         }
+        if(avctx->codec_type == AVMEDIA_TYPE_VIDEO &&
+           avctx->codec_id != AV_CODEC_ID_PNG // For mplayer
+        ) {
+            if (avctx->width <= 0 || avctx->height <= 0) {
+                av_log(avctx, AV_LOG_ERROR, "dimensions not set\n");
+                ret = AVERROR(EINVAL);
+                goto free_and_end;
+            }
+        }
+        if (   (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
+            && avctx->bit_rate>0 && avctx->bit_rate<1000) {
+            av_log(avctx, AV_LOG_WARNING, "Bitrate %d is extreemly low, did you mean %dk\n", avctx->bit_rate, avctx->bit_rate);
+        }
+
+        if (!avctx->rc_initial_buffer_occupancy)
+            avctx->rc_initial_buffer_occupancy = avctx->rc_buffer_size * 3 / 4;
     }
 
     avctx->pts_correction_num_faulty_pts =
@@ -1101,14 +1099,35 @@
             ret = AVERROR(EINVAL);
             goto free_and_end;
         }
+        if (avctx->sub_charenc) {
+            if (avctx->codec_type != AVMEDIA_TYPE_SUBTITLE) {
+                av_log(avctx, AV_LOG_ERROR, "Character encoding is only "
+                       "supported with subtitles codecs\n");
+                ret = AVERROR(EINVAL);
+                goto free_and_end;
+            } else if (avctx->codec_descriptor->props & AV_CODEC_PROP_BITMAP_SUB) {
+                av_log(avctx, AV_LOG_WARNING, "Codec '%s' is bitmap-based, "
+                       "subtitles character encoding will be ignored\n",
+                       avctx->codec_descriptor->name);
+                avctx->sub_charenc_mode = FF_SUB_CHARENC_MODE_DO_NOTHING;
+            } else {
+                /* input character encoding is set for a text based subtitle
+                 * codec at this point */
+                if (avctx->sub_charenc_mode == FF_SUB_CHARENC_MODE_AUTOMATIC)
+                    avctx->sub_charenc_mode = FF_SUB_CHARENC_MODE_PRE_DECODER;
+
+                if (!CONFIG_ICONV && avctx->sub_charenc_mode == FF_SUB_CHARENC_MODE_PRE_DECODER) {
+                    av_log(avctx, AV_LOG_ERROR, "Character encoding subtitles "
+                           "conversion needs a libavcodec built with iconv support "
+                           "for this codec\n");
+                    ret = AVERROR(ENOSYS);
+                    goto free_and_end;
+                }
+            }
+        }
     }
 end:
-    entangled_thread_counter--;
-
-    /* Release any user-supplied mutex. */
-    if (ff_lockmgr_cb) {
-        (*ff_lockmgr_cb)(&codec_mutex, AV_LOCK_RELEASE);
-    }
+    ff_unlock_avcodec();
     if (options) {
         av_dict_free(options);
         *options = tmp;
@@ -1344,7 +1363,7 @@
                                              const short *samples)
 {
     AVPacket pkt;
-    AVFrame frame0 = { 0 };
+    AVFrame frame0 = { { 0 } };
     AVFrame *frame;
     int ret, samples_size, got_packet;
 
@@ -1668,16 +1687,19 @@
         else {
             ret = avctx->codec->decode(avctx, picture, got_picture_ptr,
                                        &tmp);
-            picture->pkt_dts             = avpkt->dts;
+            picture->pkt_dts = avpkt->dts;
 
             if(!avctx->has_b_frames){
                 picture->pkt_pos         = avpkt->pos;
             }
             //FIXME these should be under if(!avctx->has_b_frames)
-            if (!picture->sample_aspect_ratio.num) picture->sample_aspect_ratio = avctx->sample_aspect_ratio;
-            if (!picture->width)                   picture->width               = avctx->width;
-            if (!picture->height)                  picture->height              = avctx->height;
-            if (picture->format == AV_PIX_FMT_NONE)   picture->format              = avctx->pix_fmt;
+            /* get_buffer is supposed to set frame parameters */
+            if (!(avctx->codec->capabilities & CODEC_CAP_DR1)) {
+                if (!picture->sample_aspect_ratio.num)    picture->sample_aspect_ratio = avctx->sample_aspect_ratio;
+                if (!picture->width)                      picture->width               = avctx->width;
+                if (!picture->height)                     picture->height              = avctx->height;
+                if (picture->format == AV_PIX_FMT_NONE)   picture->format              = avctx->pix_fmt;
+            }
         }
         add_metadata_from_side_data(avctx, picture);
 
@@ -1711,7 +1733,7 @@
                                               int *frame_size_ptr,
                                               AVPacket *avpkt)
 {
-    AVFrame frame = {0};
+    AVFrame frame = { { 0 } };
     int ret, got_frame = 0;
 
     if (avctx->get_buffer != avcodec_default_get_buffer) {
@@ -1809,7 +1831,7 @@
             av_log(avctx, AV_LOG_DEBUG, "skip %d samples due to side data\n",
                    avctx->internal->skip_samples);
         }
-        if (avctx->internal->skip_samples) {
+        if (avctx->internal->skip_samples && *got_frame_ptr) {
             if(frame->nb_samples <= avctx->internal->skip_samples){
                 *got_frame_ptr = 0;
                 avctx->internal->skip_samples -= frame->nb_samples;
@@ -1851,7 +1873,7 @@
      * extended_data are doing it correctly */
     if (*got_frame_ptr) {
         planar   = av_sample_fmt_is_planar(frame->format);
-        channels = av_get_channel_layout_nb_channels(frame->channel_layout);
+        channels = frame->channels;
         if (!(planar && channels > AV_NUM_DATA_POINTERS))
             frame->extended_data = frame->data;
     } else {
@@ -1861,6 +1883,68 @@
     return ret;
 }
 
+#define UTF8_MAX_BYTES 4 /* 5 and 6 bytes sequences should not be used */
+static int recode_subtitle(AVCodecContext *avctx,
+                           AVPacket *outpkt, const AVPacket *inpkt)
+{
+#if CONFIG_ICONV
+    iconv_t cd = (iconv_t)-1;
+    int ret = 0;
+    char *inb, *outb;
+    size_t inl, outl;
+    AVPacket tmp;
+#endif
+
+    if (avctx->sub_charenc_mode != FF_SUB_CHARENC_MODE_PRE_DECODER)
+        return 0;
+
+#if CONFIG_ICONV
+    cd = iconv_open("UTF-8", avctx->sub_charenc);
+    if (cd == (iconv_t)-1) {
+        av_log(avctx, AV_LOG_ERROR, "Unable to open iconv context "
+               "with input character encoding \"%s\"\n", avctx->sub_charenc);
+        ret = AVERROR(errno);
+        goto end;
+    }
+
+    inb = inpkt->data;
+    inl = inpkt->size;
+
+    if (inl >= INT_MAX / UTF8_MAX_BYTES - FF_INPUT_BUFFER_PADDING_SIZE) {
+        av_log(avctx, AV_LOG_ERROR, "Subtitles packet is too big for recoding\n");
+        ret = AVERROR(ENOMEM);
+        goto end;
+    }
+
+    ret = av_new_packet(&tmp, inl * UTF8_MAX_BYTES);
+    if (ret < 0)
+        goto end;
+    outpkt->data = tmp.data;
+    outpkt->size = tmp.size;
+    outb = outpkt->data;
+    outl = outpkt->size;
+
+    if (iconv(cd, &inb, &inl, &outb, &outl) == (size_t)-1 ||
+        iconv(cd, NULL, NULL, &outb, &outl) == (size_t)-1 ||
+        outl >= outpkt->size || inl != 0) {
+        av_log(avctx, AV_LOG_ERROR, "Unable to recode subtitle event \"%s\" "
+               "from %s to UTF-8\n", inpkt->data, avctx->sub_charenc);
+        av_free_packet(&tmp);
+        ret = AVERROR(errno);
+        goto end;
+    }
+    outpkt->size -= outl;
+    outpkt->data[outpkt->size - 1] = '\0';
+
+end:
+    if (cd != (iconv_t)-1)
+        iconv_close(cd);
+    return ret;
+#else
+    av_assert0(!"requesting subtitles recoding without iconv");
+#endif
+}
+
 int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub,
                              int *got_sub_ptr,
                              AVPacket *avpkt)
@@ -1876,26 +1960,38 @@
     avcodec_get_subtitle_defaults(sub);
 
     if (avpkt->size) {
+        AVPacket pkt_recoded;
         AVPacket tmp = *avpkt;
         int did_split = av_packet_split_side_data(&tmp);
         //apply_param_change(avctx, &tmp);
 
-        avctx->pkt = &tmp;
+        pkt_recoded = tmp;
+        ret = recode_subtitle(avctx, &pkt_recoded, &tmp);
+        if (ret < 0) {
+            *got_sub_ptr = 0;
+        } else {
+            avctx->pkt = &pkt_recoded;
 
-    if (avctx->pkt_timebase.den && avpkt->pts != AV_NOPTS_VALUE)
-        sub->pts = av_rescale_q(avpkt->pts,
-                                avctx->pkt_timebase, AV_TIME_BASE_Q);
-        ret = avctx->codec->decode(avctx, sub, got_sub_ptr, &tmp);
+            if (avctx->pkt_timebase.den && avpkt->pts != AV_NOPTS_VALUE)
+                sub->pts = av_rescale_q(avpkt->pts,
+                                        avctx->pkt_timebase, AV_TIME_BASE_Q);
+            ret = avctx->codec->decode(avctx, sub, got_sub_ptr, &pkt_recoded);
+            av_assert1((ret >= 0) >= !!*got_sub_ptr &&
+                       !!*got_sub_ptr >= !!sub->num_rects);
+            if (tmp.data != pkt_recoded.data)
+                av_free(pkt_recoded.data);
+            sub->format = !(avctx->codec_descriptor->props & AV_CODEC_PROP_BITMAP_SUB);
+            avctx->pkt = NULL;
+        }
 
-        avctx->pkt = NULL;
         if (did_split) {
             ff_packet_free_side_data(&tmp);
             if(ret == tmp.size)
                 ret = avpkt->size;
         }
 
-    if (*got_sub_ptr)
-        avctx->frame_number++;
+        if (*got_sub_ptr)
+            avctx->frame_number++;
     }
 
     return ret;
@@ -1924,43 +2020,25 @@
 {
     int ret = 0;
 
-    entangled_thread_counter--;
-    /* Release any user-supplied mutex. */
-    if (ff_lockmgr_cb) {
-        (*ff_lockmgr_cb)(&codec_mutex, AV_LOCK_RELEASE);
-    }
+    ff_unlock_avcodec();
 
     ret = avcodec_close(avctx);
 
-    /* If there is a user-supplied mutex locking routine, call it. */
-    if (ff_lockmgr_cb) {
-        if ((*ff_lockmgr_cb)(&codec_mutex, AV_LOCK_OBTAIN))
-            return -1;
-    }
-    entangled_thread_counter++;
+    ff_lock_avcodec(NULL);
     return ret;
 }
 
 av_cold int avcodec_close(AVCodecContext *avctx)
 {
-    /* If there is a user-supplied mutex locking routine, call it. */
-    if (ff_lockmgr_cb) {
-        if ((*ff_lockmgr_cb)(&codec_mutex, AV_LOCK_OBTAIN))
-            return -1;
-    }
-
-    entangled_thread_counter++;
-    if (entangled_thread_counter != 1) {
-        av_log(avctx, AV_LOG_ERROR, "insufficient thread locking around avcodec_open/close()\n");
-        entangled_thread_counter--;
-        return -1;
-    }
+    int ret = ff_lock_avcodec(avctx);
+    if (ret < 0)
+        return ret;
 
     if (avcodec_is_open(avctx)) {
         if (HAVE_THREADS && avctx->internal->frame_thread_encoder && avctx->thread_count > 1) {
-            entangled_thread_counter --;
+            ff_unlock_avcodec();
             ff_frame_thread_encoder_free(avctx);
-            entangled_thread_counter ++;
+            ff_lock_avcodec(avctx);
         }
         if (HAVE_THREADS && avctx->thread_opaque)
             ff_thread_free(avctx);
@@ -1982,12 +2060,8 @@
         av_freep(&avctx->extradata);
     avctx->codec = NULL;
     avctx->active_thread_type = 0;
-    entangled_thread_counter--;
 
-    /* Release any user-supplied mutex. */
-    if (ff_lockmgr_cb) {
-        (*ff_lockmgr_cb)(&codec_mutex, AV_LOCK_RELEASE);
-    }
+    ff_unlock_avcodec();
     return 0;
 }
 
@@ -1998,6 +2072,7 @@
         //last major bump but will fill up again over time, please don't remove it
 //         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;
         default                         : return id;
     }
 }
@@ -2085,7 +2160,7 @@
 #define IS_PRINT(x)                                               \
     (((x) >= '0' && (x) <= '9') ||                                \
      ((x) >= 'a' && (x) <= 'z') || ((x) >= 'A' && (x) <= 'Z') ||  \
-     ((x) == '.' || (x) == ' ' || (x) == '-'))
+     ((x) == '.' || (x) == ' ' || (x) == '-' || (x) == '_'))
 
     for (i = 0; i < 4; i++) {
         len = snprintf(buf, buf_size,
@@ -2139,6 +2214,10 @@
             snprintf(buf + strlen(buf), buf_size - strlen(buf),
                      ", %s",
                      av_get_pix_fmt_name(enc->pix_fmt));
+            if (enc->bits_per_raw_sample &&
+                enc->bits_per_raw_sample <= av_pix_fmt_desc_get(enc->pix_fmt)->comp[0].depth_minus1)
+                snprintf(buf + strlen(buf), buf_size - strlen(buf),
+                         " (%d bpc)", enc->bits_per_raw_sample);
         }
         if (enc->width) {
             snprintf(buf + strlen(buf), buf_size - strlen(buf),
@@ -2178,6 +2257,15 @@
                      ", %s", av_get_sample_fmt_name(enc->sample_fmt));
         }
         break;
+    case AVMEDIA_TYPE_DATA:
+        if (av_log_get_level() >= AV_LOG_DEBUG) {
+            int g = av_gcd(enc->time_base.num, enc->time_base.den);
+            if (g)
+                snprintf(buf + strlen(buf), buf_size - strlen(buf),
+                         ", %d/%d",
+                         enc->time_base.num / g, enc->time_base.den / g);
+        }
+        break;
     default:
         return;
     }
@@ -2269,18 +2357,7 @@
 static void audio_free_buffers(AVCodecContext *avctx)
 {
     AVCodecInternal *avci = avctx->internal;
-    InternalBuffer *buf;
-
-    if (!avci->buffer)
-        return;
-    buf = avci->buffer;
-
-    if (buf->extended_data) {
-        av_free(buf->extended_data[0]);
-        if (buf->extended_data != buf->data)
-            av_freep(&buf->extended_data);
-    }
-    av_freep(&avci->buffer);
+    av_freep(&avci->audio_data);
 }
 
 void avcodec_default_free_buffers(AVCodecContext *avctx)
@@ -2408,6 +2485,7 @@
     case AV_CODEC_ID_ADPCM_IMA_QT: return   64;
     case AV_CODEC_ID_ADPCM_EA_XAS: return  128;
     case AV_CODEC_ID_AMR_NB:
+    case AV_CODEC_ID_EVRC:
     case AV_CODEC_ID_GSM:
     case AV_CODEC_ID_QCELP:
     case AV_CODEC_ID_RA_288:       return  160;
@@ -2645,6 +2723,36 @@
     return 0;
 }
 
+int ff_lock_avcodec(AVCodecContext *log_ctx)
+{
+    if (ff_lockmgr_cb) {
+        if ((*ff_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");
+        ff_avcodec_locked = 1;
+        ff_unlock_avcodec();
+        return AVERROR(EINVAL);
+    }
+    av_assert0(!ff_avcodec_locked);
+    ff_avcodec_locked = 1;
+    return 0;
+}
+
+int ff_unlock_avcodec(void)
+{
+    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))
+            return -1;
+    }
+    return 0;
+}
+
 int avpriv_lock_avformat(void)
 {
     if (ff_lockmgr_cb) {
@@ -2677,9 +2785,7 @@
 {
     f->owner = avctx;
 
-    ff_init_buffer_info(avctx, f);
-
-    return avctx->get_buffer(avctx, f);
+    return ff_get_buffer(avctx, f);
 }
 
 void ff_thread_release_buffer(AVCodecContext *avctx, AVFrame *f)
@@ -2730,3 +2836,21 @@
 {
     return !!s->internal;
 }
+
+int avpriv_bprint_to_extradata(AVCodecContext *avctx, struct AVBPrint *buf)
+{
+    int ret;
+    char *str;
+
+    ret = av_bprint_finalize(buf, &str);
+    if (ret < 0)
+        return ret;
+    avctx->extradata = str;
+    /* Note: the string is NUL terminated (so extradata can be read as a
+     * string), but the ending character is not accounted in the size (in
+     * binary formats you are likely not supposed to mux that character). When
+     * extradata is copied, it is also padded with FF_INPUT_BUFFER_PADDING_SIZE
+     * zeros. */
+    avctx->extradata_size = buf->len;
+    return 0;
+}
diff --git a/libavcodec/utvideodec.c b/libavcodec/utvideodec.c
index cfeb46b..259030a 100644
--- a/libavcodec/utvideodec.c
+++ b/libavcodec/utvideodec.c
@@ -320,7 +320,7 @@
     }
 }
 
-static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
@@ -463,7 +463,7 @@
     c->pic.pict_type = AV_PICTURE_TYPE_I;
     c->pic.interlaced_frame = !!c->interlaced;
 
-    *data_size = sizeof(AVFrame);
+    *got_frame      = 1;
     *(AVFrame*)data = c->pic;
 
     /* always report that the buffer was completely consumed */
diff --git a/libavcodec/utvideoenc.c b/libavcodec/utvideoenc.c
index 7167278..acb25c3 100644
--- a/libavcodec/utvideoenc.c
+++ b/libavcodec/utvideoenc.c
@@ -594,7 +594,6 @@
      * At least currently Ut Video is IDR only.
      * Set flags accordingly.
      */
-    avctx->coded_frame->reference = 0;
     avctx->coded_frame->key_frame = 1;
     avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
 
diff --git a/libavcodec/v210dec.c b/libavcodec/v210dec.c
index d508ce8..132b42a 100644
--- a/libavcodec/v210dec.c
+++ b/libavcodec/v210dec.c
@@ -22,6 +22,7 @@
  */
 
 #include "avcodec.h"
+#include "internal.h"
 #include "v210dec.h"
 #include "libavutil/bswap.h"
 #include "libavutil/internal.h"
@@ -54,7 +55,7 @@
 
     if (avctx->width & 1) {
         av_log(avctx, AV_LOG_ERROR, "v210 needs even width\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     avctx->pix_fmt             = AV_PIX_FMT_YUV422P10;
     avctx->bits_per_raw_sample = 10;
@@ -71,12 +72,12 @@
     return 0;
 }
 
-static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         AVPacket *avpkt)
 {
     V210DecContext *s = avctx->priv_data;
 
-    int h, w, stride, aligned_input;
+    int h, w, ret, stride, aligned_input;
     AVFrame *pic = avctx->coded_frame;
     const uint8_t *psrc = avpkt->data;
     uint16_t *y, *u, *v;
@@ -96,7 +97,7 @@
             s->stride_warning_shown = 1;
         } else {
             av_log(avctx, AV_LOG_ERROR, "packet too small\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
     }
 
@@ -111,8 +112,8 @@
         avctx->release_buffer(avctx, pic);
 
     pic->reference = 0;
-    if (avctx->get_buffer(avctx, pic) < 0)
-        return -1;
+    if ((ret = ff_get_buffer(avctx, pic)) < 0)
+        return ret;
 
     y = (uint16_t*)pic->data[0];
     u = (uint16_t*)pic->data[1];
@@ -153,7 +154,7 @@
         v += pic->linesize[2] / 2 - avctx->width / 2;
     }
 
-    *data_size = sizeof(AVFrame);
+    *got_frame      = 1;
     *(AVFrame*)data = *avctx->coded_frame;
 
     return avpkt->size;
diff --git a/libavcodec/v210x.c b/libavcodec/v210x.c
index 376588c..cb9fc6f 100644
--- a/libavcodec/v210x.c
+++ b/libavcodec/v210x.c
@@ -19,18 +19,19 @@
  */
 
 #include "avcodec.h"
+#include "internal.h"
 #include "libavutil/bswap.h"
 #include "libavutil/internal.h"
 #include "libavutil/mem.h"
 
 static av_cold int decode_init(AVCodecContext *avctx)
 {
-    if(avctx->width & 1){
+    if (avctx->width & 1) {
         av_log(avctx, AV_LOG_ERROR, "v210x needs even width\n");
-        return -1;
+        return AVERROR(EINVAL);
     }
-    avctx->pix_fmt = AV_PIX_FMT_YUV422P16;
-    avctx->bits_per_raw_sample= 10;
+    avctx->pix_fmt             = AV_PIX_FMT_YUV422P16;
+    avctx->bits_per_raw_sample = 10;
 
     avctx->coded_frame= avcodec_alloc_frame();
     if (!avctx->coded_frame)
@@ -39,88 +40,90 @@
     return 0;
 }
 
-static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt)
+static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
+                        AVPacket *avpkt)
 {
-    int y=0;
-    int width= avctx->width;
-    AVFrame *pic= avctx->coded_frame;
-    const uint32_t *src= (const uint32_t *)avpkt->data;
+    const uint32_t *src = (const uint32_t *)avpkt->data;
+    AVFrame *pic        = avctx->coded_frame;
+    int width           = avctx->width;
+    int y               = 0;
     uint16_t *ydst, *udst, *vdst, *yend;
+    int ret;
 
-    if(pic->data[0])
+    if (pic->data[0])
         avctx->release_buffer(avctx, pic);
 
-    if(avpkt->size < avctx->width * avctx->height * 8 / 3){
+    if (avpkt->size < avctx->width * avctx->height * 8 / 3) {
         av_log(avctx, AV_LOG_ERROR, "Packet too small\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
-    if(avpkt->size > avctx->width * avctx->height * 8 / 3){
+    if (avpkt->size > avctx->width * avctx->height * 8 / 3) {
         av_log_ask_for_sample(avctx, "Probably padded data\n");
     }
 
-    pic->reference= 0;
-    if(avctx->get_buffer(avctx, pic) < 0)
-        return -1;
+    pic->reference = 0;
+    if ((ret = ff_get_buffer(avctx, pic)) < 0)
+        return ret;
 
-    ydst= (uint16_t *)pic->data[0];
-    udst= (uint16_t *)pic->data[1];
-    vdst= (uint16_t *)pic->data[2];
-    yend= ydst + width;
-    pic->pict_type= AV_PICTURE_TYPE_I;
-    pic->key_frame= 1;
+    ydst = (uint16_t *)pic->data[0];
+    udst = (uint16_t *)pic->data[1];
+    vdst = (uint16_t *)pic->data[2];
+    yend = ydst + width;
+    pic->pict_type = AV_PICTURE_TYPE_I;
+    pic->key_frame = 1;
 
-    for(;;){
-        uint32_t v= av_be2ne32(*src++);
-        *udst++= (v>>16) & 0xFFC0;
-        *ydst++= (v>>6 ) & 0xFFC0;
-        *vdst++= (v<<4 ) & 0xFFC0;
+    for (;;) {
+        uint32_t v = av_be2ne32(*src++);
+        *udst++ = (v >> 16) & 0xFFC0;
+        *ydst++ = (v >> 6 ) & 0xFFC0;
+        *vdst++ = (v << 4 ) & 0xFFC0;
 
-        v= av_be2ne32(*src++);
-        *ydst++= (v>>16) & 0xFFC0;
+        v       = av_be2ne32(*src++);
+        *ydst++ = (v >> 16) & 0xFFC0;
 
-        if(ydst >= yend){
-            ydst+= pic->linesize[0]/2 - width;
-            udst+= pic->linesize[1]/2 - width/2;
-            vdst+= pic->linesize[2]/2 - width/2;
-            yend= ydst + width;
-            if(++y >= avctx->height)
+        if (ydst >= yend) {
+            ydst += pic->linesize[0] / 2 - width;
+            udst += pic->linesize[1] / 2 - width / 2;
+            vdst += pic->linesize[2] / 2 - width / 2;
+            yend = ydst + width;
+            if (++y >= avctx->height)
                 break;
         }
 
-        *udst++= (v>>6 ) & 0xFFC0;
-        *ydst++= (v<<4 ) & 0xFFC0;
+        *udst++ = (v >> 6 ) & 0xFFC0;
+        *ydst++ = (v << 4 ) & 0xFFC0;
 
-        v= av_be2ne32(*src++);
-        *vdst++= (v>>16) & 0xFFC0;
-        *ydst++= (v>>6 ) & 0xFFC0;
+        v = av_be2ne32(*src++);
+        *vdst++ = (v >> 16) & 0xFFC0;
+        *ydst++ = (v >> 6 ) & 0xFFC0;
 
-        if(ydst >= yend){
-            ydst+= pic->linesize[0]/2 - width;
-            udst+= pic->linesize[1]/2 - width/2;
-            vdst+= pic->linesize[2]/2 - width/2;
-            yend= ydst + width;
-            if(++y >= avctx->height)
+        if (ydst >= yend) {
+            ydst += pic->linesize[0] / 2 - width;
+            udst += pic->linesize[1] / 2 - width / 2;
+            vdst += pic->linesize[2] / 2 - width / 2;
+            yend  = ydst + width;
+            if (++y >= avctx->height)
                 break;
         }
 
-        *udst++= (v<<4 ) & 0xFFC0;
+        *udst++ = (v << 4 ) & 0xFFC0;
 
-        v= av_be2ne32(*src++);
-        *ydst++= (v>>16) & 0xFFC0;
-        *vdst++= (v>>6 ) & 0xFFC0;
-        *ydst++= (v<<4 ) & 0xFFC0;
-        if(ydst >= yend){
-            ydst+= pic->linesize[0]/2 - width;
-            udst+= pic->linesize[1]/2 - width/2;
-            vdst+= pic->linesize[2]/2 - width/2;
-            yend= ydst + width;
-            if(++y >= avctx->height)
+        v = av_be2ne32(*src++);
+        *ydst++ = (v >> 16) & 0xFFC0;
+        *vdst++ = (v >> 6 ) & 0xFFC0;
+        *ydst++ = (v << 4 ) & 0xFFC0;
+        if (ydst >= yend) {
+            ydst += pic->linesize[0] / 2 - width;
+            udst += pic->linesize[1] / 2 - width / 2;
+            vdst += pic->linesize[2] / 2 - width / 2;
+            yend  = ydst + width;
+            if (++y >= avctx->height)
                 break;
         }
     }
 
-    *data_size=sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*)data= *avctx->coded_frame;
 
     return avpkt->size;
diff --git a/libavcodec/v308dec.c b/libavcodec/v308dec.c
index fd742ca..b5567f8 100644
--- a/libavcodec/v308dec.c
+++ b/libavcodec/v308dec.c
@@ -20,6 +20,7 @@
  */
 
 #include "avcodec.h"
+#include "internal.h"
 
 static av_cold int v308_decode_init(AVCodecContext *avctx)
 {
@@ -39,7 +40,7 @@
 }
 
 static int v308_decode_frame(AVCodecContext *avctx, void *data,
-                             int *data_size, AVPacket *avpkt)
+                             int *got_frame, AVPacket *avpkt)
 {
     AVFrame *pic = avctx->coded_frame;
     const uint8_t *src = avpkt->data;
@@ -56,7 +57,7 @@
 
     pic->reference = 0;
 
-    if (avctx->get_buffer(avctx, pic) < 0) {
+    if (ff_get_buffer(avctx, pic) < 0) {
         av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
         return AVERROR(ENOMEM);
     }
@@ -80,7 +81,7 @@
         v += pic->linesize[2];
     }
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame *)data = *pic;
 
     return avpkt->size;
diff --git a/libavcodec/v408dec.c b/libavcodec/v408dec.c
index 8820fc4c..470853d 100644
--- a/libavcodec/v408dec.c
+++ b/libavcodec/v408dec.c
@@ -20,6 +20,7 @@
  */
 
 #include "avcodec.h"
+#include "internal.h"
 
 static av_cold int v408_decode_init(AVCodecContext *avctx)
 {
@@ -36,7 +37,7 @@
 }
 
 static int v408_decode_frame(AVCodecContext *avctx, void *data,
-                             int *data_size, AVPacket *avpkt)
+                             int *got_frame, AVPacket *avpkt)
 {
     AVFrame *pic = avctx->coded_frame;
     const uint8_t *src = avpkt->data;
@@ -53,7 +54,7 @@
 
     pic->reference = 0;
 
-    if (avctx->get_buffer(avctx, pic) < 0) {
+    if (ff_get_buffer(avctx, pic) < 0) {
         av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
         return AVERROR(ENOMEM);
     }
@@ -87,7 +88,7 @@
         a += pic->linesize[3];
     }
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame *)data = *pic;
 
     return avpkt->size;
diff --git a/libavcodec/v410dec.c b/libavcodec/v410dec.c
index 4d4d625..ff23817 100644
--- a/libavcodec/v410dec.c
+++ b/libavcodec/v410dec.c
@@ -23,6 +23,7 @@
 #include "libavutil/common.h"
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
+#include "internal.h"
 
 static av_cold int v410_decode_init(AVCodecContext *avctx)
 {
@@ -49,7 +50,7 @@
 }
 
 static int v410_decode_frame(AVCodecContext *avctx, void *data,
-                             int *data_size, AVPacket *avpkt)
+                             int *got_frame, AVPacket *avpkt)
 {
     AVFrame *pic = avctx->coded_frame;
     uint8_t *src = avpkt->data;
@@ -67,7 +68,7 @@
 
     pic->reference = 0;
 
-    if (avctx->get_buffer(avctx, pic) < 0) {
+    if (ff_get_buffer(avctx, pic) < 0) {
         av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
         return AVERROR(ENOMEM);
     }
@@ -95,7 +96,7 @@
         v += pic->linesize[2] >> 1;
     }
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame *)data = *pic;
 
     return avpkt->size;
diff --git a/libavcodec/v410enc.c b/libavcodec/v410enc.c
index 67d8fc9..9661c7c 100644
--- a/libavcodec/v410enc.c
+++ b/libavcodec/v410enc.c
@@ -54,7 +54,6 @@
         return ret;
     dst = pkt->data;
 
-    avctx->coded_frame->reference = 0;
     avctx->coded_frame->key_frame = 1;
     avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
 
diff --git a/libavcodec/vaapi.c b/libavcodec/vaapi.c
index 774fde8..fc869bd 100644
--- a/libavcodec/vaapi.c
+++ b/libavcodec/vaapi.c
@@ -21,6 +21,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "h264.h"
 #include "vaapi_internal.h"
 
 /**
@@ -40,7 +41,7 @@
     }
 }
 
-static int render_picture(struct vaapi_context *vactx, VASurfaceID surface)
+int ff_vaapi_render_picture(struct vaapi_context *vactx, VASurfaceID surface)
 {
     VABufferID va_buffers[3];
     unsigned int n_va_buffers = 0;
@@ -77,7 +78,7 @@
     return 0;
 }
 
-static int commit_slices(struct vaapi_context *vactx)
+int ff_vaapi_commit_slices(struct vaapi_context *vactx)
 {
     VABufferID *slice_buf_ids;
     VABufferID slice_param_buf_id, slice_data_buf_id;
@@ -152,7 +153,7 @@
     if (!vactx->slice_data)
         vactx->slice_data = buffer;
     if (vactx->slice_data + vactx->slice_data_size != buffer) {
-        if (commit_slices(vactx) < 0)
+        if (ff_vaapi_commit_slices(vactx) < 0)
             return NULL;
         vactx->slice_data = buffer;
     }
@@ -175,23 +176,12 @@
     return slice_param;
 }
 
-int ff_vaapi_common_end_frame(MpegEncContext *s)
+void ff_vaapi_common_end_frame(AVCodecContext *avctx)
 {
-    struct vaapi_context * const vactx = s->avctx->hwaccel_context;
-    int ret = -1;
+    struct vaapi_context * const vactx = avctx->hwaccel_context;
 
-    av_dlog(s->avctx, "ff_vaapi_common_end_frame()\n");
+    av_dlog(avctx, "ff_vaapi_common_end_frame()\n");
 
-    if (commit_slices(vactx) < 0)
-        goto done;
-    if (vactx->n_slice_buf_ids > 0) {
-        if (render_picture(vactx, ff_vaapi_get_surface_id(s->current_picture_ptr)) < 0)
-            goto done;
-        ff_draw_horiz_band(s, 0, s->avctx->height);
-    }
-    ret = 0;
-
-done:
     destroy_buffers(vactx->display, &vactx->pic_param_buf_id, 1);
     destroy_buffers(vactx->display, &vactx->iq_matrix_buf_id, 1);
     destroy_buffers(vactx->display, &vactx->bitplane_buf_id, 1);
@@ -202,6 +192,27 @@
     vactx->slice_buf_ids_alloc = 0;
     vactx->slice_count         = 0;
     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->priv_data);
     return ret;
 }
 
diff --git a/libavcodec/vaapi_h264.c b/libavcodec/vaapi_h264.c
index 9be51bf..78ae315 100644
--- a/libavcodec/vaapi_h264.c
+++ b/libavcodec/vaapi_h264.c
@@ -224,7 +224,6 @@
                        av_unused uint32_t       size)
 {
     H264Context * const h = avctx->priv_data;
-    MpegEncContext * const s = &h->s;
     struct vaapi_context * const vactx = avctx->hwaccel_context;
     VAPictureParameterBufferH264 *pic_param;
     VAIQMatrixBufferH264 *iq_matrix;
@@ -237,11 +236,11 @@
     pic_param = ff_vaapi_alloc_pic_param(vactx, sizeof(VAPictureParameterBufferH264));
     if (!pic_param)
         return -1;
-    fill_vaapi_pic(&pic_param->CurrPic, s->current_picture_ptr, s->picture_structure);
+    fill_vaapi_pic(&pic_param->CurrPic, h->cur_pic_ptr, h->picture_structure);
     if (fill_vaapi_ReferenceFrames(pic_param, h) < 0)
         return -1;
-    pic_param->picture_width_in_mbs_minus1                      = s->mb_width - 1;
-    pic_param->picture_height_in_mbs_minus1                     = s->mb_height - 1;
+    pic_param->picture_width_in_mbs_minus1                      = h->mb_width - 1;
+    pic_param->picture_height_in_mbs_minus1                     = h->mb_height - 1;
     pic_param->bit_depth_luma_minus8                            = h->sps.bit_depth_luma - 8;
     pic_param->bit_depth_chroma_minus8                          = h->sps.bit_depth_chroma - 8;
     pic_param->num_ref_frames                                   = h->sps.ref_frame_count;
@@ -269,7 +268,7 @@
     pic_param->pic_fields.bits.weighted_pred_flag               = h->pps.weighted_pred;
     pic_param->pic_fields.bits.weighted_bipred_idc              = h->pps.weighted_bipred_idc;
     pic_param->pic_fields.bits.transform_8x8_mode_flag          = h->pps.transform_8x8_mode;
-    pic_param->pic_fields.bits.field_pic_flag                   = s->picture_structure != PICT_FRAME;
+    pic_param->pic_fields.bits.field_pic_flag                   = h->picture_structure != PICT_FRAME;
     pic_param->pic_fields.bits.constrained_intra_pred_flag      = h->pps.constrained_intra_pred;
     pic_param->pic_fields.bits.pic_order_present_flag           = h->pps.pic_order_present;
     pic_param->pic_fields.bits.deblocking_filter_control_present_flag = h->pps.deblocking_filter_parameters_present;
@@ -290,10 +289,24 @@
 /** End a hardware decoding based frame. */
 static int end_frame(AVCodecContext *avctx)
 {
+    struct vaapi_context * const vactx = avctx->hwaccel_context;
     H264Context * const h = avctx->priv_data;
+    int ret;
 
     av_dlog(avctx, "end_frame()\n");
-    return ff_vaapi_common_end_frame(&h->s);
+    ret = ff_vaapi_commit_slices(vactx);
+    if (ret < 0)
+        goto finish;
+
+    ret = ff_vaapi_render_picture(vactx, ff_vaapi_get_surface_id(h->cur_pic_ptr));
+    if (ret < 0)
+        goto finish;
+
+    ff_h264_draw_horiz_band(h, 0, h->avctx->height);
+
+finish:
+    ff_vaapi_common_end_frame(avctx);
+    return ret;
 }
 
 /** Decode the given H.264 slice with VA API. */
@@ -302,7 +315,6 @@
                         uint32_t        size)
 {
     H264Context * const h = avctx->priv_data;
-    MpegEncContext * const s = &h->s;
     VASliceParameterBufferH264 *slice_param;
 
     av_dlog(avctx, "decode_slice(): buffer %p, size %d\n", buffer, size);
@@ -311,14 +323,14 @@
     slice_param = (VASliceParameterBufferH264 *)ff_vaapi_alloc_slice(avctx->hwaccel_context, buffer, size);
     if (!slice_param)
         return -1;
-    slice_param->slice_data_bit_offset          = get_bits_count(&h->s.gb) + 8; /* bit buffer started beyond nal_unit_type */
-    slice_param->first_mb_in_slice              = (s->mb_y >> FIELD_OR_MBAFF_PICTURE) * s->mb_width + s->mb_x;
+    slice_param->slice_data_bit_offset          = get_bits_count(&h->gb) + 8; /* bit buffer started beyond nal_unit_type */
+    slice_param->first_mb_in_slice              = (h->mb_y >> FIELD_OR_MBAFF_PICTURE) * h->mb_width + h->mb_x;
     slice_param->slice_type                     = ff_h264_get_slice_type(h);
     slice_param->direct_spatial_mv_pred_flag    = h->slice_type == AV_PICTURE_TYPE_B ? h->direct_spatial_mv_pred : 0;
     slice_param->num_ref_idx_l0_active_minus1   = h->list_count > 0 ? h->ref_count[0] - 1 : 0;
     slice_param->num_ref_idx_l1_active_minus1   = h->list_count > 1 ? h->ref_count[1] - 1 : 0;
     slice_param->cabac_init_idc                 = h->cabac_init_idc;
-    slice_param->slice_qp_delta                 = s->qscale - h->pps.init_qp;
+    slice_param->slice_qp_delta                 = h->qscale - h->pps.init_qp;
     slice_param->disable_deblocking_filter_idc  = h->deblocking_filter < 2 ? !h->deblocking_filter : h->deblocking_filter;
     slice_param->slice_alpha_c0_offset_div2     = h->slice_alpha_c0_offset / 2 - 26;
     slice_param->slice_beta_offset_div2         = h->slice_beta_offset     / 2 - 26;
diff --git a/libavcodec/vaapi_internal.h b/libavcodec/vaapi_internal.h
index e514dd6..1ac0e9f 100644
--- a/libavcodec/vaapi_internal.h
+++ b/libavcodec/vaapi_internal.h
@@ -42,7 +42,7 @@
 }
 
 /** Common AVHWAccel.end_frame() implementation */
-int ff_vaapi_common_end_frame(MpegEncContext *s);
+void ff_vaapi_common_end_frame(AVCodecContext *avctx);
 
 /** Allocate a new picture parameter buffer */
 void *ff_vaapi_alloc_pic_param(struct vaapi_context *vactx, unsigned int size);
@@ -63,6 +63,10 @@
  */
 VASliceParameterBufferBase *ff_vaapi_alloc_slice(struct vaapi_context *vactx, const uint8_t *buffer, uint32_t size);
 
+int ff_vaapi_mpeg_end_frame(AVCodecContext *avctx);
+int ff_vaapi_commit_slices(struct vaapi_context *vactx);
+int ff_vaapi_render_picture(struct vaapi_context *vactx, VASurfaceID surface);
+
 /* @} */
 
 #endif /* AVCODEC_VAAPI_INTERNAL_H */
diff --git a/libavcodec/vaapi_mpeg2.c b/libavcodec/vaapi_mpeg2.c
index 50ba06d..d626f24 100644
--- a/libavcodec/vaapi_mpeg2.c
+++ b/libavcodec/vaapi_mpeg2.c
@@ -21,7 +21,6 @@
  */
 
 #include "vaapi_internal.h"
-#include "dsputil.h"
 
 /** Reconstruct bitstream f_code */
 static inline int mpeg2_get_f_code(MpegEncContext *s)
@@ -99,11 +98,6 @@
     return 0;
 }
 
-static int vaapi_mpeg2_end_frame(AVCodecContext *avctx)
-{
-    return ff_vaapi_common_end_frame(avctx->priv_data);
-}
-
 static int vaapi_mpeg2_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
 {
     MpegEncContext * const s = avctx->priv_data;
@@ -144,6 +138,6 @@
     .id             = AV_CODEC_ID_MPEG2VIDEO,
     .pix_fmt        = AV_PIX_FMT_VAAPI_VLD,
     .start_frame    = vaapi_mpeg2_start_frame,
-    .end_frame      = vaapi_mpeg2_end_frame,
+    .end_frame      = ff_vaapi_mpeg_end_frame,
     .decode_slice   = vaapi_mpeg2_decode_slice,
 };
diff --git a/libavcodec/vaapi_mpeg4.c b/libavcodec/vaapi_mpeg4.c
index 3178740..bcc0eba 100644
--- a/libavcodec/vaapi_mpeg4.c
+++ b/libavcodec/vaapi_mpeg4.c
@@ -115,11 +115,6 @@
     return 0;
 }
 
-static int vaapi_mpeg4_end_frame(AVCodecContext *avctx)
-{
-    return ff_vaapi_common_end_frame(avctx->priv_data);
-}
-
 static int vaapi_mpeg4_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
 {
     MpegEncContext * const s = avctx->priv_data;
@@ -156,7 +151,7 @@
     .id             = AV_CODEC_ID_MPEG4,
     .pix_fmt        = AV_PIX_FMT_VAAPI_VLD,
     .start_frame    = vaapi_mpeg4_start_frame,
-    .end_frame      = vaapi_mpeg4_end_frame,
+    .end_frame      = ff_vaapi_mpeg_end_frame,
     .decode_slice   = vaapi_mpeg4_decode_slice,
 };
 #endif
@@ -168,7 +163,7 @@
     .id             = AV_CODEC_ID_H263,
     .pix_fmt        = AV_PIX_FMT_VAAPI_VLD,
     .start_frame    = vaapi_mpeg4_start_frame,
-    .end_frame      = vaapi_mpeg4_end_frame,
+    .end_frame      = ff_vaapi_mpeg_end_frame,
     .decode_slice   = vaapi_mpeg4_decode_slice,
 };
 #endif
diff --git a/libavcodec/vaapi_vc1.c b/libavcodec/vaapi_vc1.c
index af01e51..b8f0530 100644
--- a/libavcodec/vaapi_vc1.c
+++ b/libavcodec/vaapi_vc1.c
@@ -310,13 +310,6 @@
     return 0;
 }
 
-static int vaapi_vc1_end_frame(AVCodecContext *avctx)
-{
-    VC1Context * const v = avctx->priv_data;
-
-    return ff_vaapi_common_end_frame(&v->s);
-}
-
 static int vaapi_vc1_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
 {
     VC1Context * const v = avctx->priv_data;
@@ -347,7 +340,7 @@
     .id             = AV_CODEC_ID_WMV3,
     .pix_fmt        = AV_PIX_FMT_VAAPI_VLD,
     .start_frame    = vaapi_vc1_start_frame,
-    .end_frame      = vaapi_vc1_end_frame,
+    .end_frame      = ff_vaapi_mpeg_end_frame,
     .decode_slice   = vaapi_vc1_decode_slice,
 };
 #endif
@@ -358,6 +351,6 @@
     .id             = AV_CODEC_ID_VC1,
     .pix_fmt        = AV_PIX_FMT_VAAPI_VLD,
     .start_frame    = vaapi_vc1_start_frame,
-    .end_frame      = vaapi_vc1_end_frame,
+    .end_frame      = ff_vaapi_mpeg_end_frame,
     .decode_slice   = vaapi_vc1_decode_slice,
 };
diff --git a/libavcodec/vb.c b/libavcodec/vb.c
index 5129458..3b5a83b 100644
--- a/libavcodec/vb.c
+++ b/libavcodec/vb.c
@@ -29,8 +29,9 @@
 
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 
-enum VBFlags{
+enum VBFlags {
     VB_HAS_GMC     = 0x01,
     VB_HAS_AUDIO   = 0x04,
     VB_HAS_VIDEO   = 0x08,
@@ -63,16 +64,16 @@
     int start, size, i;
 
     start = bytestream2_get_byte(&c->stream);
-    size = (bytestream2_get_byte(&c->stream) - 1) & 0xFF;
-    if(start + size > 255){
+    size  = (bytestream2_get_byte(&c->stream) - 1) & 0xFF;
+    if (start + size > 255) {
         av_log(c->avctx, AV_LOG_ERROR, "Palette change runs beyond entry 256\n");
         return;
     }
-    if(size*3+2 > data_size){
+    if (size*3+2 > data_size) {
         av_log(c->avctx, AV_LOG_ERROR, "Palette data runs beyond chunk size\n");
         return;
     }
-    for(i = start; i <= start + size; i++)
+    for (i = start; i <= start + size; i++)
         c->pal[i] = 0xFFU << 24 | bytestream2_get_be24(&c->stream);
 }
 
@@ -96,42 +97,42 @@
     int pattype, pattern;
     const int width = c->avctx->width;
     uint8_t *pstart = c->prev_frame;
-    uint8_t *pend = c->prev_frame + width*c->avctx->height;
+    uint8_t *pend   = c->prev_frame + width*c->avctx->height;
 
     g = c->stream;
 
     prev = c->prev_frame + offset;
-    cur = c->frame;
+    cur  = c->frame;
 
     blocks = (c->avctx->width >> 2) * (c->avctx->height >> 2);
-    blk2 = 0;
-    for(blk = 0; blk < blocks; blk++){
-        if(!(blk & 3)) {
+    blk2   = 0;
+    for (blk = 0; blk < blocks; blk++) {
+        if (!(blk & 3)) {
             blocktypes = bytestream2_get_byte(&g);
         }
-        switch(blocktypes & 0xC0){
+        switch (blocktypes & 0xC0) {
         case 0x00: //skip
-            for(y = 0; y < 4; y++)
-                if(check_line(prev + y*width, pstart, pend))
+            for (y = 0; y < 4; y++)
+                if (check_line(prev + y*width, pstart, pend))
                     memcpy(cur + y*width, prev + y*width, 4);
                 else
                     memset(cur + y*width, 0, 4);
             break;
         case 0x40:
             t = bytestream2_get_byte(&g);
-            if(!t){ //raw block
+            if (!t) { //raw block
                 if (bytestream2_get_bytes_left(&g) < 16) {
                     av_log(c->avctx, AV_LOG_ERROR, "Insufficient data\n");
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 }
-                for(y = 0; y < 4; y++)
+                for (y = 0; y < 4; y++)
                     bytestream2_get_buffer(&g, cur + y * width, 4);
-            }else{ // motion compensation
+            } else { // motion compensation
                 x = ((t & 0xF)^8) - 8;
                 y = ((t >> 4) ^8) - 8;
                 t = x + y*width;
-                for(y = 0; y < 4; y++)
-                    if(check_line(prev + t + y*width, pstart, pend))
+                for (y = 0; y < 4; y++)
+                    if (check_line(prev + t + y*width, pstart, pend))
                         memcpy(cur + y*width, prev + t + y*width, 4);
                     else
                         memset(cur + y*width, 0, 4);
@@ -139,35 +140,35 @@
             break;
         case 0x80: // fill
             t = bytestream2_get_byte(&g);
-            for(y = 0; y < 4; y++)
+            for (y = 0; y < 4; y++)
                 memset(cur + y*width, t, 4);
             break;
         case 0xC0: // pattern fill
-            t = bytestream2_get_byte(&g);
+            t       = bytestream2_get_byte(&g);
             pattype = t >> 6;
             pattern = vb_patterns[t & 0x3F];
-            switch(pattype){
+            switch (pattype) {
             case 0:
                 a = bytestream2_get_byte(&g);
                 b = bytestream2_get_byte(&g);
-                for(y = 0; y < 4; y++)
-                    for(x = 0; x < 4; x++, pattern >>= 1)
+                for (y = 0; y < 4; y++)
+                    for (x = 0; x < 4; x++, pattern >>= 1)
                         cur[x + y*width] = (pattern & 1) ? b : a;
                 break;
             case 1:
                 pattern = ~pattern;
             case 2:
                 a = bytestream2_get_byte(&g);
-                for(y = 0; y < 4; y++)
-                    for(x = 0; x < 4; x++, pattern >>= 1)
-                        if(pattern & 1 && check_pixel(prev + x + y*width, pstart, pend))
+                for (y = 0; y < 4; y++)
+                    for (x = 0; x < 4; x++, pattern >>= 1)
+                        if (pattern & 1 && check_pixel(prev + x + y*width, pstart, pend))
                             cur[x + y*width] = prev[x + y*width];
                         else
                             cur[x + y*width] = a;
                 break;
             case 3:
-                av_log(c->avctx, AV_LOG_ERROR, "Invalid opcode seen @%d\n",blk);
-                return -1;
+                av_log(c->avctx, AV_LOG_ERROR, "Invalid opcode seen @%d\n", blk);
+                return AVERROR_INVALIDDATA;
             }
             break;
         }
@@ -175,8 +176,8 @@
         cur  += 4;
         prev += 4;
         blk2++;
-        if(blk2 == (width >> 2)){
-            blk2 = 0;
+        if (blk2 == (width >> 2)) {
+            blk2  = 0;
             cur  += width * 3;
             prev += width * 3;
         }
@@ -184,33 +185,34 @@
     return 0;
 }
 
-static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt)
+static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
+                        AVPacket *avpkt)
 {
     VBDecContext * const c = avctx->priv_data;
     uint8_t *outptr, *srcptr;
-    int i, j;
+    int i, j, ret;
     int flags;
     uint32_t size;
     int offset = 0;
 
     bytestream2_init(&c->stream, avpkt->data, avpkt->size);
 
-    if(c->pic.data[0])
+    if (c->pic.data[0])
         avctx->release_buffer(avctx, &c->pic);
     c->pic.reference = 3;
-    if(avctx->get_buffer(avctx, &c->pic) < 0){
+    if ((ret = ff_get_buffer(avctx, &c->pic)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     flags = bytestream2_get_le16(&c->stream);
 
-    if(flags & VB_HAS_GMC){
+    if (flags & VB_HAS_GMC) {
         i = (int16_t)bytestream2_get_le16(&c->stream);
         j = (int16_t)bytestream2_get_le16(&c->stream);
         offset = i + j * avctx->width;
     }
-    if(flags & VB_HAS_VIDEO){
+    if (flags & VB_HAS_VIDEO) {
         size = bytestream2_get_le32(&c->stream);
         if(size > bytestream2_get_bytes_left(&c->stream)+4 || size<4){
             av_log(avctx, AV_LOG_ERROR, "Frame size invalid\n");
@@ -219,7 +221,7 @@
         vb_decode_framedata(c, offset);
         bytestream2_skip(&c->stream, size - 4);
     }
-    if(flags & VB_HAS_PALETTE){
+    if (flags & VB_HAS_PALETTE) {
         size = bytestream2_get_le32(&c->stream);
         vb_decode_palette(c, size);
     }
@@ -230,7 +232,7 @@
     outptr = c->pic.data[0];
     srcptr = c->frame;
 
-    for(i = 0; i < avctx->height; i++){
+    for (i = 0; i < avctx->height; i++) {
         memcpy(outptr, srcptr, avctx->width);
         srcptr += avctx->width;
         outptr += c->pic.linesize[0];
@@ -238,7 +240,7 @@
 
     FFSWAP(uint8_t*, c->frame, c->prev_frame);
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*)data = c->pic;
 
     /* always report that the buffer was completely consumed */
@@ -249,7 +251,7 @@
 {
     VBDecContext * const c = avctx->priv_data;
 
-    c->avctx = avctx;
+    c->avctx       = avctx;
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
     avcodec_get_frame_defaults(&c->pic);
 
diff --git a/libavcodec/vble.c b/libavcodec/vble.c
index 2c68178..c8037bd 100644
--- a/libavcodec/vble.c
+++ b/libavcodec/vble.c
@@ -29,6 +29,7 @@
 #include "avcodec.h"
 #include "dsputil.h"
 #include "get_bits.h"
+#include "internal.h"
 #include "mathops.h"
 
 typedef struct {
@@ -110,7 +111,7 @@
     }
 }
 
-static int vble_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+static int vble_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                              AVPacket *avpkt)
 {
     VBLEContext *ctx = avctx->priv_data;
@@ -133,7 +134,7 @@
     }
 
     /* Allocate buffer */
-    if (avctx->get_buffer(avctx, pic) < 0) {
+    if (ff_get_buffer(avctx, pic) < 0) {
         av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
         return AVERROR(ENOMEM);
     }
@@ -168,7 +169,7 @@
         vble_restore_plane(ctx, &gb, 2, offset, width_uv, height_uv);
     }
 
-    *data_size = sizeof(AVFrame);
+    *got_frame       = 1;
     *(AVFrame *)data = *pic;
 
     return avpkt->size;
diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c
index fa0b916..a6a7bac 100644
--- a/libavcodec/vc1.c
+++ b/libavcodec/vc1.c
@@ -28,7 +28,6 @@
  */
 
 #include "internal.h"
-#include "dsputil.h"
 #include "avcodec.h"
 #include "mpegvideo.h"
 #include "vc1.h"
diff --git a/libavcodec/vc1.h b/libavcodec/vc1.h
index 4ed8923..596d4d3 100644
--- a/libavcodec/vc1.h
+++ b/libavcodec/vc1.h
@@ -24,6 +24,7 @@
 #define AVCODEC_VC1_H
 
 #include "avcodec.h"
+#include "h264chroma.h"
 #include "mpegvideo.h"
 #include "intrax8.h"
 #include "vc1dsp.h"
@@ -181,6 +182,7 @@
 typedef struct VC1Context{
     MpegEncContext s;
     IntraX8Context x8;
+    H264ChromaContext h264chroma;
     VC1DSPContext vc1dsp;
 
     int bits;
@@ -384,7 +386,7 @@
     int bi_type;
     int x8_type;
 
-    DCTELEM (*block)[6][64];
+    int16_t (*block)[6][64];
     int n_allocated_blks, cur_blk_idx, left_blk_idx, topleft_blk_idx, top_blk_idx;
     uint32_t *cbp_base, *cbp;
     uint8_t *is_intra_base, *is_intra;
@@ -452,9 +454,9 @@
 int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext *gb);
 int ff_vc1_init_common(VC1Context *v);
 
-av_cold int  ff_vc1_decode_init_alloc_tables(VC1Context *v);
-av_cold void ff_vc1_init_transposed_scantables(VC1Context *v);
-av_cold int  ff_vc1_decode_end(AVCodecContext *avctx);
+int  ff_vc1_decode_init_alloc_tables(VC1Context *v);
+void ff_vc1_init_transposed_scantables(VC1Context *v);
+int  ff_vc1_decode_end(AVCodecContext *avctx);
 void ff_vc1_decode_blocks(VC1Context *v);
 
 #endif /* AVCODEC_VC1_H */
diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c
index f5c5329..585918c 100644
--- a/libavcodec/vc1dec.c
+++ b/libavcodec/vc1dec.c
@@ -27,10 +27,10 @@
  */
 
 #include "internal.h"
-#include "dsputil.h"
 #include "avcodec.h"
 #include "mpegvideo.h"
 #include "h263.h"
+#include "h264chroma.h"
 #include "vc1.h"
 #include "vc1data.h"
 #include "vc1acdata.h"
@@ -73,6 +73,17 @@
 };
 /** @} */ //imode defines
 
+static void init_block_index(VC1Context *v)
+{
+    MpegEncContext *s = &v->s;
+    ff_init_block_index(s);
+    if (v->field_mode && v->second_field) {
+        s->dest[0] += s->current_picture_ptr->f.linesize[0];
+        s->dest[1] += s->current_picture_ptr->f.linesize[1];
+        s->dest[2] += s->current_picture_ptr->f.linesize[2];
+    }
+}
+
 
 /** @} */ //Bitplane group
 
@@ -80,7 +91,7 @@
 {
     MpegEncContext *s = &v->s;
     int topleft_mb_pos, top_mb_pos;
-    int stride_y, fieldtx;
+    int stride_y, fieldtx = 0;
     int v_dist;
 
     /* The put pixels loop is always one MB row behind the decoding loop,
@@ -93,7 +104,8 @@
     if (!s->first_slice_line) {
         if (s->mb_x) {
             topleft_mb_pos = (s->mb_y - 1) * s->mb_stride + s->mb_x - 1;
-            fieldtx        = v->fieldtx_plane[topleft_mb_pos];
+            if (v->fcm == ILACE_FRAME)
+                fieldtx = v->fieldtx_plane[topleft_mb_pos];
             stride_y       = s->linesize << fieldtx;
             v_dist         = (16 - fieldtx) >> (fieldtx == 0);
             s->dsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][0],
@@ -117,7 +129,8 @@
         }
         if (s->mb_x == s->mb_width - 1) {
             top_mb_pos = (s->mb_y - 1) * s->mb_stride + s->mb_x;
-            fieldtx    = v->fieldtx_plane[top_mb_pos];
+            if (v->fcm == ILACE_FRAME)
+                fieldtx = v->fieldtx_plane[top_mb_pos];
             stride_y   = s->linesize << fieldtx;
             v_dist     = fieldtx ? 15 : 8;
             s->dsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][0],
@@ -332,6 +345,7 @@
 {
     MpegEncContext *s = &v->s;
     DSPContext *dsp   = &v->s.dsp;
+    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;
@@ -438,15 +452,15 @@
         uint8_t *uvbuf = s->edge_emu_buffer + 19 * s->linesize;
 
         srcY -= s->mspel * (1 + s->linesize);
-        s->dsp.emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize,
-                                17 + s->mspel * 2, 17 + s->mspel * 2,
-                                src_x - s->mspel, src_y - s->mspel,
-                                s->h_edge_pos, v_edge_pos);
+        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize,
+                                 17 + s->mspel * 2, 17 + s->mspel * 2,
+                                 src_x - s->mspel, src_y - s->mspel,
+                                 s->h_edge_pos, v_edge_pos);
         srcY = s->edge_emu_buffer;
-        s->dsp.emulated_edge_mc(uvbuf     , srcU, s->uvlinesize, 8 + 1, 8 + 1,
-                                uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos >> 1);
-        s->dsp.emulated_edge_mc(uvbuf + 16, srcV, s->uvlinesize, 8 + 1, 8 + 1,
-                                uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos >> 1);
+        s->vdsp.emulated_edge_mc(uvbuf     , srcU, s->uvlinesize, 8 + 1, 8 + 1,
+                                 uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos >> 1);
+        s->vdsp.emulated_edge_mc(uvbuf + 16, srcV, s->uvlinesize, 8 + 1, 8 + 1,
+                                 uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos >> 1);
         srcU = uvbuf;
         srcV = uvbuf + 16;
         /* if we deal with range reduction we need to scale source blocks */
@@ -496,13 +510,8 @@
         srcY += s->mspel * (1 + s->linesize);
     }
 
-    if (v->field_mode && v->second_field) {
-        off    = s->current_picture_ptr->f.linesize[0];
-        off_uv = s->current_picture_ptr->f.linesize[1];
-    } else {
         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);
@@ -523,8 +532,8 @@
     uvmx = (uvmx & 3) << 1;
     uvmy = (uvmy & 3) << 1;
     if (!v->rnd) {
-        dsp->put_h264_chroma_pixels_tab[0](s->dest[1] + off_uv, srcU, s->uvlinesize, 8, uvmx, uvmy);
-        dsp->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] + 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);
     } 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);
@@ -638,8 +647,6 @@
         off = ((n > 1) ? s->linesize : 0) + (n & 1) * 8;
     else
         off = s->linesize * 4 * (n & 2) + (n & 1) * 8;
-    if (v->field_mode && v->second_field)
-        off += s->current_picture_ptr->f.linesize[0];
 
     src_x = s->mb_x * 16 + (n & 1) * 8 + (mx >> 2);
     if (!fieldmv)
@@ -676,10 +683,10 @@
         || (unsigned)(src_y - (s->mspel << fieldmv)) > v_edge_pos - (my & 3) - ((8 + s->mspel * 2) << fieldmv)) {
         srcY -= s->mspel * (1 + (s->linesize << fieldmv));
         /* check emulate edge stride and offset */
-        s->dsp.emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize,
-                                9 + s->mspel * 2, (9 + s->mspel * 2) << fieldmv,
-                                src_x - s->mspel, src_y - (s->mspel << fieldmv),
-                                s->h_edge_pos, v_edge_pos);
+        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize,
+                                 9 + s->mspel * 2, (9 + s->mspel * 2) << fieldmv,
+                                 src_x - s->mspel, src_y - (s->mspel << fieldmv),
+                                 s->h_edge_pos, v_edge_pos);
         srcY = s->edge_emu_buffer;
         /* if we deal with range reduction we need to scale source blocks */
         if (v->rangeredfrm) {
@@ -778,7 +785,7 @@
 static void vc1_mc_4mv_chroma(VC1Context *v, int dir)
 {
     MpegEncContext *s = &v->s;
-    DSPContext *dsp   = &v->s.dsp;
+    H264ChromaContext *h264chroma = &v->h264chroma;
     uint8_t *srcU, *srcV;
     int uvmx, uvmy, uvsrc_x, uvsrc_y;
     int k, tx = 0, ty = 0;
@@ -876,19 +883,19 @@
             srcU += s->current_picture_ptr->f.linesize[1];
             srcV += s->current_picture_ptr->f.linesize[2];
         }
-        off = v->second_field ? s->current_picture_ptr->f.linesize[1] : 0;
+        off = 0;
     }
 
     if (v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP)
         || s->h_edge_pos < 18 || v_edge_pos < 18
         || (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 9
         || (unsigned)uvsrc_y > (v_edge_pos    >> 1) - 9) {
-        s->dsp.emulated_edge_mc(s->edge_emu_buffer     , srcU, s->uvlinesize,
-                                8 + 1, 8 + 1, uvsrc_x, uvsrc_y,
-                                s->h_edge_pos >> 1, v_edge_pos >> 1);
-        s->dsp.emulated_edge_mc(s->edge_emu_buffer + 16, srcV, s->uvlinesize,
-                                8 + 1, 8 + 1, uvsrc_x, uvsrc_y,
-                                s->h_edge_pos >> 1, v_edge_pos >> 1);
+        s->vdsp.emulated_edge_mc(s->edge_emu_buffer     , srcU, s->uvlinesize,
+                                 8 + 1, 8 + 1, uvsrc_x, uvsrc_y,
+                                 s->h_edge_pos >> 1, v_edge_pos >> 1);
+        s->vdsp.emulated_edge_mc(s->edge_emu_buffer + 16, srcV, s->uvlinesize,
+                                 8 + 1, 8 + 1, uvsrc_x, uvsrc_y,
+                                 s->h_edge_pos >> 1, v_edge_pos >> 1);
         srcU = s->edge_emu_buffer;
         srcV = s->edge_emu_buffer + 16;
 
@@ -930,8 +937,8 @@
     uvmx = (uvmx & 3) << 1;
     uvmy = (uvmy & 3) << 1;
     if (!v->rnd) {
-        dsp->put_h264_chroma_pixels_tab[0](s->dest[1] + off, srcU, s->uvlinesize, 8, uvmx, uvmy);
-        dsp->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] + off, srcU, s->uvlinesize, 8, uvmx, uvmy);
+        h264chroma->put_h264_chroma_pixels_tab[0](s->dest[2] + off, 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);
@@ -943,7 +950,7 @@
 static void vc1_mc_4mv_chroma4(VC1Context *v)
 {
     MpegEncContext *s = &v->s;
-    DSPContext *dsp = &v->s.dsp;
+    H264ChromaContext *h264chroma = &v->h264chroma;
     uint8_t *srcU, *srcV;
     int uvsrc_x, uvsrc_y;
     int uvmx_field[4], uvmy_field[4];
@@ -981,19 +988,20 @@
         uvmy_field[i] = (uvmy_field[i] & 3) << 1;
 
         if (fieldmv && !(uvsrc_y & 1))
-            v_edge_pos--;
+            v_edge_pos = (s->v_edge_pos >> 1) - 1;
+
         if (fieldmv && (uvsrc_y & 1) && uvsrc_y < 2)
             uvsrc_y--;
         if ((v->mv_mode == MV_PMODE_INTENSITY_COMP)
             || 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)) {
-            s->dsp.emulated_edge_mc(s->edge_emu_buffer, srcU, s->uvlinesize,
-                                    5, (5 << fieldmv), uvsrc_x, uvsrc_y,
-                                    s->h_edge_pos >> 1, v_edge_pos);
-            s->dsp.emulated_edge_mc(s->edge_emu_buffer + 16, srcV, s->uvlinesize,
-                                    5, (5 << fieldmv), uvsrc_x, uvsrc_y,
-                                    s->h_edge_pos >> 1, v_edge_pos);
+            s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcU, s->uvlinesize,
+                                     5, (5 << fieldmv), uvsrc_x, uvsrc_y,
+                                     s->h_edge_pos >> 1, v_edge_pos);
+            s->vdsp.emulated_edge_mc(s->edge_emu_buffer + 16, srcV, s->uvlinesize,
+                                     5, (5 << fieldmv), uvsrc_x, uvsrc_y,
+                                     s->h_edge_pos >> 1, v_edge_pos);
             srcU = s->edge_emu_buffer;
             srcV = s->edge_emu_buffer + 16;
 
@@ -1015,8 +1023,8 @@
             }
         }
         if (!v->rnd) {
-            dsp->put_h264_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
-            dsp->put_h264_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
+            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]);
@@ -1148,8 +1156,12 @@
         *dmv_x = get_bits(gb, v->k_x);
         *dmv_y = get_bits(gb, v->k_y);
         if (v->numref) {
-            *pred_flag = *dmv_y & 1;
-            *dmv_y     = (*dmv_y + *pred_flag) >> 1;
+            if (pred_flag) {
+                *pred_flag = *dmv_y & 1;
+                *dmv_y     = (*dmv_y + *pred_flag) >> 1;
+            } else {
+                *dmv_y     = (*dmv_y + (*dmv_y & 1)) >> 1;
+            }
         }
     }
     else {
@@ -1176,7 +1188,7 @@
             *dmv_y = (sign ^ ((val >> 1) + offs_tab[index1 >> v->numref])) - sign;
         } else
             *dmv_y = 0;
-        if (v->numref)
+        if (v->numref && pred_flag)
             *pred_flag = index1 & 1;
     }
 }
@@ -1750,9 +1762,10 @@
                 px = mid_pred(A[0], B[0], C[0]);
                 py = mid_pred(A[1], B[1], C[1]);
             } else if (total_valid) {
-                if (a_valid) { px = A[0]; py = A[1]; }
-                if (b_valid) { px = B[0]; py = B[1]; }
-                if (c_valid) { px = C[0]; py = C[1]; }
+                if      (a_valid) { px = A[0]; py = A[1]; }
+                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;
         }
@@ -1840,6 +1853,7 @@
 {
     MpegEncContext *s = &v->s;
     DSPContext *dsp = &v->s.dsp;
+    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;
@@ -1904,15 +1918,15 @@
         uint8_t *uvbuf = s->edge_emu_buffer + 19 * s->linesize;
 
         srcY -= s->mspel * (1 + s->linesize);
-        s->dsp.emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize,
-                                17 + s->mspel * 2, 17 + s->mspel * 2,
-                                src_x - s->mspel, src_y - s->mspel,
-                                s->h_edge_pos, v_edge_pos);
+        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize,
+                                 17 + s->mspel * 2, 17 + s->mspel * 2,
+                                 src_x - s->mspel, src_y - s->mspel,
+                                 s->h_edge_pos, v_edge_pos);
         srcY = s->edge_emu_buffer;
-        s->dsp.emulated_edge_mc(uvbuf     , srcU, s->uvlinesize, 8 + 1, 8 + 1,
-                                uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos >> 1);
-        s->dsp.emulated_edge_mc(uvbuf + 16, srcV, s->uvlinesize, 8 + 1, 8 + 1,
-                                uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos >> 1);
+        s->vdsp.emulated_edge_mc(uvbuf     , srcU, s->uvlinesize, 8 + 1, 8 + 1,
+                                 uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos >> 1);
+        s->vdsp.emulated_edge_mc(uvbuf + 16, srcV, s->uvlinesize, 8 + 1, 8 + 1,
+                                 uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos >> 1);
         srcU = uvbuf;
         srcV = uvbuf + 16;
         /* if we deal with range reduction we need to scale source blocks */
@@ -1940,13 +1954,8 @@
         srcY += s->mspel * (1 + s->linesize);
     }
 
-    if (v->field_mode && v->second_field) {
-        off    = s->current_picture_ptr->f.linesize[0];
-        off_uv = s->current_picture_ptr->f.linesize[1];
-    } else {
         off    = 0;
         off_uv = 0;
-    }
 
     if (s->mspel) {
         dxy = ((my & 3) << 2) | (mx & 3);
@@ -1961,7 +1970,7 @@
         if (!v->rnd)
             dsp->avg_pixels_tab[0][dxy](s->dest[0] + off, srcY, s->linesize, 16);
         else
-            dsp->avg_no_rnd_pixels_tab[0][dxy](s->dest[0] + off, srcY, s->linesize, 16);
+            dsp->avg_no_rnd_pixels_tab[dxy](s->dest[0] + off, srcY, s->linesize, 16);
     }
 
     if (s->flags & CODEC_FLAG_GRAY) return;
@@ -1969,8 +1978,8 @@
     uvmx = (uvmx & 3) << 1;
     uvmy = (uvmy & 3) << 1;
     if (!v->rnd) {
-        dsp->avg_h264_chroma_pixels_tab[0](s->dest[1] + off_uv, srcU, s->uvlinesize, 8, uvmx, uvmy);
-        dsp->avg_h264_chroma_pixels_tab[0](s->dest[2] + off_uv, srcV, s->uvlinesize, 8, uvmx, uvmy);
+        h264chroma->avg_h264_chroma_pixels_tab[0](s->dest[1] + off_uv, srcU, s->uvlinesize, 8, uvmx, uvmy);
+        h264chroma->avg_h264_chroma_pixels_tab[0](s->dest[2] + off_uv, srcV, s->uvlinesize, 8, uvmx, uvmy);
     } else {
         v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1] + off_uv, srcU, s->uvlinesize, 8, uvmx, uvmy);
         v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2] + off_uv, srcV, s->uvlinesize, 8, uvmx, uvmy);
@@ -2550,7 +2559,7 @@
  * @param coded are AC coeffs present or not
  * @param codingset set of VLC to decode data
  */
-static int vc1_decode_i_block(VC1Context *v, DCTELEM block[64], int n,
+static int vc1_decode_i_block(VC1Context *v, int16_t block[64], int n,
                               int coded, int codingset)
 {
     GetBitContext *gb = &v->s.gb;
@@ -2713,14 +2722,14 @@
  * @param codingset set of VLC to decode data
  * @param mquant quantizer value for this macroblock
  */
-static int vc1_decode_i_block_adv(VC1Context *v, DCTELEM block[64], int n,
+static int vc1_decode_i_block_adv(VC1Context *v, int16_t block[64], int n,
                                   int coded, int codingset, int mquant)
 {
     GetBitContext *gb = &v->s.gb;
     MpegEncContext *s = &v->s;
     int dc_pred_dir = 0; /* Direction of the DC prediction used */
     int i;
-    int16_t *dc_val;
+    int16_t *dc_val = NULL;
     int16_t *ac_val, *ac_val2;
     int dcdiff;
     int a_avail = v->a_avail, c_avail = v->c_avail;
@@ -2925,14 +2934,14 @@
  * @param mquant block quantizer
  * @param codingset set of VLC to decode data
  */
-static int vc1_decode_intra_block(VC1Context *v, DCTELEM block[64], int n,
+static int vc1_decode_intra_block(VC1Context *v, int16_t block[64], int n,
                                   int coded, int mquant, int codingset)
 {
     GetBitContext *gb = &v->s.gb;
     MpegEncContext *s = &v->s;
     int dc_pred_dir = 0; /* Direction of the DC prediction used */
     int i;
-    int16_t *dc_val;
+    int16_t *dc_val = NULL;
     int16_t *ac_val, *ac_val2;
     int dcdiff;
     int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
@@ -3135,7 +3144,7 @@
 
 /** Decode P block
  */
-static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n,
+static int vc1_decode_p_block(VC1Context *v, int16_t block[64], int n,
                               int mquant, int ttmb, int first_block,
                               uint8_t *dst, int linesize, int skip_block,
                               int *ttmb_out)
@@ -3950,7 +3959,6 @@
                 continue;
             v->vc1dsp.vc1_inv_trans_8x8(s->block[i]);
             off  = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
-            off += v->second_field ? ((i & 4) ? s->current_picture_ptr->f.linesize[1] : s->current_picture_ptr->f.linesize[0]) : 0;
             s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off, (i & 4) ? s->uvlinesize : s->linesize);
             // TODO: loop filter
         }
@@ -3997,8 +4005,6 @@
             dst_idx += i >> 2;
             val = ((cbp >> (5 - i)) & 1);
             off = (i & 4) ? 0 : (i & 1) * 8 + (i & 2) * 4 * s->linesize;
-            if (v->second_field)
-                off += (i & 4) ? s->current_picture_ptr->f.linesize[1] : s->current_picture_ptr->f.linesize[0];
             if (val) {
                 pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb,
                                          first_block, s->dest[dst_idx] + off,
@@ -4227,7 +4233,6 @@
                 for (j = 0; j < 64; j++)
                     s->block[i][j] <<= 1;
             off  = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
-            off += v->second_field ? ((i & 4) ? s->current_picture_ptr->f.linesize[1] : s->current_picture_ptr->f.linesize[0]) : 0;
             s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off, (i & 4) ? s->uvlinesize : s->linesize);
             // TODO: yet to perform loop filter
         }
@@ -4309,8 +4314,6 @@
             dst_idx += i >> 2;
             val = ((cbp >> (5 - i)) & 1);
             off = (i & 4) ? 0 : (i & 1) * 8 + (i & 2) * 4 * s->linesize;
-            if (v->second_field)
-                off += (i & 4) ? s->current_picture_ptr->f.linesize[1] : s->current_picture_ptr->f.linesize[0];
             if (val) {
                 vc1_decode_p_block(v, s->block[i], i, mquant, ttmb,
                                    first_block, s->dest[dst_idx] + off,
@@ -4369,7 +4372,7 @@
     s->first_slice_line = 1;
     for (s->mb_y = 0; s->mb_y < s->end_mb_y; s->mb_y++) {
         s->mb_x = 0;
-        ff_init_block_index(s);
+        init_block_index(v);
         for (; s->mb_x < v->end_mb_x; s->mb_x++) {
             uint8_t *dst[6];
             ff_update_block_index(s);
@@ -4443,25 +4446,25 @@
             if (v->s.loop_filter) vc1_loop_filter_iblk(v, v->pq);
 
             if (get_bits_count(&s->gb) > v->bits) {
-                ff_er_add_slice(s, 0, 0, s->mb_x, s->mb_y, ER_MB_ERROR);
+                ff_er_add_slice(&s->er, 0, 0, s->mb_x, s->mb_y, ER_MB_ERROR);
                 av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i\n",
                        get_bits_count(&s->gb), v->bits);
                 return;
             }
         }
         if (!v->s.loop_filter)
-            ff_draw_horiz_band(s, s->mb_y * 16, 16);
+            ff_mpeg_draw_horiz_band(s, s->mb_y * 16, 16);
         else if (s->mb_y)
-            ff_draw_horiz_band(s, (s->mb_y - 1) * 16, 16);
+            ff_mpeg_draw_horiz_band(s, (s->mb_y - 1) * 16, 16);
 
         s->first_slice_line = 0;
     }
     if (v->s.loop_filter)
-        ff_draw_horiz_band(s, (s->end_mb_y - 1) * 16, 16);
+        ff_mpeg_draw_horiz_band(s, (s->end_mb_y - 1) * 16, 16);
 
     /* This is intentionally mb_height and not end_mb_y - unlike in advanced
      * profile, these only differ are when decoding MSS2 rectangles. */
-    ff_er_add_slice(s, 0, 0, s->mb_width - 1, s->mb_height - 1, ER_MB_END);
+    ff_er_add_slice(&s->er, 0, 0, s->mb_width - 1, s->mb_height - 1, ER_MB_END);
 }
 
 /** Decode blocks of I-frame for advanced profile
@@ -4509,15 +4512,15 @@
     s->mb_y             = s->start_mb_y;
     if (s->start_mb_y) {
         s->mb_x = 0;
-        ff_init_block_index(s);
+        init_block_index(v);
         memset(&s->coded_block[s->block_index[0] - s->b8_stride], 0,
                (1 + s->b8_stride) * sizeof(*s->coded_block));
     }
     for (; s->mb_y < s->end_mb_y; s->mb_y++) {
         s->mb_x = 0;
-        ff_init_block_index(s);
+        init_block_index(v);
         for (;s->mb_x < s->mb_width; s->mb_x++) {
-            DCTELEM (*block)[64] = v->block[v->cur_blk_idx];
+            int16_t (*block)[64] = v->block[v->cur_blk_idx];
             ff_update_block_index(s);
             s->dsp.clear_blocks(block[0]);
             mb_pos = s->mb_x + s->mb_y * s->mb_stride;
@@ -4571,22 +4574,23 @@
 
             if (get_bits_count(&s->gb) > v->bits) {
                 // TODO: may need modification to handle slice coding
-                ff_er_add_slice(s, 0, s->start_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR);
+                ff_er_add_slice(&s->er, 0, s->start_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR);
                 av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i\n",
                        get_bits_count(&s->gb), v->bits);
                 return;
             }
         }
         if (!v->s.loop_filter)
-            ff_draw_horiz_band(s, s->mb_y * 16, 16);
+            ff_mpeg_draw_horiz_band(s, s->mb_y * 16, 16);
         else if (s->mb_y)
-            ff_draw_horiz_band(s, (s->mb_y-1) * 16, 16);
+            ff_mpeg_draw_horiz_band(s, (s->mb_y-1) * 16, 16);
         s->first_slice_line = 0;
     }
 
     /* raw bottom MB row */
     s->mb_x = 0;
-    ff_init_block_index(s);
+    init_block_index(v);
+
     for (;s->mb_x < s->mb_width; s->mb_x++) {
         ff_update_block_index(s);
         vc1_put_signed_blocks_clamped(v);
@@ -4594,8 +4598,8 @@
             vc1_loop_filter_iblk_delayed(v, v->pq);
     }
     if (v->s.loop_filter)
-        ff_draw_horiz_band(s, (s->end_mb_y-1)*16, 16);
-    ff_er_add_slice(s, 0, s->start_mb_y << v->field_mode, s->mb_width - 1,
+        ff_mpeg_draw_horiz_band(s, (s->end_mb_y-1)*16, 16);
+    ff_er_add_slice(&s->er, 0, s->start_mb_y << v->field_mode, s->mb_width - 1,
                     (s->end_mb_y << v->field_mode) - 1, ER_MB_END);
 }
 
@@ -4634,7 +4638,7 @@
     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++) {
         s->mb_x = 0;
-        ff_init_block_index(s);
+        init_block_index(v);
         for (; s->mb_x < s->mb_width; s->mb_x++) {
             ff_update_block_index(s);
 
@@ -4647,7 +4651,7 @@
                 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
-                ff_er_add_slice(s, 0, s->start_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR);
+                ff_er_add_slice(&s->er, 0, s->start_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR);
                 av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i at %ix%i\n",
                        get_bits_count(&s->gb), v->bits, s->mb_x, s->mb_y);
                 return;
@@ -4657,20 +4661,20 @@
         memmove(v->ttblk_base,    v->ttblk,    sizeof(v->ttblk_base[0])    * s->mb_stride);
         memmove(v->is_intra_base, v->is_intra, sizeof(v->is_intra_base[0]) * s->mb_stride);
         memmove(v->luma_mv_base,  v->luma_mv,  sizeof(v->luma_mv_base[0])  * s->mb_stride);
-        if (s->mb_y != s->start_mb_y) ff_draw_horiz_band(s, (s->mb_y - 1) * 16, 16);
+        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) {
         s->mb_x = 0;
-        ff_init_block_index(s);
+        init_block_index(v);
         for (; s->mb_x < s->mb_width; s->mb_x++) {
             ff_update_block_index(s);
             vc1_apply_p_loop_filter(v);
         }
     }
     if (s->end_mb_y >= s->start_mb_y)
-        ff_draw_horiz_band(s, (s->end_mb_y - 1) * 16, 16);
-    ff_er_add_slice(s, 0, s->start_mb_y << v->field_mode, s->mb_width - 1,
+        ff_mpeg_draw_horiz_band(s, (s->end_mb_y - 1) * 16, 16);
+    ff_er_add_slice(&s->er, 0, s->start_mb_y << v->field_mode, s->mb_width - 1,
                     (s->end_mb_y << v->field_mode) - 1, ER_MB_END);
 }
 
@@ -4706,7 +4710,7 @@
     s->first_slice_line = 1;
     for (s->mb_y = s->start_mb_y; s->mb_y < s->end_mb_y; s->mb_y++) {
         s->mb_x = 0;
-        ff_init_block_index(s);
+        init_block_index(v);
         for (; s->mb_x < s->mb_width; s->mb_x++) {
             ff_update_block_index(s);
 
@@ -4716,7 +4720,7 @@
                 vc1_decode_b_mb(v);
             if (get_bits_count(&s->gb) > v->bits || get_bits_count(&s->gb) < 0) {
                 // TODO: may need modification to handle slice coding
-                ff_er_add_slice(s, 0, s->start_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR);
+                ff_er_add_slice(&s->er, 0, s->start_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR);
                 av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i at %ix%i\n",
                        get_bits_count(&s->gb), v->bits, s->mb_x, s->mb_y);
                 return;
@@ -4724,14 +4728,14 @@
             if (v->s.loop_filter) vc1_loop_filter_iblk(v, v->pq);
         }
         if (!v->s.loop_filter)
-            ff_draw_horiz_band(s, s->mb_y * 16, 16);
+            ff_mpeg_draw_horiz_band(s, s->mb_y * 16, 16);
         else if (s->mb_y)
-            ff_draw_horiz_band(s, (s->mb_y - 1) * 16, 16);
+            ff_mpeg_draw_horiz_band(s, (s->mb_y - 1) * 16, 16);
         s->first_slice_line = 0;
     }
     if (v->s.loop_filter)
-        ff_draw_horiz_band(s, (s->end_mb_y - 1) * 16, 16);
-    ff_er_add_slice(s, 0, s->start_mb_y << v->field_mode, s->mb_width - 1,
+        ff_mpeg_draw_horiz_band(s, (s->end_mb_y - 1) * 16, 16);
+    ff_er_add_slice(&s->er, 0, s->start_mb_y << v->field_mode, s->mb_width - 1,
                     (s->end_mb_y << v->field_mode) - 1, ER_MB_END);
 }
 
@@ -4739,16 +4743,18 @@
 {
     MpegEncContext *s = &v->s;
 
-    ff_er_add_slice(s, 0, s->start_mb_y, s->mb_width - 1, s->end_mb_y - 1, ER_MB_END);
+    ff_er_add_slice(&s->er, 0, s->start_mb_y, s->mb_width - 1, s->end_mb_y - 1, ER_MB_END);
     s->first_slice_line = 1;
     for (s->mb_y = s->start_mb_y; s->mb_y < s->end_mb_y; s->mb_y++) {
         s->mb_x = 0;
-        ff_init_block_index(s);
+        init_block_index(v);
         ff_update_block_index(s);
-        memcpy(s->dest[0], s->last_picture.f.data[0] + s->mb_y * 16 * s->linesize,   s->linesize   * 16);
-        memcpy(s->dest[1], s->last_picture.f.data[1] + s->mb_y *  8 * s->uvlinesize, s->uvlinesize *  8);
-        memcpy(s->dest[2], s->last_picture.f.data[2] + s->mb_y *  8 * s->uvlinesize, s->uvlinesize *  8);
-        ff_draw_horiz_band(s, s->mb_y * 16, 16);
+        if (s->last_picture.f.data[0]) {
+            memcpy(s->dest[0], s->last_picture.f.data[0] + s->mb_y * 16 * s->linesize,   s->linesize   * 16);
+            memcpy(s->dest[1], s->last_picture.f.data[1] + s->mb_y *  8 * s->uvlinesize, s->uvlinesize *  8);
+            memcpy(s->dest[2], s->last_picture.f.data[2] + s->mb_y *  8 * s->uvlinesize, s->uvlinesize *  8);
+        }
+        ff_mpeg_draw_horiz_band(s, s->mb_y * 16, 16);
         s->first_slice_line = 0;
     }
     s->pict_type = AV_PICTURE_TYPE_P;
@@ -5038,7 +5044,7 @@
 
     v->sprite_output_frame.buffer_hints = FF_BUFFER_HINTS_VALID;
     v->sprite_output_frame.reference = 0;
-    if (avctx->get_buffer(avctx, &v->sprite_output_frame) < 0) {
+    if (ff_get_buffer(avctx, &v->sprite_output_frame) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return -1;
     }
@@ -5174,10 +5180,6 @@
     avctx->flags |= CODEC_FLAG_EMU_EDGE;
     v->s.flags   |= CODEC_FLAG_EMU_EDGE;
 
-    if (avctx->idct_algo == FF_IDCT_AUTO) {
-        avctx->idct_algo = FF_IDCT_WMV2;
-    }
-
     if (ff_vc1_init_common(v) < 0)
         return -1;
     // ensure static VLC tables are initialized
@@ -5189,6 +5191,8 @@
     // again once we know all necessary settings.
     // That this is necessary might indicate a bug.
     ff_vc1_decode_end(avctx);
+
+    ff_h264chroma_init(&v->h264chroma, 8);
     ff_vc1dsp_init(&v->vc1dsp);
 
     if (avctx->codec_id == AV_CODEC_ID_WMV3 || avctx->codec_id == AV_CODEC_ID_WMV3IMAGE) {
@@ -5256,7 +5260,7 @@
             av_log(avctx, AV_LOG_ERROR, "Incomplete extradata\n");
             return -1;
         }
-        v->res_sprite = (avctx->codec_tag == MKTAG('W','V','P','2'));
+        v->res_sprite = (avctx->codec_id == AV_CODEC_ID_VC1IMAGE);
     }
 
     avctx->profile = v->profile;
@@ -5333,7 +5337,7 @@
  * @todo TODO: Handle VC-1 IDUs (Transport level?)
  */
 static int vc1_decode_frame(AVCodecContext *avctx, void *data,
-                            int *data_size, AVPacket *avpkt)
+                            int *got_frame, AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size, n_slices = 0, i;
@@ -5361,7 +5365,7 @@
             *pict = s->next_picture_ptr->f;
             s->next_picture_ptr = NULL;
 
-            *data_size = sizeof(AVFrame);
+            *got_frame = 1;
         }
 
         return buf_size;
@@ -5568,7 +5572,7 @@
     s->current_picture.f.key_frame = s->pict_type == AV_PICTURE_TYPE_I;
 
     /* skip B-frames if we don't have reference frames */
-    if (s->last_picture_ptr == NULL && (s->pict_type == AV_PICTURE_TYPE_B || s->dropable)) {
+    if (s->last_picture_ptr == NULL && (s->pict_type == AV_PICTURE_TYPE_B || s->droppable)) {
         goto err;
     }
     if ((avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type == AV_PICTURE_TYPE_B) ||
@@ -5635,10 +5639,12 @@
                 goto err;
         }
     } else {
+        int header_ret = 0;
+
         if (v->fcm == ILACE_FRAME && s->pict_type == AV_PICTURE_TYPE_B)
             goto err; // This codepath is still incomplete thus it is disabled
 
-        ff_er_frame_start(s);
+        ff_mpeg_er_frame_start(s);
 
         v->bits = buf_size * 8;
         v->end_mb_x = s->mb_width;
@@ -5668,7 +5674,7 @@
                     continue;
                 }
                 v->second_field = 1;
-                v->blocks_off   = s->mb_width  * s->mb_height << 1;
+                v->blocks_off   = s->b8_stride * (s->mb_height&~1);
                 v->mb_off       = s->mb_stride * s->mb_height >> 1;
             } else {
                 v->second_field = 0;
@@ -5678,18 +5684,20 @@
             if (i) {
                 v->pic_header_flag = 0;
                 if (v->field_mode && i == n_slices1 + 2) {
-                    if (ff_vc1_parse_frame_header_adv(v, &s->gb) < 0) {
+                    if ((header_ret = ff_vc1_parse_frame_header_adv(v, &s->gb)) < 0) {
                         av_log(v->s.avctx, AV_LOG_ERROR, "Field header damaged\n");
                         continue;
                     }
                 } else if (get_bits1(&s->gb)) {
                     v->pic_header_flag = 1;
-                    if (ff_vc1_parse_frame_header_adv(v, &s->gb) < 0) {
+                    if ((header_ret = ff_vc1_parse_frame_header_adv(v, &s->gb)) < 0) {
                         av_log(v->s.avctx, AV_LOG_ERROR, "Slice header damaged\n");
                         continue;
                     }
                 }
             }
+            if (header_ret < 0)
+                continue;
             s->start_mb_y = (i == 0) ? 0 : FFMAX(0, slices[i-1].mby_start % mb_height);
             if (!v->field_mode || v->second_field)
                 s->end_mb_y = (i == n_slices     ) ? mb_height : FFMIN(mb_height, slices[i].mby_start % mb_height);
@@ -5704,6 +5712,10 @@
                 av_log(v->s.avctx, AV_LOG_ERROR, "end mb y %d %d invalid\n", s->end_mb_y, s->start_mb_y);
                 continue;
             }
+            if (!v->p_frame_skipped && s->pict_type != AV_PICTURE_TYPE_I && !v->cbpcy_vlc) {
+                av_log(v->s.avctx, AV_LOG_ERROR, "missing cbpcy_vlc\n");
+                continue;
+            }
             ff_vc1_decode_blocks(v);
             if (i != n_slices)
                 s->gb = slices[i].gb;
@@ -5724,10 +5736,10 @@
                 get_bits_count(&s->gb), s->gb.size_in_bits);
 //  if (get_bits_count(&s->gb) > buf_size * 8)
 //      return -1;
-        if(s->error_occurred && s->pict_type == AV_PICTURE_TYPE_B)
+        if(s->er.error_occurred && s->pict_type == AV_PICTURE_TYPE_B)
             goto err;
         if(!v->field_mode)
-            ff_er_frame_end(s);
+            ff_er_frame_end(&s->er);
     }
 
     ff_MPV_frame_end(s);
@@ -5743,7 +5755,7 @@
             goto err;
 #endif
         *pict      = v->sprite_output_frame;
-        *data_size = sizeof(AVFrame);
+        *got_frame = 1;
     } else {
         if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {
             *pict = s->current_picture_ptr->f;
@@ -5751,7 +5763,7 @@
             *pict = s->last_picture_ptr->f;
         }
         if (s->last_picture_ptr || s->low_delay) {
-            *data_size = sizeof(AVFrame);
+            *got_frame = 1;
             ff_print_debug_info(s, pict);
         }
     }
@@ -5780,6 +5792,20 @@
     { FF_PROFILE_UNKNOWN },
 };
 
+static const enum AVPixelFormat vc1_hwaccel_pixfmt_list_420[] = {
+#if CONFIG_DXVA2
+    AV_PIX_FMT_DXVA2_VLD,
+#endif
+#if CONFIG_VAAPI
+    AV_PIX_FMT_VAAPI_VLD,
+#endif
+#if CONFIG_VDPAU
+    AV_PIX_FMT_VDPAU,
+#endif
+    AV_PIX_FMT_YUV420P,
+    AV_PIX_FMT_NONE
+};
+
 AVCodec ff_vc1_decoder = {
     .name           = "vc1",
     .type           = AVMEDIA_TYPE_VIDEO,
@@ -5791,7 +5817,7 @@
     .flush          = ff_mpeg_flush,
     .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_DELAY,
     .long_name      = NULL_IF_CONFIG_SMALL("SMPTE VC-1"),
-    .pix_fmts       = ff_hwaccel_pixfmt_list_420,
+    .pix_fmts       = vc1_hwaccel_pixfmt_list_420,
     .profiles       = NULL_IF_CONFIG_SMALL(profiles)
 };
 
@@ -5807,7 +5833,7 @@
     .flush          = ff_mpeg_flush,
     .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_DELAY,
     .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Video 9"),
-    .pix_fmts       = ff_hwaccel_pixfmt_list_420,
+    .pix_fmts       = vc1_hwaccel_pixfmt_list_420,
     .profiles       = NULL_IF_CONFIG_SMALL(profiles)
 };
 #endif
diff --git a/libavcodec/vc1dsp.c b/libavcodec/vc1dsp.c
index a874509..260eda4 100644
--- a/libavcodec/vc1dsp.c
+++ b/libavcodec/vc1dsp.c
@@ -25,9 +25,11 @@
  *
  */
 
-#include "vc1dsp.h"
 #include "libavutil/avassert.h"
 #include "libavutil/common.h"
+#include "h264chroma.h"
+#include "rnd_avg.h"
+#include "vc1dsp.h"
 
 
 /** Apply overlap transform to horizontal edge
@@ -80,7 +82,7 @@
     }
 }
 
-static void vc1_v_s_overlap_c(DCTELEM *top,  DCTELEM *bottom)
+static void vc1_v_s_overlap_c(int16_t *top,  int16_t *bottom)
 {
     int i;
     int a, b, c, d;
@@ -106,7 +108,7 @@
     }
 }
 
-static void vc1_h_s_overlap_c(DCTELEM *left, DCTELEM *right)
+static void vc1_h_s_overlap_c(int16_t *left, int16_t *right)
 {
     int i;
     int a, b, c, d;
@@ -230,7 +232,7 @@
 
 /** Do inverse transform on 8x8 block
 */
-static void vc1_inv_trans_8x8_dc_c(uint8_t *dest, int linesize, DCTELEM *block)
+static void vc1_inv_trans_8x8_dc_c(uint8_t *dest, int linesize, int16_t *block)
 {
     int i;
     int dc = block[0];
@@ -249,11 +251,11 @@
     }
 }
 
-static void vc1_inv_trans_8x8_c(DCTELEM block[64])
+static void vc1_inv_trans_8x8_c(int16_t block[64])
 {
     int i;
     register int t1,t2,t3,t4,t5,t6,t7,t8;
-    DCTELEM *src, *dst, temp[64];
+    int16_t *src, *dst, temp[64];
 
     src = block;
     dst = temp;
@@ -320,7 +322,7 @@
 
 /** Do inverse transform on 8x4 part of block
 */
-static void vc1_inv_trans_8x4_dc_c(uint8_t *dest, int linesize, DCTELEM *block)
+static void vc1_inv_trans_8x4_dc_c(uint8_t *dest, int linesize, int16_t *block)
 {
     int i;
     int dc = block[0];
@@ -339,11 +341,11 @@
     }
 }
 
-static void vc1_inv_trans_8x4_c(uint8_t *dest, int linesize, DCTELEM *block)
+static void vc1_inv_trans_8x4_c(uint8_t *dest, int linesize, int16_t *block)
 {
     int i;
     register int t1,t2,t3,t4,t5,t6,t7,t8;
-    DCTELEM *src, *dst;
+    int16_t *src, *dst;
 
     src = block;
     dst = block;
@@ -395,7 +397,7 @@
 
 /** Do inverse transform on 4x8 parts of block
 */
-static void vc1_inv_trans_4x8_dc_c(uint8_t *dest, int linesize, DCTELEM *block)
+static void vc1_inv_trans_4x8_dc_c(uint8_t *dest, int linesize, int16_t *block)
 {
     int i;
     int dc = block[0];
@@ -410,11 +412,11 @@
     }
 }
 
-static void vc1_inv_trans_4x8_c(uint8_t *dest, int linesize, DCTELEM *block)
+static void vc1_inv_trans_4x8_c(uint8_t *dest, int linesize, int16_t *block)
 {
     int i;
     register int t1,t2,t3,t4,t5,t6,t7,t8;
-    DCTELEM *src, *dst;
+    int16_t *src, *dst;
 
     src = block;
     dst = block;
@@ -466,7 +468,7 @@
 
 /** Do inverse transform on 4x4 part of block
 */
-static void vc1_inv_trans_4x4_dc_c(uint8_t *dest, int linesize, DCTELEM *block)
+static void vc1_inv_trans_4x4_dc_c(uint8_t *dest, int linesize, int16_t *block)
 {
     int i;
     int dc = block[0];
@@ -481,11 +483,11 @@
     }
 }
 
-static void vc1_inv_trans_4x4_c(uint8_t *dest, int linesize, DCTELEM *block)
+static void vc1_inv_trans_4x4_c(uint8_t *dest, int linesize, int16_t *block)
 {
     int i;
     register int t1,t2,t3,t4;
-    DCTELEM *src, *dst;
+    int16_t *src, *dst;
 
     src = block;
     dst = block;
@@ -562,7 +564,7 @@
 
 /** Function used to do motion compensation with bicubic interpolation
  */
-#define VC1_MSPEL_MC(OP, OPNAME)\
+#define VC1_MSPEL_MC(OP, OP4, OPNAME)\
 static av_always_inline void OPNAME ## vc1_mspel_mc(uint8_t *dst, const uint8_t *src, int stride, int hmode, int vmode, int rnd)\
 {\
     int     i, j;\
@@ -616,13 +618,24 @@
         dst += stride;\
         src += stride;\
     }\
+}\
+static void OPNAME ## pixels8x8_c(uint8_t *block, const uint8_t *pixels, int line_size, int rnd){\
+    int i;\
+    for(i=0; i<8; i++){\
+        OP4(*(uint32_t*)(block  ), AV_RN32(pixels  ));\
+        OP4(*(uint32_t*)(block+4), AV_RN32(pixels+4));\
+        pixels+=line_size;\
+        block +=line_size;\
+    }\
 }
 
 #define op_put(a, b) a = av_clip_uint8(b)
 #define op_avg(a, b) a = (a + av_clip_uint8(b) + 1) >> 1
+#define op4_avg(a, b) a = rnd_avg32(a, b)
+#define op4_put(a, b) a = b
 
-VC1_MSPEL_MC(op_put, put_)
-VC1_MSPEL_MC(op_avg, avg_)
+VC1_MSPEL_MC(op_put, op4_put, put_)
+VC1_MSPEL_MC(op_avg, op4_avg, avg_)
 
 /* pixel functions - really are entry points to vc1_mspel_mc */
 
@@ -802,7 +815,7 @@
     dsp->vc1_v_loop_filter16 = vc1_v_loop_filter16_c;
     dsp->vc1_h_loop_filter16 = vc1_h_loop_filter16_c;
 
-    dsp->put_vc1_mspel_pixels_tab[ 0] = ff_put_pixels8x8_c;
+    dsp->put_vc1_mspel_pixels_tab[ 0] = put_pixels8x8_c;
     dsp->put_vc1_mspel_pixels_tab[ 1] = put_vc1_mspel_mc10_c;
     dsp->put_vc1_mspel_pixels_tab[ 2] = put_vc1_mspel_mc20_c;
     dsp->put_vc1_mspel_pixels_tab[ 3] = put_vc1_mspel_mc30_c;
@@ -819,7 +832,7 @@
     dsp->put_vc1_mspel_pixels_tab[14] = put_vc1_mspel_mc23_c;
     dsp->put_vc1_mspel_pixels_tab[15] = put_vc1_mspel_mc33_c;
 
-    dsp->avg_vc1_mspel_pixels_tab[ 0] = ff_avg_pixels8x8_c;
+    dsp->avg_vc1_mspel_pixels_tab[ 0] = avg_pixels8x8_c;
     dsp->avg_vc1_mspel_pixels_tab[ 1] = avg_vc1_mspel_mc10_c;
     dsp->avg_vc1_mspel_pixels_tab[ 2] = avg_vc1_mspel_mc20_c;
     dsp->avg_vc1_mspel_pixels_tab[ 3] = avg_vc1_mspel_mc30_c;
diff --git a/libavcodec/vc1dsp.h b/libavcodec/vc1dsp.h
index 8775818..6540eff 100644
--- a/libavcodec/vc1dsp.h
+++ b/libavcodec/vc1dsp.h
@@ -29,21 +29,24 @@
 #define AVCODEC_VC1DSP_H
 
 #include "dsputil.h"
+#include "h264chroma.h"
+
+typedef void (*vc1op_pixels_func)(uint8_t *block/*align width (8 or 16)*/, const uint8_t *pixels/*align 1*/, int line_size, int h);
 
 typedef struct VC1DSPContext {
     /* vc1 functions */
-    void (*vc1_inv_trans_8x8)(DCTELEM *b);
-    void (*vc1_inv_trans_8x4)(uint8_t *dest, int line_size, DCTELEM *block);
-    void (*vc1_inv_trans_4x8)(uint8_t *dest, int line_size, DCTELEM *block);
-    void (*vc1_inv_trans_4x4)(uint8_t *dest, int line_size, DCTELEM *block);
-    void (*vc1_inv_trans_8x8_dc)(uint8_t *dest, int line_size, DCTELEM *block);
-    void (*vc1_inv_trans_8x4_dc)(uint8_t *dest, int line_size, DCTELEM *block);
-    void (*vc1_inv_trans_4x8_dc)(uint8_t *dest, int line_size, DCTELEM *block);
-    void (*vc1_inv_trans_4x4_dc)(uint8_t *dest, int line_size, DCTELEM *block);
+    void (*vc1_inv_trans_8x8)(int16_t *b);
+    void (*vc1_inv_trans_8x4)(uint8_t *dest, int line_size, int16_t *block);
+    void (*vc1_inv_trans_4x8)(uint8_t *dest, int line_size, int16_t *block);
+    void (*vc1_inv_trans_4x4)(uint8_t *dest, int line_size, int16_t *block);
+    void (*vc1_inv_trans_8x8_dc)(uint8_t *dest, int line_size, int16_t *block);
+    void (*vc1_inv_trans_8x4_dc)(uint8_t *dest, int line_size, int16_t *block);
+    void (*vc1_inv_trans_4x8_dc)(uint8_t *dest, int line_size, int16_t *block);
+    void (*vc1_inv_trans_4x4_dc)(uint8_t *dest, int line_size, int16_t *block);
     void (*vc1_v_overlap)(uint8_t *src, int stride);
     void (*vc1_h_overlap)(uint8_t *src, int stride);
-    void (*vc1_v_s_overlap)(DCTELEM *top,  DCTELEM *bottom);
-    void (*vc1_h_s_overlap)(DCTELEM *left, DCTELEM *right);
+    void (*vc1_v_s_overlap)(int16_t *top,  int16_t *bottom);
+    void (*vc1_h_s_overlap)(int16_t *left, int16_t *right);
     void (*vc1_v_loop_filter4)(uint8_t *src, int stride, int pq);
     void (*vc1_h_loop_filter4)(uint8_t *src, int stride, int pq);
     void (*vc1_v_loop_filter8)(uint8_t *src, int stride, int pq);
@@ -54,8 +57,8 @@
     /* put 8x8 block with bicubic interpolation and quarterpel precision
      * last argument is actually round value instead of height
      */
-    op_pixels_func put_vc1_mspel_pixels_tab[16];
-    op_pixels_func avg_vc1_mspel_pixels_tab[16];
+    vc1op_pixels_func put_vc1_mspel_pixels_tab[16];
+    vc1op_pixels_func avg_vc1_mspel_pixels_tab[16];
 
     /* This is really one func used in VC-1 decoding */
     h264_chroma_mc_func put_no_rnd_vc1_chroma_pixels_tab[3];
diff --git a/libavcodec/vcr1.c b/libavcodec/vcr1.c
index acac925..e9b1a7b 100644
--- a/libavcodec/vcr1.c
+++ b/libavcodec/vcr1.c
@@ -25,7 +25,7 @@
  */
 
 #include "avcodec.h"
-#include "dsputil.h"
+#include "internal.h"
 #include "libavutil/internal.h"
 
 typedef struct VCR1Context {
@@ -68,7 +68,7 @@
 }
 
 static int vcr1_decode_frame(AVCodecContext *avctx, void *data,
-                             int *data_size, AVPacket *avpkt)
+                             int *got_frame, AVPacket *avpkt)
 {
     const uint8_t *buf        = avpkt->data;
     int buf_size              = avpkt->size;
@@ -76,7 +76,7 @@
     AVFrame *picture          = data;
     AVFrame *const p          = &a->picture;
     const uint8_t *bytestream = buf;
-    int i, x, y;
+    int i, x, y, ret;
 
     if (p->data[0])
         avctx->release_buffer(avctx, p);
@@ -87,9 +87,9 @@
     }
 
     p->reference = 0;
-    if (avctx->get_buffer(avctx, p) < 0) {
+    if ((ret = ff_get_buffer(avctx, p)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
     p->pict_type = AV_PICTURE_TYPE_I;
     p->key_frame = 1;
@@ -142,7 +142,7 @@
     }
 
     *picture   = a->picture;
-    *data_size = sizeof(AVPicture);
+    *got_frame = 1;
 
     return buf_size;
 }
@@ -158,42 +158,3 @@
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("ATI VCR1"),
 };
-
-/* Disable the encoder. */
-#undef CONFIG_VCR1_ENCODER
-#define CONFIG_VCR1_ENCODER 0
-
-#if CONFIG_VCR1_ENCODER
-
-#include "put_bits.h"
-
-static int vcr1_encode_frame(AVCodecContext *avctx, unsigned char *buf,
-                             int buf_size, void *data)
-{
-    VCR1Context *const a = avctx->priv_data;
-    AVFrame *pict        = data;
-    AVFrame *const p     = &a->picture;
-    int size;
-
-    *p           = *pict;
-    p->pict_type = AV_PICTURE_TYPE_I;
-    p->key_frame = 1;
-
-    avpriv_align_put_bits(&a->pb);
-    flush_put_bits(&a->pb);
-
-    size = put_bits_count(&a->pb) / 32;
-
-    return size * 4;
-}
-
-AVCodec ff_vcr1_encoder = {
-    .name           = "vcr1",
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_VCR1,
-    .priv_data_size = sizeof(VCR1Context),
-    .init           = vcr1_common_init,
-    .encode         = vcr1_encode_frame,
-    .long_name      = NULL_IF_CONFIG_SMALL("ATI VCR1"),
-};
-#endif /* CONFIG_VCR1_ENCODER */
diff --git a/libavcodec/vda_h264.c b/libavcodec/vda_h264.c
index 89960d7..c24f4b1 100644
--- a/libavcodec/vda_h264.c
+++ b/libavcodec/vda_h264.c
@@ -243,7 +243,7 @@
 {
     H264Context *h                      = avctx->priv_data;
     struct vda_context *vda_ctx         = avctx->hwaccel_context;
-    AVFrame *frame                      = &h->s.current_picture_ptr->f;
+    AVFrame *frame                      = &h->cur_pic_ptr->f;
     int status;
 
     if (!vda_ctx->decoder || !vda_ctx->priv_bitstream)
@@ -285,7 +285,7 @@
     pthread_mutex_init(&vda_ctx->queue_mutex, NULL);
 #endif
 
-    /* Each VCL NAL in the bistream sent to the decoder
+    /* Each VCL NAL in the bitstream sent to the decoder
      * is preceded by a 4 bytes length header.
      * Change the avcC atom header if needed, to signal headers of 4 bytes. */
     if (extradata_size >= 4 && (extradata[4] & 0x03) != 0x03) {
diff --git a/libavcodec/vda_h264_dec.c b/libavcodec/vda_h264_dec.c
index 3cb13e3..d6c8f37 100644
--- a/libavcodec/vda_h264_dec.c
+++ b/libavcodec/vda_h264_dec.c
@@ -84,14 +84,14 @@
 }
 
 static int vdadec_decode(AVCodecContext *avctx,
-        void *data, int *data_size, AVPacket *avpkt)
+        void *data, int *got_frame, AVPacket *avpkt)
 {
     VDADecoderContext *ctx = avctx->priv_data;
     AVFrame *pic = data;
     int ret;
 
-    ret = ff_h264_decoder.decode(avctx, data, data_size, avpkt);
-    if (*data_size) {
+    ret = ff_h264_decoder.decode(avctx, data, got_frame, avpkt);
+    if (*got_frame) {
         CVPixelBufferRef cv_buffer = (CVPixelBufferRef)pic->data[3];
         CVPixelBufferLockBaseAddress(cv_buffer, 0);
         pic->format = ctx->pix_fmt;
diff --git a/libavcodec/vdpau.c b/libavcodec/vdpau.c
index 6ac195e..6df7f4a 100644
--- a/libavcodec/vdpau.c
+++ b/libavcodec/vdpau.c
@@ -38,15 +38,61 @@
  * @{
  */
 
-void ff_vdpau_h264_set_reference_frames(MpegEncContext *s)
+int ff_vdpau_common_start_frame(AVCodecContext *avctx,
+                                av_unused const uint8_t *buffer,
+                                av_unused uint32_t size)
 {
-    H264Context *h = s->avctx->priv_data;
+    AVVDPAUContext *hwctx = avctx->hwaccel_context;
+
+    hwctx->bitstream_buffers_used = 0;
+    return 0;
+}
+
+int ff_vdpau_mpeg_end_frame(AVCodecContext *avctx)
+{
+    AVVDPAUContext *hwctx = avctx->hwaccel_context;
+    MpegEncContext *s = avctx->priv_data;
+    VdpVideoSurface surf = ff_vdpau_get_surface_id(s->current_picture_ptr);
+
+    hwctx->render(hwctx->decoder, surf, (void *)&hwctx->info,
+                  hwctx->bitstream_buffers_used, hwctx->bitstream_buffers);
+
+    ff_mpeg_draw_horiz_band(s, 0, s->avctx->height);
+    hwctx->bitstream_buffers_used = 0;
+
+    return 0;
+}
+
+int ff_vdpau_add_buffer(AVCodecContext *avctx,
+                        const uint8_t *buf, uint32_t size)
+{
+    AVVDPAUContext *hwctx = avctx->hwaccel_context;
+    VdpBitstreamBuffer *buffers = hwctx->bitstream_buffers;
+
+    buffers = av_fast_realloc(buffers, &hwctx->bitstream_buffers_allocated,
+                              (hwctx->bitstream_buffers_used + 1) * sizeof(*buffers));
+    if (!buffers)
+        return AVERROR(ENOMEM);
+
+    hwctx->bitstream_buffers = buffers;
+    buffers += hwctx->bitstream_buffers_used++;
+
+    buffers->struct_version  = VDP_BITSTREAM_BUFFER_VERSION;
+    buffers->bitstream       = buf;
+    buffers->bitstream_bytes = size;
+    return 0;
+}
+
+/* Obsolete non-hwaccel VDPAU support below... */
+
+void ff_vdpau_h264_set_reference_frames(H264Context *h)
+{
     struct vdpau_render_state *render, *render_ref;
     VdpReferenceFrameH264 *rf, *rf2;
     Picture *pic;
     int i, list, pic_frame_idx;
 
-    render = (struct vdpau_render_state *)s->current_picture_ptr->f.data[0];
+    render = (struct vdpau_render_state *)h->cur_pic_ptr->f.data[0];
     assert(render);
 
     rf = &render->info.h264.referenceFrames[0];
@@ -107,12 +153,9 @@
     }
 }
 
-void ff_vdpau_add_data_chunk(MpegEncContext *s,
-                             const uint8_t *buf, int buf_size)
+void ff_vdpau_add_data_chunk(uint8_t *data, const uint8_t *buf, int buf_size)
 {
-    struct vdpau_render_state *render;
-
-    render = (struct vdpau_render_state *)s->current_picture_ptr->f.data[0];
+    struct vdpau_render_state *render = (struct vdpau_render_state*)data;
     assert(render);
 
     render->bitstream_buffers= av_fast_realloc(
@@ -127,17 +170,16 @@
     render->bitstream_buffers_used++;
 }
 
-void ff_vdpau_h264_picture_start(MpegEncContext *s)
+void ff_vdpau_h264_picture_start(H264Context *h)
 {
-    H264Context *h = s->avctx->priv_data;
     struct vdpau_render_state *render;
     int i;
 
-    render = (struct vdpau_render_state *)s->current_picture_ptr->f.data[0];
+    render = (struct vdpau_render_state *)h->cur_pic_ptr->f.data[0];
     assert(render);
 
     for (i = 0; i < 2; ++i) {
-        int foc = s->current_picture_ptr->field_poc[i];
+        int foc = h->cur_pic_ptr->field_poc[i];
         if (foc == INT_MAX)
             foc = 0;
         render->info.h264.field_order_cnt[i] = foc;
@@ -146,21 +188,20 @@
     render->info.h264.frame_num = h->frame_num;
 }
 
-void ff_vdpau_h264_picture_complete(MpegEncContext *s)
+void ff_vdpau_h264_picture_complete(H264Context *h)
 {
-    H264Context *h = s->avctx->priv_data;
     struct vdpau_render_state *render;
 
-    render = (struct vdpau_render_state *)s->current_picture_ptr->f.data[0];
+    render = (struct vdpau_render_state *)h->cur_pic_ptr->f.data[0];
     assert(render);
 
     render->info.h264.slice_count = h->slice_num;
     if (render->info.h264.slice_count < 1)
         return;
 
-    render->info.h264.is_reference                           = (s->current_picture_ptr->f.reference & 3) ? VDP_TRUE : VDP_FALSE;
-    render->info.h264.field_pic_flag                         = s->picture_structure != PICT_FRAME;
-    render->info.h264.bottom_field_flag                      = s->picture_structure == PICT_BOTTOM_FIELD;
+    render->info.h264.is_reference                           = (h->cur_pic_ptr->f.reference & 3) ? VDP_TRUE : VDP_FALSE;
+    render->info.h264.field_pic_flag                         = h->picture_structure != PICT_FRAME;
+    render->info.h264.bottom_field_flag                      = h->picture_structure == PICT_BOTTOM_FIELD;
     render->info.h264.num_ref_frames                         = h->sps.ref_frame_count;
     render->info.h264.mb_adaptive_frame_field_flag           = h->sps.mb_aff && !render->info.h264.field_pic_flag;
     render->info.h264.constrained_intra_pred_flag            = h->pps.constrained_intra_pred;
@@ -186,7 +227,7 @@
     memcpy(render->info.h264.scaling_lists_8x8[0], h->pps.scaling_matrix8[0], sizeof(render->info.h264.scaling_lists_8x8[0]));
     memcpy(render->info.h264.scaling_lists_8x8[1], h->pps.scaling_matrix8[3], sizeof(render->info.h264.scaling_lists_8x8[0]));
 
-    ff_draw_horiz_band(s, 0, s->avctx->height);
+    ff_h264_draw_horiz_band(h, 0, h->avctx->height);
     render->bitstream_buffers_used = 0;
 }
 
@@ -238,12 +279,12 @@
         render->info.mpeg.forward_reference      = last->surface;
     }
 
-    ff_vdpau_add_data_chunk(s, buf, buf_size);
+    ff_vdpau_add_data_chunk(s->current_picture_ptr->f.data[0], buf, buf_size);
 
     render->info.mpeg.slice_count                = slice_count;
 
     if (slice_count)
-        ff_draw_horiz_band(s, 0, s->avctx->height);
+        ff_mpeg_draw_horiz_band(s, 0, s->avctx->height);
     render->bitstream_buffers_used               = 0;
 }
 
@@ -308,11 +349,11 @@
         render->info.vc1.forward_reference = last->surface;
     }
 
-    ff_vdpau_add_data_chunk(s, buf, buf_size);
+    ff_vdpau_add_data_chunk(s->current_picture_ptr->f.data[0], buf, buf_size);
 
     render->info.vc1.slice_count          = 1;
 
-    ff_draw_horiz_band(s, 0, s->avctx->height);
+    ff_mpeg_draw_horiz_band(s, 0, s->avctx->height);
     render->bitstream_buffers_used        = 0;
 }
 
@@ -364,46 +405,10 @@
         render->info.mpeg4.forward_reference      = last->surface;
     }
 
-    ff_vdpau_add_data_chunk(s, buf, buf_size);
+    ff_vdpau_add_data_chunk(s->current_picture_ptr->f.data[0], buf, buf_size);
 
-    ff_draw_horiz_band(s, 0, s->avctx->height);
+    ff_mpeg_draw_horiz_band(s, 0, s->avctx->height);
     render->bitstream_buffers_used = 0;
 }
 
-// Only dummy functions for now
-static int vdpau_mpeg2_start_frame(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
-{
-    return 0;
-}
-
-static int vdpau_mpeg2_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
-{
-    return 0;
-}
-
-static int vdpau_mpeg2_end_frame(AVCodecContext *avctx)
-{
-    return 0;
-}
-
-AVHWAccel ff_mpeg1_vdpau_hwaccel = {
-    .name           = "mpeg1_vdpau",
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_MPEG1VIDEO,
-    .pix_fmt        = AV_PIX_FMT_VDPAU_MPEG1,
-    .start_frame    = vdpau_mpeg2_start_frame,
-    .end_frame      = vdpau_mpeg2_end_frame,
-    .decode_slice   = vdpau_mpeg2_decode_slice,
-};
-
-AVHWAccel ff_mpeg2_vdpau_hwaccel = {
-    .name           = "mpeg2_vdpau",
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_MPEG2VIDEO,
-    .pix_fmt        = AV_PIX_FMT_VDPAU_MPEG2,
-    .start_frame    = vdpau_mpeg2_start_frame,
-    .end_frame      = vdpau_mpeg2_end_frame,
-    .decode_slice   = vdpau_mpeg2_decode_slice,
-};
-
 /* @}*/
diff --git a/libavcodec/vdpau.h b/libavcodec/vdpau.h
index 23394b5..df2aace 100644
--- a/libavcodec/vdpau.h
+++ b/libavcodec/vdpau.h
@@ -52,6 +52,68 @@
 #include <vdpau/vdpau.h>
 #include <vdpau/vdpau_x11.h>
 
+union FFVdpPictureInfo {
+    VdpPictureInfoH264        h264;
+    VdpPictureInfoMPEG1Or2    mpeg;
+    VdpPictureInfoVC1          vc1;
+    VdpPictureInfoMPEG4Part2 mpeg4;
+};
+
+/**
+ * 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
+ * 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
+ * decoding functions.
+ */
+typedef struct AVVDPAUContext {
+    /**
+     * VDPAU decoder handle
+     *
+     * Set by user.
+     */
+    VdpDecoder decoder;
+
+    /**
+     * VDPAU decoder render callback
+     *
+     * Set by the user.
+     */
+    VdpDecoderRender *render;
+
+    /**
+     * VDPAU picture information
+     *
+     * Set by libavcodec.
+     */
+    union FFVdpPictureInfo info;
+
+    /**
+     * Allocated size of the bitstream_buffers table.
+     *
+     * Set by libavcodec.
+     */
+    int bitstream_buffers_allocated;
+
+    /**
+     * Useful bitstream buffers in the bitstream buffers table.
+     *
+     * Set by libavcodec.
+     */
+    int bitstream_buffers_used;
+
+   /**
+     * Table of bitstream buffers.
+     * The user is responsible for freeing this buffer using av_freep().
+     *
+     * Set by libavcodec.
+     */
+    VdpBitstreamBuffer *bitstream_buffers;
+} AVVDPAUContext;
+
+
 /** @brief The videoSurface is used for rendering. */
 #define FF_VDPAU_STATE_USED_FOR_RENDER 1
 
@@ -81,12 +143,7 @@
     VdpBitstreamBuffer *bitstream_buffers;
 
     /** picture parameter information for all supported codecs */
-    union VdpPictureInfo {
-        VdpPictureInfoH264        h264;
-        VdpPictureInfoMPEG1Or2    mpeg;
-        VdpPictureInfoVC1          vc1;
-        VdpPictureInfoMPEG4Part2 mpeg4;
-    } info;
+    union FFVdpPictureInfo info;
 };
 
 /* @}*/
diff --git a/libavcodec/vdpau_h264.c b/libavcodec/vdpau_h264.c
new file mode 100644
index 0000000..0f79c58
--- /dev/null
+++ b/libavcodec/vdpau_h264.c
@@ -0,0 +1,210 @@
+/*
+ * MPEG-4 Part 10 / AVC / H.264 HW decode acceleration through VDPAU
+ *
+ * Copyright (c) 2008 NVIDIA
+ * Copyright (c) 2013 Rémi Denis-Courmont
+ *
+ * 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 <vdpau/vdpau.h>
+
+#include "avcodec.h"
+#include "h264.h"
+#include "vdpau.h"
+#include "vdpau_internal.h"
+
+static int32_t h264_foc(int foc)
+{
+    if (foc == INT_MAX)
+        foc = 0;
+    return foc;
+}
+
+static void vdpau_h264_clear_rf(VdpReferenceFrameH264 *rf)
+{
+    rf->surface             = VDP_INVALID_HANDLE;
+    rf->is_long_term        = VDP_FALSE;
+    rf->top_is_reference    = VDP_FALSE;
+    rf->bottom_is_reference = VDP_FALSE;
+    rf->field_order_cnt[0]  = 0;
+    rf->field_order_cnt[1]  = 0;
+    rf->frame_idx           = 0;
+}
+
+static void vdpau_h264_set_rf(VdpReferenceFrameH264 *rf, Picture *pic,
+                              int pic_structure)
+{
+    VdpVideoSurface surface = ff_vdpau_get_surface_id(pic);
+
+    if (pic_structure == 0)
+        pic_structure = pic->f.reference;
+
+    rf->surface             = surface;
+    rf->is_long_term        = pic->f.reference && pic->long_ref;
+    rf->top_is_reference    = (pic_structure & PICT_TOP_FIELD)    != 0;
+    rf->bottom_is_reference = (pic_structure & PICT_BOTTOM_FIELD) != 0;
+    rf->field_order_cnt[0]  = h264_foc(pic->field_poc[0]);
+    rf->field_order_cnt[1]  = h264_foc(pic->field_poc[1]);
+    rf->frame_idx           = pic->long_ref ? pic->pic_id : pic->frame_num;
+}
+
+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;
+    int list;
+
+    VdpReferenceFrameH264 *rf = &info->referenceFrames[0];
+#define H264_RF_COUNT FF_ARRAY_ELEMS(info->referenceFrames)
+
+    for (list = 0; list < 2; ++list) {
+        Picture **lp = list ? h->long_ref : h->short_ref;
+        int i, ls    = list ? 16          : h->short_ref_count;
+
+        for (i = 0; i < ls; ++i) {
+            Picture *pic = lp[i];
+            VdpReferenceFrameH264 *rf2;
+            VdpVideoSurface surface_ref;
+            int pic_frame_idx;
+
+            if (!pic || !pic->f.reference)
+                continue;
+            pic_frame_idx = pic->long_ref ? pic->pic_id : pic->frame_num;
+            surface_ref = ff_vdpau_get_surface_id(pic);
+
+            rf2 = &info->referenceFrames[0];
+            while (rf2 != rf) {
+                if ((rf2->surface      == surface_ref)   &&
+                    (rf2->is_long_term == pic->long_ref) &&
+                    (rf2->frame_idx    == pic_frame_idx))
+                    break;
+                ++rf2;
+            }
+            if (rf2 != rf) {
+                rf2->top_is_reference    |= (pic->f.reference & PICT_TOP_FIELD)    ? VDP_TRUE : VDP_FALSE;
+                rf2->bottom_is_reference |= (pic->f.reference & PICT_BOTTOM_FIELD) ? VDP_TRUE : VDP_FALSE;
+                continue;
+            }
+
+            if (rf >= &info->referenceFrames[H264_RF_COUNT])
+                continue;
+
+            vdpau_h264_set_rf(rf, pic, pic->f.reference);
+            ++rf;
+        }
+    }
+
+    for (; rf < &info->referenceFrames[H264_RF_COUNT]; ++rf)
+        vdpau_h264_clear_rf(rf);
+}
+
+static int vdpau_h264_start_frame(AVCodecContext *avctx,
+                                  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;
+
+    /* init VdpPictureInfoH264 */
+    info->slice_count                            = 0;
+    info->field_order_cnt[0]                     = h264_foc(pic->field_poc[0]);
+    info->field_order_cnt[1]                     = h264_foc(pic->field_poc[1]);
+    info->is_reference                           = h->nal_ref_idc != 0;
+    info->frame_num                              = h->frame_num;
+    info->field_pic_flag                         = h->picture_structure != PICT_FRAME;
+    info->bottom_field_flag                      = h->picture_structure == PICT_BOTTOM_FIELD;
+    info->num_ref_frames                         = h->sps.ref_frame_count;
+    info->mb_adaptive_frame_field_flag           = h->sps.mb_aff && !info->field_pic_flag;
+    info->constrained_intra_pred_flag            = h->pps.constrained_intra_pred;
+    info->weighted_pred_flag                     = h->pps.weighted_pred;
+    info->weighted_bipred_idc                    = h->pps.weighted_bipred_idc;
+    info->frame_mbs_only_flag                    = h->sps.frame_mbs_only_flag;
+    info->transform_8x8_mode_flag                = h->pps.transform_8x8_mode;
+    info->chroma_qp_index_offset                 = h->pps.chroma_qp_index_offset[0];
+    info->second_chroma_qp_index_offset          = h->pps.chroma_qp_index_offset[1];
+    info->pic_init_qp_minus26                    = h->pps.init_qp - 26;
+    info->num_ref_idx_l0_active_minus1           = h->pps.ref_count[0] - 1;
+    info->num_ref_idx_l1_active_minus1           = h->pps.ref_count[1] - 1;
+    info->log2_max_frame_num_minus4              = h->sps.log2_max_frame_num - 4;
+    info->pic_order_cnt_type                     = h->sps.poc_type;
+    info->log2_max_pic_order_cnt_lsb_minus4      = h->sps.poc_type ? 0 : h->sps.log2_max_poc_lsb - 4;
+    info->delta_pic_order_always_zero_flag       = h->sps.delta_pic_order_always_zero_flag;
+    info->direct_8x8_inference_flag              = h->sps.direct_8x8_inference_flag;
+    info->entropy_coding_mode_flag               = h->pps.cabac;
+    info->pic_order_present_flag                 = h->pps.pic_order_present;
+    info->deblocking_filter_control_present_flag = h->pps.deblocking_filter_parameters_present;
+    info->redundant_pic_cnt_present_flag         = h->pps.redundant_pic_cnt_present;
+
+    memcpy(info->scaling_lists_4x4, h->pps.scaling_matrix4,
+           sizeof(info->scaling_lists_4x4));
+    memcpy(info->scaling_lists_8x8[0], h->pps.scaling_matrix8[0],
+           sizeof(info->scaling_lists_8x8[0]));
+    memcpy(info->scaling_lists_8x8[1], h->pps.scaling_matrix8[3],
+           sizeof(info->scaling_lists_8x8[1]));
+
+    vdpau_h264_set_reference_frames(avctx);
+
+    return ff_vdpau_common_start_frame(avctx, buffer, size);
+}
+
+static const uint8_t start_code_prefix[3] = { 0x00, 0x00, 0x01 };
+
+static int vdpau_h264_decode_slice(AVCodecContext *avctx,
+                                   const uint8_t *buffer, uint32_t size)
+{
+    AVVDPAUContext *hwctx = avctx->hwaccel_context;
+    int val;
+
+    val = ff_vdpau_add_buffer(avctx, start_code_prefix, 3);
+    if (val)
+        return val;
+
+    val = ff_vdpau_add_buffer(avctx, buffer, size);
+    if (val)
+        return val;
+
+    hwctx->info.h264.slice_count++;
+    return 0;
+}
+
+static int vdpau_h264_end_frame(AVCodecContext *avctx)
+{
+    AVVDPAUContext *hwctx = avctx->hwaccel_context;
+    H264Context *h = avctx->priv_data;
+    VdpVideoSurface surf = ff_vdpau_get_surface_id(h->cur_pic_ptr);
+
+    hwctx->render(hwctx->decoder, surf, (void *)&hwctx->info,
+                  hwctx->bitstream_buffers_used, hwctx->bitstream_buffers);
+
+    ff_h264_draw_horiz_band(h, 0, h->avctx->height);
+    hwctx->bitstream_buffers_used = 0;
+
+    return 0;
+}
+
+AVHWAccel ff_h264_vdpau_hwaccel = {
+    .name           = "h264_vdpau",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_H264,
+    .pix_fmt        = AV_PIX_FMT_VDPAU,
+    .start_frame    = vdpau_h264_start_frame,
+    .end_frame      = vdpau_h264_end_frame,
+    .decode_slice   = vdpau_h264_decode_slice,
+};
diff --git a/libavcodec/vdpau_internal.h b/libavcodec/vdpau_internal.h
index 0a8d0b6..790b3ef 100644
--- a/libavcodec/vdpau_internal.h
+++ b/libavcodec/vdpau_internal.h
@@ -25,17 +25,31 @@
 #define AVCODEC_VDPAU_INTERNAL_H
 
 #include <stdint.h>
+#include "h264.h"
 #include "mpegvideo.h"
 
-void ff_vdpau_add_data_chunk(MpegEncContext *s, const uint8_t *buf,
+/** Extract VdpVideoSurface from a Picture */
+static inline uintptr_t ff_vdpau_get_surface_id(Picture *pic)
+{
+    return (uintptr_t)pic->f.data[3];
+}
+
+int ff_vdpau_common_start_frame(AVCodecContext *avctx,
+                                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);
+
+
+void ff_vdpau_add_data_chunk(uint8_t *data, const uint8_t *buf,
                              int buf_size);
 
 void ff_vdpau_mpeg_picture_complete(MpegEncContext *s, const uint8_t *buf,
                                     int buf_size, int slice_count);
 
-void ff_vdpau_h264_picture_start(MpegEncContext *s);
-void ff_vdpau_h264_set_reference_frames(MpegEncContext *s);
-void ff_vdpau_h264_picture_complete(MpegEncContext *s);
+void ff_vdpau_h264_picture_start(H264Context *h);
+void ff_vdpau_h264_set_reference_frames(H264Context *h);
+void ff_vdpau_h264_picture_complete(H264Context *h);
 
 void ff_vdpau_vc1_decode_picture(MpegEncContext *s, const uint8_t *buf,
                                  int buf_size);
diff --git a/libavcodec/vdpau_mpeg12.c b/libavcodec/vdpau_mpeg12.c
new file mode 100644
index 0000000..74e3f16
--- /dev/null
+++ b/libavcodec/vdpau_mpeg12.c
@@ -0,0 +1,116 @@
+/*
+ * MPEG-1/2 HW decode acceleration through VDPAU
+ *
+ * Copyright (c) 2008 NVIDIA
+ * Copyright (c) 2013 Rémi Denis-Courmont
+ *
+ * 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 <vdpau/vdpau.h>
+
+#include "avcodec.h"
+#include "vdpau.h"
+#include "vdpau_internal.h"
+
+static int vdpau_mpeg_start_frame(AVCodecContext *avctx,
+                                  const uint8_t *buffer, uint32_t size)
+{
+    MpegEncContext * const s = avctx->priv_data;
+    AVVDPAUContext *hwctx    = avctx->hwaccel_context;
+    VdpPictureInfoMPEG1Or2 *info = &hwctx->info.mpeg;
+    VdpVideoSurface ref;
+    int i;
+
+    /* fill VdpPictureInfoMPEG1Or2 struct */
+    info->forward_reference  = VDP_INVALID_HANDLE;
+    info->backward_reference = VDP_INVALID_HANDLE;
+
+    switch (s->pict_type) {
+    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;
+        /* 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->slice_count                = 0;
+    info->picture_structure          = s->picture_structure;
+    info->picture_coding_type        = s->pict_type;
+    info->intra_dc_precision         = s->intra_dc_precision;
+    info->frame_pred_frame_dct       = s->frame_pred_frame_dct;
+    info->concealment_motion_vectors = s->concealment_motion_vectors;
+    info->intra_vlc_format           = s->intra_vlc_format;
+    info->alternate_scan             = s->alternate_scan;
+    info->q_scale_type               = s->q_scale_type;
+    info->top_field_first            = s->top_field_first;
+    // Both for MPEG-1 only, zero for MPEG-2:
+    info->full_pel_forward_vector    = s->full_pel[0];
+    info->full_pel_backward_vector   = s->full_pel[1];
+    // For MPEG-1 fill both horizontal & vertical:
+    info->f_code[0][0]               = s->mpeg_f_code[0][0];
+    info->f_code[0][1]               = s->mpeg_f_code[0][1];
+    info->f_code[1][0]               = s->mpeg_f_code[1][0];
+    info->f_code[1][1]               = s->mpeg_f_code[1][1];
+    for (i = 0; i < 64; ++i) {
+        info->intra_quantizer_matrix[i]     = s->intra_matrix[i];
+        info->non_intra_quantizer_matrix[i] = s->inter_matrix[i];
+    }
+
+    return ff_vdpau_common_start_frame(avctx, buffer, size);
+}
+
+static int vdpau_mpeg_decode_slice(AVCodecContext *avctx,
+                                   const uint8_t *buffer, uint32_t size)
+{
+    AVVDPAUContext *hwctx = avctx->hwaccel_context;
+    int val;
+
+    val = ff_vdpau_add_buffer(avctx, buffer, size);
+    if (val < 0)
+        return val;
+
+    hwctx->info.mpeg.slice_count++;
+    return 0;
+}
+
+#if CONFIG_MPEG1_VDPAU_HWACCEL
+AVHWAccel ff_mpeg1_vdpau_hwaccel = {
+    .name           = "mpeg1_vdpau",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_MPEG1VIDEO,
+    .pix_fmt        = AV_PIX_FMT_VDPAU,
+    .start_frame    = vdpau_mpeg_start_frame,
+    .end_frame      = ff_vdpau_mpeg_end_frame,
+    .decode_slice   = vdpau_mpeg_decode_slice,
+};
+#endif
+
+#if CONFIG_MPEG2_VDPAU_HWACCEL
+AVHWAccel ff_mpeg2_vdpau_hwaccel = {
+    .name           = "mpeg2_vdpau",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_MPEG2VIDEO,
+    .pix_fmt        = AV_PIX_FMT_VDPAU,
+    .start_frame    = vdpau_mpeg_start_frame,
+    .end_frame      = ff_vdpau_mpeg_end_frame,
+    .decode_slice   = vdpau_mpeg_decode_slice,
+};
+#endif
diff --git a/libavcodec/vdpau_mpeg4.c b/libavcodec/vdpau_mpeg4.c
new file mode 100644
index 0000000..cb8ee0a
--- /dev/null
+++ b/libavcodec/vdpau_mpeg4.c
@@ -0,0 +1,110 @@
+/*
+ * MPEG-4 Part 2 / H.263 decode acceleration through VDPAU
+ *
+ * Copyright (c) 2008 NVIDIA
+ * Copyright (c) 2013 Rémi Denis-Courmont
+ *
+ * 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 <vdpau/vdpau.h>
+
+#include "avcodec.h"
+#include "vdpau.h"
+#include "vdpau_internal.h"
+
+static int vdpau_mpeg4_start_frame(AVCodecContext *avctx,
+                                   const uint8_t *buffer, uint32_t size)
+{
+    MpegEncContext * const s = avctx->priv_data;
+    AVVDPAUContext *hwctx    = avctx->hwaccel_context;
+    VdpPictureInfoMPEG4Part2 *info = &hwctx->info.mpeg4;
+    VdpVideoSurface ref;
+    int i;
+
+    /* fill VdpPictureInfoMPEG4Part2 struct */
+    info->forward_reference  = VDP_INVALID_HANDLE;
+    info->backward_reference = VDP_INVALID_HANDLE;
+    info->vop_coding_type    = 0;
+
+    switch (s->pict_type) {
+    case AV_PICTURE_TYPE_B:
+        ref = ff_vdpau_get_surface_id(&s->next_picture);
+        assert(ref != VDP_INVALID_HANDLE);
+        info->backward_reference = ref;
+        info->vop_coding_type    = 2;
+        /* fall-through */
+    case AV_PICTURE_TYPE_P:
+        ref = ff_vdpau_get_surface_id(&s->last_picture);
+        assert(ref != VDP_INVALID_HANDLE);
+        info->forward_reference  = ref;
+    }
+
+    info->trd[0]                            = s->pp_time;
+    info->trb[0]                            = s->pb_time;
+    info->trd[1]                            = s->pp_field_time >> 1;
+    info->trb[1]                            = s->pb_field_time >> 1;
+    info->vop_time_increment_resolution     = s->avctx->time_base.den;
+    info->vop_fcode_forward                 = s->f_code;
+    info->vop_fcode_backward                = s->b_code;
+    info->resync_marker_disable             = !s->resync_marker;
+    info->interlaced                        = !s->progressive_sequence;
+    info->quant_type                        = s->mpeg_quant;
+    info->quarter_sample                    = s->quarter_sample;
+    info->short_video_header                = avctx->codec->id == AV_CODEC_ID_H263;
+    info->rounding_control                  = s->no_rounding;
+    info->alternate_vertical_scan_flag      = s->alternate_scan;
+    info->top_field_first                   = s->top_field_first;
+    for (i = 0; i < 64; ++i) {
+        info->intra_quantizer_matrix[i]     = s->intra_matrix[i];
+        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);
+}
+
+static int vdpau_mpeg4_decode_slice(av_unused AVCodecContext *avctx,
+                                    av_unused const uint8_t *buffer,
+                                    av_unused uint32_t size)
+{
+     return 0;
+}
+
+#if CONFIG_H263_VDPAU_HWACCEL
+AVHWAccel ff_h263_vdpau_hwaccel = {
+    .name           = "h263_vdpau",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_H263,
+    .pix_fmt        = AV_PIX_FMT_VDPAU,
+    .start_frame    = vdpau_mpeg4_start_frame,
+    .end_frame      = ff_vdpau_mpeg_end_frame,
+    .decode_slice   = vdpau_mpeg4_decode_slice,
+};
+#endif
+
+#if CONFIG_MPEG4_VDPAU_HWACCEL
+AVHWAccel ff_mpeg4_vdpau_hwaccel = {
+    .name           = "mpeg4_vdpau",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_MPEG4,
+    .pix_fmt        = AV_PIX_FMT_VDPAU,
+    .start_frame    = vdpau_mpeg4_start_frame,
+    .end_frame      = ff_vdpau_mpeg_end_frame,
+    .decode_slice   = vdpau_mpeg4_decode_slice,
+};
+#endif
diff --git a/libavcodec/vdpau_vc1.c b/libavcodec/vdpau_vc1.c
new file mode 100644
index 0000000..f5da9bb
--- /dev/null
+++ b/libavcodec/vdpau_vc1.c
@@ -0,0 +1,128 @@
+/*
+ * VC-1 decode acceleration through VDPAU
+ *
+ * Copyright (c) 2008 NVIDIA
+ * Copyright (c) 2013 Rémi Denis-Courmont
+ *
+ * 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 <vdpau/vdpau.h>
+
+#include "avcodec.h"
+#include "vc1.h"
+#include "vdpau.h"
+#include "vdpau_internal.h"
+
+static int vdpau_vc1_start_frame(AVCodecContext *avctx,
+                                 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;
+    VdpVideoSurface ref;
+
+    /*  fill LvPictureInfoVC1 struct */
+    info->forward_reference  = VDP_INVALID_HANDLE;
+    info->backward_reference = VDP_INVALID_HANDLE;
+
+    switch (s->pict_type) {
+    case AV_PICTURE_TYPE_B:
+        ref = ff_vdpau_get_surface_id(&s->next_picture);
+        assert(ref != VDP_INVALID_HANDLE);
+        info->backward_reference = ref;
+        /* fall-through */
+    case AV_PICTURE_TYPE_P:
+        ref = ff_vdpau_get_surface_id(&s->last_picture);
+        assert(ref != VDP_INVALID_HANDLE);
+        info->forward_reference  = ref;
+    }
+
+    info->slice_count       = 0;
+    if (v->bi_type)
+        info->picture_type  = 4;
+    else
+        info->picture_type  = s->pict_type - 1 + s->pict_type / 3;
+
+    info->frame_coding_mode = v->fcm;
+    info->postprocflag      = v->postprocflag;
+    info->pulldown          = v->broadcast;
+    info->interlace         = v->interlace;
+    info->tfcntrflag        = v->tfcntrflag;
+    info->finterpflag       = v->finterpflag;
+    info->psf               = v->psf;
+    info->dquant            = v->dquant;
+    info->panscan_flag      = v->panscanflag;
+    info->refdist_flag      = v->refdist_flag;
+    info->quantizer         = v->quantizer_mode;
+    info->extended_mv       = v->extended_mv;
+    info->extended_dmv      = v->extended_dmv;
+    info->overlap           = v->overlap;
+    info->vstransform       = v->vstransform;
+    info->loopfilter        = v->s.loop_filter;
+    info->fastuvmc          = v->fastuvmc;
+    info->range_mapy_flag   = v->range_mapy_flag;
+    info->range_mapy        = v->range_mapy;
+    info->range_mapuv_flag  = v->range_mapuv_flag;
+    info->range_mapuv       = v->range_mapuv;
+    /* Specific to simple/main profile only */
+    info->multires          = v->multires;
+    info->syncmarker        = v->s.resync_marker;
+    info->rangered          = v->rangered | (v->rangeredfrm << 1);
+    info->maxbframes        = v->s.max_b_frames;
+    info->deblockEnable     = v->postprocflag & 1;
+    info->pquant            = v->pq;
+
+    return ff_vdpau_common_start_frame(avctx, buffer, size);
+}
+
+static int vdpau_vc1_decode_slice(AVCodecContext *avctx,
+                                  const uint8_t *buffer, uint32_t size)
+{
+    AVVDPAUContext *hwctx = avctx->hwaccel_context;
+    int val;
+
+    val = ff_vdpau_add_buffer(avctx, buffer, size);
+    if (val < 0)
+        return val;
+
+    hwctx->info.vc1.slice_count++;
+    return 0;
+}
+
+#if CONFIG_WMV3_VDPAU_HWACCEL
+AVHWAccel ff_wmv3_vdpau_hwaccel = {
+    .name           = "wm3_vdpau",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_WMV3,
+    .pix_fmt        = AV_PIX_FMT_VDPAU,
+    .start_frame    = vdpau_vc1_start_frame,
+    .end_frame      = ff_vdpau_mpeg_end_frame,
+    .decode_slice   = vdpau_vc1_decode_slice,
+};
+#endif
+
+AVHWAccel ff_vc1_vdpau_hwaccel = {
+    .name           = "vc1_vdpau",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_VC1,
+    .pix_fmt        = AV_PIX_FMT_VDPAU,
+    .start_frame    = vdpau_vc1_start_frame,
+    .end_frame      = ff_vdpau_mpeg_end_frame,
+    .decode_slice   = vdpau_vc1_decode_slice,
+};
diff --git a/libavcodec/version.h b/libavcodec/version.h
index a56e415..dceeaa4 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -29,8 +29,8 @@
 #include "libavutil/avutil.h"
 
 #define LIBAVCODEC_VERSION_MAJOR 54
-#define LIBAVCODEC_VERSION_MINOR 78
-#define LIBAVCODEC_VERSION_MICRO 101
+#define LIBAVCODEC_VERSION_MINOR 92
+#define LIBAVCODEC_VERSION_MICRO 100
 
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
                                                LIBAVCODEC_VERSION_MINOR, \
@@ -103,5 +103,8 @@
 #ifndef FF_API_MMI
 #define FF_API_MMI               (LIBAVCODEC_VERSION_MAJOR < 55)
 #endif
+#ifndef FF_API_IDCT
+#define FF_API_IDCT              (LIBAVCODEC_VERSION_MAJOR < 55)
+#endif
 
 #endif /* AVCODEC_VERSION_H */
diff --git a/libavcodec/videodsp.c b/libavcodec/videodsp.c
new file mode 100644
index 0000000..f91bac3
--- /dev/null
+++ b/libavcodec/videodsp.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2012 Ronald S. Bultje
+ *
+ * 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 "libavutil/common.h"
+#include "videodsp.h"
+
+#define BIT_DEPTH 8
+#include "videodsp_template.c"
+#undef BIT_DEPTH
+
+#define BIT_DEPTH 16
+#include "videodsp_template.c"
+#undef BIT_DEPTH
+
+static void just_return(uint8_t *buf, ptrdiff_t stride, int h)
+{
+}
+
+void ff_videodsp_init(VideoDSPContext *ctx, int bpc)
+{
+    ctx->prefetch = just_return;
+    if (bpc <= 8) {
+        ctx->emulated_edge_mc = ff_emulated_edge_mc_8;
+    } else {
+        ctx->emulated_edge_mc = ff_emulated_edge_mc_16;
+    }
+
+    if (ARCH_ARM)
+        ff_videodsp_init_arm(ctx, bpc);
+    if (ARCH_PPC)
+        ff_videodsp_init_ppc(ctx, bpc);
+    if (ARCH_X86)
+        ff_videodsp_init_x86(ctx, bpc);
+}
diff --git a/libavcodec/videodsp.h b/libavcodec/videodsp.h
new file mode 100644
index 0000000..e397720
--- /dev/null
+++ b/libavcodec/videodsp.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2012 Ronald S. Bultje
+ *
+ * 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
+ * Core video DSP helper functions
+ */
+
+#ifndef AVCODEC_VIDEODSP_H
+#define AVCODEC_VIDEODSP_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#define EMULATED_EDGE(depth) \
+void ff_emulated_edge_mc_ ## depth (uint8_t *buf, const uint8_t *src, ptrdiff_t linesize,\
+                         int block_w, int block_h,\
+                         int src_x, int src_y, int w, int h);
+
+EMULATED_EDGE(8)
+EMULATED_EDGE(16)
+
+typedef struct VideoDSPContext {
+    /**
+     * Copy a rectangular area of samples to a temporary buffer and replicate
+     * the border samples.
+     *
+     * @param buf destination buffer
+     * @param src source buffer
+     * @param linesize number of bytes between 2 vertically adjacent samples
+     *                 in both the source and destination buffers
+     * @param block_w width of block
+     * @param block_h height of block
+     * @param src_x x coordinate of the top left sample of the block in the
+     *                source buffer
+     * @param src_y y coordinate of the top left sample of the block in the
+     *                source buffer
+     * @param w width of the source buffer
+     * @param h height of the source buffer
+     */
+    void (*emulated_edge_mc)(uint8_t *buf, const uint8_t *src,
+                             ptrdiff_t linesize, int block_w, int block_h,
+                             int src_x, int src_y, int w, int h);
+
+    /**
+     * Prefetch memory into cache (if supported by hardware).
+     *
+     * @buf pointer to buffer to prefetch memory from
+     * @stride distance between two lines of buf (in bytes)
+     * @h number of lines to prefetch
+     */
+    void (*prefetch)(uint8_t *buf, ptrdiff_t stride, int h);
+} VideoDSPContext;
+
+void ff_videodsp_init(VideoDSPContext *ctx, int bpc);
+
+/* for internal use only (i.e. called by ff_videodsp_init() */
+void ff_videodsp_init_arm(VideoDSPContext *ctx, int bpc);
+void ff_videodsp_init_ppc(VideoDSPContext *ctx, int bpc);
+void ff_videodsp_init_x86(VideoDSPContext *ctx, int bpc);
+
+#endif /* AVCODEC_VIDEODSP_H */
diff --git a/libavcodec/videodsp_template.c b/libavcodec/videodsp_template.c
new file mode 100644
index 0000000..44f6a4d
--- /dev/null
+++ b/libavcodec/videodsp_template.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2002-2012 Michael Niedermayer
+ * Copyright (C) 2012 Ronald S. Bultje
+ *
+ * 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 "bit_depth_template.c"
+void FUNC(ff_emulated_edge_mc)(uint8_t *buf, const uint8_t *src,
+                                      ptrdiff_t linesize_arg,
+                                      int block_w, int block_h,
+                                      int src_x, int src_y, int w, int h)
+{
+    int x, y;
+    int start_y, start_x, end_y, end_x;
+    int linesize = linesize_arg;
+
+    if (!w || !h)
+        return;
+
+    if (src_y >= h) {
+        src -= src_y * linesize;
+        src += (h - 1) * linesize;
+        src_y = h - 1;
+    } else if (src_y <= -block_h) {
+        src -= src_y * linesize;
+        src += (1 - block_h) * linesize;
+        src_y = 1 - block_h;
+    }
+    if (src_x >= w) {
+        src  += (w - 1 - src_x) * sizeof(pixel);
+        src_x = w - 1;
+    } else if (src_x <= -block_w) {
+        src  += (1 - block_w - src_x) * sizeof(pixel);
+        src_x = 1 - block_w;
+    }
+
+    start_y = FFMAX(0, -src_y);
+    start_x = FFMAX(0, -src_x);
+    end_y = FFMIN(block_h, h-src_y);
+    end_x = FFMIN(block_w, w-src_x);
+    av_assert2(start_y < end_y && block_h);
+    av_assert2(start_x < end_x && block_w);
+
+    w    = end_x - start_x;
+    src += start_y * linesize + start_x * sizeof(pixel);
+    buf += start_x * sizeof(pixel);
+
+    // top
+    for (y = 0; y < start_y; y++) {
+        memcpy(buf, src, w * sizeof(pixel));
+        buf += linesize;
+    }
+
+    // copy existing part
+    for (; y < end_y; y++) {
+        memcpy(buf, src, w * sizeof(pixel));
+        src += linesize;
+        buf += linesize;
+    }
+
+    // bottom
+    src -= linesize;
+    for (; y < block_h; y++) {
+        memcpy(buf, src, w * sizeof(pixel));
+        buf += linesize;
+    }
+
+    buf -= block_h * linesize + start_x * sizeof(pixel);
+    while (block_h--) {
+        pixel *bufp = (pixel *) buf;
+
+        // left
+        for(x = 0; x < start_x; x++) {
+            bufp[x] = bufp[start_x];
+        }
+
+        // right
+        for (x = end_x; x < block_w; x++) {
+            bufp[x] = bufp[end_x - 1];
+        }
+        buf += linesize;
+    }
+}
diff --git a/libavcodec/vima.c b/libavcodec/vima.c
index 35e2a3c..604e0ce 100644
--- a/libavcodec/vima.c
+++ b/libavcodec/vima.c
@@ -22,10 +22,10 @@
 #include "libavutil/channel_layout.h"
 #include "avcodec.h"
 #include "get_bits.h"
+#include "internal.h"
 #include "adpcm_data.h"
 
 typedef struct {
-    AVFrame     frame;
     uint16_t    predict_table[5786 * 2];
 } VimaContext;
 
@@ -124,8 +124,6 @@
         }
     }
 
-    avcodec_get_frame_defaults(&vima->frame);
-    avctx->coded_frame = &vima->frame;
     avctx->sample_fmt  = AV_SAMPLE_FMT_S16;
 
     return 0;
@@ -136,6 +134,7 @@
 {
     GetBitContext  gb;
     VimaContext    *vima = avctx->priv_data;
+    AVFrame        *frame = data;
     int16_t        pcm_data[2];
     uint32_t       samples;
     int8_t         channel_hint[2];
@@ -144,7 +143,8 @@
     if (pkt->size < 13)
         return AVERROR_INVALIDDATA;
 
-    init_get_bits(&gb, pkt->data, pkt->size * 8);
+    if ((ret = init_get_bits8(&gb, pkt->data, pkt->size)) < 0)
+        return ret;
 
     samples = get_bits_long(&gb, 32);
     if (samples == 0xffffffff) {
@@ -169,14 +169,14 @@
         pcm_data[1] = get_sbits(&gb, 16);
     }
 
-    vima->frame.nb_samples = samples;
-    if ((ret = avctx->get_buffer(avctx, &vima->frame)) < 0) {
+    frame->nb_samples = samples;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
 
     for (chan = 0; chan < channels; chan++) {
-        uint16_t *dest = (uint16_t*)vima->frame.data[0] + chan;
+        uint16_t *dest = (uint16_t*)frame->data[0] + chan;
         int step_index = channel_hint[chan];
         int output = pcm_data[chan];
         int sample;
@@ -219,7 +219,6 @@
     }
 
     *got_frame_ptr   = 1;
-    *(AVFrame *)data = vima->frame;
 
     return pkt->size;
 }
diff --git a/libavcodec/vmdav.c b/libavcodec/vmdav.c
index 6e92e18..d7f136c 100644
--- a/libavcodec/vmdav.c
+++ b/libavcodec/vmdav.c
@@ -47,6 +47,7 @@
 #include "libavutil/common.h"
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
+#include "internal.h"
 
 #define VMD_HEADER_SIZE 0x330
 #define PALETTE_COUNT 256
@@ -411,7 +412,7 @@
 }
 
 static int vmdvideo_decode_frame(AVCodecContext *avctx,
-                                 void *data, int *data_size,
+                                 void *data, int *got_frame,
                                  AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
@@ -425,7 +426,7 @@
         return buf_size;
 
     s->frame.reference = 3;
-    if (avctx->get_buffer(avctx, &s->frame)) {
+    if (ff_get_buffer(avctx, &s->frame)) {
         av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return -1;
     }
@@ -440,7 +441,7 @@
     if (s->frame.data[0])
         avctx->release_buffer(avctx, &s->frame);
 
-    *data_size = sizeof(AVFrame);
+    *got_frame      = 1;
     *(AVFrame*)data = s->prev_frame;
 
     /* report that the buffer was completely consumed */
@@ -468,7 +469,6 @@
 #define BLOCK_TYPE_SILENCE  3
 
 typedef struct VmdAudioContext {
-    AVFrame frame;
     int out_bps;
     int chunk_size;
 } VmdAudioContext;
@@ -513,9 +513,6 @@
 
     s->chunk_size = avctx->block_align + avctx->channels * (s->out_bps == 2);
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     av_log(avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, "
            "block align = %d, sample rate = %d\n",
            avctx->channels, avctx->bits_per_coded_sample, avctx->block_align,
@@ -556,6 +553,7 @@
 static int vmdaudio_decode_frame(AVCodecContext *avctx, void *data,
                                  int *got_frame_ptr, AVPacket *avpkt)
 {
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     const uint8_t *buf_end;
     int buf_size = avpkt->size;
@@ -600,13 +598,14 @@
     audio_chunks = buf_size / s->chunk_size;
 
     /* get output buffer */
-    s->frame.nb_samples = ((silent_chunks + audio_chunks) * avctx->block_align) / avctx->channels;
-    if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = ((silent_chunks + audio_chunks) * avctx->block_align) /
+                        avctx->channels;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    output_samples_u8  = s->frame.data[0];
-    output_samples_s16 = (int16_t *)s->frame.data[0];
+    output_samples_u8  =            frame->data[0];
+    output_samples_s16 = (int16_t *)frame->data[0];
 
     /* decode silent chunks */
     if (silent_chunks > 0) {
@@ -636,8 +635,7 @@
         }
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
+    *got_frame_ptr = 1;
 
     return avpkt->size;
 }
diff --git a/libavcodec/vmnc.c b/libavcodec/vmnc.c
index d465f30..eb39fc9 100644
--- a/libavcodec/vmnc.c
+++ b/libavcodec/vmnc.c
@@ -285,7 +285,8 @@
     return src - ssrc;
 }
 
-static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt)
+static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
+                        AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
@@ -454,7 +455,7 @@
             put_cursor(outptr, c->pic.linesize[0], c, c->cur_x, c->cur_y);
         }
     }
-    *data_size = sizeof(AVFrame);
+    *got_frame      = 1;
     *(AVFrame*)data = c->pic;
 
     /* always report that the buffer was completely consumed */
diff --git a/libavcodec/vorbis.c b/libavcodec/vorbis.c
index adf08b5..6eb765d 100644
--- a/libavcodec/vorbis.c
+++ b/libavcodec/vorbis.c
@@ -121,7 +121,7 @@
     return 0;
 }
 
-int ff_vorbis_ready_floor1_list(AVCodecContext *avccontext,
+int ff_vorbis_ready_floor1_list(AVCodecContext *avctx,
                                 vorbis_floor1_entry *list, int values)
 {
     int i;
@@ -147,7 +147,7 @@
         int j;
         for (j = i + 1; j < values; j++) {
             if (list[i].x == list[j].x) {
-                av_log(avccontext, AV_LOG_ERROR,
+                av_log(avctx, AV_LOG_ERROR,
                        "Duplicate value found in floor 1 X coordinates\n");
                 return AVERROR_INVALIDDATA;
             }
diff --git a/libavcodec/vorbis.h b/libavcodec/vorbis.h
index 0bab0b9..98dd14f 100644
--- a/libavcodec/vorbis.h
+++ b/libavcodec/vorbis.h
@@ -36,14 +36,14 @@
     uint16_t high;
 } vorbis_floor1_entry;
 
-int ff_vorbis_ready_floor1_list(AVCodecContext *avccontext,
+int ff_vorbis_ready_floor1_list(AVCodecContext *avctx,
                                 vorbis_floor1_entry *list, int values);
 unsigned int ff_vorbis_nth_root(unsigned int x, unsigned int n); // x^(1/n)
 int ff_vorbis_len2vlc(uint8_t *bits, uint32_t *codes, unsigned num);
 void ff_vorbis_floor1_render_list(vorbis_floor1_entry * list, int values,
                                   uint16_t *y_list, int *flag,
                                   int multiplier, float * out, int samples);
-void ff_vorbis_inverse_coupling(float *mag, float *ang, int blocksize);
+void ff_vorbis_inverse_coupling(float *mag, float *ang, intptr_t blocksize);
 
 #define ilog(i) av_log2(2*(i))
 
diff --git a/libavcodec/vorbis_data.c b/libavcodec/vorbis_data.c
index 8aa8015..063a075 100644
--- a/libavcodec/vorbis_data.c
+++ b/libavcodec/vorbis_data.c
@@ -20,7 +20,6 @@
 
 #include "libavutil/channel_layout.h"
 #include "libavutil/mem.h"
-#include "dsputil.h"
 #include "vorbis.h"
 
 const uint8_t ff_vorbis_channel_layout_offsets[8][8] = {
diff --git a/libavcodec/vorbisdec.c b/libavcodec/vorbisdec.c
index 8654b42..e738654 100644
--- a/libavcodec/vorbisdec.c
+++ b/libavcodec/vorbisdec.c
@@ -34,11 +34,12 @@
 #include "libavutil/avassert.h"
 #include "avcodec.h"
 #include "get_bits.h"
-#include "dsputil.h"
 #include "fft.h"
 #include "fmtconvert.h"
+#include "internal.h"
 
 #include "vorbis.h"
+#include "vorbisdsp.h"
 #include "xiph.h"
 
 #define V_NB_BITS 8
@@ -123,10 +124,9 @@
 } vorbis_mode;
 
 typedef struct vorbis_context_s {
-    AVCodecContext *avccontext;
-    AVFrame frame;
+    AVCodecContext *avctx;
     GetBitContext gb;
-    DSPContext dsp;
+    VorbisDSPContext dsp;
     AVFloatDSPContext fdsp;
     FmtConvertContext fmt_conv;
 
@@ -164,7 +164,7 @@
 static const char idx_err_str[] = "Index value %d out of range (0 - %d) for %s at %s:%i\n";
 #define VALIDATE_INDEX(idx, limit) \
     if (idx >= limit) {\
-        av_log(vc->avccontext, AV_LOG_ERROR,\
+        av_log(vc->avctx, AV_LOG_ERROR,\
                idx_err_str,\
                (int)(idx), (int)(limit - 1), #idx, __FILE__, __LINE__);\
         return AVERROR_INVALIDDATA;\
@@ -194,37 +194,41 @@
     av_freep(&vc->channel_residues);
     av_freep(&vc->saved);
 
-    for (i = 0; i < vc->residue_count; i++)
-        av_free(vc->residues[i].classifs);
+    if (vc->residues)
+        for (i = 0; i < vc->residue_count; i++)
+            av_free(vc->residues[i].classifs);
     av_freep(&vc->residues);
     av_freep(&vc->modes);
 
     ff_mdct_end(&vc->mdct[0]);
     ff_mdct_end(&vc->mdct[1]);
 
-    for (i = 0; i < vc->codebook_count; ++i) {
-        av_free(vc->codebooks[i].codevectors);
-        ff_free_vlc(&vc->codebooks[i].vlc);
-    }
+    if (vc->codebooks)
+        for (i = 0; i < vc->codebook_count; ++i) {
+            av_free(vc->codebooks[i].codevectors);
+            ff_free_vlc(&vc->codebooks[i].vlc);
+        }
     av_freep(&vc->codebooks);
 
-    for (i = 0; i < vc->floor_count; ++i) {
-        if (vc->floors[i].floor_type == 0) {
-            av_free(vc->floors[i].data.t0.map[0]);
-            av_free(vc->floors[i].data.t0.map[1]);
-            av_free(vc->floors[i].data.t0.book_list);
-            av_free(vc->floors[i].data.t0.lsp);
-        } else {
-            av_free(vc->floors[i].data.t1.list);
+    if (vc->floors)
+        for (i = 0; i < vc->floor_count; ++i) {
+            if (vc->floors[i].floor_type == 0) {
+                av_free(vc->floors[i].data.t0.map[0]);
+                av_free(vc->floors[i].data.t0.map[1]);
+                av_free(vc->floors[i].data.t0.book_list);
+                av_free(vc->floors[i].data.t0.lsp);
+            } else {
+                av_free(vc->floors[i].data.t1.list);
+            }
         }
-    }
     av_freep(&vc->floors);
 
-    for (i = 0; i < vc->mapping_count; ++i) {
-        av_free(vc->mappings[i].magnitude);
-        av_free(vc->mappings[i].angle);
-        av_free(vc->mappings[i].mux);
-    }
+    if (vc->mappings)
+        for (i = 0; i < vc->mapping_count; ++i) {
+            av_free(vc->mappings[i].magnitude);
+            av_free(vc->mappings[i].angle);
+            av_free(vc->mappings[i].mux);
+        }
     av_freep(&vc->mappings);
 }
 
@@ -257,7 +261,7 @@
         av_dlog(NULL, " %u. Codebook\n", cb);
 
         if (get_bits(gb, 24) != 0x564342) {
-            av_log(vc->avccontext, AV_LOG_ERROR,
+            av_log(vc->avctx, AV_LOG_ERROR,
                    " %u. Codebook setup data corrupt.\n", cb);
             ret = AVERROR_INVALIDDATA;
             goto error;
@@ -265,7 +269,7 @@
 
         codebook_setup->dimensions=get_bits(gb, 16);
         if (codebook_setup->dimensions > 16 || codebook_setup->dimensions == 0) {
-            av_log(vc->avccontext, AV_LOG_ERROR,
+            av_log(vc->avctx, AV_LOG_ERROR,
                    " %u. Codebook's dimension is invalid (%d).\n",
                    cb, codebook_setup->dimensions);
             ret = AVERROR_INVALIDDATA;
@@ -273,7 +277,7 @@
         }
         entries = get_bits(gb, 24);
         if (entries > V_MAX_VLCS) {
-            av_log(vc->avccontext, AV_LOG_ERROR,
+            av_log(vc->avctx, AV_LOG_ERROR,
                    " %u. Codebook has too many entries (%u).\n",
                    cb, entries);
             ret = AVERROR_INVALIDDATA;
@@ -333,7 +337,7 @@
                 current_entry+=number;
             }
             if (current_entry>used_entries) {
-                av_log(vc->avccontext, AV_LOG_ERROR, " More codelengths than codes in codebook. \n");
+                av_log(vc->avctx, AV_LOG_ERROR, " More codelengths than codes in codebook. \n");
                 ret = AVERROR_INVALIDDATA;
                 goto error;
             }
@@ -380,7 +384,7 @@
                     float last = 0.0;
                     unsigned lookup_offset = i;
 
-                    av_dlog(vc->avccontext, "Lookup offset %u ,", i);
+                    av_dlog(vc->avctx, "Lookup offset %u ,", i);
 
                     for (k = 0; k < dim; ++k) {
                         unsigned multiplicand_offset = lookup_offset % codebook_lookup_values;
@@ -391,30 +395,30 @@
                     }
                     tmp_vlc_bits[j] = tmp_vlc_bits[i];
 
-                    av_dlog(vc->avccontext, "real lookup offset %u, vector: ", j);
+                    av_dlog(vc->avctx, "real lookup offset %u, vector: ", j);
                     for (k = 0; k < dim; ++k)
-                        av_dlog(vc->avccontext, " %f ",
+                        av_dlog(vc->avctx, " %f ",
                                 codebook_setup->codevectors[j * dim + k]);
-                    av_dlog(vc->avccontext, "\n");
+                    av_dlog(vc->avctx, "\n");
 
                     ++j;
                 }
             }
             if (j != used_entries) {
-                av_log(vc->avccontext, AV_LOG_ERROR, "Bug in codevector vector building code. \n");
+                av_log(vc->avctx, AV_LOG_ERROR, "Bug in codevector vector building code. \n");
                 ret = AVERROR_INVALIDDATA;
                 goto error;
             }
             entries = used_entries;
         } else if (codebook_setup->lookup_type >= 2) {
-            av_log(vc->avccontext, AV_LOG_ERROR, "Codebook lookup type not supported. \n");
+            av_log(vc->avctx, AV_LOG_ERROR, "Codebook lookup type not supported. \n");
             ret = AVERROR_INVALIDDATA;
             goto error;
         }
 
 // Initialize VLC table
         if (ff_vorbis_len2vlc(tmp_vlc_bits, tmp_vlc_codes, entries)) {
-            av_log(vc->avccontext, AV_LOG_ERROR, " Invalid code lengths while generating vlcs. \n");
+            av_log(vc->avctx, AV_LOG_ERROR, " Invalid code lengths while generating vlcs. \n");
             ret = AVERROR_INVALIDDATA;
             goto error;
         }
@@ -435,7 +439,7 @@
                             sizeof(*tmp_vlc_bits), tmp_vlc_codes,
                             sizeof(*tmp_vlc_codes), sizeof(*tmp_vlc_codes),
                             INIT_VLC_LE))) {
-            av_log(vc->avccontext, AV_LOG_ERROR, " Error generating vlc tables. \n");
+            av_log(vc->avctx, AV_LOG_ERROR, " Error generating vlc tables. \n");
             goto error;
         }
     }
@@ -467,7 +471,7 @@
                 vorbis_time_count, vorbis_tdtransform);
 
         if (vorbis_tdtransform) {
-            av_log(vc->avccontext, AV_LOG_ERROR, "Vorbis time domain transform data nonzero. \n");
+            av_log(vc->avctx, AV_LOG_ERROR, "Vorbis time domain transform data nonzero. \n");
             return AVERROR_INVALIDDATA;
         }
     }
@@ -557,7 +561,7 @@
             rangebits = get_bits(gb, 4);
             rangemax = (1 << rangebits);
             if (rangemax > vc->blocksize[1] / 2) {
-                av_log(vc->avccontext, AV_LOG_ERROR,
+                av_log(vc->avctx, AV_LOG_ERROR,
                        "Floor value is too large for blocksize: %u (%"PRIu32")\n",
                        rangemax, vc->blocksize[1] / 2);
                 return AVERROR_INVALIDDATA;
@@ -575,7 +579,7 @@
             }
 
 // Precalculate order of x coordinates - needed for decode
-            if (ff_vorbis_ready_floor1_list(vc->avccontext,
+            if (ff_vorbis_ready_floor1_list(vc->avctx,
                                             floor_setup->data.t1.list,
                                             floor_setup->data.t1.x_list_dim)) {
                 return AVERROR_INVALIDDATA;
@@ -586,20 +590,22 @@
             floor_setup->decode = vorbis_floor0_decode;
 
             floor_setup->data.t0.order          = get_bits(gb,  8);
+            if (!floor_setup->data.t0.order) {
+                av_log(vc->avctx, AV_LOG_ERROR, "Floor 0 order is 0.\n");
+                return AVERROR_INVALIDDATA;
+            }
             floor_setup->data.t0.rate           = get_bits(gb, 16);
+            if (!floor_setup->data.t0.rate) {
+                av_log(vc->avctx, AV_LOG_ERROR, "Floor 0 rate is 0.\n");
+                return AVERROR_INVALIDDATA;
+            }
             floor_setup->data.t0.bark_map_size  = get_bits(gb, 16);
+            if (!floor_setup->data.t0.bark_map_size) {
+                av_log(vc->avctx, AV_LOG_ERROR,
+                       "Floor 0 bark map size is 0.\n");
+                return AVERROR_INVALIDDATA;
+            }
             floor_setup->data.t0.amplitude_bits = get_bits(gb,  6);
-            /* zero would result in a div by zero later *
-             * 2^0 - 1 == 0                             */
-            if (floor_setup->data.t0.amplitude_bits == 0) {
-                av_log(vc->avccontext, AV_LOG_ERROR,
-                       "Floor 0 amplitude bits is 0.\n");
-                return AVERROR_INVALIDDATA;
-            }
-            if (floor_setup->data.t0.bark_map_size == 0) {
-                av_log(vc->avccontext, AV_LOG_ERROR, "Floor 0 bark map size is 0.\n");
-                return AVERROR_INVALIDDATA;
-            }
             floor_setup->data.t0.amplitude_offset = get_bits(gb, 8);
             floor_setup->data.t0.num_books        = get_bits(gb, 4) + 1;
 
@@ -651,7 +657,7 @@
                 }
             }
         } else {
-            av_log(vc->avccontext, AV_LOG_ERROR, "Invalid floor type!\n");
+            av_log(vc->avctx, AV_LOG_ERROR, "Invalid floor type!\n");
             return AVERROR_INVALIDDATA;
         }
     }
@@ -686,7 +692,7 @@
         if (res_setup->begin>res_setup->end ||
             res_setup->end > (res_setup->type == 2 ? vc->audio_channels : 1) * vc->blocksize[1] / 2 ||
             (res_setup->end-res_setup->begin) / res_setup->partition_size > V_MAX_PARTITIONS) {
-            av_log(vc->avccontext, AV_LOG_ERROR,
+            av_log(vc->avctx, AV_LOG_ERROR,
                    "partition out of bounds: type, begin, end, size, blocksize: %"PRIu16", %"PRIu32", %"PRIu32", %u, %"PRIu32"\n",
                    res_setup->type, res_setup->begin, res_setup->end,
                    res_setup->partition_size, vc->blocksize[1] / 2);
@@ -754,7 +760,7 @@
         vorbis_mapping *mapping_setup = &vc->mappings[i];
 
         if (get_bits(gb, 16)) {
-            av_log(vc->avccontext, AV_LOG_ERROR, "Other mappings than type 0 are not compliant with the Vorbis I specification. \n");
+            av_log(vc->avctx, AV_LOG_ERROR, "Other mappings than type 0 are not compliant with the Vorbis I specification. \n");
             return AVERROR_INVALIDDATA;
         }
         if (get_bits1(gb)) {
@@ -781,7 +787,7 @@
                 i, mapping_setup->coupling_steps);
 
         if (get_bits(gb, 2)) {
-            av_log(vc->avccontext, AV_LOG_ERROR, "%u. mapping setup data invalid.\n", i);
+            av_log(vc->avctx, AV_LOG_ERROR, "%u. mapping setup data invalid.\n", i);
             return AVERROR_INVALIDDATA; // following spec.
         }
 
@@ -873,36 +879,36 @@
     if ((get_bits(gb, 8) != 'v') || (get_bits(gb, 8) != 'o') ||
         (get_bits(gb, 8) != 'r') || (get_bits(gb, 8) != 'b') ||
         (get_bits(gb, 8) != 'i') || (get_bits(gb, 8) != 's')) {
-        av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (no vorbis signature). \n");
+        av_log(vc->avctx, AV_LOG_ERROR, " Vorbis setup header packet corrupt (no vorbis signature). \n");
         return AVERROR_INVALIDDATA;
     }
 
     if ((ret = vorbis_parse_setup_hdr_codebooks(vc))) {
-        av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (codebooks). \n");
+        av_log(vc->avctx, AV_LOG_ERROR, " Vorbis setup header packet corrupt (codebooks). \n");
         return ret;
     }
     if ((ret = vorbis_parse_setup_hdr_tdtransforms(vc))) {
-        av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (time domain transforms). \n");
+        av_log(vc->avctx, AV_LOG_ERROR, " Vorbis setup header packet corrupt (time domain transforms). \n");
         return ret;
     }
     if ((ret = vorbis_parse_setup_hdr_floors(vc))) {
-        av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (floors). \n");
+        av_log(vc->avctx, AV_LOG_ERROR, " Vorbis setup header packet corrupt (floors). \n");
         return ret;
     }
     if ((ret = vorbis_parse_setup_hdr_residues(vc))) {
-        av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (residues). \n");
+        av_log(vc->avctx, AV_LOG_ERROR, " Vorbis setup header packet corrupt (residues). \n");
         return ret;
     }
     if ((ret = vorbis_parse_setup_hdr_mappings(vc))) {
-        av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (mappings). \n");
+        av_log(vc->avctx, AV_LOG_ERROR, " Vorbis setup header packet corrupt (mappings). \n");
         return ret;
     }
     if ((ret = vorbis_parse_setup_hdr_modes(vc))) {
-        av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (modes). \n");
+        av_log(vc->avctx, AV_LOG_ERROR, " Vorbis setup header packet corrupt (modes). \n");
         return ret;
     }
     if (!get_bits1(gb)) {
-        av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (framing flag). \n");
+        av_log(vc->avctx, AV_LOG_ERROR, " Vorbis setup header packet corrupt (framing flag). \n");
         return AVERROR_INVALIDDATA; // framing flag bit unset error
     }
 
@@ -919,19 +925,19 @@
     if ((get_bits(gb, 8) != 'v') || (get_bits(gb, 8) != 'o') ||
         (get_bits(gb, 8) != 'r') || (get_bits(gb, 8) != 'b') ||
         (get_bits(gb, 8) != 'i') || (get_bits(gb, 8) != 's')) {
-        av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis id header packet corrupt (no vorbis signature). \n");
+        av_log(vc->avctx, AV_LOG_ERROR, " Vorbis id header packet corrupt (no vorbis signature). \n");
         return AVERROR_INVALIDDATA;
     }
 
     vc->version        = get_bits_long(gb, 32);    //FIXME check 0
     vc->audio_channels = get_bits(gb, 8);
     if (vc->audio_channels <= 0) {
-        av_log(vc->avccontext, AV_LOG_ERROR, "Invalid number of channels\n");
+        av_log(vc->avctx, AV_LOG_ERROR, "Invalid number of channels\n");
         return AVERROR_INVALIDDATA;
     }
     vc->audio_samplerate = get_bits_long(gb, 32);
     if (vc->audio_samplerate <= 0) {
-        av_log(vc->avccontext, AV_LOG_ERROR, "Invalid samplerate\n");
+        av_log(vc->avctx, AV_LOG_ERROR, "Invalid samplerate\n");
         return AVERROR_INVALIDDATA;
     }
     vc->bitrate_maximum = get_bits_long(gb, 32);
@@ -940,7 +946,7 @@
     bl0 = get_bits(gb, 4);
     bl1 = get_bits(gb, 4);
     if (bl0 > 13 || bl0 < 6 || bl1 > 13 || bl1 < 6 || bl1 < bl0) {
-        av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis id header packet corrupt (illegal blocksize). \n");
+        av_log(vc->avctx, AV_LOG_ERROR, " Vorbis id header packet corrupt (illegal blocksize). \n");
         return AVERROR_INVALIDDATA;
     }
     vc->blocksize[0] = (1 << bl0);
@@ -949,7 +955,7 @@
     vc->win[1] = ff_vorbis_vwin[bl1 - 6];
 
     if ((get_bits1(gb)) == 0) {
-        av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis id header packet corrupt (framing flag not set). \n");
+        av_log(vc->avctx, AV_LOG_ERROR, " Vorbis id header packet corrupt (framing flag not set). \n");
         return AVERROR_INVALIDDATA;
     }
 
@@ -975,41 +981,41 @@
 
 // Process the extradata using the functions above (identification header, setup header)
 
-static av_cold int vorbis_decode_init(AVCodecContext *avccontext)
+static av_cold int vorbis_decode_init(AVCodecContext *avctx)
 {
-    vorbis_context *vc = avccontext->priv_data;
-    uint8_t *headers   = avccontext->extradata;
-    int headers_len    = avccontext->extradata_size;
+    vorbis_context *vc = avctx->priv_data;
+    uint8_t *headers   = avctx->extradata;
+    int headers_len    = avctx->extradata_size;
     uint8_t *header_start[3];
     int header_len[3];
     GetBitContext *gb = &vc->gb;
     int hdr_type, ret;
 
-    vc->avccontext = avccontext;
-    ff_dsputil_init(&vc->dsp, avccontext);
-    avpriv_float_dsp_init(&vc->fdsp, avccontext->flags & CODEC_FLAG_BITEXACT);
-    ff_fmt_convert_init(&vc->fmt_conv, avccontext);
+    vc->avctx = avctx;
+    ff_vorbisdsp_init(&vc->dsp);
+    avpriv_float_dsp_init(&vc->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
+    ff_fmt_convert_init(&vc->fmt_conv, avctx);
 
-    avccontext->sample_fmt = AV_SAMPLE_FMT_FLTP;
+    avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
 
     if (!headers_len) {
-        av_log(avccontext, AV_LOG_ERROR, "Extradata missing.\n");
+        av_log(avctx, AV_LOG_ERROR, "Extradata missing.\n");
         return AVERROR_INVALIDDATA;
     }
 
     if ((ret = avpriv_split_xiph_headers(headers, headers_len, 30, header_start, header_len)) < 0) {
-        av_log(avccontext, AV_LOG_ERROR, "Extradata corrupt.\n");
+        av_log(avctx, AV_LOG_ERROR, "Extradata corrupt.\n");
         return ret;
     }
 
     init_get_bits(gb, header_start[0], header_len[0]*8);
     hdr_type = get_bits(gb, 8);
     if (hdr_type != 1) {
-        av_log(avccontext, AV_LOG_ERROR, "First header is not the id header.\n");
+        av_log(avctx, AV_LOG_ERROR, "First header is not the id header.\n");
         return AVERROR_INVALIDDATA;
     }
     if ((ret = vorbis_parse_id_hdr(vc))) {
-        av_log(avccontext, AV_LOG_ERROR, "Id header corrupt.\n");
+        av_log(avctx, AV_LOG_ERROR, "Id header corrupt.\n");
         vorbis_free(vc);
         return ret;
     }
@@ -1017,26 +1023,23 @@
     init_get_bits(gb, header_start[2], header_len[2]*8);
     hdr_type = get_bits(gb, 8);
     if (hdr_type != 5) {
-        av_log(avccontext, AV_LOG_ERROR, "Third header is not the setup header.\n");
+        av_log(avctx, AV_LOG_ERROR, "Third header is not the setup header.\n");
         vorbis_free(vc);
         return AVERROR_INVALIDDATA;
     }
     if ((ret = vorbis_parse_setup_hdr(vc))) {
-        av_log(avccontext, AV_LOG_ERROR, "Setup header corrupt.\n");
+        av_log(avctx, AV_LOG_ERROR, "Setup header corrupt.\n");
         vorbis_free(vc);
         return ret;
     }
 
     if (vc->audio_channels > 8)
-        avccontext->channel_layout = 0;
+        avctx->channel_layout = 0;
     else
-        avccontext->channel_layout = ff_vorbis_channel_layouts[vc->audio_channels - 1];
+        avctx->channel_layout = ff_vorbis_channel_layouts[vc->audio_channels - 1];
 
-    avccontext->channels    = vc->audio_channels;
-    avccontext->sample_rate = vc->audio_samplerate;
-
-    avcodec_get_frame_defaults(&vc->frame);
-    avccontext->coded_frame = &vc->frame;
+    avctx->channels    = vc->audio_channels;
+    avctx->sample_rate = vc->audio_samplerate;
 
     return 0;
 }
@@ -1053,6 +1056,9 @@
     unsigned amplitude, book_idx;
     unsigned blockflag = vc->modes[vc->mode_number].blockflag;
 
+    if (!vf->amplitude_bits)
+        return 1;
+
     amplitude = get_bits(&vc->gb, vf->amplitude_bits);
     if (amplitude > 0) {
         float last = 0;
@@ -1061,8 +1067,7 @@
 
         book_idx = get_bits(&vc->gb, ilog(vf->num_books));
         if (book_idx >= vf->num_books) {
-            av_log(vc->avccontext, AV_LOG_ERROR,
-                    "floor0 dec: booknumber too high!\n");
+            av_log(vc->avctx, AV_LOG_ERROR, "floor0 dec: booknumber too high!\n");
             book_idx =  0;
         }
         av_dlog(NULL, "floor0 dec: booknumber: %u\n", book_idx);
@@ -1238,7 +1243,7 @@
         if (highroom < lowroom) {
             room = highroom * 2;
         } else {
-            room = lowroom * 2;   // SPEC mispelling
+            room = lowroom * 2;   // SPEC misspelling
         }
         if (val) {
             floor1_flag[low_neigh_offs]  = 1;
@@ -1306,7 +1311,7 @@
     }
 
     if (max_output > ch_left * vlen) {
-        av_log(vc->avccontext, AV_LOG_ERROR, "Insufficient output buffer\n");
+        av_log(vc->avctx, AV_LOG_ERROR, "Insufficient output buffer\n");
         return -1;
     }
 
@@ -1450,12 +1455,12 @@
     else if (vr->type == 0)
         return vorbis_residue_decode_internal(vc, vr, ch, do_not_decode, vec, vlen, ch_left, 0);
     else {
-        av_log(vc->avccontext, AV_LOG_ERROR, " Invalid residue type while residue decode?! \n");
+        av_log(vc->avctx, AV_LOG_ERROR, " Invalid residue type while residue decode?! \n");
         return AVERROR_INVALIDDATA;
     }
 }
 
-void ff_vorbis_inverse_coupling(float *mag, float *ang, int blocksize)
+void ff_vorbis_inverse_coupling(float *mag, float *ang, intptr_t blocksize)
 {
     int i;
     for (i = 0;  i < blocksize;  i++) {
@@ -1499,7 +1504,7 @@
     unsigned vlen;
 
     if (get_bits1(gb)) {
-        av_log(vc->avccontext, AV_LOG_ERROR, "Not a Vorbis I audio packet.\n");
+        av_log(vc->avctx, AV_LOG_ERROR, "Not a Vorbis I audio packet.\n");
         return AVERROR_INVALIDDATA; // packet type not audio
     }
 
@@ -1540,7 +1545,7 @@
         ret = floor->decode(vc, &floor->data, floor_ptr[i]);
 
         if (ret < 0) {
-            av_log(vc->avccontext, AV_LOG_ERROR, "Invalid codebook in vorbis_floor_decode.\n");
+            av_log(vc->avctx, AV_LOG_ERROR, "Invalid codebook in vorbis_floor_decode.\n");
             return AVERROR_INVALIDDATA;
         }
         no_residue[i] = ret;
@@ -1576,7 +1581,7 @@
         }
         residue = &vc->residues[mapping->submap_residue[i]];
         if (ch_left < ch) {
-            av_log(vc->avccontext, AV_LOG_ERROR, "Too many channels in vorbis_floor_decode.\n");
+            av_log(vc->avctx, AV_LOG_ERROR, "Too many channels in vorbis_floor_decode.\n");
             return -1;
         }
         if (ch) {
@@ -1625,13 +1630,13 @@
         const float *win  = vc->win[blockflag & previous_window];
 
         if (blockflag == previous_window) {
-            vc->dsp.vector_fmul_window(ret, saved, buf, win, blocksize / 4);
+            vc->fdsp.vector_fmul_window(ret, saved, buf, win, blocksize / 4);
         } else if (blockflag > previous_window) {
-            vc->dsp.vector_fmul_window(ret, saved, buf, win, bs0 / 4);
+            vc->fdsp.vector_fmul_window(ret, saved, buf, win, bs0 / 4);
             memcpy(ret+bs0/2, buf+bs0/4, ((bs1-bs0)/4) * sizeof(float));
         } else {
             memcpy(ret, saved, ((bs1 - bs0) / 4) * sizeof(float));
-            vc->dsp.vector_fmul_window(ret + (bs1 - bs0) / 4, saved + (bs1 - bs0) / 4, buf, win, bs0 / 4);
+            vc->fdsp.vector_fmul_window(ret + (bs1 - bs0) / 4, saved + (bs1 - bs0) / 4, buf, win, bs0 / 4);
         }
         memcpy(saved, buf + blocksize / 4, blocksize / 4 * sizeof(float));
     }
@@ -1642,32 +1647,72 @@
 
 // Return the decoded audio packet through the standard api
 
-static int vorbis_decode_frame(AVCodecContext *avccontext, void *data,
+static int vorbis_decode_frame(AVCodecContext *avctx, void *data,
                                int *got_frame_ptr, AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
-    vorbis_context *vc = avccontext->priv_data;
+    vorbis_context *vc = avctx->priv_data;
+    AVFrame *frame     = data;
     GetBitContext *gb = &vc->gb;
     float *channel_ptrs[255];
     int i, len, ret;
 
     av_dlog(NULL, "packet length %d \n", buf_size);
 
+    if (*buf == 1 && buf_size > 7) {
+        init_get_bits(gb, buf+1, buf_size*8 - 8);
+        vorbis_free(vc);
+        if ((ret = vorbis_parse_id_hdr(vc))) {
+            av_log(avctx, AV_LOG_ERROR, "Id header corrupt.\n");
+            vorbis_free(vc);
+            return ret;
+        }
+
+        if (vc->audio_channels > 8)
+            avctx->channel_layout = 0;
+        else
+            avctx->channel_layout = ff_vorbis_channel_layouts[vc->audio_channels - 1];
+
+        avctx->channels    = vc->audio_channels;
+        avctx->sample_rate = vc->audio_samplerate;
+        return buf_size;
+    }
+
+    if (*buf == 3 && buf_size > 7) {
+        av_log(avctx, AV_LOG_DEBUG, "Ignoring comment header\n");
+        return buf_size;
+    }
+
+    if (*buf == 5 && buf_size > 7 && vc->channel_residues && !vc->modes) {
+        init_get_bits(gb, buf+1, buf_size*8 - 8);
+        if ((ret = vorbis_parse_setup_hdr(vc))) {
+            av_log(avctx, AV_LOG_ERROR, "Setup header corrupt.\n");
+            vorbis_free(vc);
+            return ret;
+        }
+        return buf_size;
+    }
+
+    if (!vc->channel_residues || !vc->modes) {
+        av_log(avctx, AV_LOG_ERROR, "Data packet before valid headers\n");
+        return AVERROR_INVALIDDATA;
+    }
+
     /* get output buffer */
-    vc->frame.nb_samples = vc->blocksize[1] / 2;
-    if ((ret = avccontext->get_buffer(avccontext, &vc->frame)) < 0) {
-        av_log(avccontext, AV_LOG_ERROR, "get_buffer() failed\n");
+    frame->nb_samples = vc->blocksize[1] / 2;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
 
     if (vc->audio_channels > 8) {
         for (i = 0; i < vc->audio_channels; i++)
-            channel_ptrs[i] = (float *)vc->frame.extended_data[i];
+            channel_ptrs[i] = (float *)frame->extended_data[i];
     } else {
         for (i = 0; i < vc->audio_channels; i++) {
             int ch = ff_vorbis_channel_layout_offsets[vc->audio_channels - 1][i];
-            channel_ptrs[ch] = (float *)vc->frame.extended_data[i];
+            channel_ptrs[ch] = (float *)frame->extended_data[i];
         }
     }
 
@@ -1685,27 +1730,26 @@
     av_dlog(NULL, "parsed %d bytes %d bits, returned %d samples (*ch*bits) \n",
             get_bits_count(gb) / 8, get_bits_count(gb) % 8, len);
 
-    vc->frame.nb_samples = len;
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = vc->frame;
+    frame->nb_samples = len;
+    *got_frame_ptr    = 1;
 
     return buf_size;
 }
 
 // Close decoder
 
-static av_cold int vorbis_decode_close(AVCodecContext *avccontext)
+static av_cold int vorbis_decode_close(AVCodecContext *avctx)
 {
-    vorbis_context *vc = avccontext->priv_data;
+    vorbis_context *vc = avctx->priv_data;
 
     vorbis_free(vc);
 
     return 0;
 }
 
-static av_cold void vorbis_decode_flush(AVCodecContext *avccontext)
+static av_cold void vorbis_decode_flush(AVCodecContext *avctx)
 {
-    vorbis_context *vc = avccontext->priv_data;
+    vorbis_context *vc = avctx->priv_data;
 
     if (vc->saved) {
         memset(vc->saved, 0, (vc->blocksize[1] / 4) * vc->audio_channels *
diff --git a/libavcodec/arm/dsputil_init_vfp.c b/libavcodec/vorbisdsp.c
similarity index 66%
copy from libavcodec/arm/dsputil_init_vfp.c
copy to libavcodec/vorbisdsp.c
index 5713c71..fd8dcd7 100644
--- a/libavcodec/arm/dsputil_init_vfp.c
+++ b/libavcodec/vorbisdsp.c
@@ -1,6 +1,4 @@
 /*
- * Copyright (c) 2008 Siarhei Siamashka <ssvb@users.sourceforge.net>
- *
  * This file is part of FFmpeg.
  *
  * FFmpeg is free software; you can redistribute it and/or
@@ -18,13 +16,18 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavcodec/dsputil.h"
-#include "dsputil_arm.h"
+#include "config.h"
+#include "vorbisdsp.h"
+#include "vorbis.h"
 
-void ff_vector_fmul_reverse_vfp(float *dst, const float *src0,
-                                const float *src1, int len);
-
-void ff_dsputil_init_vfp(DSPContext* c, AVCodecContext *avctx)
+void ff_vorbisdsp_init(VorbisDSPContext *dsp)
 {
-    c->vector_fmul_reverse = ff_vector_fmul_reverse_vfp;
+    dsp->vorbis_inverse_coupling = ff_vorbis_inverse_coupling;
+
+    if (ARCH_X86)
+        ff_vorbisdsp_init_x86(dsp);
+    if (ARCH_PPC)
+        ff_vorbisdsp_init_ppc(dsp);
+    if (ARCH_ARM)
+        ff_vorbisdsp_init_arm(dsp);
 }
diff --git a/libavcodec/vorbisdsp.h b/libavcodec/vorbisdsp.h
new file mode 100644
index 0000000..ed14049
--- /dev/null
+++ b/libavcodec/vorbisdsp.h
@@ -0,0 +1,37 @@
+/*
+ * 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_VORBISDSP_H
+#define AVCODEC_VORBISDSP_H
+
+#include <stdint.h>
+
+typedef struct VorbisDSPContext {
+    /* assume len is a multiple of 4, and arrays are 16-byte aligned */
+    void (*vorbis_inverse_coupling)(float *mag, float *ang,
+                                    intptr_t blocksize);
+} VorbisDSPContext;
+
+void ff_vorbisdsp_init(VorbisDSPContext *dsp);
+
+/* for internal use only */
+void ff_vorbisdsp_init_x86(VorbisDSPContext *dsp);
+void ff_vorbisdsp_init_arm(VorbisDSPContext *dsp);
+void ff_vorbisdsp_init_ppc(VorbisDSPContext *dsp);
+
+#endif /* AVCODEC_VORBISDSP_H */
diff --git a/libavcodec/vorbisenc.c b/libavcodec/vorbisenc.c
index 33b2577..22b6681 100644
--- a/libavcodec/vorbisenc.c
+++ b/libavcodec/vorbisenc.c
@@ -26,7 +26,6 @@
 
 #include <float.h>
 #include "avcodec.h"
-#include "dsputil.h"
 #include "internal.h"
 #include "fft.h"
 #include "vorbis.h"
@@ -236,15 +235,15 @@
 }
 
 static int create_vorbis_context(vorbis_enc_context *venc,
-                                 AVCodecContext *avccontext)
+                                 AVCodecContext *avctx)
 {
     vorbis_enc_floor   *fc;
     vorbis_enc_residue *rc;
     vorbis_enc_mapping *mc;
     int i, book, ret;
 
-    venc->channels    = avccontext->channels;
-    venc->sample_rate = avccontext->sample_rate;
+    venc->channels    = avctx->channels;
+    venc->sample_rate = avctx->sample_rate;
     venc->log2_blocksize[0] = venc->log2_blocksize[1] = 11;
 
     venc->ncodebooks = FF_ARRAY_ELEMS(cvectors);
@@ -340,7 +339,7 @@
         };
         fc->list[i].x = a[i - 2];
     }
-    if (ff_vorbis_ready_floor1_list(avccontext, fc->list, fc->values))
+    if (ff_vorbis_ready_floor1_list(avctx, fc->list, fc->values))
         return AVERROR_BUG;
 
     venc->nresidues = 1;
@@ -1014,10 +1013,10 @@
     return 1;
 }
 
-static int vorbis_encode_frame(AVCodecContext *avccontext, AVPacket *avpkt,
+static int vorbis_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
                                const AVFrame *frame, int *got_packet_ptr)
 {
-    vorbis_enc_context *venc = avccontext->priv_data;
+    vorbis_enc_context *venc = avctx->priv_data;
     float **audio = frame ? (float **)frame->extended_data : NULL;
     int samples = frame ? frame->nb_samples : 0;
     vorbis_enc_mode *mode;
@@ -1029,13 +1028,13 @@
         return 0;
     samples = 1 << (venc->log2_blocksize[0] - 1);
 
-    if ((ret = ff_alloc_packet2(avccontext, avpkt, 8192)))
+    if ((ret = ff_alloc_packet2(avctx, avpkt, 8192)))
         return ret;
 
     init_put_bits(&pb, avpkt->data, avpkt->size);
 
     if (pb.size_in_bits - put_bits_count(&pb) < 1 + ilog(venc->nmodes - 1)) {
-        av_log(avccontext, AV_LOG_ERROR, "output buffer is too small\n");
+        av_log(avctx, AV_LOG_ERROR, "output buffer is too small\n");
         return AVERROR(EINVAL);
     }
 
@@ -1055,7 +1054,7 @@
         uint16_t posts[MAX_FLOOR_VALUES];
         floor_fit(venc, fc, &venc->coeffs[i * samples], posts, samples);
         if (floor_encode(venc, fc, &pb, posts, &venc->floor[i * samples], samples)) {
-            av_log(avccontext, AV_LOG_ERROR, "output buffer is too small\n");
+            av_log(avctx, AV_LOG_ERROR, "output buffer is too small\n");
             return AVERROR(EINVAL);
         }
     }
@@ -1079,17 +1078,17 @@
 
     if (residue_encode(venc, &venc->residues[mapping->residue[mapping->mux[0]]],
                        &pb, venc->coeffs, samples, venc->channels)) {
-        av_log(avccontext, AV_LOG_ERROR, "output buffer is too small\n");
+        av_log(avctx, AV_LOG_ERROR, "output buffer is too small\n");
         return AVERROR(EINVAL);
     }
 
     flush_put_bits(&pb);
     avpkt->size = put_bits_count(&pb) >> 3;
 
-    avpkt->duration = ff_samples_to_time_base(avccontext, avccontext->frame_size);
+    avpkt->duration = ff_samples_to_time_base(avctx, avctx->frame_size);
     if (frame) {
         if (frame->pts != AV_NOPTS_VALUE)
-            avpkt->pts = ff_samples_to_time_base(avccontext, frame->pts);
+            avpkt->pts = ff_samples_to_time_base(avctx, frame->pts);
     } else
         avpkt->pts = venc->next_pts;
     if (avpkt->pts != AV_NOPTS_VALUE)
@@ -1100,9 +1099,9 @@
 }
 
 
-static av_cold int vorbis_encode_close(AVCodecContext *avccontext)
+static av_cold int vorbis_encode_close(AVCodecContext *avctx)
 {
-    vorbis_enc_context *venc = avccontext->priv_data;
+    vorbis_enc_context *venc = avctx->priv_data;
     int i;
 
     if (venc->codebooks)
@@ -1155,42 +1154,42 @@
     ff_mdct_end(&venc->mdct[1]);
 
 #if FF_API_OLD_ENCODE_AUDIO
-    av_freep(&avccontext->coded_frame);
+    av_freep(&avctx->coded_frame);
 #endif
-    av_freep(&avccontext->extradata);
+    av_freep(&avctx->extradata);
 
     return 0 ;
 }
 
-static av_cold int vorbis_encode_init(AVCodecContext *avccontext)
+static av_cold int vorbis_encode_init(AVCodecContext *avctx)
 {
-    vorbis_enc_context *venc = avccontext->priv_data;
+    vorbis_enc_context *venc = avctx->priv_data;
     int ret;
 
-    if (avccontext->channels != 2) {
-        av_log(avccontext, AV_LOG_ERROR, "Current FFmpeg Vorbis encoder only supports 2 channels.\n");
+    if (avctx->channels != 2) {
+        av_log(avctx, AV_LOG_ERROR, "Current FFmpeg Vorbis encoder only supports 2 channels.\n");
         return -1;
     }
 
-    if ((ret = create_vorbis_context(venc, avccontext)) < 0)
+    if ((ret = create_vorbis_context(venc, avctx)) < 0)
         goto error;
 
-    avccontext->bit_rate = 0;
-    if (avccontext->flags & CODEC_FLAG_QSCALE)
-        venc->quality = avccontext->global_quality / (float)FF_QP2LAMBDA;
+    avctx->bit_rate = 0;
+    if (avctx->flags & CODEC_FLAG_QSCALE)
+        venc->quality = avctx->global_quality / (float)FF_QP2LAMBDA;
     else
         venc->quality = 8;
     venc->quality *= venc->quality;
 
-    if ((ret = put_main_header(venc, (uint8_t**)&avccontext->extradata)) < 0)
+    if ((ret = put_main_header(venc, (uint8_t**)&avctx->extradata)) < 0)
         goto error;
-    avccontext->extradata_size = ret;
+    avctx->extradata_size = ret;
 
-    avccontext->frame_size = 1 << (venc->log2_blocksize[0] - 1);
+    avctx->frame_size = 1 << (venc->log2_blocksize[0] - 1);
 
 #if FF_API_OLD_ENCODE_AUDIO
-    avccontext->coded_frame = avcodec_alloc_frame();
-    if (!avccontext->coded_frame) {
+    avctx->coded_frame = avcodec_alloc_frame();
+    if (!avctx->coded_frame) {
         ret = AVERROR(ENOMEM);
         goto error;
     }
@@ -1198,7 +1197,7 @@
 
     return 0;
 error:
-    vorbis_encode_close(avccontext);
+    vorbis_encode_close(avctx);
     return ret;
 }
 
diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c
index cc6fb3a..00a77e9 100644
--- a/libavcodec/vp3.c
+++ b/libavcodec/vp3.c
@@ -38,7 +38,7 @@
 #include "internal.h"
 #include "dsputil.h"
 #include "get_bits.h"
-
+#include "videodsp.h"
 #include "vp3data.h"
 #include "vp3dsp.h"
 #include "xiph.h"
@@ -75,6 +75,10 @@
 /* special internal mode */
 #define MODE_COPY             8
 
+static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb);
+static int theora_decode_tables(AVCodecContext *avctx, GetBitContext *gb);
+
+
 /* There are 6 preset schemes, plus a free-form scheme */
 static const int ModeAlphabet[6][CODING_MODE_COUNT] =
 {
@@ -136,7 +140,9 @@
     AVFrame current_frame;
     int keyframe;
     DSPContext dsp;
+    VideoDSPContext vdsp;
     VP3DSPContext vp3dsp;
+    DECLARE_ALIGNED(16, int16_t, block)[64];
     int flipped_image;
     int last_slice_end;
     int skip_loop_filter;
@@ -290,6 +296,8 @@
     av_freep(&s->motion_val[1]);
     av_freep(&s->edge_emu_buffer);
 
+    s->theora_tables = 0;
+
     if (avctx->internal->is_copy)
         return 0;
 
@@ -918,7 +926,7 @@
     int i, j = 0;
     int token;
     int zero_run = 0;
-    DCTELEM coeff = 0;
+    int16_t coeff = 0;
     int bits_to_get;
     int blocks_ended;
     int coeff_i = 0;
@@ -1348,7 +1356,7 @@
  * for the next block in coding order
  */
 static inline int vp3_dequant(Vp3DecodeContext *s, Vp3Fragment *frag,
-                              int plane, int inter, DCTELEM block[64])
+                              int plane, int inter, int16_t block[64])
 {
     int16_t *dequantizer = s->qmat[frag->qpi][inter][plane];
     uint8_t *perm = s->scantable.permutated;
@@ -1457,7 +1465,7 @@
 static void render_slice(Vp3DecodeContext *s, int slice)
 {
     int x, y, i, j, fragment;
-    LOCAL_ALIGNED_16(DCTELEM, block, [64]);
+    int16_t *block = s->block;
     int motion_x = 0xdeadbeef, motion_y = 0xdeadbeef;
     int motion_halfpel_index;
     uint8_t *motion_source;
@@ -1543,7 +1551,7 @@
                             uint8_t *temp= s->edge_emu_buffer;
                             if(stride<0) temp -= 8*stride;
 
-                            s->dsp.emulated_edge_mc(temp, motion_source, stride, 9, 9, src_x, src_y, plane_width, plane_height);
+                            s->vdsp.emulated_edge_mc(temp, motion_source, stride, 9, 9, src_x, src_y, plane_width, plane_height);
                             motion_source= temp;
                         }
                     }
@@ -1562,7 +1570,7 @@
                                 motion_source, stride, 8);
                         }else{
                             int d= (motion_x ^ motion_y)>>31; // d is 0 if motion_x and _y have the same sign, else -1
-                            s->dsp.put_no_rnd_pixels_l2[1](
+                            s->vp3dsp.put_no_rnd_pixels_l2(
                                 output_plane + first_pixel,
                                 motion_source - d,
                                 motion_source + stride + 1 + d,
@@ -1570,8 +1578,6 @@
                         }
                     }
 
-                        s->dsp.clear_block(block);
-
                     /* invert DCT and place (or add) in final output */
 
                     if (s->all_fragments[i].coding_method == MODE_INTRA) {
@@ -1671,6 +1677,7 @@
         avctx->pix_fmt = AV_PIX_FMT_YUV420P;
     avctx->chroma_sample_location = AVCHROMA_LOC_CENTER;
     ff_dsputil_init(&s->dsp, avctx);
+    ff_videodsp_init(&s->vdsp, 8);
     ff_vp3dsp_init(&s->vp3dsp, avctx->flags);
 
     ff_init_scantable_permutation(s->dsp.idct_permutation, s->vp3dsp.idct_perm);
@@ -1903,7 +1910,7 @@
 }
 
 static int vp3_decode_frame(AVCodecContext *avctx,
-                            void *data, int *data_size,
+                            void *data, int *got_frame,
                             AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
@@ -1911,16 +1918,48 @@
     Vp3DecodeContext *s = avctx->priv_data;
     GetBitContext gb;
     int i;
+    int ret;
 
     init_get_bits(&gb, buf, buf_size * 8);
 
+#if CONFIG_THEORA_DECODER
     if (s->theora && get_bits1(&gb))
     {
+        int type = get_bits(&gb, 7);
+        skip_bits_long(&gb, 6*8); /* "theora" */
+
+        if (s->avctx->active_thread_type&FF_THREAD_FRAME) {
+            av_log(avctx, AV_LOG_ERROR, "midstream reconfiguration with multithreading is unsupported, try -threads 1\n");
+            return AVERROR_PATCHWELCOME;
+        }
+        if (type == 0) {
+            vp3_decode_end(avctx);
+            ret = theora_decode_header(avctx, &gb);
+
+            if (ret < 0) {
+                vp3_decode_end(avctx);
+            } else
+                ret = vp3_decode_init(avctx);
+            return ret;
+        } else if (type == 2) {
+            ret = theora_decode_tables(avctx, &gb);
+            if (ret < 0) {
+                vp3_decode_end(avctx);
+            } else
+                ret = vp3_decode_init(avctx);
+            return ret;
+        }
+
         av_log(avctx, AV_LOG_ERROR, "Header packet passed to frame decoder, skipping\n");
         return -1;
     }
+#endif
 
     s->keyframe = !get_bits1(&gb);
+    if (!s->all_fragments) {
+        av_log(avctx, AV_LOG_ERROR, "Data packet without prior valid headers\n");
+        return -1;
+    }
     if (!s->theora)
         skip_bits(&gb, 1);
     for (i = 0; i < 3; i++)
@@ -2040,7 +2079,7 @@
     }
     vp3_draw_horiz_band(s, s->avctx->height);
 
-    *data_size=sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*)data= s->current_frame;
 
     if (!HAVE_THREADS || !(s->avctx->active_thread_type&FF_THREAD_FRAME))
@@ -2337,6 +2376,8 @@
     }
 
   for(i=0;i<3;i++) {
+    if (header_len[i] <= 0)
+        continue;
     init_get_bits(&gb, header_start[i], header_len[i] * 8);
 
     ptype = get_bits(&gb, 8);
diff --git a/libavcodec/vp3dsp.c b/libavcodec/vp3dsp.c
index 0e0c0f5..051812e 100644
--- a/libavcodec/vp3dsp.c
+++ b/libavcodec/vp3dsp.c
@@ -28,6 +28,7 @@
 #include "libavutil/common.h"
 #include "avcodec.h"
 #include "dsputil.h"
+#include "rnd_avg.h"
 #include "vp3dsp.h"
 
 #define IdctAdjustBeforeShift 8
@@ -213,16 +214,23 @@
     }
 }
 
-static void vp3_idct_put_c(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/){
+static void vp3_idct_put_c(uint8_t *dest/*align 8*/, int line_size,
+                           int16_t *block/*align 16*/)
+{
     idct(dest, line_size, block, 1);
+    memset(block, 0, sizeof(*block) * 64);
 }
 
-static void vp3_idct_add_c(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/){
+static void vp3_idct_add_c(uint8_t *dest/*align 8*/, int line_size,
+                           int16_t *block/*align 16*/)
+{
     idct(dest, line_size, block, 2);
+    memset(block, 0, sizeof(*block) * 64);
 }
 
 static void vp3_idct_dc_add_c(uint8_t *dest/*align 8*/, int line_size,
-                              const DCTELEM *block/*align 16*/){
+                              int16_t *block/*align 16*/)
+{
     int i, dc = (block[0] + 15) >> 5;
 
     for(i = 0; i < 8; i++){
@@ -236,6 +244,7 @@
         dest[7] = av_clip_uint8(dest[7] + dc);
         dest += line_size;
     }
+    block[0] = 0;
 }
 
 static void vp3_v_loop_filter_c(uint8_t *first_pixel, int stride,
@@ -271,8 +280,27 @@
     }
 }
 
+static void put_no_rnd_pixels_l2(uint8_t *dst, const uint8_t *src1,
+                                 const uint8_t *src2, ptrdiff_t stride, int h)
+{
+    int i;
+
+    for (i = 0; i < h; i++) {
+        uint32_t a, b;
+
+        a = AV_RN32(&src1[i * stride]);
+        b = AV_RN32(&src2[i * stride]);
+        AV_WN32A(&dst[i * stride], no_rnd_avg32(a, b));
+        a = AV_RN32(&src1[i * stride + 4]);
+        b = AV_RN32(&src2[i * stride + 4]);
+        AV_WN32A(&dst[i * stride + 4], no_rnd_avg32(a, b));
+    }
+}
+
 av_cold void ff_vp3dsp_init(VP3DSPContext *c, int flags)
 {
+    c->put_no_rnd_pixels_l2 = put_no_rnd_pixels_l2;
+
     c->idct_put      = vp3_idct_put_c;
     c->idct_add      = vp3_idct_add_c;
     c->idct_dc_add   = vp3_idct_dc_add_c;
@@ -283,6 +311,8 @@
 
     if (ARCH_ARM)
         ff_vp3dsp_init_arm(c, flags);
+    if (ARCH_BFIN)
+        ff_vp3dsp_init_bfin(c, flags);
     if (ARCH_PPC)
         ff_vp3dsp_init_ppc(c, flags);
     if (ARCH_X86)
diff --git a/libavcodec/vp3dsp.h b/libavcodec/vp3dsp.h
index a14dec1..558077f 100644
--- a/libavcodec/vp3dsp.h
+++ b/libavcodec/vp3dsp.h
@@ -19,13 +19,28 @@
 #ifndef AVCODEC_VP3DSP_H
 #define AVCODEC_VP3DSP_H
 
+#include <stddef.h>
 #include <stdint.h>
-#include "dsputil.h"
 
 typedef struct VP3DSPContext {
-    void (*idct_put)(uint8_t *dest, int line_size, DCTELEM *block);
-    void (*idct_add)(uint8_t *dest, int line_size, DCTELEM *block);
-    void (*idct_dc_add)(uint8_t *dest, int line_size, const DCTELEM *block);
+    /**
+     * Copy 8xH pixels from source to destination buffer using a bilinear
+     * filter with no rounding (i.e. *dst = (*a + *b) >> 1).
+     *
+     * @param dst destination buffer, aligned by 8
+     * @param a first source buffer, no alignment
+     * @param b second source buffer, no alignment
+     * @param stride distance between two lines in source/dest buffers
+     * @param h height
+     */
+    void (*put_no_rnd_pixels_l2)(uint8_t *dst,
+                                 const uint8_t *a,
+                                 const uint8_t *b,
+                                 ptrdiff_t stride, int h);
+
+    void (*idct_put)(uint8_t *dest, int line_size, int16_t *block);
+    void (*idct_add)(uint8_t *dest, int line_size, int16_t *block);
+    void (*idct_dc_add)(uint8_t *dest, int line_size, int16_t *block);
     void (*v_loop_filter)(uint8_t *src, int stride, int *bounding_values);
     void (*h_loop_filter)(uint8_t *src, int stride, int *bounding_values);
 
@@ -34,6 +49,7 @@
 
 void ff_vp3dsp_init(VP3DSPContext *c, int flags);
 void ff_vp3dsp_init_arm(VP3DSPContext *c, int flags);
+void ff_vp3dsp_init_bfin(VP3DSPContext *c, int flags);
 void ff_vp3dsp_init_ppc(VP3DSPContext *c, int flags);
 void ff_vp3dsp_init_x86(VP3DSPContext *c, int flags);
 
diff --git a/libavcodec/vp5.c b/libavcodec/vp5.c
index 3ae7c25..10dab39 100644
--- a/libavcodec/vp5.c
+++ b/libavcodec/vp5.c
@@ -27,7 +27,6 @@
 #include <string.h>
 
 #include "avcodec.h"
-#include "dsputil.h"
 #include "get_bits.h"
 
 #include "vp56.h"
@@ -48,18 +47,18 @@
     {
         vp56_rac_gets(c, 8);
         if(vp56_rac_gets(c, 5) > 5)
-            return 0;
+            return AVERROR_INVALIDDATA;
         vp56_rac_gets(c, 2);
         if (vp56_rac_get(c)) {
             av_log(s->avctx, AV_LOG_ERROR, "interlacing not supported\n");
-            return 0;
+            return AVERROR_PATCHWELCOME;
         }
         rows = vp56_rac_gets(c, 8);  /* number of stored macroblock rows */
         cols = vp56_rac_gets(c, 8);  /* number of stored macroblock cols */
         if (!rows || !cols) {
             av_log(s->avctx, AV_LOG_ERROR, "Invalid size %dx%d\n",
                    cols << 4, rows << 4);
-            return 0;
+            return AVERROR_INVALIDDATA;
         }
         vp56_rac_gets(c, 8);  /* number of displayed macroblock rows */
         vp56_rac_gets(c, 8);  /* number of displayed macroblock cols */
@@ -68,11 +67,11 @@
             16*cols != s->avctx->coded_width ||
             16*rows != s->avctx->coded_height) {
             avcodec_set_dimensions(s->avctx, 16*cols, 16*rows);
-            return 2;
+            return VP56_SIZE_CHANGE;
         }
     } else if (!s->macroblocks)
-        return 0;
-    return 1;
+        return AVERROR_INVALIDDATA;
+    return 0;
 }
 
 static void vp5_parse_vector_adjustment(VP56Context *s, VP56mv *vect)
diff --git a/libavcodec/vp56.c b/libavcodec/vp56.c
index ae7a117..b4af2ca 100644
--- a/libavcodec/vp56.c
+++ b/libavcodec/vp56.c
@@ -25,7 +25,8 @@
 
 #include "avcodec.h"
 #include "bytestream.h"
-
+#include "internal.h"
+#include "h264chroma.h"
 #include "vp56.h"
 #include "vp56data.h"
 
@@ -339,7 +340,7 @@
 
     if (x<0 || x+12>=s->plane_width[plane] ||
         y<0 || y+12>=s->plane_height[plane]) {
-        s->dsp.emulated_edge_mc(s->edge_emu_buffer,
+        s->vdsp.emulated_edge_mc(s->edge_emu_buffer,
                             src + s->block_offset[b] + (dy-2)*stride + (dx-2),
                             stride, 12, 12, x, y,
                             s->plane_width[plane],
@@ -372,7 +373,7 @@
             s->filter(s, dst, src_block, src_offset, src_offset+overlap_offset,
                       stride, s->mv[b], mask, s->filter_selection, b<4);
         else
-            s->dsp.put_no_rnd_pixels_l2[1](dst, src_block+src_offset,
+            s->vp3dsp.put_no_rnd_pixels_l2(dst, src_block+src_offset,
                                            src_block+src_offset+overlap_offset,
                                            stride, 8);
     } else {
@@ -393,8 +394,6 @@
         mb_type = vp56_decode_mv(s, row, col);
     ref_frame = vp56_reference_frame[mb_type];
 
-    s->dsp.clear_blocks(*s->block_coeff);
-
     s->parse_coeff(s);
 
     vp56_add_predictors_dc(s, ref_frame);
@@ -447,6 +446,11 @@
             }
             break;
     }
+
+    if (is_alpha) {
+        s->block_coeff[4][0] = 0;
+        s->block_coeff[5][0] = 0;
+    }
 }
 
 static int vp56_size_changed(VP56Context *s)
@@ -491,7 +495,7 @@
 
 static int ff_vp56_decode_mbs(AVCodecContext *avctx, void *, int, int);
 
-int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                          AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
@@ -523,10 +527,10 @@
     }
 
     res = s->parse_header(s, buf, remaining_buf_size);
-    if (!res)
-        return -1;
+    if (res < 0)
+        return res;
 
-    if (res == 2) {
+    if (res == VP56_SIZE_CHANGE) {
         for (i = 0; i < 4; i++) {
             if (s->frames[i].data[0])
                 avctx->release_buffer(avctx, &s->frames[i]);
@@ -534,12 +538,12 @@
     }
 
     p->reference = 3;
-    if (avctx->get_buffer(avctx, p) < 0) {
+    if (ff_get_buffer(avctx, p) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return -1;
     }
 
-    if (res == 2) {
+    if (res == VP56_SIZE_CHANGE) {
         if (vp56_size_changed(s)) {
             avctx->release_buffer(avctx, p);
             return -1;
@@ -555,8 +559,8 @@
         remaining_buf_size -= alpha_offset;
 
         res = s->alpha_context->parse_header(s->alpha_context, buf, remaining_buf_size);
-        if (res != 1) {
-            if(res==2) {
+        if (res != 0) {
+            if(res==VP56_SIZE_CHANGE) {
                 av_log(avctx, AV_LOG_ERROR, "Alpha reconfiguration\n");
                 avctx->width  = bak_w;
                 avctx->height = bak_h;
@@ -585,7 +589,7 @@
     p->qscale_table = s->qscale_table;
     p->qscale_type = FF_QSCALE_TYPE_VP56;
     *(AVFrame*)data = *p;
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
 
     return avpkt->size;
 }
@@ -702,6 +706,8 @@
     avctx->pix_fmt = has_alpha ? AV_PIX_FMT_YUVA420P : AV_PIX_FMT_YUV420P;
 
     ff_dsputil_init(&s->dsp, avctx);
+    ff_h264chroma_init(&s->h264chroma, 8);
+    ff_videodsp_init(&s->vdsp, 8);
     ff_vp3dsp_init(&s->vp3dsp, avctx->flags);
     ff_vp56dsp_init(&s->vp56dsp, avctx->codec->id);
     ff_init_scantable_permutation(s->dsp.idct_permutation, s->vp3dsp.idct_perm);
diff --git a/libavcodec/vp56.h b/libavcodec/vp56.h
index 65245a2..14c130f 100644
--- a/libavcodec/vp56.h
+++ b/libavcodec/vp56.h
@@ -30,6 +30,8 @@
 #include "dsputil.h"
 #include "get_bits.h"
 #include "bytestream.h"
+#include "h264chroma.h"
+#include "videodsp.h"
 #include "vp3dsp.h"
 #include "vp56dsp.h"
 
@@ -40,6 +42,8 @@
     int16_t y;
 } VP56mv;
 
+#define VP56_SIZE_CHANGE 1
+
 typedef void (*VP56ParseVectorAdjustment)(VP56Context *s,
                                           VP56mv *vect);
 typedef void (*VP56Filter)(VP56Context *s, uint8_t *dst, uint8_t *src,
@@ -64,7 +68,7 @@
 typedef struct VP56RefDc {
     uint8_t not_null_dc;
     VP56Frame ref_frame;
-    DCTELEM dc_coeff;
+    int16_t dc_coeff;
 } VP56RefDc;
 
 typedef struct VP56Macroblock {
@@ -92,6 +96,8 @@
 struct vp56_context {
     AVCodecContext *avctx;
     DSPContext dsp;
+    H264ChromaContext h264chroma;
+    VideoDSPContext vdsp;
     VP3DSPContext vp3dsp;
     VP56DSPContext vp56dsp;
     ScanTable scantable;
@@ -121,12 +127,12 @@
     VP56RefDc *above_blocks;
     VP56RefDc left_block[4];
     int above_block_idx[6];
-    DCTELEM prev_dc[3][3];    /* [plan][ref_frame] */
+    int16_t prev_dc[3][3];    /* [plan][ref_frame] */
 
     /* blocks / macroblock */
     VP56mb mb_type;
     VP56Macroblock *macroblocks;
-    DECLARE_ALIGNED(16, DCTELEM, block_coeff)[6][64];
+    DECLARE_ALIGNED(16, int16_t, block_coeff)[6][64];
 
     /* motion vectors */
     VP56mv mv[6];  /* vectors for each block in MB */
@@ -183,7 +189,7 @@
 int ff_vp56_free(AVCodecContext *avctx);
 int ff_vp56_free_context(VP56Context *s);
 void ff_vp56_init_dequant(VP56Context *s, int quantizer);
-int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                          AVPacket *avpkt);
 
 
diff --git a/libavcodec/vp6.c b/libavcodec/vp6.c
index bafa2b4..f761aa7 100644
--- a/libavcodec/vp6.c
+++ b/libavcodec/vp6.c
@@ -30,7 +30,6 @@
 #include <stdlib.h>
 
 #include "avcodec.h"
-#include "dsputil.h"
 #include "get_bits.h"
 #include "huffman.h"
 
@@ -51,7 +50,7 @@
     int vrt_shift = 0;
     int sub_version;
     int rows, cols;
-    int res = 1;
+    int res = 0;
     int separated_coeff = buf[0] & 1;
 
     s->framep[VP56_FRAME_CURRENT]->key_frame = !(buf[0] & 0x80);
@@ -60,11 +59,11 @@
     if (s->framep[VP56_FRAME_CURRENT]->key_frame) {
         sub_version = buf[1] >> 3;
         if (sub_version > 8)
-            return 0;
+            return AVERROR_INVALIDDATA;
         s->filter_header = buf[1] & 0x06;
         if (buf[1] & 1) {
-            av_log(s->avctx, AV_LOG_ERROR, "interlacing not supported\n");
-            return 0;
+            av_log_missing_feature(s->avctx, "Interlacing", 0);
+            return AVERROR_PATCHWELCOME;
         }
         if (separated_coeff || !s->filter_header) {
             coeff_offset = AV_RB16(buf+2) - 2;
@@ -78,7 +77,7 @@
         /* buf[5] is number of displayed macroblock cols */
         if (!rows || !cols) {
             av_log(s->avctx, AV_LOG_ERROR, "Invalid size %dx%d\n", cols << 4, rows << 4);
-            return 0;
+            return AVERROR_INVALIDDATA;
         }
 
         if (!s->macroblocks || /* first frame */
@@ -89,7 +88,7 @@
                 s->avctx->width  -= s->avctx->extradata[0] >> 4;
                 s->avctx->height -= s->avctx->extradata[0] & 0x0F;
             }
-            res = 2;
+            res = VP56_SIZE_CHANGE;
         }
 
         ff_vp56_init_range_decoder(c, buf+6, buf_size-6);
@@ -102,7 +101,7 @@
         s->golden_frame = 0;
     } else {
         if (!s->sub_version || !s->avctx->coded_width || !s->avctx->coded_height)
-            return 0;
+            return AVERROR_INVALIDDATA;
 
         if (separated_coeff || !s->filter_header) {
             coeff_offset = AV_RB16(buf+1) - 2;
@@ -146,7 +145,7 @@
         if (buf_size < 0) {
             if (s->framep[VP56_FRAME_CURRENT]->key_frame)
                 avcodec_set_dimensions(s->avctx, 0, 0);
-            return 0;
+            return AVERROR_INVALIDDATA;
         }
         if (s->use_huffman) {
             s->parse_coeff = vp6_parse_coeff_huffman;
@@ -536,8 +535,8 @@
                              int stride, int h_weight, int v_weight)
 {
     uint8_t *tmp = s->edge_emu_buffer+16;
-    s->dsp.put_h264_chroma_pixels_tab[0](tmp, src, stride, 9, h_weight, 0);
-    s->dsp.put_h264_chroma_pixels_tab[0](dst, tmp, stride, 8, 0, v_weight);
+    s->h264chroma.put_h264_chroma_pixels_tab[0](tmp, src, stride, 9, h_weight, 0);
+    s->h264chroma.put_h264_chroma_pixels_tab[0](dst, tmp, stride, 8, 0, v_weight);
 }
 
 static void vp6_filter(VP56Context *s, uint8_t *dst, uint8_t *src,
@@ -583,7 +582,7 @@
         }
     } else {
         if (!x8 || !y8) {
-            s->dsp.put_h264_chroma_pixels_tab[0](dst, src+offset1, stride, 8, x8, y8);
+            s->h264chroma.put_h264_chroma_pixels_tab[0](dst, src + offset1, stride, 8, x8, y8);
         } else {
             vp6_filter_diag2(s, dst, src+offset1 + ((mv.x^mv.y)>>31), stride, x8, y8);
         }
diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c
index 9424c45..fc6fd37 100644
--- a/libavcodec/vp8.c
+++ b/libavcodec/vp8.c
@@ -761,7 +761,7 @@
  * @return 0 if no coeffs were decoded
  *         otherwise, the index of the last coeff decoded plus one
  */
-static int decode_block_coeffs_internal(VP56RangeCoder *r, DCTELEM block[16],
+static int decode_block_coeffs_internal(VP56RangeCoder *r, int16_t block[16],
                                         uint8_t probs[16][3][NUM_DCT_TOKENS-1],
                                         int i, uint8_t *token_prob, int16_t qmul[2])
 {
@@ -829,7 +829,7 @@
  *         otherwise, the index of the last coeff decoded plus one
  */
 static av_always_inline
-int decode_block_coeffs(VP56RangeCoder *c, DCTELEM block[16],
+int decode_block_coeffs(VP56RangeCoder *c, int16_t block[16],
                         uint8_t probs[16][3][NUM_DCT_TOKENS-1],
                         int i, int zero_nhood, int16_t qmul[2])
 {
@@ -1199,9 +1199,9 @@
         src += y_off * linesize + x_off;
         if (x_off < mx_idx || x_off >= width  - block_w - subpel_idx[2][mx] ||
             y_off < my_idx || y_off >= height - block_h - subpel_idx[2][my]) {
-            s->dsp.emulated_edge_mc(td->edge_emu_buffer, src - my_idx * linesize - mx_idx, linesize,
-                                    block_w + subpel_idx[1][mx], block_h + subpel_idx[1][my],
-                                    x_off - mx_idx, y_off - my_idx, width, height);
+            s->vdsp.emulated_edge_mc(td->edge_emu_buffer, src - my_idx * linesize - mx_idx, linesize,
+                                     block_w + subpel_idx[1][mx], block_h + subpel_idx[1][my],
+                                     x_off - mx_idx, y_off - my_idx, width, height);
             src = td->edge_emu_buffer + mx_idx + linesize * my_idx;
         }
         mc_func[my_idx][mx_idx](dst, linesize, src, linesize, block_h, mx, my);
@@ -1249,15 +1249,15 @@
         ff_thread_await_progress(ref, (3 + y_off + block_h + subpel_idx[2][my]) >> 3, 0);
         if (x_off < mx_idx || x_off >= width  - block_w - subpel_idx[2][mx] ||
             y_off < my_idx || y_off >= height - block_h - subpel_idx[2][my]) {
-            s->dsp.emulated_edge_mc(td->edge_emu_buffer, src1 - my_idx * linesize - mx_idx, linesize,
-                                    block_w + subpel_idx[1][mx], block_h + subpel_idx[1][my],
-                                    x_off - mx_idx, y_off - my_idx, width, height);
+            s->vdsp.emulated_edge_mc(td->edge_emu_buffer, src1 - my_idx * linesize - mx_idx, linesize,
+                                     block_w + subpel_idx[1][mx], block_h + subpel_idx[1][my],
+                                     x_off - mx_idx, y_off - my_idx, width, height);
             src1 = td->edge_emu_buffer + mx_idx + linesize * my_idx;
             mc_func[my_idx][mx_idx](dst1, linesize, src1, linesize, block_h, mx, my);
 
-            s->dsp.emulated_edge_mc(td->edge_emu_buffer, src2 - my_idx * linesize - mx_idx, linesize,
-                                    block_w + subpel_idx[1][mx], block_h + subpel_idx[1][my],
-                                    x_off - mx_idx, y_off - my_idx, width, height);
+            s->vdsp.emulated_edge_mc(td->edge_emu_buffer, src2 - my_idx * linesize - mx_idx, linesize,
+                                     block_w + subpel_idx[1][mx], block_h + subpel_idx[1][my],
+                                     x_off - mx_idx, y_off - my_idx, width, height);
             src2 = td->edge_emu_buffer + mx_idx + linesize * my_idx;
             mc_func[my_idx][mx_idx](dst2, linesize, src2, linesize, block_h, mx, my);
         } else {
@@ -1316,9 +1316,9 @@
         /* For threading, a ff_thread_await_progress here might be useful, but
          * it actually slows down the decoder. Since a bad prefetch doesn't
          * generate bad decoder output, we don't run it here. */
-        s->dsp.prefetch(src[0]+off, s->linesize, 4);
+        s->vdsp.prefetch(src[0]+off, s->linesize, 4);
         off= (mx>>1) + ((my>>1) + (mb_x&7))*s->uvlinesize + 64;
-        s->dsp.prefetch(src[1]+off, src[2]-src[1], 2);
+        s->vdsp.prefetch(src[1]+off, src[2]-src[1], 2);
     }
 }
 
@@ -1717,8 +1717,8 @@
             }
         }
 
-        s->dsp.prefetch(dst[0] + (mb_x&3)*4*s->linesize + 64, s->linesize, 4);
-        s->dsp.prefetch(dst[1] + (mb_x&7)*s->uvlinesize + 64, dst[2] - dst[1], 2);
+        s->vdsp.prefetch(dst[0] + (mb_x&3)*4*s->linesize + 64, s->linesize, 4);
+        s->vdsp.prefetch(dst[1] + (mb_x&7)*s->uvlinesize + 64, dst[2] - dst[1], 2);
 
         if (!s->mb_layout)
             decode_mb_mode(s, mb, mb_x, mb_y, curframe->ref_index[0] + mb_xy,
@@ -1856,7 +1856,7 @@
     return 0;
 }
 
-static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                             AVPacket *avpkt)
 {
     VP8Context *s = avctx->priv_data;
@@ -2005,7 +2005,7 @@
 
     if (!s->invisible) {
         *(AVFrame*)data = *curframe;
-        *data_size = sizeof(AVFrame);
+        *got_frame      = 1;
     }
 
     return avpkt->size;
@@ -2021,7 +2021,7 @@
     s->avctx = avctx;
     avctx->pix_fmt = AV_PIX_FMT_YUV420P;
 
-    ff_dsputil_init(&s->dsp, avctx);
+    ff_videodsp_init(&s->vdsp, 8);
     ff_h264_pred_init(&s->hpc, AV_CODEC_ID_VP8, 8, 1);
     ff_vp8dsp_init(&s->vp8dsp);
 
diff --git a/libavcodec/vp8.h b/libavcodec/vp8.h
index 2193487..1976390 100644
--- a/libavcodec/vp8.h
+++ b/libavcodec/vp8.h
@@ -96,8 +96,8 @@
 } VP8Macroblock;
 
 typedef struct VP8ThreadData {
-    DECLARE_ALIGNED(16, DCTELEM, block)[6][4][16];
-    DECLARE_ALIGNED(16, DCTELEM, block_dc)[16];
+    DECLARE_ALIGNED(16, int16_t, block)[6][4][16];
+    DECLARE_ALIGNED(16, int16_t, block_dc)[16];
     /**
      * This is the index plus one of the last non-zero coeff
      * for each of the blocks in the current macroblock.
@@ -249,7 +249,7 @@
      */
     int num_coeff_partitions;
     VP56RangeCoder coeff_partition[8];
-    DSPContext dsp;
+    VideoDSPContext vdsp;
     VP8DSPContext vp8dsp;
     H264PredContext hpc;
     vp8_mc_func put_pixels_tab[3][3][3];
diff --git a/libavcodec/vp8dsp.c b/libavcodec/vp8dsp.c
index a53643c..017278e 100644
--- a/libavcodec/vp8dsp.c
+++ b/libavcodec/vp8dsp.c
@@ -29,7 +29,7 @@
 #include "libavutil/common.h"
 
 // TODO: Maybe add dequant
-static void vp8_luma_dc_wht_c(DCTELEM block[4][4][16], DCTELEM dc[16])
+static void vp8_luma_dc_wht_c(int16_t block[4][4][16], int16_t dc[16])
 {
     int i, t0, t1, t2, t3;
 
@@ -62,7 +62,7 @@
     }
 }
 
-static void vp8_luma_dc_wht_dc_c(DCTELEM block[4][4][16], DCTELEM dc[16])
+static void vp8_luma_dc_wht_dc_c(int16_t block[4][4][16], int16_t dc[16])
 {
     int i, val = (dc[0] + 3) >> 3;
     dc[0] = 0;
@@ -78,10 +78,10 @@
 #define MUL_20091(a) ((((a)*20091) >> 16) + (a))
 #define MUL_35468(a)  (((a)*35468) >> 16)
 
-static void vp8_idct_add_c(uint8_t *dst, DCTELEM block[16], ptrdiff_t stride)
+static void vp8_idct_add_c(uint8_t *dst, int16_t block[16], ptrdiff_t stride)
 {
     int i, t0, t1, t2, t3;
-    DCTELEM tmp[16];
+    int16_t tmp[16];
 
     for (i = 0; i < 4; i++) {
         t0 = block[0*4+i] + block[2*4+i];
@@ -113,7 +113,7 @@
     }
 }
 
-static void vp8_idct_dc_add_c(uint8_t *dst, DCTELEM block[16], ptrdiff_t stride)
+static void vp8_idct_dc_add_c(uint8_t *dst, int16_t block[16], ptrdiff_t stride)
 {
     int i, dc = (block[0] + 4) >> 3;
     block[0] = 0;
@@ -127,7 +127,7 @@
     }
 }
 
-static void vp8_idct_dc_add4uv_c(uint8_t *dst, DCTELEM block[4][16], ptrdiff_t stride)
+static void vp8_idct_dc_add4uv_c(uint8_t *dst, int16_t block[4][16], ptrdiff_t stride)
 {
     vp8_idct_dc_add_c(dst+stride*0+0, block[0], stride);
     vp8_idct_dc_add_c(dst+stride*0+4, block[1], stride);
@@ -135,7 +135,7 @@
     vp8_idct_dc_add_c(dst+stride*4+4, block[3], stride);
 }
 
-static void vp8_idct_dc_add4y_c(uint8_t *dst, DCTELEM block[4][16], ptrdiff_t stride)
+static void vp8_idct_dc_add4y_c(uint8_t *dst, int16_t block[4][16], ptrdiff_t stride)
 {
     vp8_idct_dc_add_c(dst+ 0, block[0], stride);
     vp8_idct_dc_add_c(dst+ 4, block[1], stride);
diff --git a/libavcodec/vp8dsp.h b/libavcodec/vp8dsp.h
index c4b9aa1..6308ff4 100644
--- a/libavcodec/vp8dsp.h
+++ b/libavcodec/vp8dsp.h
@@ -27,20 +27,21 @@
 #ifndef AVCODEC_VP8DSP_H
 #define AVCODEC_VP8DSP_H
 
-#include "dsputil.h"
+#include <stddef.h>
+#include <stdint.h>
 
 typedef void (*vp8_mc_func)(uint8_t *dst/*align 8*/, ptrdiff_t dstStride,
                             uint8_t *src/*align 1*/, ptrdiff_t srcStride,
                             int h, int x, int y);
 
 typedef struct VP8DSPContext {
-    void (*vp8_luma_dc_wht)(DCTELEM block[4][4][16], DCTELEM dc[16]);
-    void (*vp8_luma_dc_wht_dc)(DCTELEM block[4][4][16], DCTELEM dc[16]);
-    void (*vp8_idct_add)(uint8_t *dst, DCTELEM block[16], ptrdiff_t stride);
-    void (*vp8_idct_dc_add)(uint8_t *dst, DCTELEM block[16], ptrdiff_t stride);
-    void (*vp8_idct_dc_add4y)(uint8_t *dst, DCTELEM block[4][16],
+    void (*vp8_luma_dc_wht)(int16_t block[4][4][16], int16_t dc[16]);
+    void (*vp8_luma_dc_wht_dc)(int16_t block[4][4][16], int16_t dc[16]);
+    void (*vp8_idct_add)(uint8_t *dst, int16_t block[16], ptrdiff_t stride);
+    void (*vp8_idct_dc_add)(uint8_t *dst, int16_t block[16], ptrdiff_t stride);
+    void (*vp8_idct_dc_add4y)(uint8_t *dst, int16_t block[4][16],
                               ptrdiff_t stride);
-    void (*vp8_idct_dc_add4uv)(uint8_t *dst, DCTELEM block[4][16],
+    void (*vp8_idct_dc_add4uv)(uint8_t *dst, int16_t block[4][16],
                                ptrdiff_t stride);
 
     // loop filter applied to edges between macroblocks
diff --git a/libavcodec/vqavideo.c b/libavcodec/vqavideo.c
index 2980f94..43b3aaf 100644
--- a/libavcodec/vqavideo.c
+++ b/libavcodec/vqavideo.c
@@ -71,6 +71,7 @@
 #include "libavutil/imgutils.h"
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 
 #define PALETTE_COUNT 256
 #define VQA_HEADER_SIZE 0x2A
@@ -121,7 +122,7 @@
 static av_cold int vqa_decode_init(AVCodecContext *avctx)
 {
     VqaContext *s = avctx->priv_data;
-    int i, j, codebook_index;
+    int i, j, codebook_index, ret;
 
     s->avctx = avctx;
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
@@ -129,7 +130,7 @@
     /* make sure the extradata made it */
     if (s->avctx->extradata_size != VQA_HEADER_SIZE) {
         av_log(s->avctx, AV_LOG_ERROR, "expected extradata size of %d\n", VQA_HEADER_SIZE);
-        return AVERROR_INVALIDDATA;
+        return AVERROR(EINVAL);
     }
 
     /* load up the VQA parameters from the header */
@@ -140,9 +141,9 @@
     }
     s->width = AV_RL16(&s->avctx->extradata[6]);
     s->height = AV_RL16(&s->avctx->extradata[8]);
-    if(av_image_check_size(s->width, s->height, 0, avctx)){
+    if ((ret = av_image_check_size(s->width, s->height, 0, avctx)) < 0) {
         s->width= s->height= 0;
-        return AVERROR_INVALIDDATA;
+        return ret;
     }
     s->vector_width = s->avctx->extradata[10];
     s->vector_height = s->avctx->extradata[11];
@@ -536,6 +537,12 @@
         bytestream2_seek(&s->gb, cbp0_chunk, SEEK_SET);
         chunk_size = bytestream2_get_be32(&s->gb);
 
+        if (chunk_size > MAX_CODEBOOK_SIZE - s->next_codebook_buffer_index) {
+            av_log(s->avctx, AV_LOG_ERROR, "cbp0 chunk too large (%u bytes)\n",
+                   chunk_size);
+            return AVERROR_INVALIDDATA;
+        }
+
         /* accumulate partial codebook */
         bytestream2_get_buffer(&s->gb, &s->next_codebook_buffer[s->next_codebook_buffer_index],
                                chunk_size);
@@ -559,6 +566,12 @@
         bytestream2_seek(&s->gb, cbpz_chunk, SEEK_SET);
         chunk_size = bytestream2_get_be32(&s->gb);
 
+        if (chunk_size > MAX_CODEBOOK_SIZE - s->next_codebook_buffer_index) {
+            av_log(s->avctx, AV_LOG_ERROR, "cbpz chunk too large (%u bytes)\n",
+                   chunk_size);
+            return AVERROR_INVALIDDATA;
+        }
+
         /* accumulate partial codebook */
         bytestream2_get_buffer(&s->gb, &s->next_codebook_buffer[s->next_codebook_buffer_index],
                                chunk_size);
@@ -582,7 +595,7 @@
 }
 
 static int vqa_decode_frame(AVCodecContext *avctx,
-                            void *data, int *data_size,
+                            void *data, int *got_frame,
                             AVPacket *avpkt)
 {
     VqaContext *s = avctx->priv_data;
@@ -591,7 +604,7 @@
     if (s->frame.data[0])
         avctx->release_buffer(avctx, &s->frame);
 
-    if ((res = avctx->get_buffer(avctx, &s->frame))) {
+    if ((res = ff_get_buffer(avctx, &s->frame)) < 0) {
         av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return res;
     }
@@ -604,7 +617,7 @@
     memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4);
     s->frame.palette_has_changed = 1;
 
-    *data_size = sizeof(AVFrame);
+    *got_frame      = 1;
     *(AVFrame*)data = s->frame;
 
     /* report that the buffer was completely consumed */
diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c
index bc038a9..b5663b4 100644
--- a/libavcodec/wavpack.c
+++ b/libavcodec/wavpack.c
@@ -24,6 +24,7 @@
 #include "libavutil/channel_layout.h"
 #include "avcodec.h"
 #include "get_bits.h"
+#include "internal.h"
 #include "unary.h"
 
 /**
@@ -128,7 +129,6 @@
 
 typedef struct WavpackContext {
     AVCodecContext *avctx;
-    AVFrame frame;
 
     WavpackFrameContext *fdec[WV_MAX_FRAME_DECODERS];
     int fdec_num;
@@ -740,9 +740,6 @@
 
     s->fdec_num = 0;
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     return 0;
 }
 
@@ -905,7 +902,7 @@
                 continue;
             }
             t = 0;
-            for (i = s->terms - 1; (i >= 0) && (t < size); i--) {
+            for (i = s->terms - 1; (i >= 0) && (t < size) && buf <= buf_end; 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;
@@ -920,7 +917,7 @@
                     s->decorr[i].samplesB[0] = wp_exp2(AV_RL16(buf)); buf += 2;
                     t += 4;
                 } else {
-                    for (j = 0; j < s->decorr[i].value; j++) {
+                    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;
                         if (s->stereo_in) {
                             s->decorr[i].samplesB[j] = wp_exp2(AV_RL16(buf)); buf += 2;
@@ -1182,6 +1179,7 @@
     WavpackContext *s  = avctx->priv_data;
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
+    AVFrame *frame     = data;
     int frame_size, ret, frame_flags;
     int samplecount = 0;
 
@@ -1217,12 +1215,12 @@
     }
 
     /* get output buffer */
-    s->frame.nb_samples = s->samples + 1;
-    if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = s->samples + 1;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    s->frame.nb_samples = s->samples;
+    frame->nb_samples = s->samples;
 
     while (buf_size > 0) {
         if (!s->multichannel) {
@@ -1243,7 +1241,7 @@
             return AVERROR_INVALIDDATA;
         }
         if ((samplecount = wavpack_decode_block(avctx, s->block,
-                                                s->frame.data[0], got_frame_ptr,
+                                                frame->data[0], got_frame_ptr,
                                                 buf, frame_size)) < 0) {
             wavpack_decode_flush(avctx);
             return AVERROR_INVALIDDATA;
@@ -1252,9 +1250,6 @@
         buf += frame_size; buf_size -= frame_size;
     }
 
-    if (*got_frame_ptr)
-        *(AVFrame *)data = s->frame;
-
     return avpkt->size;
 }
 
diff --git a/libavcodec/wma.c b/libavcodec/wma.c
index d0c0b34..e704223 100644
--- a/libavcodec/wma.c
+++ b/libavcodec/wma.c
@@ -82,7 +82,6 @@
         || avctx->bit_rate    <= 0)
         return -1;
 
-    ff_dsputil_init(&s->dsp, avctx);
     ff_fmt_convert_init(&s->fmt_conv, avctx);
     avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
 
@@ -135,6 +134,10 @@
 
     bps = (float)avctx->bit_rate / (float)(avctx->channels * avctx->sample_rate);
     s->byte_offset_bits = av_log2((int)(bps * s->frame_len / 8.0 + 0.5)) + 2;
+    if (s->byte_offset_bits + 3 > MIN_CACHE_BITS) {
+        av_log(avctx, AV_LOG_ERROR, "byte_offset_bits %d is too large\n", s->byte_offset_bits);
+        return AVERROR_PATCHWELCOME;
+    }
 
     /* compute high frequency value and choose if noise coding should
        be activated */
@@ -387,6 +390,11 @@
         av_free(s->int_table[i]);
     }
 
+#if FF_API_OLD_ENCODE_AUDIO
+    if (av_codec_is_encoder(avctx->codec))
+        av_freep(&avctx->coded_frame);
+#endif
+
     return 0;
 }
 
diff --git a/libavcodec/wma.h b/libavcodec/wma.h
index 4db4faa..c4056ec 100644
--- a/libavcodec/wma.h
+++ b/libavcodec/wma.h
@@ -25,7 +25,6 @@
 #include "libavutil/float_dsp.h"
 #include "get_bits.h"
 #include "put_bits.h"
-#include "dsputil.h"
 #include "fft.h"
 #include "fmtconvert.h"
 
@@ -66,7 +65,6 @@
 
 typedef struct WMACodecContext {
     AVCodecContext* avctx;
-    AVFrame frame;
     GetBitContext gb;
     PutBitContext pb;
     int version;                            ///< 1 = 0x160 (WMAV1), 2 = 0x161 (WMAV2)
@@ -132,7 +130,6 @@
     float lsp_pow_e_table[256];
     float lsp_pow_m_table1[(1 << LSP_POW_BITS)];
     float lsp_pow_m_table2[(1 << LSP_POW_BITS)];
-    DSPContext dsp;
     FmtConvertContext fmt_conv;
     AVFloatDSPContext fdsp;
 
diff --git a/libavcodec/wma_common.h b/libavcodec/wma_common.h
index 84d2cda..55404af 100644
--- a/libavcodec/wma_common.h
+++ b/libavcodec/wma_common.h
@@ -21,9 +21,7 @@
 #ifndef AVCODEC_WMA_COMMON_H
 #define AVCODEC_WMA_COMMON_H
 
-#include "libavutil/attributes.h"
-
-av_cold int ff_wma_get_frame_len_bits(int sample_rate, int version,
-                                      unsigned int decode_flags);
+int ff_wma_get_frame_len_bits(int sample_rate, int version,
+                              unsigned int decode_flags);
 
 #endif /* AVCODEC_WMA_COMMON_H */
diff --git a/libavcodec/wmadec.c b/libavcodec/wmadec.c
index f3ce474..df5089f 100644
--- a/libavcodec/wmadec.c
+++ b/libavcodec/wmadec.c
@@ -34,6 +34,7 @@
  */
 
 #include "avcodec.h"
+#include "internal.h"
 #include "wma.h"
 
 #undef NDEBUG
@@ -116,9 +117,6 @@
 
     avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     return 0;
 }
 
@@ -385,16 +383,16 @@
         block_len = s->block_len;
         bsize = s->frame_len_bits - s->block_len_bits;
 
-        s->dsp.vector_fmul_add(out, in, s->windows[bsize],
-                               out, block_len);
+        s->fdsp.vector_fmul_add(out, in, s->windows[bsize],
+                                out, block_len);
 
     } else {
         block_len = 1 << s->prev_block_len_bits;
         n = (s->block_len - block_len) / 2;
         bsize = s->frame_len_bits - s->prev_block_len_bits;
 
-        s->dsp.vector_fmul_add(out+n, in+n, s->windows[bsize],
-                               out+n, block_len);
+        s->fdsp.vector_fmul_add(out+n, in+n, s->windows[bsize],
+                                out+n, block_len);
 
         memcpy(out+n+block_len, in+n+block_len, n*sizeof(float));
     }
@@ -407,7 +405,7 @@
         block_len = s->block_len;
         bsize = s->frame_len_bits - s->block_len_bits;
 
-        s->dsp.vector_fmul_reverse(out, in, s->windows[bsize], block_len);
+        s->fdsp.vector_fmul_reverse(out, in, s->windows[bsize], block_len);
 
     } else {
         block_len = 1 << s->next_block_len_bits;
@@ -416,7 +414,7 @@
 
         memcpy(out, in, n*sizeof(float));
 
-        s->dsp.vector_fmul_reverse(out+n, in+n, s->windows[bsize], block_len);
+        s->fdsp.vector_fmul_reverse(out+n, in+n, s->windows[bsize], block_len);
 
         memset(out+n+block_len, 0, n*sizeof(float));
     }
@@ -730,7 +728,7 @@
             s->channel_coded[0] = 1;
         }
 
-        s->dsp.butterflies_float(s->coefs[0], s->coefs[1], s->block_len);
+        s->fdsp.butterflies_float(s->coefs[0], s->coefs[1], s->block_len);
     }
 
 next:
@@ -799,6 +797,7 @@
 static int wma_decode_superframe(AVCodecContext *avctx, void *data,
                                  int *got_frame_ptr, AVPacket *avpkt)
 {
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     WMACodecContext *s = avctx->priv_data;
@@ -833,12 +832,12 @@
     }
 
     /* get output buffer */
-    s->frame.nb_samples = nb_frames * s->frame_len;
-    if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = nb_frames * s->frame_len;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    samples = (float **)s->frame.extended_data;
+    samples = (float **)frame->extended_data;
     samples_offset = 0;
 
     if (s->use_bit_reservoir) {
@@ -917,8 +916,7 @@
             s->frame_len_bits, s->block_len_bits, s->frame_len, s->block_len,
             (int8_t *)samples - (int8_t *)data, avctx->block_align);
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
+    *got_frame_ptr = 1;
 
     return buf_size;
  fail:
diff --git a/libavcodec/wmaenc.c b/libavcodec/wmaenc.c
index 969ffc5..0ee5dda 100644
--- a/libavcodec/wmaenc.c
+++ b/libavcodec/wmaenc.c
@@ -33,13 +33,13 @@
     s->avctx = avctx;
 
     if(avctx->channels > MAX_CHANNELS) {
-        av_log(avctx, AV_LOG_ERROR, "too many channels: got %i, need %i or fewer",
+        av_log(avctx, AV_LOG_ERROR, "too many channels: got %i, need %i or fewer\n",
                avctx->channels, MAX_CHANNELS);
         return AVERROR(EINVAL);
     }
 
     if (avctx->sample_rate > 48000) {
-        av_log(avctx, AV_LOG_ERROR, "sample rate is too high: %d > 48kHz",
+        av_log(avctx, AV_LOG_ERROR, "sample rate is too high: %d > 48kHz\n",
                avctx->sample_rate);
         return AVERROR(EINVAL);
     }
@@ -50,6 +50,11 @@
         return AVERROR(EINVAL);
     }
 
+#if FF_API_OLD_ENCODE_AUDIO
+    if (!(avctx->coded_frame = avcodec_alloc_frame()))
+        return AVERROR(ENOMEM);
+#endif
+
     /* extract flag infos */
     flags1 = 0;
     flags2 = 1;
@@ -85,11 +90,6 @@
 
     avctx->frame_size = avctx->delay = s->frame_len;
 
-#if FF_API_OLD_ENCODE_AUDIO
-    avctx->coded_frame = &s->frame;
-    avcodec_get_frame_defaults(avctx->coded_frame);
-#endif
-
     return 0;
 }
 
@@ -109,7 +109,7 @@
     for (ch = 0; ch < avctx->channels; ch++) {
         memcpy(s->output, s->frame_out[ch], window_len * sizeof(*s->output));
         s->fdsp.vector_fmul_scalar(s->frame_out[ch], audio[ch], n, len);
-        s->dsp.vector_fmul_reverse(&s->output[window_len], s->frame_out[ch], win, len);
+        s->fdsp.vector_fmul_reverse(&s->output[window_len], s->frame_out[ch], win, len);
         s->fdsp.vector_fmul(s->frame_out[ch], s->frame_out[ch], win, len);
         mdct->mdct_calc(mdct, s->coefs[ch], s->output);
     }
diff --git a/libavcodec/wmalosslessdec.c b/libavcodec/wmalosslessdec.c
index 749e41f..331a027 100644
--- a/libavcodec/wmalosslessdec.c
+++ b/libavcodec/wmalosslessdec.c
@@ -123,7 +123,7 @@
     int8_t  acfilter_order;
     int8_t  acfilter_scaling;
     int64_t acfilter_coeffs[16];
-    int     acfilter_prevvalues[2][16];
+    int     acfilter_prevvalues[WMALL_MAX_CHANNELS][16];
 
     int8_t  mclms_order;
     int8_t  mclms_scaling;
@@ -145,29 +145,29 @@
         int16_t lms_prevvalues[MAX_ORDER * 2];
         int16_t lms_updates[MAX_ORDER * 2];
         int recent;
-    } cdlms[2][9];
+    } cdlms[WMALL_MAX_CHANNELS][9];
 
-    int cdlms_ttl[2];
+    int cdlms_ttl[WMALL_MAX_CHANNELS];
 
     int bV3RTM;
 
-    int is_channel_coded[2];
-    int update_speed[2];
+    int is_channel_coded[WMALL_MAX_CHANNELS];
+    int update_speed[WMALL_MAX_CHANNELS];
 
-    int transient[2];
-    int transient_pos[2];
+    int transient[WMALL_MAX_CHANNELS];
+    int transient_pos[WMALL_MAX_CHANNELS];
     int seekable_tile;
 
-    int ave_sum[2];
+    int ave_sum[WMALL_MAX_CHANNELS];
 
-    int channel_residues[2][WMALL_BLOCK_MAX_SIZE];
+    int channel_residues[WMALL_MAX_CHANNELS][WMALL_BLOCK_MAX_SIZE];
 
-    int lpc_coefs[2][40];
+    int lpc_coefs[WMALL_MAX_CHANNELS][40];
     int lpc_order;
     int lpc_scaling;
     int lpc_intbits;
 
-    int channel_coeffs[2][WMALL_BLOCK_MAX_SIZE];
+    int channel_coeffs[WMALL_MAX_CHANNELS][WMALL_BLOCK_MAX_SIZE];
 } WmallDecodeCtx;
 
 
@@ -203,7 +203,7 @@
 
     } else {
         av_log_ask_for_sample(avctx, "Unsupported extradata size\n");
-        return AVERROR_INVALIDDATA;
+        return AVERROR_PATCHWELCOME;
     }
 
     /* generic init */
@@ -1015,7 +1015,7 @@
     int more_frames = 0, len = 0, i, ret;
 
     s->frame.nb_samples = s->samples_per_frame;
-    if ((ret = s->avctx->get_buffer(s->avctx, &s->frame)) < 0) {
+    if ((ret = ff_get_buffer(s->avctx, &s->frame)) < 0) {
         /* return an error if no frame could be decoded at all */
         av_log(s->avctx, AV_LOG_ERROR,
                "not enough space for the output samples\n");
diff --git a/libavcodec/wmaprodec.c b/libavcodec/wmaprodec.c
index 235425e..a772e73 100644
--- a/libavcodec/wmaprodec.c
+++ b/libavcodec/wmaprodec.c
@@ -94,7 +94,6 @@
 #include "get_bits.h"
 #include "put_bits.h"
 #include "wmaprodata.h"
-#include "dsputil.h"
 #include "sinewin.h"
 #include "wma.h"
 #include "wma_common.h"
@@ -169,8 +168,6 @@
 typedef struct WMAProDecodeCtx {
     /* generic decoder variables */
     AVCodecContext*  avctx;                         ///< codec context for av_log
-    AVFrame          frame;                         ///< AVFrame for decoded output
-    DSPContext       dsp;                           ///< accelerated DSP functions
     AVFloatDSPContext fdsp;
     uint8_t          frame_data[MAX_FRAMESIZE +
                       FF_INPUT_BUFFER_PADDING_SIZE];///< compressed frame data
@@ -281,7 +278,6 @@
     int num_possible_block_sizes;
 
     s->avctx = avctx;
-    ff_dsputil_init(&s->dsp, avctx);
     avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
 
     init_put_bits(&s->pb, s->frame_data, MAX_FRAMESIZE);
@@ -299,7 +295,7 @@
 
     } else {
         av_log_ask_for_sample(avctx, "Unknown extradata size\n");
-        return AVERROR_INVALIDDATA;
+        return AVERROR_PATCHWELCOME;
     }
 
     /** generic init */
@@ -473,9 +469,6 @@
 
     avctx->channel_layout = channel_mask;
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     return 0;
 }
 
@@ -690,7 +683,7 @@
         if (get_bits1(&s->gb)) {
             av_log_ask_for_sample(s->avctx,
                                   "unsupported channel transform bit\n");
-            return AVERROR_INVALIDDATA;
+            return AVERROR_PATCHWELCOME;
         }
 
         for (s->num_chgroups = 0; remaining_channels &&
@@ -1056,8 +1049,8 @@
 
         winlen >>= 1;
 
-        s->dsp.vector_fmul_window(start, start, start + winlen,
-                                  window, winlen);
+        s->fdsp.vector_fmul_window(start, start, start + winlen,
+                                   window, winlen);
 
         s->channel[c].prev_block_len = s->subframe_len;
     }
@@ -1099,7 +1092,7 @@
     s->channels_for_cur_subframe = 0;
     for (i = 0; i < s->avctx->channels; i++) {
         const int cur_subframe = s->channel[i].cur_subframe;
-        /** substract already processed samples */
+        /** subtract already processed samples */
         total_samples -= s->channel[i].decoded_samples;
 
         /** and count if there are multiple subframes that match our profile */
@@ -1160,7 +1153,7 @@
     /** no idea for what the following bit is used */
     if (get_bits1(&s->gb)) {
         av_log_ask_for_sample(s->avctx, "reserved bit set\n");
-        return AVERROR_INVALIDDATA;
+        return AVERROR_PATCHWELCOME;
     }
 
 
@@ -1306,7 +1299,7 @@
  *@return 0 if the trailer bit indicates that this is the last frame,
  *        1 if there are additional frames
  */
-static int decode_frame(WMAProDecodeCtx *s, int *got_frame_ptr)
+static int decode_frame(WMAProDecodeCtx *s, AVFrame *frame, int *got_frame_ptr)
 {
     AVCodecContext *avctx = s->avctx;
     GetBitContext* gb = &s->gb;
@@ -1379,8 +1372,8 @@
     }
 
     /* get output buffer */
-    s->frame.nb_samples = s->samples_per_frame;
-    if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = s->samples_per_frame;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         s->packet_loss = 1;
         return 0;
@@ -1388,7 +1381,7 @@
 
     /** copy samples to the output buffer */
     for (i = 0; i < avctx->channels; i++)
-        memcpy(s->frame.extended_data[i], s->channel[i].out,
+        memcpy(frame->extended_data[i], s->channel[i].out,
                s->samples_per_frame * sizeof(*s->channel[i].out));
 
     for (i = 0; i < avctx->channels; i++) {
@@ -1556,7 +1549,7 @@
 
             /** decode the cross packet frame if it is valid */
             if (!s->packet_loss)
-                decode_frame(s, got_frame_ptr);
+                decode_frame(s, data, got_frame_ptr);
         } else if (s->num_saved_bits - s->frame_offset) {
             av_dlog(avctx, "ignoring %x previously saved bits\n",
                     s->num_saved_bits - s->frame_offset);
@@ -1579,7 +1572,7 @@
             (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, got_frame_ptr);
+            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
@@ -1589,7 +1582,7 @@
                 therefore we save the incoming packet first, then we append
                 the "previous frame" data from the next packet so that
                 we get a buffer that only contains full frames */
-            s->packet_done = !decode_frame(s, got_frame_ptr);
+            s->packet_done = !decode_frame(s, data, got_frame_ptr);
         } else
             s->packet_done = 1;
     }
@@ -1605,9 +1598,6 @@
     if (s->packet_loss)
         return AVERROR_INVALIDDATA;
 
-    if (*got_frame_ptr)
-        *(AVFrame *)data = s->frame;
-
     return get_bits_count(gb) >> 3;
 }
 
diff --git a/libavcodec/wmavoice.c b/libavcodec/wmavoice.c
index 89b3094..a82ee94 100644
--- a/libavcodec/wmavoice.c
+++ b/libavcodec/wmavoice.c
@@ -28,9 +28,10 @@
 #include <math.h>
 
 #include "libavutil/channel_layout.h"
+#include "libavutil/float_dsp.h"
 #include "libavutil/mem.h"
-#include "dsputil.h"
 #include "avcodec.h"
+#include "internal.h"
 #include "get_bits.h"
 #include "put_bits.h"
 #include "wmavoice_data.h"
@@ -133,7 +134,6 @@
      * @name Global values specified in the stream header / extradata or used all over.
      * @{
      */
-    AVFrame frame;
     GetBitContext gb;             ///< packet bitreader. During decoder init,
                                   ///< it contains the extradata from the
                                   ///< demuxer. During decoding, it contains
@@ -442,9 +442,6 @@
     ctx->channel_layout         = AV_CH_LAYOUT_MONO;
     ctx->sample_fmt             = AV_SAMPLE_FMT_FLT;
 
-    avcodec_get_frame_defaults(&s->frame);
-    ctx->coded_frame = &s->frame;
-
     return 0;
 }
 
@@ -520,7 +517,7 @@
 
     /* find best fitting point in history */
     do {
-        dot = ff_scalarproduct_float_c(in, ptr, size);
+        dot = avpriv_scalarproduct_float_c(in, ptr, size);
         if (dot > optimal_gain) {
             optimal_gain  = dot;
             best_hist_ptr = ptr;
@@ -529,7 +526,7 @@
 
     if (optimal_gain <= 0)
         return -1;
-    dot = ff_scalarproduct_float_c(best_hist_ptr, best_hist_ptr, size);
+    dot = avpriv_scalarproduct_float_c(best_hist_ptr, best_hist_ptr, size);
     if (dot <= 0) // would be 1.0
         return -1;
 
@@ -559,8 +556,8 @@
 {
     float rh0, rh1;
 
-    rh0 = 1.0     + ff_scalarproduct_float_c(lpcs,  lpcs,    n_lpcs);
-    rh1 = lpcs[0] + ff_scalarproduct_float_c(lpcs, &lpcs[1], n_lpcs - 1);
+    rh0 = 1.0     + avpriv_scalarproduct_float_c(lpcs,  lpcs,    n_lpcs);
+    rh1 = lpcs[0] + avpriv_scalarproduct_float_c(lpcs, &lpcs[1], n_lpcs - 1);
 
     return rh1 / rh0;
 }
@@ -653,7 +650,8 @@
                              -1.8 * tilt_factor(coeffs, remainder - 1),
                              coeffs, remainder);
     }
-    sq = (1.0 / 64.0) * sqrtf(1 / ff_scalarproduct_float_c(coeffs, coeffs, remainder));
+    sq = (1.0 / 64.0) * sqrtf(1 / avpriv_scalarproduct_float_c(coeffs, coeffs,
+                                                               remainder));
     for (n = 0; n < remainder; n++)
         coeffs[n] *= sq;
 }
@@ -1317,7 +1315,8 @@
     /* Calculate gain for adaptive & fixed codebook signal.
      * see ff_amr_set_fixed_gain(). */
     idx = get_bits(gb, 7);
-    fcb_gain = expf(ff_scalarproduct_float_c(s->gain_pred_err, gain_coeff, 6) -
+    fcb_gain = expf(avpriv_scalarproduct_float_c(s->gain_pred_err,
+                                                 gain_coeff, 6) -
                     5.2409161640 + wmavoice_gain_codebook_fcb[idx]);
     acb_gain = wmavoice_gain_codebook_acb[idx];
     pred_err = av_clipf(wmavoice_gain_codebook_fcb[idx],
@@ -1437,8 +1436,8 @@
                        float *excitation, float *synth)
 {
     WMAVoiceContext *s = ctx->priv_data;
-    int n, n_blocks_x2, log_n_blocks_x2, cur_pitch_val;
-    int pitch[MAX_BLOCKS], last_block_pitch;
+    int n, n_blocks_x2, log_n_blocks_x2, av_uninit(cur_pitch_val);
+    int pitch[MAX_BLOCKS], av_uninit(last_block_pitch);
 
     /* Parse frame type ("frame header"), see frame_descs */
     int bd_idx = s->vbm_tree[get_vlc2(gb, frame_type_vlc.table, 6, 3)], block_nsamples;
@@ -1730,7 +1729,8 @@
  * @return 0 on success, <0 on error or 1 if there was not enough data to
  *         fully parse the superframe
  */
-static int synth_superframe(AVCodecContext *ctx, int *got_frame_ptr)
+static int synth_superframe(AVCodecContext *ctx, AVFrame *frame,
+                            int *got_frame_ptr)
 {
     WMAVoiceContext *s = ctx->priv_data;
     GetBitContext *gb = &s->gb, s_gb;
@@ -1798,13 +1798,13 @@
     }
 
     /* get output buffer */
-    s->frame.nb_samples = 480;
-    if ((res = ctx->get_buffer(ctx, &s->frame)) < 0) {
+    frame->nb_samples = 480;
+    if ((res = ff_get_buffer(ctx, frame)) < 0) {
         av_log(ctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return res;
     }
-    s->frame.nb_samples = n_samples;
-    samples = (float *)s->frame.data[0];
+    frame->nb_samples = n_samples;
+    samples = (float *)frame->data[0];
 
     /* Parse frames, optionally preceded by per-frame (independent) LSPs. */
     for (n = 0; n < 3; n++) {
@@ -1961,11 +1961,10 @@
                 copy_bits(&s->pb, avpkt->data, size, gb, s->spillover_nbits);
                 flush_put_bits(&s->pb);
                 s->sframe_cache_size += s->spillover_nbits;
-                if ((res = synth_superframe(ctx, got_frame_ptr)) == 0 &&
+                if ((res = synth_superframe(ctx, data, got_frame_ptr)) == 0 &&
                     *got_frame_ptr) {
                     cnt += s->spillover_nbits;
                     s->skip_bits_next = cnt & 7;
-                    *(AVFrame *)data = s->frame;
                     return cnt >> 3;
                 } else
                     skip_bits_long (gb, s->spillover_nbits - cnt +
@@ -1980,12 +1979,11 @@
     s->sframe_cache_size = 0;
     s->skip_bits_next = 0;
     pos = get_bits_left(gb);
-    if ((res = synth_superframe(ctx, got_frame_ptr)) < 0) {
+    if ((res = synth_superframe(ctx, data, got_frame_ptr)) < 0) {
         return res;
     } else if (*got_frame_ptr) {
         int cnt = get_bits_count(gb);
         s->skip_bits_next = cnt & 7;
-        *(AVFrame *)data = s->frame;
         return cnt >> 3;
     } else if ((s->sframe_cache_size = pos) > 0) {
         /* rewind bit reader to start of last (incomplete) superframe... */
diff --git a/libavcodec/wmv2.c b/libavcodec/wmv2.c
index 621b6be..6676652 100644
--- a/libavcodec/wmv2.c
+++ b/libavcodec/wmv2.c
@@ -28,17 +28,34 @@
 av_cold void ff_wmv2_common_init(Wmv2Context * w){
     MpegEncContext * const s= &w->s;
 
-    ff_init_scantable(s->dsp.idct_permutation, &w->abt_scantable[0], ff_wmv2_scantableA);
-    ff_init_scantable(s->dsp.idct_permutation, &w->abt_scantable[1], ff_wmv2_scantableB);
+    ff_wmv2dsp_init(&w->wdsp);
+    s->dsp.idct_permutation_type = w->wdsp.idct_perm;
+    ff_init_scantable_permutation(s->dsp.idct_permutation,
+                                  w->wdsp.idct_perm);
+    ff_init_scantable(s->dsp.idct_permutation, &w->abt_scantable[0],
+                      ff_wmv2_scantableA);
+    ff_init_scantable(s->dsp.idct_permutation, &w->abt_scantable[1],
+                      ff_wmv2_scantableB);
+    ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable,
+                      ff_wmv1_scantable[1]);
+    ff_init_scantable(s->dsp.idct_permutation, &s->intra_h_scantable,
+                      ff_wmv1_scantable[2]);
+    ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_scantable,
+                      ff_wmv1_scantable[3]);
+    ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable,
+                      ff_wmv1_scantable[0]);
+    s->dsp.idct_put = w->wdsp.idct_put;
+    s->dsp.idct_add = w->wdsp.idct_add;
+    s->dsp.idct     = NULL;
 }
 
-static void wmv2_add_block(Wmv2Context *w, DCTELEM *block1, uint8_t *dst, int stride, int n){
+static void wmv2_add_block(Wmv2Context *w, int16_t *block1, uint8_t *dst, int stride, int n){
     MpegEncContext * const s= &w->s;
 
   if (s->block_last_index[n] >= 0) {
     switch(w->abt_type_table[n]){
     case 0:
-        s->dsp.idct_add (dst, stride, block1);
+        w->wdsp.idct_add(dst, stride, block1);
         break;
     case 1:
         ff_simple_idct84_add(dst           , stride, block1);
@@ -56,7 +73,7 @@
   }
 }
 
-void ff_wmv2_add_mb(MpegEncContext *s, DCTELEM block1[6][64], uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr){
+void ff_wmv2_add_mb(MpegEncContext *s, int16_t block1[6][64], uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr){
     Wmv2Context * const w= (Wmv2Context*)s;
 
     wmv2_add_block(w, block1[0], dest_y                    , s->linesize, 0);
@@ -102,7 +119,7 @@
     if(s->flags&CODEC_FLAG_EMU_EDGE){
         if(src_x<1 || src_y<1 || src_x + 17  >= s->h_edge_pos
                               || src_y + h+1 >= v_edge_pos){
-            s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr - 1 - s->linesize, s->linesize, 19, 19,
+            s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr - 1 - s->linesize, s->linesize, 19, 19,
                              src_x-1, src_y-1, s->h_edge_pos, s->v_edge_pos);
             ptr= s->edge_emu_buffer + 1 + s->linesize;
             emu=1;
@@ -143,7 +160,7 @@
     offset = (src_y * uvlinesize) + src_x;
     ptr = ref_picture[1] + offset;
     if(emu){
-        s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize, 9, 9,
+        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize, 9, 9,
                          src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
         ptr= s->edge_emu_buffer;
     }
@@ -151,7 +168,7 @@
 
     ptr = ref_picture[2] + offset;
     if(emu){
-        s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize, 9, 9,
+        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize, 9, 9,
                          src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
         ptr= s->edge_emu_buffer;
     }
diff --git a/libavcodec/wmv2.h b/libavcodec/wmv2.h
index c69c9f4..52739c1 100644
--- a/libavcodec/wmv2.h
+++ b/libavcodec/wmv2.h
@@ -22,9 +22,9 @@
 #define AVCODEC_WMV2_H
 
 #include "avcodec.h"
-#include "dsputil.h"
 #include "mpegvideo.h"
 #include "intrax8.h"
+#include "wmv2dsp.h"
 
 #define SKIP_TYPE_NONE 0
 #define SKIP_TYPE_MPEG 1
@@ -35,6 +35,7 @@
 typedef struct Wmv2Context{
     MpegEncContext s;
     IntraX8Context x8;
+    WMV2DSPContext wdsp;
     int j_type_bit;
     int j_type;
     int abt_flag;
@@ -50,7 +51,7 @@
     int hshift;
 
     ScanTable abt_scantable[2];
-    DECLARE_ALIGNED(16, DCTELEM, abt_block2)[6][64];
+    DECLARE_ALIGNED(16, int16_t, abt_block2)[6][64];
 }Wmv2Context;
 
 void ff_wmv2_common_init(Wmv2Context * w);
diff --git a/libavcodec/wmv2dec.c b/libavcodec/wmv2dec.c
index df11c21..fc7a1b3 100644
--- a/libavcodec/wmv2dec.c
+++ b/libavcodec/wmv2dec.c
@@ -19,7 +19,6 @@
  */
 
 #include "avcodec.h"
-#include "dsputil.h"
 #include "mpegvideo.h"
 #include "h263.h"
 #include "mathops.h"
@@ -291,7 +290,7 @@
     return mot_val;
 }
 
-static inline int wmv2_decode_inter_block(Wmv2Context *w, DCTELEM *block, int n, int cbp){
+static inline int wmv2_decode_inter_block(Wmv2Context *w, int16_t *block, int n, int cbp){
     MpegEncContext * const s= &w->s;
     static const int sub_cbp_table[3]= {2,3,1};
     int sub_cbp;
@@ -331,7 +330,7 @@
 }
 
 
-int ff_wmv2_decode_mb(MpegEncContext *s, DCTELEM block[6][64])
+int ff_wmv2_decode_mb(MpegEncContext *s, int16_t block[6][64])
 {
     Wmv2Context * const w= (Wmv2Context*)s;
     int cbp, code, i;
@@ -447,10 +446,6 @@
 static av_cold int wmv2_decode_init(AVCodecContext *avctx){
     Wmv2Context * const w= avctx->priv_data;
 
-    if(avctx->idct_algo==FF_IDCT_AUTO){
-        avctx->idct_algo=FF_IDCT_WMV2;
-    }
-
     if(ff_msmpeg4_decode_init(avctx) < 0)
         return -1;
 
diff --git a/libavcodec/wmv2dsp.c b/libavcodec/wmv2dsp.c
new file mode 100644
index 0000000..9627442
--- /dev/null
+++ b/libavcodec/wmv2dsp.c
@@ -0,0 +1,146 @@
+/*
+ * 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/attributes.h"
+#include "libavutil/common.h"
+#include "avcodec.h"
+#include "dsputil.h"
+#include "wmv2dsp.h"
+
+#define W0 2048
+#define W1 2841 /* 2048*sqrt (2)*cos (1*pi/16) */
+#define W2 2676 /* 2048*sqrt (2)*cos (2*pi/16) */
+#define W3 2408 /* 2048*sqrt (2)*cos (3*pi/16) */
+#define W4 2048 /* 2048*sqrt (2)*cos (4*pi/16) */
+#define W5 1609 /* 2048*sqrt (2)*cos (5*pi/16) */
+#define W6 1108 /* 2048*sqrt (2)*cos (6*pi/16) */
+#define W7 565  /* 2048*sqrt (2)*cos (7*pi/16) */
+
+static void wmv2_idct_row(short * b)
+{
+    int s1, s2;
+    int a0, a1, a2, a3, a4, a5, a6, a7;
+
+    /* step 1 */
+    a1 = W1 * b[1] + W7 * b[7];
+    a7 = W7 * b[1] - W1 * b[7];
+    a5 = W5 * b[5] + W3 * b[3];
+    a3 = W3 * b[5] - W5 * b[3];
+    a2 = W2 * b[2] + W6 * b[6];
+    a6 = W6 * b[2] - W2 * b[6];
+    a0 = W0 * b[0] + W0 * b[4];
+    a4 = W0 * b[0] - W0 * b[4];
+
+    /* step 2 */
+    s1 = (181 * (a1 - a5 + a7 - a3) + 128) >> 8; // 1, 3, 5, 7
+    s2 = (181 * (a1 - a5 - a7 + a3) + 128) >> 8;
+
+    /* step 3 */
+    b[0] = (a0 + a2 + a1 + a5 + (1 << 7)) >> 8;
+    b[1] = (a4 + a6 + s1      + (1 << 7)) >> 8;
+    b[2] = (a4 - a6 + s2      + (1 << 7)) >> 8;
+    b[3] = (a0 - a2 + a7 + a3 + (1 << 7)) >> 8;
+    b[4] = (a0 - a2 - a7 - a3 + (1 << 7)) >> 8;
+    b[5] = (a4 - a6 - s2      + (1 << 7)) >> 8;
+    b[6] = (a4 + a6 - s1      + (1 << 7)) >> 8;
+    b[7] = (a0 + a2 - a1 - a5 + (1 << 7)) >> 8;
+}
+
+static void wmv2_idct_col(short * b)
+{
+    int s1, s2;
+    int a0, a1, a2, a3, a4, a5, a6, a7;
+
+    /* step 1, with extended precision */
+    a1 = (W1 * b[8 * 1] + W7 * b[8 * 7] + 4) >> 3;
+    a7 = (W7 * b[8 * 1] - W1 * b[8 * 7] + 4) >> 3;
+    a5 = (W5 * b[8 * 5] + W3 * b[8 * 3] + 4) >> 3;
+    a3 = (W3 * b[8 * 5] - W5 * b[8 * 3] + 4) >> 3;
+    a2 = (W2 * b[8 * 2] + W6 * b[8 * 6] + 4) >> 3;
+    a6 = (W6 * b[8 * 2] - W2 * b[8 * 6] + 4) >> 3;
+    a0 = (W0 * b[8 * 0] + W0 * b[8 * 4]    ) >> 3;
+    a4 = (W0 * b[8 * 0] - W0 * b[8 * 4]    ) >> 3;
+
+    /* step 2 */
+    s1 = (181 * (a1 - a5 + a7 - a3) + 128) >> 8;
+    s2 = (181 * (a1 - a5 - a7 + a3) + 128) >> 8;
+
+    /* step 3 */
+    b[8 * 0] = (a0 + a2 + a1 + a5 + (1 << 13)) >> 14;
+    b[8 * 1] = (a4 + a6 + s1      + (1 << 13)) >> 14;
+    b[8 * 2] = (a4 - a6 + s2      + (1 << 13)) >> 14;
+    b[8 * 3] = (a0 - a2 + a7 + a3 + (1 << 13)) >> 14;
+
+    b[8 * 4] = (a0 - a2 - a7 - a3 + (1 << 13)) >> 14;
+    b[8 * 5] = (a4 - a6 - s2      + (1 << 13)) >> 14;
+    b[8 * 6] = (a4 + a6 - s1      + (1 << 13)) >> 14;
+    b[8 * 7] = (a0 + a2 - a1 - a5 + (1 << 13)) >> 14;
+}
+
+static void wmv2_idct_add_c(uint8_t *dest, int line_size, int16_t *block)
+{
+    int i;
+
+    for (i = 0; i < 64; i += 8)
+        wmv2_idct_row(block + i);
+    for (i = 0; i < 8; i++)
+        wmv2_idct_col(block + i);
+
+    for (i = 0; i < 8; i++) {
+        dest[0] = av_clip_uint8(dest[0] + block[0]);
+        dest[1] = av_clip_uint8(dest[1] + block[1]);
+        dest[2] = av_clip_uint8(dest[2] + block[2]);
+        dest[3] = av_clip_uint8(dest[3] + block[3]);
+        dest[4] = av_clip_uint8(dest[4] + block[4]);
+        dest[5] = av_clip_uint8(dest[5] + block[5]);
+        dest[6] = av_clip_uint8(dest[6] + block[6]);
+        dest[7] = av_clip_uint8(dest[7] + block[7]);
+        dest += line_size;
+        block += 8;
+    }
+}
+
+static void wmv2_idct_put_c(uint8_t *dest, int line_size, int16_t *block)
+{
+    int i;
+
+    for (i = 0; i < 64; i += 8)
+        wmv2_idct_row(block + i);
+    for (i = 0; i < 8; i++)
+        wmv2_idct_col(block + i);
+
+    for (i = 0; i < 8; i++) {
+        dest[0] = av_clip_uint8(block[0]);
+        dest[1] = av_clip_uint8(block[1]);
+        dest[2] = av_clip_uint8(block[2]);
+        dest[3] = av_clip_uint8(block[3]);
+        dest[4] = av_clip_uint8(block[4]);
+        dest[5] = av_clip_uint8(block[5]);
+        dest[6] = av_clip_uint8(block[6]);
+        dest[7] = av_clip_uint8(block[7]);
+        dest += line_size;
+        block += 8;
+    }
+}
+
+av_cold void ff_wmv2dsp_init(WMV2DSPContext *c)
+{
+    c->idct_add  = wmv2_idct_add_c;
+    c->idct_put  = wmv2_idct_put_c;
+    c->idct_perm = FF_NO_IDCT_PERM;
+}
diff --git a/libavcodec/arm/dsputil_init_vfp.c b/libavcodec/wmv2dsp.h
similarity index 66%
copy from libavcodec/arm/dsputil_init_vfp.c
copy to libavcodec/wmv2dsp.h
index 5713c71..37bee20 100644
--- a/libavcodec/arm/dsputil_init_vfp.c
+++ b/libavcodec/wmv2dsp.h
@@ -1,6 +1,4 @@
 /*
- * Copyright (c) 2008 Siarhei Siamashka <ssvb@users.sourceforge.net>
- *
  * This file is part of FFmpeg.
  *
  * FFmpeg is free software; you can redistribute it and/or
@@ -18,13 +16,18 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavcodec/dsputil.h"
-#include "dsputil_arm.h"
+#ifndef AVCODEC_WMV2DSP_H
+#define AVCODEC_WMV2DSP_H
 
-void ff_vector_fmul_reverse_vfp(float *dst, const float *src0,
-                                const float *src1, int len);
+#include <stdint.h>
 
-void ff_dsputil_init_vfp(DSPContext* c, AVCodecContext *avctx)
-{
-    c->vector_fmul_reverse = ff_vector_fmul_reverse_vfp;
-}
+typedef struct WMV2DSPContext {
+    void (*idct_add)(uint8_t *dest, int line_size, int16_t *block);
+    void (*idct_put)(uint8_t *dest, int line_size, int16_t *block);
+
+    int idct_perm;
+} WMV2DSPContext;
+
+void ff_wmv2dsp_init(WMV2DSPContext *c);
+
+#endif /* AVCODEC_WMV2DSP_H */
diff --git a/libavcodec/wmv2enc.c b/libavcodec/wmv2enc.c
index e6e1e67..23b64a7 100644
--- a/libavcodec/wmv2enc.c
+++ b/libavcodec/wmv2enc.c
@@ -19,7 +19,6 @@
  */
 
 #include "avcodec.h"
-#include "dsputil.h"
 #include "mpegvideo.h"
 #include "msmpeg4.h"
 #include "msmpeg4data.h"
@@ -148,7 +147,7 @@
  * useless M$ crap features. It is duplicated here in case someone wants
  * to add support for these crap features. */
 void ff_wmv2_encode_mb(MpegEncContext * s,
-                       DCTELEM block[6][64],
+                       int16_t block[6][64],
                        int motion_x, int motion_y)
 {
     Wmv2Context * const w= (Wmv2Context*)s;
diff --git a/libavcodec/wnv1.c b/libavcodec/wnv1.c
index 494dc98..c59ceb7 100644
--- a/libavcodec/wnv1.c
+++ b/libavcodec/wnv1.c
@@ -26,10 +26,11 @@
 
 #include "avcodec.h"
 #include "get_bits.h"
+#include "internal.h"
 #include "mathops.h"
 
 
-typedef struct WNV1Context{
+typedef struct WNV1Context {
     AVCodecContext *avctx;
     AVFrame pic;
 
@@ -37,10 +38,10 @@
     GetBitContext gb;
 } WNV1Context;
 
-static const uint16_t code_tab[16][2]={
-{0x1FD,9}, {0xFD,8}, {0x7D,7}, {0x3D,6}, {0x1D,5}, {0x0D,4}, {0x005,3},
-{0x000,1},
-{0x004,3}, {0x0C,4}, {0x1C,5}, {0x3C,6}, {0x7C,7}, {0xFC,8}, {0x1FC,9}, {0xFF,8}
+static const uint16_t code_tab[16][2] = {
+    { 0x1FD, 9 }, { 0xFD, 8 }, { 0x7D, 7 }, { 0x3D, 6 }, { 0x1D, 5 }, { 0x0D, 4 }, { 0x005, 3 },
+    { 0x000, 1 },
+    { 0x004, 3 }, { 0x0C, 4 }, { 0x1C, 5 }, { 0x3C, 6 }, { 0x7C, 7 }, { 0xFC, 8 }, { 0x1FC, 9 }, { 0xFF, 8 }
 };
 
 #define CODE_VLC_BITS 9
@@ -51,20 +52,20 @@
 {
     int v = get_vlc2(&w->gb, code_vlc.table, CODE_VLC_BITS, 1);
 
-    if(v==15)
-        return ff_reverse[ get_bits(&w->gb, 8 - w->shift) ];
+    if (v == 15)
+        return ff_reverse[get_bits(&w->gb, 8 - w->shift)];
     else
-        return base_value + ((v - 7)<<w->shift);
+        return base_value + ((v - 7) << w->shift);
 }
 
 static int decode_frame(AVCodecContext *avctx,
-                        void *data, int *data_size,
+                        void *data, int *got_frame,
                         AVPacket *avpkt)
 {
-    const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
     WNV1Context * const l = avctx->priv_data;
-    AVFrame * const p = &l->pic;
+    const uint8_t *buf    = avpkt->data;
+    int buf_size          = avpkt->size;
+    AVFrame * const p     = &l->pic;
     unsigned char *Y,*U,*V;
     int i, j, ret;
     int prev_y = 0, prev_u = 0, prev_v = 0;
@@ -76,25 +77,25 @@
     }
 
     rbuf = av_malloc(buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
-    if(!rbuf){
+    if (!rbuf) {
         av_log(avctx, AV_LOG_ERROR, "Cannot allocate temporary buffer\n");
         return AVERROR(ENOMEM);
     }
 
-    if(p->data[0])
+    if (p->data[0])
         avctx->release_buffer(avctx, p);
 
     p->reference = 0;
-    if ((ret = avctx->get_buffer(avctx, p)) < 0) {
+    if ((ret = ff_get_buffer(avctx, p)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         av_free(rbuf);
         return ret;
     }
     p->key_frame = 1;
 
-    for(i=8; i<buf_size; i++)
-        rbuf[i]= ff_reverse[ buf[i] ];
-    init_get_bits(&l->gb, rbuf+8, (buf_size-8)*8);
+    for (i = 8; i < buf_size; i++)
+        rbuf[i] = ff_reverse[buf[i]];
+    init_get_bits(&l->gb, rbuf + 8, (buf_size - 8) * 8);
 
     if (buf[2] >> 4 == 6)
         l->shift = 2;
@@ -128,22 +129,23 @@
     }
 
 
-    *data_size = sizeof(AVFrame);
+    *got_frame      = 1;
     *(AVFrame*)data = l->pic;
     av_free(rbuf);
 
     return buf_size;
 }
 
-static av_cold int decode_init(AVCodecContext *avctx){
+static av_cold int decode_init(AVCodecContext *avctx)
+{
     WNV1Context * const l = avctx->priv_data;
     static VLC_TYPE code_table[1 << CODE_VLC_BITS][2];
 
-    l->avctx = avctx;
+    l->avctx       = avctx;
     avctx->pix_fmt = AV_PIX_FMT_YUV422P;
     avcodec_get_frame_defaults(&l->pic);
 
-    code_vlc.table = code_table;
+    code_vlc.table           = code_table;
     code_vlc.table_allocated = 1 << CODE_VLC_BITS;
     init_vlc(&code_vlc, CODE_VLC_BITS, 16,
              &code_tab[0][1], 4, 2,
@@ -152,7 +154,8 @@
     return 0;
 }
 
-static av_cold int decode_end(AVCodecContext *avctx){
+static av_cold int decode_end(AVCodecContext *avctx)
+{
     WNV1Context * const l = avctx->priv_data;
     AVFrame *pic = &l->pic;
 
diff --git a/libavcodec/ws-snd1.c b/libavcodec/ws-snd1.c
index 7cc0678..24ebceb 100644
--- a/libavcodec/ws-snd1.c
+++ b/libavcodec/ws-snd1.c
@@ -25,6 +25,7 @@
 #include "libavutil/common.h"
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
+#include "internal.h"
 
 /**
  * @file
@@ -40,28 +41,19 @@
      0,  1,  2,  3,  4,  5,  6,  8
 };
 
-typedef struct WSSndContext {
-    AVFrame frame;
-} WSSndContext;
-
 static av_cold int ws_snd_decode_init(AVCodecContext *avctx)
 {
-    WSSndContext *s = avctx->priv_data;
-
     avctx->channels       = 1;
     avctx->channel_layout = AV_CH_LAYOUT_MONO;
     avctx->sample_fmt     = AV_SAMPLE_FMT_U8;
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     return 0;
 }
 
 static int ws_snd_decode_frame(AVCodecContext *avctx, void *data,
                                int *got_frame_ptr, AVPacket *avpkt)
 {
-    WSSndContext *s = avctx->priv_data;
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
 
@@ -88,18 +80,17 @@
     }
 
     /* get output buffer */
-    s->frame.nb_samples = out_size;
-    if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = out_size;
+    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    samples     = s->frame.data[0];
+    samples     = frame->data[0];
     samples_end = samples + out_size;
 
     if (in_size == out_size) {
         memcpy(samples, buf, out_size);
-        *got_frame_ptr   = 1;
-        *(AVFrame *)data = s->frame;
+        *got_frame_ptr = 1;
         return buf_size;
     }
 
@@ -175,9 +166,8 @@
         }
     }
 
-    s->frame.nb_samples = samples - s->frame.data[0];
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
+    frame->nb_samples = samples - frame->data[0];
+    *got_frame_ptr    = 1;
 
     return buf_size;
 }
@@ -186,7 +176,6 @@
     .name           = "ws_snd1",
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_WESTWOOD_SND1,
-    .priv_data_size = sizeof(WSSndContext),
     .init           = ws_snd_decode_init,
     .decode         = ws_snd_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
diff --git a/libavcodec/x86/Makefile b/libavcodec/x86/Makefile
index 66884a5..ff7ea77 100644
--- a/libavcodec/x86/Makefile
+++ b/libavcodec/x86/Makefile
@@ -6,14 +6,17 @@
 OBJS-$(CONFIG_DNXHD_ENCODER)           += x86/dnxhdenc.o
 OBJS-$(CONFIG_FFT)                     += x86/fft_init.o
 OBJS-$(CONFIG_GPL)                     += x86/idct_mmx.o
+OBJS-$(CONFIG_H264CHROMA)              += x86/h264chroma_init.o
 OBJS-$(CONFIG_H264DSP)                 += x86/h264dsp_init.o
 OBJS-$(CONFIG_H264PRED)                += x86/h264_intrapred_init.o
+OBJS-$(CONFIG_H264QPEL)                += x86/h264_qpel.o
 OBJS-$(CONFIG_LPC)                     += x86/lpc.o
 OBJS-$(CONFIG_MLP_DECODER)             += x86/mlpdsp.o
 OBJS-$(CONFIG_MPEGAUDIODSP)            += x86/mpegaudiodec.o
 OBJS-$(CONFIG_MPEGVIDEO)               += x86/mpegvideo.o
 OBJS-$(CONFIG_MPEGVIDEOENC)            += x86/mpegvideoenc.o
 OBJS-$(CONFIG_PNG_DECODER)             += x86/pngdsp_init.o
+OBJS-$(CONFIG_PRORES_DECODER)          += x86/proresdsp_init.o
 OBJS-$(CONFIG_PRORES_LGPL_DECODER)     += x86/proresdsp_init.o
 OBJS-$(CONFIG_RV30_DECODER)            += x86/rv34dsp_init.o
 OBJS-$(CONFIG_RV40_DECODER)            += x86/rv34dsp_init.o            \
@@ -21,6 +24,8 @@
 OBJS-$(CONFIG_V210_DECODER)            += x86/v210-init.o
 OBJS-$(CONFIG_TRUEHD_DECODER)          += x86/mlpdsp.o
 OBJS-$(CONFIG_VC1_DECODER)             += x86/vc1dsp_init.o
+OBJS-$(CONFIG_VIDEODSP)                += x86/videodsp_init.o
+OBJS-$(CONFIG_VORBIS_DECODER)          += x86/vorbisdsp_init.o
 OBJS-$(CONFIG_VP3DSP)                  += x86/vp3dsp_init.o
 OBJS-$(CONFIG_VP5_DECODER)             += x86/vp56dsp_init.o
 OBJS-$(CONFIG_VP6_DECODER)             += x86/vp56dsp_init.o
@@ -33,19 +38,22 @@
                                           x86/idct_sse2_xvid.o          \
                                           x86/simple_idct.o             \
 
-MMX-OBJS-$(CONFIG_DWT)                 += x86/snowdsp.o \
-                                          x86/dwt.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_SNOW_DECODER)        += x86/snowdsp.o
+MMX-OBJS-$(CONFIG_SNOW_ENCODER)        += x86/snowdsp.o
 MMX-OBJS-$(CONFIG_VC1_DECODER)         += x86/vc1dsp_mmx.o
 
 YASM-OBJS-$(CONFIG_AAC_DECODER)        += x86/sbrdsp.o
 YASM-OBJS-$(CONFIG_AC3DSP)             += x86/ac3dsp.o
 YASM-OBJS-$(CONFIG_DCT)                += x86/dct32.o
-YASM-OBJS-$(CONFIG_DIRAC_DECODER)      += x86/diracdsp_mmx.o x86/diracdsp_yasm.o
-YASM-OBJS-$(CONFIG_DWT)                += x86/dwt_yasm.o
+YASM-OBJS-$(CONFIG_DIRAC_DECODER)      += x86/diracdsp_mmx.o x86/diracdsp_yasm.o\
+                                          x86/dwt_yasm.o
 YASM-OBJS-$(CONFIG_ENCODERS)           += x86/dsputilenc.o
 YASM-OBJS-$(CONFIG_FFT)                += x86/fft.o
+YASM-OBJS-$(CONFIG_H263_DECODER)       += x86/h263_loopfilter.o
+YASM-OBJS-$(CONFIG_H263_ENCODER)       += x86/h263_loopfilter.o
 YASM-OBJS-$(CONFIG_H264CHROMA)         += x86/h264_chromamc.o           \
                                           x86/h264_chromamc_10bit.o
 YASM-OBJS-$(CONFIG_H264DSP)            += x86/h264_deblock.o            \
@@ -67,6 +75,8 @@
                                           x86/rv40dsp.o
 YASM-OBJS-$(CONFIG_V210_DECODER)       += x86/v210.o
 YASM-OBJS-$(CONFIG_VC1_DECODER)        += x86/vc1dsp.o
+YASM-OBJS-$(CONFIG_VIDEODSP)           += x86/videodsp.o
+YASM-OBJS-$(CONFIG_VORBIS_DECODER)     += x86/vorbisdsp.o
 YASM-OBJS-$(CONFIG_VP3DSP)             += x86/vp3dsp.o
 YASM-OBJS-$(CONFIG_VP6_DECODER)        += x86/vp56dsp.o
 YASM-OBJS-$(CONFIG_VP8_DECODER)        += x86/vp8dsp.o
@@ -74,3 +84,5 @@
 YASM-OBJS                              += x86/dsputil.o                 \
                                           x86/deinterlace.o             \
                                           x86/fmtconvert.o              \
+                                          x86/hpeldsp.o                 \
+                                          x86/mpeg4qpel.o               \
diff --git a/libavcodec/x86/ac3dsp.asm b/libavcodec/x86/ac3dsp.asm
index 4958a7b..98fb446 100644
--- a/libavcodec/x86/ac3dsp.asm
+++ b/libavcodec/x86/ac3dsp.asm
@@ -151,15 +151,12 @@
 %endmacro
 
 INIT_MMX mmx
-%define ABS2 ABS2_MMX
 AC3_MAX_MSB_ABS_INT16 or_abs
 INIT_MMX mmxext
-%define ABS2 ABS2_MMXEXT
 AC3_MAX_MSB_ABS_INT16 min_max
 INIT_XMM sse2
 AC3_MAX_MSB_ABS_INT16 min_max
 INIT_XMM ssse3
-%define ABS2 ABS2_SSSE3
 AC3_MAX_MSB_ABS_INT16 or_abs
 
 ;-----------------------------------------------------------------------------
diff --git a/libavcodec/x86/ac3dsp_init.c b/libavcodec/x86/ac3dsp_init.c
index e95131e..e2a190e 100644
--- a/libavcodec/x86/ac3dsp_init.c
+++ b/libavcodec/x86/ac3dsp_init.c
@@ -51,25 +51,30 @@
 extern void ff_ac3_extract_exponents_sse2 (uint8_t *exp, int32_t *coef, int nb_coefs);
 extern void ff_ac3_extract_exponents_ssse3(uint8_t *exp, int32_t *coef, int nb_coefs);
 
-#if HAVE_SSE_INLINE
+#if ARCH_X86_32 && defined(__INTEL_COMPILER)
+#       undef HAVE_7REGS
+#       define HAVE_7REGS 0
+#endif
+
+#if HAVE_SSE_INLINE && HAVE_7REGS
 
 #define IF1(x) x
 #define IF0(x)
 
 #define MIX5(mono, stereo)                                      \
     __asm__ volatile (                                          \
-        "movss           0(%2), %%xmm5          \n"             \
-        "movss           8(%2), %%xmm6          \n"             \
-        "movss          24(%2), %%xmm7          \n"             \
+        "movss           0(%1), %%xmm5          \n"             \
+        "movss           8(%1), %%xmm6          \n"             \
+        "movss          24(%1), %%xmm7          \n"             \
         "shufps     $0, %%xmm5, %%xmm5          \n"             \
         "shufps     $0, %%xmm6, %%xmm6          \n"             \
         "shufps     $0, %%xmm7, %%xmm7          \n"             \
         "1:                                     \n"             \
-        "movaps       (%0, %1), %%xmm0          \n"             \
-        "movaps  0x400(%0, %1), %%xmm1          \n"             \
-        "movaps  0x800(%0, %1), %%xmm2          \n"             \
-        "movaps  0xc00(%0, %1), %%xmm3          \n"             \
-        "movaps 0x1000(%0, %1), %%xmm4          \n"             \
+        "movaps       (%0, %2), %%xmm0          \n"             \
+        "movaps       (%0, %3), %%xmm1          \n"             \
+        "movaps       (%0, %4), %%xmm2          \n"             \
+        "movaps       (%0, %5), %%xmm3          \n"             \
+        "movaps       (%0, %6), %%xmm4          \n"             \
         "mulps          %%xmm5, %%xmm0          \n"             \
         "mulps          %%xmm6, %%xmm1          \n"             \
         "mulps          %%xmm5, %%xmm2          \n"             \
@@ -80,12 +85,17 @@
         "addps          %%xmm3, %%xmm0          \n"             \
         "addps          %%xmm4, %%xmm2          \n"             \
    mono("addps          %%xmm2, %%xmm0          \n")            \
-        "movaps         %%xmm0, (%0, %1)        \n"             \
- stereo("movaps         %%xmm2, 0x400(%0, %1)   \n")            \
+        "movaps         %%xmm0, (%0, %2)        \n"             \
+ stereo("movaps         %%xmm2, (%0, %3)        \n")            \
         "add               $16, %0              \n"             \
         "jl                 1b                  \n"             \
         : "+&r"(i)                                              \
-        : "r"(samples[0] + len), "r"(matrix)                    \
+        : "r"(matrix),                                          \
+          "r"(samples[0] + len),                                \
+          "r"(samples[1] + len),                                \
+          "r"(samples[2] + len),                                \
+          "r"(samples[3] + len),                                \
+          "r"(samples[4] + len)                                 \
         : XMM_CLOBBERS("%xmm0", "%xmm1", "%xmm2", "%xmm3",      \
                       "%xmm4", "%xmm5", "%xmm6", "%xmm7",)      \
          "memory"                                               \
@@ -93,38 +103,42 @@
 
 #define MIX_MISC(stereo)                                        \
     __asm__ volatile (                                          \
+        "mov              %5, %2            \n"                 \
         "1:                                 \n"                 \
+        "mov -%c7(%6, %2, %c8), %3          \n"                 \
         "movaps     (%3, %0), %%xmm0        \n"                 \
  stereo("movaps       %%xmm0, %%xmm1        \n")                \
         "mulps        %%xmm4, %%xmm0        \n"                 \
  stereo("mulps        %%xmm5, %%xmm1        \n")                \
-        "lea    1024(%3, %0), %1            \n"                 \
-        "mov              %5, %2            \n"                 \
         "2:                                 \n"                 \
-        "movaps         (%1), %%xmm2        \n"                 \
+        "mov   (%6, %2, %c8), %1            \n"                 \
+        "movaps     (%1, %0), %%xmm2        \n"                 \
  stereo("movaps       %%xmm2, %%xmm3        \n")                \
-        "mulps      (%4, %2), %%xmm2        \n"                 \
- stereo("mulps    16(%4, %2), %%xmm3        \n")                \
+        "mulps   (%4, %2, 8), %%xmm2        \n"                 \
+ stereo("mulps 16(%4, %2, 8), %%xmm3        \n")                \
         "addps        %%xmm2, %%xmm0        \n"                 \
  stereo("addps        %%xmm3, %%xmm1        \n")                \
-        "add           $1024, %1            \n"                 \
-        "add             $32, %2            \n"                 \
+        "add              $4, %2            \n"                 \
         "jl               2b                \n"                 \
-        "movaps       %%xmm0,     (%3, %0)  \n"                 \
- stereo("movaps       %%xmm1, 1024(%3, %0)  \n")                \
+        "mov              %5, %2            \n"                 \
+ stereo("mov   (%6, %2, %c8), %1            \n")                \
+        "movaps       %%xmm0, (%3, %0)      \n"                 \
+ stereo("movaps       %%xmm1, (%1, %0)      \n")                \
         "add             $16, %0            \n"                 \
         "jl               1b                \n"                 \
-        : "+&r"(i), "=&r"(j), "=&r"(k)                          \
-        : "r"(samples[0] + len), "r"(matrix_simd + in_ch),      \
-          "g"((intptr_t) - 32 * (in_ch - 1))                    \
+        : "+&r"(i), "=&r"(j), "=&r"(k), "=&r"(m)                \
+        : "r"(matrix_simd + in_ch),                             \
+          "g"((intptr_t) - 4 * (in_ch - 1)),                    \
+          "r"(samp + in_ch),                                    \
+          "i"(sizeof(float *)), "i"(sizeof(float *)/4)          \
         : "memory"                                              \
     );
 
-static void ac3_downmix_sse(float (*samples)[256], float (*matrix)[2],
+static void ac3_downmix_sse(float **samples, float (*matrix)[2],
                             int out_ch, int in_ch, int len)
 {
     int (*matrix_cmp)[2] = (int(*)[2])matrix;
-    intptr_t i, j, k;
+    intptr_t i, j, k, m;
 
     i = -len * sizeof(float);
     if (in_ch == 5 && out_ch == 2 &&
@@ -139,6 +153,11 @@
         MIX5(IF1, IF0);
     } else {
         DECLARE_ALIGNED(16, float, matrix_simd)[AC3_MAX_CHANNELS][2][4];
+        float *samp[AC3_MAX_CHANNELS];
+
+        for (j = 0; j < in_ch; j++)
+            samp[j] = samples[j] + len;
+
         j = 2 * in_ch * sizeof(float);
         __asm__ volatile (
             "1:                                 \n"
@@ -162,7 +181,7 @@
     }
 }
 
-#endif /* HAVE_SSE_INLINE */
+#endif /* HAVE_SSE_INLINE && HAVE_7REGS */
 
 av_cold void ff_ac3dsp_init_x86(AC3DSPContext *c, int bit_exact)
 {
@@ -205,7 +224,7 @@
         }
     }
 
-#if HAVE_SSE_INLINE
+#if HAVE_SSE_INLINE && HAVE_7REGS
     if (INLINE_SSE(mm_flags)) {
         c->downmix = ac3_downmix_sse;
     }
diff --git a/libavcodec/x86/cabac.h b/libavcodec/x86/cabac.h
index 35f4ca7..2c9f77e 100644
--- a/libavcodec/x86/cabac.h
+++ b/libavcodec/x86/cabac.h
@@ -151,7 +151,7 @@
 
 
 #if HAVE_7REGS && !(defined(__i386) && defined(__clang__) && (__clang_major__<2 || (__clang_major__==2 && __clang_minor__<10)))\
-               && !(defined(__i386) && !defined(__clang__) && defined(__llvm__) && __GNUC__==4 && __GNUC_MINOR__==2 && __GNUC_PATCHLEVEL__<=1)
+               && !(                  !defined(__clang__) && defined(__llvm__) && __GNUC__==4 && __GNUC_MINOR__==2 && __GNUC_PATCHLEVEL__<=1)
 #define get_cabac_inline get_cabac_inline_x86
 static av_always_inline int get_cabac_inline_x86(CABACContext *c,
                                                  uint8_t *const state)
diff --git a/libavcodec/x86/cavsdsp.c b/libavcodec/x86/cavsdsp.c
index 6a252e0..dd75584 100644
--- a/libavcodec/x86/cavsdsp.c
+++ b/libavcodec/x86/cavsdsp.c
@@ -22,11 +22,11 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/common.h"
 #include "libavutil/cpu.h"
 #include "libavutil/x86/asm.h"
 #include "libavutil/x86/cpu.h"
-#include "libavcodec/dsputil.h"
 #include "libavcodec/cavsdsp.h"
 #include "dsputil_mmx.h"
 #include "config.h"
@@ -446,7 +446,8 @@
 CAVS_MC(avg_,  8, mmxext)
 CAVS_MC(avg_, 16, mmxext)
 
-static void ff_cavsdsp_init_mmxext(CAVSDSPContext *c, AVCodecContext *avctx)
+static av_cold void ff_cavsdsp_init_mmxext(CAVSDSPContext *c,
+                                           AVCodecContext *avctx)
 {
 #define dspfunc(PFX, IDX, NUM) \
     c->PFX ## _pixels_tab[IDX][ 0] = ff_ ## PFX ## NUM ## _mc00_mmxext; \
@@ -474,7 +475,9 @@
 CAVS_MC(avg_, 8, 3dnow)
 CAVS_MC(avg_, 16,3dnow)
 
-static void ff_cavsdsp_init_3dnow(CAVSDSPContext* c, AVCodecContext *avctx) {
+static av_cold void ff_cavsdsp_init_3dnow(CAVSDSPContext *c,
+                                          AVCodecContext *avctx)
+{
 #define dspfunc(PFX, IDX, NUM) \
     c->PFX ## _pixels_tab[IDX][ 0] = ff_ ## PFX ## NUM ## _mc00_mmxext; \
     c->PFX ## _pixels_tab[IDX][ 2] = ff_ ## PFX ## NUM ## _mc20_3dnow; \
diff --git a/libavcodec/x86/dwt.c b/libavcodec/x86/dirac_dwt.c
similarity index 99%
rename from libavcodec/x86/dwt.c
rename to libavcodec/x86/dirac_dwt.c
index e718c80..fbb25a4 100644
--- a/libavcodec/x86/dwt.c
+++ b/libavcodec/x86/dirac_dwt.c
@@ -22,7 +22,7 @@
 
 #include "libavutil/x86/asm.h"
 #include "dsputil_mmx.h"
-#include "dwt.h"
+#include "dirac_dwt.h"
 
 #define COMPOSE_VERTICAL(ext, align) \
 void ff_vertical_compose53iL0##ext(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width); \
diff --git a/libavcodec/x86/dwt.h b/libavcodec/x86/dirac_dwt.h
similarity index 91%
rename from libavcodec/x86/dwt.h
rename to libavcodec/x86/dirac_dwt.h
index 199f611..126b290 100644
--- a/libavcodec/x86/dwt.h
+++ b/libavcodec/x86/dirac_dwt.h
@@ -16,10 +16,10 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#ifndef AVCODEC_X86_DWT_H
-#define AVCODEC_X86_DWT_H
+#ifndef AVCODEC_X86_DIRAC_DWT_H
+#define AVCODEC_X86_DIRAC_DWT_H
 
-#include "libavcodec/dwt.h"
+#include "libavcodec/dirac_dwt.h"
 
 void ff_horizontal_compose_dd97i_end_c(IDWTELEM *b, IDWTELEM *tmp, int w2, int x);
 void ff_horizontal_compose_haar1i_end_c(IDWTELEM *b, IDWTELEM *tmp, int w2, int x);
diff --git a/libavcodec/x86/diracdsp_mmx.c b/libavcodec/x86/diracdsp_mmx.c
index ee89295..cb6465f 100644
--- a/libavcodec/x86/diracdsp_mmx.c
+++ b/libavcodec/x86/diracdsp_mmx.c
@@ -60,6 +60,9 @@
 {
     int mm_flags = av_get_cpu_flags();
 
+    if (!(mm_flags & AV_CPU_FLAG_MMX))
+        return;
+
 #if HAVE_YASM
     c->add_dirac_obmc[0] = ff_add_dirac_obmc8_mmx;
 #if !ARCH_X86_64
diff --git a/libavcodec/x86/diracdsp_yasm.asm b/libavcodec/x86/diracdsp_yasm.asm
index d12fc64..3e9765b 100644
--- a/libavcodec/x86/diracdsp_yasm.asm
+++ b/libavcodec/x86/diracdsp_yasm.asm
@@ -136,6 +136,8 @@
     and     wd, ~(mmsize-1)
 
 %if ARCH_X86_64
+    movsxd   dst_strideq, dst_strided
+    movsxd   src_strideq, src_strided
     mov   r7d, r5m
     mov   r8d, wd
     %define wspill r8d
@@ -177,6 +179,8 @@
     and     wd, ~(mmsize-1)
 
 %if ARCH_X86_64
+    movsxd   strideq, strided
+    movsxd   idwt_strideq, idwt_strided
     mov   r8d, wd
     %define wspill r8d
 %else
diff --git a/libavcodec/x86/dnxhdenc.c b/libavcodec/x86/dnxhdenc.c
index b2ba894..349fbb0 100644
--- a/libavcodec/x86/dnxhdenc.c
+++ b/libavcodec/x86/dnxhdenc.c
@@ -21,12 +21,13 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/x86/asm.h"
 #include "libavcodec/dnxhdenc.h"
 
 #if HAVE_SSE2_INLINE
 
-static void get_pixels_8x4_sym_sse2(DCTELEM *block, const uint8_t *pixels, int line_size)
+static void get_pixels_8x4_sym_sse2(int16_t *block, const uint8_t *pixels, int line_size)
 {
     __asm__ volatile(
         "pxor %%xmm5,      %%xmm5       \n\t"
@@ -54,7 +55,7 @@
 
 #endif /* HAVE_SSE2_INLINE */
 
-void ff_dnxhdenc_init_x86(DNXHDEncContext *ctx)
+av_cold void ff_dnxhdenc_init_x86(DNXHDEncContext *ctx)
 {
 #if HAVE_SSE2_INLINE
     if (av_get_cpu_flags() & AV_CPU_FLAG_SSE2) {
diff --git a/libavcodec/x86/dsputil.asm b/libavcodec/x86/dsputil.asm
index 61b5cf3..aa18bdd 100644
--- a/libavcodec/x86/dsputil.asm
+++ b/libavcodec/x86/dsputil.asm
@@ -1,6 +1,8 @@
 ;******************************************************************************
 ;* MMX optimized DSP utils
 ;* Copyright (c) 2008 Loren Merritt
+;* Copyright (c) 2003-2013 Michael Niedermayer
+;* Copyright (c) 2013 Daniel Kang
 ;*
 ;* This file is part of FFmpeg.
 ;*
@@ -463,603 +465,6 @@
 .src_unaligned:
     ADD_HFYU_LEFT_LOOP 0, 0
 
-
-; float scalarproduct_float_sse(const float *v1, const float *v2, int len)
-INIT_XMM sse
-cglobal scalarproduct_float, 3,3,2, v1, v2, offset
-    neg offsetq
-    shl offsetq, 2
-    sub v1q, offsetq
-    sub v2q, offsetq
-    xorps xmm0, xmm0
-    .loop:
-        movaps   xmm1, [v1q+offsetq]
-        mulps    xmm1, [v2q+offsetq]
-        addps    xmm0, xmm1
-        add      offsetq, 16
-        js       .loop
-    movhlps xmm1, xmm0
-    addps   xmm0, xmm1
-    movss   xmm1, xmm0
-    shufps  xmm0, xmm0, 1
-    addss   xmm0, xmm1
-%if ARCH_X86_64 == 0
-    movss   r0m,  xmm0
-    fld     dword r0m
-%endif
-    RET
-
-; extern void ff_emu_edge_core(uint8_t *buf, const uint8_t *src, x86_reg linesize,
-;                              x86_reg start_y, x86_reg end_y, x86_reg block_h,
-;                              x86_reg start_x, x86_reg end_x, x86_reg block_w);
-;
-; The actual function itself is below. It basically wraps a very simple
-; w = end_x - start_x
-; if (w) {
-;   if (w > 22) {
-;     jump to the slow loop functions
-;   } else {
-;     jump to the fast loop functions
-;   }
-; }
-;
-; ... and then the same for left/right extend also. See below for loop
-; function implementations. Fast are fixed-width, slow is variable-width
-
-%macro EMU_EDGE_FUNC 0
-%if ARCH_X86_64
-%define w_reg r7
-cglobal emu_edge_core, 6, 9, 1
-    mov         r8, r5          ; save block_h
-%else
-%define w_reg r6
-cglobal emu_edge_core, 2, 7, 0
-    mov         r4, r4m         ; end_y
-    mov         r5, r5m         ; block_h
-%endif
-
-    ; start with vertical extend (top/bottom) and body pixel copy
-    mov      w_reg, r7m
-    sub      w_reg, r6m         ; w = start_x - end_x
-    sub         r5, r4
-%if ARCH_X86_64
-    sub         r4, r3
-%else
-    sub         r4, dword r3m
-%endif
-    cmp      w_reg, 22
-    jg .slow_v_extend_loop
-%if ARCH_X86_32
-    mov         r2, r2m         ; linesize
-%endif
-    sal      w_reg, 7           ; w * 128
-%ifdef PIC
-    lea        rax, [.emuedge_v_extend_1 - (.emuedge_v_extend_2 - .emuedge_v_extend_1)]
-    add      w_reg, rax
-%else
-    lea      w_reg, [.emuedge_v_extend_1 - (.emuedge_v_extend_2 - .emuedge_v_extend_1)+w_reg]
-%endif
-    call     w_reg              ; fast top extend, body copy and bottom extend
-.v_extend_end:
-
-    ; horizontal extend (left/right)
-    mov      w_reg, r6m         ; start_x
-    sub         r0, w_reg
-%if ARCH_X86_64
-    mov         r3, r0          ; backup of buf+block_h*linesize
-    mov         r5, r8
-%else
-    mov        r0m, r0          ; backup of buf+block_h*linesize
-    mov         r5, r5m
-%endif
-    test     w_reg, w_reg
-    jz .right_extend
-    cmp      w_reg, 22
-    jg .slow_left_extend_loop
-    mov         r1, w_reg
-    dec      w_reg
-    ; FIXME we can do a if size == 1 here if that makes any speed difference, test me
-    sar      w_reg, 1
-    sal      w_reg, 6
-    ; r0=buf+block_h*linesize,r7(64)/r6(32)=start_x offset for funcs
-    ; r6(rax)/r3(ebx)=val,r2=linesize,r1=start_x,r5=block_h
-%ifdef PIC
-    lea        rax, [.emuedge_extend_left_2]
-    add      w_reg, rax
-%else
-    lea      w_reg, [.emuedge_extend_left_2+w_reg]
-%endif
-    call     w_reg
-
-    ; now r3(64)/r0(32)=buf,r2=linesize,r8/r5=block_h,r6/r3=val, r7/r6=end_x, r1=block_w
-.right_extend:
-%if ARCH_X86_32
-    mov         r0, r0m
-    mov         r5, r5m
-%endif
-    mov      w_reg, r7m         ; end_x
-    mov         r1, r8m         ; block_w
-    mov         r4, r1
-    sub         r1, w_reg
-    jz .h_extend_end            ; if (end_x == block_w) goto h_extend_end
-    cmp         r1, 22
-    jg .slow_right_extend_loop
-    dec         r1
-    ; FIXME we can do a if size == 1 here if that makes any speed difference, test me
-    sar         r1, 1
-    sal         r1, 6
-%ifdef PIC
-    lea        rax, [.emuedge_extend_right_2]
-    add         r1, rax
-%else
-    lea         r1, [.emuedge_extend_right_2+r1]
-%endif
-    call        r1
-.h_extend_end:
-    RET
-
-%if ARCH_X86_64
-%define vall  al
-%define valh  ah
-%define valw  ax
-%define valw2 r7w
-%define valw3 r3w
-%if WIN64
-%define valw4 r7w
-%else ; unix64
-%define valw4 r3w
-%endif
-%define vald eax
-%else
-%define vall  bl
-%define valh  bh
-%define valw  bx
-%define valw2 r6w
-%define valw3 valw2
-%define valw4 valw3
-%define vald ebx
-%define stack_offset 0x14
-%endif
-
-%endmacro
-
-; macro to read/write a horizontal number of pixels (%2) to/from registers
-; on x86-64, - fills xmm0-15 for consecutive sets of 16 pixels
-;            - if (%2 & 15 == 8) fills the last 8 bytes into rax
-;            - else if (%2 & 8)  fills 8 bytes into mm0
-;            - if (%2 & 7 == 4)  fills the last 4 bytes into rax
-;            - else if (%2 & 4)  fills 4 bytes into mm0-1
-;            - if (%2 & 3 == 3)  fills 2 bytes into r7/r3, and 1 into eax
-;              (note that we're using r3 for body/bottom because it's a shorter
-;               opcode, and then the loop fits in 128 bytes)
-;            - else              fills remaining bytes into rax
-; on x86-32, - fills mm0-7 for consecutive sets of 8 pixels
-;            - if (%2 & 7 == 4)  fills 4 bytes into ebx
-;            - else if (%2 & 4)  fills 4 bytes into mm0-7
-;            - if (%2 & 3 == 3)  fills 2 bytes into r6, and 1 into ebx
-;            - else              fills remaining bytes into ebx
-; writing data out is in the same way
-%macro READ_NUM_BYTES 2
-%assign %%src_off 0 ; offset in source buffer
-%assign %%smidx   0 ; mmx register idx
-%assign %%sxidx   0 ; xmm register idx
-
-%if cpuflag(sse)
-%rep %2/16
-    movups xmm %+ %%sxidx, [r1+%%src_off]
-%assign %%src_off %%src_off+16
-%assign %%sxidx   %%sxidx+1
-%endrep ; %2/16
-%endif
-
-%if ARCH_X86_64
-%if (%2-%%src_off) == 8
-    mov           rax, [r1+%%src_off]
-%assign %%src_off %%src_off+8
-%endif ; (%2-%%src_off) == 8
-%endif ; x86-64
-
-%rep (%2-%%src_off)/8
-    movq    mm %+ %%smidx, [r1+%%src_off]
-%assign %%src_off %%src_off+8
-%assign %%smidx   %%smidx+1
-%endrep ; (%2-%%dst_off)/8
-
-%if (%2-%%src_off) == 4
-    mov          vald, [r1+%%src_off]
-%elif (%2-%%src_off) & 4
-    movd    mm %+ %%smidx, [r1+%%src_off]
-%assign %%src_off %%src_off+4
-%endif ; (%2-%%src_off) ==/& 4
-
-%if (%2-%%src_off) == 1
-    mov          vall, [r1+%%src_off]
-%elif (%2-%%src_off) == 2
-    mov          valw, [r1+%%src_off]
-%elif (%2-%%src_off) == 3
-%ifidn %1, top
-    mov         valw2, [r1+%%src_off]
-%elifidn %1, body
-    mov         valw3, [r1+%%src_off]
-%elifidn %1, bottom
-    mov         valw4, [r1+%%src_off]
-%endif ; %1 ==/!= top
-    mov          vall, [r1+%%src_off+2]
-%endif ; (%2-%%src_off) == 1/2/3
-%endmacro ; READ_NUM_BYTES
-
-%macro WRITE_NUM_BYTES 2
-%assign %%dst_off 0 ; offset in destination buffer
-%assign %%dmidx   0 ; mmx register idx
-%assign %%dxidx   0 ; xmm register idx
-
-%if cpuflag(sse)
-%rep %2/16
-    movups [r0+%%dst_off], xmm %+ %%dxidx
-%assign %%dst_off %%dst_off+16
-%assign %%dxidx   %%dxidx+1
-%endrep ; %2/16
-%endif
-
-%if ARCH_X86_64
-%if (%2-%%dst_off) == 8
-    mov    [r0+%%dst_off], rax
-%assign %%dst_off %%dst_off+8
-%endif ; (%2-%%dst_off) == 8
-%endif ; x86-64
-
-%rep (%2-%%dst_off)/8
-    movq   [r0+%%dst_off], mm %+ %%dmidx
-%assign %%dst_off %%dst_off+8
-%assign %%dmidx   %%dmidx+1
-%endrep ; (%2-%%dst_off)/8
-
-%if (%2-%%dst_off) == 4
-    mov    [r0+%%dst_off], vald
-%elif (%2-%%dst_off) & 4
-    movd   [r0+%%dst_off], mm %+ %%dmidx
-%assign %%dst_off %%dst_off+4
-%endif ; (%2-%%dst_off) ==/& 4
-
-%if (%2-%%dst_off) == 1
-    mov    [r0+%%dst_off], vall
-%elif (%2-%%dst_off) == 2
-    mov    [r0+%%dst_off], valw
-%elif (%2-%%dst_off) == 3
-%ifidn %1, top
-    mov    [r0+%%dst_off], valw2
-%elifidn %1, body
-    mov    [r0+%%dst_off], valw3
-%elifidn %1, bottom
-    mov    [r0+%%dst_off], valw4
-%endif ; %1 ==/!= top
-    mov  [r0+%%dst_off+2], vall
-%endif ; (%2-%%dst_off) == 1/2/3
-%endmacro ; WRITE_NUM_BYTES
-
-; vertical top/bottom extend and body copy fast loops
-; these are function pointers to set-width line copy functions, i.e.
-; they read a fixed number of pixels into set registers, and write
-; those out into the destination buffer
-; r0=buf,r1=src,r2=linesize,r3(64)/r3m(32)=start_x,r4=end_y,r5=block_h
-; r6(eax/64)/r3(ebx/32)=val_reg
-%macro VERTICAL_EXTEND 0
-%assign %%n 1
-%rep 22
-ALIGN 128
-.emuedge_v_extend_ %+ %%n:
-    ; extend pixels above body
-%if ARCH_X86_64
-    test           r3 , r3                   ; if (!start_y)
-    jz .emuedge_copy_body_ %+ %%n %+ _loop   ;   goto body
-%else ; ARCH_X86_32
-    cmp      dword r3m, 0
-    je .emuedge_copy_body_ %+ %%n %+ _loop
-%endif ; ARCH_X86_64/32
-    READ_NUM_BYTES  top,    %%n              ; read bytes
-.emuedge_extend_top_ %+ %%n %+ _loop:        ; do {
-    WRITE_NUM_BYTES top,    %%n              ;   write bytes
-    add            r0 , r2                   ;   dst += linesize
-%if ARCH_X86_64
-    dec            r3d
-%else ; ARCH_X86_32
-    dec      dword r3m
-%endif ; ARCH_X86_64/32
-    jnz .emuedge_extend_top_ %+ %%n %+ _loop ; } while (--start_y)
-
-    ; copy body pixels
-.emuedge_copy_body_ %+ %%n %+ _loop:         ; do {
-    READ_NUM_BYTES  body,   %%n              ;   read bytes
-    WRITE_NUM_BYTES body,   %%n              ;   write bytes
-    add            r0 , r2                   ;   dst += linesize
-    add            r1 , r2                   ;   src += linesize
-    dec            r4d
-    jnz .emuedge_copy_body_ %+ %%n %+ _loop  ; } while (--end_y)
-
-    ; copy bottom pixels
-    test           r5 , r5                   ; if (!block_h)
-    jz .emuedge_v_extend_end_ %+ %%n         ;   goto end
-    sub            r1 , r2                   ; src -= linesize
-    READ_NUM_BYTES  bottom, %%n              ; read bytes
-.emuedge_extend_bottom_ %+ %%n %+ _loop:     ; do {
-    WRITE_NUM_BYTES bottom, %%n              ;   write bytes
-    add            r0 , r2                   ;   dst += linesize
-    dec            r5d
-    jnz .emuedge_extend_bottom_ %+ %%n %+ _loop ; } while (--block_h)
-
-.emuedge_v_extend_end_ %+ %%n:
-%if ARCH_X86_64
-    ret
-%else ; ARCH_X86_32
-    rep ret
-%endif ; ARCH_X86_64/32
-%assign %%n %%n+1
-%endrep
-%endmacro VERTICAL_EXTEND
-
-; left/right (horizontal) fast extend functions
-; these are essentially identical to the vertical extend ones above,
-; just left/right separated because number of pixels to extend is
-; obviously not the same on both sides.
-; for reading, pixels are placed in eax (x86-64) or ebx (x86-64) in the
-; lowest two bytes of the register (so val*0x0101), and are splatted
-; into each byte of mm0 as well if n_pixels >= 8
-
-%macro READ_V_PIXEL 2
-    mov        vall, %2
-    mov        valh, vall
-%if %1 >= 8
-    movd        mm0, vald
-%if cpuflag(mmxext)
-    pshufw      mm0, mm0, 0
-%else ; mmx
-    punpcklwd   mm0, mm0
-    punpckldq   mm0, mm0
-%endif ; sse
-%endif ; %1 >= 8
-%endmacro
-
-%macro WRITE_V_PIXEL 2
-%assign %%dst_off 0
-%rep %1/8
-    movq [%2+%%dst_off], mm0
-%assign %%dst_off %%dst_off+8
-%endrep
-%if %1 & 4
-%if %1 >= 8
-    movd [%2+%%dst_off], mm0
-%else ; %1 < 8
-    mov  [%2+%%dst_off]  , valw
-    mov  [%2+%%dst_off+2], valw
-%endif ; %1 >=/< 8
-%assign %%dst_off %%dst_off+4
-%endif ; %1 & 4
-%if %1&2
-    mov  [%2+%%dst_off], valw
-%endif ; %1 & 2
-%endmacro
-
-; r0=buf+block_h*linesize, r1=start_x, r2=linesize, r5=block_h, r6/r3=val
-%macro LEFT_EXTEND 0
-%assign %%n 2
-%rep 11
-ALIGN 64
-.emuedge_extend_left_ %+ %%n:          ; do {
-    sub         r0, r2                 ;   dst -= linesize
-    READ_V_PIXEL  %%n, [r0+r1]         ;   read pixels
-    WRITE_V_PIXEL %%n, r0              ;   write pixels
-    dec         r5
-    jnz .emuedge_extend_left_ %+ %%n   ; } while (--block_h)
-%if ARCH_X86_64
-    ret
-%else ; ARCH_X86_32
-    rep ret
-%endif ; ARCH_X86_64/32
-%assign %%n %%n+2
-%endrep
-%endmacro ; LEFT_EXTEND
-
-; r3/r0=buf+block_h*linesize, r2=linesize, r8/r5=block_h, r0/r6=end_x, r6/r3=val
-%macro RIGHT_EXTEND 0
-%assign %%n 2
-%rep 11
-ALIGN 64
-.emuedge_extend_right_ %+ %%n:          ; do {
-%if ARCH_X86_64
-    sub        r3, r2                   ;   dst -= linesize
-    READ_V_PIXEL  %%n, [r3+w_reg-1]     ;   read pixels
-    WRITE_V_PIXEL %%n, r3+r4-%%n        ;   write pixels
-    dec       r8
-%else ; ARCH_X86_32
-    sub        r0, r2                   ;   dst -= linesize
-    READ_V_PIXEL  %%n, [r0+w_reg-1]     ;   read pixels
-    WRITE_V_PIXEL %%n, r0+r4-%%n        ;   write pixels
-    dec     r5
-%endif ; ARCH_X86_64/32
-    jnz .emuedge_extend_right_ %+ %%n   ; } while (--block_h)
-%if ARCH_X86_64
-    ret
-%else ; ARCH_X86_32
-    rep ret
-%endif ; ARCH_X86_64/32
-%assign %%n %%n+2
-%endrep
-
-%if ARCH_X86_32
-%define stack_offset 0x10
-%endif
-%endmacro ; RIGHT_EXTEND
-
-; below follow the "slow" copy/extend functions, these act on a non-fixed
-; width specified in a register, and run a loop to copy the full amount
-; of bytes. They are optimized for copying of large amounts of pixels per
-; line, so they unconditionally splat data into mm registers to copy 8
-; bytes per loop iteration. It could be considered to use xmm for x86-64
-; also, but I haven't optimized this as much (i.e. FIXME)
-%macro V_COPY_NPX 4-5
-%if %0 == 4
-    test     w_reg, %4
-    jz .%1_skip_%4_px
-%else ; %0 == 5
-.%1_%4_px_loop:
-%endif
-    %3          %2, [r1+cnt_reg]
-    %3 [r0+cnt_reg], %2
-    add    cnt_reg, %4
-%if %0 == 5
-    sub      w_reg, %4
-    test     w_reg, %5
-    jnz .%1_%4_px_loop
-%endif
-.%1_skip_%4_px:
-%endmacro
-
-%macro V_COPY_ROW 2
-%ifidn %1, bottom
-    sub         r1, linesize
-%endif
-.%1_copy_loop:
-    xor    cnt_reg, cnt_reg
-%if notcpuflag(sse)
-%define linesize r2m
-    V_COPY_NPX %1,  mm0, movq,    8, 0xFFFFFFF8
-%else ; sse
-    V_COPY_NPX %1, xmm0, movups, 16, 0xFFFFFFF0
-%if ARCH_X86_64
-%define linesize r2
-    V_COPY_NPX %1, rax , mov,     8
-%else ; ARCH_X86_32
-%define linesize r2m
-    V_COPY_NPX %1,  mm0, movq,    8
-%endif ; ARCH_X86_64/32
-%endif ; sse
-    V_COPY_NPX %1, vald, mov,     4
-    V_COPY_NPX %1, valw, mov,     2
-    V_COPY_NPX %1, vall, mov,     1
-    mov      w_reg, cnt_reg
-%ifidn %1, body
-    add         r1, linesize
-%endif
-    add         r0, linesize
-    dec         %2
-    jnz .%1_copy_loop
-%endmacro
-
-%macro SLOW_V_EXTEND 0
-.slow_v_extend_loop:
-; r0=buf,r1=src,r2(64)/r2m(32)=linesize,r3(64)/r3m(32)=start_x,r4=end_y,r5=block_h
-; r8(64)/r3(later-64)/r2(32)=cnt_reg,r6(64)/r3(32)=val_reg,r7(64)/r6(32)=w=end_x-start_x
-%if ARCH_X86_64
-    push        r8              ; save old value of block_h
-    test        r3, r3
-%define cnt_reg r8
-    jz .do_body_copy            ; if (!start_y) goto do_body_copy
-    V_COPY_ROW top, r3
-%else
-    cmp  dword r3m, 0
-%define cnt_reg r2
-    je .do_body_copy            ; if (!start_y) goto do_body_copy
-    V_COPY_ROW top, dword r3m
-%endif
-
-.do_body_copy:
-    V_COPY_ROW body, r4
-
-%if ARCH_X86_64
-    pop         r8              ; restore old value of block_h
-%define cnt_reg r3
-%endif
-    test        r5, r5
-%if ARCH_X86_64
-    jz .v_extend_end
-%else
-    jz .skip_bottom_extend
-%endif
-    V_COPY_ROW bottom, r5
-%if ARCH_X86_32
-.skip_bottom_extend:
-    mov         r2, r2m
-%endif
-    jmp .v_extend_end
-%endmacro
-
-%macro SLOW_LEFT_EXTEND 0
-.slow_left_extend_loop:
-; r0=buf+block_h*linesize,r2=linesize,r6(64)/r3(32)=val,r5=block_h,r4=cntr,r7/r6=start_x
-    mov         r4, 8
-    sub         r0, linesize
-    READ_V_PIXEL 8, [r0+w_reg]
-.left_extend_8px_loop:
-    movq [r0+r4-8], mm0
-    add         r4, 8
-    cmp         r4, w_reg
-    jle .left_extend_8px_loop
-    sub         r4, 8
-    cmp         r4, w_reg
-    jge .left_extend_loop_end
-.left_extend_2px_loop:
-    mov    [r0+r4], valw
-    add         r4, 2
-    cmp         r4, w_reg
-    jl .left_extend_2px_loop
-.left_extend_loop_end:
-    dec         r5
-    jnz .slow_left_extend_loop
-%if ARCH_X86_32
-    mov         r2, r2m
-%endif
-    jmp .right_extend
-%endmacro
-
-%macro SLOW_RIGHT_EXTEND 0
-.slow_right_extend_loop:
-; r3(64)/r0(32)=buf+block_h*linesize,r2=linesize,r4=block_w,r8(64)/r5(32)=block_h,
-; r7(64)/r6(32)=end_x,r6/r3=val,r1=cntr
-%if ARCH_X86_64
-%define buf_reg r3
-%define bh_reg r8
-%else
-%define buf_reg r0
-%define bh_reg r5
-%endif
-    lea         r1, [r4-8]
-    sub    buf_reg, linesize
-    READ_V_PIXEL 8, [buf_reg+w_reg-1]
-.right_extend_8px_loop:
-    movq [buf_reg+r1], mm0
-    sub         r1, 8
-    cmp         r1, w_reg
-    jge .right_extend_8px_loop
-    add         r1, 8
-    cmp         r1, w_reg
-    je .right_extend_loop_end
-.right_extend_2px_loop:
-    sub         r1, 2
-    mov [buf_reg+r1], valw
-    cmp         r1, w_reg
-    jg .right_extend_2px_loop
-.right_extend_loop_end:
-    dec         bh_reg
-    jnz .slow_right_extend_loop
-    jmp .h_extend_end
-%endmacro
-
-%macro emu_edge 1
-INIT_XMM %1
-EMU_EDGE_FUNC
-VERTICAL_EXTEND
-LEFT_EXTEND
-RIGHT_EXTEND
-SLOW_V_EXTEND
-SLOW_LEFT_EXTEND
-SLOW_RIGHT_EXTEND
-%endmacro
-
-emu_edge sse
-%if ARCH_X86_32
-emu_edge mmx
-%endif
-
 ;-----------------------------------------------------------------------------
 ; void ff_vector_clip_int32(int32_t *dst, const int32_t *src, int32_t min,
 ;                           int32_t max, unsigned int len)
@@ -1138,121 +543,6 @@
 VECTOR_CLIP_INT32 6, 1, 0, 0
 %endif
 
-;-----------------------------------------------------------------------------
-; void vector_fmul_reverse(float *dst, const float *src0, const float *src1,
-;                          int len)
-;-----------------------------------------------------------------------------
-%macro VECTOR_FMUL_REVERSE 0
-cglobal vector_fmul_reverse, 4,4,2, dst, src0, src1, len
-    lea       lenq, [lend*4 - 2*mmsize]
-ALIGN 16
-.loop:
-%if cpuflag(avx)
-    vmovaps     xmm0, [src1q + 16]
-    vinsertf128 m0, m0, [src1q], 1
-    vshufps     m0, m0, m0, q0123
-    vmovaps     xmm1, [src1q + mmsize + 16]
-    vinsertf128 m1, m1, [src1q + mmsize], 1
-    vshufps     m1, m1, m1, q0123
-%else
-    mova    m0, [src1q]
-    mova    m1, [src1q + mmsize]
-    shufps  m0, m0, q0123
-    shufps  m1, m1, q0123
-%endif
-    mulps   m0, m0, [src0q + lenq + mmsize]
-    mulps   m1, m1, [src0q + lenq]
-    mova    [dstq + lenq + mmsize], m0
-    mova    [dstq + lenq], m1
-    add     src1q, 2*mmsize
-    sub     lenq,  2*mmsize
-    jge     .loop
-    REP_RET
-%endmacro
-
-INIT_XMM sse
-VECTOR_FMUL_REVERSE
-%if HAVE_AVX_EXTERNAL
-INIT_YMM avx
-VECTOR_FMUL_REVERSE
-%endif
-
-;-----------------------------------------------------------------------------
-; vector_fmul_add(float *dst, const float *src0, const float *src1,
-;                 const float *src2, int len)
-;-----------------------------------------------------------------------------
-%macro VECTOR_FMUL_ADD 0
-cglobal vector_fmul_add, 5,5,2, dst, src0, src1, src2, len
-    lea       lenq, [lend*4 - 2*mmsize]
-ALIGN 16
-.loop:
-    mova    m0,   [src0q + lenq]
-    mova    m1,   [src0q + lenq + mmsize]
-    mulps   m0, m0, [src1q + lenq]
-    mulps   m1, m1, [src1q + lenq + mmsize]
-    addps   m0, m0, [src2q + lenq]
-    addps   m1, m1, [src2q + lenq + mmsize]
-    mova    [dstq + lenq], m0
-    mova    [dstq + lenq + mmsize], m1
-
-    sub     lenq,   2*mmsize
-    jge     .loop
-    REP_RET
-%endmacro
-
-INIT_XMM sse
-VECTOR_FMUL_ADD
-%if HAVE_AVX_EXTERNAL
-INIT_YMM avx
-VECTOR_FMUL_ADD
-%endif
-
-;-----------------------------------------------------------------------------
-; void ff_butterflies_float_interleave(float *dst, const float *src0,
-;                                      const float *src1, int len);
-;-----------------------------------------------------------------------------
-
-%macro BUTTERFLIES_FLOAT_INTERLEAVE 0
-cglobal butterflies_float_interleave, 4,4,3, dst, src0, src1, len
-%if ARCH_X86_64
-    movsxd    lenq, lend
-%endif
-    test      lenq, lenq
-    jz .end
-    shl       lenq, 2
-    lea      src0q, [src0q +   lenq]
-    lea      src1q, [src1q +   lenq]
-    lea       dstq, [ dstq + 2*lenq]
-    neg       lenq
-.loop:
-    mova        m0, [src0q + lenq]
-    mova        m1, [src1q + lenq]
-    subps       m2, m0, m1
-    addps       m0, m0, m1
-    unpcklps    m1, m0, m2
-    unpckhps    m0, m0, m2
-%if cpuflag(avx)
-    vextractf128 [dstq + 2*lenq     ], m1, 0
-    vextractf128 [dstq + 2*lenq + 16], m0, 0
-    vextractf128 [dstq + 2*lenq + 32], m1, 1
-    vextractf128 [dstq + 2*lenq + 48], m0, 1
-%else
-    mova [dstq + 2*lenq         ], m1
-    mova [dstq + 2*lenq + mmsize], m0
-%endif
-    add       lenq, mmsize
-    jl .loop
-.end:
-    REP_RET
-%endmacro
-
-INIT_XMM sse
-BUTTERFLIES_FLOAT_INTERLEAVE
-%if HAVE_AVX_EXTERNAL
-INIT_YMM avx
-BUTTERFLIES_FLOAT_INTERLEAVE
-%endif
-
 ; %1 = aligned/unaligned
 %macro BSWAP_LOOPS  1
     mov      r3, r2
@@ -1361,6 +651,10 @@
 INIT_XMM ssse3
 BSWAP32_BUF
 
+
+; FIXME: All of the code below should be put back in h264_qpel_8bit.asm.
+; Unfortunately it is unconditionally used from dsputil_mmx.c since 71155d7 ..
+
 %macro op_avgh 3
     movh   %3, %2
     pavgb  %1, %3
@@ -1548,46 +842,3 @@
 PIXELS48 avg, 4
 PIXELS48 put, 8
 PIXELS48 avg, 8
-
-INIT_XMM sse2
-; void put_pixels16_sse2(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-cglobal put_pixels16, 4,5,4
-    movsxdifnidn r2, r2d
-    lea          r4, [r2*3]
-.loop:
-    movu         m0, [r1]
-    movu         m1, [r1+r2]
-    movu         m2, [r1+r2*2]
-    movu         m3, [r1+r4]
-    lea          r1, [r1+r2*4]
-    mova       [r0], m0
-    mova    [r0+r2], m1
-    mova  [r0+r2*2], m2
-    mova    [r0+r4], m3
-    sub         r3d, 4
-    lea          r0, [r0+r2*4]
-    jnz       .loop
-    REP_RET
-
-; void avg_pixels16_sse2(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-cglobal avg_pixels16, 4,5,4
-    movsxdifnidn r2, r2d
-    lea          r4, [r2*3]
-.loop:
-    movu         m0, [r1]
-    movu         m1, [r1+r2]
-    movu         m2, [r1+r2*2]
-    movu         m3, [r1+r4]
-    lea          r1, [r1+r2*4]
-    pavgb        m0, [r0]
-    pavgb        m1, [r0+r2]
-    pavgb        m2, [r0+r2*2]
-    pavgb        m3, [r0+r4]
-    mova       [r0], m0
-    mova    [r0+r2], m1
-    mova  [r0+r2*2], m2
-    mova    [r0+r4], m3
-    sub         r3d, 4
-    lea          r0, [r0+r2*4]
-    jnz       .loop
-    REP_RET
diff --git a/libavcodec/x86/dsputil_avg_template.c b/libavcodec/x86/dsputil_avg_template.c
index 17f8955..b9a8f83 100644
--- a/libavcodec/x86/dsputil_avg_template.c
+++ b/libavcodec/x86/dsputil_avg_template.c
@@ -24,832 +24,54 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-/* XXX: we use explicit registers to avoid a gcc 2.95.2 register asm
-   clobber bug - now it will work with 2.95.2 and also with -fPIC
- */
-static void DEF(put_pixels8_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    __asm__ volatile(
-        "lea (%3, %3), %%"REG_a"        \n\t"
-        "1:                             \n\t"
-        "movq (%1), %%mm0               \n\t"
-        "movq (%1, %3), %%mm1           \n\t"
-        PAVGB" 1(%1), %%mm0             \n\t"
-        PAVGB" 1(%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"
-        PAVGB" 1(%1), %%mm0             \n\t"
-        PAVGB" 1(%1, %3), %%mm1         \n\t"
-        "add %%"REG_a", %1              \n\t"
-        "movq %%mm0, (%2)               \n\t"
-        "movq %%mm1, (%2, %3)           \n\t"
-        "add %%"REG_a", %2              \n\t"
-        "subl $4, %0                    \n\t"
-        "jnz 1b                         \n\t"
-        :"+g"(h), "+S"(pixels), "+D"(block)
-        :"r" ((x86_reg)line_size)
-        :"%"REG_a, "memory");
-}
-
-#ifndef SKIP_FOR_3DNOW
-static void DEF(put_pixels8_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
-{
-    __asm__ volatile(
-        "testl $1, %0                   \n\t"
-            " jz 1f                     \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "movq   (%2), %%mm1             \n\t"
-        "add    %4, %1                  \n\t"
-        "add    $8, %2                  \n\t"
-        PAVGB" %%mm1, %%mm0             \n\t"
-        "movq   %%mm0, (%3)             \n\t"
-        "add    %5, %3                  \n\t"
-        "decl   %0                      \n\t"
-        "1:                             \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "add    %4, %1                  \n\t"
-        "movq   (%1), %%mm1             \n\t"
-        "add    %4, %1                  \n\t"
-        PAVGB" (%2), %%mm0              \n\t"
-        PAVGB" 8(%2), %%mm1             \n\t"
-        "movq   %%mm0, (%3)             \n\t"
-        "add    %5, %3                  \n\t"
-        "movq   %%mm1, (%3)             \n\t"
-        "add    %5, %3                  \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "add    %4, %1                  \n\t"
-        "movq   (%1), %%mm1             \n\t"
-        "add    %4, %1                  \n\t"
-        PAVGB" 16(%2), %%mm0            \n\t"
-        PAVGB" 24(%2), %%mm1            \n\t"
-        "movq   %%mm0, (%3)             \n\t"
-        "add    %5, %3                  \n\t"
-        "movq   %%mm1, (%3)             \n\t"
-        "add    %5, %3                  \n\t"
-        "add    $32, %2                 \n\t"
-        "subl   $4, %0                  \n\t"
-        "jnz    1b                      \n\t"
-#if !HAVE_EBX_AVAILABLE //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cannot be used
-        :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst)
-#else
-        :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst)
-#endif
-        :"S"((x86_reg)src1Stride), "D"((x86_reg)dstStride)
-        :"memory");
-//the following should be used, though better not with gcc ...
-/*        :"+g"(h), "+r"(src1), "+r"(src2), "+r"(dst)
-        :"r"(src1Stride), "r"(dstStride)
-        :"memory");*/
-}
-
-static void DEF(put_no_rnd_pixels8_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
-{
-    __asm__ volatile(
-        "pcmpeqb %%mm6, %%mm6           \n\t"
-        "testl $1, %0                   \n\t"
-            " jz 1f                     \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "movq   (%2), %%mm1             \n\t"
-        "add    %4, %1                  \n\t"
-        "add    $8, %2                  \n\t"
-        "pxor %%mm6, %%mm0              \n\t"
-        "pxor %%mm6, %%mm1              \n\t"
-        PAVGB" %%mm1, %%mm0             \n\t"
-        "pxor %%mm6, %%mm0              \n\t"
-        "movq   %%mm0, (%3)             \n\t"
-        "add    %5, %3                  \n\t"
-        "decl   %0                      \n\t"
-        "1:                             \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "add    %4, %1                  \n\t"
-        "movq   (%1), %%mm1             \n\t"
-        "add    %4, %1                  \n\t"
-        "movq   (%2), %%mm2             \n\t"
-        "movq   8(%2), %%mm3            \n\t"
-        "pxor %%mm6, %%mm0              \n\t"
-        "pxor %%mm6, %%mm1              \n\t"
-        "pxor %%mm6, %%mm2              \n\t"
-        "pxor %%mm6, %%mm3              \n\t"
-        PAVGB" %%mm2, %%mm0             \n\t"
-        PAVGB" %%mm3, %%mm1             \n\t"
-        "pxor %%mm6, %%mm0              \n\t"
-        "pxor %%mm6, %%mm1              \n\t"
-        "movq   %%mm0, (%3)             \n\t"
-        "add    %5, %3                  \n\t"
-        "movq   %%mm1, (%3)             \n\t"
-        "add    %5, %3                  \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "add    %4, %1                  \n\t"
-        "movq   (%1), %%mm1             \n\t"
-        "add    %4, %1                  \n\t"
-        "movq   16(%2), %%mm2           \n\t"
-        "movq   24(%2), %%mm3           \n\t"
-        "pxor %%mm6, %%mm0              \n\t"
-        "pxor %%mm6, %%mm1              \n\t"
-        "pxor %%mm6, %%mm2              \n\t"
-        "pxor %%mm6, %%mm3              \n\t"
-        PAVGB" %%mm2, %%mm0             \n\t"
-        PAVGB" %%mm3, %%mm1             \n\t"
-        "pxor %%mm6, %%mm0              \n\t"
-        "pxor %%mm6, %%mm1              \n\t"
-        "movq   %%mm0, (%3)             \n\t"
-        "add    %5, %3                  \n\t"
-        "movq   %%mm1, (%3)             \n\t"
-        "add    %5, %3                  \n\t"
-        "add    $32, %2                 \n\t"
-        "subl   $4, %0                  \n\t"
-        "jnz    1b                      \n\t"
-#if !HAVE_EBX_AVAILABLE //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cannot be used
-        :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst)
-#else
-        :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst)
-#endif
-        :"S"((x86_reg)src1Stride), "D"((x86_reg)dstStride)
-        :"memory");
-//the following should be used, though better not with gcc ...
-/*        :"+g"(h), "+r"(src1), "+r"(src2), "+r"(dst)
-        :"r"(src1Stride), "r"(dstStride)
-        :"memory");*/
-}
-
-static void DEF(avg_pixels8_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
-{
-    __asm__ volatile(
-        "testl $1, %0                   \n\t"
-            " jz 1f                     \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "movq   (%2), %%mm1             \n\t"
-        "add    %4, %1                  \n\t"
-        "add    $8, %2                  \n\t"
-        PAVGB" %%mm1, %%mm0             \n\t"
-        PAVGB" (%3), %%mm0              \n\t"
-        "movq   %%mm0, (%3)             \n\t"
-        "add    %5, %3                  \n\t"
-        "decl   %0                      \n\t"
-        "1:                             \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "add    %4, %1                  \n\t"
-        "movq   (%1), %%mm1             \n\t"
-        "add    %4, %1                  \n\t"
-        PAVGB" (%2), %%mm0              \n\t"
-        PAVGB" 8(%2), %%mm1             \n\t"
-        PAVGB" (%3), %%mm0              \n\t"
-        "movq   %%mm0, (%3)             \n\t"
-        "add    %5, %3                  \n\t"
-        PAVGB" (%3), %%mm1              \n\t"
-        "movq   %%mm1, (%3)             \n\t"
-        "add    %5, %3                  \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "add    %4, %1                  \n\t"
-        "movq   (%1), %%mm1             \n\t"
-        "add    %4, %1                  \n\t"
-        PAVGB" 16(%2), %%mm0            \n\t"
-        PAVGB" 24(%2), %%mm1            \n\t"
-        PAVGB" (%3), %%mm0              \n\t"
-        "movq   %%mm0, (%3)             \n\t"
-        "add    %5, %3                  \n\t"
-        PAVGB" (%3), %%mm1              \n\t"
-        "movq   %%mm1, (%3)             \n\t"
-        "add    %5, %3                  \n\t"
-        "add    $32, %2                 \n\t"
-        "subl   $4, %0                  \n\t"
-        "jnz    1b                      \n\t"
-#if !HAVE_EBX_AVAILABLE  //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cannot be used
-        :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst)
-#else
-        :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst)
-#endif
-        :"S"((x86_reg)src1Stride), "D"((x86_reg)dstStride)
-        :"memory");
-//the following should be used, though better not with gcc ...
-/*        :"+g"(h), "+r"(src1), "+r"(src2), "+r"(dst)
-        :"r"(src1Stride), "r"(dstStride)
-        :"memory");*/
-}
-#endif /* SKIP_FOR_3DNOW */
-
-static void DEF(put_pixels16_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    __asm__ volatile(
-        "lea (%3, %3), %%"REG_a"        \n\t"
-        "1:                             \n\t"
-        "movq (%1), %%mm0               \n\t"
-        "movq (%1, %3), %%mm1           \n\t"
-        "movq 8(%1), %%mm2              \n\t"
-        "movq 8(%1, %3), %%mm3          \n\t"
-        PAVGB" 1(%1), %%mm0             \n\t"
-        PAVGB" 1(%1, %3), %%mm1         \n\t"
-        PAVGB" 9(%1), %%mm2             \n\t"
-        PAVGB" 9(%1, %3), %%mm3         \n\t"
-        "movq %%mm0, (%2)               \n\t"
-        "movq %%mm1, (%2, %3)           \n\t"
-        "movq %%mm2, 8(%2)              \n\t"
-        "movq %%mm3, 8(%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 8(%1), %%mm2              \n\t"
-        "movq 8(%1, %3), %%mm3          \n\t"
-        PAVGB" 1(%1), %%mm0             \n\t"
-        PAVGB" 1(%1, %3), %%mm1         \n\t"
-        PAVGB" 9(%1), %%mm2             \n\t"
-        PAVGB" 9(%1, %3), %%mm3         \n\t"
-        "add %%"REG_a", %1              \n\t"
-        "movq %%mm0, (%2)               \n\t"
-        "movq %%mm1, (%2, %3)           \n\t"
-        "movq %%mm2, 8(%2)              \n\t"
-        "movq %%mm3, 8(%2, %3)          \n\t"
-        "add %%"REG_a", %2              \n\t"
-        "subl $4, %0                    \n\t"
-        "jnz 1b                         \n\t"
-        :"+g"(h), "+S"(pixels), "+D"(block)
-        :"r" ((x86_reg)line_size)
-        :"%"REG_a, "memory");
-}
-
-#ifndef SKIP_FOR_3DNOW
-static void DEF(put_pixels16_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
-{
-    __asm__ volatile(
-        "testl $1, %0                   \n\t"
-            " jz 1f                     \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "movq   8(%1), %%mm1            \n\t"
-        PAVGB" (%2), %%mm0              \n\t"
-        PAVGB" 8(%2), %%mm1             \n\t"
-        "add    %4, %1                  \n\t"
-        "add    $16, %2                 \n\t"
-        "movq   %%mm0, (%3)             \n\t"
-        "movq   %%mm1, 8(%3)            \n\t"
-        "add    %5, %3                  \n\t"
-        "decl   %0                      \n\t"
-        "1:                             \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "movq   8(%1), %%mm1            \n\t"
-        "add    %4, %1                  \n\t"
-        PAVGB" (%2), %%mm0              \n\t"
-        PAVGB" 8(%2), %%mm1             \n\t"
-        "movq   %%mm0, (%3)             \n\t"
-        "movq   %%mm1, 8(%3)            \n\t"
-        "add    %5, %3                  \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "movq   8(%1), %%mm1            \n\t"
-        "add    %4, %1                  \n\t"
-        PAVGB" 16(%2), %%mm0            \n\t"
-        PAVGB" 24(%2), %%mm1            \n\t"
-        "movq   %%mm0, (%3)             \n\t"
-        "movq   %%mm1, 8(%3)            \n\t"
-        "add    %5, %3                  \n\t"
-        "add    $32, %2                 \n\t"
-        "subl   $2, %0                  \n\t"
-        "jnz    1b                      \n\t"
-#if !HAVE_EBX_AVAILABLE  //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cannot be used
-        :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst)
-#else
-        :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst)
-#endif
-        :"S"((x86_reg)src1Stride), "D"((x86_reg)dstStride)
-        :"memory");
-//the following should be used, though better not with gcc ...
-/*        :"+g"(h), "+r"(src1), "+r"(src2), "+r"(dst)
-        :"r"(src1Stride), "r"(dstStride)
-        :"memory");*/
-}
-
-static void DEF(avg_pixels16_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
-{
-    __asm__ volatile(
-        "testl $1, %0                   \n\t"
-            " jz 1f                     \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "movq   8(%1), %%mm1            \n\t"
-        PAVGB" (%2), %%mm0              \n\t"
-        PAVGB" 8(%2), %%mm1             \n\t"
-        "add    %4, %1                  \n\t"
-        "add    $16, %2                 \n\t"
-        PAVGB" (%3), %%mm0              \n\t"
-        PAVGB" 8(%3), %%mm1             \n\t"
-        "movq   %%mm0, (%3)             \n\t"
-        "movq   %%mm1, 8(%3)            \n\t"
-        "add    %5, %3                  \n\t"
-        "decl   %0                      \n\t"
-        "1:                             \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "movq   8(%1), %%mm1            \n\t"
-        "add    %4, %1                  \n\t"
-        PAVGB" (%2), %%mm0              \n\t"
-        PAVGB" 8(%2), %%mm1             \n\t"
-        PAVGB" (%3), %%mm0              \n\t"
-        PAVGB" 8(%3), %%mm1             \n\t"
-        "movq   %%mm0, (%3)             \n\t"
-        "movq   %%mm1, 8(%3)            \n\t"
-        "add    %5, %3                  \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "movq   8(%1), %%mm1            \n\t"
-        "add    %4, %1                  \n\t"
-        PAVGB" 16(%2), %%mm0            \n\t"
-        PAVGB" 24(%2), %%mm1            \n\t"
-        PAVGB" (%3), %%mm0              \n\t"
-        PAVGB" 8(%3), %%mm1             \n\t"
-        "movq   %%mm0, (%3)             \n\t"
-        "movq   %%mm1, 8(%3)            \n\t"
-        "add    %5, %3                  \n\t"
-        "add    $32, %2                 \n\t"
-        "subl   $2, %0                  \n\t"
-        "jnz    1b                      \n\t"
-#if !HAVE_EBX_AVAILABLE  //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cannot be used
-        :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst)
-#else
-        :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst)
-#endif
-        :"S"((x86_reg)src1Stride), "D"((x86_reg)dstStride)
-        :"memory");
-//the following should be used, though better not with gcc ...
-/*        :"+g"(h), "+r"(src1), "+r"(src2), "+r"(dst)
-        :"r"(src1Stride), "r"(dstStride)
-        :"memory");*/
-}
-
-static void DEF(put_no_rnd_pixels16_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
-{
-    __asm__ volatile(
-        "pcmpeqb %%mm6, %%mm6           \n\t"
-        "testl $1, %0                   \n\t"
-            " jz 1f                     \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "movq   8(%1), %%mm1            \n\t"
-        "movq   (%2), %%mm2             \n\t"
-        "movq   8(%2), %%mm3            \n\t"
-        "pxor %%mm6, %%mm0              \n\t"
-        "pxor %%mm6, %%mm1              \n\t"
-        "pxor %%mm6, %%mm2              \n\t"
-        "pxor %%mm6, %%mm3              \n\t"
-        PAVGB" %%mm2, %%mm0             \n\t"
-        PAVGB" %%mm3, %%mm1             \n\t"
-        "pxor %%mm6, %%mm0              \n\t"
-        "pxor %%mm6, %%mm1              \n\t"
-        "add    %4, %1                  \n\t"
-        "add    $16, %2                 \n\t"
-        "movq   %%mm0, (%3)             \n\t"
-        "movq   %%mm1, 8(%3)            \n\t"
-        "add    %5, %3                  \n\t"
-        "decl   %0                      \n\t"
-        "1:                             \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "movq   8(%1), %%mm1            \n\t"
-        "add    %4, %1                  \n\t"
-        "movq   (%2), %%mm2             \n\t"
-        "movq   8(%2), %%mm3            \n\t"
-        "pxor %%mm6, %%mm0              \n\t"
-        "pxor %%mm6, %%mm1              \n\t"
-        "pxor %%mm6, %%mm2              \n\t"
-        "pxor %%mm6, %%mm3              \n\t"
-        PAVGB" %%mm2, %%mm0             \n\t"
-        PAVGB" %%mm3, %%mm1             \n\t"
-        "pxor %%mm6, %%mm0              \n\t"
-        "pxor %%mm6, %%mm1              \n\t"
-        "movq   %%mm0, (%3)             \n\t"
-        "movq   %%mm1, 8(%3)            \n\t"
-        "add    %5, %3                  \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "movq   8(%1), %%mm1            \n\t"
-        "add    %4, %1                  \n\t"
-        "movq   16(%2), %%mm2           \n\t"
-        "movq   24(%2), %%mm3           \n\t"
-        "pxor %%mm6, %%mm0              \n\t"
-        "pxor %%mm6, %%mm1              \n\t"
-        "pxor %%mm6, %%mm2              \n\t"
-        "pxor %%mm6, %%mm3              \n\t"
-        PAVGB" %%mm2, %%mm0             \n\t"
-        PAVGB" %%mm3, %%mm1             \n\t"
-        "pxor %%mm6, %%mm0              \n\t"
-        "pxor %%mm6, %%mm1              \n\t"
-        "movq   %%mm0, (%3)             \n\t"
-        "movq   %%mm1, 8(%3)            \n\t"
-        "add    %5, %3                  \n\t"
-        "add    $32, %2                 \n\t"
-        "subl   $2, %0                  \n\t"
-        "jnz    1b                      \n\t"
-#if !HAVE_EBX_AVAILABLE //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cannot be used
-        :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst)
-#else
-        :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst)
-#endif
-        :"S"((x86_reg)src1Stride), "D"((x86_reg)dstStride)
-        :"memory");
-//the following should be used, though better not with gcc ...
-/*        :"+g"(h), "+r"(src1), "+r"(src2), "+r"(dst)
-        :"r"(src1Stride), "r"(dstStride)
-        :"memory");*/
-}
-#endif /* SKIP_FOR_3DNOW */
-
-/* GL: this function does incorrect rounding if overflow */
-static void DEF(put_no_rnd_pixels8_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    MOVQ_BONE(mm6);
-    __asm__ volatile(
-        "lea (%3, %3), %%"REG_a"        \n\t"
-        "1:                             \n\t"
-        "movq (%1), %%mm0               \n\t"
-        "movq (%1, %3), %%mm2           \n\t"
-        "movq 1(%1), %%mm1              \n\t"
-        "movq 1(%1, %3), %%mm3          \n\t"
-        "add %%"REG_a", %1              \n\t"
-        "psubusb %%mm6, %%mm0           \n\t"
-        "psubusb %%mm6, %%mm2           \n\t"
-        PAVGB" %%mm1, %%mm0             \n\t"
-        PAVGB" %%mm3, %%mm2             \n\t"
-        "movq %%mm0, (%2)               \n\t"
-        "movq %%mm2, (%2, %3)           \n\t"
-        "movq (%1), %%mm0               \n\t"
-        "movq 1(%1), %%mm1              \n\t"
-        "movq (%1, %3), %%mm2           \n\t"
-        "movq 1(%1, %3), %%mm3          \n\t"
-        "add %%"REG_a", %2              \n\t"
-        "add %%"REG_a", %1              \n\t"
-        "psubusb %%mm6, %%mm0           \n\t"
-        "psubusb %%mm6, %%mm2           \n\t"
-        PAVGB" %%mm1, %%mm0             \n\t"
-        PAVGB" %%mm3, %%mm2             \n\t"
-        "movq %%mm0, (%2)               \n\t"
-        "movq %%mm2, (%2, %3)           \n\t"
-        "add %%"REG_a", %2              \n\t"
-        "subl $4, %0                    \n\t"
-        "jnz 1b                         \n\t"
-        :"+g"(h), "+S"(pixels), "+D"(block)
-        :"r" ((x86_reg)line_size)
-        :"%"REG_a, "memory");
-}
-
-static void DEF(put_no_rnd_pixels8_x2_exact)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    __asm__ volatile (
-        "pcmpeqb %%mm6, %%mm6           \n\t"
-        "1:                             \n\t"
-        "movq  (%1),     %%mm0          \n\t"
-        "movq  (%1, %3), %%mm2          \n\t"
-        "movq 1(%1),     %%mm1          \n\t"
-        "movq 1(%1, %3), %%mm3          \n\t"
-        "pxor  %%mm6, %%mm0             \n\t"
-        "pxor  %%mm6, %%mm2             \n\t"
-        "pxor  %%mm6, %%mm1             \n\t"
-        "pxor  %%mm6, %%mm3             \n\t"
-        PAVGB" %%mm1, %%mm0             \n\t"
-        PAVGB" %%mm3, %%mm2             \n\t"
-        "pxor  %%mm6, %%mm0             \n\t"
-        "pxor  %%mm6, %%mm2             \n\t"
-        "movq  %%mm0, (%2)              \n\t"
-        "movq  %%mm2, (%2, %3)          \n\t"
-        "movq  (%1, %3,2), %%mm0        \n\t"
-        "movq 1(%1, %3,2), %%mm1        \n\t"
-        "movq  (%1, %4),   %%mm2        \n\t"
-        "movq 1(%1, %4),   %%mm3        \n\t"
-        "pxor  %%mm6, %%mm0             \n\t"
-        "pxor  %%mm6, %%mm1             \n\t"
-        "pxor  %%mm6, %%mm2             \n\t"
-        "pxor  %%mm6, %%mm3             \n\t"
-        PAVGB" %%mm1, %%mm0             \n\t"
-        PAVGB" %%mm3, %%mm2             \n\t"
-        "pxor  %%mm6, %%mm0             \n\t"
-        "pxor  %%mm6, %%mm2             \n\t"
-        "movq  %%mm0, (%2, %3,2)        \n\t"
-        "movq  %%mm2, (%2, %4)          \n\t"
-        "lea   (%1, %3,4), %1           \n\t"
-        "lea   (%2, %3,4), %2           \n\t"
-        "subl  $4, %0                   \n\t"
-        "jg 1b                          \n\t"
-        : "+g"(h), "+r"(pixels), "+r"(block)
-        : "r" ((x86_reg)line_size), "r"((x86_reg)3*line_size)
-        : "memory"
-    );
-}
-
-static void DEF(put_pixels8_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    __asm__ volatile(
-        "lea (%3, %3), %%"REG_a"        \n\t"
-        "movq (%1), %%mm0               \n\t"
-        "sub %3, %2                     \n\t"
-        "1:                             \n\t"
-        "movq (%1, %3), %%mm1           \n\t"
-        "movq (%1, %%"REG_a"), %%mm2    \n\t"
-        "add %%"REG_a", %1              \n\t"
-        PAVGB" %%mm1, %%mm0             \n\t"
-        PAVGB" %%mm2, %%mm1             \n\t"
-        "movq %%mm0, (%2, %3)           \n\t"
-        "movq %%mm1, (%2, %%"REG_a")    \n\t"
-        "movq (%1, %3), %%mm1           \n\t"
-        "movq (%1, %%"REG_a"), %%mm0    \n\t"
-        "add %%"REG_a", %2              \n\t"
-        "add %%"REG_a", %1              \n\t"
-        PAVGB" %%mm1, %%mm2             \n\t"
-        PAVGB" %%mm0, %%mm1             \n\t"
-        "movq %%mm2, (%2, %3)           \n\t"
-        "movq %%mm1, (%2, %%"REG_a")    \n\t"
-        "add %%"REG_a", %2              \n\t"
-        "subl $4, %0                    \n\t"
-        "jnz 1b                         \n\t"
-        :"+g"(h), "+S"(pixels), "+D" (block)
-        :"r" ((x86_reg)line_size)
-        :"%"REG_a, "memory");
-}
-
-/* GL: this function does incorrect rounding if overflow */
-static void DEF(put_no_rnd_pixels8_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    MOVQ_BONE(mm6);
-    __asm__ volatile(
-        "lea (%3, %3), %%"REG_a"        \n\t"
-        "movq (%1), %%mm0               \n\t"
-        "sub %3, %2                     \n\t"
-        "1:                             \n\t"
-        "movq (%1, %3), %%mm1           \n\t"
-        "movq (%1, %%"REG_a"), %%mm2    \n\t"
-        "add %%"REG_a", %1              \n\t"
-        "psubusb %%mm6, %%mm1           \n\t"
-        PAVGB" %%mm1, %%mm0             \n\t"
-        PAVGB" %%mm2, %%mm1             \n\t"
-        "movq %%mm0, (%2, %3)           \n\t"
-        "movq %%mm1, (%2, %%"REG_a")    \n\t"
-        "movq (%1, %3), %%mm1           \n\t"
-        "movq (%1, %%"REG_a"), %%mm0    \n\t"
-        "add %%"REG_a", %2              \n\t"
-        "add %%"REG_a", %1              \n\t"
-        "psubusb %%mm6, %%mm1           \n\t"
-        PAVGB" %%mm1, %%mm2             \n\t"
-        PAVGB" %%mm0, %%mm1             \n\t"
-        "movq %%mm2, (%2, %3)           \n\t"
-        "movq %%mm1, (%2, %%"REG_a")    \n\t"
-        "add %%"REG_a", %2              \n\t"
-        "subl $4, %0                    \n\t"
-        "jnz 1b                         \n\t"
-        :"+g"(h), "+S"(pixels), "+D" (block)
-        :"r" ((x86_reg)line_size)
-        :"%"REG_a, "memory");
-}
-
-static void DEF(put_no_rnd_pixels8_y2_exact)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    __asm__ volatile (
-        "movq     (%1), %%mm0           \n\t"
-        "pcmpeqb %%mm6, %%mm6           \n\t"
-        "add        %3, %1              \n\t"
-        "pxor    %%mm6, %%mm0           \n\t"
-        "1:                             \n\t"
-        "movq  (%1),     %%mm1          \n\t"
-        "movq  (%1, %3), %%mm2          \n\t"
-        "pxor  %%mm6, %%mm1             \n\t"
-        "pxor  %%mm6, %%mm2             \n\t"
-        PAVGB" %%mm1, %%mm0             \n\t"
-        PAVGB" %%mm2, %%mm1             \n\t"
-        "pxor  %%mm6, %%mm0             \n\t"
-        "pxor  %%mm6, %%mm1             \n\t"
-        "movq  %%mm0, (%2)              \n\t"
-        "movq  %%mm1, (%2, %3)          \n\t"
-        "movq  (%1, %3,2), %%mm1        \n\t"
-        "movq  (%1, %4),   %%mm0        \n\t"
-        "pxor  %%mm6, %%mm1             \n\t"
-        "pxor  %%mm6, %%mm0             \n\t"
-        PAVGB" %%mm1, %%mm2             \n\t"
-        PAVGB" %%mm0, %%mm1             \n\t"
-        "pxor  %%mm6, %%mm2             \n\t"
-        "pxor  %%mm6, %%mm1             \n\t"
-        "movq %%mm2, (%2, %3,2)         \n\t"
-        "movq %%mm1, (%2, %4)           \n\t"
-        "lea   (%1, %3,4), %1           \n\t"
-        "lea   (%2, %3,4), %2           \n\t"
-        "subl $4, %0                    \n\t"
-        "jg 1b                          \n\t"
-        :"+g"(h), "+r"(pixels), "+r" (block)
-        :"r" ((x86_reg)line_size), "r"((x86_reg)3*line_size)
-        :"memory"
-    );
-}
-
-static void DEF(avg_pixels8)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    __asm__ volatile(
-        "lea (%3, %3), %%"REG_a"        \n\t"
-        "1:                             \n\t"
-        "movq (%2), %%mm0               \n\t"
-        "movq (%2, %3), %%mm1           \n\t"
-        PAVGB" (%1), %%mm0              \n\t"
-        PAVGB" (%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 (%2), %%mm0               \n\t"
-        "movq (%2, %3), %%mm1           \n\t"
-        PAVGB" (%1), %%mm0              \n\t"
-        PAVGB" (%1, %3), %%mm1          \n\t"
-        "add %%"REG_a", %1              \n\t"
-        "movq %%mm0, (%2)               \n\t"
-        "movq %%mm1, (%2, %3)           \n\t"
-        "add %%"REG_a", %2              \n\t"
-        "subl $4, %0                    \n\t"
-        "jnz 1b                         \n\t"
-        :"+g"(h), "+S"(pixels), "+D"(block)
-        :"r" ((x86_reg)line_size)
-        :"%"REG_a, "memory");
-}
-
-static void DEF(avg_pixels8_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    __asm__ volatile(
-        "lea (%3, %3), %%"REG_a"        \n\t"
-        "1:                             \n\t"
-        "movq (%1), %%mm0               \n\t"
-        "movq (%1, %3), %%mm2           \n\t"
-        PAVGB" 1(%1), %%mm0             \n\t"
-        PAVGB" 1(%1, %3), %%mm2         \n\t"
-        PAVGB" (%2), %%mm0              \n\t"
-        PAVGB" (%2, %3), %%mm2          \n\t"
-        "add %%"REG_a", %1              \n\t"
-        "movq %%mm0, (%2)               \n\t"
-        "movq %%mm2, (%2, %3)           \n\t"
-        "movq (%1), %%mm0               \n\t"
-        "movq (%1, %3), %%mm2           \n\t"
-        PAVGB" 1(%1), %%mm0             \n\t"
-        PAVGB" 1(%1, %3), %%mm2         \n\t"
-        "add %%"REG_a", %2              \n\t"
-        "add %%"REG_a", %1              \n\t"
-        PAVGB" (%2), %%mm0              \n\t"
-        PAVGB" (%2, %3), %%mm2          \n\t"
-        "movq %%mm0, (%2)               \n\t"
-        "movq %%mm2, (%2, %3)           \n\t"
-        "add %%"REG_a", %2              \n\t"
-        "subl $4, %0                    \n\t"
-        "jnz 1b                         \n\t"
-        :"+g"(h), "+S"(pixels), "+D"(block)
-        :"r" ((x86_reg)line_size)
-        :"%"REG_a, "memory");
-}
-
-static void DEF(avg_pixels8_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    __asm__ volatile(
-        "lea (%3, %3), %%"REG_a"        \n\t"
-        "movq (%1), %%mm0               \n\t"
-        "sub %3, %2                     \n\t"
-        "1:                             \n\t"
-        "movq (%1, %3), %%mm1           \n\t"
-        "movq (%1, %%"REG_a"), %%mm2    \n\t"
-        "add %%"REG_a", %1              \n\t"
-        PAVGB" %%mm1, %%mm0             \n\t"
-        PAVGB" %%mm2, %%mm1             \n\t"
-        "movq (%2, %3), %%mm3           \n\t"
-        "movq (%2, %%"REG_a"), %%mm4    \n\t"
-        PAVGB" %%mm3, %%mm0             \n\t"
-        PAVGB" %%mm4, %%mm1             \n\t"
-        "movq %%mm0, (%2, %3)           \n\t"
-        "movq %%mm1, (%2, %%"REG_a")    \n\t"
-        "movq (%1, %3), %%mm1           \n\t"
-        "movq (%1, %%"REG_a"), %%mm0    \n\t"
-        PAVGB" %%mm1, %%mm2             \n\t"
-        PAVGB" %%mm0, %%mm1             \n\t"
-        "add %%"REG_a", %2              \n\t"
-        "add %%"REG_a", %1              \n\t"
-        "movq (%2, %3), %%mm3           \n\t"
-        "movq (%2, %%"REG_a"), %%mm4    \n\t"
-        PAVGB" %%mm3, %%mm2             \n\t"
-        PAVGB" %%mm4, %%mm1             \n\t"
-        "movq %%mm2, (%2, %3)           \n\t"
-        "movq %%mm1, (%2, %%"REG_a")    \n\t"
-        "add %%"REG_a", %2              \n\t"
-        "subl $4, %0                    \n\t"
-        "jnz 1b                         \n\t"
-        :"+g"(h), "+S"(pixels), "+D"(block)
-        :"r" ((x86_reg)line_size)
-        :"%"REG_a, "memory");
-}
-
-/* Note this is not correctly rounded, but this function is only
- * used for B-frames so it does not matter. */
-static void DEF(avg_pixels8_xy2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    MOVQ_BONE(mm6);
-    __asm__ volatile(
-        "lea (%3, %3), %%"REG_a"        \n\t"
-        "movq (%1), %%mm0               \n\t"
-        PAVGB" 1(%1), %%mm0             \n\t"
-         ".p2align 3                    \n\t"
-        "1:                             \n\t"
-        "movq (%1, %%"REG_a"), %%mm2    \n\t"
-        "movq (%1, %3), %%mm1           \n\t"
-        "psubusb %%mm6, %%mm2           \n\t"
-        PAVGB" 1(%1, %3), %%mm1         \n\t"
-        PAVGB" 1(%1, %%"REG_a"), %%mm2  \n\t"
-        "add %%"REG_a", %1              \n\t"
-        PAVGB" %%mm1, %%mm0             \n\t"
-        PAVGB" %%mm2, %%mm1             \n\t"
-        PAVGB" (%2), %%mm0              \n\t"
-        PAVGB" (%2, %3), %%mm1          \n\t"
-        "movq %%mm0, (%2)               \n\t"
-        "movq %%mm1, (%2, %3)           \n\t"
-        "movq (%1, %3), %%mm1           \n\t"
-        "movq (%1, %%"REG_a"), %%mm0    \n\t"
-        PAVGB" 1(%1, %3), %%mm1         \n\t"
-        PAVGB" 1(%1, %%"REG_a"), %%mm0  \n\t"
-        "add %%"REG_a", %2              \n\t"
-        "add %%"REG_a", %1              \n\t"
-        PAVGB" %%mm1, %%mm2             \n\t"
-        PAVGB" %%mm0, %%mm1             \n\t"
-        PAVGB" (%2), %%mm2              \n\t"
-        PAVGB" (%2, %3), %%mm1          \n\t"
-        "movq %%mm2, (%2)               \n\t"
-        "movq %%mm1, (%2, %3)           \n\t"
-        "add %%"REG_a", %2              \n\t"
-        "subl $4, %0                    \n\t"
-        "jnz 1b                         \n\t"
-        :"+g"(h), "+S"(pixels), "+D"(block)
-        :"r" ((x86_reg)line_size)
-        :"%"REG_a,  "memory");
-}
-
 //FIXME the following could be optimized too ...
-static void DEF(put_no_rnd_pixels16_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){
-    DEF(put_no_rnd_pixels8_x2)(block  , pixels  , line_size, h);
-    DEF(put_no_rnd_pixels8_x2)(block+8, pixels+8, line_size, h);
-}
-static void DEF(put_pixels16_y2)(uint8_t *block, const uint8_t *pixels, int 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(put_no_rnd_pixels16_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){
-    DEF(put_no_rnd_pixels8_y2)(block  , pixels  , line_size, h);
-    DEF(put_no_rnd_pixels8_y2)(block+8, pixels+8, line_size, h);
-}
-static void DEF(avg_pixels16)(uint8_t *block, const uint8_t *pixels, int line_size, int h){
-    DEF(avg_pixels8)(block  , pixels  , line_size, h);
-    DEF(avg_pixels8)(block+8, pixels+8, line_size, h);
-}
-static void DEF(avg_pixels16_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){
-    DEF(avg_pixels8_x2)(block  , pixels  , line_size, h);
-    DEF(avg_pixels8_x2)(block+8, pixels+8, line_size, h);
-}
-static void DEF(avg_pixels16_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){
-    DEF(avg_pixels8_y2)(block  , pixels  , line_size, h);
-    DEF(avg_pixels8_y2)(block+8, pixels+8, line_size, h);
-}
-static void DEF(avg_pixels16_xy2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){
-    DEF(avg_pixels8_xy2)(block  , pixels  , line_size, h);
-    DEF(avg_pixels8_xy2)(block+8, pixels+8, line_size, h);
+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);
 }
 
-#define QPEL_2TAP_L3(OPNAME) \
-static void DEF(OPNAME ## 2tap_qpel16_l3)(uint8_t *dst, uint8_t *src, int stride, int h, int off1, int off2){\
-    __asm__ volatile(\
-        "1:                    \n\t"\
-        "movq   (%1,%2), %%mm0 \n\t"\
-        "movq  8(%1,%2), %%mm1 \n\t"\
-        PAVGB"  (%1,%3), %%mm0 \n\t"\
-        PAVGB" 8(%1,%3), %%mm1 \n\t"\
-        PAVGB"  (%1),    %%mm0 \n\t"\
-        PAVGB" 8(%1),    %%mm1 \n\t"\
-        STORE_OP( (%1,%4),%%mm0)\
-        STORE_OP(8(%1,%4),%%mm1)\
-        "movq  %%mm0,  (%1,%4) \n\t"\
-        "movq  %%mm1, 8(%1,%4) \n\t"\
-        "add   %5, %1          \n\t"\
-        "decl  %0              \n\t"\
-        "jnz   1b              \n\t"\
-        :"+g"(h), "+r"(src)\
-        :"r"((x86_reg)off1), "r"((x86_reg)off2),\
-         "r"((x86_reg)(dst-src)), "r"((x86_reg)stride)\
-        :"memory"\
-    );\
-}\
-static void DEF(OPNAME ## 2tap_qpel8_l3)(uint8_t *dst, uint8_t *src, int stride, int h, int off1, int off2){\
-    __asm__ volatile(\
-        "1:                    \n\t"\
-        "movq   (%1,%2), %%mm0 \n\t"\
-        PAVGB"  (%1,%3), %%mm0 \n\t"\
-        PAVGB"  (%1),    %%mm0 \n\t"\
-        STORE_OP((%1,%4),%%mm0)\
-        "movq  %%mm0,  (%1,%4) \n\t"\
-        "add   %5, %1          \n\t"\
-        "decl  %0              \n\t"\
-        "jnz   1b              \n\t"\
-        :"+g"(h), "+r"(src)\
-        :"r"((x86_reg)off1), "r"((x86_reg)off2),\
-         "r"((x86_reg)(dst-src)), "r"((x86_reg)stride)\
-        :"memory"\
-    );\
+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);
 }
 
-#ifndef SKIP_FOR_3DNOW
-#define STORE_OP(a,b) PAVGB" "#a","#b" \n\t"
-QPEL_2TAP_L3(avg_)
-#undef STORE_OP
-#define STORE_OP(a,b)
-QPEL_2TAP_L3(put_)
-#undef STORE_OP
-#undef QPEL_2TAP_L3
-#endif /* SKIP_FOR_3DNOW */
+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/dsputil_mmx.c b/libavcodec/x86/dsputil_mmx.c
index 3fb9d21..15e46c7 100644
--- a/libavcodec/x86/dsputil_mmx.c
+++ b/libavcodec/x86/dsputil_mmx.c
@@ -22,12 +22,14 @@
  * MMX optimization by Nick Kurshev <nickols_k@mail.ru>
  */
 
+#include "libavutil/attributes.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 "diracdsp_mmx.h"
@@ -39,9 +41,6 @@
 DECLARE_ALIGNED(8,  const uint64_t, ff_bone) = 0x0101010101010101ULL;
 DECLARE_ALIGNED(8,  const uint64_t, ff_wtwo) = 0x0002000200020002ULL;
 
-DECLARE_ALIGNED(16, const uint64_t, ff_pdw_80000000)[2] =
-    { 0x8000000080000000ULL, 0x8000000080000000ULL };
-
 DECLARE_ALIGNED(16, const xmm_reg,  ff_pw_1)    = { 0x0001000100010001ULL, 0x0001000100010001ULL };
 DECLARE_ALIGNED(16, const xmm_reg,  ff_pw_2)    = { 0x0002000200020002ULL, 0x0002000200020002ULL };
 DECLARE_ALIGNED(16, const xmm_reg,  ff_pw_3)    = { 0x0003000300030003ULL, 0x0003000300030003ULL };
@@ -84,6 +83,107 @@
 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_x2_mmxext(uint8_t *block, const uint8_t *pixels,
+                              ptrdiff_t line_size, int h);
+void ff_put_pixels8_x2_3dnow(uint8_t *block, const uint8_t *pixels,
+                             ptrdiff_t line_size, int 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_x2_mmxext(uint8_t *block, const uint8_t *pixels,
+                               ptrdiff_t line_size, int h);
+void ff_put_pixels16_x2_3dnow(uint8_t *block, const uint8_t *pixels,
+                              ptrdiff_t line_size, 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_no_rnd_pixels8_x2_mmxext(uint8_t *block, const uint8_t *pixels,
+                                     ptrdiff_t line_size, int h);
+void ff_put_no_rnd_pixels8_x2_3dnow(uint8_t *block, const uint8_t *pixels,
+                                    ptrdiff_t line_size, int h);
+void ff_put_no_rnd_pixels8_x2_exact_mmxext(uint8_t *block,
+                                           const uint8_t *pixels,
+                                           ptrdiff_t line_size, int h);
+void ff_put_no_rnd_pixels8_x2_exact_3dnow(uint8_t *block,
+                                          const uint8_t *pixels,
+                                          ptrdiff_t line_size, int h);
+void ff_put_pixels8_y2_mmxext(uint8_t *block, const uint8_t *pixels,
+                              ptrdiff_t line_size, int h);
+void ff_put_pixels8_y2_3dnow(uint8_t *block, const uint8_t *pixels,
+                             ptrdiff_t line_size, int h);
+void ff_put_no_rnd_pixels8_y2_mmxext(uint8_t *block, const uint8_t *pixels,
+                                     ptrdiff_t line_size, int h);
+void ff_put_no_rnd_pixels8_y2_3dnow(uint8_t *block, const uint8_t *pixels,
+                                    ptrdiff_t line_size, int h);
+void ff_put_no_rnd_pixels8_y2_exact_mmxext(uint8_t *block,
+                                           const uint8_t *pixels,
+                                           ptrdiff_t line_size, int h);
+void ff_put_no_rnd_pixels8_y2_exact_3dnow(uint8_t *block,
+                                          const uint8_t *pixels,
+                                          ptrdiff_t line_size, int h);
+void ff_avg_pixels8_3dnow(uint8_t *block, const uint8_t *pixels,
+                          ptrdiff_t line_size, int h);
+void ff_avg_pixels8_x2_mmxext(uint8_t *block, const uint8_t *pixels,
+                              ptrdiff_t line_size, int h);
+void ff_avg_pixels8_x2_3dnow(uint8_t *block, const uint8_t *pixels,
+                             ptrdiff_t line_size, int h);
+void ff_avg_pixels8_y2_mmxext(uint8_t *block, const uint8_t *pixels,
+                              ptrdiff_t line_size, int h);
+void ff_avg_pixels8_y2_3dnow(uint8_t *block, const uint8_t *pixels,
+                             ptrdiff_t line_size, int h);
+void ff_avg_pixels8_xy2_mmxext(uint8_t *block, const uint8_t *pixels,
+                               ptrdiff_t line_size, int h);
+void ff_avg_pixels8_xy2_3dnow(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, 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);
+}
+
+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
 
 #define JUMPALIGN()     __asm__ volatile (".p2align 3"::)
@@ -164,6 +264,7 @@
 
 /***********************************/
 /* 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)
@@ -176,6 +277,7 @@
 #undef SET_RND
 #undef PAVGBP
 #undef PAVGB
+#undef NO_RND
 /***********************************/
 /* MMX rounding */
 
@@ -192,51 +294,43 @@
 #undef PAVGB
 #undef OP_AVG
 
+#endif /* HAVE_INLINE_ASM */
+
+
+#if HAVE_YASM
+
 /***********************************/
 /* 3Dnow specific */
 
 #define DEF(x) x ## _3dnow
-#define PAVGB "pavgusb"
-#define OP_AVG PAVGB
-#define SKIP_FOR_3DNOW
 
 #include "dsputil_avg_template.c"
 
 #undef DEF
-#undef PAVGB
-#undef OP_AVG
-#undef SKIP_FOR_3DNOW
 
 /***********************************/
 /* MMXEXT specific */
 
 #define DEF(x) x ## _mmxext
 
-/* Introduced only in MMXEXT set */
-#define PAVGB "pavgb"
-#define OP_AVG PAVGB
-
 #include "dsputil_avg_template.c"
 
 #undef DEF
-#undef PAVGB
-#undef OP_AVG
 
+#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
 
 /***********************************/
 /* standard MMX */
 
-void ff_put_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels,
+void ff_put_pixels_clamped_mmx(const int16_t *block, uint8_t *pixels,
                                int line_size)
 {
-    const DCTELEM *p;
+    const int16_t *p;
     uint8_t *pix;
 
     /* read the pixels */
@@ -308,7 +402,7 @@
     "movq               %%mm3, (%0, %3, 2)  \n\t"           \
     "movq               %%mm4, (%0, %1)     \n\t"
 
-void ff_put_signed_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels,
+void ff_put_signed_pixels_clamped_mmx(const int16_t *block, uint8_t *pixels,
                                       int line_size)
 {
     x86_reg line_skip = line_size;
@@ -325,10 +419,10 @@
         : "memory");
 }
 
-void ff_add_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels,
+void ff_add_pixels_clamped_mmx(const int16_t *block, uint8_t *pixels,
                                int line_size)
 {
-    const DCTELEM *p;
+    const int16_t *p;
     uint8_t *pix;
     int i;
 
@@ -368,7 +462,7 @@
 }
 
 static void put_pixels8_mmx(uint8_t *block, const uint8_t *pixels,
-                            int line_size, int h)
+                            ptrdiff_t line_size, int h)
 {
     __asm__ volatile (
         "lea   (%3, %3), %%"REG_a"      \n\t"
@@ -395,7 +489,7 @@
 }
 
 static void put_pixels16_mmx(uint8_t *block, const uint8_t *pixels,
-                             int line_size, int h)
+                             ptrdiff_t line_size, int h)
 {
     __asm__ volatile (
         "lea   (%3, %3), %%"REG_a"      \n\t"
@@ -430,7 +524,7 @@
 }
 
 #define CLEAR_BLOCKS(name, n)                           \
-static void name(DCTELEM *blocks)                       \
+static void name(int16_t *blocks)                       \
 {                                                       \
     __asm__ volatile (                                  \
         "pxor %%mm7, %%mm7              \n\t"           \
@@ -450,7 +544,7 @@
 CLEAR_BLOCKS(clear_blocks_mmx, 6)
 CLEAR_BLOCKS(clear_block_mmx, 1)
 
-static void clear_block_sse(DCTELEM *block)
+static void clear_block_sse(int16_t *block)
 {
     __asm__ volatile (
         "xorps  %%xmm0, %%xmm0          \n"
@@ -467,7 +561,7 @@
     );
 }
 
-static void clear_blocks_sse(DCTELEM *blocks)
+static void clear_blocks_sse(int16_t *blocks)
 {
     __asm__ volatile (
         "xorps  %%xmm0, %%xmm0              \n"
@@ -551,181 +645,12 @@
     *left_top = tl;
 }
 #endif
+#endif /* HAVE_INLINE_ASM */
 
-static inline void transpose4x4(uint8_t *dst, uint8_t *src, x86_reg dst_stride, x86_reg src_stride){
-    __asm__ volatile( //FIXME could save 1 instruction if done as 8x4 ...
-        "movd  (%1), %%mm0              \n\t"
-        "add   %3, %1                   \n\t"
-        "movd  (%1), %%mm1              \n\t"
-        "movd  (%1,%3,1), %%mm2         \n\t"
-        "movd  (%1,%3,2), %%mm3         \n\t"
-        "punpcklbw %%mm1, %%mm0         \n\t"
-        "punpcklbw %%mm3, %%mm2         \n\t"
-        "movq %%mm0, %%mm1              \n\t"
-        "punpcklwd %%mm2, %%mm0         \n\t"
-        "punpckhwd %%mm2, %%mm1         \n\t"
-        "movd  %%mm0, (%0)              \n\t"
-        "add   %2, %0                   \n\t"
-        "punpckhdq %%mm0, %%mm0         \n\t"
-        "movd  %%mm0, (%0)              \n\t"
-        "movd  %%mm1, (%0,%2,1)         \n\t"
-        "punpckhdq %%mm1, %%mm1         \n\t"
-        "movd  %%mm1, (%0,%2,2)         \n\t"
+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);
 
-        :  "+&r" (dst),
-           "+&r" (src)
-        :  "r" (dst_stride),
-           "r" (src_stride)
-        :  "memory"
-    );
-}
-
-#define H263_LOOP_FILTER                        \
-    "pxor      %%mm7, %%mm7             \n\t"   \
-    "movq         %0, %%mm0             \n\t"   \
-    "movq         %0, %%mm1             \n\t"   \
-    "movq         %3, %%mm2             \n\t"   \
-    "movq         %3, %%mm3             \n\t"   \
-    "punpcklbw %%mm7, %%mm0             \n\t"   \
-    "punpckhbw %%mm7, %%mm1             \n\t"   \
-    "punpcklbw %%mm7, %%mm2             \n\t"   \
-    "punpckhbw %%mm7, %%mm3             \n\t"   \
-    "psubw     %%mm2, %%mm0             \n\t"   \
-    "psubw     %%mm3, %%mm1             \n\t"   \
-    "movq         %1, %%mm2             \n\t"   \
-    "movq         %1, %%mm3             \n\t"   \
-    "movq         %2, %%mm4             \n\t"   \
-    "movq         %2, %%mm5             \n\t"   \
-    "punpcklbw %%mm7, %%mm2             \n\t"   \
-    "punpckhbw %%mm7, %%mm3             \n\t"   \
-    "punpcklbw %%mm7, %%mm4             \n\t"   \
-    "punpckhbw %%mm7, %%mm5             \n\t"   \
-    "psubw     %%mm2, %%mm4             \n\t"   \
-    "psubw     %%mm3, %%mm5             \n\t"   \
-    "psllw        $2, %%mm4             \n\t"   \
-    "psllw        $2, %%mm5             \n\t"   \
-    "paddw     %%mm0, %%mm4             \n\t"   \
-    "paddw     %%mm1, %%mm5             \n\t"   \
-    "pxor      %%mm6, %%mm6             \n\t"   \
-    "pcmpgtw   %%mm4, %%mm6             \n\t"   \
-    "pcmpgtw   %%mm5, %%mm7             \n\t"   \
-    "pxor      %%mm6, %%mm4             \n\t"   \
-    "pxor      %%mm7, %%mm5             \n\t"   \
-    "psubw     %%mm6, %%mm4             \n\t"   \
-    "psubw     %%mm7, %%mm5             \n\t"   \
-    "psrlw        $3, %%mm4             \n\t"   \
-    "psrlw        $3, %%mm5             \n\t"   \
-    "packuswb  %%mm5, %%mm4             \n\t"   \
-    "packsswb  %%mm7, %%mm6             \n\t"   \
-    "pxor      %%mm7, %%mm7             \n\t"   \
-    "movd         %4, %%mm2             \n\t"   \
-    "punpcklbw %%mm2, %%mm2             \n\t"   \
-    "punpcklbw %%mm2, %%mm2             \n\t"   \
-    "punpcklbw %%mm2, %%mm2             \n\t"   \
-    "psubusb   %%mm4, %%mm2             \n\t"   \
-    "movq      %%mm2, %%mm3             \n\t"   \
-    "psubusb   %%mm4, %%mm3             \n\t"   \
-    "psubb     %%mm3, %%mm2             \n\t"   \
-    "movq         %1, %%mm3             \n\t"   \
-    "movq         %2, %%mm4             \n\t"   \
-    "pxor      %%mm6, %%mm3             \n\t"   \
-    "pxor      %%mm6, %%mm4             \n\t"   \
-    "paddusb   %%mm2, %%mm3             \n\t"   \
-    "psubusb   %%mm2, %%mm4             \n\t"   \
-    "pxor      %%mm6, %%mm3             \n\t"   \
-    "pxor      %%mm6, %%mm4             \n\t"   \
-    "paddusb   %%mm2, %%mm2             \n\t"   \
-    "packsswb  %%mm1, %%mm0             \n\t"   \
-    "pcmpgtb   %%mm0, %%mm7             \n\t"   \
-    "pxor      %%mm7, %%mm0             \n\t"   \
-    "psubb     %%mm7, %%mm0             \n\t"   \
-    "movq      %%mm0, %%mm1             \n\t"   \
-    "psubusb   %%mm2, %%mm0             \n\t"   \
-    "psubb     %%mm0, %%mm1             \n\t"   \
-    "pand         %5, %%mm1             \n\t"   \
-    "psrlw        $2, %%mm1             \n\t"   \
-    "pxor      %%mm7, %%mm1             \n\t"   \
-    "psubb     %%mm7, %%mm1             \n\t"   \
-    "movq         %0, %%mm5             \n\t"   \
-    "movq         %3, %%mm6             \n\t"   \
-    "psubb     %%mm1, %%mm5             \n\t"   \
-    "paddb     %%mm1, %%mm6             \n\t"
-
-static void h263_v_loop_filter_mmx(uint8_t *src, int stride, int qscale)
-{
-    if (CONFIG_H263_DECODER || CONFIG_H263_ENCODER) {
-        const int strength = ff_h263_loop_filter_strength[qscale];
-
-        __asm__ volatile (
-            H263_LOOP_FILTER
-
-            "movq %%mm3, %1             \n\t"
-            "movq %%mm4, %2             \n\t"
-            "movq %%mm5, %0             \n\t"
-            "movq %%mm6, %3             \n\t"
-            : "+m"(*(uint64_t*)(src - 2 * stride)),
-              "+m"(*(uint64_t*)(src - 1 * stride)),
-              "+m"(*(uint64_t*)(src + 0 * stride)),
-              "+m"(*(uint64_t*)(src + 1 * stride))
-            : "g"(2 * strength), "m"(ff_pb_FC)
-            );
-    }
-}
-
-static void h263_h_loop_filter_mmx(uint8_t *src, int stride, int qscale)
-{
-    if (CONFIG_H263_DECODER || CONFIG_H263_ENCODER) {
-        const int strength = ff_h263_loop_filter_strength[qscale];
-        DECLARE_ALIGNED(8, uint64_t, temp)[4];
-        uint8_t *btemp = (uint8_t*)temp;
-
-        src -= 2;
-
-        transpose4x4(btemp,     src,              8, stride);
-        transpose4x4(btemp + 4, src + 4 * stride, 8, stride);
-        __asm__ volatile (
-            H263_LOOP_FILTER // 5 3 4 6
-
-            : "+m"(temp[0]),
-              "+m"(temp[1]),
-              "+m"(temp[2]),
-              "+m"(temp[3])
-            : "g"(2 * strength), "m"(ff_pb_FC)
-            );
-
-        __asm__ volatile (
-            "movq      %%mm5, %%mm1         \n\t"
-            "movq      %%mm4, %%mm0         \n\t"
-            "punpcklbw %%mm3, %%mm5         \n\t"
-            "punpcklbw %%mm6, %%mm4         \n\t"
-            "punpckhbw %%mm3, %%mm1         \n\t"
-            "punpckhbw %%mm6, %%mm0         \n\t"
-            "movq      %%mm5, %%mm3         \n\t"
-            "movq      %%mm1, %%mm6         \n\t"
-            "punpcklwd %%mm4, %%mm5         \n\t"
-            "punpcklwd %%mm0, %%mm1         \n\t"
-            "punpckhwd %%mm4, %%mm3         \n\t"
-            "punpckhwd %%mm0, %%mm6         \n\t"
-            "movd      %%mm5, (%0)          \n\t"
-            "punpckhdq %%mm5, %%mm5         \n\t"
-            "movd      %%mm5, (%0, %2)      \n\t"
-            "movd      %%mm3, (%0, %2, 2)   \n\t"
-            "punpckhdq %%mm3, %%mm3         \n\t"
-            "movd      %%mm3, (%0, %3)      \n\t"
-            "movd      %%mm1, (%1)          \n\t"
-            "punpckhdq %%mm1, %%mm1         \n\t"
-            "movd      %%mm1, (%1, %2)      \n\t"
-            "movd      %%mm6, (%1, %2, 2)   \n\t"
-            "punpckhdq %%mm6, %%mm6         \n\t"
-            "movd      %%mm6, (%1, %3)      \n\t"
-            :: "r"(src),
-               "r"(src + 4 * stride),
-               "r"((x86_reg)stride),
-               "r"((x86_reg)(3 * stride))
-            );
-    }
-}
-
+#if HAVE_INLINE_ASM
 /* 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,
@@ -840,382 +765,15 @@
         }
     }
 }
+#endif /* HAVE_INLINE_ASM */
 
-#define QPEL_V_LOW(m3, m4, m5, m6, pw_20, pw_3, rnd,                      \
-                   in0, in1, in2, in7, out, OP)                           \
-    "paddw               "#m4", "#m3"   \n\t" /* x1 */                    \
-    "movq   "MANGLE(ff_pw_20)", %%mm4   \n\t" /* 20 */                    \
-    "pmullw              "#m3", %%mm4   \n\t" /* 20x1 */                  \
-    "movq               "#in7", "#m3"   \n\t" /* d */                     \
-    "movq               "#in0", %%mm5   \n\t" /* D */                     \
-    "paddw               "#m3", %%mm5   \n\t" /* x4 */                    \
-    "psubw               %%mm5, %%mm4   \n\t" /* 20x1 - x4 */             \
-    "movq               "#in1", %%mm5   \n\t" /* C */                     \
-    "movq               "#in2", %%mm6   \n\t" /* B */                     \
-    "paddw               "#m6", %%mm5   \n\t" /* x3 */                    \
-    "paddw               "#m5", %%mm6   \n\t" /* x2 */                    \
-    "paddw               %%mm6, %%mm6   \n\t" /* 2x2 */                   \
-    "psubw               %%mm6, %%mm5   \n\t" /* -2x2 + x3 */             \
-    "pmullw  "MANGLE(ff_pw_3)", %%mm5   \n\t" /* -6x2 + 3x3 */            \
-    "paddw              "#rnd", %%mm4   \n\t" /* x2 */                    \
-    "paddw               %%mm4, %%mm5   \n\t" /* 20x1 - 6x2 + 3x3 - x4 */ \
-    "psraw                  $5, %%mm5   \n\t"                             \
-    "packuswb            %%mm5, %%mm5   \n\t"                             \
-    OP(%%mm5, out, %%mm7, d)
 
-#define QPEL_BASE(OPNAME, ROUNDER, RND, OP_MMXEXT)                        \
-static void OPNAME ## mpeg4_qpel16_h_lowpass_mmxext(uint8_t *dst,         \
-                                                    uint8_t *src,         \
-                                                    int dstStride,        \
-                                                    int srcStride,        \
-                                                    int h)                \
-{                                                                         \
-    uint64_t temp;                                                        \
-                                                                          \
-    __asm__ volatile (                                                    \
-        "pxor      %%mm7, %%mm7             \n\t"                         \
-        "1:                                 \n\t"                         \
-        "movq       (%0), %%mm0             \n\t" /* ABCDEFGH */          \
-        "movq      %%mm0, %%mm1             \n\t" /* ABCDEFGH */          \
-        "movq      %%mm0, %%mm2             \n\t" /* ABCDEFGH */          \
-        "punpcklbw %%mm7, %%mm0             \n\t" /* 0A0B0C0D */          \
-        "punpckhbw %%mm7, %%mm1             \n\t" /* 0E0F0G0H */          \
-        "pshufw    $0x90, %%mm0, %%mm5      \n\t" /* 0A0A0B0C */          \
-        "pshufw    $0x41, %%mm0, %%mm6      \n\t" /* 0B0A0A0B */          \
-        "movq      %%mm2, %%mm3             \n\t" /* ABCDEFGH */          \
-        "movq      %%mm2, %%mm4             \n\t" /* ABCDEFGH */          \
-        "psllq        $8, %%mm2             \n\t" /* 0ABCDEFG */          \
-        "psllq       $16, %%mm3             \n\t" /* 00ABCDEF */          \
-        "psllq       $24, %%mm4             \n\t" /* 000ABCDE */          \
-        "punpckhbw %%mm7, %%mm2             \n\t" /* 0D0E0F0G */          \
-        "punpckhbw %%mm7, %%mm3             \n\t" /* 0C0D0E0F */          \
-        "punpckhbw %%mm7, %%mm4             \n\t" /* 0B0C0D0E */          \
-        "paddw     %%mm3, %%mm5             \n\t" /* b */                 \
-        "paddw     %%mm2, %%mm6             \n\t" /* c */                 \
-        "paddw     %%mm5, %%mm5             \n\t" /* 2b */                \
-        "psubw     %%mm5, %%mm6             \n\t" /* c - 2b */            \
-        "pshufw    $0x06, %%mm0, %%mm5      \n\t" /* 0C0B0A0A */          \
-        "pmullw "MANGLE(ff_pw_3)", %%mm6    \n\t" /* 3c - 6b */           \
-        "paddw     %%mm4, %%mm0             \n\t" /* a */                 \
-        "paddw     %%mm1, %%mm5             \n\t" /* d */                 \
-        "pmullw "MANGLE(ff_pw_20)", %%mm0   \n\t" /* 20a */               \
-        "psubw     %%mm5, %%mm0             \n\t" /* 20a - d */           \
-        "paddw        %6, %%mm6             \n\t"                         \
-        "paddw     %%mm6, %%mm0             \n\t" /* 20a - 6b + 3c - d */ \
-        "psraw        $5, %%mm0             \n\t"                         \
-        "movq      %%mm0, %5                \n\t"                         \
-        /* mm1 = EFGH, mm2 = DEFG, mm3 = CDEF, mm4 = BCDE, mm7 = 0 */     \
-                                                                          \
-        "movq      5(%0), %%mm0             \n\t" /* FGHIJKLM */          \
-        "movq      %%mm0, %%mm5             \n\t" /* FGHIJKLM */          \
-        "movq      %%mm0, %%mm6             \n\t" /* FGHIJKLM */          \
-        "psrlq        $8, %%mm0             \n\t" /* GHIJKLM0 */          \
-        "psrlq       $16, %%mm5             \n\t" /* HIJKLM00 */          \
-        "punpcklbw %%mm7, %%mm0             \n\t" /* 0G0H0I0J */          \
-        "punpcklbw %%mm7, %%mm5             \n\t" /* 0H0I0J0K */          \
-        "paddw     %%mm0, %%mm2             \n\t" /* b */                 \
-        "paddw     %%mm5, %%mm3             \n\t" /* c */                 \
-        "paddw     %%mm2, %%mm2             \n\t" /* 2b */                \
-        "psubw     %%mm2, %%mm3             \n\t" /* c - 2b */            \
-        "movq      %%mm6, %%mm2             \n\t" /* FGHIJKLM */          \
-        "psrlq       $24, %%mm6             \n\t" /* IJKLM000 */          \
-        "punpcklbw %%mm7, %%mm2             \n\t" /* 0F0G0H0I */          \
-        "punpcklbw %%mm7, %%mm6             \n\t" /* 0I0J0K0L */          \
-        "pmullw "MANGLE(ff_pw_3)", %%mm3    \n\t" /* 3c - 6b */           \
-        "paddw     %%mm2, %%mm1             \n\t" /* a */                 \
-        "paddw     %%mm6, %%mm4             \n\t" /* d */                 \
-        "pmullw "MANGLE(ff_pw_20)", %%mm1   \n\t" /* 20a */               \
-        "psubw     %%mm4, %%mm3             \n\t" /* - 6b +3c - d */      \
-        "paddw        %6, %%mm1             \n\t"                         \
-        "paddw     %%mm1, %%mm3             \n\t" /* 20a - 6b +3c - d */  \
-        "psraw        $5, %%mm3             \n\t"                         \
-        "movq         %5, %%mm1             \n\t"                         \
-        "packuswb  %%mm3, %%mm1             \n\t"                         \
-        OP_MMXEXT(%%mm1, (%1), %%mm4, q)                                  \
-        /* mm0 = GHIJ, mm2 = FGHI, mm5 = HIJK, mm6 = IJKL, mm7 = 0 */     \
-                                                                          \
-        "movq      9(%0), %%mm1             \n\t" /* JKLMNOPQ */          \
-        "movq      %%mm1, %%mm4             \n\t" /* JKLMNOPQ */          \
-        "movq      %%mm1, %%mm3             \n\t" /* JKLMNOPQ */          \
-        "psrlq        $8, %%mm1             \n\t" /* KLMNOPQ0 */          \
-        "psrlq       $16, %%mm4             \n\t" /* LMNOPQ00 */          \
-        "punpcklbw %%mm7, %%mm1             \n\t" /* 0K0L0M0N */          \
-        "punpcklbw %%mm7, %%mm4             \n\t" /* 0L0M0N0O */          \
-        "paddw     %%mm1, %%mm5             \n\t" /* b */                 \
-        "paddw     %%mm4, %%mm0             \n\t" /* c */                 \
-        "paddw     %%mm5, %%mm5             \n\t" /* 2b */                \
-        "psubw     %%mm5, %%mm0             \n\t" /* c - 2b */            \
-        "movq      %%mm3, %%mm5             \n\t" /* JKLMNOPQ */          \
-        "psrlq       $24, %%mm3             \n\t" /* MNOPQ000 */          \
-        "pmullw "MANGLE(ff_pw_3)", %%mm0    \n\t" /* 3c - 6b */           \
-        "punpcklbw %%mm7, %%mm3             \n\t" /* 0M0N0O0P */          \
-        "paddw     %%mm3, %%mm2             \n\t" /* d */                 \
-        "psubw     %%mm2, %%mm0             \n\t" /* -6b + 3c - d */      \
-        "movq      %%mm5, %%mm2             \n\t" /* JKLMNOPQ */          \
-        "punpcklbw %%mm7, %%mm2             \n\t" /* 0J0K0L0M */          \
-        "punpckhbw %%mm7, %%mm5             \n\t" /* 0N0O0P0Q */          \
-        "paddw     %%mm2, %%mm6             \n\t" /* a */                 \
-        "pmullw "MANGLE(ff_pw_20)", %%mm6   \n\t" /* 20a */               \
-        "paddw        %6, %%mm0             \n\t"                         \
-        "paddw     %%mm6, %%mm0             \n\t" /* 20a - 6b + 3c - d */ \
-        "psraw        $5, %%mm0             \n\t"                         \
-        /* mm1 = KLMN, mm2 = JKLM, mm3 = MNOP, */                         \
-        /* mm4 = LMNO, mm5 = NOPQ mm7 = 0 */                              \
-                                                                          \
-        "paddw    %%mm5, %%mm3              \n\t" /* a */                 \
-        "pshufw   $0xF9, %%mm5, %%mm6       \n\t" /* 0O0P0Q0Q */          \
-        "paddw    %%mm4, %%mm6              \n\t" /* b */                 \
-        "pshufw   $0xBE, %%mm5, %%mm4       \n\t" /* 0P0Q0Q0P */          \
-        "pshufw   $0x6F, %%mm5, %%mm5       \n\t" /* 0Q0Q0P0O */          \
-        "paddw    %%mm1, %%mm4              \n\t" /* c */                 \
-        "paddw    %%mm2, %%mm5              \n\t" /* d */                 \
-        "paddw    %%mm6, %%mm6              \n\t" /* 2b */                \
-        "psubw    %%mm6, %%mm4              \n\t" /* c - 2b */            \
-        "pmullw "MANGLE(ff_pw_20)", %%mm3   \n\t" /* 20a */               \
-        "pmullw  "MANGLE(ff_pw_3)", %%mm4   \n\t" /* 3c - 6b */           \
-        "psubw    %%mm5, %%mm3              \n\t" /* -6b + 3c - d */      \
-        "paddw       %6, %%mm4              \n\t"                         \
-        "paddw    %%mm3, %%mm4              \n\t" /* 20a - 6b + 3c - d */ \
-        "psraw       $5, %%mm4              \n\t"                         \
-        "packuswb %%mm4, %%mm0              \n\t"                         \
-        OP_MMXEXT(%%mm0, 8(%1), %%mm4, q)                                 \
-                                                                          \
-        "add         %3, %0                 \n\t"                         \
-        "add         %4, %1                 \n\t"                         \
-        "decl        %2                     \n\t"                         \
-        "jnz         1b                     \n\t"                         \
-        : "+a"(src), "+c"(dst), "+D"(h)                                   \
-        : "d"((x86_reg)srcStride), "S"((x86_reg)dstStride),               \
-          /* "m"(ff_pw_20), "m"(ff_pw_3), */ "m"(temp), "m"(ROUNDER)      \
-        : "memory"                                                        \
-        );                                                                \
-}                                                                         \
-                                                                          \
-static void OPNAME ## mpeg4_qpel8_h_lowpass_mmxext(uint8_t *dst,          \
-                                                   uint8_t *src,          \
-                                                   int dstStride,         \
-                                                   int srcStride,         \
-                                                   int h)                 \
-{                                                                         \
-    __asm__ volatile (                                                    \
-        "pxor      %%mm7, %%mm7             \n\t"                         \
-        "1:                                 \n\t"                         \
-        "movq       (%0), %%mm0             \n\t" /* ABCDEFGH */          \
-        "movq      %%mm0, %%mm1             \n\t" /* ABCDEFGH */          \
-        "movq      %%mm0, %%mm2             \n\t" /* ABCDEFGH */          \
-        "punpcklbw %%mm7, %%mm0             \n\t" /* 0A0B0C0D */          \
-        "punpckhbw %%mm7, %%mm1             \n\t" /* 0E0F0G0H */          \
-        "pshufw    $0x90, %%mm0, %%mm5      \n\t" /* 0A0A0B0C */          \
-        "pshufw    $0x41, %%mm0, %%mm6      \n\t" /* 0B0A0A0B */          \
-        "movq      %%mm2, %%mm3             \n\t" /* ABCDEFGH */          \
-        "movq      %%mm2, %%mm4             \n\t" /* ABCDEFGH */          \
-        "psllq        $8, %%mm2             \n\t" /* 0ABCDEFG */          \
-        "psllq       $16, %%mm3             \n\t" /* 00ABCDEF */          \
-        "psllq       $24, %%mm4             \n\t" /* 000ABCDE */          \
-        "punpckhbw %%mm7, %%mm2             \n\t" /* 0D0E0F0G */          \
-        "punpckhbw %%mm7, %%mm3             \n\t" /* 0C0D0E0F */          \
-        "punpckhbw %%mm7, %%mm4             \n\t" /* 0B0C0D0E */          \
-        "paddw     %%mm3, %%mm5             \n\t" /* b */                 \
-        "paddw     %%mm2, %%mm6             \n\t" /* c */                 \
-        "paddw     %%mm5, %%mm5             \n\t" /* 2b */                \
-        "psubw     %%mm5, %%mm6             \n\t" /* c - 2b */            \
-        "pshufw    $0x06, %%mm0, %%mm5      \n\t" /* 0C0B0A0A */          \
-        "pmullw "MANGLE(ff_pw_3)", %%mm6    \n\t" /* 3c - 6b */           \
-        "paddw     %%mm4, %%mm0             \n\t" /* a */                 \
-        "paddw     %%mm1, %%mm5             \n\t" /* d */                 \
-        "pmullw "MANGLE(ff_pw_20)", %%mm0   \n\t" /* 20a */               \
-        "psubw     %%mm5, %%mm0             \n\t" /* 20a - d */           \
-        "paddw        %5, %%mm6             \n\t"                         \
-        "paddw     %%mm6, %%mm0             \n\t" /* 20a - 6b + 3c - d */ \
-        "psraw        $5, %%mm0             \n\t"                         \
-        /* mm1 = EFGH, mm2 = DEFG, mm3 = CDEF, mm4 = BCDE, mm7 = 0 */     \
-                                                                          \
-        "movd      5(%0), %%mm5             \n\t" /* FGHI */              \
-        "punpcklbw %%mm7, %%mm5             \n\t" /* 0F0G0H0I */          \
-        "pshufw    $0xF9, %%mm5, %%mm6      \n\t" /* 0G0H0I0I */          \
-        "paddw     %%mm5, %%mm1             \n\t" /* a */                 \
-        "paddw     %%mm6, %%mm2             \n\t" /* b */                 \
-        "pshufw    $0xBE, %%mm5, %%mm6      \n\t" /* 0H0I0I0H */          \
-        "pshufw    $0x6F, %%mm5, %%mm5      \n\t" /* 0I0I0H0G */          \
-        "paddw     %%mm6, %%mm3             \n\t" /* c */                 \
-        "paddw     %%mm5, %%mm4             \n\t" /* d */                 \
-        "paddw     %%mm2, %%mm2             \n\t" /* 2b */                \
-        "psubw     %%mm2, %%mm3             \n\t" /* c - 2b */            \
-        "pmullw "MANGLE(ff_pw_20)", %%mm1   \n\t" /* 20a */               \
-        "pmullw  "MANGLE(ff_pw_3)", %%mm3   \n\t" /* 3c - 6b */           \
-        "psubw     %%mm4, %%mm3             \n\t" /* -6b + 3c - d */      \
-        "paddw        %5, %%mm1             \n\t"                         \
-        "paddw     %%mm1, %%mm3             \n\t" /* 20a - 6b + 3c - d */ \
-        "psraw        $5, %%mm3             \n\t"                         \
-        "packuswb  %%mm3, %%mm0             \n\t"                         \
-        OP_MMXEXT(%%mm0, (%1), %%mm4, q)                                  \
-                                                                          \
-        "add          %3, %0                \n\t"                         \
-        "add          %4, %1                \n\t"                         \
-        "decl         %2                    \n\t"                         \
-        "jnz          1b                    \n\t"                         \
-        : "+a"(src), "+c"(dst), "+d"(h)                                   \
-        : "S"((x86_reg)srcStride), "D"((x86_reg)dstStride),               \
-          /* "m"(ff_pw_20), "m"(ff_pw_3), */ "m"(ROUNDER)                 \
-        : "memory"                                                        \
-        );                                                                \
-}
-
-#define QPEL_OP(OPNAME, ROUNDER, RND, OP, MMX)                          \
-static void OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(uint8_t *dst,      \
-                                                     uint8_t *src,      \
-                                                     int dstStride,     \
-                                                     int srcStride)     \
-{                                                                       \
-    uint64_t temp[17 * 4];                                              \
-    uint64_t *temp_ptr = temp;                                          \
-    int count = 17;                                                     \
-                                                                        \
-    /* FIXME unroll */                                                  \
-    __asm__ volatile (                                                  \
-        "pxor      %%mm7, %%mm7             \n\t"                       \
-        "1:                                 \n\t"                       \
-        "movq       (%0), %%mm0             \n\t"                       \
-        "movq       (%0), %%mm1             \n\t"                       \
-        "movq      8(%0), %%mm2             \n\t"                       \
-        "movq      8(%0), %%mm3             \n\t"                       \
-        "punpcklbw %%mm7, %%mm0             \n\t"                       \
-        "punpckhbw %%mm7, %%mm1             \n\t"                       \
-        "punpcklbw %%mm7, %%mm2             \n\t"                       \
-        "punpckhbw %%mm7, %%mm3             \n\t"                       \
-        "movq      %%mm0, (%1)              \n\t"                       \
-        "movq      %%mm1, 17 * 8(%1)        \n\t"                       \
-        "movq      %%mm2, 2 * 17 * 8(%1)    \n\t"                       \
-        "movq      %%mm3, 3 * 17 * 8(%1)    \n\t"                       \
-        "add          $8, %1                \n\t"                       \
-        "add          %3, %0                \n\t"                       \
-        "decl         %2                    \n\t"                       \
-        "jnz          1b                    \n\t"                       \
-        : "+r"(src), "+r"(temp_ptr), "+r"(count)                        \
-        : "r"((x86_reg)srcStride)                                       \
-        : "memory"                                                      \
-        );                                                              \
-                                                                        \
-    temp_ptr = temp;                                                    \
-    count    = 4;                                                       \
-                                                                        \
-    /* FIXME reorder for speed */                                       \
-    __asm__ volatile (                                                  \
-        /* "pxor  %%mm7, %%mm7            \n\t" */                      \
-        "1:                             \n\t"                           \
-        "movq    (%0), %%mm0            \n\t"                           \
-        "movq   8(%0), %%mm1            \n\t"                           \
-        "movq  16(%0), %%mm2            \n\t"                           \
-        "movq  24(%0), %%mm3            \n\t"                           \
-        QPEL_V_LOW(%%mm0, %%mm1, %%mm2, %%mm3, %5, %6, %5, 16(%0),   8(%0),    (%0),  32(%0), (%1),     OP) \
-        QPEL_V_LOW(%%mm1, %%mm2, %%mm3, %%mm0, %5, %6, %5,  8(%0),    (%0),    (%0),  40(%0), (%1, %3), OP) \
-        "add       %4, %1               \n\t"                           \
-        QPEL_V_LOW(%%mm2, %%mm3, %%mm0, %%mm1, %5, %6, %5,   (%0),    (%0),   8(%0),  48(%0), (%1),     OP) \
-                                                                        \
-        QPEL_V_LOW(%%mm3, %%mm0, %%mm1, %%mm2, %5, %6, %5,   (%0),   8(%0),  16(%0),  56(%0), (%1, %3), OP) \
-        "add       %4, %1               \n\t"                           \
-        QPEL_V_LOW(%%mm0, %%mm1, %%mm2, %%mm3, %5, %6, %5,  8(%0),  16(%0),  24(%0),  64(%0), (%1),     OP) \
-        QPEL_V_LOW(%%mm1, %%mm2, %%mm3, %%mm0, %5, %6, %5, 16(%0),  24(%0),  32(%0),  72(%0), (%1, %3), OP) \
-        "add       %4, %1               \n\t"                           \
-        QPEL_V_LOW(%%mm2, %%mm3, %%mm0, %%mm1, %5, %6, %5, 24(%0),  32(%0),  40(%0),  80(%0), (%1),     OP) \
-        QPEL_V_LOW(%%mm3, %%mm0, %%mm1, %%mm2, %5, %6, %5, 32(%0),  40(%0),  48(%0),  88(%0), (%1, %3), OP) \
-        "add       %4, %1               \n\t"                           \
-        QPEL_V_LOW(%%mm0, %%mm1, %%mm2, %%mm3, %5, %6, %5, 40(%0),  48(%0),  56(%0),  96(%0), (%1),     OP) \
-        QPEL_V_LOW(%%mm1, %%mm2, %%mm3, %%mm0, %5, %6, %5, 48(%0),  56(%0),  64(%0), 104(%0), (%1, %3), OP) \
-        "add       %4, %1               \n\t"                           \
-        QPEL_V_LOW(%%mm2, %%mm3, %%mm0, %%mm1, %5, %6, %5, 56(%0),  64(%0),  72(%0), 112(%0), (%1),     OP) \
-        QPEL_V_LOW(%%mm3, %%mm0, %%mm1, %%mm2, %5, %6, %5, 64(%0),  72(%0),  80(%0), 120(%0), (%1, %3), OP) \
-        "add       %4, %1               \n\t"                           \
-        QPEL_V_LOW(%%mm0, %%mm1, %%mm2, %%mm3, %5, %6, %5, 72(%0),  80(%0),  88(%0), 128(%0), (%1),     OP) \
-                                                                        \
-        QPEL_V_LOW(%%mm1, %%mm2, %%mm3, %%mm0, %5, %6, %5, 80(%0),  88(%0),  96(%0), 128(%0), (%1, %3), OP) \
-        "add       %4, %1               \n\t"                           \
-        QPEL_V_LOW(%%mm2, %%mm3, %%mm0, %%mm1, %5, %6, %5, 88(%0),  96(%0), 104(%0), 120(%0), (%1),     OP) \
-        QPEL_V_LOW(%%mm3, %%mm0, %%mm1, %%mm2, %5, %6, %5, 96(%0), 104(%0), 112(%0), 112(%0), (%1, %3), OP) \
-                                                                        \
-        "add     $136, %0               \n\t"                           \
-        "add       %6, %1               \n\t"                           \
-        "decl      %2                   \n\t"                           \
-        "jnz       1b                   \n\t"                           \
-                                                                        \
-        : "+r"(temp_ptr), "+r"(dst), "+g"(count)                        \
-        : "r"((x86_reg)dstStride), "r"(2 * (x86_reg)dstStride),         \
-          /* "m"(ff_pw_20), "m"(ff_pw_3), */ "m"(ROUNDER),              \
-          "g"(4 - 14 * (x86_reg)dstStride)                              \
-        : "memory"                                                      \
-        );                                                              \
-}                                                                       \
-                                                                        \
-static void OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(uint8_t *dst,       \
-                                                    uint8_t *src,       \
-                                                    int dstStride,      \
-                                                    int srcStride)      \
-{                                                                       \
-    uint64_t temp[9 * 2];                                               \
-    uint64_t *temp_ptr = temp;                                          \
-    int count = 9;                                                      \
-                                                                        \
-    /* FIXME unroll */                                                  \
-    __asm__ volatile (                                                  \
-        "pxor      %%mm7, %%mm7         \n\t"                           \
-        "1:                             \n\t"                           \
-        "movq       (%0), %%mm0         \n\t"                           \
-        "movq       (%0), %%mm1         \n\t"                           \
-        "punpcklbw %%mm7, %%mm0         \n\t"                           \
-        "punpckhbw %%mm7, %%mm1         \n\t"                           \
-        "movq      %%mm0, (%1)          \n\t"                           \
-        "movq      %%mm1, 9*8(%1)       \n\t"                           \
-        "add          $8, %1            \n\t"                           \
-        "add          %3, %0            \n\t"                           \
-        "decl         %2                \n\t"                           \
-        "jnz          1b                \n\t"                           \
-        : "+r"(src), "+r"(temp_ptr), "+r"(count)                        \
-        : "r"((x86_reg)srcStride)                                       \
-        : "memory"                                                      \
-        );                                                              \
-                                                                        \
-    temp_ptr = temp;                                                    \
-    count    = 2;                                                       \
-                                                                        \
-    /* FIXME reorder for speed */                                       \
-    __asm__ volatile (                                                  \
-        /* "pxor  %%mm7, %%mm7            \n\t" */                      \
-        "1:                             \n\t"                           \
-        "movq    (%0), %%mm0            \n\t"                           \
-        "movq   8(%0), %%mm1            \n\t"                           \
-        "movq  16(%0), %%mm2            \n\t"                           \
-        "movq  24(%0), %%mm3            \n\t"                           \
-        QPEL_V_LOW(%%mm0, %%mm1, %%mm2, %%mm3, %5, %6, %5, 16(%0),  8(%0),   (%0), 32(%0), (%1), OP)     \
-        QPEL_V_LOW(%%mm1, %%mm2, %%mm3, %%mm0, %5, %6, %5,  8(%0),   (%0),   (%0), 40(%0), (%1, %3), OP) \
-        "add       %4, %1               \n\t"                           \
-        QPEL_V_LOW(%%mm2, %%mm3, %%mm0, %%mm1, %5, %6, %5,   (%0),   (%0),  8(%0), 48(%0), (%1), OP)     \
-                                                                        \
-        QPEL_V_LOW(%%mm3, %%mm0, %%mm1, %%mm2, %5, %6, %5,   (%0),  8(%0), 16(%0), 56(%0), (%1, %3), OP) \
-        "add       %4, %1               \n\t"                           \
-        QPEL_V_LOW(%%mm0, %%mm1, %%mm2, %%mm3, %5, %6, %5,  8(%0), 16(%0), 24(%0), 64(%0), (%1), OP)     \
-                                                                        \
-        QPEL_V_LOW(%%mm1, %%mm2, %%mm3, %%mm0, %5, %6, %5, 16(%0), 24(%0), 32(%0), 64(%0), (%1, %3), OP) \
-        "add       %4, %1               \n\t"                           \
-        QPEL_V_LOW(%%mm2, %%mm3, %%mm0, %%mm1, %5, %6, %5, 24(%0), 32(%0), 40(%0), 56(%0), (%1), OP)     \
-        QPEL_V_LOW(%%mm3, %%mm0, %%mm1, %%mm2, %5, %6, %5, 32(%0), 40(%0), 48(%0), 48(%0), (%1, %3), OP) \
-                                                                        \
-        "add      $72, %0               \n\t"                           \
-        "add       %6, %1               \n\t"                           \
-        "decl      %2                   \n\t"                           \
-        "jnz       1b                   \n\t"                           \
-                                                                        \
-        : "+r"(temp_ptr), "+r"(dst), "+g"(count)                        \
-        : "r"((x86_reg)dstStride), "r"(2 * (x86_reg)dstStride),         \
-          /* "m"(ff_pw_20), "m"(ff_pw_3), */ "m"(ROUNDER),              \
-          "g"(4 - 6 * (x86_reg)dstStride)                               \
-        : "memory"                                                      \
-        );                                                              \
-}                                                                       \
-                                                                        \
+#if HAVE_YASM
+#define QPEL_OP(OPNAME, ROUNDER, RND, MMX)                              \
 static void OPNAME ## qpel8_mc00_ ## MMX (uint8_t *dst, uint8_t *src,   \
                                           int stride)                   \
 {                                                                       \
-    OPNAME ## pixels8_ ## MMX(dst, src, stride, 8);                     \
+    ff_ ## OPNAME ## pixels8_ ## MMX(dst, src, stride, 8);              \
 }                                                                       \
                                                                         \
 static void OPNAME ## qpel8_mc10_ ## MMX(uint8_t *dst, uint8_t *src,    \
@@ -1223,16 +781,17 @@
 {                                                                       \
     uint64_t temp[8];                                                   \
     uint8_t * const half = (uint8_t*)temp;                              \
-    put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(half, src, 8,           \
-                                                stride, 8);             \
-    OPNAME ## pixels8_l2_ ## MMX(dst, src, half, stride, stride, 8);    \
+    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,    \
                                          int stride)                    \
 {                                                                       \
-    OPNAME ## mpeg4_qpel8_h_lowpass_ ## MMX(dst, src, stride,           \
-                                            stride, 8);                 \
+    ff_ ## OPNAME ## mpeg4_qpel8_h_lowpass_ ## MMX(dst, src, stride,    \
+                                                   stride, 8);          \
 }                                                                       \
                                                                         \
 static void OPNAME ## qpel8_mc30_ ## MMX(uint8_t *dst, uint8_t *src,    \
@@ -1240,10 +799,10 @@
 {                                                                       \
     uint64_t temp[8];                                                   \
     uint8_t * const half = (uint8_t*)temp;                              \
-    put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(half, src, 8,           \
-                                                stride, 8);             \
-    OPNAME ## pixels8_l2_ ## MMX(dst, src + 1, half, stride,            \
-                                 stride, 8);                            \
+    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,    \
@@ -1251,14 +810,17 @@
 {                                                                       \
     uint64_t temp[8];                                                   \
     uint8_t * const half = (uint8_t*)temp;                              \
-    put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(half, src, 8, stride);  \
-    OPNAME ## pixels8_l2_ ## MMX(dst, src, half, stride, stride, 8);    \
+    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,    \
                                          int stride)                    \
 {                                                                       \
-    OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(dst, src, stride, stride);  \
+    ff_ ## OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(dst, src,            \
+                                                   stride, stride);     \
 }                                                                       \
                                                                         \
 static void OPNAME ## qpel8_mc03_ ## MMX(uint8_t *dst, uint8_t *src,    \
@@ -1266,9 +828,10 @@
 {                                                                       \
     uint64_t temp[8];                                                   \
     uint8_t * const half = (uint8_t*)temp;                              \
-    put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(half, src, 8, stride);  \
-    OPNAME ## pixels8_l2_ ## MMX(dst, src + stride, half, stride,       \
-                                 stride, 8);                            \
+    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,    \
@@ -1277,11 +840,13 @@
     uint64_t half[8 + 9];                                               \
     uint8_t * const halfH  = ((uint8_t*)half) + 64;                     \
     uint8_t * const halfHV = ((uint8_t*)half);                          \
-    put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,          \
-                                                stride, 9);             \
-    put ## RND ## pixels8_l2_ ## MMX(halfH, src, halfH, 8, stride, 9);  \
-    put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);   \
-    OPNAME ## pixels8_l2_ ## MMX(dst, halfH, halfHV, stride, 8, 8);     \
+    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,    \
@@ -1290,12 +855,13 @@
     uint64_t half[8 + 9];                                               \
     uint8_t * const halfH  = ((uint8_t*)half) + 64;                     \
     uint8_t * const halfHV = ((uint8_t*)half);                          \
-    put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,          \
-                                                stride, 9);             \
-    put ## RND ## pixels8_l2_ ## MMX(halfH, src + 1, halfH, 8,          \
-                                     stride, 9);                        \
-    put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);   \
-    OPNAME ## pixels8_l2_ ## MMX(dst, halfH, halfHV, stride, 8, 8);     \
+    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,    \
@@ -1304,11 +870,13 @@
     uint64_t half[8 + 9];                                               \
     uint8_t * const halfH  = ((uint8_t*)half) + 64;                     \
     uint8_t * const halfHV = ((uint8_t*)half);                          \
-    put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,          \
-                                                stride, 9);             \
-    put ## RND ## pixels8_l2_ ## MMX(halfH, src, halfH, 8, stride, 9);  \
-    put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);   \
-    OPNAME ## pixels8_l2_ ## MMX(dst, halfH + 8, halfHV, stride, 8, 8); \
+    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,    \
@@ -1317,12 +885,13 @@
     uint64_t half[8 + 9];                                               \
     uint8_t * const halfH  = ((uint8_t*)half) + 64;                     \
     uint8_t * const halfHV = ((uint8_t*)half);                          \
-    put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,          \
-                                                stride, 9);             \
-    put ## RND ## pixels8_l2_ ## MMX(halfH, src + 1, halfH, 8,          \
-                                     stride, 9);                        \
-    put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);   \
-    OPNAME ## pixels8_l2_ ## MMX(dst, halfH + 8, halfHV, stride, 8, 8); \
+    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,    \
@@ -1331,10 +900,11 @@
     uint64_t half[8 + 9];                                               \
     uint8_t * const halfH  = ((uint8_t*)half) + 64;                     \
     uint8_t * const halfHV = ((uint8_t*)half);                          \
-    put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,          \
-                                                stride, 9);             \
-    put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);   \
-    OPNAME ## pixels8_l2_ ## MMX(dst, halfH, halfHV, stride, 8, 8);     \
+    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,    \
@@ -1343,10 +913,11 @@
     uint64_t half[8 + 9];                                               \
     uint8_t * const halfH  = ((uint8_t*)half) + 64;                     \
     uint8_t * const halfHV = ((uint8_t*)half);                          \
-    put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,          \
-                                                stride, 9);             \
-    put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);   \
-    OPNAME ## pixels8_l2_ ## MMX(dst, halfH + 8, halfHV, stride, 8, 8); \
+    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,    \
@@ -1354,10 +925,12 @@
 {                                                                       \
     uint64_t half[8 + 9];                                               \
     uint8_t * const halfH = ((uint8_t*)half);                           \
-    put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,          \
-                                                stride, 9);             \
-    put ## RND ## pixels8_l2_ ## MMX(halfH, src, halfH, 8, stride, 9);  \
-    OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(dst, halfH, stride, 8);     \
+    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,    \
@@ -1365,11 +938,12 @@
 {                                                                       \
     uint64_t half[8 + 9];                                               \
     uint8_t * const halfH = ((uint8_t*)half);                           \
-    put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,          \
-                                                stride, 9);             \
-    put ## RND ## pixels8_l2_ ## MMX(halfH, src + 1, halfH, 8,          \
-                                     stride, 9);                        \
-    OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(dst, halfH, stride, 8);     \
+    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,    \
@@ -1377,15 +951,16 @@
 {                                                                       \
     uint64_t half[9];                                                   \
     uint8_t * const halfH = ((uint8_t*)half);                           \
-    put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,          \
-                                                stride, 9);             \
-    OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(dst, halfH, stride, 8);     \
+    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,  \
                                            int stride)                  \
 {                                                                       \
-    OPNAME ## pixels16_ ## MMX(dst, src, stride, 16);                   \
+    ff_ ## OPNAME ## pixels16_ ## MMX(dst, src, stride, 16);            \
 }                                                                       \
                                                                         \
 static void OPNAME ## qpel16_mc10_ ## MMX(uint8_t *dst, uint8_t *src,   \
@@ -1393,16 +968,17 @@
 {                                                                       \
     uint64_t temp[32];                                                  \
     uint8_t * const half = (uint8_t*)temp;                              \
-    put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(half, src, 16,         \
-                                                 stride, 16);           \
-    OPNAME ## pixels16_l2_ ## MMX(dst, src, half, stride, stride, 16);  \
+    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,   \
                                           int stride)                   \
 {                                                                       \
-    OPNAME ## mpeg4_qpel16_h_lowpass_ ## MMX(dst, src,                  \
-                                             stride, stride, 16);       \
+    ff_ ## OPNAME ## mpeg4_qpel16_h_lowpass_ ## MMX(dst, src,           \
+                                                    stride, stride, 16);\
 }                                                                       \
                                                                         \
 static void OPNAME ## qpel16_mc30_ ## MMX(uint8_t *dst, uint8_t *src,   \
@@ -1410,10 +986,10 @@
 {                                                                       \
     uint64_t temp[32];                                                  \
     uint8_t * const half = (uint8_t*)temp;                              \
-    put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(half, src, 16,         \
-                                                 stride, 16);           \
-    OPNAME ## pixels16_l2_ ## MMX(dst, src + 1, half,                   \
-                                  stride, stride, 16);                  \
+    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,   \
@@ -1421,15 +997,17 @@
 {                                                                       \
     uint64_t temp[32];                                                  \
     uint8_t * const half = (uint8_t*)temp;                              \
-    put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(half, src, 16,         \
-                                                 stride);               \
-    OPNAME ## pixels16_l2_ ## MMX(dst, src, half, stride, stride, 16);  \
+    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,   \
                                           int stride)                   \
 {                                                                       \
-    OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(dst, src, stride, stride); \
+    ff_ ## OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(dst, src,           \
+                                                    stride, stride);    \
 }                                                                       \
                                                                         \
 static void OPNAME ## qpel16_mc03_ ## MMX(uint8_t *dst, uint8_t *src,   \
@@ -1437,10 +1015,10 @@
 {                                                                       \
     uint64_t temp[32];                                                  \
     uint8_t * const half = (uint8_t*)temp;                              \
-    put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(half, src, 16,         \
-                                                 stride);               \
-    OPNAME ## pixels16_l2_ ## MMX(dst, src+stride, half,                \
-                                  stride, stride, 16);                  \
+    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,   \
@@ -1449,13 +1027,14 @@
     uint64_t half[16 * 2 + 17 * 2];                                     \
     uint8_t * const halfH  = ((uint8_t*)half) + 256;                    \
     uint8_t * const halfHV = ((uint8_t*)half);                          \
-    put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,        \
-                                                 stride, 17);           \
-    put ## RND ## pixels16_l2_ ## MMX(halfH, src, halfH, 16,            \
-                                      stride, 17);                      \
-    put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH,         \
-                                                 16, 16);               \
-    OPNAME ## pixels16_l2_ ## MMX(dst, halfH, halfHV, stride, 16, 16);  \
+    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,   \
@@ -1464,13 +1043,14 @@
     uint64_t half[16 * 2 + 17 * 2];                                     \
     uint8_t * const halfH  = ((uint8_t*)half) + 256;                    \
     uint8_t * const halfHV = ((uint8_t*)half);                          \
-    put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,        \
-                                                 stride, 17);           \
-    put ## RND ## pixels16_l2_ ## MMX(halfH, src + 1, halfH, 16,        \
-                                      stride, 17);                      \
-    put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH,         \
-                                                 16, 16);               \
-    OPNAME ## pixels16_l2_ ## MMX(dst, halfH, halfHV, stride, 16, 16);  \
+    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,   \
@@ -1479,14 +1059,14 @@
     uint64_t half[16 * 2 + 17 * 2];                                     \
     uint8_t * const halfH  = ((uint8_t*)half) + 256;                    \
     uint8_t * const halfHV = ((uint8_t*)half);                          \
-    put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,        \
-                                                 stride, 17);           \
-    put ## RND ## pixels16_l2_ ## MMX(halfH, src, halfH, 16,            \
-                                      stride, 17);                      \
-    put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH,         \
-                                                 16, 16);               \
-    OPNAME ## pixels16_l2_ ## MMX(dst, halfH + 16, halfHV, stride,      \
-                                  16, 16);                              \
+    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,   \
@@ -1495,14 +1075,14 @@
     uint64_t half[16 * 2 + 17 * 2];                                     \
     uint8_t * const halfH  = ((uint8_t*)half) + 256;                    \
     uint8_t * const halfHV = ((uint8_t*)half);                          \
-    put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,        \
-                                                 stride, 17);           \
-    put ## RND ## pixels16_l2_ ## MMX(halfH, src + 1, halfH, 16,        \
-                                      stride, 17);                      \
-    put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH,         \
-                                                 16, 16);               \
-    OPNAME ## pixels16_l2_ ## MMX(dst, halfH + 16, halfHV, stride,      \
-                                  16, 16);                              \
+    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,   \
@@ -1511,11 +1091,12 @@
     uint64_t half[16 * 2 + 17 * 2];                                     \
     uint8_t * const halfH  = ((uint8_t*)half) + 256;                    \
     uint8_t * const halfHV = ((uint8_t*)half);                          \
-    put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,        \
-                                                 stride, 17);           \
-    put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH,         \
-                                                 16, 16);               \
-    OPNAME ## pixels16_l2_ ## MMX(dst, halfH, halfHV, stride, 16, 16);  \
+    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,   \
@@ -1524,12 +1105,12 @@
     uint64_t half[16 * 2 + 17 * 2];                                     \
     uint8_t * const halfH  = ((uint8_t*)half) + 256;                    \
     uint8_t * const halfHV = ((uint8_t*)half);                          \
-    put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,        \
-                                                 stride, 17);           \
-    put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH,         \
-                                                 16, 16);               \
-    OPNAME ## pixels16_l2_ ## MMX(dst, halfH + 16, halfHV, stride,      \
-                                  16, 16);                              \
+    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,   \
@@ -1537,11 +1118,12 @@
 {                                                                       \
     uint64_t half[17 * 2];                                              \
     uint8_t * const halfH = ((uint8_t*)half);                           \
-    put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,        \
-                                                 stride, 17);           \
-    put ## RND ## pixels16_l2_ ## MMX(halfH, src, halfH, 16,            \
-                                      stride, 17);                      \
-    OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(dst, halfH, stride, 16);   \
+    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,   \
@@ -1549,11 +1131,12 @@
 {                                                                       \
     uint64_t half[17 * 2];                                              \
     uint8_t * const halfH = ((uint8_t*)half);                           \
-    put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,        \
-                                                 stride, 17);           \
-    put ## RND ## pixels16_l2_ ## MMX(halfH, src + 1, halfH, 16,        \
-                                      stride, 17);                      \
-    OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(dst, halfH, stride, 16);   \
+    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,   \
@@ -1561,83 +1144,19 @@
 {                                                                       \
     uint64_t half[17 * 2];                                              \
     uint8_t * const halfH = ((uint8_t*)half);                           \
-    put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,        \
-                                                 stride, 17);           \
-    OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(dst, halfH, stride, 16);   \
+    ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,     \
+                                                    stride, 17);        \
+    ff_ ## OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(dst, halfH,         \
+                                                    stride, 16);        \
 }
 
-#define PUT_OP(a, b, temp, size)                \
-    "mov"#size"        "#a", "#b"       \n\t"
+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 */
 
-#define AVG_MMXEXT_OP(a, b, temp, size)         \
-    "mov"#size"        "#b", "#temp"    \n\t"   \
-    "pavgb          "#temp", "#a"       \n\t"   \
-    "mov"#size"        "#a", "#b"       \n\t"
 
-QPEL_BASE(put_,        ff_pw_16, _,        PUT_OP)
-QPEL_BASE(avg_,        ff_pw_16, _,        AVG_MMXEXT_OP)
-QPEL_BASE(put_no_rnd_, ff_pw_15, _no_rnd_, PUT_OP)
-QPEL_OP(put_,          ff_pw_16, _,        PUT_OP,        mmxext)
-QPEL_OP(avg_,          ff_pw_16, _,        AVG_MMXEXT_OP, mmxext)
-QPEL_OP(put_no_rnd_,   ff_pw_15, _no_rnd_, PUT_OP,        mmxext)
-
-/***********************************/
-/* bilinear qpel: not compliant to any spec, only for -lavdopts fast */
-
-#define QPEL_2TAP_XY(OPNAME, SIZE, MMX, XY, HPEL)                              \
-static void OPNAME ## 2tap_qpel ## SIZE ## _mc ## XY ## _ ## MMX(uint8_t *dst, \
-                                                                 uint8_t *src, \
-                                                                 int stride)   \
-{                                                                              \
-    OPNAME ## pixels ## SIZE ## HPEL(dst, src, stride, SIZE);                  \
-}
-
-#define QPEL_2TAP_L3(OPNAME, SIZE, MMX, XY, S0, S1, S2)                        \
-static void OPNAME ## 2tap_qpel ## SIZE ## _mc ## XY ## _ ## MMX(uint8_t *dst, \
-                                                                 uint8_t *src, \
-                                                                 int stride)   \
-{                                                                              \
-    OPNAME ## 2tap_qpel ## SIZE ## _l3_ ## MMX(dst, src + S0, stride, SIZE,    \
-                                               S1, S2);                        \
-}
-
-#define QPEL_2TAP(OPNAME, SIZE, MMX)                                        \
-QPEL_2TAP_XY(OPNAME, SIZE, MMX, 20, _x2_ ## MMX)                            \
-QPEL_2TAP_XY(OPNAME, SIZE, MMX, 02, _y2_ ## MMX)                            \
-QPEL_2TAP_XY(OPNAME, SIZE, MMX, 22, _xy2_mmx)                               \
-static const qpel_mc_func OPNAME ## 2tap_qpel ## SIZE ## _mc00_ ## MMX =    \
-    OPNAME ## qpel ## SIZE ## _mc00_ ## MMX;                                \
-static const qpel_mc_func OPNAME ## 2tap_qpel ## SIZE ## _mc21_ ## MMX =    \
-    OPNAME ## 2tap_qpel ## SIZE ## _mc20_ ## MMX;                           \
-static const qpel_mc_func OPNAME ## 2tap_qpel ## SIZE ## _mc12_ ## MMX =    \
-    OPNAME ## 2tap_qpel ## SIZE ## _mc02_ ## MMX;                           \
-static void OPNAME ## 2tap_qpel ## SIZE ## _mc32_ ## MMX(uint8_t *dst,      \
-                                                         uint8_t *src,      \
-                                                         int stride)        \
-{                                                                           \
-    OPNAME ## pixels ## SIZE ## _y2_ ## MMX(dst, src + 1, stride, SIZE);    \
-}                                                                           \
-static void OPNAME ## 2tap_qpel ## SIZE ## _mc23_ ## MMX(uint8_t *dst,      \
-                                                         uint8_t *src,      \
-                                                         int stride)        \
-{                                                                           \
-    OPNAME ## pixels ## SIZE ## _x2_ ## MMX(dst, src + stride,              \
-                                            stride, SIZE);                  \
-}                                                                           \
-QPEL_2TAP_L3(OPNAME, SIZE, MMX, 10, 0,           1,       0)                \
-QPEL_2TAP_L3(OPNAME, SIZE, MMX, 30, 1,          -1,       0)                \
-QPEL_2TAP_L3(OPNAME, SIZE, MMX, 01, 0,           stride,  0)                \
-QPEL_2TAP_L3(OPNAME, SIZE, MMX, 03, stride,     -stride,  0)                \
-QPEL_2TAP_L3(OPNAME, SIZE, MMX, 11, 0,           stride,  1)                \
-QPEL_2TAP_L3(OPNAME, SIZE, MMX, 31, 1,           stride, -1)                \
-QPEL_2TAP_L3(OPNAME, SIZE, MMX, 13, stride,     -stride,  1)                \
-QPEL_2TAP_L3(OPNAME, SIZE, MMX, 33, stride + 1, -stride, -1)                \
-
-QPEL_2TAP(put_, 16, mmxext)
-QPEL_2TAP(avg_, 16, mmxext)
-QPEL_2TAP(put_,  8, mmxext)
-QPEL_2TAP(avg_,  8, mmxext)
-
+#if HAVE_INLINE_ASM
 void ff_put_rv40_qpel8_mc33_mmx(uint8_t *dst, uint8_t *src, int stride)
 {
   put_pixels8_xy2_mmx(dst, src, stride, 8);
@@ -1655,82 +1174,8 @@
   avg_pixels16_xy2_mmx(dst, src, stride, 16);
 }
 
-#endif /* HAVE_INLINE_ASM */
-
-#if HAVE_YASM
-typedef void emu_edge_core_func(uint8_t *buf, const uint8_t *src,
-                                x86_reg linesize, x86_reg start_y,
-                                x86_reg end_y, x86_reg block_h,
-                                x86_reg start_x, x86_reg end_x,
-                                x86_reg block_w);
-extern emu_edge_core_func ff_emu_edge_core_mmx;
-extern emu_edge_core_func ff_emu_edge_core_sse;
-
-static av_always_inline void emulated_edge_mc(uint8_t *buf, const uint8_t *src,
-                                              int linesize,
-                                              int block_w, int block_h,
-                                              int src_x, int src_y,
-                                              int w, int h,
-                                              emu_edge_core_func *core_fn)
-{
-    int start_y, start_x, end_y, end_x, src_y_add = 0;
-
-    if (src_y >= h) {
-        src -= src_y*linesize;
-        src_y_add = h - 1;
-        src_y     = h - 1;
-    } else if (src_y <= -block_h) {
-        src -= src_y*linesize;
-        src_y_add = 1 - block_h;
-        src_y     = 1 - block_h;
-    }
-    if (src_x >= w) {
-        src   += w - 1 - src_x;
-        src_x  = w - 1;
-    } else if (src_x <= -block_w) {
-        src   += 1 - block_w - src_x;
-        src_x  = 1 - block_w;
-    }
-
-    start_y = FFMAX(0, -src_y);
-    start_x = FFMAX(0, -src_x);
-    end_y   = FFMIN(block_h, h-src_y);
-    end_x   = FFMIN(block_w, w-src_x);
-    av_assert2(start_x < end_x && block_w > 0);
-    av_assert2(start_y < end_y && block_h > 0);
-
-    // fill in the to-be-copied part plus all above/below
-    src += (src_y_add + start_y) * linesize + start_x;
-    buf += start_x;
-    core_fn(buf, src, linesize, start_y, end_y,
-            block_h, start_x, end_x, block_w);
-}
-
-#if ARCH_X86_32
-static av_noinline void emulated_edge_mc_mmx(uint8_t *buf, const uint8_t *src,
-                                             int linesize,
-                                             int block_w, int block_h,
-                                             int src_x, int src_y, int w, int h)
-{
-    emulated_edge_mc(buf, src, linesize, block_w, block_h, src_x, src_y,
-                     w, h, &ff_emu_edge_core_mmx);
-}
-#endif
-
-static av_noinline void emulated_edge_mc_sse(uint8_t *buf, const uint8_t *src,
-                                             int linesize,
-                                             int block_w, int block_h,
-                                             int src_x, int src_y, int w, int h)
-{
-    emulated_edge_mc(buf, src, linesize, block_w, block_h, src_x, src_y,
-                     w, h, &ff_emu_edge_core_sse);
-}
-#endif /* HAVE_YASM */
-
-#if HAVE_INLINE_ASM
-
 typedef void emulated_edge_mc_func(uint8_t *dst, const uint8_t *src,
-                                   int linesize, int block_w, int block_h,
+                                   ptrdiff_t linesize, int block_w, int block_h,
                                    int src_x, int src_y, int w, int h);
 
 static av_always_inline void gmc(uint8_t *dst, uint8_t *src,
@@ -1859,6 +1304,7 @@
     }
 }
 
+#if CONFIG_VIDEODSP
 #if HAVE_YASM
 #if ARCH_X86_32
 static void gmc_mmx(uint8_t *dst, uint8_t *src,
@@ -1867,7 +1313,7 @@
                     int shift, int r, int width, int height)
 {
     gmc(dst, src, stride, h, ox, oy, dxx, dxy, dyx, dyy, shift, r,
-        width, height, &emulated_edge_mc_mmx);
+        width, height, &ff_emulated_edge_mc_8);
 }
 #endif
 static void gmc_sse(uint8_t *dst, uint8_t *src,
@@ -1876,7 +1322,7 @@
                     int shift, int r, int width, int height)
 {
     gmc(dst, src, stride, h, ox, oy, dxx, dxy, dyx, dyy, shift, r,
-        width, height, &emulated_edge_mc_sse);
+        width, height, &ff_emulated_edge_mc_8);
 }
 #else
 static void gmc_mmx(uint8_t *dst, uint8_t *src,
@@ -1888,67 +1334,14 @@
         width, height, &ff_emulated_edge_mc_8);
 }
 #endif
-
-#define PREFETCH(name, op)                      \
-static void name(void *mem, int stride, int h)  \
-{                                               \
-    const uint8_t *p = mem;                     \
-    do {                                        \
-        __asm__ volatile (#op" %0" :: "m"(*p)); \
-        p += stride;                            \
-    } while (--h);                              \
-}
-
-PREFETCH(prefetch_mmxext, prefetcht0)
-PREFETCH(prefetch_3dnow, prefetch)
-#undef PREFETCH
+#endif
 
 #endif /* HAVE_INLINE_ASM */
 
-#include "h264_qpel.c"
-
-void ff_put_h264_chroma_mc8_rnd_mmx  (uint8_t *dst, uint8_t *src,
-                                      int stride, int h, int x, int y);
-void ff_avg_h264_chroma_mc8_rnd_mmxext(uint8_t *dst, uint8_t *src,
-                                       int stride, int h, int x, int y);
-void ff_avg_h264_chroma_mc8_rnd_3dnow(uint8_t *dst, uint8_t *src,
-                                      int stride, int h, int x, int y);
-
-void ff_put_h264_chroma_mc4_mmx      (uint8_t *dst, uint8_t *src,
-                                      int stride, int h, int x, int y);
-void ff_avg_h264_chroma_mc4_mmxext   (uint8_t *dst, uint8_t *src,
-                                      int stride, int h, int x, int y);
-void ff_avg_h264_chroma_mc4_3dnow    (uint8_t *dst, uint8_t *src,
-                                      int stride, int h, int x, int y);
-
-void ff_put_h264_chroma_mc2_mmxext   (uint8_t *dst, uint8_t *src,
-                                      int stride, int h, int x, int y);
-void ff_avg_h264_chroma_mc2_mmxext   (uint8_t *dst, uint8_t *src,
-                                      int stride, int h, int x, int y);
-
-void ff_put_h264_chroma_mc8_rnd_ssse3(uint8_t *dst, uint8_t *src,
-                                      int stride, int h, int x, int y);
-void ff_put_h264_chroma_mc4_ssse3    (uint8_t *dst, uint8_t *src,
-                                      int stride, int h, int x, int y);
-
-void ff_avg_h264_chroma_mc8_rnd_ssse3(uint8_t *dst, uint8_t *src,
-                                      int stride, int h, int x, int y);
-void ff_avg_h264_chroma_mc4_ssse3    (uint8_t *dst, uint8_t *src,
-                                      int stride, int h, int x, int y);
-
-#define CHROMA_MC(OP, NUM, DEPTH, OPT)                                  \
-void ff_ ## OP ## _h264_chroma_mc ## NUM ## _ ## DEPTH ## _ ## OPT      \
-                                      (uint8_t *dst, uint8_t *src,      \
-                                       int stride, int h, int x, int y);
-
-CHROMA_MC(put, 2, 10, mmxext)
-CHROMA_MC(avg, 2, 10, mmxext)
-CHROMA_MC(put, 4, 10, mmxext)
-CHROMA_MC(avg, 4, 10, mmxext)
-CHROMA_MC(put, 8, 10, sse2)
-CHROMA_MC(avg, 8, 10, sse2)
-CHROMA_MC(put, 8, 10, avx)
-CHROMA_MC(avg, 8, 10, avx)
+void ff_put_pixels16_sse2(uint8_t *block, const uint8_t *pixels,
+                          ptrdiff_t line_size, int h);
+void ff_avg_pixels16_sse2(uint8_t *block, const uint8_t *pixels,
+                          ptrdiff_t line_size, int h);
 
 #if HAVE_INLINE_ASM
 
@@ -1980,88 +1373,71 @@
     put_pixels8_mmx(dst, src, stride, 8);
 }
 
-void ff_avg_vc1_mspel_mc00_mmxext(uint8_t *dst, const uint8_t *src,
-                                  int stride, int rnd)
-{
-    avg_pixels8_mmxext(dst, src, stride, 8);
-}
-
-/* only used in VP3/5/6 */
-static void put_vp_no_rnd_pixels8_l2_mmx(uint8_t *dst, const uint8_t *a, const uint8_t *b, int stride, int h)
-{
-//    START_TIMER
-    MOVQ_BFE(mm6);
-    __asm__ volatile(
-        "1:                             \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "movq   (%2), %%mm1             \n\t"
-        "movq   (%1,%4), %%mm2          \n\t"
-        "movq   (%2,%4), %%mm3          \n\t"
-        PAVGBP_MMX_NO_RND(%%mm0, %%mm1, %%mm4,   %%mm2, %%mm3, %%mm5)
-        "movq   %%mm4, (%3)             \n\t"
-        "movq   %%mm5, (%3,%4)          \n\t"
-
-        "movq   (%1,%4,2), %%mm0        \n\t"
-        "movq   (%2,%4,2), %%mm1        \n\t"
-        "movq   (%1,%5), %%mm2          \n\t"
-        "movq   (%2,%5), %%mm3          \n\t"
-        "lea    (%1,%4,4), %1           \n\t"
-        "lea    (%2,%4,4), %2           \n\t"
-        PAVGBP_MMX_NO_RND(%%mm0, %%mm1, %%mm4,   %%mm2, %%mm3, %%mm5)
-        "movq   %%mm4, (%3,%4,2)        \n\t"
-        "movq   %%mm5, (%3,%5)          \n\t"
-        "lea    (%3,%4,4), %3           \n\t"
-        "subl   $4, %0                  \n\t"
-        "jnz    1b                      \n\t"
-        :"+r"(h), "+r"(a), "+r"(b), "+r"(dst)
-        :"r"((x86_reg)stride), "r"((x86_reg)3L*stride)
-        :"memory");
-//    STOP_TIMER("put_vp_no_rnd_pixels8_l2_mmx")
-}
-static void put_vp_no_rnd_pixels16_l2_mmx(uint8_t *dst, const uint8_t *a, const uint8_t *b, int stride, int h)
-{
-    put_vp_no_rnd_pixels8_l2_mmx(dst, a, b, stride, h);
-    put_vp_no_rnd_pixels8_l2_mmx(dst+8, a+8, b+8, stride, h);
-}
-
 #if CONFIG_DIRAC_DECODER
-#define DIRAC_PIXOP(OPNAME, EXT)\
-void ff_ ## OPNAME ## _dirac_pixels8_ ## EXT(uint8_t *dst, const uint8_t *src[5], int stride, int h)\
+#define DIRAC_PIXOP(OPNAME2, OPNAME, EXT)\
+void ff_ ## OPNAME2 ## _dirac_pixels8_ ## EXT(uint8_t *dst, const uint8_t *src[5], int stride, int h)\
 {\
-    OPNAME ## _pixels8_ ## EXT(dst, src[0], stride, h);\
+    if (h&3)\
+        ff_ ## OPNAME2 ## _dirac_pixels8_c(dst, src, stride, h);\
+    else\
+        OPNAME ## _pixels8_ ## EXT(dst, src[0], stride, h);\
 }\
-void ff_ ## OPNAME ## _dirac_pixels16_ ## EXT(uint8_t *dst, const uint8_t *src[5], int stride, int h)\
+void ff_ ## OPNAME2 ## _dirac_pixels16_ ## EXT(uint8_t *dst, const uint8_t *src[5], int stride, int h)\
 {\
-    OPNAME ## _pixels16_ ## EXT(dst, src[0], stride, h);\
+    if (h&3)\
+        ff_ ## OPNAME2 ## _dirac_pixels16_c(dst, src, stride, h);\
+    else\
+        OPNAME ## _pixels16_ ## EXT(dst, src[0], stride, h);\
 }\
-void ff_ ## OPNAME ## _dirac_pixels32_ ## EXT(uint8_t *dst, const uint8_t *src[5], int stride, int h)\
+void ff_ ## OPNAME2 ## _dirac_pixels32_ ## EXT(uint8_t *dst, const uint8_t *src[5], int stride, int h)\
 {\
-    OPNAME ## _pixels16_ ## EXT(dst   , src[0]   , stride, h);\
-    OPNAME ## _pixels16_ ## EXT(dst+16, src[0]+16, stride, h);\
+    if (h&3) {\
+        ff_ ## OPNAME2 ## _dirac_pixels32_c(dst, src, stride, h);\
+    } else {\
+        OPNAME ## _pixels16_ ## EXT(dst   , src[0]   , stride, h);\
+        OPNAME ## _pixels16_ ## EXT(dst+16, src[0]+16, stride, h);\
+    }\
 }
 
-DIRAC_PIXOP(put, mmx)
-DIRAC_PIXOP(avg, mmx)
-DIRAC_PIXOP(avg, mmxext)
+#if HAVE_MMX_INLINE
+DIRAC_PIXOP(put, put, mmx)
+DIRAC_PIXOP(avg, avg, mmx)
+#endif
 
 #if HAVE_YASM
+DIRAC_PIXOP(avg, ff_avg, mmxext)
+
 void ff_put_dirac_pixels16_sse2(uint8_t *dst, const uint8_t *src[5], int stride, int h)
 {
+    if (h&3)
+        ff_put_dirac_pixels16_c(dst, src, stride, h);
+    else
     ff_put_pixels16_sse2(dst, src[0], stride, h);
 }
 void ff_avg_dirac_pixels16_sse2(uint8_t *dst, const uint8_t *src[5], int stride, int h)
 {
+    if (h&3)
+        ff_avg_dirac_pixels16_c(dst, src, stride, h);
+    else
     ff_avg_pixels16_sse2(dst, src[0], stride, h);
 }
 void ff_put_dirac_pixels32_sse2(uint8_t *dst, const uint8_t *src[5], int stride, int h)
 {
+    if (h&3) {
+        ff_put_dirac_pixels32_c(dst, src, stride, h);
+    } else {
     ff_put_pixels16_sse2(dst   , src[0]   , stride, h);
     ff_put_pixels16_sse2(dst+16, src[0]+16, stride, h);
+    }
 }
 void ff_avg_dirac_pixels32_sse2(uint8_t *dst, const uint8_t *src[5], int stride, int h)
 {
+    if (h&3) {
+        ff_avg_dirac_pixels32_c(dst, src, stride, h);
+    } else {
     ff_avg_pixels16_sse2(dst   , src[0]   , stride, h);
     ff_avg_pixels16_sse2(dst+16, src[0]+16, stride, h);
+    }
 }
 #endif
 #endif
@@ -2070,159 +1446,34 @@
  * converted. */
 #if CONFIG_GPL
 static void ff_libmpeg2mmx_idct_put(uint8_t *dest, int line_size,
-                                    DCTELEM *block)
+                                    int16_t *block)
 {
     ff_mmx_idct(block);
     ff_put_pixels_clamped_mmx(block, dest, line_size);
 }
 
 static void ff_libmpeg2mmx_idct_add(uint8_t *dest, int line_size,
-                                    DCTELEM *block)
+                                    int16_t *block)
 {
     ff_mmx_idct(block);
     ff_add_pixels_clamped_mmx(block, dest, line_size);
 }
 
 static void ff_libmpeg2mmx2_idct_put(uint8_t *dest, int line_size,
-                                     DCTELEM *block)
+                                     int16_t *block)
 {
     ff_mmxext_idct(block);
     ff_put_pixels_clamped_mmx(block, dest, line_size);
 }
 
 static void ff_libmpeg2mmx2_idct_add(uint8_t *dest, int line_size,
-                                     DCTELEM *block)
+                                     int16_t *block)
 {
     ff_mmxext_idct(block);
     ff_add_pixels_clamped_mmx(block, dest, line_size);
 }
 #endif
 
-static void vorbis_inverse_coupling_3dnow(float *mag, float *ang, int blocksize)
-{
-    int i;
-    __asm__ volatile ("pxor %%mm7, %%mm7":);
-    for (i = 0; i < blocksize; i += 2) {
-        __asm__ volatile (
-            "movq       %0, %%mm0   \n\t"
-            "movq       %1, %%mm1   \n\t"
-            "movq    %%mm0, %%mm2   \n\t"
-            "movq    %%mm1, %%mm3   \n\t"
-            "pfcmpge %%mm7, %%mm2   \n\t" // m <= 0.0
-            "pfcmpge %%mm7, %%mm3   \n\t" // a <= 0.0
-            "pslld     $31, %%mm2   \n\t" // keep only the sign bit
-            "pxor    %%mm2, %%mm1   \n\t"
-            "movq    %%mm3, %%mm4   \n\t"
-            "pand    %%mm1, %%mm3   \n\t"
-            "pandn   %%mm1, %%mm4   \n\t"
-            "pfadd   %%mm0, %%mm3   \n\t" // a = m + ((a < 0) & (a ^ sign(m)))
-            "pfsub   %%mm4, %%mm0   \n\t" // m = m + ((a > 0) & (a ^ sign(m)))
-            "movq    %%mm3, %1      \n\t"
-            "movq    %%mm0, %0      \n\t"
-            : "+m"(mag[i]), "+m"(ang[i])
-            :: "memory"
-        );
-    }
-    __asm__ volatile ("femms");
-}
-
-static void vorbis_inverse_coupling_sse(float *mag, float *ang, int blocksize)
-{
-    int i;
-
-    __asm__ volatile (
-        "movaps  %0, %%xmm5 \n\t"
-        :: "m"(ff_pdw_80000000[0])
-    );
-    for (i = 0; i < blocksize; i += 4) {
-        __asm__ volatile (
-            "movaps      %0, %%xmm0 \n\t"
-            "movaps      %1, %%xmm1 \n\t"
-            "xorps   %%xmm2, %%xmm2 \n\t"
-            "xorps   %%xmm3, %%xmm3 \n\t"
-            "cmpleps %%xmm0, %%xmm2 \n\t" // m <= 0.0
-            "cmpleps %%xmm1, %%xmm3 \n\t" // a <= 0.0
-            "andps   %%xmm5, %%xmm2 \n\t" // keep only the sign bit
-            "xorps   %%xmm2, %%xmm1 \n\t"
-            "movaps  %%xmm3, %%xmm4 \n\t"
-            "andps   %%xmm1, %%xmm3 \n\t"
-            "andnps  %%xmm1, %%xmm4 \n\t"
-            "addps   %%xmm0, %%xmm3 \n\t" // a = m + ((a < 0) & (a ^ sign(m)))
-            "subps   %%xmm4, %%xmm0 \n\t" // m = m + ((a > 0) & (a ^ sign(m)))
-            "movaps  %%xmm3, %1     \n\t"
-            "movaps  %%xmm0, %0     \n\t"
-            : "+m"(mag[i]), "+m"(ang[i])
-            :: "memory"
-        );
-    }
-}
-
-#if HAVE_6REGS
-static void vector_fmul_window_3dnowext(float *dst, const float *src0,
-                                        const float *src1, const float *win,
-                                        int len)
-{
-    x86_reg i = -len * 4;
-    x86_reg j =  len * 4 - 8;
-    __asm__ volatile (
-        "1:                             \n"
-        "pswapd (%5, %1), %%mm1         \n"
-        "movq   (%5, %0), %%mm0         \n"
-        "pswapd (%4, %1), %%mm5         \n"
-        "movq   (%3, %0), %%mm4         \n"
-        "movq      %%mm0, %%mm2         \n"
-        "movq      %%mm1, %%mm3         \n"
-        "pfmul     %%mm4, %%mm2         \n" // src0[len + i] * win[len + i]
-        "pfmul     %%mm5, %%mm3         \n" // src1[j]       * win[len + j]
-        "pfmul     %%mm4, %%mm1         \n" // src0[len + i] * win[len + j]
-        "pfmul     %%mm5, %%mm0         \n" // src1[j]       * win[len + i]
-        "pfadd     %%mm3, %%mm2         \n"
-        "pfsub     %%mm0, %%mm1         \n"
-        "pswapd    %%mm2, %%mm2         \n"
-        "movq      %%mm1, (%2, %0)      \n"
-        "movq      %%mm2, (%2, %1)      \n"
-        "sub          $8, %1            \n"
-        "add          $8, %0            \n"
-        "jl           1b                \n"
-        "femms                          \n"
-        : "+r"(i), "+r"(j)
-        : "r"(dst + len), "r"(src0 + len), "r"(src1), "r"(win + len)
-    );
-}
-
-static void vector_fmul_window_sse(float *dst, const float *src0,
-                                   const float *src1, const float *win, int len)
-{
-    x86_reg i = -len * 4;
-    x86_reg j =  len * 4 - 16;
-    __asm__ volatile (
-        "1:                             \n"
-        "movaps      (%5, %1), %%xmm1   \n"
-        "movaps      (%5, %0), %%xmm0   \n"
-        "movaps      (%4, %1), %%xmm5   \n"
-        "movaps      (%3, %0), %%xmm4   \n"
-        "shufps $0x1b, %%xmm1, %%xmm1   \n"
-        "shufps $0x1b, %%xmm5, %%xmm5   \n"
-        "movaps        %%xmm0, %%xmm2   \n"
-        "movaps        %%xmm1, %%xmm3   \n"
-        "mulps         %%xmm4, %%xmm2   \n" // src0[len + i] * win[len + i]
-        "mulps         %%xmm5, %%xmm3   \n" // src1[j]       * win[len + j]
-        "mulps         %%xmm4, %%xmm1   \n" // src0[len + i] * win[len + j]
-        "mulps         %%xmm5, %%xmm0   \n" // src1[j]       * win[len + i]
-        "addps         %%xmm3, %%xmm2   \n"
-        "subps         %%xmm0, %%xmm1   \n"
-        "shufps $0x1b, %%xmm2, %%xmm2   \n"
-        "movaps        %%xmm1, (%2, %0) \n"
-        "movaps        %%xmm2, (%2, %1) \n"
-        "sub              $16, %1       \n"
-        "add              $16, %0       \n"
-        "jl                1b           \n"
-        : "+r"(i), "+r"(j)
-        : "r"(dst + len), "r"(src0 + len), "r"(src1), "r"(win + len)
-    );
-}
-#endif /* HAVE_6REGS */
-
 static void vector_clipf_sse(float *dst, const float *src,
                              float min, float max, int len)
 {
@@ -2297,18 +1548,6 @@
 int  ff_add_hfyu_left_prediction_sse4(uint8_t *dst, const uint8_t *src,
                                       int w, int left);
 
-float ff_scalarproduct_float_sse(const float *v1, const float *v2, int order);
-
-void ff_vector_fmul_reverse_sse(float *dst, const float *src0,
-                                const float *src1, int len);
-void ff_vector_fmul_reverse_avx(float *dst, const float *src0,
-                                const float *src1, int len);
-
-void ff_vector_fmul_add_sse(float *dst, const float *src0, const float *src1,
-                            const float *src2, int len);
-void ff_vector_fmul_add_avx(float *dst, const float *src0, const float *src1,
-                            const float *src2, int len);
-
 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,
@@ -2318,11 +1557,6 @@
 void ff_vector_clip_int32_sse4    (int32_t *dst, const int32_t *src,
                                    int32_t min, int32_t max, unsigned int len);
 
-extern void ff_butterflies_float_interleave_sse(float *dst, const float *src0,
-                                                const float *src1, int len);
-extern void ff_butterflies_float_interleave_avx(float *dst, const float *src0,
-                                                const float *src1, int len);
-
 #define SET_QPEL_FUNCS(PFX, IDX, SIZE, CPU, PREFIX)                          \
     do {                                                                     \
     c->PFX ## _pixels_tab[IDX][ 0] = PREFIX ## PFX ## SIZE ## _mc00_ ## CPU; \
@@ -2345,29 +1579,14 @@
 
 #define SET_HPEL_FUNCS(PFX, IDX, SIZE, CPU)                                     \
     do {                                                                        \
-        c->PFX ## _pixels_tab[IDX][0] = PFX ## _pixels ## SIZE ## _     ## CPU; \
-        c->PFX ## _pixels_tab[IDX][1] = PFX ## _pixels ## SIZE ## _x2_  ## CPU; \
-        c->PFX ## _pixels_tab[IDX][2] = PFX ## _pixels ## SIZE ## _y2_  ## CPU; \
-        c->PFX ## _pixels_tab[IDX][3] = PFX ## _pixels ## SIZE ## _xy2_ ## CPU; \
+        c->PFX ## _pixels_tab IDX [0] = PFX ## _pixels ## SIZE ## _     ## CPU; \
+        c->PFX ## _pixels_tab IDX [1] = PFX ## _pixels ## SIZE ## _x2_  ## CPU; \
+        c->PFX ## _pixels_tab IDX [2] = PFX ## _pixels ## SIZE ## _y2_  ## CPU; \
+        c->PFX ## _pixels_tab IDX [3] = PFX ## _pixels ## SIZE ## _xy2_ ## CPU; \
     } while (0)
 
-#define H264_QPEL_FUNCS(x, y, CPU)                                                            \
-    do {                                                                                      \
-        c->put_h264_qpel_pixels_tab[0][x + y * 4] = put_h264_qpel16_mc ## x ## y ## _ ## CPU; \
-        c->put_h264_qpel_pixels_tab[1][x + y * 4] = put_h264_qpel8_mc  ## x ## y ## _ ## CPU; \
-        c->avg_h264_qpel_pixels_tab[0][x + y * 4] = avg_h264_qpel16_mc ## x ## y ## _ ## CPU; \
-        c->avg_h264_qpel_pixels_tab[1][x + y * 4] = avg_h264_qpel8_mc  ## x ## y ## _ ## CPU; \
-    } while (0)
-
-#define H264_QPEL_FUNCS_10(x, y, CPU)                                                               \
-    do {                                                                                            \
-        c->put_h264_qpel_pixels_tab[0][x + y * 4] = ff_put_h264_qpel16_mc ## x ## y ## _10_ ## CPU; \
-        c->put_h264_qpel_pixels_tab[1][x + y * 4] = ff_put_h264_qpel8_mc  ## x ## y ## _10_ ## CPU; \
-        c->avg_h264_qpel_pixels_tab[0][x + y * 4] = ff_avg_h264_qpel16_mc ## x ## y ## _10_ ## CPU; \
-        c->avg_h264_qpel_pixels_tab[1][x + y * 4] = ff_avg_h264_qpel8_mc  ## x ## y ## _10_ ## CPU; \
-    } while (0)
-
-static void dsputil_init_mmx(DSPContext *c, AVCodecContext *avctx, int mm_flags)
+static av_cold void dsputil_init_mmx(DSPContext *c, AVCodecContext *avctx,
+                                     int mm_flags)
 {
     const int high_bit_depth = avctx->bits_per_raw_sample > 8;
 
@@ -2381,40 +1600,26 @@
         c->clear_blocks = clear_blocks_mmx;
         c->draw_edges   = draw_edges_mmx;
 
-        SET_HPEL_FUNCS(put,        0, 16, mmx);
-        SET_HPEL_FUNCS(put_no_rnd, 0, 16, mmx);
-        SET_HPEL_FUNCS(avg,        0, 16, mmx);
-        SET_HPEL_FUNCS(avg_no_rnd, 0, 16, mmx);
-        SET_HPEL_FUNCS(put,        1,  8, mmx);
-        SET_HPEL_FUNCS(put_no_rnd, 1,  8, mmx);
-        SET_HPEL_FUNCS(avg,        1,  8, mmx);
-        SET_HPEL_FUNCS(avg_no_rnd, 1,  8, mmx);
+        SET_HPEL_FUNCS(put,        [0], 16, mmx);
+        SET_HPEL_FUNCS(put_no_rnd, [0], 16, mmx);
+        SET_HPEL_FUNCS(avg,        [0], 16, mmx);
+        SET_HPEL_FUNCS(avg_no_rnd,    , 16, mmx);
+        SET_HPEL_FUNCS(put,        [1],  8, mmx);
+        SET_HPEL_FUNCS(put_no_rnd, [1],  8, mmx);
+        SET_HPEL_FUNCS(avg,        [1],  8, mmx);
     }
 
-#if ARCH_X86_32 || !HAVE_YASM
+#if CONFIG_VIDEODSP && (ARCH_X86_32 || !HAVE_YASM)
     c->gmc = gmc_mmx;
 #endif
 
     c->add_bytes = add_bytes_mmx;
-
-    c->put_no_rnd_pixels_l2[0]= put_vp_no_rnd_pixels16_l2_mmx;
-    c->put_no_rnd_pixels_l2[1]= put_vp_no_rnd_pixels8_l2_mmx;
-
-    if (CONFIG_H263_DECODER || CONFIG_H263_ENCODER) {
-        c->h263_v_loop_filter = h263_v_loop_filter_mmx;
-        c->h263_h_loop_filter = h263_h_loop_filter_mmx;
-    }
 #endif /* HAVE_INLINE_ASM */
 
 #if HAVE_YASM
-#if ARCH_X86_32
-    if (!high_bit_depth)
-        c->emulated_edge_mc = emulated_edge_mc_mmx;
-#endif
-
-    if (!high_bit_depth && CONFIG_H264CHROMA) {
-        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 (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;
@@ -2422,94 +1627,55 @@
 
 }
 
-static void dsputil_init_mmxext(DSPContext *c, AVCodecContext *avctx,
-                                int mm_flags)
+static av_cold void dsputil_init_mmxext(DSPContext *c, AVCodecContext *avctx,
+                                        int mm_flags)
 {
     const int bit_depth      = avctx->bits_per_raw_sample;
     const int high_bit_depth = bit_depth > 8;
 
-#if HAVE_INLINE_ASM
-    c->prefetch = prefetch_mmxext;
-
+#if HAVE_YASM
     SET_QPEL_FUNCS(avg_qpel,        0, 16, mmxext, );
     SET_QPEL_FUNCS(avg_qpel,        1,  8, mmxext, );
-    SET_QPEL_FUNCS(avg_2tap_qpel,   0, 16, mmxext, );
-    SET_QPEL_FUNCS(avg_2tap_qpel,   1,  8, mmxext, );
 
     SET_QPEL_FUNCS(put_qpel,        0, 16, mmxext, );
     SET_QPEL_FUNCS(put_qpel,        1,  8, mmxext, );
-    SET_QPEL_FUNCS(put_2tap_qpel,   0, 16, mmxext, );
-    SET_QPEL_FUNCS(put_2tap_qpel,   1,  8, mmxext, );
     SET_QPEL_FUNCS(put_no_rnd_qpel, 0, 16, mmxext, );
     SET_QPEL_FUNCS(put_no_rnd_qpel, 1,  8, mmxext, );
 
     if (!high_bit_depth) {
-        c->put_pixels_tab[0][1] = put_pixels16_x2_mmxext;
-        c->put_pixels_tab[0][2] = put_pixels16_y2_mmxext;
+        c->put_pixels_tab[0][1] = ff_put_pixels16_x2_mmxext;
+        c->put_pixels_tab[0][2] = ff_put_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->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->put_pixels_tab[1][1] = put_pixels8_x2_mmxext;
-        c->put_pixels_tab[1][2] = put_pixels8_y2_mmxext;
+        c->put_pixels_tab[1][1] = ff_put_pixels8_x2_mmxext;
+        c->put_pixels_tab[1][2] = ff_put_pixels8_y2_mmxext;
 
-        c->avg_pixels_tab[1][0] = avg_pixels8_mmxext;
-        c->avg_pixels_tab[1][1] = avg_pixels8_x2_mmxext;
-        c->avg_pixels_tab[1][2] = avg_pixels8_y2_mmxext;
+        c->avg_pixels_tab[1][0] = ff_avg_pixels8_mmxext;
+        c->avg_pixels_tab[1][1] = ff_avg_pixels8_x2_mmxext;
+        c->avg_pixels_tab[1][2] = ff_avg_pixels8_y2_mmxext;
     }
 
     if (!(avctx->flags & CODEC_FLAG_BITEXACT)) {
         if (!high_bit_depth) {
-            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] = put_no_rnd_pixels8_x2_mmxext;
-            c->put_no_rnd_pixels_tab[1][2] = put_no_rnd_pixels8_y2_mmxext;
+            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[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] = avg_pixels16_xy2_mmxext;
-            c->avg_pixels_tab[1][3] = avg_pixels8_xy2_mmxext;
+            c->avg_pixels_tab[0][3] = ff_avg_pixels16_xy2_mmxext;
+            c->avg_pixels_tab[1][3] = ff_avg_pixels8_xy2_mmxext;
         }
     }
-
-    if (CONFIG_VP3_DECODER && (avctx->codec_id == AV_CODEC_ID_VP3 ||
-                               avctx->codec_id == AV_CODEC_ID_THEORA)) {
-        c->put_no_rnd_pixels_tab[1][1] = put_no_rnd_pixels8_x2_exact_mmxext;
-        c->put_no_rnd_pixels_tab[1][2] = put_no_rnd_pixels8_y2_exact_mmxext;
-    }
-#endif /* HAVE_INLINE_ASM */
+#endif /* HAVE_YASM */
 
 #if HAVE_MMXEXT_EXTERNAL
-    if (CONFIG_H264QPEL) {
-        if (!high_bit_depth) {
-            SET_QPEL_FUNCS(put_h264_qpel, 0, 16, mmxext, );
-            SET_QPEL_FUNCS(put_h264_qpel, 1,  8, mmxext, );
-            SET_QPEL_FUNCS(put_h264_qpel, 2,  4, mmxext, );
-            SET_QPEL_FUNCS(avg_h264_qpel, 0, 16, mmxext, );
-            SET_QPEL_FUNCS(avg_h264_qpel, 1,  8, mmxext, );
-            SET_QPEL_FUNCS(avg_h264_qpel, 2,  4, mmxext, );
-        } else if (bit_depth == 10) {
-#if !ARCH_X86_64
-            SET_QPEL_FUNCS(avg_h264_qpel, 0, 16, 10_mmxext, ff_);
-            SET_QPEL_FUNCS(put_h264_qpel, 0, 16, 10_mmxext, ff_);
-            SET_QPEL_FUNCS(put_h264_qpel, 1,  8, 10_mmxext, ff_);
-            SET_QPEL_FUNCS(avg_h264_qpel, 1,  8, 10_mmxext, ff_);
-#endif
-            SET_QPEL_FUNCS(put_h264_qpel, 2, 4,  10_mmxext, ff_);
-            SET_QPEL_FUNCS(avg_h264_qpel, 2, 4,  10_mmxext, ff_);
-        }
-    }
-
-    if (!high_bit_depth && CONFIG_H264CHROMA) {
-        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 (bit_depth == 10 && CONFIG_H264CHROMA) {
-        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 (CONFIG_VP3_DECODER && (avctx->codec_id == AV_CODEC_ID_VP3 ||
+                               avctx->codec_id == AV_CODEC_ID_THEORA)) {
+        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;
     }
 
     /* slower than cmov version on AMD */
@@ -2527,66 +1693,48 @@
 #endif /* HAVE_MMXEXT_EXTERNAL */
 }
 
-static void dsputil_init_3dnow(DSPContext *c, AVCodecContext *avctx,
-                               int mm_flags)
+static av_cold void dsputil_init_3dnow(DSPContext *c, AVCodecContext *avctx,
+                                       int mm_flags)
 {
     const int high_bit_depth = avctx->bits_per_raw_sample > 8;
 
-#if HAVE_INLINE_ASM
-    c->prefetch = prefetch_3dnow;
-
+#if HAVE_YASM
     if (!high_bit_depth) {
-        c->put_pixels_tab[0][1] = put_pixels16_x2_3dnow;
-        c->put_pixels_tab[0][2] = put_pixels16_y2_3dnow;
+        c->put_pixels_tab[0][1] = ff_put_pixels16_x2_3dnow;
+        c->put_pixels_tab[0][2] = ff_put_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->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->put_pixels_tab[1][1] = put_pixels8_x2_3dnow;
-        c->put_pixels_tab[1][2] = put_pixels8_y2_3dnow;
+        c->put_pixels_tab[1][1] = ff_put_pixels8_x2_3dnow;
+        c->put_pixels_tab[1][2] = ff_put_pixels8_y2_3dnow;
 
-        c->avg_pixels_tab[1][0] = avg_pixels8_3dnow;
-        c->avg_pixels_tab[1][1] = avg_pixels8_x2_3dnow;
-        c->avg_pixels_tab[1][2] = avg_pixels8_y2_3dnow;
+        c->avg_pixels_tab[1][0] = ff_avg_pixels8_3dnow;
+        c->avg_pixels_tab[1][1] = ff_avg_pixels8_x2_3dnow;
+        c->avg_pixels_tab[1][2] = ff_avg_pixels8_y2_3dnow;
 
         if (!(avctx->flags & CODEC_FLAG_BITEXACT)){
-            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] = put_no_rnd_pixels8_x2_3dnow;
-            c->put_no_rnd_pixels_tab[1][2] = put_no_rnd_pixels8_y2_3dnow;
+            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[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] = avg_pixels16_xy2_3dnow;
-            c->avg_pixels_tab[1][3] = avg_pixels8_xy2_3dnow;
+            c->avg_pixels_tab[0][3] = ff_avg_pixels16_xy2_3dnow;
+            c->avg_pixels_tab[1][3] = ff_avg_pixels8_xy2_3dnow;
         }
     }
 
     if (CONFIG_VP3_DECODER && (avctx->codec_id == AV_CODEC_ID_VP3 ||
                                avctx->codec_id == AV_CODEC_ID_THEORA)) {
-        c->put_no_rnd_pixels_tab[1][1] = put_no_rnd_pixels8_x2_exact_3dnow;
-        c->put_no_rnd_pixels_tab[1][2] = put_no_rnd_pixels8_y2_exact_3dnow;
-    }
-
-    c->vorbis_inverse_coupling = vorbis_inverse_coupling_3dnow;
-#endif /* HAVE_INLINE_ASM */
-
-#if HAVE_YASM
-    if (!high_bit_depth && CONFIG_H264CHROMA) {
-        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;
+        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 */
 }
 
-static void dsputil_init_3dnowext(DSPContext *c, AVCodecContext *avctx,
-                                  int mm_flags)
-{
-#if HAVE_AMD3DNOWEXT_INLINE && HAVE_6REGS
-    c->vector_fmul_window  = vector_fmul_window_3dnowext;
-#endif
-}
-
-static void dsputil_init_sse(DSPContext *c, AVCodecContext *avctx, int mm_flags)
+static av_cold void dsputil_init_sse(DSPContext *c, AVCodecContext *avctx,
+                                     int mm_flags)
 {
     const int high_bit_depth = avctx->bits_per_raw_sample > 8;
 
@@ -2599,32 +1747,18 @@
         }
     }
 
-    c->vorbis_inverse_coupling = vorbis_inverse_coupling_sse;
-
-#if HAVE_6REGS
-    c->vector_fmul_window = vector_fmul_window_sse;
-#endif
-
     c->vector_clipf = vector_clipf_sse;
 #endif /* HAVE_INLINE_ASM */
 
 #if HAVE_YASM
-    c->vector_fmul_reverse = ff_vector_fmul_reverse_sse;
-    c->vector_fmul_add     = ff_vector_fmul_add_sse;
-
-    c->scalarproduct_float          = ff_scalarproduct_float_sse;
-    c->butterflies_float_interleave = ff_butterflies_float_interleave_sse;
-
-    if (!high_bit_depth)
-        c->emulated_edge_mc = emulated_edge_mc_sse;
-#if HAVE_INLINE_ASM
+#if HAVE_INLINE_ASM && CONFIG_VIDEODSP
     c->gmc = gmc_sse;
 #endif
 #endif /* HAVE_YASM */
 }
 
-static void dsputil_init_sse2(DSPContext *c, AVCodecContext *avctx,
-                              int mm_flags)
+static av_cold void dsputil_init_sse2(DSPContext *c, AVCodecContext *avctx,
+                                      int mm_flags)
 {
     const int bit_depth      = avctx->bits_per_raw_sample;
     const int high_bit_depth = bit_depth > 8;
@@ -2645,39 +1779,6 @@
             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;
-            if (CONFIG_H264QPEL)
-                H264_QPEL_FUNCS(0, 0, sse2);
-        }
-    }
-
-    if (!high_bit_depth && CONFIG_H264QPEL) {
-        H264_QPEL_FUNCS(0, 1, sse2);
-        H264_QPEL_FUNCS(0, 2, sse2);
-        H264_QPEL_FUNCS(0, 3, sse2);
-        H264_QPEL_FUNCS(1, 1, sse2);
-        H264_QPEL_FUNCS(1, 2, sse2);
-        H264_QPEL_FUNCS(1, 3, sse2);
-        H264_QPEL_FUNCS(2, 1, sse2);
-        H264_QPEL_FUNCS(2, 2, sse2);
-        H264_QPEL_FUNCS(2, 3, sse2);
-        H264_QPEL_FUNCS(3, 1, sse2);
-        H264_QPEL_FUNCS(3, 2, sse2);
-        H264_QPEL_FUNCS(3, 3, sse2);
-    }
-
-    if (bit_depth == 10) {
-        if (CONFIG_H264QPEL) {
-            SET_QPEL_FUNCS(put_h264_qpel, 0, 16, 10_sse2, ff_);
-            SET_QPEL_FUNCS(put_h264_qpel, 1,  8, 10_sse2, ff_);
-            SET_QPEL_FUNCS(avg_h264_qpel, 0, 16, 10_sse2, ff_);
-            SET_QPEL_FUNCS(avg_h264_qpel, 1,  8, 10_sse2, ff_);
-            H264_QPEL_FUNCS_10(1, 0, sse2_cache64);
-            H264_QPEL_FUNCS_10(2, 0, sse2_cache64);
-            H264_QPEL_FUNCS_10(3, 0, sse2_cache64);
-        }
-        if (CONFIG_H264CHROMA) {
-            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;
         }
     }
 
@@ -2697,38 +1798,10 @@
 #endif /* HAVE_SSE2_EXTERNAL */
 }
 
-static void dsputil_init_ssse3(DSPContext *c, AVCodecContext *avctx,
-                               int mm_flags)
+static av_cold void dsputil_init_ssse3(DSPContext *c, AVCodecContext *avctx,
+                                       int mm_flags)
 {
 #if HAVE_SSSE3_EXTERNAL
-    const int high_bit_depth = avctx->bits_per_raw_sample > 8;
-    const int bit_depth      = avctx->bits_per_raw_sample;
-
-    if (!high_bit_depth && CONFIG_H264QPEL) {
-        H264_QPEL_FUNCS(1, 0, ssse3);
-        H264_QPEL_FUNCS(1, 1, ssse3);
-        H264_QPEL_FUNCS(1, 2, ssse3);
-        H264_QPEL_FUNCS(1, 3, ssse3);
-        H264_QPEL_FUNCS(2, 0, ssse3);
-        H264_QPEL_FUNCS(2, 1, ssse3);
-        H264_QPEL_FUNCS(2, 2, ssse3);
-        H264_QPEL_FUNCS(2, 3, ssse3);
-        H264_QPEL_FUNCS(3, 0, ssse3);
-        H264_QPEL_FUNCS(3, 1, ssse3);
-        H264_QPEL_FUNCS(3, 2, ssse3);
-        H264_QPEL_FUNCS(3, 3, ssse3);
-    }
-    if (bit_depth == 10 && CONFIG_H264QPEL) {
-        H264_QPEL_FUNCS_10(1, 0, ssse3_cache64);
-        H264_QPEL_FUNCS_10(2, 0, ssse3_cache64);
-        H264_QPEL_FUNCS_10(3, 0, ssse3_cache64);
-    }
-    if (!high_bit_depth && CONFIG_H264CHROMA) {
-        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;
-    }
     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;
@@ -2743,40 +1816,15 @@
 #endif /* HAVE_SSSE3_EXTERNAL */
 }
 
-static void dsputil_init_sse4(DSPContext *c, AVCodecContext *avctx,
-                              int mm_flags)
+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 */
 }
 
-static void dsputil_init_avx(DSPContext *c, AVCodecContext *avctx, int mm_flags)
-{
-#if HAVE_AVX_EXTERNAL
-    const int bit_depth = avctx->bits_per_raw_sample;
-
-    if (bit_depth == 10) {
-        // AVX implies !cache64.
-        // TODO: Port cache(32|64) detection from x264.
-        if (CONFIG_H264QPEL) {
-            H264_QPEL_FUNCS_10(1, 0, sse2);
-            H264_QPEL_FUNCS_10(2, 0, sse2);
-            H264_QPEL_FUNCS_10(3, 0, sse2);
-        }
-
-        if (CONFIG_H264CHROMA) {
-            c->put_h264_chroma_pixels_tab[0] = ff_put_h264_chroma_mc8_10_avx;
-            c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_10_avx;
-        }
-    }
-    c->butterflies_float_interleave = ff_butterflies_float_interleave_avx;
-    c->vector_fmul_reverse = ff_vector_fmul_reverse_avx;
-    c->vector_fmul_add = ff_vector_fmul_add_avx;
-#endif /* HAVE_AVX_EXTERNAL */
-}
-
-void ff_dsputil_init_mmx(DSPContext *c, AVCodecContext *avctx)
+av_cold void ff_dsputil_init_mmx(DSPContext *c, AVCodecContext *avctx)
 {
     int mm_flags = av_get_cpu_flags();
 
@@ -2836,9 +1884,6 @@
     if (mm_flags & AV_CPU_FLAG_3DNOW)
         dsputil_init_3dnow(c, avctx, mm_flags);
 
-    if (mm_flags & AV_CPU_FLAG_3DNOWEXT)
-        dsputil_init_3dnowext(c, avctx, mm_flags);
-
     if (mm_flags & AV_CPU_FLAG_SSE)
         dsputil_init_sse(c, avctx, mm_flags);
 
@@ -2851,9 +1896,6 @@
     if (mm_flags & AV_CPU_FLAG_SSE4)
         dsputil_init_sse4(c, avctx, mm_flags);
 
-    if (mm_flags & AV_CPU_FLAG_AVX)
-        dsputil_init_avx(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_mmx.h
index d07ac9f..f365970 100644
--- a/libavcodec/x86/dsputil_mmx.h
+++ b/libavcodec/x86/dsputil_mmx.h
@@ -22,7 +22,9 @@
 #ifndef AVCODEC_X86_DSPUTIL_MMX_H
 #define AVCODEC_X86_DSPUTIL_MMX_H
 
+#include <stddef.h>
 #include <stdint.h>
+
 #include "libavcodec/dsputil.h"
 #include "libavutil/x86/asm.h"
 
@@ -31,8 +33,6 @@
 extern const uint64_t ff_bone;
 extern const uint64_t ff_wtwo;
 
-extern const uint64_t ff_pdw_80000000[2];
-
 extern const xmm_reg  ff_pw_3;
 extern const xmm_reg  ff_pw_4;
 extern const xmm_reg  ff_pw_5;
@@ -85,9 +85,12 @@
 void ff_dsputilenc_init_mmx(DSPContext* c, AVCodecContext *avctx);
 void ff_dsputil_init_pix_mmx(DSPContext* c, AVCodecContext *avctx);
 
-void ff_add_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size);
-void ff_put_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size);
-void ff_put_signed_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size);
+void ff_add_pixels_clamped_mmx(const int16_t *block, uint8_t *pixels, int line_size);
+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_avg_pixels8_mmxext(uint8_t *block, const uint8_t *pixels,
+                           ptrdiff_t line_size, int h);
 
 void ff_put_cavs_qpel8_mc00_mmxext(uint8_t *dst, uint8_t *src, int stride);
 void ff_avg_cavs_qpel8_mc00_mmxext(uint8_t *dst, uint8_t *src, int stride);
@@ -95,15 +98,14 @@
 void ff_avg_cavs_qpel16_mc00_mmxext(uint8_t *dst, uint8_t *src, int stride);
 
 void ff_put_vc1_mspel_mc00_mmx(uint8_t *dst, const uint8_t *src, int stride, int rnd);
-void ff_avg_vc1_mspel_mc00_mmxext(uint8_t *dst, const uint8_t *src, int stride, int rnd);
 
 void ff_put_rv40_qpel8_mc33_mmx(uint8_t *block, uint8_t *pixels, int line_size);
 void ff_put_rv40_qpel16_mc33_mmx(uint8_t *block, uint8_t *pixels, int line_size);
 void ff_avg_rv40_qpel8_mc33_mmx(uint8_t *block, uint8_t *pixels, int line_size);
 void ff_avg_rv40_qpel16_mc33_mmx(uint8_t *block, uint8_t *pixels, int line_size);
 
-void ff_mmx_idct(DCTELEM *block);
-void ff_mmxext_idct(DCTELEM *block);
+void ff_mmx_idct(int16_t *block);
+void ff_mmxext_idct(int16_t *block);
 
 
 void ff_deinterlace_line_mmx(uint8_t *dst,
diff --git a/libavcodec/x86/dsputil_rnd_template.c b/libavcodec/x86/dsputil_rnd_template.c
index e4c9138..4568207 100644
--- a/libavcodec/x86/dsputil_rnd_template.c
+++ b/libavcodec/x86/dsputil_rnd_template.c
@@ -25,7 +25,7 @@
  */
 
 // put_pixels
-static void DEF(put, pixels8_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
+static void DEF(put, pixels8_x2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
 {
     MOVQ_BFE(mm6);
     __asm__ volatile(
@@ -107,7 +107,7 @@
         :"memory");
 }
 
-static void DEF(put, pixels16_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
+static void DEF(put, pixels16_x2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
 {
     MOVQ_BFE(mm6);
     __asm__ volatile(
@@ -202,7 +202,7 @@
         :"memory");
 }
 
-static void DEF(put, pixels8_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
+static void DEF(put, pixels8_y2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
 {
     MOVQ_BFE(mm6);
     __asm__ volatile(
@@ -231,7 +231,7 @@
         :REG_a, "memory");
 }
 
-static void DEF(put, pixels8_xy2)(uint8_t *block, const uint8_t *pixels, int 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
@@ -298,7 +298,7 @@
 }
 
 // avg_pixels
-static void av_unused DEF(avg, pixels4)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
+static void av_unused DEF(avg, pixels4)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
 {
     MOVQ_BFE(mm6);
     JUMPALIGN();
@@ -317,8 +317,9 @@
     while (--h);
 }
 
+#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, int line_size, int h)
+static void DEF(avg, pixels8)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
 {
     MOVQ_BFE(mm6);
     JUMPALIGN();
@@ -336,8 +337,9 @@
     }
     while (--h);
 }
+#endif // NO_RND
 
-static void DEF(avg, pixels16)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
+static void DEF(avg, pixels16)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
 {
     MOVQ_BFE(mm6);
     JUMPALIGN();
@@ -360,7 +362,8 @@
     while (--h);
 }
 
-static void DEF(avg, pixels8_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
+#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();
@@ -379,6 +382,7 @@
         block += line_size;
     } while (--h);
 }
+#endif // NO_RND
 
 static av_unused void DEF(avg, pixels8_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
 {
@@ -401,7 +405,7 @@
     } while (--h);
 }
 
-static void DEF(avg, pixels16_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
+static void DEF(avg, pixels16_x2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
 {
     MOVQ_BFE(mm6);
     JUMPALIGN();
@@ -454,7 +458,7 @@
     } while (--h);
 }
 
-static void DEF(avg, pixels8_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
+static void DEF(avg, pixels8_y2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
 {
     MOVQ_BFE(mm6);
     __asm__ volatile(
@@ -494,7 +498,7 @@
 }
 
 // this routine is 'slightly' suboptimal but mostly unused
-static void DEF(avg, pixels8_xy2)(uint8_t *block, const uint8_t *pixels, int 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
@@ -569,22 +573,22 @@
 }
 
 //FIXME optimize
-static void DEF(put, pixels16_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){
+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(put, pixels16_xy2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){
+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_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int 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);
 }
 
-static void DEF(avg, pixels16_xy2)(uint8_t *block, const uint8_t *pixels, int line_size, int 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/dsputilenc.asm b/libavcodec/x86/dsputilenc.asm
index 3e7990d..1839bee 100644
--- a/libavcodec/x86/dsputilenc.asm
+++ b/libavcodec/x86/dsputilenc.asm
@@ -257,15 +257,12 @@
 %endmacro
 
 INIT_MMX mmx
-%define ABS1 ABS1_MMX
 HADAMARD8_DIFF
 
 INIT_MMX mmxext
-%define ABS1 ABS1_MMXEXT
 HADAMARD8_DIFF
 
 INIT_XMM sse2
-%define ABS2 ABS2_MMXEXT
 %if ARCH_X86_64
 %define ABS_SUM_8x8 ABS_SUM_8x8_64
 %else
@@ -274,7 +271,6 @@
 HADAMARD8_DIFF 10
 
 INIT_XMM ssse3
-%define ABS2        ABS2_SSSE3
 %define ABS_SUM_8x8 ABS_SUM_8x8_64
 HADAMARD8_DIFF 9
 
@@ -337,3 +333,155 @@
     paddd     m7, m1
     movd     eax, m7         ; return value
     RET
+
+INIT_MMX mmx
+; get_pixels_mmx(int16_t *block, const uint8_t *pixels, int line_size)
+cglobal get_pixels, 3,4
+    movsxdifnidn r2, r2d
+    add          r0, 128
+    mov          r3, -128
+    pxor         m7, m7
+.loop:
+    mova         m0, [r1]
+    mova         m2, [r1+r2]
+    mova         m1, m0
+    mova         m3, m2
+    punpcklbw    m0, m7
+    punpckhbw    m1, m7
+    punpcklbw    m2, m7
+    punpckhbw    m3, m7
+    mova [r0+r3+ 0], m0
+    mova [r0+r3+ 8], m1
+    mova [r0+r3+16], m2
+    mova [r0+r3+24], m3
+    lea          r1, [r1+r2*2]
+    add          r3, 32
+    js .loop
+    REP_RET
+
+INIT_XMM sse2
+cglobal get_pixels, 3, 4
+    movsxdifnidn r2, r2d
+    lea          r3, [r2*3]
+    pxor         m4, m4
+    movh         m0, [r1]
+    movh         m1, [r1+r2]
+    movh         m2, [r1+r2*2]
+    movh         m3, [r1+r3]
+    lea          r1, [r1+r2*4]
+    punpcklbw    m0, m4
+    punpcklbw    m1, m4
+    punpcklbw    m2, m4
+    punpcklbw    m3, m4
+    mova       [r0], m0
+    mova  [r0+0x10], m1
+    mova  [r0+0x20], m2
+    mova  [r0+0x30], m3
+    movh         m0, [r1]
+    movh         m1, [r1+r2*1]
+    movh         m2, [r1+r2*2]
+    movh         m3, [r1+r3]
+    punpcklbw    m0, m4
+    punpcklbw    m1, m4
+    punpcklbw    m2, m4
+    punpcklbw    m3, m4
+    mova  [r0+0x40], m0
+    mova  [r0+0x50], m1
+    mova  [r0+0x60], m2
+    mova  [r0+0x70], m3
+    RET
+
+INIT_MMX mmx
+; diff_pixels_mmx(int16_t *block, const uint8_t *s1, const unint8_t *s2, stride)
+cglobal diff_pixels, 4,5
+    movsxdifnidn r3, r3d
+    pxor         m7, m7
+    add          r0,  128
+    mov          r4, -128
+.loop:
+    mova         m0, [r1]
+    mova         m2, [r2]
+    mova         m1, m0
+    mova         m3, m2
+    punpcklbw    m0, m7
+    punpckhbw    m1, m7
+    punpcklbw    m2, m7
+    punpckhbw    m3, m7
+    psubw        m0, m2
+    psubw        m1, m3
+    mova  [r0+r4+0], m0
+    mova  [r0+r4+8], m1
+    add          r1, r3
+    add          r2, r3
+    add          r4, 16
+    jne .loop
+    REP_RET
+
+INIT_MMX mmx
+; pix_sum16_mmx(uint8_t * pix, int line_size)
+cglobal pix_sum16, 2, 3
+    movsxdifnidn r1, r1d
+    mov          r2, r1
+    neg          r2
+    shl          r2, 4
+    sub          r0, r2
+    pxor         m7, m7
+    pxor         m6, m6
+.loop:
+    mova         m0, [r0+r2+0]
+    mova         m1, [r0+r2+0]
+    mova         m2, [r0+r2+8]
+    mova         m3, [r0+r2+8]
+    punpcklbw    m0, m7
+    punpckhbw    m1, m7
+    punpcklbw    m2, m7
+    punpckhbw    m3, m7
+    paddw        m1, m0
+    paddw        m3, m2
+    paddw        m3, m1
+    paddw        m6, m3
+    add          r2, r1
+    js .loop
+    mova         m5, m6
+    psrlq        m6, 32
+    paddw        m6, m5
+    mova         m5, m6
+    psrlq        m6, 16
+    paddw        m6, m5
+    movd        eax, m6
+    and         eax, 0xffff
+    RET
+
+INIT_MMX mmx
+; pix_norm1_mmx(uint8_t *pix, int line_size)
+cglobal pix_norm1, 2, 4
+    movsxdifnidn r1, r1d
+    mov          r2, 16
+    pxor         m0, m0
+    pxor         m7, m7
+.loop:
+    mova         m2, [r0+0]
+    mova         m3, [r0+8]
+    mova         m1, m2
+    punpckhbw    m1, m0
+    punpcklbw    m2, m0
+    mova         m4, m3
+    punpckhbw    m3, m0
+    punpcklbw    m4, m0
+    pmaddwd      m1, m1
+    pmaddwd      m2, m2
+    pmaddwd      m3, m3
+    pmaddwd      m4, m4
+    paddd        m2, m1
+    paddd        m4, m3
+    paddd        m7, m2
+    add          r0, r1
+    paddd        m7, m4
+    dec r2
+    jne .loop
+    mova         m1, m7
+    psrlq        m7, 32
+    paddd        m1, m7
+    movd        eax, m1
+    RET
+
diff --git a/libavcodec/x86/dsputilenc_mmx.c b/libavcodec/x86/dsputilenc_mmx.c
index fb098ad..a3f268e 100644
--- a/libavcodec/x86/dsputilenc_mmx.c
+++ b/libavcodec/x86/dsputilenc_mmx.c
@@ -22,189 +22,24 @@
  * MMX optimization by Nick Kurshev <nickols_k@mail.ru>
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
 #include "libavutil/x86/asm.h"
 #include "libavutil/x86/cpu.h"
+#include "libavcodec/dct.h"
 #include "libavcodec/dsputil.h"
 #include "libavcodec/mpegvideo.h"
 #include "libavcodec/mathops.h"
 #include "dsputil_mmx.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);
+void ff_diff_pixels_mmx(int16_t *block, const uint8_t *s1, const uint8_t *s2, int stride);
+int ff_pix_sum16_mmx(uint8_t * pix, int line_size);
+int ff_pix_norm1_mmx(uint8_t *pix, int line_size);
 
 #if HAVE_INLINE_ASM
 
-static void get_pixels_mmx(DCTELEM *block, const uint8_t *pixels, int line_size)
-{
-    __asm__ volatile(
-        "mov $-128, %%"REG_a"           \n\t"
-        "pxor %%mm7, %%mm7              \n\t"
-        ".p2align 4                     \n\t"
-        "1:                             \n\t"
-        "movq (%0), %%mm0               \n\t"
-        "movq (%0, %2), %%mm2           \n\t"
-        "movq %%mm0, %%mm1              \n\t"
-        "movq %%mm2, %%mm3              \n\t"
-        "punpcklbw %%mm7, %%mm0         \n\t"
-        "punpckhbw %%mm7, %%mm1         \n\t"
-        "punpcklbw %%mm7, %%mm2         \n\t"
-        "punpckhbw %%mm7, %%mm3         \n\t"
-        "movq %%mm0, (%1, %%"REG_a")    \n\t"
-        "movq %%mm1, 8(%1, %%"REG_a")   \n\t"
-        "movq %%mm2, 16(%1, %%"REG_a")  \n\t"
-        "movq %%mm3, 24(%1, %%"REG_a")  \n\t"
-        "add %3, %0                     \n\t"
-        "add $32, %%"REG_a"             \n\t"
-        "js 1b                          \n\t"
-        : "+r" (pixels)
-        : "r" (block+64), "r" ((x86_reg)line_size), "r" ((x86_reg)line_size*2)
-        : "%"REG_a
-    );
-}
-
-static void get_pixels_sse2(DCTELEM *block, const uint8_t *pixels, int line_size)
-{
-    __asm__ volatile(
-        "pxor %%xmm4,      %%xmm4         \n\t"
-        "movq (%0),        %%xmm0         \n\t"
-        "movq (%0, %2),    %%xmm1         \n\t"
-        "movq (%0, %2,2),  %%xmm2         \n\t"
-        "movq (%0, %3),    %%xmm3         \n\t"
-        "lea (%0,%2,4), %0                \n\t"
-        "punpcklbw %%xmm4, %%xmm0         \n\t"
-        "punpcklbw %%xmm4, %%xmm1         \n\t"
-        "punpcklbw %%xmm4, %%xmm2         \n\t"
-        "punpcklbw %%xmm4, %%xmm3         \n\t"
-        "movdqa %%xmm0,      (%1)         \n\t"
-        "movdqa %%xmm1,    16(%1)         \n\t"
-        "movdqa %%xmm2,    32(%1)         \n\t"
-        "movdqa %%xmm3,    48(%1)         \n\t"
-        "movq (%0),        %%xmm0         \n\t"
-        "movq (%0, %2),    %%xmm1         \n\t"
-        "movq (%0, %2,2),  %%xmm2         \n\t"
-        "movq (%0, %3),    %%xmm3         \n\t"
-        "punpcklbw %%xmm4, %%xmm0         \n\t"
-        "punpcklbw %%xmm4, %%xmm1         \n\t"
-        "punpcklbw %%xmm4, %%xmm2         \n\t"
-        "punpcklbw %%xmm4, %%xmm3         \n\t"
-        "movdqa %%xmm0,    64(%1)         \n\t"
-        "movdqa %%xmm1,    80(%1)         \n\t"
-        "movdqa %%xmm2,    96(%1)         \n\t"
-        "movdqa %%xmm3,   112(%1)         \n\t"
-        : "+r" (pixels)
-        : "r" (block), "r" ((x86_reg)line_size), "r" ((x86_reg)line_size*3)
-    );
-}
-
-static inline void diff_pixels_mmx(DCTELEM *block, const uint8_t *s1, const uint8_t *s2, int stride)
-{
-    __asm__ volatile(
-        "pxor %%mm7, %%mm7              \n\t"
-        "mov $-128, %%"REG_a"           \n\t"
-        ".p2align 4                     \n\t"
-        "1:                             \n\t"
-        "movq (%0), %%mm0               \n\t"
-        "movq (%1), %%mm2               \n\t"
-        "movq %%mm0, %%mm1              \n\t"
-        "movq %%mm2, %%mm3              \n\t"
-        "punpcklbw %%mm7, %%mm0         \n\t"
-        "punpckhbw %%mm7, %%mm1         \n\t"
-        "punpcklbw %%mm7, %%mm2         \n\t"
-        "punpckhbw %%mm7, %%mm3         \n\t"
-        "psubw %%mm2, %%mm0             \n\t"
-        "psubw %%mm3, %%mm1             \n\t"
-        "movq %%mm0, (%2, %%"REG_a")    \n\t"
-        "movq %%mm1, 8(%2, %%"REG_a")   \n\t"
-        "add %3, %0                     \n\t"
-        "add %3, %1                     \n\t"
-        "add $16, %%"REG_a"             \n\t"
-        "jnz 1b                         \n\t"
-        : "+r" (s1), "+r" (s2)
-        : "r" (block+64), "r" ((x86_reg)stride)
-        : "%"REG_a
-    );
-}
-
-static int pix_sum16_mmx(uint8_t * pix, int line_size){
-    const int h=16;
-    int sum;
-    x86_reg index= -line_size*h;
-
-    __asm__ volatile(
-                "pxor %%mm7, %%mm7              \n\t"
-                "pxor %%mm6, %%mm6              \n\t"
-                "1:                             \n\t"
-                "movq (%2, %1), %%mm0           \n\t"
-                "movq (%2, %1), %%mm1           \n\t"
-                "movq 8(%2, %1), %%mm2          \n\t"
-                "movq 8(%2, %1), %%mm3          \n\t"
-                "punpcklbw %%mm7, %%mm0         \n\t"
-                "punpckhbw %%mm7, %%mm1         \n\t"
-                "punpcklbw %%mm7, %%mm2         \n\t"
-                "punpckhbw %%mm7, %%mm3         \n\t"
-                "paddw %%mm0, %%mm1             \n\t"
-                "paddw %%mm2, %%mm3             \n\t"
-                "paddw %%mm1, %%mm3             \n\t"
-                "paddw %%mm3, %%mm6             \n\t"
-                "add %3, %1                     \n\t"
-                " js 1b                         \n\t"
-                "movq %%mm6, %%mm5              \n\t"
-                "psrlq $32, %%mm6               \n\t"
-                "paddw %%mm5, %%mm6             \n\t"
-                "movq %%mm6, %%mm5              \n\t"
-                "psrlq $16, %%mm6               \n\t"
-                "paddw %%mm5, %%mm6             \n\t"
-                "movd %%mm6, %0                 \n\t"
-                "andl $0xFFFF, %0               \n\t"
-                : "=&r" (sum), "+r" (index)
-                : "r" (pix - index), "r" ((x86_reg)line_size)
-        );
-
-        return sum;
-}
-
-static int pix_norm1_mmx(uint8_t *pix, int line_size) {
-    int tmp;
-  __asm__ volatile (
-      "movl $16,%%ecx\n"
-      "pxor %%mm0,%%mm0\n"
-      "pxor %%mm7,%%mm7\n"
-      "1:\n"
-      "movq (%0),%%mm2\n"       /* mm2 = pix[0-7] */
-      "movq 8(%0),%%mm3\n"      /* mm3 = pix[8-15] */
-
-      "movq %%mm2,%%mm1\n"      /* mm1 = mm2 = pix[0-7] */
-
-      "punpckhbw %%mm0,%%mm1\n" /* mm1 = [pix4-7] */
-      "punpcklbw %%mm0,%%mm2\n" /* mm2 = [pix0-3] */
-
-      "movq %%mm3,%%mm4\n"      /* mm4 = mm3 = pix[8-15] */
-      "punpckhbw %%mm0,%%mm3\n" /* mm3 = [pix12-15] */
-      "punpcklbw %%mm0,%%mm4\n" /* mm4 = [pix8-11] */
-
-      "pmaddwd %%mm1,%%mm1\n"   /* mm1 = (pix0^2+pix1^2,pix2^2+pix3^2) */
-      "pmaddwd %%mm2,%%mm2\n"   /* mm2 = (pix4^2+pix5^2,pix6^2+pix7^2) */
-
-      "pmaddwd %%mm3,%%mm3\n"
-      "pmaddwd %%mm4,%%mm4\n"
-
-      "paddd %%mm1,%%mm2\n"     /* mm2 = (pix0^2+pix1^2+pix4^2+pix5^2,
-                                          pix2^2+pix3^2+pix6^2+pix7^2) */
-      "paddd %%mm3,%%mm4\n"
-      "paddd %%mm2,%%mm7\n"
-
-      "add %2, %0\n"
-      "paddd %%mm4,%%mm7\n"
-      "dec %%ecx\n"
-      "jnz 1b\n"
-
-      "movq %%mm7,%%mm1\n"
-      "psrlq $32, %%mm7\n"      /* shift hi dword to lo */
-      "paddd %%mm7,%%mm1\n"
-      "movd %%mm1,%1\n"
-      : "+r" (pix), "=r"(tmp) : "r" ((x86_reg)line_size) : "%ecx" );
-    return tmp;
-}
-
 static int sse8_mmx(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h) {
     int tmp;
   __asm__ volatile (
@@ -589,8 +424,8 @@
 static int vsad_intra16_mmx(void *v, uint8_t * pix, uint8_t * dummy, int line_size, int h) {
     int tmp;
 
-    assert( (((int)pix) & 7) == 0);
-    assert((line_size &7) ==0);
+    av_assert2( (((int)pix) & 7) == 0);
+    av_assert2((line_size &7) ==0);
 
 #define SUM(in0, in1, out0, out1) \
       "movq (%0), %%mm2\n"\
@@ -652,8 +487,8 @@
 {
     int tmp;
 
-    assert( (((int)pix) & 7) == 0);
-    assert((line_size &7) ==0);
+    av_assert2( (((int)pix) & 7) == 0);
+    av_assert2((line_size &7) ==0);
 
 #define SUM(in0, in1, out0, out1) \
       "movq (%0), " #out0 "\n"\
@@ -692,9 +527,9 @@
 static int vsad16_mmx(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h) {
     int tmp;
 
-    assert( (((int)pix1) & 7) == 0);
-    assert( (((int)pix2) & 7) == 0);
-    assert((line_size &7) ==0);
+    av_assert2( (((int)pix1) & 7) == 0);
+    av_assert2( (((int)pix2) & 7) == 0);
+    av_assert2((line_size &7) ==0);
 
 #define SUM(in0, in1, out0, out1) \
       "movq (%0),%%mm2\n"\
@@ -772,9 +607,9 @@
 {
     int tmp;
 
-    assert( (((int)pix1) & 7) == 0);
-    assert( (((int)pix2) & 7) == 0);
-    assert((line_size &7) ==0);
+    av_assert2( (((int)pix1) & 7) == 0);
+    av_assert2( (((int)pix2) & 7) == 0);
+    av_assert2((line_size &7) ==0);
 
 #define SUM(in0, in1, out0, out1) \
       "movq (%0)," #out0 "\n"\
@@ -965,7 +800,7 @@
     HSUM(%%xmm0, %%xmm1, %0)
 
 #define DCT_SAD_FUNC(cpu) \
-static int sum_abs_dctelem_##cpu(DCTELEM *block){\
+static int sum_abs_dctelem_##cpu(int16_t *block){\
     int sum;\
     __asm__ volatile(\
         DCT_SAD\
@@ -1109,13 +944,26 @@
 hadamard_func(sse2)
 hadamard_func(ssse3)
 
-void ff_dsputilenc_init_mmx(DSPContext* c, AVCodecContext *avctx)
+av_cold void ff_dsputilenc_init_mmx(DSPContext *c, AVCodecContext *avctx)
 {
     int mm_flags = av_get_cpu_flags();
-
-#if HAVE_INLINE_ASM
     int bit_depth = avctx->bits_per_raw_sample;
 
+#if HAVE_YASM
+    if (EXTERNAL_MMX(mm_flags)) {
+        if (bit_depth <= 8)
+            c->get_pixels = ff_get_pixels_mmx;
+        c->diff_pixels = ff_diff_pixels_mmx;
+        c->pix_sum = ff_pix_sum16_mmx;
+
+        c->pix_norm1 = ff_pix_norm1_mmx;
+    }
+    if (EXTERNAL_SSE2(mm_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) {
         const int dct_algo = avctx->dct_algo;
         if (avctx->bits_per_raw_sample <= 8 &&
@@ -1129,15 +977,10 @@
             }
         }
 
-        if (bit_depth <= 8)
-            c->get_pixels = get_pixels_mmx;
-        c->diff_pixels = diff_pixels_mmx;
-        c->pix_sum = pix_sum16_mmx;
 
         c->diff_bytes= diff_bytes_mmx;
         c->sum_abs_dctelem= sum_abs_dctelem_mmx;
 
-        c->pix_norm1 = pix_norm1_mmx;
         c->sse[0] = sse16_mmx;
         c->sse[1] = sse8_mmx;
         c->vsad[4]= vsad_intra16_mmx;
@@ -1167,8 +1010,6 @@
         }
 
         if(mm_flags & AV_CPU_FLAG_SSE2){
-            if (bit_depth <= 8)
-                c->get_pixels = get_pixels_sse2;
             c->sum_abs_dctelem= sum_abs_dctelem_sse2;
         }
 
diff --git a/libavcodec/x86/dwt_yasm.asm b/libavcodec/x86/dwt_yasm.asm
index f6280d1..5253abc 100644
--- a/libavcodec/x86/dwt_yasm.asm
+++ b/libavcodec/x86/dwt_yasm.asm
@@ -64,6 +64,9 @@
 ;                                  int width)
 cglobal vertical_compose53iL0_%1, 4,4,1, b0, b1, b2, width
     mova    m2, [pw_2]
+%if ARCH_X86_64
+    mov     widthd, widthd
+%endif
 .loop:
     sub     widthq, mmsize/2
     mova    m1, [b0q+2*widthq]
@@ -77,6 +80,9 @@
 ;                                  int width)
 cglobal vertical_compose_dirac53iH0_%1, 4,4,1, b0, b1, b2, width
     mova    m1, [pw_1]
+%if ARCH_X86_64
+    mov     widthd, widthd
+%endif
 .loop:
     sub     widthq, mmsize/2
     mova    m0, [b0q+2*widthq]
@@ -93,6 +99,9 @@
 cglobal vertical_compose_dd97iH0_%1, 6,6,5, b0, b1, b2, b3, b4, width
     mova    m3, [pw_8]
     mova    m4, [pw_1991]
+%if ARCH_X86_64
+    mov     widthd, widthd
+%endif
 .loop:
     sub     widthq, mmsize/2
     mova    m0, [b0q+2*widthq]
@@ -107,6 +116,9 @@
 cglobal vertical_compose_dd137iL0_%1, 6,6,6, b0, b1, b2, b3, b4, width
     mova    m3, [pw_16]
     mova    m4, [pw_1991]
+%if ARCH_X86_64
+    mov     widthd, widthd
+%endif
 .loop:
     sub     widthq, mmsize/2
     mova    m0, [b0q+2*widthq]
@@ -131,6 +143,9 @@
 ; void vertical_compose_haar(IDWTELEM *b0, IDWTELEM *b1, int width)
 cglobal vertical_compose_haar_%1, 3,4,3, b0, b1, width
     mova    m3, [pw_1]
+%if ARCH_X86_64
+    mov     widthd, widthd
+%endif
 .loop:
     sub     widthq, mmsize/2
     mova    m1, [b1q+2*widthq]
diff --git a/libavcodec/x86/fdct.c b/libavcodec/x86/fdct.c
index 44a3d7c..d35245d 100644
--- a/libavcodec/x86/fdct.c
+++ b/libavcodec/x86/fdct.c
@@ -32,7 +32,7 @@
 
 #include "libavutil/common.h"
 #include "libavutil/x86/asm.h"
-#include "libavcodec/dsputil.h"
+#include "libavcodec/dct.h"
 
 #if HAVE_INLINE_ASM
 
diff --git a/libavcodec/x86/fft_init.c b/libavcodec/x86/fft_init.c
index a9d9579..bfa7947 100644
--- a/libavcodec/x86/fft_init.c
+++ b/libavcodec/x86/fft_init.c
@@ -18,7 +18,6 @@
 
 #include "libavutil/cpu.h"
 #include "libavutil/x86/cpu.h"
-#include "libavcodec/dsputil.h"
 #include "libavcodec/dct.h"
 #include "fft.h"
 
diff --git a/libavcodec/x86/fmtconvert_init.c b/libavcodec/x86/fmtconvert_init.c
index 528b7b1..4a4c017 100644
--- a/libavcodec/x86/fmtconvert_init.c
+++ b/libavcodec/x86/fmtconvert_init.c
@@ -22,11 +22,11 @@
  * MMX optimization by Nick Kurshev <nickols_k@mail.ru>
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
 #include "libavutil/x86/asm.h"
 #include "libavutil/x86/cpu.h"
 #include "libavcodec/fmtconvert.h"
-#include "libavcodec/dsputil.h"
 
 #if HAVE_YASM
 
@@ -113,7 +113,7 @@
 }
 #endif /* HAVE_YASM */
 
-void ff_fmt_convert_init_x86(FmtConvertContext *c, AVCodecContext *avctx)
+av_cold void ff_fmt_convert_init_x86(FmtConvertContext *c, AVCodecContext *avctx)
 {
 #if HAVE_YASM
     int mm_flags = av_get_cpu_flags();
diff --git a/libavcodec/x86/h263_loopfilter.asm b/libavcodec/x86/h263_loopfilter.asm
new file mode 100644
index 0000000..a21baf1
--- /dev/null
+++ b/libavcodec/x86/h263_loopfilter.asm
@@ -0,0 +1,189 @@
+;******************************************************************************
+;* MMX-optimized H.263 loop filter
+;* Copyright (c) 2003-2013 Michael Niedermayer
+;* Copyright (c) 2013 Daniel Kang
+;*
+;* 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/x86/x86util.asm"
+
+SECTION_RODATA
+cextern pb_FC
+cextern h263_loop_filter_strength
+
+SECTION_TEXT
+
+%macro H263_LOOP_FILTER 5
+    pxor         m7, m7
+    mova         m0, [%1]
+    mova         m1, [%1]
+    mova         m2, [%4]
+    mova         m3, [%4]
+    punpcklbw    m0, m7
+    punpckhbw    m1, m7
+    punpcklbw    m2, m7
+    punpckhbw    m3, m7
+    psubw        m0, m2
+    psubw        m1, m3
+    mova         m2, [%2]
+    mova         m3, [%2]
+    mova         m4, [%3]
+    mova         m5, [%3]
+    punpcklbw    m2, m7
+    punpckhbw    m3, m7
+    punpcklbw    m4, m7
+    punpckhbw    m5, m7
+    psubw        m4, m2
+    psubw        m5, m3
+    psllw        m4, 2
+    psllw        m5, 2
+    paddw        m4, m0
+    paddw        m5, m1
+    pxor         m6, m6
+    pcmpgtw      m6, m4
+    pcmpgtw      m7, m5
+    pxor         m4, m6
+    pxor         m5, m7
+    psubw        m4, m6
+    psubw        m5, m7
+    psrlw        m4, 3
+    psrlw        m5, 3
+    packuswb     m4, m5
+    packsswb     m6, m7
+    pxor         m7, m7
+    movd         m2, %5
+    punpcklbw    m2, m2
+    punpcklbw    m2, m2
+    punpcklbw    m2, m2
+    psubusb      m2, m4
+    mova         m3, m2
+    psubusb      m3, m4
+    psubb        m2, m3
+    mova         m3, [%2]
+    mova         m4, [%3]
+    pxor         m3, m6
+    pxor         m4, m6
+    paddusb      m3, m2
+    psubusb      m4, m2
+    pxor         m3, m6
+    pxor         m4, m6
+    paddusb      m2, m2
+    packsswb     m0, m1
+    pcmpgtb      m7, m0
+    pxor         m0, m7
+    psubb        m0, m7
+    mova         m1, m0
+    psubusb      m0, m2
+    psubb        m1, m0
+    pand         m1, [pb_FC]
+    psrlw        m1, 2
+    pxor         m1, m7
+    psubb        m1, m7
+    mova         m5, [%1]
+    mova         m6, [%4]
+    psubb        m5, m1
+    paddb        m6, m1
+%endmacro
+
+INIT_MMX mmx
+; void h263_v_loop_filter(uint8_t *src, int stride, int qscale)
+cglobal h263_v_loop_filter, 3,5
+    movsxdifnidn r1, r1d
+    movsxdifnidn r2, r2d
+
+    lea          r4, [h263_loop_filter_strength]
+    movzx       r3d, BYTE [r4+r2]
+    movsx        r2, r3b
+    shl          r2, 1
+
+    mov          r3, r0
+    sub          r3, r1
+    mov          r4, r3
+    sub          r4, r1
+    H263_LOOP_FILTER r4, r3, r0, r0+r1, r2d
+
+    mova       [r3], m3
+    mova       [r0], m4
+    mova       [r4], m5
+    mova    [r0+r1], m6
+    RET
+
+%macro TRANSPOSE4X4 2
+    movd      m0, [%1]
+    movd      m1, [%1+r1]
+    movd      m2, [%1+r1*2]
+    movd      m3, [%1+r3]
+    punpcklbw m0, m1
+    punpcklbw m2, m3
+    mova      m1, m0
+    punpcklwd m0, m2
+    punpckhwd m1, m2
+    movd [%2+ 0], m0
+    punpckhdq m0, m0
+    movd [%2+ 8], m0
+    movd [%2+16], m1
+    punpckhdq m1, m1
+    movd [%2+24], m1
+%endmacro
+
+
+; void h263_h_loop_filter(uint8_t *src, int stride, int qscale)
+INIT_MMX mmx
+cglobal h263_h_loop_filter, 3,5,0,32
+    movsxdifnidn r1, r1d
+    movsxdifnidn r2, r2d
+
+    lea          r4, [h263_loop_filter_strength]
+    movzx       r3d, BYTE [r4+r2]
+    movsx        r2, r3b
+    shl          r2, 1
+
+    sub          r0, 2
+    lea          r3, [r1*3]
+
+    TRANSPOSE4X4 r0, rsp
+    lea          r4, [r0+r1*4]
+    TRANSPOSE4X4 r4, rsp+4
+
+    H263_LOOP_FILTER rsp, rsp+8, rsp+16, rsp+24, r2d
+
+    mova         m1, m5
+    mova         m0, m4
+    punpcklbw    m5, m3
+    punpcklbw    m4, m6
+    punpckhbw    m1, m3
+    punpckhbw    m0, m6
+    mova         m3, m5
+    mova         m6, m1
+    punpcklwd    m5, m4
+    punpcklwd    m1, m0
+    punpckhwd    m3, m4
+    punpckhwd    m6, m0
+    movd       [r0], m5
+    punpckhdq    m5, m5
+    movd  [r0+r1*1], m5
+    movd  [r0+r1*2], m3
+    punpckhdq    m3, m3
+    movd    [r0+r3], m3
+    movd       [r4], m1
+    punpckhdq    m1, m1
+    movd  [r4+r1*1], m1
+    movd  [r4+r1*2], m6
+    punpckhdq    m6, m6
+    movd    [r4+r3], m6
+    RET
diff --git a/libavcodec/x86/h264_chromamc.asm b/libavcodec/x86/h264_chromamc.asm
index 7f5be75..867ba49 100644
--- a/libavcodec/x86/h264_chromamc.asm
+++ b/libavcodec/x86/h264_chromamc.asm
@@ -427,11 +427,11 @@
 %macro NOTHING 2-3
 %endmacro
 %macro DIRECT_AVG 2
-    PAVG          %1, %2
+    PAVGB         %1, %2
 %endmacro
 %macro COPY_AVG 3
     movd          %2, %3
-    PAVG          %1, %2
+    PAVGB         %1, %2
 %endmacro
 
 INIT_MMX mmx
@@ -448,7 +448,6 @@
 
 %define CHROMAMC_AVG  DIRECT_AVG
 %define CHROMAMC_AVG4 COPY_AVG
-%define PAVG          pavgb
 chroma_mc8_mmx_func avg, h264, _rnd
 chroma_mc8_mmx_func avg, vc1,  _nornd
 chroma_mc8_mmx_func avg, rv40
@@ -456,7 +455,6 @@
 chroma_mc4_mmx_func avg, rv40
 chroma_mc2_mmx_func avg, h264
 
-%define PAVG          pavgusb
 INIT_MMX 3dnow
 chroma_mc8_mmx_func avg, h264, _rnd
 chroma_mc8_mmx_func avg, vc1,  _nornd
@@ -673,7 +671,6 @@
 chroma_mc4_ssse3_func put, h264
 
 %define CHROMAMC_AVG DIRECT_AVG
-%define PAVG         pavgb
 INIT_XMM ssse3
 chroma_mc8_ssse3_func avg, h264, _rnd
 chroma_mc8_ssse3_func avg, vc1,  _nornd
diff --git a/libavcodec/x86/h264_deblock.asm b/libavcodec/x86/h264_deblock.asm
index 749fc7b..5f2374d 100644
--- a/libavcodec/x86/h264_deblock.asm
+++ b/libavcodec/x86/h264_deblock.asm
@@ -400,7 +400,7 @@
 ;-----------------------------------------------------------------------------
 ; void deblock_v8_luma( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
 ;-----------------------------------------------------------------------------
-cglobal deblock_%1_luma_8, 5, 6 - HAVE_ALIGNED_STACK, 0, 2 * %2
+cglobal deblock_%1_luma_8, 5,5,8,2*%2
     lea     r4, [r1*3]
     dec     r2     ; alpha-1
     neg     r4
@@ -449,24 +449,22 @@
 ; void deblock_h_luma( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
 ;-----------------------------------------------------------------------------
 INIT_MMX cpuname
-cglobal deblock_h_luma_8, 0,6 - HAVE_ALIGNED_STACK, 0, 0x60
+cglobal deblock_h_luma_8, 0,5,8,0x60+HAVE_ALIGNED_STACK*12
     mov    r0, r0mp
     mov    r3, r1m
     lea    r4, [r3*3]
     sub    r0, 4
     lea    r1, [r0+r4]
+%define pix_tmp esp+12*HAVE_ALIGNED_STACK
 
     ; transpose 6x16 -> tmp space
-    TRANSPOSE6x8_MEM  PASS8ROWS(r0, r1, r3, r4), esp
+    TRANSPOSE6x8_MEM  PASS8ROWS(r0, r1, r3, r4), pix_tmp
     lea    r0, [r0+r3*8]
     lea    r1, [r1+r3*8]
-    TRANSPOSE6x8_MEM  PASS8ROWS(r0, r1, r3, r4), esp+8
+    TRANSPOSE6x8_MEM  PASS8ROWS(r0, r1, r3, r4), pix_tmp+8
 
     ; vertical filter
-    lea    r0, [esp+0x30]
-%if HAVE_ALIGNED_STACK
-    SUB    esp, 12
-%endif
+    lea    r0, [pix_tmp+0x30]
     PUSH   dword r4m
     PUSH   dword r3m
     PUSH   dword r2m
@@ -474,29 +472,29 @@
     PUSH   dword r0
     call   deblock_%1_luma_8
 %ifidn %1, v8
-    add    dword [esp   ], 8 ; esp+0x38
+    add    dword [esp   ], 8 ; pix_tmp+0x38
     add    dword [esp+16], 2 ; tc0+2
     call   deblock_%1_luma_8
 %endif
-    ADD    esp, 20 + HAVE_ALIGNED_STACK * 12
+    ADD    esp, 20
 
     ; transpose 16x4 -> original space  (only the middle 4 rows were changed by the filter)
     mov    r0, r0mp
     sub    r0, 2
 
-    movq   m0, [esp+0x10]
-    movq   m1, [esp+0x20]
+    movq   m0, [pix_tmp+0x10]
+    movq   m1, [pix_tmp+0x20]
     lea    r1, [r0+r4]
-    movq   m2, [esp+0x30]
-    movq   m3, [esp+0x40]
+    movq   m2, [pix_tmp+0x30]
+    movq   m3, [pix_tmp+0x40]
     TRANSPOSE8x4B_STORE  PASS8ROWS(r0, r1, r3, r4)
 
     lea    r0, [r0+r3*8]
     lea    r1, [r1+r3*8]
-    movq   m0, [esp+0x18]
-    movq   m1, [esp+0x28]
-    movq   m2, [esp+0x38]
-    movq   m3, [esp+0x48]
+    movq   m0, [pix_tmp+0x18]
+    movq   m1, [pix_tmp+0x28]
+    movq   m2, [pix_tmp+0x38]
+    movq   m3, [pix_tmp+0x48]
     TRANSPOSE8x4B_STORE  PASS8ROWS(r0, r1, r3, r4)
 
     RET
@@ -651,9 +649,9 @@
 ; void deblock_v_luma_intra( uint8_t *pix, int stride, int alpha, int beta )
 ;-----------------------------------------------------------------------------
 %if WIN64
-cglobal deblock_%1_luma_intra_8, 4, 6, 16, 0x10
+cglobal deblock_%1_luma_intra_8, 4,6,16,0x10
 %else
-cglobal deblock_%1_luma_intra_8, 4, 6, 16, ARCH_X86_32 * 0x50
+cglobal deblock_%1_luma_intra_8, 4,6,16,ARCH_X86_64*0x50-0x50
 %endif
     lea     r4, [r1*4]
     lea     r5, [r1*3] ; 3*stride
@@ -739,7 +737,7 @@
     add    rsp, 0x88
     RET
 %else
-cglobal deblock_h_luma_intra_8, 2, 5 - HAVE_ALIGNED_STACK, 0, 0x80
+cglobal deblock_h_luma_intra_8, 2,4,8,0x80
     lea    r3,  [r1*3]
     sub    r0,  4
     lea    r2,  [r0+r3]
diff --git a/libavcodec/x86/h264_idct.asm b/libavcodec/x86/h264_idct.asm
index d0ac0fe..7bb1653 100644
--- a/libavcodec/x86/h264_idct.asm
+++ b/libavcodec/x86/h264_idct.asm
@@ -70,6 +70,10 @@
     paddw        m0, m6
     IDCT4_1D      w, 0, 1, 2, 3, 4, 5
     pxor         m7, m7
+    movq    [%2+ 0], m7
+    movq    [%2+ 8], m7
+    movq    [%2+16], m7
+    movq    [%2+24], m7
 
     STORE_DIFFx2 m0, m1, m4, m5, m7, 6, %1, %3
     lea          %1, [%1+%3*2]
@@ -161,13 +165,31 @@
 %endmacro
 
 ; %1=uint8_t *dst, %2=int16_t *block, %3=int stride
-%macro IDCT8_ADD_MMX_END 3
+%macro IDCT8_ADD_MMX_END 3-4
     IDCT8_1D_FULL %2
     mova    [%2   ], m5
     mova    [%2+16], m6
     mova    [%2+32], m7
 
     pxor         m7, m7
+%if %0 == 4
+    movq   [%4+  0], m7
+    movq   [%4+  8], m7
+    movq   [%4+ 16], m7
+    movq   [%4+ 24], m7
+    movq   [%4+ 32], m7
+    movq   [%4+ 40], m7
+    movq   [%4+ 48], m7
+    movq   [%4+ 56], m7
+    movq   [%4+ 64], m7
+    movq   [%4+ 72], m7
+    movq   [%4+ 80], m7
+    movq   [%4+ 88], m7
+    movq   [%4+ 96], m7
+    movq   [%4+104], m7
+    movq   [%4+112], m7
+    movq   [%4+120], m7
+%endif
     STORE_DIFFx2 m0, m1, m5, m6, m7, 6, %1, %3
     lea          %1, [%1+%3*2]
     STORE_DIFFx2 m2, m3, m5, m6, m7, 6, %1, %3
@@ -190,7 +212,7 @@
     IDCT8_ADD_MMX_START r1  , rsp
     IDCT8_ADD_MMX_START r1+8, rsp+64
     lea          r3, [r0+4]
-    IDCT8_ADD_MMX_END   r0  , rsp,   r2
+    IDCT8_ADD_MMX_END   r0  , rsp,   r2, r1
     IDCT8_ADD_MMX_END   r3  , rsp+8, r2
 
     ADD         rsp, pad
@@ -233,6 +255,14 @@
     SWAP          0, 8
     SWAP          1, 9
 %endif
+    mova   [%2+  0], m7
+    mova   [%2+ 16], m7
+    mova   [%2+ 32], m7
+    mova   [%2+ 48], m7
+    mova   [%2+ 64], m7
+    mova   [%2+ 80], m7
+    mova   [%2+ 96], m7
+    mova   [%2+112], m7
     lea          %1, [%1+%3*4]
     STORE_DIFF   m4, m6, m7, [%1     ]
     STORE_DIFF   m5, m6, m7, [%1+%3  ]
@@ -246,19 +276,11 @@
     IDCT8_ADD_SSE r0, r1, r2, r3
     RET
 
-%macro DC_ADD_MMXEXT_INIT 2-3
-%if %0 == 2
-    movsx        %1, word [%1]
+%macro DC_ADD_MMXEXT_INIT 2
     add          %1, 32
     sar          %1, 6
     movd         m0, %1d
     lea          %1, [%2*3]
-%else
-    add          %3, 32
-    sar          %3, 6
-    movd         m0, %3d
-    lea          %3, [%2*3]
-%endif
     pshufw       m0, m0, 0
     pxor         m1, m1
     psubw        m1, m0
@@ -287,22 +309,47 @@
 
 INIT_MMX mmxext
 ; ff_h264_idct_dc_add_mmxext(uint8_t *dst, int16_t *block, int stride)
-cglobal h264_idct_dc_add_8, 3, 3, 0
-    DC_ADD_MMXEXT_INIT r1, r2
-    DC_ADD_MMXEXT_OP movh, r0, r2, r1
+%if ARCH_X86_64
+cglobal h264_idct_dc_add_8, 3, 4, 0
+    movsx        r3, word [r1]
+    mov   word [r1], 0
+    DC_ADD_MMXEXT_INIT r3, r2
+    DC_ADD_MMXEXT_OP movh, r0, r2, r3
     RET
 
 ; ff_h264_idct8_dc_add_mmxext(uint8_t *dst, int16_t *block, int stride)
-cglobal h264_idct8_dc_add_8, 3, 3, 0
-    DC_ADD_MMXEXT_INIT r1, r2
-    DC_ADD_MMXEXT_OP mova, r0, r2, r1
+cglobal h264_idct8_dc_add_8, 3, 4, 0
+    movsx        r3, word [r1]
+    mov   word [r1], 0
+    DC_ADD_MMXEXT_INIT r3, r2
+    DC_ADD_MMXEXT_OP mova, r0, r2, r3
     lea          r0, [r0+r2*4]
-    DC_ADD_MMXEXT_OP mova, r0, r2, r1
+    DC_ADD_MMXEXT_OP mova, r0, r2, r3
     RET
+%else
+cglobal h264_idct_dc_add_8, 2, 3, 0
+    movsx        r2, word [r1]
+    mov   word [r1], 0
+    mov          r1, r2m
+    DC_ADD_MMXEXT_INIT r2, r1
+    DC_ADD_MMXEXT_OP movh, r0, r1, r2
+    RET
+
+; ff_h264_idct8_dc_add_mmxext(uint8_t *dst, int16_t *block, int stride)
+cglobal h264_idct8_dc_add_8, 2, 3, 0
+    movsx        r2, word [r1]
+    mov   word [r1], 0
+    mov          r1, r2m
+    DC_ADD_MMXEXT_INIT r2, r1
+    DC_ADD_MMXEXT_OP mova, r0, r1, r2
+    lea          r0, [r0+r1*4]
+    DC_ADD_MMXEXT_OP mova, r0, r1, r2
+    RET
+%endif
 
 INIT_MMX mmx
 ; ff_h264_idct_add16_mmx(uint8_t *dst, const int *block_offset,
-;             DCTELEM *block, int stride, const uint8_t nnzc[6*8])
+;             int16_t *block, int stride, const uint8_t nnzc[6*8])
 cglobal h264_idct_add16_8, 5, 7 + npicregs, 0, dst, block_offset, block, stride, nnzc, cntr, coeff, picreg
     xor          r5, r5
 %ifdef PIC
@@ -324,7 +371,7 @@
     REP_RET
 
 ; ff_h264_idct8_add4_mmx(uint8_t *dst, const int *block_offset,
-;                        DCTELEM *block, int stride, const uint8_t nnzc[6*8])
+;                        int16_t *block, int stride, const uint8_t nnzc[6*8])
 cglobal h264_idct8_add4_8, 5, 7 + npicregs, 0, dst, block_offset, block, stride, nnzc, cntr, coeff, picreg
     %assign pad 128+4-(stack_offset&7)
     SUB         rsp, pad
@@ -343,7 +390,7 @@
     add   word [r2], 32
     IDCT8_ADD_MMX_START r2  , rsp
     IDCT8_ADD_MMX_START r2+8, rsp+64
-    IDCT8_ADD_MMX_END   r6  , rsp,   r3
+    IDCT8_ADD_MMX_END   r6  , rsp,   r3, r2
     mov         r6d, dword [r1+r5*4]
     lea          r6, [r0+r6+4]
     IDCT8_ADD_MMX_END   r6  , rsp+8, r3
@@ -357,7 +404,7 @@
 
 INIT_MMX mmxext
 ; ff_h264_idct_add16_mmxext(uint8_t *dst, const int *block_offset,
-;                           DCTELEM *block, int stride, const uint8_t nnzc[6*8])
+;                           int16_t *block, int stride, const uint8_t nnzc[6*8])
 cglobal h264_idct_add16_8, 5, 8 + npicregs, 0, dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg
     xor          r5, r5
 %ifdef PIC
@@ -373,7 +420,8 @@
     movsx        r6, word [r2]
     test         r6, r6
     jz .no_dc
-    DC_ADD_MMXEXT_INIT r2, r3, r6
+    mov   word [r2], 0
+    DC_ADD_MMXEXT_INIT r6, r3
 %if ARCH_X86_64 == 0
 %define dst2q r1
 %define dst2d r1d
@@ -402,7 +450,7 @@
 
 INIT_MMX mmx
 ; ff_h264_idct_add16intra_mmx(uint8_t *dst, const int *block_offset,
-;                             DCTELEM *block, int stride, const uint8_t nnzc[6*8])
+;                             int16_t *block, int stride, const uint8_t nnzc[6*8])
 cglobal h264_idct_add16intra_8, 5, 7 + npicregs, 0, dst, block_offset, block, stride, nnzc, cntr, coeff, picreg
     xor          r5, r5
 %ifdef PIC
@@ -426,7 +474,7 @@
 
 INIT_MMX mmxext
 ; ff_h264_idct_add16intra_mmxext(uint8_t *dst, const int *block_offset,
-;                                DCTELEM *block, int stride,
+;                                int16_t *block, int stride,
 ;                                const uint8_t nnzc[6*8])
 cglobal h264_idct_add16intra_8, 5, 8 + npicregs, 0, dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg
     xor          r5, r5
@@ -450,7 +498,8 @@
     movsx        r6, word [r2]
     test         r6, r6
     jz .skipblock
-    DC_ADD_MMXEXT_INIT r2, r3, r6
+    mov   word [r2], 0
+    DC_ADD_MMXEXT_INIT r6, r3
 %if ARCH_X86_64 == 0
 %define dst2q r1
 %define dst2d r1d
@@ -469,7 +518,7 @@
     REP_RET
 
 ; ff_h264_idct8_add4_mmxext(uint8_t *dst, const int *block_offset,
-;                           DCTELEM *block, int stride,
+;                           int16_t *block, int stride,
 ;                           const uint8_t nnzc[6*8])
 cglobal h264_idct8_add4_8, 5, 8 + npicregs, 0, dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg
     %assign pad 128+4-(stack_offset&7)
@@ -489,7 +538,8 @@
     movsx        r6, word [r2]
     test         r6, r6
     jz .no_dc
-    DC_ADD_MMXEXT_INIT r2, r3, r6
+    mov   word [r2], 0
+    DC_ADD_MMXEXT_INIT r6, r3
 %if ARCH_X86_64 == 0
 %define dst2q r1
 %define dst2d r1d
@@ -515,7 +565,7 @@
     add   word [r2], 32
     IDCT8_ADD_MMX_START r2  , rsp
     IDCT8_ADD_MMX_START r2+8, rsp+64
-    IDCT8_ADD_MMX_END   r6  , rsp,   r3
+    IDCT8_ADD_MMX_END   r6  , rsp,   r3, r2
     mov         r6d, dword [r1+r5*4]
     lea          r6, [r0+r6+4]
     IDCT8_ADD_MMX_END   r6  , rsp+8, r3
@@ -530,7 +580,7 @@
 
 INIT_XMM sse2
 ; ff_h264_idct8_add4_sse2(uint8_t *dst, const int *block_offset,
-;                         DCTELEM *block, int stride, const uint8_t nnzc[6*8])
+;                         int16_t *block, int stride, const uint8_t nnzc[6*8])
 cglobal h264_idct8_add4_8, 5, 8 + npicregs, 10, dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg
     xor          r5, r5
 %ifdef PIC
@@ -547,7 +597,8 @@
     test         r6, r6
     jz .no_dc
 INIT_MMX cpuname
-    DC_ADD_MMXEXT_INIT r2, r3, r6
+    mov   word [r2], 0
+    DC_ADD_MMXEXT_INIT r6, r3
 %if ARCH_X86_64 == 0
 %define dst2q r1
 %define dst2d r1d
@@ -605,7 +656,7 @@
     rep ret
 
 ; ff_h264_idct_add8_mmx(uint8_t **dest, const int *block_offset,
-;                       DCTELEM *block, int stride, const uint8_t nnzc[6*8])
+;                       int16_t *block, int stride, const uint8_t nnzc[6*8])
 cglobal h264_idct_add8_8, 5, 8 + npicregs, 0, dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg
     mov          r5, 16
     add          r2, 512
@@ -650,7 +701,8 @@
     movsx        r6, word [r2]
     test         r6, r6
     jz .skipblock
-    DC_ADD_MMXEXT_INIT r2, r3, r6
+    mov   word [r2], 0
+    DC_ADD_MMXEXT_INIT r6, r3
 %if ARCH_X86_64
     mov         r0d, dword [r1+r5*4]
     add          r0, [dst2q]
@@ -669,7 +721,7 @@
 
 INIT_MMX mmxext
 ; ff_h264_idct_add8_mmxext(uint8_t **dest, const int *block_offset,
-;                          DCTELEM *block, int stride, const uint8_t nnzc[6*8])
+;                          int16_t *block, int stride, const uint8_t nnzc[6*8])
 cglobal h264_idct_add8_8, 5, 8 + npicregs, 0, dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg
     mov          r5, 16
     add          r2, 512
@@ -693,7 +745,9 @@
 ; r0 = uint8_t *dst, r2 = int16_t *block, r3 = int stride, r6=clobbered
 h264_idct_dc_add8_mmxext:
     movd         m0, [r2   ]          ;  0 0 X D
+    mov word [r2+ 0], 0
     punpcklwd    m0, [r2+32]          ;  x X d D
+    mov word [r2+32], 0
     paddsw       m0, [pw_32]
     psraw        m0, 6
     punpcklwd    m0, m0               ;  d d D D
@@ -723,6 +777,10 @@
     paddw m0, [pw_32]
     IDCT4_1D w,0,1,2,3,4,5
     pxor  m7, m7
+    mova [r2+ 0], m7
+    mova [r2+16], m7
+    mova [r2+32], m7
+    mova [r2+48], m7
     STORE_DIFFx2 m0, m1, m4, m5, m7, 6, r0, r3
     lea   r0, [r0+r3*2]
     STORE_DIFFx2 m2, m3, m4, m5, m7, 6, r0, r3
@@ -746,7 +804,7 @@
 %endmacro
 
 ; ff_h264_idct_add16_sse2(uint8_t *dst, const int *block_offset,
-;                         DCTELEM *block, int stride, const uint8_t nnzc[6*8])
+;                         int16_t *block, int stride, const uint8_t nnzc[6*8])
 cglobal h264_idct_add16_8, 5, 5 + ARCH_X86_64, 8
 %if ARCH_X86_64
     mov         r5, r0
@@ -793,7 +851,7 @@
 %endmacro
 
 ; ff_h264_idct_add16intra_sse2(uint8_t *dst, const int *block_offset,
-;                              DCTELEM *block, int stride, const uint8_t nnzc[6*8])
+;                              int16_t *block, int stride, const uint8_t nnzc[6*8])
 cglobal h264_idct_add16intra_8, 5, 7 + ARCH_X86_64, 8
 %if ARCH_X86_64
     mov         r7, r0
@@ -844,7 +902,7 @@
 %endmacro
 
 ; ff_h264_idct_add8_sse2(uint8_t **dest, const int *block_offset,
-;                        DCTELEM *block, int stride, const uint8_t nnzc[6*8])
+;                        int16_t *block, int stride, const uint8_t nnzc[6*8])
 cglobal h264_idct_add8_8, 5, 7 + ARCH_X86_64, 8
     add          r2, 512
 %if ARCH_X86_64
@@ -861,7 +919,7 @@
     add8_sse2_cycle 3, 0x64
     RET
 
-;void ff_h264_luma_dc_dequant_idct_mmx(DCTELEM *output, DCTELEM *input, int qmul)
+;void ff_h264_luma_dc_dequant_idct_mmx(int16_t *output, int16_t *input, int qmul)
 
 %macro WALSH4_1D 5
     SUMSUB_BADC w, %4, %3, %2, %1, %5
diff --git a/libavcodec/x86/h264_idct_10bit.asm b/libavcodec/x86/h264_idct_10bit.asm
index eb375f9..88fdb84 100644
--- a/libavcodec/x86/h264_idct_10bit.asm
+++ b/libavcodec/x86/h264_idct_10bit.asm
@@ -66,6 +66,10 @@
     paddd m0, [pd_32]
     IDCT4_1D d,0,1,2,3,4,5
     pxor  m5, m5
+    mova [%2+ 0], m5
+    mova [%2+16], m5
+    mova [%2+32], m5
+    mova [%2+48], m5
     STORE_DIFFx2 m0, m1, m4, m5, %1, %3
     lea   %1, [%1+%3*2]
     STORE_DIFFx2 m2, m3, m4, m5, %1, %3
@@ -100,6 +104,10 @@
     paddd m0, [pd_32]
     IDCT4_1D d,0,1,2,3,4,5
     pxor  m5, m5
+    mova  [r2+ 0], m5
+    mova  [r2+16], m5
+    mova  [r2+32], m5
+    mova  [r2+48], m5
     STORE_DIFFx2 m0, m1, m4, m5, r5, r3
     lea   r5, [r5+r3*2]
     STORE_DIFFx2 m2, m3, m4, m5, r5, r3
@@ -187,6 +195,7 @@
 INIT_MMX mmxext
 cglobal h264_idct_dc_add_10,3,3
     movd      m0, [r1]
+    mov dword [r1], 0
     paddd     m0, [pd_32]
     psrad     m0, 6
     lea       r1, [r2*3]
@@ -199,11 +208,11 @@
 ; void h264_idct8_dc_add(pixel *dst, dctcoef *block, int stride)
 ;-----------------------------------------------------------------------------
 %macro IDCT8_DC_ADD 0
-cglobal h264_idct8_dc_add_10,3,3,7
-    mov      r1d, [r1]
-    add       r1, 32
-    sar       r1, 6
-    movd      m0, r1d
+cglobal h264_idct8_dc_add_10,3,4,7
+    movd      m0, [r1]
+    mov dword[r1], 0
+    paddd     m0, [pd_32]
+    psrad     m0, 6
     lea       r1, [r2*3]
     SPLATW    m0, m0, 0
     mova      m6, [pw_pixel_max]
@@ -255,6 +264,8 @@
     add       r5, r0
     movq      m0, [r2+ 0]
     movhps    m0, [r2+64]
+    mov dword [r2+ 0], 0
+    mov dword [r2+64], 0
     paddd     m0, [pd_32]
     psrad     m0, 6
     pshufhw   m0, m0, 0
@@ -473,6 +484,22 @@
     packssdw      m8, m0
     paddsw        m8, [r0]
     pxor          m0, m0
+    mova    [r1+  0], m0
+    mova    [r1+ 16], m0
+    mova    [r1+ 32], m0
+    mova    [r1+ 48], m0
+    mova    [r1+ 64], m0
+    mova    [r1+ 80], m0
+    mova    [r1+ 96], m0
+    mova    [r1+112], m0
+    mova    [r1+128], m0
+    mova    [r1+144], m0
+    mova    [r1+160], m0
+    mova    [r1+176], m0
+    mova    [r1+192], m0
+    mova    [r1+208], m0
+    mova    [r1+224], m0
+    mova    [r1+240], m0
     CLIPW         m8, m0, [pw_pixel_max]
     mova        [r0], m8
     mova          m8, [pw_pixel_max]
@@ -492,6 +519,22 @@
     lea           r3, [r0+8]
     IDCT8_ADD_SSE_END r0, rsp,    r2
     IDCT8_ADD_SSE_END r3, rsp+16, r2
+    mova    [r1+  0], m7
+    mova    [r1+ 16], m7
+    mova    [r1+ 32], m7
+    mova    [r1+ 48], m7
+    mova    [r1+ 64], m7
+    mova    [r1+ 80], m7
+    mova    [r1+ 96], m7
+    mova    [r1+112], m7
+    mova    [r1+128], m7
+    mova    [r1+144], m7
+    mova    [r1+160], m7
+    mova    [r1+176], m7
+    mova    [r1+192], m7
+    mova    [r1+208], m7
+    mova    [r1+224], m7
+    mova    [r1+240], m7
 %endif ; ARCH_X86_64
 
     add          rsp, pad
diff --git a/libavcodec/x86/h264_intrapred_init.c b/libavcodec/x86/h264_intrapred_init.c
index deededa..f5b5e3e 100644
--- a/libavcodec/x86/h264_intrapred_init.c
+++ b/libavcodec/x86/h264_intrapred_init.c
@@ -18,8 +18,10 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
 #include "libavutil/x86/cpu.h"
+#include "libavcodec/avcodec.h"
 #include "libavcodec/h264pred.h"
 
 #define PRED4x4(TYPE, DEPTH, OPT) \
@@ -179,7 +181,9 @@
 PRED4x4(tm_vp8, 8, ssse3)
 PRED4x4(vertical_vp8, 8, mmxext)
 
-void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth, const int chroma_format_idc)
+av_cold void ff_h264_pred_init_x86(H264PredContext *h, int codec_id,
+                                   const int bit_depth,
+                                   const int chroma_format_idc)
 {
     int mm_flags = av_get_cpu_flags();
 
diff --git a/libavcodec/x86/h264_qpel.c b/libavcodec/x86/h264_qpel.c
index 171ef2a..c1e7fb7 100644
--- a/libavcodec/x86/h264_qpel.c
+++ b/libavcodec/x86/h264_qpel.c
@@ -19,9 +19,11 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
 #include "libavutil/x86/asm.h"
-#include "libavcodec/dsputil.h"
+#include "libavutil/x86/cpu.h"
+#include "libavcodec/h264qpel.h"
 #include "libavcodec/mpegvideo.h"
 #include "dsputil_mmx.h"
 
@@ -29,7 +31,6 @@
 void ff_put_pixels4_mmxext(uint8_t *block, const uint8_t *pixels, int line_size, int h);
 void ff_avg_pixels4_mmxext(uint8_t *block, const uint8_t *pixels, int line_size, int h);
 void ff_put_pixels8_mmxext(uint8_t *block, const uint8_t *pixels, int line_size, int h);
-void ff_avg_pixels8_mmxext(uint8_t *block, const uint8_t *pixels, int line_size, int h);
 static void ff_put_pixels16_mmxext(uint8_t *block, const uint8_t *pixels,
                                    int line_size, int h)
 {
@@ -490,3 +491,134 @@
 #endif
 
 #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)
+
+#define H264_QPEL_FUNCS(x, y, CPU)                                                            \
+    do {                                                                                      \
+        c->put_h264_qpel_pixels_tab[0][x + y * 4] = put_h264_qpel16_mc ## x ## y ## _ ## CPU; \
+        c->put_h264_qpel_pixels_tab[1][x + y * 4] = put_h264_qpel8_mc  ## x ## y ## _ ## CPU; \
+        c->avg_h264_qpel_pixels_tab[0][x + y * 4] = avg_h264_qpel16_mc ## x ## y ## _ ## CPU; \
+        c->avg_h264_qpel_pixels_tab[1][x + y * 4] = avg_h264_qpel8_mc  ## x ## y ## _ ## CPU; \
+    } while (0)
+
+#define H264_QPEL_FUNCS_10(x, y, CPU)                                                               \
+    do {                                                                                            \
+        c->put_h264_qpel_pixels_tab[0][x + y * 4] = ff_put_h264_qpel16_mc ## x ## y ## _10_ ## CPU; \
+        c->put_h264_qpel_pixels_tab[1][x + y * 4] = ff_put_h264_qpel8_mc  ## x ## y ## _10_ ## CPU; \
+        c->avg_h264_qpel_pixels_tab[0][x + y * 4] = ff_avg_h264_qpel16_mc ## x ## y ## _10_ ## CPU; \
+        c->avg_h264_qpel_pixels_tab[1][x + y * 4] = ff_avg_h264_qpel8_mc  ## x ## y ## _10_ ## CPU; \
+    } while (0)
+
+av_cold void ff_h264qpel_init_x86(H264QpelContext *c, int bit_depth)
+{
+#if HAVE_YASM
+    int high_bit_depth = bit_depth > 8;
+    int mm_flags = av_get_cpu_flags();
+
+    if (EXTERNAL_MMXEXT(mm_flags)) {
+        if (!high_bit_depth) {
+            SET_QPEL_FUNCS(put_h264_qpel, 0, 16, mmxext, );
+            SET_QPEL_FUNCS(put_h264_qpel, 1,  8, mmxext, );
+            SET_QPEL_FUNCS(put_h264_qpel, 2,  4, mmxext, );
+            SET_QPEL_FUNCS(avg_h264_qpel, 0, 16, mmxext, );
+            SET_QPEL_FUNCS(avg_h264_qpel, 1,  8, mmxext, );
+            SET_QPEL_FUNCS(avg_h264_qpel, 2,  4, mmxext, );
+        } else if (bit_depth == 10) {
+#if ARCH_X86_32
+            SET_QPEL_FUNCS(avg_h264_qpel, 0, 16, 10_mmxext, ff_);
+            SET_QPEL_FUNCS(put_h264_qpel, 0, 16, 10_mmxext, ff_);
+            SET_QPEL_FUNCS(put_h264_qpel, 1,  8, 10_mmxext, ff_);
+            SET_QPEL_FUNCS(avg_h264_qpel, 1,  8, 10_mmxext, ff_);
+#endif
+            SET_QPEL_FUNCS(put_h264_qpel, 2, 4,  10_mmxext, ff_);
+            SET_QPEL_FUNCS(avg_h264_qpel, 2, 4,  10_mmxext, ff_);
+        }
+    }
+
+    if (EXTERNAL_SSE2(mm_flags)) {
+        if (!(mm_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);
+        }
+
+        if (!high_bit_depth) {
+            H264_QPEL_FUNCS(0, 1, sse2);
+            H264_QPEL_FUNCS(0, 2, sse2);
+            H264_QPEL_FUNCS(0, 3, sse2);
+            H264_QPEL_FUNCS(1, 1, sse2);
+            H264_QPEL_FUNCS(1, 2, sse2);
+            H264_QPEL_FUNCS(1, 3, sse2);
+            H264_QPEL_FUNCS(2, 1, sse2);
+            H264_QPEL_FUNCS(2, 2, sse2);
+            H264_QPEL_FUNCS(2, 3, sse2);
+            H264_QPEL_FUNCS(3, 1, sse2);
+            H264_QPEL_FUNCS(3, 2, sse2);
+            H264_QPEL_FUNCS(3, 3, sse2);
+        }
+
+        if (bit_depth == 10) {
+            SET_QPEL_FUNCS(put_h264_qpel, 0, 16, 10_sse2, ff_);
+            SET_QPEL_FUNCS(put_h264_qpel, 1,  8, 10_sse2, ff_);
+            SET_QPEL_FUNCS(avg_h264_qpel, 0, 16, 10_sse2, ff_);
+            SET_QPEL_FUNCS(avg_h264_qpel, 1,  8, 10_sse2, ff_);
+            H264_QPEL_FUNCS_10(1, 0, sse2_cache64);
+            H264_QPEL_FUNCS_10(2, 0, sse2_cache64);
+            H264_QPEL_FUNCS_10(3, 0, sse2_cache64);
+        }
+    }
+
+    if (EXTERNAL_SSSE3(mm_flags)) {
+        if (!high_bit_depth) {
+            H264_QPEL_FUNCS(1, 0, ssse3);
+            H264_QPEL_FUNCS(1, 1, ssse3);
+            H264_QPEL_FUNCS(1, 2, ssse3);
+            H264_QPEL_FUNCS(1, 3, ssse3);
+            H264_QPEL_FUNCS(2, 0, ssse3);
+            H264_QPEL_FUNCS(2, 1, ssse3);
+            H264_QPEL_FUNCS(2, 2, ssse3);
+            H264_QPEL_FUNCS(2, 3, ssse3);
+            H264_QPEL_FUNCS(3, 0, ssse3);
+            H264_QPEL_FUNCS(3, 1, ssse3);
+            H264_QPEL_FUNCS(3, 2, ssse3);
+            H264_QPEL_FUNCS(3, 3, ssse3);
+        }
+
+        if (bit_depth == 10) {
+            H264_QPEL_FUNCS_10(1, 0, ssse3_cache64);
+            H264_QPEL_FUNCS_10(2, 0, ssse3_cache64);
+            H264_QPEL_FUNCS_10(3, 0, ssse3_cache64);
+        }
+    }
+
+    if (EXTERNAL_AVX(mm_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
+         * having to treat SSE2 functions with such properties as AVX. */
+        if (bit_depth == 10) {
+            H264_QPEL_FUNCS_10(1, 0, sse2);
+            H264_QPEL_FUNCS_10(2, 0, sse2);
+            H264_QPEL_FUNCS_10(3, 0, sse2);
+        }
+    }
+#endif
+}
diff --git a/libavcodec/x86/h264chroma_init.c b/libavcodec/x86/h264chroma_init.c
new file mode 100644
index 0000000..b5c078f
--- /dev/null
+++ b/libavcodec/x86/h264chroma_init.c
@@ -0,0 +1,118 @@
+/*
+ * 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 "config.h"
+#include "libavutil/cpu.h"
+#include "libavutil/x86/cpu.h"
+#include "libavcodec/h264chroma.h"
+
+void ff_put_h264_chroma_mc8_rnd_mmx  (uint8_t *dst, uint8_t *src,
+                                      int stride, int h, int x, int y);
+void ff_avg_h264_chroma_mc8_rnd_mmxext(uint8_t *dst, uint8_t *src,
+                                       int stride, int h, int x, int y);
+void ff_avg_h264_chroma_mc8_rnd_3dnow(uint8_t *dst, uint8_t *src,
+                                      int stride, int h, int x, int y);
+
+void ff_put_h264_chroma_mc4_mmx      (uint8_t *dst, uint8_t *src,
+                                      int stride, int h, int x, int y);
+void ff_avg_h264_chroma_mc4_mmxext   (uint8_t *dst, uint8_t *src,
+                                      int stride, int h, int x, int y);
+void ff_avg_h264_chroma_mc4_3dnow    (uint8_t *dst, uint8_t *src,
+                                      int stride, int h, int x, int y);
+
+void ff_put_h264_chroma_mc2_mmxext   (uint8_t *dst, uint8_t *src,
+                                      int stride, int h, int x, int y);
+void ff_avg_h264_chroma_mc2_mmxext   (uint8_t *dst, uint8_t *src,
+                                      int stride, int h, int x, int y);
+
+void ff_put_h264_chroma_mc8_rnd_ssse3(uint8_t *dst, uint8_t *src,
+                                      int stride, int h, int x, int y);
+void ff_put_h264_chroma_mc4_ssse3    (uint8_t *dst, uint8_t *src,
+                                      int stride, int h, int x, int y);
+
+void ff_avg_h264_chroma_mc8_rnd_ssse3(uint8_t *dst, uint8_t *src,
+                                      int stride, int h, int x, int y);
+void ff_avg_h264_chroma_mc4_ssse3    (uint8_t *dst, uint8_t *src,
+                                      int stride, int h, int x, int y);
+
+#define CHROMA_MC(OP, NUM, DEPTH, OPT)                                  \
+void ff_ ## OP ## _h264_chroma_mc ## NUM ## _ ## DEPTH ## _ ## OPT      \
+                                      (uint8_t *dst, uint8_t *src,      \
+                                       int stride, int h, int x, int y);
+
+CHROMA_MC(put, 2, 10, mmxext)
+CHROMA_MC(avg, 2, 10, mmxext)
+CHROMA_MC(put, 4, 10, mmxext)
+CHROMA_MC(avg, 4, 10, mmxext)
+CHROMA_MC(put, 8, 10, sse2)
+CHROMA_MC(avg, 8, 10, sse2)
+CHROMA_MC(put, 8, 10, avx)
+CHROMA_MC(avg, 8, 10, avx)
+
+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();
+
+    if (EXTERNAL_MMX(mm_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) {
+        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) {
+        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) {
+        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) {
+        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) {
+        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) {
+        // 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;
+        c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_10_avx;
+    }
+#endif
+}
diff --git a/libavcodec/x86/h264dsp_init.c b/libavcodec/x86/h264dsp_init.c
index 65d300f..11aae77 100644
--- a/libavcodec/x86/h264dsp_init.c
+++ b/libavcodec/x86/h264dsp_init.c
@@ -18,6 +18,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
 #include "libavutil/x86/asm.h"
 #include "libavutil/x86/cpu.h"
@@ -48,7 +49,7 @@
 #define IDCT_ADD_REP_FUNC(NUM, REP, DEPTH, OPT)                         \
 void ff_h264_idct ## NUM ## _add ## REP ## _ ## DEPTH ## _ ## OPT       \
     (uint8_t *dst, const int *block_offset,                             \
-     DCTELEM *block, int stride, const uint8_t nnzc[6 * 8]);
+     int16_t *block, int stride, const uint8_t nnzc[6 * 8]);
 
 IDCT_ADD_REP_FUNC(8, 4, 8, mmx)
 IDCT_ADD_REP_FUNC(8, 4, 8, mmxext)
@@ -70,7 +71,7 @@
 #define IDCT_ADD_REP_FUNC2(NUM, REP, DEPTH, OPT)                      \
 void ff_h264_idct ## NUM ## _add ## REP ## _ ## DEPTH ## _ ## OPT     \
     (uint8_t **dst, const int *block_offset,                          \
-     DCTELEM *block, int stride, const uint8_t nnzc[6 * 8]);
+     int16_t *block, int stride, const uint8_t nnzc[6 * 8]);
 
 IDCT_ADD_REP_FUNC2(, 8, 8, mmx)
 IDCT_ADD_REP_FUNC2(, 8, 8, mmxext)
@@ -78,8 +79,8 @@
 IDCT_ADD_REP_FUNC2(, 8, 10, sse2)
 IDCT_ADD_REP_FUNC2(, 8, 10, avx)
 
-void ff_h264_luma_dc_dequant_idct_mmx(DCTELEM *output, DCTELEM *input, int qmul);
-void ff_h264_luma_dc_dequant_idct_sse2(DCTELEM *output, DCTELEM *input, int qmul);
+void ff_h264_luma_dc_dequant_idct_mmx(int16_t *output, int16_t *input, int qmul);
+void ff_h264_luma_dc_dequant_idct_sse2(int16_t *output, int16_t *input, int qmul);
 
 /***********************************/
 /* deblocking */
@@ -207,8 +208,8 @@
 H264_BIWEIGHT_10_SSE(8,  10)
 H264_BIWEIGHT_10_SSE(4,  10)
 
-void ff_h264dsp_init_x86(H264DSPContext *c, const int bit_depth,
-                         const int chroma_format_idc)
+av_cold void ff_h264dsp_init_x86(H264DSPContext *c, const int bit_depth,
+                                 const int chroma_format_idc)
 {
 #if HAVE_YASM
     int mm_flags = av_get_cpu_flags();
diff --git a/libavcodec/x86/hpeldsp.asm b/libavcodec/x86/hpeldsp.asm
new file mode 100644
index 0000000..c83c388
--- /dev/null
+++ b/libavcodec/x86/hpeldsp.asm
@@ -0,0 +1,502 @@
+;******************************************************************************
+;*
+;* Copyright (c) 2000-2001 Fabrice Bellard <fabrice@bellard.org>
+;* Copyright (c)      Nick Kurshev <nickols_k@mail.ru>
+;* Copyright (c) 2002 Michael Niedermayer <michaelni@gmx.at>
+;* Copyright (c) 2002 Zdenek Kabelac <kabi@informatics.muni.cz>
+;* Copyright (c) 2013 Daniel Kang
+;*
+;* MMX optimized hpel 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
+;******************************************************************************
+
+%include "libavutil/x86/x86util.asm"
+
+SECTION_RODATA
+cextern pb_1
+
+SECTION_TEXT
+
+; put_pixels8_x2(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+%macro PUT_PIXELS8_X2 0
+cglobal put_pixels8_x2, 4,5
+    lea          r4, [r2*2]
+.loop:
+    mova         m0, [r1]
+    mova         m1, [r1+r2]
+    PAVGB        m0, [r1+1]
+    PAVGB        m1, [r1+r2+1]
+    mova       [r0], m0
+    mova    [r0+r2], m1
+    add          r1, r4
+    add          r0, r4
+    mova         m0, [r1]
+    mova         m1, [r1+r2]
+    PAVGB        m0, [r1+1]
+    PAVGB        m1, [r1+r2+1]
+    add          r1, r4
+    mova       [r0], m0
+    mova    [r0+r2], m1
+    add          r0, r4
+    sub         r3d, 4
+    jne .loop
+    REP_RET
+%endmacro
+
+INIT_MMX mmxext
+PUT_PIXELS8_X2
+INIT_MMX 3dnow
+PUT_PIXELS8_X2
+
+
+; put_pixels16_x2(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+%macro PUT_PIXELS_16 0
+cglobal put_pixels16_x2, 4,5
+    lea          r4, [r2*2]
+.loop:
+    mova         m0, [r1]
+    mova         m1, [r1+r2]
+    mova         m2, [r1+8]
+    mova         m3, [r1+r2+8]
+    PAVGB        m0, [r1+1]
+    PAVGB        m1, [r1+r2+1]
+    PAVGB        m2, [r1+9]
+    PAVGB        m3, [r1+r2+9]
+    mova       [r0], m0
+    mova    [r0+r2], m1
+    mova     [r0+8], m2
+    mova  [r0+r2+8], m3
+    add          r1, r4
+    add          r0, r4
+    mova         m0, [r1]
+    mova         m1, [r1+r2]
+    mova         m2, [r1+8]
+    mova         m3, [r1+r2+8]
+    PAVGB        m0, [r1+1]
+    PAVGB        m1, [r1+r2+1]
+    PAVGB        m2, [r1+9]
+    PAVGB        m3, [r1+r2+9]
+    add          r1, r4
+    mova       [r0], m0
+    mova    [r0+r2], m1
+    mova     [r0+8], m2
+    mova  [r0+r2+8], m3
+    add          r0, r4
+    sub         r3d, 4
+    jne .loop
+    REP_RET
+%endmacro
+
+INIT_MMX mmxext
+PUT_PIXELS_16
+INIT_MMX 3dnow
+PUT_PIXELS_16
+
+
+; put_no_rnd_pixels8_x2(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+%macro PUT_NO_RND_PIXELS8_X2 0
+cglobal put_no_rnd_pixels8_x2, 4,5
+    mova         m6, [pb_1]
+    lea          r4, [r2*2]
+.loop:
+    mova         m0, [r1]
+    mova         m2, [r1+r2]
+    mova         m1, [r1+1]
+    mova         m3, [r1+r2+1]
+    add          r1, r4
+    psubusb      m0, m6
+    psubusb      m2, m6
+    PAVGB        m0, m1
+    PAVGB        m2, m3
+    mova       [r0], m0
+    mova    [r0+r2], m2
+    mova         m0, [r1]
+    mova         m1, [r1+1]
+    mova         m2, [r1+r2]
+    mova         m3, [r1+r2+1]
+    add          r0, r4
+    add          r1, r4
+    psubusb      m0, m6
+    psubusb      m2, m6
+    PAVGB        m0, m1
+    PAVGB        m2, m3
+    mova       [r0], m0
+    mova    [r0+r2], m2
+    add          r0, r4
+    sub         r3d, 4
+    jne .loop
+    REP_RET
+%endmacro
+
+INIT_MMX mmxext
+PUT_NO_RND_PIXELS8_X2
+INIT_MMX 3dnow
+PUT_NO_RND_PIXELS8_X2
+
+
+; put_no_rnd_pixels8_x2_exact(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+%macro PUT_NO_RND_PIXELS8_X2_EXACT 0
+cglobal put_no_rnd_pixels8_x2_exact, 4,5
+    lea          r4, [r2*3]
+    pcmpeqb      m6, m6
+.loop:
+    mova         m0, [r1]
+    mova         m2, [r1+r2]
+    mova         m1, [r1+1]
+    mova         m3, [r1+r2+1]
+    pxor         m0, m6
+    pxor         m2, m6
+    pxor         m1, m6
+    pxor         m3, m6
+    PAVGB        m0, m1
+    PAVGB        m2, m3
+    pxor         m0, m6
+    pxor         m2, m6
+    mova       [r0], m0
+    mova    [r0+r2], m2
+    mova         m0, [r1+r2*2]
+    mova         m1, [r1+r2*2+1]
+    mova         m2, [r1+r4]
+    mova         m3, [r1+r4+1]
+    pxor         m0, m6
+    pxor         m1, m6
+    pxor         m2, m6
+    pxor         m3, m6
+    PAVGB        m0, m1
+    PAVGB        m2, m3
+    pxor         m0, m6
+    pxor         m2, m6
+    mova  [r0+r2*2], m0
+    mova    [r0+r4], m2
+    lea          r1, [r1+r2*4]
+    lea          r0, [r0+r2*4]
+    sub         r3d, 4
+    jg .loop
+    REP_RET
+%endmacro
+
+INIT_MMX mmxext
+PUT_NO_RND_PIXELS8_X2_EXACT
+INIT_MMX 3dnow
+PUT_NO_RND_PIXELS8_X2_EXACT
+
+
+; put_pixels8_y2(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+%macro PUT_PIXELS8_Y2 0
+cglobal put_pixels8_y2, 4,5
+    lea          r4, [r2*2]
+    mova         m0, [r1]
+    sub          r0, r2
+.loop:
+    mova         m1, [r1+r2]
+    mova         m2, [r1+r4]
+    add          r1, r4
+    PAVGB        m0, m1
+    PAVGB        m1, m2
+    mova    [r0+r2], m0
+    mova    [r0+r4], m1
+    mova         m1, [r1+r2]
+    mova         m0, [r1+r4]
+    add          r0, r4
+    add          r1, r4
+    PAVGB        m2, m1
+    PAVGB        m1, m0
+    mova    [r0+r2], m2
+    mova    [r0+r4], m1
+    add          r0, r4
+    sub         r3d, 4
+    jne .loop
+    REP_RET
+%endmacro
+
+INIT_MMX mmxext
+PUT_PIXELS8_Y2
+INIT_MMX 3dnow
+PUT_PIXELS8_Y2
+
+
+; put_no_rnd_pixels8_y2(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+%macro PUT_NO_RND_PIXELS8_Y2 0
+cglobal put_no_rnd_pixels8_y2, 4,5
+    mova         m6, [pb_1]
+    lea          r4, [r2+r2]
+    mova         m0, [r1]
+    sub          r0, r2
+.loop:
+    mova         m1, [r1+r2]
+    mova         m2, [r1+r4]
+    add          r1, r4
+    psubusb      m1, m6
+    PAVGB        m0, m1
+    PAVGB        m1, m2
+    mova    [r0+r2], m0
+    mova    [r0+r4], m1
+    mova         m1, [r1+r2]
+    mova         m0, [r1+r4]
+    add          r0, r4
+    add          r1, r4
+    psubusb      m1, m6
+    PAVGB        m2, m1
+    PAVGB        m1, m0
+    mova    [r0+r2], m2
+    mova    [r0+r4], m1
+    add          r0, r4
+    sub         r3d, 4
+    jne .loop
+    REP_RET
+%endmacro
+
+INIT_MMX mmxext
+PUT_NO_RND_PIXELS8_Y2
+INIT_MMX 3dnow
+PUT_NO_RND_PIXELS8_Y2
+
+
+; put_no_rnd_pixels8_y2_exact(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+%macro PUT_NO_RND_PIXELS8_Y2_EXACT 0
+cglobal put_no_rnd_pixels8_y2_exact, 4,5
+    lea          r4, [r2*3]
+    mova         m0, [r1]
+    pcmpeqb      m6, m6
+    add          r1, r2
+    pxor         m0, m6
+.loop:
+    mova         m1, [r1]
+    mova         m2, [r1+r2]
+    pxor         m1, m6
+    pxor         m2, m6
+    PAVGB        m0, m1
+    PAVGB        m1, m2
+    pxor         m0, m6
+    pxor         m1, m6
+    mova       [r0], m0
+    mova    [r0+r2], m1
+    mova         m1, [r1+r2*2]
+    mova         m0, [r1+r4]
+    pxor         m1, m6
+    pxor         m0, m6
+    PAVGB        m2, m1
+    PAVGB        m1, m0
+    pxor         m2, m6
+    pxor         m1, m6
+    mova  [r0+r2*2], m2
+    mova    [r0+r4], m1
+    lea          r1, [r1+r2*4]
+    lea          r0, [r0+r2*4]
+    sub         r3d, 4
+    jg .loop
+    REP_RET
+%endmacro
+
+INIT_MMX mmxext
+PUT_NO_RND_PIXELS8_Y2_EXACT
+INIT_MMX 3dnow
+PUT_NO_RND_PIXELS8_Y2_EXACT
+
+
+; avg_pixels8(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+%macro AVG_PIXELS8 0
+cglobal avg_pixels8, 4,5
+    lea          r4, [r2*2]
+.loop:
+    mova         m0, [r0]
+    mova         m1, [r0+r2]
+    PAVGB        m0, [r1]
+    PAVGB        m1, [r1+r2]
+    mova       [r0], m0
+    mova    [r0+r2], m1
+    add          r1, r4
+    add          r0, r4
+    mova         m0, [r0]
+    mova         m1, [r0+r2]
+    PAVGB        m0, [r1]
+    PAVGB        m1, [r1+r2]
+    add          r1, r4
+    mova       [r0], m0
+    mova    [r0+r2], m1
+    add          r0, r4
+    sub         r3d, 4
+    jne .loop
+    REP_RET
+%endmacro
+
+INIT_MMX 3dnow
+AVG_PIXELS8
+
+
+; avg_pixels8_x2(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+%macro AVG_PIXELS8_X2 0
+cglobal avg_pixels8_x2, 4,5
+    lea          r4, [r2*2]
+.loop:
+    mova         m0, [r1]
+    mova         m2, [r1+r2]
+    PAVGB        m0, [r1+1]
+    PAVGB        m2, [r1+r2+1]
+    PAVGB        m0, [r0]
+    PAVGB        m2, [r0+r2]
+    add          r1, r4
+    mova       [r0], m0
+    mova    [r0+r2], m2
+    mova         m0, [r1]
+    mova         m2, [r1+r2]
+    PAVGB        m0, [r1+1]
+    PAVGB        m2, [r1+r2+1]
+    add          r0, r4
+    add          r1, r4
+    PAVGB        m0, [r0]
+    PAVGB        m2, [r0+r2]
+    mova       [r0], m0
+    mova    [r0+r2], m2
+    add          r0, r4
+    sub         r3d, 4
+    jne .loop
+    REP_RET
+%endmacro
+
+INIT_MMX mmxext
+AVG_PIXELS8_X2
+INIT_MMX 3dnow
+AVG_PIXELS8_X2
+
+
+; avg_pixels8_y2(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+%macro AVG_PIXELS8_Y2 0
+cglobal avg_pixels8_y2, 4,5
+    lea          r4, [r2*2]
+    mova         m0, [r1]
+    sub          r0, r2
+.loop:
+    mova         m1, [r1+r2]
+    mova         m2, [r1+r4]
+    add          r1, r4
+    PAVGB        m0, m1
+    PAVGB        m1, m2
+    mova         m3, [r0+r2]
+    mova         m4, [r0+r4]
+    PAVGB        m0, m3
+    PAVGB        m1, m4
+    mova    [r0+r2], m0
+    mova    [r0+r4], m1
+    mova         m1, [r1+r2]
+    mova         m0, [r1+r4]
+    PAVGB        m2, m1
+    PAVGB        m1, m0
+    add          r0, r4
+    add          r1, r4
+    mova         m3, [r0+r2]
+    mova         m4, [r0+r4]
+    PAVGB        m2, m3
+    PAVGB        m1, m4
+    mova    [r0+r2], m2
+    mova    [r0+r4], m1
+    add          r0, r4
+    sub         r3d, 4
+    jne .loop
+    REP_RET
+%endmacro
+
+INIT_MMX mmxext
+AVG_PIXELS8_Y2
+INIT_MMX 3dnow
+AVG_PIXELS8_Y2
+
+
+; avg_pixels8_xy2(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+%macro AVG_PIXELS8_XY2 0
+cglobal avg_pixels8_xy2, 4,5
+    mova         m6, [pb_1]
+    lea          r4, [r2*2]
+    mova         m0, [r1]
+    pavgb        m0, [r1+1]
+.loop:
+    mova         m2, [r1+r4]
+    mova         m1, [r1+r2]
+    psubusb      m2, m6
+    pavgb        m1, [r1+r2+1]
+    pavgb        m2, [r1+r4+1]
+    add          r1, r4
+    pavgb        m0, m1
+    pavgb        m1, m2
+    pavgb        m0, [r0]
+    pavgb        m1, [r0+r2]
+    mova       [r0], m0
+    mova    [r0+r2], m1
+    mova         m1, [r1+r2]
+    mova         m0, [r1+r4]
+    pavgb        m1, [r1+r2+1]
+    pavgb        m0, [r1+r4+1]
+    add          r0, r4
+    add          r1, r4
+    pavgb        m2, m1
+    pavgb        m1, m0
+    pavgb        m2, [r0]
+    pavgb        m1, [r0+r2]
+    mova       [r0], m2
+    mova    [r0+r2], m1
+    add          r0, r4
+    sub         r3d, 4
+    jne .loop
+    REP_RET
+%endmacro
+
+INIT_MMX mmxext
+AVG_PIXELS8_XY2
+INIT_MMX 3dnow
+AVG_PIXELS8_XY2
+
+INIT_XMM sse2
+; void put_pixels16_sse2(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+cglobal put_pixels16, 4,5,4
+    lea          r4, [r2*3]
+.loop:
+    movu         m0, [r1]
+    movu         m1, [r1+r2]
+    movu         m2, [r1+r2*2]
+    movu         m3, [r1+r4]
+    lea          r1, [r1+r2*4]
+    mova       [r0], m0
+    mova    [r0+r2], m1
+    mova  [r0+r2*2], m2
+    mova    [r0+r4], m3
+    sub         r3d, 4
+    lea          r0, [r0+r2*4]
+    jnz       .loop
+    REP_RET
+
+; void avg_pixels16_sse2(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+cglobal avg_pixels16, 4,5,4
+    lea          r4, [r2*3]
+.loop:
+    movu         m0, [r1]
+    movu         m1, [r1+r2]
+    movu         m2, [r1+r2*2]
+    movu         m3, [r1+r4]
+    lea          r1, [r1+r2*4]
+    pavgb        m0, [r0]
+    pavgb        m1, [r0+r2]
+    pavgb        m2, [r0+r2*2]
+    pavgb        m3, [r0+r4]
+    mova       [r0], m0
+    mova    [r0+r2], m1
+    mova  [r0+r2*2], m2
+    mova    [r0+r4], m3
+    sub         r3d, 4
+    lea          r0, [r0+r2*4]
+    jnz       .loop
+    REP_RET
diff --git a/libavcodec/x86/idct_mmx_xvid.c b/libavcodec/x86/idct_mmx_xvid.c
index b62865e..5e9f405 100644
--- a/libavcodec/x86/idct_mmx_xvid.c
+++ b/libavcodec/x86/idct_mmx_xvid.c
@@ -531,25 +531,25 @@
     :: "r"(block), "r"(rounder_0), "r"(tab_i_04_xmm), "r"(tg_1_16));
 }
 
-void ff_idct_xvid_mmx_put(uint8_t *dest, int line_size, DCTELEM *block)
+void ff_idct_xvid_mmx_put(uint8_t *dest, int line_size, int16_t *block)
 {
     ff_idct_xvid_mmx(block);
     ff_put_pixels_clamped_mmx(block, dest, line_size);
 }
 
-void ff_idct_xvid_mmx_add(uint8_t *dest, int line_size, DCTELEM *block)
+void ff_idct_xvid_mmx_add(uint8_t *dest, int line_size, int16_t *block)
 {
     ff_idct_xvid_mmx(block);
     ff_add_pixels_clamped_mmx(block, dest, line_size);
 }
 
-void ff_idct_xvid_mmxext_put(uint8_t *dest, int line_size, DCTELEM *block)
+void ff_idct_xvid_mmxext_put(uint8_t *dest, int line_size, int16_t *block)
 {
     ff_idct_xvid_mmxext(block);
     ff_put_pixels_clamped_mmx(block, dest, line_size);
 }
 
-void ff_idct_xvid_mmxext_add(uint8_t *dest, int line_size, DCTELEM *block)
+void ff_idct_xvid_mmxext_add(uint8_t *dest, int line_size, int16_t *block)
 {
     ff_idct_xvid_mmxext(block);
     ff_add_pixels_clamped_mmx(block, dest, line_size);
diff --git a/libavcodec/x86/idct_sse2_xvid.c b/libavcodec/x86/idct_sse2_xvid.c
index d121b25..b51466c 100644
--- a/libavcodec/x86/idct_sse2_xvid.c
+++ b/libavcodec/x86/idct_sse2_xvid.c
@@ -38,7 +38,6 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavcodec/dsputil.h"
 #include "libavutil/mem.h"
 #include "libavutil/x86/asm.h"
 #include "idct_xvid.h"
@@ -376,7 +375,7 @@
     JZ("%%esi", "1f")
     "5:                                                          \n\t"
     iMTX_MULT("7*16(%0)", MANGLE(iTab2), ROUND(walkenIdctRounders+5*16), PUT_ODD(ROW7))
-#if !ARCH_X86_64
+#if ARCH_X86_32
     iLLM_HEAD
 #endif
     iLLM_PASS("%0")
diff --git a/libavcodec/x86/idct_xvid.h b/libavcodec/x86/idct_xvid.h
index a584fba..7a2847b 100644
--- a/libavcodec/x86/idct_xvid.h
+++ b/libavcodec/x86/idct_xvid.h
@@ -28,15 +28,13 @@
 
 #include <stdint.h>
 
-#include "libavcodec/dsputil.h"
-
 void ff_idct_xvid_mmx(short *block);
-void ff_idct_xvid_mmx_put(uint8_t *dest, int line_size, DCTELEM *block);
-void ff_idct_xvid_mmx_add(uint8_t *dest, int line_size, DCTELEM *block);
+void ff_idct_xvid_mmx_put(uint8_t *dest, int line_size, int16_t *block);
+void ff_idct_xvid_mmx_add(uint8_t *dest, int line_size, int16_t *block);
 
 void ff_idct_xvid_mmxext(short *block);
-void ff_idct_xvid_mmxext_put(uint8_t *dest, int line_size, DCTELEM *block);
-void ff_idct_xvid_mmxext_add(uint8_t *dest, int line_size, DCTELEM *block);
+void ff_idct_xvid_mmxext_put(uint8_t *dest, int line_size, int16_t *block);
+void ff_idct_xvid_mmxext_add(uint8_t *dest, int line_size, int16_t *block);
 
 void ff_idct_xvid_sse2(short *block);
 void ff_idct_xvid_sse2_put(uint8_t *dest, int line_size, short *block);
diff --git a/libavcodec/x86/lpc.c b/libavcodec/x86/lpc.c
index a66f1e0..1962212 100644
--- a/libavcodec/x86/lpc.c
+++ b/libavcodec/x86/lpc.c
@@ -20,6 +20,7 @@
  */
 
 #include "libavutil/x86/asm.h"
+#include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
 #include "libavcodec/lpc.h"
 
diff --git a/libavcodec/x86/mlpdsp.c b/libavcodec/x86/mlpdsp.c
index de28e22..81cab5a 100644
--- a/libavcodec/x86/mlpdsp.c
+++ b/libavcodec/x86/mlpdsp.c
@@ -19,6 +19,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/x86/asm.h"
 #include "libavcodec/mlpdsp.h"
 #include "libavcodec/mlp.h"
@@ -173,7 +174,7 @@
 
 #endif /* HAVE_7REGS && HAVE_INLINE_ASM */
 
-void ff_mlpdsp_init_x86(MLPDSPContext *c)
+av_cold void ff_mlpdsp_init_x86(MLPDSPContext *c)
 {
 #if HAVE_7REGS && HAVE_INLINE_ASM
     c->mlp_filter_channel = mlp_filter_channel_x86;
diff --git a/libavcodec/x86/motion_est.c b/libavcodec/x86/motion_est.c
index e054a0d..3ffb002 100644
--- a/libavcodec/x86/motion_est.c
+++ b/libavcodec/x86/motion_est.c
@@ -22,10 +22,10 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/avassert.h"
 #include "libavutil/mem.h"
 #include "libavutil/x86/asm.h"
-#include "libavcodec/dsputil.h"
 #include "dsputil_mmx.h"
 
 #if HAVE_INLINE_ASM
@@ -432,7 +432,7 @@
 
 #endif /* HAVE_INLINE_ASM */
 
-void ff_dsputil_init_pix_mmx(DSPContext* c, AVCodecContext *avctx)
+av_cold void ff_dsputil_init_pix_mmx(DSPContext *c, AVCodecContext *avctx)
 {
 #if HAVE_INLINE_ASM
     int mm_flags = av_get_cpu_flags();
diff --git a/libavcodec/x86/mpeg4qpel.asm b/libavcodec/x86/mpeg4qpel.asm
new file mode 100644
index 0000000..ca52375
--- /dev/null
+++ b/libavcodec/x86/mpeg4qpel.asm
@@ -0,0 +1,560 @@
+;******************************************************************************
+;* mpeg4 qpel
+;* Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
+;* Copyright (c) 2008 Loren Merritt
+;* Copyright (c) 2013 Daniel Kang
+;*
+;* 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/x86/x86util.asm"
+
+SECTION_RODATA
+cextern pb_1
+cextern pw_3
+cextern pw_15
+cextern pw_16
+cextern pw_20
+
+
+SECTION_TEXT
+
+; put_no_rnd_pixels8_l2(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
+%macro PUT_NO_RND_PIXELS8_L2 0
+cglobal put_no_rnd_pixels8_l2, 6,6
+    movsxdifnidn r4, r4d
+    movsxdifnidn r3, r3d
+    pcmpeqb      m6, m6
+    test        r5d, 1
+    je .loop
+    mova         m0, [r1]
+    mova         m1, [r2]
+    add          r1, r4
+    add          r2, 8
+    pxor         m0, m6
+    pxor         m1, m6
+    PAVGB        m0, m1
+    pxor         m0, m6
+    mova       [r0], m0
+    add          r0, r3
+    dec r5d
+.loop:
+    mova         m0, [r1]
+    add          r1, r4
+    mova         m1, [r1]
+    add          r1, r4
+    mova         m2, [r2]
+    mova         m3, [r2+8]
+    pxor         m0, m6
+    pxor         m1, m6
+    pxor         m2, m6
+    pxor         m3, m6
+    PAVGB        m0, m2
+    PAVGB        m1, m3
+    pxor         m0, m6
+    pxor         m1, m6
+    mova       [r0], m0
+    add          r0, r3
+    mova       [r0], m1
+    add          r0, r3
+    mova         m0, [r1]
+    add          r1, r4
+    mova         m1, [r1]
+    add          r1, r4
+    mova         m2, [r2+16]
+    mova         m3, [r2+24]
+    pxor         m0, m6
+    pxor         m1, m6
+    pxor         m2, m6
+    pxor         m3, m6
+    PAVGB        m0, m2
+    PAVGB        m1, m3
+    pxor         m0, m6
+    pxor         m1, m6
+    mova       [r0], m0
+    add          r0, r3
+    mova       [r0], m1
+    add          r0, r3
+    add          r2, 32
+    sub         r5d, 4
+    jne .loop
+    REP_RET
+%endmacro
+
+INIT_MMX mmxext
+PUT_NO_RND_PIXELS8_L2
+
+
+; put_no_rnd_pixels16_l2(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
+%macro PUT_NO_RND_PIXELS16_l2 0
+cglobal put_no_rnd_pixels16_l2, 6,6
+    movsxdifnidn r3, r3d
+    movsxdifnidn r4, r4d
+    pcmpeqb      m6, m6
+    test        r5d, 1
+    je .loop
+    mova         m0, [r1]
+    mova         m1, [r1+8]
+    mova         m2, [r2]
+    mova         m3, [r2+8]
+    pxor         m0, m6
+    pxor         m1, m6
+    pxor         m2, m6
+    pxor         m3, m6
+    PAVGB        m0, m2
+    PAVGB        m1, m3
+    pxor         m0, m6
+    pxor         m1, m6
+    add          r1, r4
+    add          r2, 16
+    mova       [r0], m0
+    mova     [r0+8], m1
+    add          r0, r3
+    dec r5d
+.loop:
+    mova         m0, [r1]
+    mova         m1, [r1+8]
+    add          r1, r4
+    mova         m2, [r2]
+    mova         m3, [r2+8]
+    pxor         m0, m6
+    pxor         m1, m6
+    pxor         m2, m6
+    pxor         m3, m6
+    PAVGB        m0, m2
+    PAVGB        m1, m3
+    pxor         m0, m6
+    pxor         m1, m6
+    mova       [r0], m0
+    mova     [r0+8], m1
+    add          r0, r3
+    mova         m0, [r1]
+    mova         m1, [r1+8]
+    add          r1, r4
+    mova         m2, [r2+16]
+    mova         m3, [r2+24]
+    pxor         m0, m6
+    pxor         m1, m6
+    pxor         m2, m6
+    pxor         m3, m6
+    PAVGB        m0, m2
+    PAVGB        m1, m3
+    pxor         m0, m6
+    pxor         m1, m6
+    mova       [r0], m0
+    mova     [r0+8], m1
+    add          r0, r3
+    add          r2, 32
+    sub         r5d, 2
+    jne .loop
+    REP_RET
+%endmacro
+
+INIT_MMX mmxext
+PUT_NO_RND_PIXELS16_l2
+INIT_MMX 3dnow
+PUT_NO_RND_PIXELS16_l2
+
+%macro MPEG4_QPEL16_H_LOWPASS 1
+cglobal %1_mpeg4_qpel16_h_lowpass, 5, 5, 0, 16
+    movsxdifnidn r2, r2d
+    movsxdifnidn r3, r3d
+    pxor         m7, m7
+.loop:
+    mova         m0, [r1]
+    mova         m1, m0
+    mova         m2, m0
+    punpcklbw    m0, m7
+    punpckhbw    m1, m7
+    pshufw       m5, m0, 0x90
+    pshufw       m6, m0, 0x41
+    mova         m3, m2
+    mova         m4, m2
+    psllq        m2, 8
+    psllq        m3, 16
+    psllq        m4, 24
+    punpckhbw    m2, m7
+    punpckhbw    m3, m7
+    punpckhbw    m4, m7
+    paddw        m5, m3
+    paddw        m6, m2
+    paddw        m5, m5
+    psubw        m6, m5
+    pshufw       m5, m0, 6
+    pmullw       m6, [pw_3]
+    paddw        m0, m4
+    paddw        m5, m1
+    pmullw       m0, [pw_20]
+    psubw        m0, m5
+    paddw        m6, [PW_ROUND]
+    paddw        m0, m6
+    psraw        m0, 5
+    mova    [rsp+8], m0
+    mova         m0, [r1+5]
+    mova         m5, m0
+    mova         m6, m0
+    psrlq        m0, 8
+    psrlq        m5, 16
+    punpcklbw    m0, m7
+    punpcklbw    m5, m7
+    paddw        m2, m0
+    paddw        m3, m5
+    paddw        m2, m2
+    psubw        m3, m2
+    mova         m2, m6
+    psrlq        m6, 24
+    punpcklbw    m2, m7
+    punpcklbw    m6, m7
+    pmullw       m3, [pw_3]
+    paddw        m1, m2
+    paddw        m4, m6
+    pmullw       m1, [pw_20]
+    psubw        m3, m4
+    paddw        m1, [PW_ROUND]
+    paddw        m3, m1
+    psraw        m3, 5
+    mova         m1, [rsp+8]
+    packuswb     m1, m3
+    OP_MOV     [r0], m1, m4
+    mova         m1, [r1+9]
+    mova         m4, m1
+    mova         m3, m1
+    psrlq        m1, 8
+    psrlq        m4, 16
+    punpcklbw    m1, m7
+    punpcklbw    m4, m7
+    paddw        m5, m1
+    paddw        m0, m4
+    paddw        m5, m5
+    psubw        m0, m5
+    mova         m5, m3
+    psrlq        m3, 24
+    pmullw       m0, [pw_3]
+    punpcklbw    m3, m7
+    paddw        m2, m3
+    psubw        m0, m2
+    mova         m2, m5
+    punpcklbw    m2, m7
+    punpckhbw    m5, m7
+    paddw        m6, m2
+    pmullw       m6, [pw_20]
+    paddw        m0, [PW_ROUND]
+    paddw        m0, m6
+    psraw        m0, 5
+    paddw        m3, m5
+    pshufw       m6, m5, 0xf9
+    paddw        m6, m4
+    pshufw       m4, m5, 0xbe
+    pshufw       m5, m5, 0x6f
+    paddw        m4, m1
+    paddw        m5, m2
+    paddw        m6, m6
+    psubw        m4, m6
+    pmullw       m3, [pw_20]
+    pmullw       m4, [pw_3]
+    psubw        m3, m5
+    paddw        m4, [PW_ROUND]
+    paddw        m4, m3
+    psraw        m4, 5
+    packuswb     m0, m4
+    OP_MOV   [r0+8], m0, m4
+    add          r1, r3
+    add          r0, r2
+    dec r4d
+    jne .loop
+    REP_RET
+%endmacro
+
+%macro PUT_OP 2-3
+    mova %1, %2
+%endmacro
+
+%macro AVG_OP 2-3
+    mova  %3, %1
+    pavgb %2, %3
+    mova  %1, %2
+%endmacro
+
+INIT_MMX mmxext
+%define PW_ROUND pw_16
+%define OP_MOV PUT_OP
+MPEG4_QPEL16_H_LOWPASS put
+%define PW_ROUND pw_16
+%define OP_MOV AVG_OP
+MPEG4_QPEL16_H_LOWPASS avg
+%define PW_ROUND pw_15
+%define OP_MOV PUT_OP
+MPEG4_QPEL16_H_LOWPASS put_no_rnd
+
+
+
+%macro MPEG4_QPEL8_H_LOWPASS 1
+cglobal %1_mpeg4_qpel8_h_lowpass, 5, 5, 0, 8
+    movsxdifnidn r2, r2d
+    movsxdifnidn r3, r3d
+    pxor         m7, m7
+.loop:
+    mova         m0, [r1]
+    mova         m1, m0
+    mova         m2, m0
+    punpcklbw    m0, m7
+    punpckhbw    m1, m7
+    pshufw       m5, m0, 0x90
+    pshufw       m6, m0, 0x41
+    mova         m3, m2
+    mova         m4, m2
+    psllq        m2, 8
+    psllq        m3, 16
+    psllq        m4, 24
+    punpckhbw    m2, m7
+    punpckhbw    m3, m7
+    punpckhbw    m4, m7
+    paddw        m5, m3
+    paddw        m6, m2
+    paddw        m5, m5
+    psubw        m6, m5
+    pshufw       m5, m0, 0x6
+    pmullw       m6, [pw_3]
+    paddw        m0, m4
+    paddw        m5, m1
+    pmullw       m0, [pw_20]
+    psubw        m0, m5
+    paddw        m6, [PW_ROUND]
+    paddw        m0, m6
+    psraw        m0, 5
+    movh         m5, [r1+5]
+    punpcklbw    m5, m7
+    pshufw       m6, m5, 0xf9
+    paddw        m1, m5
+    paddw        m2, m6
+    pshufw       m6, m5, 0xbe
+    pshufw       m5, m5, 0x6f
+    paddw        m3, m6
+    paddw        m4, m5
+    paddw        m2, m2
+    psubw        m3, m2
+    pmullw       m1, [pw_20]
+    pmullw       m3, [pw_3]
+    psubw        m3, m4
+    paddw        m1, [PW_ROUND]
+    paddw        m3, m1
+    psraw        m3, 5
+    packuswb     m0, m3
+    OP_MOV     [r0], m0, m4
+    add          r1, r3
+    add          r0, r2
+    dec r4d
+    jne .loop
+    REP_RET
+%endmacro
+
+INIT_MMX mmxext
+%define PW_ROUND pw_16
+%define OP_MOV PUT_OP
+MPEG4_QPEL8_H_LOWPASS put
+%define PW_ROUND pw_16
+%define OP_MOV AVG_OP
+MPEG4_QPEL8_H_LOWPASS avg
+%define PW_ROUND pw_15
+%define OP_MOV PUT_OP
+MPEG4_QPEL8_H_LOWPASS put_no_rnd
+
+
+
+%macro QPEL_V_LOW 5
+    paddw      m0, m1
+    mova       m4, [pw_20]
+    pmullw     m4, m0
+    mova       m0, %4
+    mova       m5, %1
+    paddw      m5, m0
+    psubw      m4, m5
+    mova       m5, %2
+    mova       m6, %3
+    paddw      m5, m3
+    paddw      m6, m2
+    paddw      m6, m6
+    psubw      m5, m6
+    pmullw     m5, [pw_3]
+    paddw      m4, [PW_ROUND]
+    paddw      m5, m4
+    psraw      m5, 5
+    packuswb   m5, m5
+    OP_MOV     %5, m5, m7
+    SWAP 0,1,2,3
+%endmacro
+
+%macro MPEG4_QPEL16_V_LOWPASS 1
+cglobal %1_mpeg4_qpel16_v_lowpass, 4, 6, 0, 544
+    movsxdifnidn r2, r2d
+    movsxdifnidn r3, r3d
+
+    mov         r4d, 17
+    mov          r5, rsp
+    pxor         m7, m7
+.looph:
+    mova         m0, [r1]
+    mova         m1, [r1]
+    mova         m2, [r1+8]
+    mova         m3, [r1+8]
+    punpcklbw    m0, m7
+    punpckhbw    m1, m7
+    punpcklbw    m2, m7
+    punpckhbw    m3, m7
+    mova       [r5], m0
+    mova  [r5+0x88], m1
+    mova [r5+0x110], m2
+    mova [r5+0x198], m3
+    add          r5, 8
+    add          r1, r3
+    dec r4d
+    jne .looph
+
+
+    ; NOTE: r1 CHANGES VALUES: r1 -> 4 - 14*dstStride
+    mov         r4d, 4
+    mov          r1, 4
+    neg          r2
+    lea          r1, [r1+r2*8]
+    lea          r1, [r1+r2*4]
+    lea          r1, [r1+r2*2]
+    neg          r2
+    mov          r5, rsp
+.loopv:
+    pxor         m7, m7
+    mova         m0, [r5+ 0x0]
+    mova         m1, [r5+ 0x8]
+    mova         m2, [r5+0x10]
+    mova         m3, [r5+0x18]
+    QPEL_V_LOW [r5+0x10], [r5+ 0x8], [r5+ 0x0], [r5+0x20], [r0]
+    QPEL_V_LOW [r5+ 0x8], [r5+ 0x0], [r5+ 0x0], [r5+0x28], [r0+r2]
+    lea    r0, [r0+r2*2]
+    QPEL_V_LOW [r5+ 0x0], [r5+ 0x0], [r5+ 0x8], [r5+0x30], [r0]
+    QPEL_V_LOW [r5+ 0x0], [r5+ 0x8], [r5+0x10], [r5+0x38], [r0+r2]
+    lea    r0, [r0+r2*2]
+    QPEL_V_LOW [r5+ 0x8], [r5+0x10], [r5+0x18], [r5+0x40], [r0]
+    QPEL_V_LOW [r5+0x10], [r5+0x18], [r5+0x20], [r5+0x48], [r0+r2]
+    lea    r0, [r0+r2*2]
+    QPEL_V_LOW [r5+0x18], [r5+0x20], [r5+0x28], [r5+0x50], [r0]
+    QPEL_V_LOW [r5+0x20], [r5+0x28], [r5+0x30], [r5+0x58], [r0+r2]
+    lea    r0, [r0+r2*2]
+    QPEL_V_LOW [r5+0x28], [r5+0x30], [r5+0x38], [r5+0x60], [r0]
+    QPEL_V_LOW [r5+0x30], [r5+0x38], [r5+0x40], [r5+0x68], [r0+r2]
+    lea    r0, [r0+r2*2]
+    QPEL_V_LOW [r5+0x38], [r5+0x40], [r5+0x48], [r5+0x70], [r0]
+    QPEL_V_LOW [r5+0x40], [r5+0x48], [r5+0x50], [r5+0x78], [r0+r2]
+    lea    r0, [r0+r2*2]
+    QPEL_V_LOW [r5+0x48], [r5+0x50], [r5+0x58], [r5+0x80], [r0]
+    QPEL_V_LOW [r5+0x50], [r5+0x58], [r5+0x60], [r5+0x80], [r0+r2]
+    lea    r0, [r0+r2*2]
+    QPEL_V_LOW [r5+0x58], [r5+0x60], [r5+0x68], [r5+0x78], [r0]
+    QPEL_V_LOW [r5+0x60], [r5+0x68], [r5+0x70], [r5+0x70], [r0+r2]
+
+    add    r5, 0x88
+    add    r0, r1
+    dec r4d
+    jne .loopv
+    REP_RET
+%endmacro
+
+%macro PUT_OPH 2-3
+    movh %1, %2
+%endmacro
+
+%macro AVG_OPH 2-3
+    movh  %3, %1
+    pavgb %2, %3
+    movh  %1, %2
+%endmacro
+
+INIT_MMX mmxext
+%define PW_ROUND pw_16
+%define OP_MOV PUT_OPH
+MPEG4_QPEL16_V_LOWPASS put
+%define PW_ROUND pw_16
+%define OP_MOV AVG_OPH
+MPEG4_QPEL16_V_LOWPASS avg
+%define PW_ROUND pw_15
+%define OP_MOV PUT_OPH
+MPEG4_QPEL16_V_LOWPASS put_no_rnd
+
+
+
+%macro MPEG4_QPEL8_V_LOWPASS 1
+cglobal %1_mpeg4_qpel8_v_lowpass, 4, 6, 0, 288
+    movsxdifnidn r2, r2d
+    movsxdifnidn r3, r3d
+
+    mov         r4d, 9
+    mov          r5, rsp
+    pxor         m7, m7
+.looph:
+    mova         m0, [r1]
+    mova         m1, [r1]
+    punpcklbw    m0, m7
+    punpckhbw    m1, m7
+    mova       [r5], m0
+    mova  [r5+0x48], m1
+    add          r5, 8
+    add          r1, r3
+    dec r4d
+    jne .looph
+
+
+    ; NOTE: r1 CHANGES VALUES: r1 -> 4 - 6*dstStride
+    mov         r4d, 2
+    mov          r1, 4
+    neg          r2
+    lea          r1, [r1+r2*4]
+    lea          r1, [r1+r2*2]
+    neg          r2
+    mov          r5, rsp
+.loopv:
+    pxor         m7, m7
+    mova         m0, [r5+ 0x0]
+    mova         m1, [r5+ 0x8]
+    mova         m2, [r5+0x10]
+    mova         m3, [r5+0x18]
+    QPEL_V_LOW [r5+0x10], [r5+ 0x8], [r5+ 0x0], [r5+0x20], [r0]
+    QPEL_V_LOW [r5+ 0x8], [r5+ 0x0], [r5+ 0x0], [r5+0x28], [r0+r2]
+    lea    r0, [r0+r2*2]
+    QPEL_V_LOW [r5+ 0x0], [r5+ 0x0], [r5+ 0x8], [r5+0x30], [r0]
+    QPEL_V_LOW [r5+ 0x0], [r5+ 0x8], [r5+0x10], [r5+0x38], [r0+r2]
+    lea    r0, [r0+r2*2]
+    QPEL_V_LOW [r5+ 0x8], [r5+0x10], [r5+0x18], [r5+0x40], [r0]
+    QPEL_V_LOW [r5+0x10], [r5+0x18], [r5+0x20], [r5+0x40], [r0+r2]
+    lea    r0, [r0+r2*2]
+    QPEL_V_LOW [r5+0x18], [r5+0x20], [r5+0x28], [r5+0x38], [r0]
+    QPEL_V_LOW [r5+0x20], [r5+0x28], [r5+0x30], [r5+0x30], [r0+r2]
+
+    add    r5, 0x48
+    add    r0, r1
+    dec r4d
+    jne .loopv
+    REP_RET
+%endmacro
+
+INIT_MMX mmxext
+%define PW_ROUND pw_16
+%define OP_MOV PUT_OPH
+MPEG4_QPEL8_V_LOWPASS put
+%define PW_ROUND pw_16
+%define OP_MOV AVG_OPH
+MPEG4_QPEL8_V_LOWPASS avg
+%define PW_ROUND pw_15
+%define OP_MOV PUT_OPH
+MPEG4_QPEL8_V_LOWPASS put_no_rnd
diff --git a/libavcodec/x86/mpegaudiodec.c b/libavcodec/x86/mpegaudiodec.c
index 44cbf9a..287d8ff 100644
--- a/libavcodec/x86/mpegaudiodec.c
+++ b/libavcodec/x86/mpegaudiodec.c
@@ -19,10 +19,11 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
+#include "libavutil/internal.h"
 #include "libavutil/x86/asm.h"
 #include "libavutil/x86/cpu.h"
-#include "libavcodec/dsputil.h"
 #include "libavcodec/mpegaudiodsp.h"
 
 #define DECL(CPU)\
@@ -232,7 +233,7 @@
 #endif
 #endif /* HAVE_YASM */
 
-void ff_mpadsp_init_x86(MPADSPContext *s)
+av_cold void ff_mpadsp_init_x86(MPADSPContext *s)
 {
     int mm_flags = av_get_cpu_flags();
 
diff --git a/libavcodec/x86/mpegvideo.c b/libavcodec/x86/mpegvideo.c
index 7c7ca87..903ad62 100644
--- a/libavcodec/x86/mpegvideo.c
+++ b/libavcodec/x86/mpegvideo.c
@@ -19,23 +19,23 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
 #include "libavutil/x86/asm.h"
 #include "libavcodec/avcodec.h"
-#include "libavcodec/dsputil.h"
 #include "libavcodec/mpegvideo.h"
 #include "dsputil_mmx.h"
 
 #if HAVE_INLINE_ASM
 
 static void dct_unquantize_h263_intra_mmx(MpegEncContext *s,
-                                  DCTELEM *block, int n, int qscale)
+                                  int16_t *block, int n, int qscale)
 {
     x86_reg level, qmul, qadd, nCoeffs;
 
     qmul = qscale << 1;
 
-    assert(s->block_last_index[n]>=0 || s->h263_aic);
+    av_assert2(s->block_last_index[n]>=0 || s->h263_aic);
 
     if (!s->h263_aic) {
         if (n < 4)
@@ -104,7 +104,7 @@
 
 
 static void dct_unquantize_h263_inter_mmx(MpegEncContext *s,
-                                  DCTELEM *block, int n, int qscale)
+                                  int16_t *block, int n, int qscale)
 {
     x86_reg qmul, qadd, nCoeffs;
 
@@ -166,14 +166,6 @@
 
 
 /*
-  NK:
-  Note: looking at PARANOID:
-  "enable all paranoid tests for rounding, overflows, etc..."
-
-#ifdef PARANOID
-                if (level < -2048 || level > 2047)
-                    fprintf(stderr, "unquant error %d %d\n", i, level);
-#endif
   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.
@@ -195,13 +187,13 @@
  high3 += tlow1
 */
 static void dct_unquantize_mpeg1_intra_mmx(MpegEncContext *s,
-                                     DCTELEM *block, int n, int qscale)
+                                     int16_t *block, int n, int qscale)
 {
     x86_reg nCoeffs;
     const uint16_t *quant_matrix;
     int block0;
 
-    assert(s->block_last_index[n]>=0);
+    av_assert2(s->block_last_index[n]>=0);
 
     nCoeffs= s->intra_scantable.raster_end[ s->block_last_index[n] ]+1;
 
@@ -264,12 +256,12 @@
 }
 
 static void dct_unquantize_mpeg1_inter_mmx(MpegEncContext *s,
-                                     DCTELEM *block, int n, int qscale)
+                                     int16_t *block, int n, int qscale)
 {
     x86_reg nCoeffs;
     const uint16_t *quant_matrix;
 
-    assert(s->block_last_index[n]>=0);
+    av_assert2(s->block_last_index[n]>=0);
 
     nCoeffs= s->intra_scantable.raster_end[ s->block_last_index[n] ]+1;
 
@@ -330,13 +322,13 @@
 }
 
 static void dct_unquantize_mpeg2_intra_mmx(MpegEncContext *s,
-                                     DCTELEM *block, int n, int qscale)
+                                     int16_t *block, int n, int qscale)
 {
     x86_reg nCoeffs;
     const uint16_t *quant_matrix;
     int block0;
 
-    assert(s->block_last_index[n]>=0);
+    av_assert2(s->block_last_index[n]>=0);
 
     if(s->alternate_scan) nCoeffs= 63; //FIXME
     else nCoeffs= s->intra_scantable.raster_end[ s->block_last_index[n] ];
@@ -396,12 +388,12 @@
 }
 
 static void dct_unquantize_mpeg2_inter_mmx(MpegEncContext *s,
-                                     DCTELEM *block, int n, int qscale)
+                                     int16_t *block, int n, int qscale)
 {
     x86_reg nCoeffs;
     const uint16_t *quant_matrix;
 
-    assert(s->block_last_index[n]>=0);
+    av_assert2(s->block_last_index[n]>=0);
 
     if(s->alternate_scan) nCoeffs= 63; //FIXME
     else nCoeffs= s->intra_scantable.raster_end[ s->block_last_index[n] ];
@@ -472,7 +464,7 @@
         );
 }
 
-static void  denoise_dct_mmx(MpegEncContext *s, DCTELEM *block){
+static void  denoise_dct_mmx(MpegEncContext *s, int16_t *block){
     const int intra= s->mb_intra;
     int *sum= s->dct_error_sum[intra];
     uint16_t *offset= s->dct_offset[intra];
@@ -526,7 +518,7 @@
     );
 }
 
-static void  denoise_dct_sse2(MpegEncContext *s, DCTELEM *block){
+static void  denoise_dct_sse2(MpegEncContext *s, int16_t *block){
     const int intra= s->mb_intra;
     int *sum= s->dct_error_sum[intra];
     uint16_t *offset= s->dct_offset[intra];
@@ -584,7 +576,7 @@
 
 #endif /* HAVE_INLINE_ASM */
 
-void ff_MPV_common_init_x86(MpegEncContext *s)
+av_cold void ff_MPV_common_init_x86(MpegEncContext *s)
 {
 #if HAVE_INLINE_ASM
     int mm_flags = av_get_cpu_flags();
diff --git a/libavcodec/x86/mpegvideoenc.c b/libavcodec/x86/mpegvideoenc.c
index 8e711f6..6219667 100644
--- a/libavcodec/x86/mpegvideoenc.c
+++ b/libavcodec/x86/mpegvideoenc.c
@@ -19,11 +19,12 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
 #include "libavutil/x86/asm.h"
 #include "libavutil/x86/cpu.h"
 #include "libavcodec/avcodec.h"
-#include "libavcodec/dsputil.h"
+#include "libavcodec/dct.h"
 #include "libavcodec/mpegvideo.h"
 #include "dsputil_mmx.h"
 
@@ -80,7 +81,7 @@
 #include "mpegvideoenc_template.c"
 #endif /* HAVE_SSSE3_INLINE */
 
-void ff_dct_encode_init_x86(MpegEncContext *s)
+av_cold void ff_dct_encode_init_x86(MpegEncContext *s)
 {
     int mm_flags = av_get_cpu_flags();
     const int dct_algo = s->avctx->dct_algo;
diff --git a/libavcodec/x86/mpegvideoenc_template.c b/libavcodec/x86/mpegvideoenc_template.c
index 47c3b43..1e0505e 100644
--- a/libavcodec/x86/mpegvideoenc_template.c
+++ b/libavcodec/x86/mpegvideoenc_template.c
@@ -92,7 +92,7 @@
 #endif
 
 static int RENAME(dct_quantize)(MpegEncContext *s,
-                            DCTELEM *block, int n,
+                            int16_t *block, int n,
                             int qscale, int *overflow)
 {
     x86_reg last_non_zero_p1;
diff --git a/libavcodec/x86/pngdsp_init.c b/libavcodec/x86/pngdsp_init.c
index 2355eee..4c54ed3 100644
--- a/libavcodec/x86/pngdsp_init.c
+++ b/libavcodec/x86/pngdsp_init.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 "libavutil/x86/cpu.h"
 #include "libavcodec/pngdsp.h"
@@ -32,7 +33,7 @@
 void ff_add_bytes_l2_sse2(uint8_t *dst, uint8_t *src1,
                           uint8_t *src2, int w);
 
-void ff_pngdsp_init_x86(PNGDSPContext *dsp)
+av_cold void ff_pngdsp_init_x86(PNGDSPContext *dsp)
 {
     int flags = av_get_cpu_flags();
 
diff --git a/libavcodec/x86/proresdsp.asm b/libavcodec/x86/proresdsp.asm
index 094f872..aedacc2 100644
--- a/libavcodec/x86/proresdsp.asm
+++ b/libavcodec/x86/proresdsp.asm
@@ -232,7 +232,7 @@
 %endmacro
 
 ; void prores_idct_put_10_<opt>(uint8_t *pixels, int stride,
-;                               DCTELEM *block, const int16_t *qmat);
+;                               int16_t *block, const int16_t *qmat);
 %macro idct_put_fn 1
 cglobal prores_idct_put_10, 4, 4, %1
     movsxd      r1,  r1d
diff --git a/libavcodec/x86/proresdsp_init.c b/libavcodec/x86/proresdsp_init.c
index 21ce098..91ff257 100644
--- a/libavcodec/x86/proresdsp_init.c
+++ b/libavcodec/x86/proresdsp_init.c
@@ -21,14 +21,15 @@
  */
 
 #include "libavutil/x86/cpu.h"
+#include "libavcodec/dsputil.h"
 #include "libavcodec/proresdsp.h"
 
 void ff_prores_idct_put_10_sse2(uint16_t *dst, int linesize,
-                                DCTELEM *block, const int16_t *qmat);
+                                int16_t *block, const int16_t *qmat);
 void ff_prores_idct_put_10_sse4(uint16_t *dst, int linesize,
-                                DCTELEM *block, const int16_t *qmat);
+                                int16_t *block, const int16_t *qmat);
 void ff_prores_idct_put_10_avx (uint16_t *dst, int linesize,
-                                DCTELEM *block, const int16_t *qmat);
+                                int16_t *block, const int16_t *qmat);
 
 void ff_proresdsp_x86_init(ProresDSPContext *dsp, AVCodecContext *avctx)
 {
diff --git a/libavcodec/x86/rv34dsp.asm b/libavcodec/x86/rv34dsp.asm
index c099ac5..4d9c35b 100644
--- a/libavcodec/x86/rv34dsp.asm
+++ b/libavcodec/x86/rv34dsp.asm
@@ -133,7 +133,7 @@
     mova        mm5, [pd_512]           ; 0x200
 %endmacro
 
-; ff_rv34_idct_add_mmxext(uint8_t *dst, ptrdiff_t stride, DCTELEM *block);
+; ff_rv34_idct_add_mmxext(uint8_t *dst, ptrdiff_t stride, int16_t *block);
 %macro COL_TRANSFORM  4
     pshufw      mm3, %2, 0xDD        ; col. 1,3,1,3
     pshufw       %2, %2, 0x88        ; col. 0,2,0,2
diff --git a/libavcodec/x86/rv34dsp_init.c b/libavcodec/x86/rv34dsp_init.c
index 6b6cf91..a2dea74 100644
--- a/libavcodec/x86/rv34dsp_init.c
+++ b/libavcodec/x86/rv34dsp_init.c
@@ -22,16 +22,15 @@
 #include "libavutil/cpu.h"
 #include "libavutil/x86/asm.h"
 #include "libavutil/x86/cpu.h"
-#include "libavcodec/dsputil.h"
 #include "libavcodec/rv34dsp.h"
 
-void ff_rv34_idct_dc_mmxext(DCTELEM *block);
-void ff_rv34_idct_dc_noround_mmxext(DCTELEM *block);
+void ff_rv34_idct_dc_mmxext(int16_t *block);
+void ff_rv34_idct_dc_noround_mmxext(int16_t *block);
 void ff_rv34_idct_dc_add_mmx(uint8_t *dst, ptrdiff_t stride, int dc);
 void ff_rv34_idct_dc_add_sse4(uint8_t *dst, ptrdiff_t stride, int dc);
-void ff_rv34_idct_add_mmxext(uint8_t *dst, ptrdiff_t stride, DCTELEM *block);
+void ff_rv34_idct_add_mmxext(uint8_t *dst, ptrdiff_t stride, int16_t *block);
 
-av_cold void ff_rv34dsp_init_x86(RV34DSPContext* c, DSPContext *dsp)
+av_cold void ff_rv34dsp_init_x86(RV34DSPContext* c)
 {
     int mm_flags = av_get_cpu_flags();
 
diff --git a/libavcodec/x86/rv40dsp_init.c b/libavcodec/x86/rv40dsp_init.c
index 06ee86e..51e9852 100644
--- a/libavcodec/x86/rv40dsp_init.c
+++ b/libavcodec/x86/rv40dsp_init.c
@@ -27,6 +27,7 @@
  */
 
 #include "libavcodec/rv34dsp.h"
+#include "libavutil/attributes.h"
 #include "libavutil/mem.h"
 #include "libavutil/x86/cpu.h"
 #include "dsputil_mmx.h"
@@ -187,7 +188,7 @@
 
 #endif /* HAVE_YASM */
 
-void ff_rv40dsp_init_x86(RV34DSPContext *c, DSPContext *dsp)
+av_cold void ff_rv40dsp_init_x86(RV34DSPContext *c)
 {
 #if HAVE_YASM
     int mm_flags = av_get_cpu_flags();
diff --git a/libavcodec/x86/sbrdsp.asm b/libavcodec/x86/sbrdsp.asm
index c351de4..1b7f3a8 100644
--- a/libavcodec/x86/sbrdsp.asm
+++ b/libavcodec/x86/sbrdsp.asm
@@ -21,8 +21,12 @@
 
 %include "libavutil/x86/x86util.asm"
 
-;SECTION_RODATA
-SECTION .text
+SECTION_RODATA
+; mask equivalent for multiply by -1.0 1.0
+ps_mask         times 2 dd 1<<31, 0
+ps_neg          times 4 dd 1<<31
+
+SECTION_TEXT
 
 INIT_XMM sse
 cglobal sbr_sum_square, 2, 3, 6
@@ -112,3 +116,107 @@
     jnz         .loop1
 .end:
     RET
+
+; static void sbr_hf_gen_c(float (*X_high)[2], const float (*X_low)[2],
+;                          const float alpha0[2], const float alpha1[2],
+;                          float bw, int start, int end)
+;
+cglobal sbr_hf_gen, 4,4,8, X_high, X_low, alpha0, alpha1, BW, S, E
+    ; load alpha factors
+%define bw m0
+%if ARCH_X86_64 == 0 || WIN64
+    movss      bw, BWm
+%endif
+    movlps     m2, [alpha1q]
+    movlps     m1, [alpha0q]
+    shufps     bw, bw, 0
+    mulps      m2, bw             ; (a1[0] a1[1])*bw
+    mulps      m1, bw             ; (a0[0] a0[1])*bw    = (a2 a3)
+    mulps      m2, bw             ; (a1[0] a1[1])*bw*bw = (a0 a1)
+    mova       m3, m1
+    mova       m4, m2
+
+    ; Set pointers
+%if ARCH_X86_64 == 0 || WIN64
+    ; start and end 6th and 7th args on stack
+    mov        r2d, Sm
+    mov        r3d, Em
+%define  start r2q
+%define  end   r3q
+%else
+; BW does not actually occupy a register, so shift by 1
+%define  start BWq
+%define  end   Sq
+%endif
+    sub      start, end          ; neg num of loops
+    lea    X_highq, [X_highq + end*2*4]
+    lea     X_lowq, [X_lowq  + end*2*4 - 2*2*4]
+    shl      start, 3            ; offset from num loops
+
+    mova        m0, [X_lowq + start]
+    shufps      m3, m3, q1111
+    shufps      m4, m4, q1111
+    xorps       m3, [ps_mask]
+    shufps      m1, m1, q0000
+    shufps      m2, m2, q0000
+    xorps       m4, [ps_mask]
+.loop2:
+    movu        m7, [X_lowq + start + 8]        ; BbCc
+    mova        m6, m0
+    mova        m5, m7
+    shufps      m0, m0, q2301                   ; aAbB
+    shufps      m7, m7, q2301                   ; bBcC
+    mulps       m0, m4
+    mulps       m7, m3
+    mulps       m6, m2
+    mulps       m5, m1
+    addps       m7, m0
+    mova        m0, [X_lowq + start +16]        ; CcDd
+    addps       m7, m0
+    addps       m6, m5
+    addps       m7, m6
+    mova  [X_highq + start], m7
+    add     start, 16
+    jnz         .loop2
+    RET
+
+cglobal sbr_sum64x5, 1,2,4,z
+    lea    r1q, [zq+ 256]
+.loop:
+    mova    m0, [zq+   0]
+    mova    m2, [zq+  16]
+    mova    m1, [zq+ 256]
+    mova    m3, [zq+ 272]
+    addps   m0, [zq+ 512]
+    addps   m2, [zq+ 528]
+    addps   m1, [zq+ 768]
+    addps   m3, [zq+ 784]
+    addps   m0, [zq+1024]
+    addps   m2, [zq+1040]
+    addps   m0, m1
+    addps   m2, m3
+    mova  [zq], m0
+    mova  [zq+16], m2
+    add     zq, 32
+    cmp     zq, r1q
+    jne  .loop
+    REP_RET
+
+INIT_XMM sse
+cglobal sbr_qmf_post_shuffle, 2,3,4,W,z
+    lea              r2q, [zq + (64-4)*4]
+    mova              m3, [ps_neg]
+.loop:
+    mova              m1, [zq]
+    xorps             m0, m3, [r2q]
+    shufps            m0, m0, m0, q0123
+    unpcklps          m2, m0, m1
+    unpckhps          m0, m0, m1
+    mova       [Wq +  0], m2
+    mova       [Wq + 16], m0
+    add               Wq, 32
+    sub              r2q, 16
+    add               zq, 16
+    cmp               zq, r2q
+    jl             .loop
+    REP_RET
diff --git a/libavcodec/x86/sbrdsp_init.c b/libavcodec/x86/sbrdsp_init.c
index d272896..27fade1 100644
--- a/libavcodec/x86/sbrdsp_init.c
+++ b/libavcodec/x86/sbrdsp_init.c
@@ -20,20 +20,29 @@
  */
 
 #include "config.h"
+#include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
 #include "libavutil/x86/cpu.h"
 #include "libavcodec/sbrdsp.h"
 
 float ff_sbr_sum_square_sse(float (*x)[2], int n);
+void ff_sbr_sum64x5_sse(float *z);
 void ff_sbr_hf_g_filt_sse(float (*Y)[2], const float (*X_high)[40][2],
                           const float *g_filt, int m_max, intptr_t ixh);
+void ff_sbr_hf_gen_sse(float (*X_high)[2], const float (*X_low)[2],
+                       const float alpha0[2], const float alpha1[2],
+                       float bw, int start, int end);
+void ff_sbr_qmf_post_shuffle_sse(float W[32][2], const float *z);
 
-void ff_sbrdsp_init_x86(SBRDSPContext *s)
+av_cold void ff_sbrdsp_init_x86(SBRDSPContext *s)
 {
     int mm_flags = av_get_cpu_flags();
 
     if (EXTERNAL_SSE(mm_flags)) {
         s->sum_square = ff_sbr_sum_square_sse;
+        s->sum64x5    = ff_sbr_sum64x5_sse;
         s->hf_g_filt  = ff_sbr_hf_g_filt_sse;
+        s->hf_gen     = ff_sbr_hf_gen_sse;
+        s->qmf_post_shuffle = ff_sbr_qmf_post_shuffle_sse;
     }
 }
diff --git a/libavcodec/x86/simple_idct.c b/libavcodec/x86/simple_idct.c
index c514d75..f27d2b9 100644
--- a/libavcodec/x86/simple_idct.c
+++ b/libavcodec/x86/simple_idct.c
@@ -19,7 +19,6 @@
  * 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/dsputil.h"
 #include "libavcodec/simple_idct.h"
 #include "libavutil/mem.h"
 #include "dsputil_mmx.h"
@@ -1154,12 +1153,12 @@
 
 //FIXME merge add/put into the idct
 
-void ff_simple_idct_put_mmx(uint8_t *dest, int line_size, DCTELEM *block)
+void ff_simple_idct_put_mmx(uint8_t *dest, int line_size, int16_t *block)
 {
     idct(block);
     ff_put_pixels_clamped_mmx(block, dest, line_size);
 }
-void ff_simple_idct_add_mmx(uint8_t *dest, int line_size, DCTELEM *block)
+void ff_simple_idct_add_mmx(uint8_t *dest, int line_size, int16_t *block)
 {
     idct(block);
     ff_add_pixels_clamped_mmx(block, dest, line_size);
diff --git a/libavcodec/x86/snowdsp.c b/libavcodec/x86/snowdsp.c
index 631291a..5505ee8 100644
--- a/libavcodec/x86/snowdsp.c
+++ b/libavcodec/x86/snowdsp.c
@@ -23,7 +23,7 @@
 #include "libavutil/x86/asm.h"
 #include "libavcodec/avcodec.h"
 #include "libavcodec/snow.h"
-#include "libavcodec/dwt.h"
+#include "libavcodec/snow_dwt.h"
 #include "dsputil_mmx.h"
 
 #if HAVE_INLINE_ASM
@@ -875,7 +875,7 @@
 
 #endif /* HAVE_INLINE_ASM */
 
-void ff_dwt_init_x86(DWTContext *c)
+void ff_dwt_init_x86(SnowDWTContext *c)
 {
 #if HAVE_INLINE_ASM
     int mm_flags = av_get_cpu_flags();
diff --git a/libavcodec/x86/vc1dsp_init.c b/libavcodec/x86/vc1dsp_init.c
index 230d06f..3f0b67c 100644
--- a/libavcodec/x86/vc1dsp_init.c
+++ b/libavcodec/x86/vc1dsp_init.c
@@ -27,6 +27,7 @@
 #include "libavutil/cpu.h"
 #include "libavutil/x86/cpu.h"
 #include "libavcodec/vc1dsp.h"
+#include "dsputil_mmx.h"
 #include "vc1dsp.h"
 #include "config.h"
 
@@ -60,6 +61,12 @@
     ff_vc1_h_loop_filter8_sse4(src,          stride, pq);
     ff_vc1_h_loop_filter8_sse4(src+8*stride, stride, pq);
 }
+
+static void avg_vc1_mspel_mc00_mmxext(uint8_t *dst, const uint8_t *src,
+                                      int stride, int rnd)
+{
+    ff_avg_pixels8_mmxext(dst, src, stride, 8);
+}
 #endif /* HAVE_YASM */
 
 void ff_put_vc1_chroma_mc8_nornd_mmx  (uint8_t *dst, uint8_t *src,
@@ -100,6 +107,8 @@
     if (mm_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) {
         dsp->avg_no_rnd_vc1_chroma_pixels_tab[0] = ff_avg_vc1_chroma_mc8_nornd_3dnow;
     }
diff --git a/libavcodec/x86/vc1dsp_mmx.c b/libavcodec/x86/vc1dsp_mmx.c
index 6ce65e4..d1e4b9d 100644
--- a/libavcodec/x86/vc1dsp_mmx.c
+++ b/libavcodec/x86/vc1dsp_mmx.c
@@ -28,7 +28,6 @@
 #include "libavutil/mem.h"
 #include "libavutil/x86/asm.h"
 #include "libavutil/x86/cpu.h"
-#include "libavcodec/dsputil.h"
 #include "dsputil_mmx.h"
 #include "libavcodec/vc1dsp.h"
 #include "vc1dsp.h"
@@ -493,7 +492,7 @@
 DECLARE_FUNCTION(3, 3)
 
 static void vc1_inv_trans_4x4_dc_mmxext(uint8_t *dest, int linesize,
-                                        DCTELEM *block)
+                                        int16_t *block)
 {
     int dc = block[0];
     dc = (17 * dc +  4) >> 3;
@@ -532,7 +531,7 @@
 }
 
 static void vc1_inv_trans_4x8_dc_mmxext(uint8_t *dest, int linesize,
-                                        DCTELEM *block)
+                                        int16_t *block)
 {
     int dc = block[0];
     dc = (17 * dc +  4) >> 3;
@@ -594,7 +593,7 @@
 }
 
 static void vc1_inv_trans_8x4_dc_mmxext(uint8_t *dest, int linesize,
-                                        DCTELEM *block)
+                                        int16_t *block)
 {
     int dc = block[0];
     dc = ( 3 * dc +  1) >> 1;
@@ -633,7 +632,7 @@
 }
 
 static void vc1_inv_trans_8x8_dc_mmxext(uint8_t *dest, int linesize,
-                                        DCTELEM *block)
+                                        int16_t *block)
 {
     int dc = block[0];
     dc = (3 * dc +  1) >> 1;
@@ -719,7 +718,6 @@
 
 av_cold void ff_vc1dsp_init_mmxext(VC1DSPContext *dsp)
 {
-        dsp->avg_vc1_mspel_pixels_tab[ 0] = ff_avg_vc1_mspel_mc00_mmxext;
         dsp->avg_vc1_mspel_pixels_tab[ 4] = avg_vc1_mspel_mc01_mmxext;
         dsp->avg_vc1_mspel_pixels_tab[ 8] = avg_vc1_mspel_mc02_mmxext;
         dsp->avg_vc1_mspel_pixels_tab[12] = avg_vc1_mspel_mc03_mmxext;
diff --git a/libavcodec/x86/videodsp.asm b/libavcodec/x86/videodsp.asm
new file mode 100644
index 0000000..0eb4721
--- /dev/null
+++ b/libavcodec/x86/videodsp.asm
@@ -0,0 +1,612 @@
+;******************************************************************************
+;* Core video DSP functions
+;* Copyright (c) 2012 Ronald S. Bultje <rsbultje@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/x86/x86util.asm"
+
+SECTION .text
+
+; extern void ff_emu_edge_core(uint8_t *buf, const uint8_t *src, x86_reg linesize,
+;                              x86_reg start_y, x86_reg end_y, x86_reg block_h,
+;                              x86_reg start_x, x86_reg end_x, x86_reg block_w);
+;
+; The actual function itself is below. It basically wraps a very simple
+; w = end_x - start_x
+; if (w) {
+;   if (w > 22) {
+;     jump to the slow loop functions
+;   } else {
+;     jump to the fast loop functions
+;   }
+; }
+;
+; ... and then the same for left/right extend also. See below for loop
+; function implementations. Fast are fixed-width, slow is variable-width
+
+%macro EMU_EDGE_FUNC 0
+%if ARCH_X86_64
+%define w_reg r7
+cglobal emu_edge_core, 6, 9, 1
+    mov         r8, r5          ; save block_h
+%else
+%define w_reg r6
+cglobal emu_edge_core, 2, 7, 0
+    mov         r4, r4m         ; end_y
+    mov         r5, r5m         ; block_h
+%endif
+
+    ; start with vertical extend (top/bottom) and body pixel copy
+    mov      w_reg, r7m
+    sub      w_reg, r6m         ; w = start_x - end_x
+    sub         r5, r4
+%if ARCH_X86_64
+    sub         r4, r3
+%else
+    sub         r4, dword r3m
+%endif
+    cmp      w_reg, 22
+    jg .slow_v_extend_loop
+%if ARCH_X86_32
+    mov         r2, r2m         ; linesize
+%endif
+    sal      w_reg, 7           ; w * 128
+%ifdef PIC
+    lea        rax, [.emuedge_v_extend_1 - (.emuedge_v_extend_2 - .emuedge_v_extend_1)]
+    add      w_reg, rax
+%else
+    lea      w_reg, [.emuedge_v_extend_1 - (.emuedge_v_extend_2 - .emuedge_v_extend_1)+w_reg]
+%endif
+    call     w_reg              ; fast top extend, body copy and bottom extend
+.v_extend_end:
+
+    ; horizontal extend (left/right)
+    mov      w_reg, r6m         ; start_x
+    sub         r0, w_reg
+%if ARCH_X86_64
+    mov         r3, r0          ; backup of buf+block_h*linesize
+    mov         r5, r8
+%else
+    mov        r0m, r0          ; backup of buf+block_h*linesize
+    mov         r5, r5m
+%endif
+    test     w_reg, w_reg
+    jz .right_extend
+    cmp      w_reg, 22
+    jg .slow_left_extend_loop
+    mov         r1, w_reg
+    dec      w_reg
+    ; FIXME we can do a if size == 1 here if that makes any speed difference, test me
+    sar      w_reg, 1
+    sal      w_reg, 6
+    ; r0=buf+block_h*linesize,r7(64)/r6(32)=start_x offset for funcs
+    ; r6(rax)/r3(ebx)=val,r2=linesize,r1=start_x,r5=block_h
+%ifdef PIC
+    lea        rax, [.emuedge_extend_left_2]
+    add      w_reg, rax
+%else
+    lea      w_reg, [.emuedge_extend_left_2+w_reg]
+%endif
+    call     w_reg
+
+    ; now r3(64)/r0(32)=buf,r2=linesize,r8/r5=block_h,r6/r3=val, r7/r6=end_x, r1=block_w
+.right_extend:
+%if ARCH_X86_32
+    mov         r0, r0m
+    mov         r5, r5m
+%endif
+    mov      w_reg, r7m         ; end_x
+    mov         r1, r8m         ; block_w
+    mov         r4, r1
+    sub         r1, w_reg
+    jz .h_extend_end            ; if (end_x == block_w) goto h_extend_end
+    cmp         r1, 22
+    jg .slow_right_extend_loop
+    dec         r1
+    ; FIXME we can do a if size == 1 here if that makes any speed difference, test me
+    sar         r1, 1
+    sal         r1, 6
+%ifdef PIC
+    lea        rax, [.emuedge_extend_right_2]
+    add         r1, rax
+%else
+    lea         r1, [.emuedge_extend_right_2+r1]
+%endif
+    call        r1
+.h_extend_end:
+    RET
+
+%if ARCH_X86_64
+%define vall  al
+%define valh  ah
+%define valw  ax
+%define valw2 r7w
+%define valw3 r3w
+%if WIN64
+%define valw4 r7w
+%else ; unix64
+%define valw4 r3w
+%endif
+%define vald eax
+%else
+%define vall  bl
+%define valh  bh
+%define valw  bx
+%define valw2 r6w
+%define valw3 valw2
+%define valw4 valw3
+%define vald ebx
+%define stack_offset 0x14
+%endif
+
+%endmacro
+
+; macro to read/write a horizontal number of pixels (%2) to/from registers
+; on x86-64, - fills xmm0-15 for consecutive sets of 16 pixels
+;            - if (%2 & 15 == 8) fills the last 8 bytes into rax
+;            - else if (%2 & 8)  fills 8 bytes into mm0
+;            - if (%2 & 7 == 4)  fills the last 4 bytes into rax
+;            - else if (%2 & 4)  fills 4 bytes into mm0-1
+;            - if (%2 & 3 == 3)  fills 2 bytes into r7/r3, and 1 into eax
+;              (note that we're using r3 for body/bottom because it's a shorter
+;               opcode, and then the loop fits in 128 bytes)
+;            - else              fills remaining bytes into rax
+; on x86-32, - fills mm0-7 for consecutive sets of 8 pixels
+;            - if (%2 & 7 == 4)  fills 4 bytes into ebx
+;            - else if (%2 & 4)  fills 4 bytes into mm0-7
+;            - if (%2 & 3 == 3)  fills 2 bytes into r6, and 1 into ebx
+;            - else              fills remaining bytes into ebx
+; writing data out is in the same way
+%macro READ_NUM_BYTES 2
+%assign %%src_off 0 ; offset in source buffer
+%assign %%smidx   0 ; mmx register idx
+%assign %%sxidx   0 ; xmm register idx
+
+%if cpuflag(sse)
+%rep %2/16
+    movups xmm %+ %%sxidx, [r1+%%src_off]
+%assign %%src_off %%src_off+16
+%assign %%sxidx   %%sxidx+1
+%endrep ; %2/16
+%endif
+
+%if ARCH_X86_64
+%if (%2-%%src_off) == 8
+    mov           rax, [r1+%%src_off]
+%assign %%src_off %%src_off+8
+%endif ; (%2-%%src_off) == 8
+%endif ; x86-64
+
+%rep (%2-%%src_off)/8
+    movq    mm %+ %%smidx, [r1+%%src_off]
+%assign %%src_off %%src_off+8
+%assign %%smidx   %%smidx+1
+%endrep ; (%2-%%dst_off)/8
+
+%if (%2-%%src_off) == 4
+    mov          vald, [r1+%%src_off]
+%elif (%2-%%src_off) & 4
+    movd    mm %+ %%smidx, [r1+%%src_off]
+%assign %%src_off %%src_off+4
+%endif ; (%2-%%src_off) ==/& 4
+
+%if (%2-%%src_off) == 1
+    mov          vall, [r1+%%src_off]
+%elif (%2-%%src_off) == 2
+    mov          valw, [r1+%%src_off]
+%elif (%2-%%src_off) == 3
+%ifidn %1, top
+    mov         valw2, [r1+%%src_off]
+%elifidn %1, body
+    mov         valw3, [r1+%%src_off]
+%elifidn %1, bottom
+    mov         valw4, [r1+%%src_off]
+%endif ; %1 ==/!= top
+    mov          vall, [r1+%%src_off+2]
+%endif ; (%2-%%src_off) == 1/2/3
+%endmacro ; READ_NUM_BYTES
+
+%macro WRITE_NUM_BYTES 2
+%assign %%dst_off 0 ; offset in destination buffer
+%assign %%dmidx   0 ; mmx register idx
+%assign %%dxidx   0 ; xmm register idx
+
+%if cpuflag(sse)
+%rep %2/16
+    movups [r0+%%dst_off], xmm %+ %%dxidx
+%assign %%dst_off %%dst_off+16
+%assign %%dxidx   %%dxidx+1
+%endrep ; %2/16
+%endif
+
+%if ARCH_X86_64
+%if (%2-%%dst_off) == 8
+    mov    [r0+%%dst_off], rax
+%assign %%dst_off %%dst_off+8
+%endif ; (%2-%%dst_off) == 8
+%endif ; x86-64
+
+%rep (%2-%%dst_off)/8
+    movq   [r0+%%dst_off], mm %+ %%dmidx
+%assign %%dst_off %%dst_off+8
+%assign %%dmidx   %%dmidx+1
+%endrep ; (%2-%%dst_off)/8
+
+%if (%2-%%dst_off) == 4
+    mov    [r0+%%dst_off], vald
+%elif (%2-%%dst_off) & 4
+    movd   [r0+%%dst_off], mm %+ %%dmidx
+%assign %%dst_off %%dst_off+4
+%endif ; (%2-%%dst_off) ==/& 4
+
+%if (%2-%%dst_off) == 1
+    mov    [r0+%%dst_off], vall
+%elif (%2-%%dst_off) == 2
+    mov    [r0+%%dst_off], valw
+%elif (%2-%%dst_off) == 3
+%ifidn %1, top
+    mov    [r0+%%dst_off], valw2
+%elifidn %1, body
+    mov    [r0+%%dst_off], valw3
+%elifidn %1, bottom
+    mov    [r0+%%dst_off], valw4
+%endif ; %1 ==/!= top
+    mov  [r0+%%dst_off+2], vall
+%endif ; (%2-%%dst_off) == 1/2/3
+%endmacro ; WRITE_NUM_BYTES
+
+; vertical top/bottom extend and body copy fast loops
+; these are function pointers to set-width line copy functions, i.e.
+; they read a fixed number of pixels into set registers, and write
+; those out into the destination buffer
+; r0=buf,r1=src,r2=linesize,r3(64)/r3m(32)=start_x,r4=end_y,r5=block_h
+; r6(eax/64)/r3(ebx/32)=val_reg
+%macro VERTICAL_EXTEND 0
+%assign %%n 1
+%rep 22
+ALIGN 128
+.emuedge_v_extend_ %+ %%n:
+    ; extend pixels above body
+%if ARCH_X86_64
+    test           r3 , r3                   ; if (!start_y)
+    jz .emuedge_copy_body_ %+ %%n %+ _loop   ;   goto body
+%else ; ARCH_X86_32
+    cmp      dword r3m, 0
+    je .emuedge_copy_body_ %+ %%n %+ _loop
+%endif ; ARCH_X86_64/32
+    READ_NUM_BYTES  top,    %%n              ; read bytes
+.emuedge_extend_top_ %+ %%n %+ _loop:        ; do {
+    WRITE_NUM_BYTES top,    %%n              ;   write bytes
+    add            r0 , r2                   ;   dst += linesize
+%if ARCH_X86_64
+    dec            r3d
+%else ; ARCH_X86_32
+    dec      dword r3m
+%endif ; ARCH_X86_64/32
+    jnz .emuedge_extend_top_ %+ %%n %+ _loop ; } while (--start_y)
+
+    ; copy body pixels
+.emuedge_copy_body_ %+ %%n %+ _loop:         ; do {
+    READ_NUM_BYTES  body,   %%n              ;   read bytes
+    WRITE_NUM_BYTES body,   %%n              ;   write bytes
+    add            r0 , r2                   ;   dst += linesize
+    add            r1 , r2                   ;   src += linesize
+    dec            r4d
+    jnz .emuedge_copy_body_ %+ %%n %+ _loop  ; } while (--end_y)
+
+    ; copy bottom pixels
+    test           r5 , r5                   ; if (!block_h)
+    jz .emuedge_v_extend_end_ %+ %%n         ;   goto end
+    sub            r1 , r2                   ; src -= linesize
+    READ_NUM_BYTES  bottom, %%n              ; read bytes
+.emuedge_extend_bottom_ %+ %%n %+ _loop:     ; do {
+    WRITE_NUM_BYTES bottom, %%n              ;   write bytes
+    add            r0 , r2                   ;   dst += linesize
+    dec            r5d
+    jnz .emuedge_extend_bottom_ %+ %%n %+ _loop ; } while (--block_h)
+
+.emuedge_v_extend_end_ %+ %%n:
+%if ARCH_X86_64
+    ret
+%else ; ARCH_X86_32
+    rep ret
+%endif ; ARCH_X86_64/32
+%assign %%n %%n+1
+%endrep
+%endmacro VERTICAL_EXTEND
+
+; left/right (horizontal) fast extend functions
+; these are essentially identical to the vertical extend ones above,
+; just left/right separated because number of pixels to extend is
+; obviously not the same on both sides.
+; for reading, pixels are placed in eax (x86-64) or ebx (x86-64) in the
+; lowest two bytes of the register (so val*0x0101), and are splatted
+; into each byte of mm0 as well if n_pixels >= 8
+
+%macro READ_V_PIXEL 2
+    mov        vall, %2
+    mov        valh, vall
+%if %1 >= 8
+    movd        mm0, vald
+%if cpuflag(mmxext)
+    pshufw      mm0, mm0, 0
+%else ; mmx
+    punpcklwd   mm0, mm0
+    punpckldq   mm0, mm0
+%endif ; sse
+%endif ; %1 >= 8
+%endmacro
+
+%macro WRITE_V_PIXEL 2
+%assign %%dst_off 0
+%rep %1/8
+    movq [%2+%%dst_off], mm0
+%assign %%dst_off %%dst_off+8
+%endrep
+%if %1 & 4
+%if %1 >= 8
+    movd [%2+%%dst_off], mm0
+%else ; %1 < 8
+    mov  [%2+%%dst_off]  , valw
+    mov  [%2+%%dst_off+2], valw
+%endif ; %1 >=/< 8
+%assign %%dst_off %%dst_off+4
+%endif ; %1 & 4
+%if %1&2
+    mov  [%2+%%dst_off], valw
+%endif ; %1 & 2
+%endmacro
+
+; r0=buf+block_h*linesize, r1=start_x, r2=linesize, r5=block_h, r6/r3=val
+%macro LEFT_EXTEND 0
+%assign %%n 2
+%rep 11
+ALIGN 64
+.emuedge_extend_left_ %+ %%n:          ; do {
+    sub         r0, r2                 ;   dst -= linesize
+    READ_V_PIXEL  %%n, [r0+r1]         ;   read pixels
+    WRITE_V_PIXEL %%n, r0              ;   write pixels
+    dec         r5
+    jnz .emuedge_extend_left_ %+ %%n   ; } while (--block_h)
+%if ARCH_X86_64
+    ret
+%else ; ARCH_X86_32
+    rep ret
+%endif ; ARCH_X86_64/32
+%assign %%n %%n+2
+%endrep
+%endmacro ; LEFT_EXTEND
+
+; r3/r0=buf+block_h*linesize, r2=linesize, r8/r5=block_h, r0/r6=end_x, r6/r3=val
+%macro RIGHT_EXTEND 0
+%assign %%n 2
+%rep 11
+ALIGN 64
+.emuedge_extend_right_ %+ %%n:          ; do {
+%if ARCH_X86_64
+    sub        r3, r2                   ;   dst -= linesize
+    READ_V_PIXEL  %%n, [r3+w_reg-1]     ;   read pixels
+    WRITE_V_PIXEL %%n, r3+r4-%%n        ;   write pixels
+    dec       r8
+%else ; ARCH_X86_32
+    sub        r0, r2                   ;   dst -= linesize
+    READ_V_PIXEL  %%n, [r0+w_reg-1]     ;   read pixels
+    WRITE_V_PIXEL %%n, r0+r4-%%n        ;   write pixels
+    dec     r5
+%endif ; ARCH_X86_64/32
+    jnz .emuedge_extend_right_ %+ %%n   ; } while (--block_h)
+%if ARCH_X86_64
+    ret
+%else ; ARCH_X86_32
+    rep ret
+%endif ; ARCH_X86_64/32
+%assign %%n %%n+2
+%endrep
+
+%if ARCH_X86_32
+%define stack_offset 0x10
+%endif
+%endmacro ; RIGHT_EXTEND
+
+; below follow the "slow" copy/extend functions, these act on a non-fixed
+; width specified in a register, and run a loop to copy the full amount
+; of bytes. They are optimized for copying of large amounts of pixels per
+; line, so they unconditionally splat data into mm registers to copy 8
+; bytes per loop iteration. It could be considered to use xmm for x86-64
+; also, but I haven't optimized this as much (i.e. FIXME)
+%macro V_COPY_NPX 4-5
+%if %0 == 4
+    test     w_reg, %4
+    jz .%1_skip_%4_px
+%else ; %0 == 5
+.%1_%4_px_loop:
+%endif
+    %3          %2, [r1+cnt_reg]
+    %3 [r0+cnt_reg], %2
+    add    cnt_reg, %4
+%if %0 == 5
+    sub      w_reg, %4
+    test     w_reg, %5
+    jnz .%1_%4_px_loop
+%endif
+.%1_skip_%4_px:
+%endmacro
+
+%macro V_COPY_ROW 2
+%ifidn %1, bottom
+    sub         r1, linesize
+%endif
+.%1_copy_loop:
+    xor    cnt_reg, cnt_reg
+%if notcpuflag(sse)
+%define linesize r2m
+    V_COPY_NPX %1,  mm0, movq,    8, 0xFFFFFFF8
+%else ; sse
+    V_COPY_NPX %1, xmm0, movups, 16, 0xFFFFFFF0
+%if ARCH_X86_64
+%define linesize r2
+    V_COPY_NPX %1, rax , mov,     8
+%else ; ARCH_X86_32
+%define linesize r2m
+    V_COPY_NPX %1,  mm0, movq,    8
+%endif ; ARCH_X86_64/32
+%endif ; sse
+    V_COPY_NPX %1, vald, mov,     4
+    V_COPY_NPX %1, valw, mov,     2
+    V_COPY_NPX %1, vall, mov,     1
+    mov      w_reg, cnt_reg
+%ifidn %1, body
+    add         r1, linesize
+%endif
+    add         r0, linesize
+    dec         %2
+    jnz .%1_copy_loop
+%endmacro
+
+%macro SLOW_V_EXTEND 0
+.slow_v_extend_loop:
+; r0=buf,r1=src,r2(64)/r2m(32)=linesize,r3(64)/r3m(32)=start_x,r4=end_y,r5=block_h
+; r8(64)/r3(later-64)/r2(32)=cnt_reg,r6(64)/r3(32)=val_reg,r7(64)/r6(32)=w=end_x-start_x
+%if ARCH_X86_64
+    push        r8              ; save old value of block_h
+    test        r3, r3
+%define cnt_reg r8
+    jz .do_body_copy            ; if (!start_y) goto do_body_copy
+    V_COPY_ROW top, r3
+%else
+    cmp  dword r3m, 0
+%define cnt_reg r2
+    je .do_body_copy            ; if (!start_y) goto do_body_copy
+    V_COPY_ROW top, dword r3m
+%endif
+
+.do_body_copy:
+    V_COPY_ROW body, r4
+
+%if ARCH_X86_64
+    pop         r8              ; restore old value of block_h
+%define cnt_reg r3
+%endif
+    test        r5, r5
+%if ARCH_X86_64
+    jz .v_extend_end
+%else
+    jz .skip_bottom_extend
+%endif
+    V_COPY_ROW bottom, r5
+%if ARCH_X86_32
+.skip_bottom_extend:
+    mov         r2, r2m
+%endif
+    jmp .v_extend_end
+%endmacro
+
+%macro SLOW_LEFT_EXTEND 0
+.slow_left_extend_loop:
+; r0=buf+block_h*linesize,r2=linesize,r6(64)/r3(32)=val,r5=block_h,r4=cntr,r7/r6=start_x
+    mov         r4, 8
+    sub         r0, linesize
+    READ_V_PIXEL 8, [r0+w_reg]
+.left_extend_8px_loop:
+    movq [r0+r4-8], mm0
+    add         r4, 8
+    cmp         r4, w_reg
+    jle .left_extend_8px_loop
+    sub         r4, 8
+    cmp         r4, w_reg
+    jge .left_extend_loop_end
+.left_extend_2px_loop:
+    mov    [r0+r4], valw
+    add         r4, 2
+    cmp         r4, w_reg
+    jl .left_extend_2px_loop
+.left_extend_loop_end:
+    dec         r5
+    jnz .slow_left_extend_loop
+%if ARCH_X86_32
+    mov         r2, r2m
+%endif
+    jmp .right_extend
+%endmacro
+
+%macro SLOW_RIGHT_EXTEND 0
+.slow_right_extend_loop:
+; r3(64)/r0(32)=buf+block_h*linesize,r2=linesize,r4=block_w,r8(64)/r5(32)=block_h,
+; r7(64)/r6(32)=end_x,r6/r3=val,r1=cntr
+%if ARCH_X86_64
+%define buf_reg r3
+%define bh_reg r8
+%else
+%define buf_reg r0
+%define bh_reg r5
+%endif
+    lea         r1, [r4-8]
+    sub    buf_reg, linesize
+    READ_V_PIXEL 8, [buf_reg+w_reg-1]
+.right_extend_8px_loop:
+    movq [buf_reg+r1], mm0
+    sub         r1, 8
+    cmp         r1, w_reg
+    jge .right_extend_8px_loop
+    add         r1, 8
+    cmp         r1, w_reg
+    je .right_extend_loop_end
+.right_extend_2px_loop:
+    sub         r1, 2
+    mov [buf_reg+r1], valw
+    cmp         r1, w_reg
+    jg .right_extend_2px_loop
+.right_extend_loop_end:
+    dec         bh_reg
+    jnz .slow_right_extend_loop
+    jmp .h_extend_end
+%endmacro
+
+%macro emu_edge 1
+INIT_XMM %1
+EMU_EDGE_FUNC
+VERTICAL_EXTEND
+LEFT_EXTEND
+RIGHT_EXTEND
+SLOW_V_EXTEND
+SLOW_LEFT_EXTEND
+SLOW_RIGHT_EXTEND
+%endmacro
+
+emu_edge sse
+%if ARCH_X86_32
+emu_edge mmx
+%endif
+
+%macro PREFETCH_FN 1
+cglobal prefetch, 3, 3, 0, buf, stride, h
+.loop:
+    %1      [bufq]
+    add      bufq, strideq
+    dec        hd
+    jg .loop
+    REP_RET
+%endmacro
+
+INIT_MMX mmxext
+PREFETCH_FN prefetcht0
+%if ARCH_X86_32
+INIT_MMX 3dnow
+PREFETCH_FN prefetch
+%endif
diff --git a/libavcodec/x86/videodsp_init.c b/libavcodec/x86/videodsp_init.c
new file mode 100644
index 0000000..902450e
--- /dev/null
+++ b/libavcodec/x86/videodsp_init.c
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2002-2012 Michael Niedermayer
+ * Copyright (C) 2012 Ronald S. Bultje
+ *
+ * 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/avassert.h"
+#include "libavutil/common.h"
+#include "libavutil/cpu.h"
+#include "libavutil/mem.h"
+#include "libavutil/x86/asm.h"
+#include "libavcodec/videodsp.h"
+
+#if HAVE_YASM
+typedef void emu_edge_core_func(uint8_t *buf, const uint8_t *src,
+                                x86_reg linesize, x86_reg start_y,
+                                x86_reg end_y, x86_reg block_h,
+                                x86_reg start_x, x86_reg end_x,
+                                x86_reg block_w);
+extern emu_edge_core_func ff_emu_edge_core_mmx;
+extern emu_edge_core_func ff_emu_edge_core_sse;
+
+static av_always_inline void emulated_edge_mc(uint8_t *buf, const uint8_t *src,
+                                              ptrdiff_t linesize_arg,
+                                              int block_w, int block_h,
+                                              int src_x, int src_y,
+                                              int w, int h,
+                                              emu_edge_core_func *core_fn)
+{
+    int start_y, start_x, end_y, end_x, src_y_add = 0;
+    int linesize = linesize_arg;
+
+    if(!w || !h)
+        return;
+
+    if (src_y >= h) {
+        src -= src_y*linesize;
+        src_y_add = h - 1;
+        src_y     = h - 1;
+    } else if (src_y <= -block_h) {
+        src -= src_y*linesize;
+        src_y_add = 1 - block_h;
+        src_y     = 1 - block_h;
+    }
+    if (src_x >= w) {
+        src   += w - 1 - src_x;
+        src_x  = w - 1;
+    } else if (src_x <= -block_w) {
+        src   += 1 - block_w - src_x;
+        src_x  = 1 - block_w;
+    }
+
+    start_y = FFMAX(0, -src_y);
+    start_x = FFMAX(0, -src_x);
+    end_y   = FFMIN(block_h, h-src_y);
+    end_x   = FFMIN(block_w, w-src_x);
+    av_assert2(start_x < end_x && block_w > 0);
+    av_assert2(start_y < end_y && block_h > 0);
+
+    // fill in the to-be-copied part plus all above/below
+    src += (src_y_add + start_y) * linesize + start_x;
+    buf += start_x;
+    core_fn(buf, src, linesize, start_y, end_y,
+            block_h, start_x, end_x, block_w);
+}
+
+#if ARCH_X86_32
+static av_noinline void emulated_edge_mc_mmx(uint8_t *buf, const uint8_t *src,
+                                             ptrdiff_t linesize,
+                                             int block_w, int block_h,
+                                             int src_x, int src_y, int w, int h)
+{
+    emulated_edge_mc(buf, src, linesize, block_w, block_h, src_x, src_y,
+                     w, h, &ff_emu_edge_core_mmx);
+}
+#endif
+
+static av_noinline void emulated_edge_mc_sse(uint8_t *buf, const uint8_t *src,
+                                             ptrdiff_t linesize,
+                                             int block_w, int block_h,
+                                             int src_x, int src_y, int w, int h)
+{
+    emulated_edge_mc(buf, src, linesize, block_w, block_h, src_x, src_y,
+                     w, h, &ff_emu_edge_core_sse);
+}
+#endif /* HAVE_YASM */
+
+void ff_prefetch_mmxext(uint8_t *buf, ptrdiff_t stride, int h);
+void ff_prefetch_3dnow(uint8_t *buf, ptrdiff_t stride, int h);
+
+av_cold void ff_videodsp_init_x86(VideoDSPContext *ctx, int bpc)
+{
+#if HAVE_YASM
+    int mm_flags = av_get_cpu_flags();
+
+#if ARCH_X86_32
+    if (bpc <= 8 && mm_flags & AV_CPU_FLAG_MMX) {
+        ctx->emulated_edge_mc = emulated_edge_mc_mmx;
+    }
+    if (mm_flags & AV_CPU_FLAG_3DNOW) {
+        ctx->prefetch = ff_prefetch_3dnow;
+    }
+#endif /* ARCH_X86_32 */
+    if (mm_flags & AV_CPU_FLAG_MMXEXT) {
+        ctx->prefetch = ff_prefetch_mmxext;
+    }
+    if (bpc <= 8 && mm_flags & AV_CPU_FLAG_SSE) {
+        ctx->emulated_edge_mc = emulated_edge_mc_sse;
+    }
+#endif /* HAVE_YASM */
+}
diff --git a/libavcodec/x86/vorbisdsp.asm b/libavcodec/x86/vorbisdsp.asm
new file mode 100644
index 0000000..b25d838
--- /dev/null
+++ b/libavcodec/x86/vorbisdsp.asm
@@ -0,0 +1,83 @@
+;******************************************************************************
+;* Vorbis x86 optimizations
+;* Copyright (C) 2006 Loren Merritt <lorenm@u.washington.edu>
+;*
+;* 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/x86/x86util.asm"
+
+SECTION_RODATA
+
+pdw_80000000: times 4 dd 0x80000000
+
+SECTION .text
+
+%if ARCH_X86_32
+INIT_MMX 3dnow
+cglobal vorbis_inverse_coupling, 3, 3, 6, mag, ang, block_size
+    pxor                     m7, m7
+    lea                    magq, [magq+block_sizeq*4]
+    lea                    angq, [angq+block_sizeq*4]
+    neg             block_sizeq
+.loop:
+    mova                     m0, [magq+block_sizeq*4]
+    mova                     m1, [angq+block_sizeq*4]
+    mova                     m2, m0
+    mova                     m3, m1
+    pfcmpge                  m2, m7     ; m <= 0.0
+    pfcmpge                  m3, m7     ; a <= 0.0
+    pslld                    m2, 31     ; keep only the sign bit
+    pxor                     m1, m2
+    mova                     m4, m3
+    pand                     m3, m1
+    pandn                    m4, m1
+    pfadd                    m3, m0     ; a = m + ((a < 0) & (a ^ sign(m)))
+    pfsub                    m0, m4     ; m = m + ((a > 0) & (a ^ sign(m)))
+    mova   [angq+block_sizeq*4], m3
+    mova   [magq+block_sizeq*4], m0
+    add             block_sizeq, 2
+    jl .loop
+    femms
+    RET
+%endif
+
+INIT_XMM sse
+cglobal vorbis_inverse_coupling, 3, 4, 6, mag, ang, block_size, cntr
+    mova                     m5, [pdw_80000000]
+    xor                   cntrq, cntrq
+align 16
+.loop:
+    mova                     m0, [magq+cntrq*4]
+    mova                     m1, [angq+cntrq*4]
+    xorps                    m2, m2
+    xorps                    m3, m3
+    cmpleps                  m2, m0     ; m <= 0.0
+    cmpleps                  m3, m1     ; a <= 0.0
+    andps                    m2, m5     ; keep only the sign bit
+    xorps                    m1, m2
+    mova                     m4, m3
+    andps                    m3, m1
+    andnps                   m4, m1
+    addps                    m3, m0     ; a = m + ((a < 0) & (a ^ sign(m)))
+    subps                    m0, m4     ; m = m + ((a > 0) & (a ^ sign(m)))
+    mova         [angq+cntrq*4], m3
+    mova         [magq+cntrq*4], m0
+    add                   cntrq, 4
+    cmp                   cntrq, block_sizeq
+    jl .loop
+    RET
diff --git a/libavcodec/x86/vorbisdsp_init.c b/libavcodec/x86/vorbisdsp_init.c
new file mode 100644
index 0000000..08a2c09
--- /dev/null
+++ b/libavcodec/x86/vorbisdsp_init.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2006 Loren Merritt <lorenm@u.washington.edu>
+ *
+ * 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 "libavcodec/vorbisdsp.h"
+
+void ff_vorbis_inverse_coupling_3dnow(float *mag, float *ang,
+                                      intptr_t blocksize);
+void ff_vorbis_inverse_coupling_sse(float *mag, float *ang,
+                                    intptr_t blocksize);
+
+av_cold void ff_vorbisdsp_init_x86(VorbisDSPContext *dsp)
+{
+#if HAVE_YASM
+    int mm_flags = av_get_cpu_flags();
+
+#if ARCH_X86_32
+    if (mm_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)
+        dsp->vorbis_inverse_coupling = ff_vorbis_inverse_coupling_sse;
+#endif /* HAVE_YASM */
+}
diff --git a/libavcodec/x86/vp3dsp.asm b/libavcodec/x86/vp3dsp.asm
index 3a5ed03..be5f21b 100644
--- a/libavcodec/x86/vp3dsp.asm
+++ b/libavcodec/x86/vp3dsp.asm
@@ -562,6 +562,13 @@
 %endif
 %assign %%i %%i+64
 %endrep
+
+    pxor          m0, m0
+%assign %%offset 0
+%rep 128/mmsize
+    mova [r2+%%offset], m0
+%assign %%offset %%offset+mmsize
+%endrep
     RET
 
 cglobal vp3_idct_add, 3, 4, 9
@@ -600,6 +607,11 @@
     movhps   [r0+r1], m0
 %endif
     lea           r0, [r0+r1*2]
+%assign %%offset 0
+%rep 32/mmsize
+    mova [r2+%%offset], m4
+%assign %%offset %%offset+mmsize
+%endrep
     add           r2, 32
     dec           r3
     jg .loop
@@ -620,7 +632,7 @@
     paddusb       m2, m0
     movq          m4, [r0+r1*2]
     paddusb       m3, m0
-    movq          m5, [r0+r3  ]
+    movq          m5, [r0+r2  ]
     paddusb       m4, m0
     paddusb       m5, m0
     psubusb       m2, m1
@@ -630,7 +642,7 @@
     movq   [r0+r1  ], m3
     psubusb       m5, m1
     movq   [r0+r1*2], m4
-    movq   [r0+r3  ], m5
+    movq   [r0+r2  ], m5
 %endmacro
 
 INIT_MMX mmxext
@@ -638,11 +650,12 @@
 %if ARCH_X86_64
     movsxd        r1, r1d
 %endif
-    lea           r3, [r1*3]
-    movsx         r2, word [r2]
-    add           r2, 15
-    sar           r2, 5
-    movd          m0, r2d
+    movsx         r3, word [r2]
+    mov    word [r2], 0
+    lea           r2, [r1*3]
+    add           r3, 15
+    sar           r3, 5
+    movd          m0, r3d
     pshufw        m0, m0, 0x0
     pxor          m1, m1
     psubw         m1, m0
diff --git a/libavcodec/x86/vp3dsp_init.c b/libavcodec/x86/vp3dsp_init.c
index eddfd07..288dbcc 100644
--- a/libavcodec/x86/vp3dsp_init.c
+++ b/libavcodec/x86/vp3dsp_init.c
@@ -1,4 +1,6 @@
 /*
+ * Copyright (c) 2009 David Conrad <lessen42@gmail.com>
+ *
  * This file is part of FFmpeg.
  *
  * FFmpeg is free software; you can redistribute it and/or
@@ -21,28 +23,88 @@
 #include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
 #include "libavutil/x86/cpu.h"
+#include "libavutil/x86/asm.h"
 #include "libavcodec/avcodec.h"
+#include "libavcodec/dsputil.h"
 #include "libavcodec/vp3dsp.h"
 #include "config.h"
 
-void ff_vp3_idct_put_mmx(uint8_t *dest, int line_size, DCTELEM *block);
-void ff_vp3_idct_add_mmx(uint8_t *dest, int line_size, DCTELEM *block);
+void ff_vp3_idct_put_mmx(uint8_t *dest, int line_size, int16_t *block);
+void ff_vp3_idct_add_mmx(uint8_t *dest, int line_size, int16_t *block);
 
-void ff_vp3_idct_put_sse2(uint8_t *dest, int line_size, DCTELEM *block);
-void ff_vp3_idct_add_sse2(uint8_t *dest, int line_size, DCTELEM *block);
+void ff_vp3_idct_put_sse2(uint8_t *dest, int line_size, int16_t *block);
+void ff_vp3_idct_add_sse2(uint8_t *dest, int line_size, int16_t *block);
 
 void ff_vp3_idct_dc_add_mmxext(uint8_t *dest, int line_size,
-                               const DCTELEM *block);
+                               int16_t *block);
 
 void ff_vp3_v_loop_filter_mmxext(uint8_t *src, int stride,
                                  int *bounding_values);
 void ff_vp3_h_loop_filter_mmxext(uint8_t *src, int stride,
                                  int *bounding_values);
 
+#if HAVE_INLINE_ASM
+
+#define MOVQ_BFE(regd)                                  \
+    __asm__ volatile (                                  \
+        "pcmpeqd %%"#regd", %%"#regd"   \n\t"           \
+        "paddb   %%"#regd", %%"#regd"   \n\t" ::)
+
+#define PAVGBP_MMX_NO_RND(rega, regb, regr,  regc, regd, regp)   \
+    "movq  "#rega", "#regr"             \n\t"                    \
+    "movq  "#regc", "#regp"             \n\t"                    \
+    "pand  "#regb", "#regr"             \n\t"                    \
+    "pand  "#regd", "#regp"             \n\t"                    \
+    "pxor  "#rega", "#regb"             \n\t"                    \
+    "pxor  "#regc", "#regd"             \n\t"                    \
+    "pand    %%mm6, "#regb"             \n\t"                    \
+    "pand    %%mm6, "#regd"             \n\t"                    \
+    "psrlq      $1, "#regb"             \n\t"                    \
+    "psrlq      $1, "#regd"             \n\t"                    \
+    "paddb "#regb", "#regr"             \n\t"                    \
+    "paddb "#regd", "#regp"             \n\t"
+
+static void put_vp_no_rnd_pixels8_l2_mmx(uint8_t *dst, const uint8_t *a, const uint8_t *b, ptrdiff_t stride, int h)
+{
+//    START_TIMER
+    MOVQ_BFE(mm6);
+    __asm__ volatile(
+        "1:                             \n\t"
+        "movq   (%1), %%mm0             \n\t"
+        "movq   (%2), %%mm1             \n\t"
+        "movq   (%1,%4), %%mm2          \n\t"
+        "movq   (%2,%4), %%mm3          \n\t"
+        PAVGBP_MMX_NO_RND(%%mm0, %%mm1, %%mm4,   %%mm2, %%mm3, %%mm5)
+        "movq   %%mm4, (%3)             \n\t"
+        "movq   %%mm5, (%3,%4)          \n\t"
+
+        "movq   (%1,%4,2), %%mm0        \n\t"
+        "movq   (%2,%4,2), %%mm1        \n\t"
+        "movq   (%1,%5), %%mm2          \n\t"
+        "movq   (%2,%5), %%mm3          \n\t"
+        "lea    (%1,%4,4), %1           \n\t"
+        "lea    (%2,%4,4), %2           \n\t"
+        PAVGBP_MMX_NO_RND(%%mm0, %%mm1, %%mm4,   %%mm2, %%mm3, %%mm5)
+        "movq   %%mm4, (%3,%4,2)        \n\t"
+        "movq   %%mm5, (%3,%5)          \n\t"
+        "lea    (%3,%4,4), %3           \n\t"
+        "subl   $4, %0                  \n\t"
+        "jnz    1b                      \n\t"
+        :"+r"(h), "+r"(a), "+r"(b), "+r"(dst)
+        :"r"((x86_reg)stride), "r"((x86_reg)3L*stride)
+        :"memory");
+//    STOP_TIMER("put_vp_no_rnd_pixels8_l2_mmx")
+}
+#endif /* HAVE_INLINE_ASM */
+
 av_cold void ff_vp3dsp_init_x86(VP3DSPContext *c, int flags)
 {
     int cpuflags = av_get_cpu_flags();
 
+#if HAVE_INLINE_ASM
+    c->put_no_rnd_pixels_l2 = put_vp_no_rnd_pixels8_l2_mmx;
+#endif /* HAVE_INLINE_ASM */
+
 #if ARCH_X86_32
     if (EXTERNAL_MMX(cpuflags)) {
         c->idct_put  = ff_vp3_idct_put_mmx;
diff --git a/libavcodec/x86/vp56dsp_init.c b/libavcodec/x86/vp56dsp_init.c
index b699f79..defc63b 100644
--- a/libavcodec/x86/vp56dsp_init.c
+++ b/libavcodec/x86/vp56dsp_init.c
@@ -23,7 +23,6 @@
 #include "libavutil/cpu.h"
 #include "libavutil/x86/asm.h"
 #include "libavutil/x86/cpu.h"
-#include "libavcodec/dsputil.h"
 #include "libavcodec/vp56dsp.h"
 
 void ff_vp6_filter_diag4_mmx(uint8_t *dst, uint8_t *src, int stride,
diff --git a/libavcodec/x86/vp8dsp.asm b/libavcodec/x86/vp8dsp.asm
index 19640c8..c5fb455 100644
--- a/libavcodec/x86/vp8dsp.asm
+++ b/libavcodec/x86/vp8dsp.asm
@@ -899,7 +899,7 @@
     REP_RET
 
 ;-----------------------------------------------------------------------------
-; void vp8_idct_dc_add_<opt>(uint8_t *dst, DCTELEM block[16], int stride);
+; void vp8_idct_dc_add_<opt>(uint8_t *dst, int16_t block[16], int stride);
 ;-----------------------------------------------------------------------------
 
 %macro ADD_DC 4
@@ -977,7 +977,7 @@
     RET
 
 ;-----------------------------------------------------------------------------
-; void vp8_idct_dc_add4y_<opt>(uint8_t *dst, DCTELEM block[4][16], int stride);
+; void vp8_idct_dc_add4y_<opt>(uint8_t *dst, int16_t block[4][16], int stride);
 ;-----------------------------------------------------------------------------
 
 %if ARCH_X86_32
@@ -1050,7 +1050,7 @@
     RET
 
 ;-----------------------------------------------------------------------------
-; void vp8_idct_dc_add4uv_<opt>(uint8_t *dst, DCTELEM block[4][16], int stride);
+; void vp8_idct_dc_add4uv_<opt>(uint8_t *dst, int16_t block[4][16], int stride);
 ;-----------------------------------------------------------------------------
 
 INIT_MMX mmx
@@ -1092,7 +1092,7 @@
     RET
 
 ;-----------------------------------------------------------------------------
-; void vp8_idct_add_<opt>(uint8_t *dst, DCTELEM block[16], int stride);
+; void vp8_idct_add_<opt>(uint8_t *dst, int16_t block[16], int stride);
 ;-----------------------------------------------------------------------------
 
 ; calculate %1=mul_35468(%1)-mul_20091(%2); %2=mul_20091(%1)+mul_35468(%2)
@@ -1172,7 +1172,7 @@
 VP8_IDCT_ADD
 
 ;-----------------------------------------------------------------------------
-; void vp8_luma_dc_wht_mmxext(DCTELEM block[4][4][16], DCTELEM dc[16])
+; void vp8_luma_dc_wht_mmxext(int16_t block[4][4][16], int16_t dc[16])
 ;-----------------------------------------------------------------------------
 
 %macro SCATTER_WHT 3
@@ -1634,9 +1634,9 @@
 %define stack_size 0
 %ifndef m8   ; stack layout: [0]=E, [1]=I, [2]=hev_thr
 %ifidn %1, v ;               [3]=hev() result
-%define stack_size mmsize * 4
+%define stack_size mmsize * -4
 %else ; h    ; extra storage space for transposes
-%define stack_size mmsize * 5
+%define stack_size mmsize * -5
 %endif
 %endif
 
@@ -2129,9 +2129,9 @@
                  ;               [4]=filter tmp result
                  ;               [5]/[6] = p2/q2 backup
                  ;               [7]=lim_res sign result
-%define stack_size mmsize * 7
+%define stack_size mmsize * -7
 %else ; 8        ; extra storage space for transposes
-%define stack_size mmsize * 8
+%define stack_size mmsize * -8
 %endif
 %endif
 
diff --git a/libavcodec/x86/vp8dsp_init.c b/libavcodec/x86/vp8dsp_init.c
index 735619c..09e2d91 100644
--- a/libavcodec/x86/vp8dsp_init.c
+++ b/libavcodec/x86/vp8dsp_init.c
@@ -230,21 +230,21 @@
 HVBILIN(ssse3, 8,  8, 16)
 HVBILIN(ssse3, 8, 16, 16)
 
-extern void ff_vp8_idct_dc_add_mmx(uint8_t *dst, DCTELEM block[16],
+extern void ff_vp8_idct_dc_add_mmx(uint8_t *dst, int16_t block[16],
                                    ptrdiff_t stride);
-extern void ff_vp8_idct_dc_add_sse4(uint8_t *dst, DCTELEM block[16],
+extern void ff_vp8_idct_dc_add_sse4(uint8_t *dst, int16_t block[16],
                                     ptrdiff_t stride);
-extern void ff_vp8_idct_dc_add4y_mmx(uint8_t *dst, DCTELEM block[4][16],
+extern void ff_vp8_idct_dc_add4y_mmx(uint8_t *dst, int16_t block[4][16],
                                       ptrdiff_t stride);
-extern void ff_vp8_idct_dc_add4y_sse2(uint8_t *dst, DCTELEM block[4][16],
+extern void ff_vp8_idct_dc_add4y_sse2(uint8_t *dst, int16_t block[4][16],
                                       ptrdiff_t stride);
-extern void ff_vp8_idct_dc_add4uv_mmx(uint8_t *dst, DCTELEM block[2][16],
+extern void ff_vp8_idct_dc_add4uv_mmx(uint8_t *dst, int16_t block[2][16],
                                       ptrdiff_t stride);
-extern void ff_vp8_luma_dc_wht_mmx(DCTELEM block[4][4][16], DCTELEM dc[16]);
-extern void ff_vp8_luma_dc_wht_sse(DCTELEM block[4][4][16], DCTELEM dc[16]);
-extern void ff_vp8_idct_add_mmx(uint8_t *dst, DCTELEM block[16],
+extern void ff_vp8_luma_dc_wht_mmx(int16_t block[4][4][16], int16_t dc[16]);
+extern void ff_vp8_luma_dc_wht_sse(int16_t block[4][4][16], int16_t dc[16]);
+extern void ff_vp8_idct_add_mmx(uint8_t *dst, int16_t block[16],
                                 ptrdiff_t stride);
-extern void ff_vp8_idct_add_sse(uint8_t *dst, DCTELEM block[16],
+extern void ff_vp8_idct_add_sse(uint8_t *dst, int16_t block[16],
                                 ptrdiff_t stride);
 
 #define DECLARE_LOOP_FILTER(NAME)\
diff --git a/libavcodec/xan.c b/libavcodec/xan.c
index bccbe24..219eedd 100644
--- a/libavcodec/xan.c
+++ b/libavcodec/xan.c
@@ -38,6 +38,7 @@
 #include "bytestream.h"
 #define BITSTREAM_READER_LE
 #include "get_bits.h"
+#include "internal.h"
 
 #define RUNTIME_GAMMA 0
 
@@ -115,7 +116,7 @@
     while (val != 0x16) {
         unsigned idx = val - 0x17 + get_bits1(&gb) * byte;
         if (idx >= 2 * byte)
-            return -1;
+            return AVERROR_INVALIDDATA;
         val = src[idx];
 
         if (val < 0x16) {
@@ -141,44 +142,47 @@
     int size;
     unsigned char *dest_org = dest;
     unsigned char *dest_end = dest + dest_len;
-    const unsigned char *src_end = src + src_len;
+    GetByteContext ctx;
 
-    while (dest < dest_end && src < src_end) {
-        opcode = *src++;
+    bytestream2_init(&ctx, src, src_len);
+    while (dest < dest_end && bytestream2_get_bytes_left(&ctx)) {
+        opcode = bytestream2_get_byte(&ctx);
 
         if (opcode < 0xe0) {
             int size2, back;
             if ((opcode & 0x80) == 0) {
                 size = opcode & 3;
 
-                back  = ((opcode & 0x60) << 3) + *src++ + 1;
+                back  = ((opcode & 0x60) << 3) + bytestream2_get_byte(&ctx) + 1;
                 size2 = ((opcode & 0x1c) >> 2) + 3;
             } else if ((opcode & 0x40) == 0) {
-                size = *src >> 6;
+                size = bytestream2_peek_byte(&ctx) >> 6;
 
-                back  = (bytestream_get_be16(&src) & 0x3fff) + 1;
+                back  = (bytestream2_get_be16(&ctx) & 0x3fff) + 1;
                 size2 = (opcode & 0x3f) + 4;
             } else {
                 size = opcode & 3;
 
-                back  = ((opcode & 0x10) << 12) + bytestream_get_be16(&src) + 1;
-                size2 = ((opcode & 0x0c) <<  6) + *src++ + 5;
+                back  = ((opcode & 0x10) << 12) + bytestream2_get_be16(&ctx) + 1;
+                size2 = ((opcode & 0x0c) <<  6) + bytestream2_get_byte(&ctx) + 5;
             }
 
             if (dest_end - dest < size + size2 ||
                 dest + size - dest_org < back ||
-                src_end - src < size)
+                bytestream2_get_bytes_left(&ctx) < size)
                 return;
-            memcpy(dest, src, size);  dest += size;  src += size;
+            bytestream2_get_buffer(&ctx, dest, size);
+            dest += size;
             av_memcpy_backptr(dest, back, size2);
             dest += size2;
         } else {
             int finish = opcode >= 0xfc;
             size = finish ? opcode & 3 : ((opcode & 0x1f) << 2) + 4;
 
-            if (dest_end - dest < size || src_end - src < size)
+            if (dest_end - dest < size || bytestream2_get_bytes_left(&ctx) < size)
                 return;
-            memcpy(dest, src, size);  dest += size;  src += size;
+            bytestream2_get_buffer(&ctx, dest, size);
+            dest += size;
             if (finish)
                 return;
         }
@@ -511,78 +515,78 @@
 #endif
 
 static int xan_decode_frame(AVCodecContext *avctx,
-                            void *data, int *data_size,
+                            void *data, int *got_frame,
                             AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
     int ret, buf_size = avpkt->size;
     XanContext *s = avctx->priv_data;
+    GetByteContext ctx;
+    int tag = 0;
 
-    if (avctx->codec->id == AV_CODEC_ID_XAN_WC3) {
-        const uint8_t *buf_end = buf + buf_size;
-        int tag = 0;
-        while (buf_end - buf > 8 && tag != VGA__TAG) {
-            unsigned *tmpptr;
-            uint32_t new_pal;
-            int size;
-            int i;
-            tag  = bytestream_get_le32(&buf);
-            size = bytestream_get_be32(&buf);
-            if(size < 0) {
-                av_log(avctx, AV_LOG_ERROR, "Invalid tag size %d\n", size);
-                return AVERROR_INVALIDDATA;
-            }
-            size = FFMIN(size, buf_end - buf);
-            switch (tag) {
-            case PALT_TAG:
-                if (size < PALETTE_SIZE)
-                    return AVERROR_INVALIDDATA;
-                if (s->palettes_count >= PALETTES_MAX)
-                    return AVERROR_INVALIDDATA;
-                tmpptr = av_realloc(s->palettes,
-                                    (s->palettes_count + 1) * AVPALETTE_SIZE);
-                if (!tmpptr)
-                    return AVERROR(ENOMEM);
-                s->palettes = tmpptr;
-                tmpptr += s->palettes_count * AVPALETTE_COUNT;
-                for (i = 0; i < PALETTE_COUNT; i++) {
-#if RUNTIME_GAMMA
-                    int r = gamma_corr(*buf++);
-                    int g = gamma_corr(*buf++);
-                    int b = gamma_corr(*buf++);
-#else
-                    int r = gamma_lookup[*buf++];
-                    int g = gamma_lookup[*buf++];
-                    int b = gamma_lookup[*buf++];
-#endif
-                    *tmpptr++ = (0xFFU << 24) | (r << 16) | (g << 8) | b;
-                }
-                s->palettes_count++;
-                break;
-            case SHOT_TAG:
-                if (size < 4)
-                    return AVERROR_INVALIDDATA;
-                new_pal = bytestream_get_le32(&buf);
-                if (new_pal < s->palettes_count) {
-                    s->cur_palette = new_pal;
-                } else
-                    av_log(avctx, AV_LOG_ERROR, "Invalid palette selected\n");
-                break;
-            case VGA__TAG:
-                break;
-            default:
-                buf += size;
-                break;
-            }
+    bytestream2_init(&ctx, buf, buf_size);
+    while (bytestream2_get_bytes_left(&ctx) > 8 && tag != VGA__TAG) {
+        unsigned *tmpptr;
+        uint32_t new_pal;
+        int size;
+        int i;
+        tag  = bytestream2_get_le32(&ctx);
+        size = bytestream2_get_be32(&ctx);
+        if(size < 0) {
+            av_log(avctx, AV_LOG_ERROR, "Invalid tag size %d\n", size);
+            return AVERROR_INVALIDDATA;
         }
-        buf_size = buf_end - buf;
+        size = FFMIN(size, bytestream2_get_bytes_left(&ctx));
+        switch (tag) {
+        case PALT_TAG:
+            if (size < PALETTE_SIZE)
+                return AVERROR_INVALIDDATA;
+            if (s->palettes_count >= PALETTES_MAX)
+                return AVERROR_INVALIDDATA;
+            tmpptr = av_realloc(s->palettes,
+                                (s->palettes_count + 1) * AVPALETTE_SIZE);
+            if (!tmpptr)
+                return AVERROR(ENOMEM);
+            s->palettes = tmpptr;
+            tmpptr += s->palettes_count * AVPALETTE_COUNT;
+            for (i = 0; i < PALETTE_COUNT; i++) {
+#if RUNTIME_GAMMA
+                int r = gamma_corr(bytestream2_get_byteu(&ctx));
+                int g = gamma_corr(bytestream2_get_byteu(&ctx));
+                int b = gamma_corr(bytestream2_get_byteu(&ctx));
+#else
+                int r = gamma_lookup[bytestream2_get_byteu(&ctx)];
+                int g = gamma_lookup[bytestream2_get_byteu(&ctx)];
+                int b = gamma_lookup[bytestream2_get_byteu(&ctx)];
+#endif
+                *tmpptr++ = (0xFFU << 24) | (r << 16) | (g << 8) | b;
+            }
+            s->palettes_count++;
+            break;
+        case SHOT_TAG:
+            if (size < 4)
+                return AVERROR_INVALIDDATA;
+            new_pal = bytestream2_get_le32(&ctx);
+            if (new_pal < s->palettes_count) {
+                s->cur_palette = new_pal;
+            } else
+                av_log(avctx, AV_LOG_ERROR, "Invalid palette selected\n");
+            break;
+        case VGA__TAG:
+            break;
+        default:
+            bytestream2_skip(&ctx, size);
+            break;
+        }
     }
+    buf_size = bytestream2_get_bytes_left(&ctx);
+
     if (s->palettes_count <= 0) {
         av_log(s->avctx, AV_LOG_ERROR, "No palette found\n");
         return AVERROR_INVALIDDATA;
     }
 
-    if ((ret = avctx->get_buffer(avctx, &s->current_frame))) {
+    if ((ret = ff_get_buffer(avctx, &s->current_frame))) {
         av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -594,7 +598,7 @@
     memcpy(s->current_frame.data[1],
            s->palettes + s->cur_palette * AVPALETTE_COUNT, AVPALETTE_SIZE);
 
-    s->buf = buf;
+    s->buf = ctx.buffer;
     s->size = buf_size;
 
     if (xan_wc3_decode_frame(s) < 0)
@@ -604,7 +608,7 @@
     if (s->last_frame.data[0])
         avctx->release_buffer(avctx, &s->last_frame);
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*)data = s->current_frame;
 
     /* shuffle frames */
diff --git a/libavcodec/xbmdec.c b/libavcodec/xbmdec.c
index 4b8704a..2a41836 100644
--- a/libavcodec/xbmdec.c
+++ b/libavcodec/xbmdec.c
@@ -45,7 +45,7 @@
 }
 
 static int xbm_decode_frame(AVCodecContext *avctx, void *data,
-                            int *data_size, AVPacket *avpkt)
+                            int *got_frame, AVPacket *avpkt)
 {
     AVFrame *p = avctx->coded_frame;
     const uint8_t *end, *ptr = avpkt->data;
@@ -81,7 +81,7 @@
         avctx->release_buffer(avctx, p);
 
     p->reference = 0;
-    if ((ret = avctx->get_buffer(avctx, p)) < 0)
+    if ((ret = ff_get_buffer(avctx, p)) < 0)
         return ret;
 
     // goto start of image data
@@ -110,7 +110,7 @@
     p->key_frame = 1;
     p->pict_type = AV_PICTURE_TYPE_I;
 
-    *data_size       = sizeof(AVFrame);
+    *got_frame       = 1;
     *(AVFrame *)data = *p;
 
     return avpkt->size;
diff --git a/libavcodec/xfacedec.c b/libavcodec/xfacedec.c
index 7cccfa5..a2f8636 100644
--- a/libavcodec/xfacedec.c
+++ b/libavcodec/xfacedec.c
@@ -27,6 +27,7 @@
 #include "libavutil/pixdesc.h"
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 #include "xface.h"
 
 static int pop_integer(BigInt *b, const ProbRange *pranges)
@@ -123,7 +124,7 @@
 }
 
 static int xface_decode_frame(AVCodecContext *avctx,
-                              void *data, int *data_size,
+                              void *data, int *got_frame,
                               AVPacket *avpkt)
 {
     XFaceContext *xface = avctx->priv_data;
@@ -136,7 +137,7 @@
     if (xface->frame.data[0])
         avctx->release_buffer(avctx, &xface->frame);
     xface->frame.data[0] = NULL;
-    if ((ret = avctx->get_buffer(avctx, &xface->frame)) < 0)
+    if ((ret = ff_get_buffer(avctx, &xface->frame)) < 0)
         return ret;
     xface->frame.reference = 0;
 
@@ -188,7 +189,7 @@
         }
     }
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*)data = xface->frame;
 
     return avpkt->size;
diff --git a/libavcodec/xl.c b/libavcodec/xl.c
index 8c5ccd3..e2701d6 100644
--- a/libavcodec/xl.c
+++ b/libavcodec/xl.c
@@ -27,6 +27,7 @@
 #include "libavutil/common.h"
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
+#include "internal.h"
 
 typedef struct VideoXLContext{
     AVCodecContext *avctx;
@@ -41,7 +42,7 @@
 };
 
 static int decode_frame(AVCodecContext *avctx,
-                        void *data, int *data_size,
+                        void *data, int *got_frame,
                         AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
@@ -68,7 +69,7 @@
         avctx->release_buffer(avctx, p);
 
     p->reference = 0;
-    if ((ret = avctx->get_buffer(avctx, p)) < 0) {
+    if ((ret = ff_get_buffer(avctx, p)) < 0){
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -127,7 +128,7 @@
         V += a->pic.linesize[2];
     }
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*)data = a->pic;
 
     return buf_size;
diff --git a/libavcodec/xwddec.c b/libavcodec/xwddec.c
index ef99a6b..9923cdc 100644
--- a/libavcodec/xwddec.c
+++ b/libavcodec/xwddec.c
@@ -23,6 +23,7 @@
 #include "libavutil/imgutils.h"
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 #include "xwd.h"
 
 static av_cold int xwd_decode_init(AVCodecContext *avctx)
@@ -35,7 +36,7 @@
 }
 
 static int xwd_decode_frame(AVCodecContext *avctx, void *data,
-                            int *data_size, AVPacket *avpkt)
+                            int *got_frame, AVPacket *avpkt)
 {
     AVFrame *p = avctx->coded_frame;
     const uint8_t *buf = avpkt->data;
@@ -211,7 +212,7 @@
         avctx->release_buffer(avctx, p);
 
     p->reference = 0;
-    if ((ret = avctx->get_buffer(avctx, p)) < 0) {
+    if ((ret = ff_get_buffer(avctx, p)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -244,7 +245,7 @@
         ptr += p->linesize[0];
     }
 
-    *data_size = sizeof(AVFrame);
+    *got_frame       = 1;
     *(AVFrame *)data = *p;
 
     return buf_size;
diff --git a/libavcodec/xxan.c b/libavcodec/xxan.c
index 47b3544..9168327 100644
--- a/libavcodec/xxan.c
+++ b/libavcodec/xxan.c
@@ -45,6 +45,11 @@
 
     avctx->pix_fmt = AV_PIX_FMT_YUV420P;
 
+    if (avctx->height < 8) {
+        av_log(avctx, AV_LOG_ERROR, "Invalid frame height: %d.\n", avctx->height);
+        return AVERROR(EINVAL);
+    }
+
     s->buffer_size = avctx->width * avctx->height;
     s->y_buffer = av_malloc(s->buffer_size);
     if (!s->y_buffer)
@@ -186,7 +191,7 @@
     dec_size = xan_unpack(s, s->scratch_buffer, s->buffer_size);
     if (dec_size < 0) {
         av_log(avctx, AV_LOG_ERROR, "Chroma unpacking failed\n");
-        return AVERROR_INVALIDDATA;
+        return dec_size;
     }
 
     U = s->pic.data[1];
@@ -212,6 +217,10 @@
             U += s->pic.linesize[1];
             V += s->pic.linesize[2];
         }
+        if (avctx->height & 1) {
+            memcpy(U, U - s->pic.linesize[1], avctx->width >> 1);
+            memcpy(V, V - s->pic.linesize[2], avctx->width >> 1);
+        }
     } else {
         uint8_t *U2 = U + s->pic.linesize[1];
         uint8_t *V2 = V + s->pic.linesize[2];
@@ -236,6 +245,12 @@
             U2 += s->pic.linesize[1] * 2;
             V2 += s->pic.linesize[2] * 2;
         }
+        if (avctx->height & 3) {
+            int lines = ((avctx->height + 1) >> 1) - (avctx->height >> 2) * 2;
+
+            memcpy(U, U - lines * s->pic.linesize[1], lines * s->pic.linesize[1]);
+            memcpy(V, V - lines * s->pic.linesize[2], lines * s->pic.linesize[2]);
+        }
     }
 
     return 0;
@@ -369,7 +384,7 @@
 }
 
 static int xan_decode_frame(AVCodecContext *avctx,
-                            void *data, int *data_size,
+                            void *data, int *got_frame,
                             AVPacket *avpkt)
 {
     XanContext *s = avctx->priv_data;
@@ -401,7 +416,7 @@
     if (ret)
         return ret;
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*)data = s->pic;
 
     return avpkt->size;
diff --git a/libavcodec/y41pdec.c b/libavcodec/y41pdec.c
index e283690..655a426 100644
--- a/libavcodec/y41pdec.c
+++ b/libavcodec/y41pdec.c
@@ -21,6 +21,7 @@
  */
 
 #include "avcodec.h"
+#include "internal.h"
 
 static av_cold int y41p_decode_init(AVCodecContext *avctx)
 {
@@ -41,7 +42,7 @@
 }
 
 static int y41p_decode_frame(AVCodecContext *avctx, void *data,
-                             int *data_size, AVPacket *avpkt)
+                             int *got_frame, AVPacket *avpkt)
 {
     AVFrame *pic = avctx->coded_frame;
     uint8_t *src = avpkt->data;
@@ -58,7 +59,7 @@
 
     pic->reference = 0;
 
-    if (avctx->get_buffer(avctx, pic) < 0) {
+    if (ff_get_buffer(avctx, pic) < 0) {
         av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
         return AVERROR(ENOMEM);
     }
@@ -88,7 +89,7 @@
         }
     }
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame *)data = *pic;
 
     return avpkt->size;
diff --git a/libavcodec/yop.c b/libavcodec/yop.c
index 255ed32..234868a 100644
--- a/libavcodec/yop.c
+++ b/libavcodec/yop.c
@@ -27,6 +27,7 @@
 
 #include "avcodec.h"
 #include "get_bits.h"
+#include "internal.h"
 
 typedef struct YopDecContext {
     AVFrame frame;
@@ -35,10 +36,10 @@
     int num_pal_colors;
     int first_color[2];
     int frame_data_length;
-    int row_pos;
 
     uint8_t *low_nibble;
     uint8_t *srcptr;
+    uint8_t *src_end;
     uint8_t *dstptr;
     uint8_t *dstbuf;
 } YopDecContext;
@@ -85,11 +86,12 @@
 
     if (avctx->width & 1 || avctx->height & 1 ||
         av_image_check_size(avctx->width, avctx->height, 0, avctx) < 0) {
-        return -1;
+        av_log(avctx, AV_LOG_ERROR, "YOP has invalid dimensions\n");
+        return AVERROR_INVALIDDATA;
     }
 
-    if (!avctx->extradata) {
-        av_log(avctx, AV_LOG_ERROR, "extradata missing\n");
+    if (avctx->extradata_size < 3) {
+        av_log(avctx, AV_LOG_ERROR, "Missing or incomplete extradata.\n");
         return AVERROR_INVALIDDATA;
     }
 
@@ -123,8 +125,13 @@
  * @param s codec context
  * @param tag the tag that was in the nibble
  */
-static void yop_paint_block(YopDecContext *s, int tag)
+static int yop_paint_block(YopDecContext *s, int tag)
 {
+    if (s->src_end - s->srcptr < paint_lut[tag][3]) {
+        av_log(s->avctx, AV_LOG_ERROR, "Packet too small.\n");
+        return AVERROR_INVALIDDATA;
+    }
+
     s->dstptr[0]                        = s->srcptr[0];
     s->dstptr[1]                        = s->srcptr[paint_lut[tag][0]];
     s->dstptr[s->frame.linesize[0]]     = s->srcptr[paint_lut[tag][1]];
@@ -132,6 +139,7 @@
 
     // The number of src bytes consumed is in the last part of the lut entry.
     s->srcptr += paint_lut[tag][3];
+    return 0;
 }
 
 /**
@@ -176,49 +184,35 @@
     return ret;
 }
 
-/**
- * Take s->dstptr to the next macroblock in sequence.
- */
-static void yop_next_macroblock(YopDecContext *s)
-{
-    // If we are advancing to the next row of macroblocks
-    if (s->row_pos == s->frame.linesize[0] - 2) {
-        s->dstptr  += s->frame.linesize[0];
-        s->row_pos =  0;
-    }else {
-        s->row_pos += 2;
-    }
-    s->dstptr += 2;
-}
-
-static int yop_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+static int yop_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                             AVPacket *avpkt)
 {
     YopDecContext *s = avctx->priv_data;
     int tag, firstcolor, is_odd_frame;
-    int ret, i;
+    int ret, i, x, y;
     uint32_t *palette;
 
+    if (avpkt->size < 4 + 3 * s->num_pal_colors) {
+        av_log(avctx, AV_LOG_ERROR, "Packet too small.\n");
+        return AVERROR_INVALIDDATA;
+    }
+
     if (s->frame.data[0])
         avctx->release_buffer(avctx, &s->frame);
 
-    if (avpkt->size < 4 + 3*s->num_pal_colors) {
-        av_log(avctx, AV_LOG_ERROR, "packet of size %d too small\n", avpkt->size);
-        return AVERROR_INVALIDDATA;
-    }
-
-    ret = avctx->get_buffer(avctx, &s->frame);
+    ret = ff_get_buffer(avctx, &s->frame);
     if (ret < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
 
-    s->frame.linesize[0] = avctx->width;
+    if (!avctx->frame_number)
+        memset(s->frame.data[1], 0, AVPALETTE_SIZE);
 
     s->dstbuf     = s->frame.data[0];
     s->dstptr     = s->frame.data[0];
     s->srcptr     = avpkt->data + 4;
-    s->row_pos    = 0;
+    s->src_end    = avpkt->data + avpkt->size;
     s->low_nibble = NULL;
 
     is_odd_frame = avpkt->data[0];
@@ -239,26 +233,33 @@
 
     s->frame.palette_has_changed = 1;
 
-    while (s->dstptr - s->dstbuf <
-           avctx->width * avctx->height &&
-           s->srcptr - avpkt->data < avpkt->size) {
-
-        tag = yop_get_next_nibble(s);
-
-        if (tag != 0xf) {
-            yop_paint_block(s, tag);
-        }else {
-            tag = yop_get_next_nibble(s);
-            ret = yop_copy_previous_block(s, tag);
-            if (ret < 0) {
-                avctx->release_buffer(avctx, &s->frame);
-                return ret;
+    for (y = 0; y < avctx->height; y += 2) {
+        for (x = 0; x < avctx->width; x += 2) {
+            if (s->srcptr - avpkt->data >= avpkt->size) {
+                av_log(avctx, AV_LOG_ERROR, "Packet too small.\n");
+                return AVERROR_INVALIDDATA;
             }
+
+            tag = yop_get_next_nibble(s);
+
+            if (tag != 0xf) {
+                ret = yop_paint_block(s, tag);
+                if (ret < 0)
+                    return ret;
+            } else {
+                tag = yop_get_next_nibble(s);
+                ret = yop_copy_previous_block(s, tag);
+                if (ret < 0) {
+                    avctx->release_buffer(avctx, &s->frame);
+                    return ret;
+                }
+            }
+            s->dstptr += 2;
         }
-        yop_next_macroblock(s);
+        s->dstptr += 2*s->frame.linesize[0] - x;
     }
 
-    *data_size        = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame *) data = s->frame;
     return avpkt->size;
 }
diff --git a/libavcodec/yuv4dec.c b/libavcodec/yuv4dec.c
index ce44f13..8eb72c2 100644
--- a/libavcodec/yuv4dec.c
+++ b/libavcodec/yuv4dec.c
@@ -21,6 +21,7 @@
  */
 
 #include "avcodec.h"
+#include "internal.h"
 
 static av_cold int yuv4_decode_init(AVCodecContext *avctx)
 {
@@ -37,7 +38,7 @@
 }
 
 static int yuv4_decode_frame(AVCodecContext *avctx, void *data,
-                             int *data_size, AVPacket *avpkt)
+                             int *got_frame, AVPacket *avpkt)
 {
     AVFrame *pic = avctx->coded_frame;
     const uint8_t *src = avpkt->data;
@@ -54,7 +55,7 @@
 
     pic->reference = 0;
 
-    if (avctx->get_buffer(avctx, pic) < 0) {
+    if (ff_get_buffer(avctx, pic) < 0) {
         av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
         return AVERROR(ENOMEM);
     }
@@ -81,7 +82,7 @@
         v +=     pic->linesize[2];
     }
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame *)data = *pic;
 
     return avpkt->size;
diff --git a/libavcodec/zerocodec.c b/libavcodec/zerocodec.c
index c6a9ba9..8122cca 100644
--- a/libavcodec/zerocodec.c
+++ b/libavcodec/zerocodec.c
@@ -19,16 +19,16 @@
 #include <zlib.h>
 
 #include "avcodec.h"
+#include "internal.h"
 #include "libavutil/common.h"
 
 typedef struct {
     AVFrame  previous_frame;
     z_stream zstream;
-    int      size;
 } ZeroCodecContext;
 
 static int zerocodec_decode_frame(AVCodecContext *avctx, void *data,
-                                  int *data_size, AVPacket *avpkt)
+                                  int *got_frame, AVPacket *avpkt)
 {
     ZeroCodecContext *zc = avctx->priv_data;
     AVFrame *pic         = avctx->coded_frame;
@@ -48,6 +48,9 @@
             av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n");
             return AVERROR_INVALIDDATA;
         }
+
+        prev += (avctx->height - 1) * prev_pic->linesize[0];
+
         pic->key_frame = 0;
         pic->pict_type = AV_PICTURE_TYPE_P;
     }
@@ -58,7 +61,7 @@
         return AVERROR_INVALIDDATA;
     }
 
-    if (avctx->get_buffer(avctx, pic) < 0) {
+    if (ff_get_buffer(avctx, pic) < 0) {
         av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
         return AVERROR(ENOMEM);
     }
@@ -66,7 +69,7 @@
     zstream->next_in  = avpkt->data;
     zstream->avail_in = avpkt->size;
 
-    dst = pic->data[0];
+    dst = pic->data[0] + (avctx->height - 1) * pic->linesize[0];
 
     /**
      * ZeroCodec has very simple interframe compression. If a value
@@ -89,15 +92,15 @@
             for (j = 0; j < avctx->width << 1; j++)
                 dst[j] += prev[j] & -!dst[j];
 
-        prev += prev_pic->linesize[0];
-        dst  += pic->linesize[0];
+        prev -= prev_pic->linesize[0];
+        dst  -= pic->linesize[0];
     }
 
     /* Release the previous buffer if need be */
     if (prev_pic->data[0])
         avctx->release_buffer(avctx, prev_pic);
 
-    *data_size       = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame *)data = *pic;
 
     /* Store the previous frame for use later.
@@ -132,9 +135,6 @@
     avctx->pix_fmt             = AV_PIX_FMT_UYVY422;
     avctx->bits_per_raw_sample = 8;
 
-    zc->size = avpicture_get_size(avctx->pix_fmt,
-                                  avctx->width, avctx->height);
-
     zstream->zalloc = Z_NULL;
     zstream->zfree  = Z_NULL;
     zstream->opaque = Z_NULL;
diff --git a/libavcodec/zmbv.c b/libavcodec/zmbv.c
index 1b94351..03821cd 100644
--- a/libavcodec/zmbv.c
+++ b/libavcodec/zmbv.c
@@ -30,6 +30,7 @@
 #include "libavutil/common.h"
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
+#include "internal.h"
 
 #include <zlib.h>
 
@@ -397,7 +398,7 @@
     return 0;
 }
 
-static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt)
+static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
@@ -411,7 +412,7 @@
 
     c->pic.reference = 3;
     c->pic.buffer_hints = FF_BUFFER_HINTS_VALID;
-    if ((ret = avctx->get_buffer(avctx, &c->pic)) < 0) {
+    if ((ret = ff_get_buffer(avctx, &c->pic)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -428,6 +429,8 @@
         c->fmt = buf[3];
         c->bw = buf[4];
         c->bh = buf[5];
+        c->decode_intra = NULL;
+        c->decode_xor = NULL;
 
         buf += 6;
         len -= 6;
@@ -484,7 +487,7 @@
         zret = inflateReset(&c->zstream);
         if (zret != Z_OK) {
             av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret);
-            return -1;
+            return AVERROR_UNKNOWN;
         }
 
         c->cur  = av_realloc_f(c->cur, avctx->width * avctx->height,  (c->bpp / 8));
@@ -600,20 +603,13 @@
         }
         FFSWAP(uint8_t *, c->cur, c->prev);
     }
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*)data = c->pic;
 
     /* always report that the buffer was completely consumed */
     return buf_size;
 }
 
-
-
-/*
- *
- * Init zmbv decoder
- *
- */
 static av_cold int decode_init(AVCodecContext *avctx)
 {
     ZmbvContext * const c = avctx->priv_data;
@@ -648,19 +644,12 @@
     zret = inflateInit(&c->zstream);
     if (zret != Z_OK) {
         av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
-        return -1;
+        return AVERROR_UNKNOWN;
     }
 
     return 0;
 }
 
-
-
-/*
- *
- * Uninit zmbv decoder
- *
- */
 static av_cold int decode_end(AVCodecContext *avctx)
 {
     ZmbvContext * const c = avctx->priv_data;
diff --git a/libavdevice/alldevices.c b/libavdevice/alldevices.c
index 7789058..daa6638 100644
--- a/libavdevice/alldevices.c
+++ b/libavdevice/alldevices.c
@@ -21,13 +21,21 @@
 #include "config.h"
 #include "avdevice.h"
 
-#define REGISTER_OUTDEV(X,x) { \
-          extern AVOutputFormat ff_##x##_muxer; \
-          if(CONFIG_##X##_OUTDEV)  av_register_output_format(&ff_##x##_muxer); }
-#define REGISTER_INDEV(X,x) { \
-          extern AVInputFormat ff_##x##_demuxer; \
-          if(CONFIG_##X##_INDEV)   av_register_input_format(&ff_##x##_demuxer); }
-#define REGISTER_INOUTDEV(X,x)  REGISTER_OUTDEV(X,x); REGISTER_INDEV(X,x)
+#define REGISTER_OUTDEV(X, x)                                           \
+    {                                                                   \
+        extern AVOutputFormat ff_##x##_muxer;                           \
+        if (CONFIG_##X##_OUTDEV)                                        \
+            av_register_output_format(&ff_##x##_muxer);                 \
+    }
+
+#define REGISTER_INDEV(X, x)                                            \
+    {                                                                   \
+        extern AVInputFormat ff_##x##_demuxer;                          \
+        if (CONFIG_##X##_INDEV)                                         \
+            av_register_input_format(&ff_##x##_demuxer);                \
+    }
+
+#define REGISTER_INOUTDEV(X, x) REGISTER_OUTDEV(X, x); REGISTER_INDEV(X, x)
 
 void avdevice_register_all(void)
 {
@@ -38,26 +46,26 @@
     initialized = 1;
 
     /* devices */
-    REGISTER_INOUTDEV (ALSA, alsa);
-    REGISTER_INDEV    (BKTR, bktr);
-    REGISTER_OUTDEV   (CACA, caca);
-    REGISTER_INDEV    (DSHOW, dshow);
-    REGISTER_INDEV    (DV1394, dv1394);
-    REGISTER_INDEV    (FBDEV, fbdev);
-    REGISTER_INDEV    (IEC61883, iec61883);
-    REGISTER_INDEV    (JACK, jack);
-    REGISTER_INDEV    (LAVFI, lavfi);
-    REGISTER_INDEV    (OPENAL, openal);
-    REGISTER_INOUTDEV (OSS, oss);
-    REGISTER_INDEV    (PULSE, pulse);
-    REGISTER_OUTDEV   (SDL, sdl);
-    REGISTER_INOUTDEV (SNDIO, sndio);
-    REGISTER_INDEV    (V4L2, v4l2);
-//    REGISTER_INDEV    (V4L, v4l
-    REGISTER_INDEV    (VFWCAP, vfwcap);
-    REGISTER_INDEV    (X11GRAB, x11grab);
+    REGISTER_INOUTDEV(ALSA,             alsa);
+    REGISTER_INDEV   (BKTR,             bktr);
+    REGISTER_OUTDEV  (CACA,             caca);
+    REGISTER_INDEV   (DSHOW,            dshow);
+    REGISTER_INDEV   (DV1394,           dv1394);
+    REGISTER_INDEV   (FBDEV,            fbdev);
+    REGISTER_INDEV   (IEC61883,         iec61883);
+    REGISTER_INDEV   (JACK,             jack);
+    REGISTER_INDEV   (LAVFI,            lavfi);
+    REGISTER_INDEV   (OPENAL,           openal);
+    REGISTER_INOUTDEV(OSS,              oss);
+    REGISTER_INDEV   (PULSE,            pulse);
+    REGISTER_OUTDEV  (SDL,              sdl);
+    REGISTER_INOUTDEV(SNDIO,            sndio);
+    REGISTER_INDEV   (V4L2,             v4l2);
+//    REGISTER_INDEV   (V4L,              v4l
+    REGISTER_INDEV   (VFWCAP,           vfwcap);
+    REGISTER_INDEV   (X11GRAB,          x11grab);
 
     /* external libraries */
-    REGISTER_INDEV    (LIBCDIO, libcdio);
-    REGISTER_INDEV    (LIBDC1394, libdc1394);
+    REGISTER_INDEV   (LIBCDIO,          libcdio);
+    REGISTER_INDEV   (LIBDC1394,        libdc1394);
 }
diff --git a/libavdevice/alsa-audio-common.c b/libavdevice/alsa-audio-common.c
index afe6751..4e63397 100644
--- a/libavdevice/alsa-audio-common.c
+++ b/libavdevice/alsa-audio-common.c
@@ -62,48 +62,45 @@
     }
 }
 
-#define REORDER_OUT_50(NAME, TYPE) \
-static void alsa_reorder_ ## NAME ## _out_50(const void *in_v, void *out_v, int n) \
-{ \
-    const TYPE *in = in_v; \
-    TYPE      *out = out_v; \
-\
-    while (n-- > 0) { \
+#define MAKE_REORDER_FUNC(NAME, TYPE, CHANNELS, LAYOUT, MAP)                \
+static void alsa_reorder_ ## NAME ## _ ## LAYOUT(const void *in_v,          \
+                                                 void *out_v,               \
+                                                 int n)                     \
+{                                                                           \
+    const TYPE *in = in_v;                                                  \
+    TYPE      *out = out_v;                                                 \
+                                                                            \
+    while (n-- > 0) {                                                       \
+        MAP                                                                 \
+        in  += CHANNELS;                                                    \
+        out += CHANNELS;                                                    \
+    }                                                                       \
+}
+
+#define MAKE_REORDER_FUNCS(CHANNELS, LAYOUT, MAP) \
+    MAKE_REORDER_FUNC(int8,  int8_t,  CHANNELS, LAYOUT, MAP) \
+    MAKE_REORDER_FUNC(int16, int16_t, CHANNELS, LAYOUT, MAP) \
+    MAKE_REORDER_FUNC(int32, int32_t, CHANNELS, LAYOUT, MAP) \
+    MAKE_REORDER_FUNC(f32,   float,   CHANNELS, LAYOUT, MAP)
+
+MAKE_REORDER_FUNCS(5, out_50, \
         out[0] = in[0]; \
         out[1] = in[1]; \
         out[2] = in[3]; \
         out[3] = in[4]; \
         out[4] = in[2]; \
-        in  += 5; \
-        out += 5; \
-    } \
-}
+        );
 
-#define REORDER_OUT_51(NAME, TYPE) \
-static void alsa_reorder_ ## NAME ## _out_51(const void *in_v, void *out_v, int n) \
-{ \
-    const TYPE *in = in_v; \
-    TYPE      *out = out_v; \
-\
-    while (n-- > 0) { \
+MAKE_REORDER_FUNCS(6, out_51, \
         out[0] = in[0]; \
         out[1] = in[1]; \
         out[2] = in[4]; \
         out[3] = in[5]; \
         out[4] = in[2]; \
         out[5] = in[3]; \
-        in  += 6; \
-        out += 6; \
-    } \
-}
+        );
 
-#define REORDER_OUT_71(NAME, TYPE) \
-static void alsa_reorder_ ## NAME ## _out_71(const void *in_v, void *out_v, int n) \
-{ \
-    const TYPE *in = in_v; \
-    TYPE      *out = out_v; \
-\
-    while (n-- > 0) { \
+MAKE_REORDER_FUNCS(8, out_71, \
         out[0] = in[0]; \
         out[1] = in[1]; \
         out[2] = in[4]; \
@@ -112,23 +109,7 @@
         out[5] = in[3]; \
         out[6] = in[6]; \
         out[7] = in[7]; \
-        in  += 8; \
-        out += 8; \
-    } \
-}
-
-REORDER_OUT_50(int8, int8_t)
-REORDER_OUT_51(int8, int8_t)
-REORDER_OUT_71(int8, int8_t)
-REORDER_OUT_50(int16, int16_t)
-REORDER_OUT_51(int16, int16_t)
-REORDER_OUT_71(int16, int16_t)
-REORDER_OUT_50(int32, int32_t)
-REORDER_OUT_51(int32, int32_t)
-REORDER_OUT_71(int32, int32_t)
-REORDER_OUT_50(f32, float)
-REORDER_OUT_51(f32, float)
-REORDER_OUT_71(f32, float)
+        );
 
 #define FORMAT_I8  0
 #define FORMAT_I16 1
diff --git a/libavdevice/bktr.c b/libavdevice/bktr.c
index e83c44a..d5f3d9f 100644
--- a/libavdevice/bktr.c
+++ b/libavdevice/bktr.c
@@ -101,7 +101,7 @@
     long ioctl_frequency;
     char *arg;
     int c;
-    struct sigaction act = { 0 }, old;
+    struct sigaction act = { {0} }, old;
 
     if (idev < 0 || idev > 4)
     {
diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c
index ea01b2a..4991414 100644
--- a/libavdevice/dshow.c
+++ b/libavdevice/dshow.c
@@ -23,8 +23,10 @@
 #include "libavutil/pixdesc.h"
 #include "libavutil/opt.h"
 #include "libavformat/internal.h"
+#include "libavformat/riff.h"
 #include "avdevice.h"
 #include "dshow_capture.h"
+#include "libavcodec/raw.h"
 
 struct dshow_ctx {
     const AVClass *class;
@@ -45,13 +47,17 @@
     libAVPin    *capture_pin[2];
 
     HANDLE mutex;
-    HANDLE event;
+    HANDLE event[2]; /* event[0] is set by DirectShow
+                      * event[1] is set by callback() */
     AVPacketList *pktl;
 
+    int eof;
+
     int64_t curbufsize;
     unsigned int video_frame_num;
 
     IMediaControl *control;
+    IMediaEvent *media_event;
 
     enum AVPixelFormat pixel_format;
     enum AVCodecID video_codec_id;
@@ -69,12 +75,6 @@
 static enum AVPixelFormat dshow_pixfmt(DWORD biCompression, WORD biBitCount)
 {
     switch(biCompression) {
-    case MKTAG('U', 'Y', 'V', 'Y'):
-        return AV_PIX_FMT_UYVY422;
-    case MKTAG('Y', 'U', 'Y', '2'):
-        return AV_PIX_FMT_YUYV422;
-    case MKTAG('I', '4', '2', '0'):
-        return AV_PIX_FMT_YUV420P;
     case BI_BITFIELDS:
     case BI_RGB:
         switch(biBitCount) { /* 1-8 are untested */
@@ -92,19 +92,7 @@
                 return AV_PIX_FMT_RGB32;
         }
     }
-    return AV_PIX_FMT_NONE;
-}
-
-static enum AVCodecID dshow_codecid(DWORD biCompression)
-{
-    switch(biCompression) {
-    case MKTAG('d', 'v', 's', 'd'):
-        return AV_CODEC_ID_DVVIDEO;
-    case MKTAG('M', 'J', 'P', 'G'):
-    case MKTAG('m', 'j', 'p', 'g'):
-        return AV_CODEC_ID_MJPEG;
-    }
-    return AV_CODEC_ID_NONE;
+    return avpriv_find_pix_fmt(ff_raw_pix_fmt_tags, biCompression); // all others
 }
 
 static int
@@ -118,6 +106,9 @@
         IMediaControl_Release(ctx->control);
     }
 
+    if (ctx->media_event)
+        IMediaEvent_Release(ctx->media_event);
+
     if (ctx->graph) {
         IEnumFilters *fenum;
         int r;
@@ -161,8 +152,10 @@
 
     if(ctx->mutex)
         CloseHandle(ctx->mutex);
-    if(ctx->event)
-        CloseHandle(ctx->event);
+    if(ctx->event[0])
+        CloseHandle(ctx->event[0]);
+    if(ctx->event[1])
+        CloseHandle(ctx->event[1]);
 
     pktl = ctx->pktl;
     while (pktl) {
@@ -172,6 +165,8 @@
         pktl = next;
     }
 
+    CoUninitialize();
+
     return 0;
 }
 
@@ -233,7 +228,7 @@
 
     ctx->curbufsize += buf_size;
 
-    SetEvent(ctx->event);
+    SetEvent(ctx->event[1]);
     ReleaseMutex(ctx->mutex);
 
     return;
@@ -375,7 +370,7 @@
             if (!pformat_set) {
                 enum AVPixelFormat pix_fmt = dshow_pixfmt(bih->biCompression, bih->biBitCount);
                 if (pix_fmt == AV_PIX_FMT_NONE) {
-                    enum AVCodecID codec_id = dshow_codecid(bih->biCompression);
+                    enum AVCodecID codec_id = ff_codec_get_id(avformat_get_riff_video_tags(), bih->biCompression);
                     AVCodec *codec = avcodec_find_decoder(codec_id);
                     if (codec_id == AV_CODEC_ID_NONE || !codec) {
                         av_log(avctx, AV_LOG_INFO, "  unknown compression type 0x%X", (int) bih->biCompression);
@@ -393,7 +388,7 @@
                 continue;
             }
             if (ctx->video_codec_id != AV_CODEC_ID_RAWVIDEO) {
-                if (ctx->video_codec_id != dshow_codecid(bih->biCompression))
+                if (ctx->video_codec_id != ff_codec_get_id(avformat_get_riff_video_tags(), bih->biCompression))
                     goto next;
             }
             if (ctx->pixel_format != AV_PIX_FMT_NONE &&
@@ -779,12 +774,15 @@
         codec->width      = bih->biWidth;
         codec->height     = bih->biHeight;
         codec->pix_fmt    = dshow_pixfmt(bih->biCompression, bih->biBitCount);
+        if(bih->biCompression == MKTAG('H', 'D', 'Y', 'C')) {
+          av_log(avctx, AV_LOG_DEBUG, "attempt use full range for HDYC...");
+          codec->color_range = AVCOL_RANGE_MPEG; // just in case it needs this...
+        }
         if (codec->pix_fmt == AV_PIX_FMT_NONE) {
-            codec->codec_id = dshow_codecid(bih->biCompression);
+            codec->codec_id = ff_codec_get_id(avformat_get_riff_video_tags(), bih->biCompression);
             if (codec->codec_id == AV_CODEC_ID_NONE) {
                 av_log(avctx, AV_LOG_ERROR, "Unknown compression type. "
-                                 "Please report verbose (-v 9) debug information.\n");
-                dshow_read_close(avctx);
+                                 "Please report type 0x%X.\n", (int) bih->biCompression);
                 return AVERROR_PATCHWELCOME;
             }
             codec->bits_per_coded_sample = bih->biBitCount;
@@ -868,9 +866,14 @@
     IGraphBuilder *graph = NULL;
     ICreateDevEnum *devenum = NULL;
     IMediaControl *control = NULL;
+    IMediaEvent *media_event = NULL;
+    HANDLE media_event_handle;
+    HANDLE proc;
     int ret = AVERROR(EIO);
     int r;
 
+    CoInitialize(0);
+
     if (!ctx->list_devices && !parse_device_name(avctx)) {
         av_log(avctx, AV_LOG_ERROR, "Malformed dshow input string.\n");
         goto error;
@@ -894,8 +897,6 @@
         }
     }
 
-    CoInitialize(0);
-
     r = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
                          &IID_IGraphBuilder, (void **) &graph);
     if (r != S_OK) {
@@ -929,20 +930,18 @@
     }
 
     if (ctx->device_name[VideoDevice]) {
-        ret = dshow_open_device(avctx, devenum, VideoDevice);
-        if (ret < 0)
+        if ((r = dshow_open_device(avctx, devenum, VideoDevice)) < 0 ||
+            (r = dshow_add_device(avctx, VideoDevice)) < 0) {
+            ret = r;
             goto error;
-        ret = dshow_add_device(avctx, VideoDevice);
-        if (ret < 0)
-            goto error;
+        }
     }
     if (ctx->device_name[AudioDevice]) {
-        ret = dshow_open_device(avctx, devenum, AudioDevice);
-        if (ret < 0)
+        if ((r = dshow_open_device(avctx, devenum, AudioDevice)) < 0 ||
+            (r = dshow_add_device(avctx, AudioDevice)) < 0) {
+            ret = r;
             goto error;
-        ret = dshow_add_device(avctx, AudioDevice);
-        if (ret < 0)
-            goto error;
+        }
     }
 
     ctx->mutex = CreateMutex(NULL, 0, NULL);
@@ -950,8 +949,8 @@
         av_log(avctx, AV_LOG_ERROR, "Could not create Mutex\n");
         goto error;
     }
-    ctx->event = CreateEvent(NULL, 1, 0, NULL);
-    if (!ctx->event) {
+    ctx->event[1] = CreateEvent(NULL, 1, 0, NULL);
+    if (!ctx->event[1]) {
         av_log(avctx, AV_LOG_ERROR, "Could not create Event\n");
         goto error;
     }
@@ -963,6 +962,26 @@
     }
     ctx->control = control;
 
+    r = IGraphBuilder_QueryInterface(graph, &IID_IMediaEvent, (void **) &media_event);
+    if (r != S_OK) {
+        av_log(avctx, AV_LOG_ERROR, "Could not get media event.\n");
+        goto error;
+    }
+    ctx->media_event = media_event;
+
+    r = IMediaEvent_GetEventHandle(media_event, (void *) &media_event_handle);
+    if (r != S_OK) {
+        av_log(avctx, AV_LOG_ERROR, "Could not get media event handle.\n");
+        goto error;
+    }
+    proc = GetCurrentProcess();
+    r = DuplicateHandle(proc, media_event_handle, proc, &ctx->event[0],
+                        0, 0, DUPLICATE_SAME_ACCESS);
+    if (!r) {
+        av_log(avctx, AV_LOG_ERROR, "Could not duplicate media event handle.\n");
+        goto error;
+    }
+
     r = IMediaControl_Run(control);
     if (r == S_FALSE) {
         OAFilterState pfs;
@@ -977,11 +996,31 @@
 
 error:
 
+    if (devenum)
+        ICreateDevEnum_Release(devenum);
+
     if (ret < 0)
         dshow_read_close(avctx);
 
-    if (devenum)
-        ICreateDevEnum_Release(devenum);
+    return ret;
+}
+
+/**
+ * Checks media events from DirectShow and returns -1 on error or EOF. Also
+ * purges all events that might be in the event queue to stop the trigger
+ * of event notification.
+ */
+static int dshow_check_event_queue(IMediaEvent *media_event)
+{
+    LONG_PTR p1, p2;
+    long code;
+    int ret = 0;
+
+    while (IMediaEvent_GetEvent(media_event, &code, &p1, &p2, 0) != E_ABORT) {
+        if (code == EC_COMPLETE || code == EC_DEVICE_LOST || code == EC_ERRORABORT)
+            ret = -1;
+        IMediaEvent_FreeEventParams(media_event, code, p1, p2);
+    }
 
     return ret;
 }
@@ -991,7 +1030,7 @@
     struct dshow_ctx *ctx = s->priv_data;
     AVPacketList *pktl = NULL;
 
-    while (!pktl) {
+    while (!ctx->eof && !pktl) {
         WaitForSingleObject(ctx->mutex, INFINITE);
         pktl = ctx->pktl;
         if (pktl) {
@@ -1000,18 +1039,20 @@
             av_free(pktl);
             ctx->curbufsize -= pkt->size;
         }
-        ResetEvent(ctx->event);
+        ResetEvent(ctx->event[1]);
         ReleaseMutex(ctx->mutex);
         if (!pktl) {
-            if (s->flags & AVFMT_FLAG_NONBLOCK) {
+            if (dshow_check_event_queue(ctx->media_event) < 0) {
+                ctx->eof = 1;
+            } else if (s->flags & AVFMT_FLAG_NONBLOCK) {
                 return AVERROR(EAGAIN);
             } else {
-                WaitForSingleObject(ctx->event, INFINITE);
+                WaitForMultipleObjects(2, ctx->event, 0, INFINITE);
             }
         }
     }
 
-    return pkt->size;
+    return ctx->eof ? AVERROR(EIO) : pkt->size;
 }
 
 #define OFFSET(x) offsetof(struct dshow_ctx, x)
@@ -1036,7 +1077,7 @@
 };
 
 static const AVClass dshow_class = {
-    .class_name = "DirectShow indev",
+    .class_name = "dshow indev",
     .item_name  = av_default_item_name,
     .option     = options,
     .version    = LIBAVUTIL_VERSION_INT,
diff --git a/libavdevice/dshow_capture.h b/libavdevice/dshow_capture.h
index 2446c7c..aff5019 100644
--- a/libavdevice/dshow_capture.h
+++ b/libavdevice/dshow_capture.h
@@ -32,6 +32,11 @@
 #include <dshow.h>
 #include <dvdmedia.h>
 
+/* EC_DEVICE_LOST is not defined in MinGW dshow headers. */
+#ifndef EC_DEVICE_LOST
+#define EC_DEVICE_LOST 0x1f
+#endif
+
 long ff_copy_dshow_media_type(AM_MEDIA_TYPE *dst, const AM_MEDIA_TYPE *src);
 void ff_print_VIDEO_STREAM_CONFIG_CAPS(const VIDEO_STREAM_CONFIG_CAPS *caps);
 void ff_print_AUDIO_STREAM_CONFIG_CAPS(const AUDIO_STREAM_CONFIG_CAPS *caps);
diff --git a/libavdevice/lavfi.c b/libavdevice/lavfi.c
index 4f1ba58..3b6f0c3 100644
--- a/libavdevice/lavfi.c
+++ b/libavdevice/lavfi.c
@@ -25,7 +25,7 @@
 
 /* #define DEBUG */
 
-#include "float.h"              /* DBL_MIN, DBL_MAX */
+#include <float.h>              /* DBL_MIN, DBL_MAX */
 
 #include "libavutil/bprint.h"
 #include "libavutil/channel_layout.h"
@@ -282,6 +282,10 @@
             st->codec->height     = link->h;
             st       ->sample_aspect_ratio =
             st->codec->sample_aspect_ratio = link->sample_aspect_ratio;
+            avctx->probesize = FFMAX(avctx->probesize,
+                                     link->w * link->h *
+                                     av_get_padded_bits_per_pixel(av_pix_fmt_desc_get(link->format)) *
+                                     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);
diff --git a/libavdevice/libcdio.c b/libavdevice/libcdio.c
index fa311fd..a824bc3 100644
--- a/libavdevice/libcdio.c
+++ b/libavdevice/libcdio.c
@@ -23,8 +23,15 @@
  * libcdio CD grabbing
  */
 
+#include "config.h"
+
+#if HAVE_CDIO_PARANOIA_H
 #include <cdio/cdda.h>
 #include <cdio/paranoia.h>
+#elif HAVE_CDIO_PARANOIA_PARANOIA_H
+#include <cdio/paranoia/cdda.h>
+#include <cdio/paranoia/paranoia.h>
+#endif
 
 #include "libavutil/log.h"
 #include "libavutil/mem.h"
@@ -33,9 +40,6 @@
 #include "libavformat/avformat.h"
 #include "libavformat/internal.h"
 
-/* cdio returns some malloced strings that need to be free()d */
-#undef free
-
 typedef struct CDIOContext {
     const AVClass       *class;
     cdrom_drive_t       *drive;
diff --git a/libavdevice/libdc1394.c b/libavdevice/libdc1394.c
index bae1497..80cb1be 100644
--- a/libavdevice/libdc1394.c
+++ b/libavdevice/libdc1394.c
@@ -48,8 +48,6 @@
 #define DC1394_FRAMERATE_240   FRAMERATE_240
 #endif
 
-#undef free
-
 typedef struct dc1394_data {
     AVClass *class;
 #if HAVE_LIBDC1394_1
diff --git a/libavdevice/timefilter.c b/libavdevice/timefilter.c
index 343f1b1..ba2e54e 100644
--- a/libavdevice/timefilter.c
+++ b/libavdevice/timefilter.c
@@ -90,8 +90,6 @@
 #include "libavutil/lfg.h"
 #define LFG_MAX ((1LL << 32) - 1)
 
-#undef printf
-
 int main(void)
 {
     AVLFG prng;
diff --git a/libavdevice/v4l2.c b/libavdevice/v4l2.c
index cd6aeb2..5287bc1 100644
--- a/libavdevice/v4l2.c
+++ b/libavdevice/v4l2.c
@@ -24,7 +24,7 @@
  * Video4Linux2 grab interface
  *
  * Part of this file is based on the V4L2 video capture example
- * (http://v4l2spec.bytesex.org/v4l2spec/capture.c)
+ * (http://linuxtv.org/downloads/v4l-dvb-apis/capture-example.html)
  *
  * Thanks to Michael Niedermayer for providing the mapping between
  * V4L2_PIX_FMT_* and AV_PIX_FMT_*
@@ -112,9 +112,11 @@
     void **buf_start;
     unsigned int *buf_len;
     char *standard;
+    v4l2_std_id std_id;
     int channel;
     char *pixel_format; /**< Set by a private option. */
     int list_format;    /**< Set by a private option. */
+    int list_standard;  /**< Set by a private option. */
     char *framerate;    /**< Set by a private option. */
 };
 
@@ -138,6 +140,7 @@
     { 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  },
@@ -147,9 +150,15 @@
     { 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
@@ -159,7 +168,7 @@
 {
     struct v4l2_capability cap;
     int fd;
-    int res, err;
+    int ret;
     int flags = O_RDWR;
 
     if (ctx->flags & AVFMT_FLAG_NONBLOCK) {
@@ -168,38 +177,32 @@
 
     fd = v4l2_open(ctx->filename, flags, 0);
     if (fd < 0) {
-        err = errno;
-
-        av_log(ctx, AV_LOG_ERROR, "Cannot open video device %s : %s\n",
-               ctx->filename, strerror(err));
-
-        return AVERROR(err);
+        ret = AVERROR(errno);
+        av_log(ctx, AV_LOG_ERROR, "Cannot open video device %s: %s\n",
+               ctx->filename, av_err2str(ret));
+        return ret;
     }
 
-    res = v4l2_ioctl(fd, VIDIOC_QUERYCAP, &cap);
-    if (res < 0) {
-        err = errno;
+    if (v4l2_ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0) {
+        ret = AVERROR(errno);
         av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYCAP): %s\n",
-               strerror(err));
-
+               av_err2str(ret));
         goto fail;
     }
 
-    av_log(ctx, AV_LOG_VERBOSE, "[%d]Capabilities: %x\n",
+    av_log(ctx, AV_LOG_VERBOSE, "fd:%d capabilities:%x\n",
            fd, cap.capabilities);
 
     if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
         av_log(ctx, AV_LOG_ERROR, "Not a video capture device.\n");
-        err = ENODEV;
-
+        ret = AVERROR(ENODEV);
         goto fail;
     }
 
     if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
         av_log(ctx, AV_LOG_ERROR,
                "The device does not support the streaming I/O method.\n");
-        err = ENOSYS;
-
+        ret = AVERROR(ENOSYS);
         goto fail;
     }
 
@@ -207,7 +210,7 @@
 
 fail:
     v4l2_close(fd);
-    return AVERROR(err);
+    return ret;
 }
 
 static int device_init(AVFormatContext *ctx, int *width, int *height,
@@ -218,14 +221,15 @@
     struct v4l2_format fmt = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE };
     struct v4l2_pix_format *pix = &fmt.fmt.pix;
 
-    int res;
+    int res = 0;
 
     pix->width = *width;
     pix->height = *height;
     pix->pixelformat = pix_fmt;
     pix->field = V4L2_FIELD_ANY;
 
-    res = v4l2_ioctl(fd, VIDIOC_S_FMT, &fmt);
+    if (v4l2_ioctl(fd, VIDIOC_S_FMT, &fmt) < 0)
+        res = AVERROR(errno);
 
     if ((*width != fmt.fmt.pix.width) || (*height != fmt.fmt.pix.height)) {
         av_log(ctx, AV_LOG_INFO,
@@ -240,11 +244,12 @@
                "The V4L2 driver changed the pixel format "
                "from 0x%08X to 0x%08X\n",
                pix_fmt, fmt.fmt.pix.pixelformat);
-        res = -1;
+        res = AVERROR(EINVAL);
     }
 
     if (fmt.fmt.pix.field == V4L2_FIELD_INTERLACED) {
-        av_log(ctx, AV_LOG_DEBUG, "The V4L2 driver using the interlaced mode");
+        av_log(ctx, AV_LOG_DEBUG,
+               "The V4L2 driver is using the interlaced mode\n");
         s->interlaced = 1;
     }
 
@@ -349,13 +354,13 @@
         if (!(vfd.flags & V4L2_FMT_FLAG_COMPRESSED) &&
             type & V4L_RAWFORMATS) {
             const char *fmt_name = av_get_pix_fmt_name(pix_fmt);
-            av_log(ctx, AV_LOG_INFO, "R : %9s : %20s :",
+            av_log(ctx, AV_LOG_INFO, "Raw       : %9s : %20s :",
                    fmt_name ? fmt_name : "Unsupported",
                    vfd.description);
         } else if (vfd.flags & V4L2_FMT_FLAG_COMPRESSED &&
                    type & V4L_COMPFORMATS) {
-            AVCodec *codec = avcodec_find_encoder(codec_id);
-            av_log(ctx, AV_LOG_INFO, "C : %9s : %20s :",
+            AVCodec *codec = avcodec_find_decoder(codec_id);
+            av_log(ctx, AV_LOG_INFO, "Compressed: %9s : %20s :",
                    codec ? codec->name : "Unsupported",
                    vfd.description);
         } else {
@@ -375,6 +380,30 @@
     }
 }
 
+static void list_standards(AVFormatContext *ctx)
+{
+    int ret;
+    struct video_data *s = ctx->priv_data;
+    struct v4l2_standard standard;
+
+    if (s->std_id == 0)
+        return;
+
+    for (standard.index = 0; ; standard.index++) {
+        if (v4l2_ioctl(s->fd, VIDIOC_ENUMSTD, &standard) < 0) {
+            ret = AVERROR(errno);
+            if (ret == AVERROR(EINVAL)) {
+                break;
+            } else {
+                av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_ENUMSTD): %s\n", av_err2str(ret));
+                return;
+            }
+        }
+        av_log(ctx, AV_LOG_INFO, "%2d, %16llx, %s\n",
+               standard.index, standard.id, standard.name);
+    }
+}
+
 static int mmap_init(AVFormatContext *ctx)
 {
     int i, res;
@@ -385,14 +414,10 @@
         .memory = V4L2_MEMORY_MMAP
     };
 
-    res = v4l2_ioctl(s->fd, VIDIOC_REQBUFS, &req);
-    if (res < 0) {
-        if (errno == EINVAL) {
-            av_log(ctx, AV_LOG_ERROR, "Device does not support mmap\n");
-        } else {
-            av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_REQBUFS)\n");
-        }
-        return AVERROR(errno);
+    if (v4l2_ioctl(s->fd, VIDIOC_REQBUFS, &req) < 0) {
+        res = AVERROR(errno);
+        av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_REQBUFS): %s\n", av_err2str(res));
+        return res;
     }
 
     if (req.count < 2) {
@@ -418,27 +443,27 @@
             .index  = i,
             .memory = V4L2_MEMORY_MMAP
         };
-        res = v4l2_ioctl(s->fd, VIDIOC_QUERYBUF, &buf);
-        if (res < 0) {
-            av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYBUF)\n");
-            return AVERROR(errno);
+        if (v4l2_ioctl(s->fd, VIDIOC_QUERYBUF, &buf) < 0) {
+            res = AVERROR(errno);
+            av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYBUF): %s\n", av_err2str(res));
+            return res;
         }
 
         s->buf_len[i] = buf.length;
         if (s->frame_size > 0 && s->buf_len[i] < s->frame_size) {
             av_log(ctx, AV_LOG_ERROR,
-                   "Buffer len [%d] = %d != %d\n",
+                   "buf_len[%d] = %d < expected frame size %d\n",
                    i, s->buf_len[i], s->frame_size);
-
-            return -1;
+            return AVERROR(ENOMEM);
         }
         s->buf_start[i] = v4l2_mmap(NULL, buf.length,
                                PROT_READ | PROT_WRITE, MAP_SHARED,
                                s->fd, buf.m.offset);
 
         if (s->buf_start[i] == MAP_FAILED) {
-            av_log(ctx, AV_LOG_ERROR, "mmap: %s\n", strerror(errno));
-            return AVERROR(errno);
+            res = AVERROR(errno);
+            av_log(ctx, AV_LOG_ERROR, "mmap: %s\n", av_err2str(res));
+            return res;
         }
     }
 
@@ -460,10 +485,10 @@
     fd = buf_descriptor->fd;
     av_free(buf_descriptor);
 
-    res = v4l2_ioctl(fd, VIDIOC_QBUF, &buf);
-    if (res < 0)
-        av_log(NULL, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n",
-               strerror(errno));
+    if (v4l2_ioctl(fd, VIDIOC_QBUF, &buf) < 0) {
+        res = AVERROR(errno);
+        av_log(NULL, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n", av_err2str(res));
+    }
 
     pkt->data = NULL;
     pkt->size = 0;
@@ -495,8 +520,8 @@
     now = av_gettime_monotonic();
     if (s->ts_mode == V4L_TS_MONO2ABS ||
         (ts <= now + 1 * AV_TIME_BASE && ts >= now - 10 * AV_TIME_BASE)) {
-        int64_t period = av_rescale_q(1, ctx->streams[0]->codec->time_base,
-                                      AV_TIME_BASE_Q);
+        int64_t period = av_rescale_q(1, AV_TIME_BASE_Q,
+                                      ctx->streams[0]->avg_frame_rate);
         av_log(ctx, AV_LOG_INFO, "Detected monotonic timestamps, converting\n");
         /* microseconds instead of seconds, MHz instead of Hz */
         s->timefilter = ff_timefilter_new(1, period, 1.0E-6);
@@ -546,12 +571,15 @@
             pkt->size = 0;
             return AVERROR(EAGAIN);
         }
-        av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_DQBUF): %s\n",
-               strerror(errno));
-
-        return AVERROR(errno);
+        res = AVERROR(errno);
+        av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_DQBUF): %s\n", av_err2str(res));
+        return res;
     }
-    av_assert0(buf.index < s->buffers);
+
+    if (buf.index >= s->buffers) {
+        av_log(ctx, AV_LOG_ERROR, "Invalid buffer index received.\n");
+        return AVERROR(EINVAL);
+    }
 
     /* CPIA is a compressed format and we don't know the exact number of bytes
      * used by a frame, so set it here as the driver announces it.
@@ -563,7 +591,6 @@
         av_log(ctx, AV_LOG_ERROR,
                "The v4l2 frame is %d bytes, but %d bytes are expected\n",
                buf.bytesused, s->frame_size);
-
         return AVERROR_INVALIDDATA;
     }
 
@@ -582,7 +609,6 @@
          */
         av_log(ctx, AV_LOG_ERROR, "Failed to allocate a buffer descriptor\n");
         res = v4l2_ioctl(s->fd, VIDIOC_QBUF, &buf);
-
         return AVERROR(ENOMEM);
     }
     buf_descriptor->fd = s->fd;
@@ -605,22 +631,18 @@
             .memory = V4L2_MEMORY_MMAP
         };
 
-        res = v4l2_ioctl(s->fd, VIDIOC_QBUF, &buf);
-        if (res < 0) {
-            av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n",
-                   strerror(errno));
-
-            return AVERROR(errno);
+        if (v4l2_ioctl(s->fd, VIDIOC_QBUF, &buf) < 0) {
+            res = AVERROR(errno);
+            av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n", av_err2str(res));
+            return res;
         }
     }
 
     type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-    res = v4l2_ioctl(s->fd, VIDIOC_STREAMON, &type);
-    if (res < 0) {
-        av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_STREAMON): %s\n",
-               strerror(errno));
-
-        return AVERROR(errno);
+    if (v4l2_ioctl(s->fd, VIDIOC_STREAMON, &type) < 0) {
+        res = AVERROR(errno);
+        av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_STREAMON): %s\n", av_err2str(res));
+        return res;
     }
 
     return 0;
@@ -646,15 +668,12 @@
 static int v4l2_set_parameters(AVFormatContext *s1)
 {
     struct video_data *s = s1->priv_data;
-    struct v4l2_input input = { 0 };
     struct v4l2_standard standard = { 0 };
     struct v4l2_streamparm streamparm = { 0 };
-    struct v4l2_fract *tpf = &streamparm.parm.capture.timeperframe;
+    struct v4l2_fract *tpf;
     AVRational framerate_q = { 0 };
     int i, ret;
 
-    streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
     if (s->framerate &&
         (ret = av_parse_video_rate(&framerate_q, s->framerate)) < 0) {
         av_log(s1, AV_LOG_ERROR, "Could not parse framerate '%s'.\n",
@@ -662,113 +681,148 @@
         return ret;
     }
 
-    /* set tv video input */
-    input.index = s->channel;
-    if (v4l2_ioctl(s->fd, VIDIOC_ENUMINPUT, &input) < 0) {
-        av_log(s1, AV_LOG_ERROR, "The V4L2 driver ioctl enum input failed:\n");
-        return AVERROR(EIO);
-    }
-
-    av_log(s1, AV_LOG_DEBUG, "The V4L2 driver set input_id: %d, input: %s\n",
-            s->channel, input.name);
-    if (v4l2_ioctl(s->fd, VIDIOC_S_INPUT, &input.index) < 0) {
-        av_log(s1, AV_LOG_ERROR,
-               "The V4L2 driver ioctl set input(%d) failed\n",
-                s->channel);
-        return AVERROR(EIO);
-    }
-
     if (s->standard) {
-        av_log(s1, AV_LOG_DEBUG, "The V4L2 driver set standard: %s\n",
-               s->standard);
-        /* set tv standard */
-        for(i=0;;i++) {
-            standard.index = i;
-            ret = v4l2_ioctl(s->fd, VIDIOC_ENUMSTD, &standard);
-            if (ret < 0 || !av_strcasecmp(standard.name, s->standard))
-                break;
-        }
-        if (ret < 0) {
-            av_log(s1, AV_LOG_ERROR, "Unknown standard '%s'\n", s->standard);
-            return ret;
-        }
+        if (s->std_id) {
+            ret = 0;
+            av_log(s1, AV_LOG_DEBUG, "Setting standard: %s\n", s->standard);
+            /* set tv standard */
+            for (i = 0; ; i++) {
+                standard.index = i;
+                if (v4l2_ioctl(s->fd, VIDIOC_ENUMSTD, &standard) < 0) {
+                    ret = AVERROR(errno);
+                    break;
+                }
+                if (!av_strcasecmp(standard.name, s->standard))
+                    break;
+            }
+            if (ret < 0) {
+                av_log(s1, AV_LOG_ERROR, "Unknown or unsupported standard '%s'\n", s->standard);
+                return ret;
+            }
 
-        av_log(s1, AV_LOG_DEBUG,
-               "The V4L2 driver set standard: %s, id: %"PRIu64"\n",
-               s->standard, (uint64_t)standard.id);
-        if (v4l2_ioctl(s->fd, VIDIOC_S_STD, &standard.id) < 0) {
-            av_log(s1, AV_LOG_ERROR,
-                   "The V4L2 driver ioctl set standard(%s) failed\n",
-                   s->standard);
-            return AVERROR(EIO);
+            if (v4l2_ioctl(s->fd, VIDIOC_S_STD, &standard.id) < 0) {
+                ret = AVERROR(errno);
+                av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_S_STD): %s\n", av_err2str(ret));
+                return ret;
+            }
+        } else {
+            av_log(s1, AV_LOG_WARNING,
+                   "This device does not support any standard\n");
         }
     }
 
+    /* get standard */
+    if (v4l2_ioctl(s->fd, VIDIOC_G_STD, &s->std_id) == 0) {
+        tpf = &standard.frameperiod;
+        for (i = 0; ; i++) {
+            standard.index = i;
+            if (v4l2_ioctl(s->fd, VIDIOC_ENUMSTD, &standard) < 0) {
+                ret = AVERROR(errno);
+                av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_ENUMSTD): %s\n", av_err2str(ret));
+                return ret;
+            }
+            if (standard.id == s->std_id) {
+                av_log(s1, AV_LOG_DEBUG,
+                       "Current standard: %s, id: %"PRIu64", frameperiod: %d/%d\n",
+                       standard.name, (uint64_t)standard.id, tpf->numerator, tpf->denominator);
+                break;
+            }
+        }
+    } else {
+        tpf = &streamparm.parm.capture.timeperframe;
+    }
+
+    streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+    if (v4l2_ioctl(s->fd, VIDIOC_G_PARM, &streamparm) < 0) {
+        ret = AVERROR(errno);
+        av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_G_PARM): %s\n", av_err2str(ret));
+        return ret;
+    }
+
     if (framerate_q.num && framerate_q.den) {
-        av_log(s1, AV_LOG_DEBUG, "Setting time per frame to %d/%d\n",
-               framerate_q.den, framerate_q.num);
-        tpf->numerator   = framerate_q.den;
-        tpf->denominator = framerate_q.num;
+        if (streamparm.parm.capture.capability & V4L2_CAP_TIMEPERFRAME) {
+            tpf = &streamparm.parm.capture.timeperframe;
 
-        if (v4l2_ioctl(s->fd, VIDIOC_S_PARM, &streamparm) != 0) {
-            av_log(s1, AV_LOG_ERROR,
-                   "ioctl set time per frame(%d/%d) failed\n",
+            av_log(s1, AV_LOG_DEBUG, "Setting time per frame to %d/%d\n",
                    framerate_q.den, framerate_q.num);
-            return AVERROR(EIO);
-        }
+            tpf->numerator   = framerate_q.den;
+            tpf->denominator = framerate_q.num;
 
-        if (framerate_q.num != tpf->denominator ||
-            framerate_q.den != tpf->numerator) {
-            av_log(s1, AV_LOG_INFO,
-                   "The driver changed the time per frame from "
-                   "%d/%d to %d/%d\n",
-                   framerate_q.den, framerate_q.num,
-                   tpf->numerator, tpf->denominator);
-        }
-    } else {
-        if (v4l2_ioctl(s->fd, VIDIOC_G_PARM, &streamparm) != 0) {
-            av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_G_PARM): %s\n",
-                   strerror(errno));
-            return AVERROR(errno);
+            if (v4l2_ioctl(s->fd, VIDIOC_S_PARM, &streamparm) < 0) {
+                ret = AVERROR(errno);
+                av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_S_PARM): %s\n", av_err2str(ret));
+                return ret;
+            }
+
+            if (framerate_q.num != tpf->denominator ||
+                framerate_q.den != tpf->numerator) {
+                av_log(s1, AV_LOG_INFO,
+                       "The driver changed the time per frame from "
+                       "%d/%d to %d/%d\n",
+                       framerate_q.den, framerate_q.num,
+                       tpf->numerator, tpf->denominator);
+            }
+        } else {
+            av_log(s1, AV_LOG_WARNING,
+                   "The driver does not allow to change time per frame\n");
         }
     }
-    s1->streams[0]->codec->time_base.den = tpf->denominator;
-    s1->streams[0]->codec->time_base.num = tpf->numerator;
+    s1->streams[0]->avg_frame_rate.num = tpf->denominator;
+    s1->streams[0]->avg_frame_rate.den = tpf->numerator;
 
     return 0;
 }
 
-static uint32_t device_try_init(AVFormatContext *s1,
-                                enum AVPixelFormat pix_fmt,
-                                int *width,
-                                int *height,
-                                enum AVCodecID *codec_id)
+static int device_try_init(AVFormatContext *s1,
+                           enum AVPixelFormat pix_fmt,
+                           int *width,
+                           int *height,
+                           uint32_t *desired_format,
+                           enum AVCodecID *codec_id)
 {
-    uint32_t desired_format = fmt_ff2v4l(pix_fmt, s1->video_codec_id);
+    int ret, i;
 
-    if (desired_format == 0 ||
-        device_init(s1, width, height, desired_format) < 0) {
-        int i;
+    *desired_format = fmt_ff2v4l(pix_fmt, s1->video_codec_id);
 
-        desired_format = 0;
-        for (i = 0; i<FF_ARRAY_ELEMS(fmt_conversion_table); i++) {
-            if (s1->video_codec_id == AV_CODEC_ID_NONE ||
-                fmt_conversion_table[i].codec_id == s1->video_codec_id) {
-                desired_format = fmt_conversion_table[i].v4l2_fmt;
-                if (device_init(s1, width, height, desired_format) >= 0) {
-                    break;
-                }
-                desired_format = 0;
-            }
+    if (*desired_format) {
+        ret = device_init(s1, width, height, *desired_format);
+        if (ret < 0) {
+            *desired_format = 0;
+            if (ret != AVERROR(EINVAL))
+                return ret;
         }
     }
 
-    if (desired_format != 0) {
-        *codec_id = fmt_v4l2codec(desired_format);
-        av_assert0(*codec_id != AV_CODEC_ID_NONE);
+    if (!*desired_format) {
+        for (i = 0; i<FF_ARRAY_ELEMS(fmt_conversion_table); i++) {
+            if (s1->video_codec_id == AV_CODEC_ID_NONE ||
+                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"));
+
+                *desired_format = fmt_conversion_table[i].v4l2_fmt;
+                ret = device_init(s1, width, height, *desired_format);
+                if (ret >= 0)
+                    break;
+                else if (ret != AVERROR(EINVAL))
+                    return ret;
+                *desired_format = 0;
+            }
+        }
+
+        if (*desired_format == 0) {
+            av_log(s1, AV_LOG_ERROR, "Cannot find a proper format for "
+                   "codec '%s' (id %d), pixel format '%s' (id %d)\n",
+                   avcodec_get_name(s1->video_codec_id), s1->video_codec_id,
+                   (char *)av_x_if_null(av_get_pix_fmt_name(pix_fmt), "none"), pix_fmt);
+            ret = AVERROR(EINVAL);
+        }
     }
 
-    return desired_format;
+    *codec_id = fmt_v4l2codec(*desired_format);
+    av_assert0(*codec_id != AV_CODEC_ID_NONE);
+    return ret;
 }
 
 static int v4l2_read_header(AVFormatContext *s1)
@@ -779,23 +833,42 @@
     uint32_t desired_format;
     enum AVCodecID codec_id = AV_CODEC_ID_NONE;
     enum AVPixelFormat pix_fmt = AV_PIX_FMT_NONE;
+    struct v4l2_input input = { 0 };
 
     st = avformat_new_stream(s1, NULL);
-    if (!st) {
-        res = AVERROR(ENOMEM);
-        goto out;
-    }
+    if (!st)
+        return AVERROR(ENOMEM);
 
     s->fd = device_open(s1);
-    if (s->fd < 0) {
-        res = s->fd;
-        goto out;
+    if (s->fd < 0)
+        return s->fd;
+
+    /* set tv video input */
+    av_log(s1, AV_LOG_DEBUG, "Selecting input_channel: %d\n", s->channel);
+    if (v4l2_ioctl(s->fd, VIDIOC_S_INPUT, &s->channel) < 0) {
+        res = AVERROR(errno);
+        av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_S_INPUT): %s\n", av_err2str(res));
+        return res;
     }
 
+    input.index = s->channel;
+    if (v4l2_ioctl(s->fd, VIDIOC_ENUMINPUT, &input) < 0) {
+        res = AVERROR(errno);
+        av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_ENUMINPUT): %s\n", av_err2str(res));
+        return res;
+    }
+    s->std_id = input.std;
+    av_log(s1, AV_LOG_DEBUG, "input_channel: %d, input_name: %s\n",
+           s->channel, input.name);
+
     if (s->list_format) {
         list_formats(s1, s->fd, s->list_format);
-        res = AVERROR_EXIT;
-        goto out;
+        return AVERROR_EXIT;
+    }
+
+    if (s->list_standard) {
+        list_standards(s1);
+        return AVERROR_EXIT;
     }
 
     avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */
@@ -812,8 +885,7 @@
             av_log(s1, AV_LOG_ERROR, "No such input format: %s.\n",
                    s->pixel_format);
 
-            res = AVERROR(EINVAL);
-            goto out;
+            return AVERROR(EINVAL);
         }
     }
 
@@ -824,10 +896,9 @@
                "Querying the device for the current frame size\n");
         fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
         if (v4l2_ioctl(s->fd, VIDIOC_G_FMT, &fmt) < 0) {
-            av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_G_FMT): %s\n",
-                   strerror(errno));
             res = AVERROR(errno);
-            goto out;
+            av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_G_FMT): %s\n", av_err2str(res));
+            return res;
         }
 
         s->width  = fmt.fmt.pix.width;
@@ -836,8 +907,11 @@
                "Setting frame size to %dx%d\n", s->width, s->height);
     }
 
-    desired_format = device_try_init(s1, pix_fmt, &s->width, &s->height,
-                                     &codec_id);
+    res = device_try_init(s1, pix_fmt, &s->width, &s->height, &desired_format, &codec_id);
+    if (res < 0) {
+        v4l2_close(s->fd);
+        return res;
+    }
 
     /* If no pixel_format was specified, the codec_id was not known up
      * until now. Set video_codec_id in the context, as codec_id will
@@ -846,21 +920,13 @@
     if (codec_id != AV_CODEC_ID_NONE && s1->video_codec_id == AV_CODEC_ID_NONE)
         s1->video_codec_id = codec_id;
 
-    if (desired_format == 0) {
-        av_log(s1, AV_LOG_ERROR, "Cannot find a proper format for "
-               "codec_id %d, pix_fmt %d.\n", s1->video_codec_id, pix_fmt);
-        v4l2_close(s->fd);
-
-        res = AVERROR(EIO);
-        goto out;
-    }
     if ((res = av_image_check_size(s->width, s->height, 0, s1)) < 0)
-        goto out;
+        return res;
 
     s->frame_format = desired_format;
 
     if ((res = v4l2_set_parameters(s1)) < 0)
-        goto out;
+        return res;
 
     st->codec->pix_fmt = fmt_v4l2ff(desired_format, codec_id);
     s->frame_size =
@@ -869,7 +935,7 @@
     if ((res = mmap_init(s1)) ||
         (res = mmap_start(s1)) < 0) {
         v4l2_close(s->fd);
-        goto out;
+        return res;
     }
 
     s->top_field_first = first_field(s->fd);
@@ -881,12 +947,13 @@
             avcodec_pix_fmt_to_codec_tag(st->codec->pix_fmt);
     if (desired_format == V4L2_PIX_FMT_YVU420)
         st->codec->codec_tag = MKTAG('Y', 'V', '1', '2');
+    else if (desired_format == V4L2_PIX_FMT_YVU410)
+        st->codec->codec_tag = MKTAG('Y', 'V', 'U', '9');
     st->codec->width = s->width;
     st->codec->height = s->height;
-    st->codec->bit_rate = s->frame_size * 1/av_q2d(st->codec->time_base) * 8;
+    st->codec->bit_rate = s->frame_size * av_q2d(st->avg_frame_rate) * 8;
 
-out:
-    return res;
+    return 0;
 }
 
 static int v4l2_read_packet(AVFormatContext *s1, AVPacket *pkt)
@@ -922,21 +989,27 @@
 #define DEC AV_OPT_FLAG_DECODING_PARAM
 
 static const AVOption options[] = {
-    { "standard",     "TV standard, used only by analog frame grabber",            OFFSET(standard),     AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0,       DEC },
-    { "channel",      "TV channel, used only by frame grabber",                    OFFSET(channel),      AV_OPT_TYPE_INT,    {.i64 = 0 },    0, INT_MAX, DEC },
-    { "video_size",   "A string describing frame size, such as 640x480 or hd720.", OFFSET(width),        AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL},  0, 0,       DEC },
-    { "pixel_format", "Preferred pixel format",                                    OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,       DEC },
-    { "input_format", "Preferred pixel format (for raw video) or codec name",      OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,       DEC },
-    { "framerate",    "",                                                          OFFSET(framerate),    AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,       DEC },
-    { "list_formats", "List available formats and exit",                           OFFSET(list_format),  AV_OPT_TYPE_INT,    {.i64 = 0 },  0, INT_MAX, DEC, "list_formats" },
-    { "all",          "Show all available formats",                                OFFSET(list_format),  AV_OPT_TYPE_CONST,  {.i64 = V4L_ALLFORMATS  },    0, INT_MAX, DEC, "list_formats" },
-    { "raw",          "Show only non-compressed formats",                          OFFSET(list_format),  AV_OPT_TYPE_CONST,  {.i64 = V4L_RAWFORMATS  },    0, INT_MAX, DEC, "list_formats" },
-    { "compressed",   "Show only compressed formats",                              OFFSET(list_format),  AV_OPT_TYPE_CONST,  {.i64 = V4L_COMPFORMATS },    0, INT_MAX, DEC, "list_formats" },
-    { "timestamps",   "Kind of timestamps for grabbed frames",                     OFFSET(ts_mode),      AV_OPT_TYPE_INT,    {.i64 = 0 }, 0, 2, DEC, "timestamps" },
-    { "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" },
-    { "ts",           "Kind of timestamps for grabbed frames",                     OFFSET(ts_mode),      AV_OPT_TYPE_INT,    {.i64 = 0 }, 0, 2, DEC, "timestamps" },
+    { "standard",     "set TV standard, used only by analog frame grabber",       OFFSET(standard),     AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0,       DEC },
+    { "channel",      "set TV channel, used only by frame grabber",               OFFSET(channel),      AV_OPT_TYPE_INT,    {.i64 = 0 },    0, INT_MAX, DEC },
+    { "video_size",   "set frame size",                                           OFFSET(width),        AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL},  0, 0,   DEC },
+    { "pixel_format", "set preferred pixel format",                               OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,       DEC },
+    { "input_format", "set preferred pixel format (for raw video) or codec name", OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,       DEC },
+    { "framerate",    "set frame rate",                                           OFFSET(framerate),    AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,       DEC },
+
+    { "list_formats", "list available formats and exit",                          OFFSET(list_format),  AV_OPT_TYPE_INT,    {.i64 = 0 },  0, INT_MAX, DEC, "list_formats" },
+    { "all",          "show all available formats",                               OFFSET(list_format),  AV_OPT_TYPE_CONST,  {.i64 = V4L_ALLFORMATS  },    0, INT_MAX, DEC, "list_formats" },
+    { "raw",          "show only non-compressed formats",                         OFFSET(list_format),  AV_OPT_TYPE_CONST,  {.i64 = V4L_RAWFORMATS  },    0, INT_MAX, DEC, "list_formats" },
+    { "compressed",   "show only compressed formats",                             OFFSET(list_format),  AV_OPT_TYPE_CONST,  {.i64 = V4L_COMPFORMATS },    0, INT_MAX, DEC, "list_formats" },
+
+    { "list_standards", "list supported standards and exit",                      OFFSET(list_standard), AV_OPT_TYPE_INT,   {.i64 = 0 },  0, 1, DEC, "list_standards" },
+    { "all",            "show all supported standards",                           OFFSET(list_standard), AV_OPT_TYPE_CONST, {.i64 = 1 },  0, 0, DEC, "list_standards" },
+
+    { "timestamps",   "set type of timestamps for grabbed frames",                OFFSET(ts_mode),      AV_OPT_TYPE_INT,    {.i64 = 0 }, 0, 2, DEC, "timestamps" },
+    { "ts",           "set type of timestamps for grabbed frames",                OFFSET(ts_mode),      AV_OPT_TYPE_INT,    {.i64 = 0 }, 0, 2, DEC, "timestamps" },
+    { "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" },
+
     { NULL },
 };
 
diff --git a/libavdevice/version.h b/libavdevice/version.h
index 5eed4f5..9e0c0ae 100644
--- a/libavdevice/version.h
+++ b/libavdevice/version.h
@@ -29,7 +29,7 @@
 
 #define LIBAVDEVICE_VERSION_MAJOR  54
 #define LIBAVDEVICE_VERSION_MINOR   3
-#define LIBAVDEVICE_VERSION_MICRO 102
+#define LIBAVDEVICE_VERSION_MICRO 103
 
 #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \
                                                LIBAVDEVICE_VERSION_MINOR, \
diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index 0e49912..04ed8b8 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -2,20 +2,23 @@
 
 NAME = avfilter
 FFLIBS = avutil
-FFLIBS-$(CONFIG_ASYNCTS_FILTER) += avresample
-FFLIBS-$(CONFIG_RESAMPLE_FILTER) += avresample
-FFLIBS-$(CONFIG_SCALE_FILTER)   += swscale
-
 FFLIBS-$(CONFIG_ACONVERT_FILTER)             += swresample
 FFLIBS-$(CONFIG_AMOVIE_FILTER)               += avformat avcodec
 FFLIBS-$(CONFIG_ARESAMPLE_FILTER)            += swresample
+FFLIBS-$(CONFIG_ASYNCTS_FILTER)              += avresample
 FFLIBS-$(CONFIG_ATEMPO_FILTER)               += avcodec
 FFLIBS-$(CONFIG_DECIMATE_FILTER)             += avcodec
+FFLIBS-$(CONFIG_DESHAKE_FILTER)              += avcodec
 FFLIBS-$(CONFIG_MOVIE_FILTER)                += avformat avcodec
+FFLIBS-$(CONFIG_MP_FILTER)                   += avcodec
 FFLIBS-$(CONFIG_PAN_FILTER)                  += swresample
-FFLIBS-$(CONFIG_REMOVELOGO_FILTER)           += avformat avcodec
-FFLIBS-$(CONFIG_MP_FILTER)                   += avcodec postproc
+FFLIBS-$(CONFIG_PP_FILTER)                   += postproc
+FFLIBS-$(CONFIG_REMOVELOGO_FILTER)           += avformat avcodec swscale
+FFLIBS-$(CONFIG_RESAMPLE_FILTER)             += avresample
+FFLIBS-$(CONFIG_SCALE_FILTER)                += swscale
+FFLIBS-$(CONFIG_SHOWSPECTRUM_FILTER)         += avcodec
 FFLIBS-$(CONFIG_SMARTBLUR_FILTER)            += swscale
+FFLIBS-$(CONFIG_SUBTITLES_FILTER)            += avformat avcodec
 
 HEADERS = asrc_abuffer.h                                                \
           avcodec.h                                                     \
@@ -33,13 +36,13 @@
        buffersink.o                                                     \
        buffersrc.o                                                      \
        drawutils.o                                                      \
+       fifo.o                                                           \
        formats.o                                                        \
        graphdump.o                                                      \
        graphparser.o                                                    \
        sink_buffer.o                                                    \
        src_buffer.o                                                     \
        transform.o                                                      \
-       vf_scale.o                                                       \
        video.o                                                          \
 
 
@@ -48,12 +51,15 @@
 OBJS-$(CONFIG_SWSCALE)                       += lswsutils.o
 
 OBJS-$(CONFIG_ACONVERT_FILTER)               += af_aconvert.o
-OBJS-$(CONFIG_AFIFO_FILTER)                  += fifo.o
+OBJS-$(CONFIG_AFADE_FILTER)                  += af_afade.o
 OBJS-$(CONFIG_AFORMAT_FILTER)                += af_aformat.o
+OBJS-$(CONFIG_ALLPASS_FILTER)                += af_biquads.o
 OBJS-$(CONFIG_AMERGE_FILTER)                 += af_amerge.o
 OBJS-$(CONFIG_AMIX_FILTER)                   += af_amix.o
 OBJS-$(CONFIG_ANULL_FILTER)                  += af_anull.o
+OBJS-$(CONFIG_APAD_FILTER)                   += af_apad.o
 OBJS-$(CONFIG_ARESAMPLE_FILTER)              += af_aresample.o
+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
@@ -63,14 +69,22 @@
 OBJS-$(CONFIG_ASTREAMSYNC_FILTER)            += af_astreamsync.o
 OBJS-$(CONFIG_ASYNCTS_FILTER)                += af_asyncts.o
 OBJS-$(CONFIG_ATEMPO_FILTER)                 += af_atempo.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_EARWAX_FILTER)                 += af_earwax.o
 OBJS-$(CONFIG_EBUR128_FILTER)                += f_ebur128.o
+OBJS-$(CONFIG_EQUALIZER_FILTER)              += af_biquads.o
+OBJS-$(CONFIG_HIGHPASS_FILTER)               += af_biquads.o
 OBJS-$(CONFIG_JOIN_FILTER)                   += af_join.o
+OBJS-$(CONFIG_LOWPASS_FILTER)                += af_biquads.o
 OBJS-$(CONFIG_PAN_FILTER)                    += af_pan.o
 OBJS-$(CONFIG_RESAMPLE_FILTER)               += af_resample.o
 OBJS-$(CONFIG_SILENCEDETECT_FILTER)          += af_silencedetect.o
+OBJS-$(CONFIG_TREBLE_FILTER)                 += af_biquads.o
 OBJS-$(CONFIG_VOLUME_FILTER)                 += af_volume.o
 OBJS-$(CONFIG_VOLUMEDETECT_FILTER)           += af_volumedetect.o
 
@@ -80,12 +94,13 @@
 
 OBJS-$(CONFIG_ANULLSINK_FILTER)              += asink_anullsink.o
 
-OBJS-$(CONFIG_ASS_FILTER)                    += vf_ass.o
+OBJS-$(CONFIG_ASS_FILTER)                    += vf_subtitles.o
 OBJS-$(CONFIG_ALPHAEXTRACT_FILTER)           += vf_alphaextract.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_BOXBLUR_FILTER)                += vf_boxblur.o
 OBJS-$(CONFIG_COLORMATRIX_FILTER)            += vf_colormatrix.o
 OBJS-$(CONFIG_COPY_FILTER)                   += vf_copy.o
@@ -100,7 +115,6 @@
 OBJS-$(CONFIG_FADE_FILTER)                   += vf_fade.o
 OBJS-$(CONFIG_FIELD_FILTER)                  += vf_field.o
 OBJS-$(CONFIG_FIELDORDER_FILTER)             += vf_fieldorder.o
-OBJS-$(CONFIG_FIFO_FILTER)                   += fifo.o
 OBJS-$(CONFIG_FORMAT_FILTER)                 += vf_format.o
 OBJS-$(CONFIG_FRAMESTEP_FILTER)              += vf_framestep.o
 OBJS-$(CONFIG_FPS_FILTER)                    += vf_fps.o
@@ -108,23 +122,29 @@
 OBJS-$(CONFIG_GEQ_FILTER)                    += vf_geq.o
 OBJS-$(CONFIG_GRADFUN_FILTER)                += vf_gradfun.o
 OBJS-$(CONFIG_HFLIP_FILTER)                  += vf_hflip.o
+OBJS-$(CONFIG_HISTEQ_FILTER)                 += vf_histeq.o
+OBJS-$(CONFIG_HISTOGRAM_FILTER)              += vf_histogram.o
 OBJS-$(CONFIG_HQDN3D_FILTER)                 += vf_hqdn3d.o
 OBJS-$(CONFIG_HUE_FILTER)                    += vf_hue.o
 OBJS-$(CONFIG_IDET_FILTER)                   += vf_idet.o
+OBJS-$(CONFIG_IL_FILTER)                     += vf_il.o
+OBJS-$(CONFIG_KERNDEINT_FILTER)              += vf_kerndeint.o
 OBJS-$(CONFIG_LUT_FILTER)                    += vf_lut.o
 OBJS-$(CONFIG_LUTRGB_FILTER)                 += vf_lut.o
 OBJS-$(CONFIG_LUTYUV_FILTER)                 += vf_lut.o
 OBJS-$(CONFIG_MP_FILTER)                     += vf_mp.o
 OBJS-$(CONFIG_NEGATE_FILTER)                 += vf_lut.o
 OBJS-$(CONFIG_NOFORMAT_FILTER)               += vf_format.o
+OBJS-$(CONFIG_NOISE_FILTER)                  += vf_noise.o
 OBJS-$(CONFIG_NULL_FILTER)                   += vf_null.o
 OBJS-$(CONFIG_OCV_FILTER)                    += vf_libopencv.o
 OBJS-$(CONFIG_OVERLAY_FILTER)                += vf_overlay.o
 OBJS-$(CONFIG_PAD_FILTER)                    += vf_pad.o
 OBJS-$(CONFIG_PIXDESCTEST_FILTER)            += vf_pixdesctest.o
+OBJS-$(CONFIG_PP_FILTER)                     += vf_pp.o
 OBJS-$(CONFIG_REMOVELOGO_FILTER)             += bbox.o lswsutils.o lavfutils.o vf_removelogo.o
 OBJS-$(CONFIG_SCALE_FILTER)                  += vf_scale.o
-OBJS-$(CONFIG_SELECT_FILTER)                 += vf_select.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
@@ -134,6 +154,7 @@
 OBJS-$(CONFIG_SHOWINFO_FILTER)               += vf_showinfo.o
 OBJS-$(CONFIG_SMARTBLUR_FILTER)              += vf_smartblur.o
 OBJS-$(CONFIG_SPLIT_FILTER)                  += split.o
+OBJS-$(CONFIG_SUBTITLES_FILTER)              += vf_subtitles.o
 OBJS-$(CONFIG_SUPER2XSAI_FILTER)             += vf_super2xsai.o
 OBJS-$(CONFIG_SWAPUV_FILTER)                 += vf_swapuv.o
 OBJS-$(CONFIG_THUMBNAIL_FILTER)              += vf_thumbnail.o
@@ -159,39 +180,32 @@
 
 OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/mp_image.o
 OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/img_format.o
-OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_denoise3d.o
 OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_detc.o
 OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_dint.o
 OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_divtc.o
 OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_down3dright.o
-OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_dsize.o
 OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_eq2.o
 OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_eq.o
 OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_fil.o
 #OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_filmdint.o
 OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_fspp.o
 OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_harddup.o
-OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_il.o
 OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_ilpack.o
 OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_ivtc.o
-OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_kerndeint.o
 OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_mcdeint.o
 OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_noise.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_pp.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_softskip.o
 OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_spp.o
 OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_stereo3d.o
 OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_telecine.o
 OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_tinterlace.o
-OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_unsharp.o
 OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_uspp.o
 OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/pullup.o
 
diff --git a/libavfilter/af_aconvert.c b/libavfilter/af_aconvert.c
index 54f1fcd..e41095f 100644
--- a/libavfilter/af_aconvert.c
+++ b/libavfilter/af_aconvert.c
@@ -147,6 +147,7 @@
                         (void *)insamplesref->data, n);
 
     avfilter_copy_buffer_ref_props(outsamplesref, insamplesref);
+    outsamplesref->audio->channels       = outlink->channels;
     outsamplesref->audio->channel_layout = outlink->channel_layout;
 
     ret = ff_filter_frame(outlink, outsamplesref);
diff --git a/libavfilter/af_afade.c b/libavfilter/af_afade.c
new file mode 100644
index 0000000..00a05e2
--- /dev/null
+++ b/libavfilter/af_afade.c
@@ -0,0 +1,307 @@
+/*
+ * 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
+ * fade audio filter
+ */
+
+#include "libavutil/opt.h"
+#include "audio.h"
+#include "avfilter.h"
+#include "internal.h"
+
+typedef struct {
+    const AVClass *class;
+    int type;
+    int curve;
+    int nb_samples;
+    int64_t start_sample;
+    double duration;
+    double start_time;
+
+    void (*fade_samples)(uint8_t **dst, uint8_t * const *src,
+                         int nb_samples, int channels, int direction,
+                         int64_t start, int range, int curve);
+} AudioFadeContext;
+
+enum CurveType { TRI, QSIN, ESIN, HSIN, LOG, PAR, QUA, CUB, SQU, CBR };
+
+#define OFFSET(x) offsetof(AudioFadeContext, x)
+#define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
+
+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 second to start fading",    OFFSET(start_time),   AV_OPT_TYPE_DOUBLE, {.dbl = 0.   }, 0, 7*24*60*60,FLAGS },
+    { "st",           "set expression of second to start fading",    OFFSET(start_time),   AV_OPT_TYPE_DOUBLE, {.dbl = 0.   }, 0, 7*24*60*60,FLAGS },
+    { "duration",     "set expression for fade duration in seconds", OFFSET(duration),     AV_OPT_TYPE_DOUBLE, {.dbl = 0.   }, 0, 24*60*60,  FLAGS },
+    { "d",            "set expression for fade duration in seconds", OFFSET(duration),     AV_OPT_TYPE_DOUBLE, {.dbl = 0.   }, 0, 24*60*60,  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" },
+    { "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" },
+    { "hsin",         "half of sine wave",                           0,                    AV_OPT_TYPE_CONST,  {.i64 = HSIN }, 0, 0, FLAGS, "curve" },
+    { "log",          "logarithmic",                                 0,                    AV_OPT_TYPE_CONST,  {.i64 = LOG  }, 0, 0, FLAGS, "curve" },
+    { "par",          "inverted parabola",                           0,                    AV_OPT_TYPE_CONST,  {.i64 = PAR  }, 0, 0, FLAGS, "curve" },
+    { "qua",          "quadratic",                                   0,                    AV_OPT_TYPE_CONST,  {.i64 = QUA  }, 0, 0, FLAGS, "curve" },
+    { "cub",          "cubic",                                       0,                    AV_OPT_TYPE_CONST,  {.i64 = CUB  }, 0, 0, FLAGS, "curve" },
+    { "squ",          "square root",                                 0,                    AV_OPT_TYPE_CONST,  {.i64 = SQU  }, 0, 0, FLAGS, "curve" },
+    { "cbr",          "cubic root",                                  0,                    AV_OPT_TYPE_CONST,  {.i64 = CBR  }, 0, 0, FLAGS, "curve" },
+    {NULL},
+};
+
+AVFILTER_DEFINE_CLASS(afade);
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    AudioFadeContext *afade = ctx->priv;
+    int ret;
+
+    afade->class = &afade_class;
+    av_opt_set_defaults(afade);
+
+    if ((ret = av_set_options_string(afade, args, "=", ":")) < 0)
+        return ret;
+
+    if (INT64_MAX - afade->nb_samples < afade->start_sample)
+        return AVERROR(EINVAL);
+
+    return 0;
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    AVFilterFormats *formats;
+    AVFilterChannelLayouts *layouts;
+    static const enum AVSampleFormat sample_fmts[] = {
+        AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16P,
+        AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S32P,
+        AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLTP,
+        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 double fade_gain(int curve, int64_t index, int range)
+{
+    double gain;
+
+    gain = FFMAX(0.0, FFMIN(1.0, 1.0 * index / range));
+
+    switch (curve) {
+    case QSIN:
+        gain = sin(gain * M_PI / 2.0);
+        break;
+    case ESIN:
+        gain = 1.0 - cos(M_PI / 4.0 * (pow(2.0*gain - 1, 3) + 1));
+        break;
+    case HSIN:
+        gain = (1.0 - cos(gain * M_PI)) / 2.0;
+        break;
+    case LOG:
+        gain = pow(0.1, (1 - gain) * 5.0);
+        break;
+    case PAR:
+        gain = (1 - (1 - gain) * (1 - gain));
+        break;
+    case QUA:
+        gain *= gain;
+        break;
+    case CUB:
+        gain = gain * gain * gain;
+        break;
+    case SQU:
+        gain = sqrt(gain);
+        break;
+    case CBR:
+        gain = cbrt(gain);
+        break;
+    }
+
+    return gain;
+}
+
+#define FADE_PLANAR(name, type)                                             \
+static void fade_samples_## name ##p(uint8_t **dst, uint8_t * const *src,   \
+                                     int nb_samples, int channels, int dir, \
+                                     int64_t start, int range, int curve)   \
+{                                                                           \
+    int i, c;                                                               \
+                                                                            \
+    for (i = 0; i < nb_samples; i++) {                                      \
+        double gain = fade_gain(curve, start + i * dir, range);             \
+        for (c = 0; c < channels; c++) {                                    \
+            type *d = (type *)dst[c];                                       \
+            const type *s = (type *)src[c];                                 \
+                                                                            \
+            d[i] = s[i] * gain;                                             \
+        }                                                                   \
+    }                                                                       \
+}
+
+#define FADE(name, type)                                                    \
+static void fade_samples_## name (uint8_t **dst, uint8_t * const *src,      \
+                                  int nb_samples, int channels, int dir,    \
+                                  int64_t start, int range, int curve)      \
+{                                                                           \
+    type *d = (type *)dst[0];                                               \
+    const type *s = (type *)src[0];                                         \
+    int i, c, k = 0;                                                        \
+                                                                            \
+    for (i = 0; i < nb_samples; i++) {                                      \
+        double gain = fade_gain(curve, start + i * dir, range);             \
+        for (c = 0; c < channels; c++, k++)                                 \
+            d[k] = s[k] * gain;                                             \
+    }                                                                       \
+}
+
+FADE_PLANAR(dbl, double)
+FADE_PLANAR(flt, float)
+FADE_PLANAR(s16, int16_t)
+FADE_PLANAR(s32, int32_t)
+
+FADE(dbl, double)
+FADE(flt, float)
+FADE(s16, int16_t)
+FADE(s32, int32_t)
+
+static int config_output(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx    = outlink->src;
+    AudioFadeContext *afade = ctx->priv;
+    AVFilterLink *inlink    = ctx->inputs[0];
+
+    switch (inlink->format) {
+    case AV_SAMPLE_FMT_DBL:  afade->fade_samples = fade_samples_dbl;  break;
+    case AV_SAMPLE_FMT_DBLP: afade->fade_samples = fade_samples_dblp; break;
+    case AV_SAMPLE_FMT_FLT:  afade->fade_samples = fade_samples_flt;  break;
+    case AV_SAMPLE_FMT_FLTP: afade->fade_samples = fade_samples_fltp; break;
+    case AV_SAMPLE_FMT_S16:  afade->fade_samples = fade_samples_s16;  break;
+    case AV_SAMPLE_FMT_S16P: afade->fade_samples = fade_samples_s16p; break;
+    case AV_SAMPLE_FMT_S32:  afade->fade_samples = fade_samples_s32;  break;
+    case AV_SAMPLE_FMT_S32P: afade->fade_samples = fade_samples_s32p; break;
+    }
+
+    if (afade->duration)
+        afade->nb_samples = afade->duration * inlink->sample_rate;
+    if (afade->start_time)
+        afade->start_sample = afade->start_time * inlink->sample_rate;
+
+    return 0;
+}
+
+static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
+{
+    AudioFadeContext *afade = inlink->dst->priv;
+    AVFilterLink *outlink   = inlink->dst->outputs[0];
+    int nb_samples          = buf->audio->nb_samples;
+    AVFilterBufferRef *out_buf;
+    int64_t cur_sample = av_rescale_q(buf->pts, (AVRational){1, outlink->sample_rate}, outlink->time_base);
+
+    if ((!afade->type && (afade->start_sample + afade->nb_samples < cur_sample)) ||
+        ( afade->type && (cur_sample + afade->nb_samples < afade->start_sample)))
+        return ff_filter_frame(outlink, buf);
+
+    if (buf->perms & AV_PERM_WRITE) {
+        out_buf = buf;
+    } else {
+        out_buf = ff_get_audio_buffer(inlink, AV_PERM_WRITE, nb_samples);
+        if (!out_buf)
+            return AVERROR(ENOMEM);
+        out_buf->pts = buf->pts;
+    }
+
+    if ((!afade->type && (cur_sample + nb_samples < afade->start_sample)) ||
+        ( afade->type && (afade->start_sample + afade->nb_samples < cur_sample))) {
+        av_samples_set_silence(out_buf->extended_data, 0, nb_samples,
+                               out_buf->audio->channels, out_buf->format);
+    } else {
+        int64_t start;
+
+        if (!afade->type)
+            start = cur_sample - afade->start_sample;
+        else
+            start = afade->start_sample + afade->nb_samples - cur_sample;
+
+        afade->fade_samples(out_buf->extended_data, buf->extended_data,
+                            nb_samples, buf->audio->channels,
+                            afade->type ? -1 : 1, start,
+                            afade->nb_samples, afade->curve);
+    }
+
+    if (buf != out_buf)
+        avfilter_unref_buffer(buf);
+
+    return ff_filter_frame(outlink, out_buf);
+}
+
+static const AVFilterPad avfilter_af_afade_inputs[] = {
+    {
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_AUDIO,
+        .filter_frame = filter_frame,
+    },
+    { NULL }
+};
+
+static const AVFilterPad avfilter_af_afade_outputs[] = {
+    {
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_AUDIO,
+        .config_props = config_output,
+    },
+    { NULL }
+};
+
+AVFilter avfilter_af_afade = {
+    .name          = "afade",
+    .description   = NULL_IF_CONFIG_SMALL("Fade in/out input audio."),
+    .query_formats = query_formats,
+    .priv_size     = sizeof(AudioFadeContext),
+    .init          = init,
+    .inputs        = avfilter_af_afade_inputs,
+    .outputs       = avfilter_af_afade_outputs,
+    .priv_class    = &afade_class,
+};
diff --git a/libavfilter/af_aformat.c b/libavfilter/af_aformat.c
index b1d779f..9ac381f 100644
--- a/libavfilter/af_aformat.c
+++ b/libavfilter/af_aformat.c
@@ -121,7 +121,7 @@
     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 :
-                                                            ff_all_channel_layouts());
+                                                            ff_all_channel_counts());
 
     return 0;
 }
diff --git a/libavfilter/af_amerge.c b/libavfilter/af_amerge.c
index 44b71e4..2d68ea6 100644
--- a/libavfilter/af_amerge.c
+++ b/libavfilter/af_amerge.c
@@ -63,8 +63,10 @@
     int i;
 
     for (i = 0; i < am->nb_inputs; i++) {
-        ff_bufqueue_discard_all(&am->in[i].queue);
-        av_freep(&ctx->input_pads[i].name);
+        if (am->in)
+            ff_bufqueue_discard_all(&am->in[i].queue);
+        if (ctx->input_pads)
+            av_freep(&ctx->input_pads[i].name);
     }
     av_freep(&am->in);
 }
@@ -231,6 +233,11 @@
         if (inlink == ctx->inputs[input_number])
             break;
     av_assert1(input_number < am->nb_inputs);
+    if (ff_bufqueue_is_full(&am->in[input_number].queue)) {
+        av_log(ctx, AV_LOG_ERROR, "Buffer queue overflow\n");
+        avfilter_unref_buffer(insamples);
+        return AVERROR(ENOMEM);
+    }
     ff_bufqueue_add(ctx, &am->in[input_number].queue, insamples);
     am->in[input_number].nb_samples += insamples->audio->nb_samples;
     nb_samples = am->in[0].nb_samples;
@@ -255,6 +262,7 @@
 
     outbuf->audio->nb_samples     = nb_samples;
     outbuf->audio->channel_layout = outlink->channel_layout;
+    outbuf->audio->channels       = outlink->channels;
 
     while (nb_samples) {
         ns = nb_samples;
@@ -335,7 +343,7 @@
 
 AVFilter avfilter_af_amerge = {
     .name          = "amerge",
-    .description   = NULL_IF_CONFIG_SMALL("Merge two audio streams into "
+    .description   = NULL_IF_CONFIG_SMALL("Merge two or more audio streams into "
                                           "a single multi-channel stream."),
     .priv_size     = sizeof(AMergeContext),
     .init          = init,
diff --git a/libavfilter/af_anull.c b/libavfilter/af_anull.c
index 40af7b8..c61da3b 100644
--- a/libavfilter/af_anull.c
+++ b/libavfilter/af_anull.c
@@ -50,6 +50,8 @@
 
     .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
new file mode 100644
index 0000000..18a0170
--- /dev/null
+++ b/libavfilter/af_apad.c
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2012 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
+ *
+ */
+
+/**
+ * @file
+ * audio pad filter.
+ *
+ * Based on af_aresample.c
+ */
+
+#include "libavutil/avstring.h"
+#include "libavutil/channel_layout.h"
+#include "libavutil/opt.h"
+#include "libavutil/samplefmt.h"
+#include "libavutil/avassert.h"
+#include "avfilter.h"
+#include "audio.h"
+#include "internal.h"
+
+typedef struct {
+    const AVClass *class;
+    int64_t next_pts;
+
+    int packet_size;
+    int64_t pad_len;
+    int64_t whole_len;
+} APadContext;
+
+#define OFFSET(x) offsetof(APadContext, x)
+#define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
+
+static const AVOption apad_options[] = {
+    { "packet_size", "set silence packet size", OFFSET(packet_size), AV_OPT_TYPE_INT, { .i64 = 4096 }, 0, INT_MAX, A },
+    { "pad_len",     "number of samples of silence to add",          OFFSET(pad_len),   AV_OPT_TYPE_INT64, { .i64 = 0 }, 0, INT64_MAX, A },
+    { "whole_len",   "target number of samples in the audio stream", OFFSET(whole_len), AV_OPT_TYPE_INT64, { .i64 = 0 }, 0, INT64_MAX, A },
+    { NULL },
+};
+
+AVFILTER_DEFINE_CLASS(apad);
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    int ret;
+    APadContext *apad = ctx->priv;
+
+    apad->class = &apad_class;
+    apad->next_pts = AV_NOPTS_VALUE;
+
+    av_opt_set_defaults(apad);
+
+    if ((ret = av_opt_set_from_string(apad, args, NULL, "=", ":")) < 0)
+        return ret;
+
+    if (apad->whole_len && apad->pad_len) {
+        av_log(ctx, AV_LOG_ERROR, "Both whole and pad length are set, this is not possible\n");
+        return AVERROR(EINVAL);
+    }
+
+    return 0;
+}
+
+static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
+{
+    AVFilterContext *ctx = inlink->dst;
+    APadContext *apad = ctx->priv;
+
+    if (apad->whole_len)
+        apad->whole_len -= frame->audio->nb_samples;
+
+    apad->next_pts = frame->pts + av_rescale_q(frame->audio->nb_samples, (AVRational){1, inlink->sample_rate}, inlink->time_base);
+    return ff_filter_frame(ctx->outputs[0], frame);
+}
+
+static int request_frame(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx = outlink->src;
+    APadContext *apad = ctx->priv;
+    int ret;
+
+    ret = ff_request_frame(ctx->inputs[0]);
+
+    if (ret == AVERROR_EOF) {
+        int n_out = apad->packet_size;
+        AVFilterBufferRef *outsamplesref;
+
+        if (apad->whole_len > 0) {
+            apad->pad_len = apad->whole_len;
+            apad->whole_len = 0;
+        }
+        if (apad->pad_len > 0) {
+            n_out = FFMIN(n_out, apad->pad_len);
+            apad->pad_len -= n_out;
+        }
+
+        if(!n_out)
+            return AVERROR_EOF;
+
+        outsamplesref = ff_get_audio_buffer(outlink, AV_PERM_WRITE, n_out);
+        if (!outsamplesref)
+            return AVERROR(ENOMEM);
+
+        av_assert0(outsamplesref->audio->sample_rate == outlink->sample_rate);
+        av_assert0(outsamplesref->audio->nb_samples  == n_out);
+
+        av_samples_set_silence(outsamplesref->extended_data, 0,
+                               n_out,
+                               outsamplesref->audio->channels,
+                               outsamplesref->format);
+
+        outsamplesref->pts = apad->next_pts;
+        if (apad->next_pts != AV_NOPTS_VALUE)
+            apad->next_pts += av_rescale_q(n_out, (AVRational){1, outlink->sample_rate}, outlink->time_base);
+
+        return ff_filter_frame(outlink, outsamplesref);
+    }
+    return ret;
+}
+
+static const AVFilterPad apad_inputs[] = {
+    {
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_AUDIO,
+        .filter_frame = filter_frame,
+        .min_perms    = AV_PERM_READ,
+    },
+    { NULL },
+};
+
+static const AVFilterPad apad_outputs[] = {
+    {
+        .name          = "default",
+        .request_frame = request_frame,
+        .type          = AVMEDIA_TYPE_AUDIO,
+    },
+    { NULL },
+};
+
+AVFilter avfilter_af_apad = {
+    .name          = "apad",
+    .description   = NULL_IF_CONFIG_SMALL("Pad audio with silence."),
+    .init          = init,
+    .priv_size     = sizeof(APadContext),
+    .inputs        = apad_inputs,
+    .outputs       = apad_outputs,
+    .priv_class    = &apad_class,
+};
diff --git a/libavfilter/af_aresample.c b/libavfilter/af_aresample.c
index 2dcfd69..66a8a53 100644
--- a/libavfilter/af_aresample.c
+++ b/libavfilter/af_aresample.c
@@ -55,20 +55,20 @@
     }
 
     if (args) {
-        char *ptr=argd, *token;
+        char *ptr = argd, *token;
 
-        while(token = av_strtok(ptr, ":", &ptr)) {
+        while (token = av_strtok(ptr, ":", &ptr)) {
             char *value;
             av_strtok(token, "=", &value);
 
-            if(value) {
-                if((ret=av_opt_set(aresample->swr, token, value, 0)) < 0)
+            if (value) {
+                if ((ret = av_opt_set(aresample->swr, token, value, 0)) < 0)
                     goto end;
             } else {
                 int out_rate;
                 if ((ret = ff_parse_sample_rate(&out_rate, token, ctx)) < 0)
                     goto end;
-                if((ret = av_opt_set_int(aresample->swr, "osr", out_rate, 0)) < 0)
+                if ((ret = av_opt_set_int(aresample->swr, "osr", out_rate, 0)) < 0)
                     goto end;
             }
         }
@@ -98,7 +98,7 @@
     AVFilterFormats        *out_formats;
     AVFilterFormats        *in_samplerates  = ff_all_samplerates();
     AVFilterFormats        *out_samplerates;
-    AVFilterChannelLayouts *in_layouts      = ff_all_channel_layouts();
+    AVFilterChannelLayouts *in_layouts      = ff_all_channel_counts();
     AVFilterChannelLayouts *out_layouts;
 
     ff_formats_ref  (in_formats,      &inlink->out_formats);
@@ -121,7 +121,7 @@
     if(out_layout) {
         out_layouts = avfilter_make_format64_list((int64_t[]){ out_layout, -1 });
     } else
-        out_layouts = ff_all_channel_layouts();
+        out_layouts = ff_all_channel_counts();
     ff_channel_layouts_ref(out_layouts, &outlink->in_channel_layouts);
 
     return 0;
@@ -145,6 +145,10 @@
                                         0, ctx);
     if (!aresample->swr)
         return AVERROR(ENOMEM);
+    if (!inlink->channel_layout)
+        av_opt_set_int(aresample->swr, "ich", inlink->channels, 0);
+    if (!outlink->channel_layout)
+        av_opt_set_int(aresample->swr, "och", outlink->channels, 0);
 
     ret = swr_init(aresample->swr);
     if (ret < 0)
@@ -156,17 +160,17 @@
     outlink->time_base = (AVRational) {1, out_rate};
 
     av_assert0(outlink->sample_rate == out_rate);
-    av_assert0(outlink->channel_layout == out_layout);
+    av_assert0(outlink->channel_layout == out_layout || !outlink->channel_layout);
     av_assert0(outlink->format == out_format);
 
     aresample->ratio = (double)outlink->sample_rate / inlink->sample_rate;
 
-    av_get_channel_layout_string(inchl_buf,  sizeof(inchl_buf),  -1, inlink ->channel_layout);
-    av_get_channel_layout_string(outchl_buf, sizeof(outchl_buf), -1, outlink->channel_layout);
+    av_get_channel_layout_string(inchl_buf,  sizeof(inchl_buf),  inlink ->channels, inlink ->channel_layout);
+    av_get_channel_layout_string(outchl_buf, sizeof(outchl_buf), outlink->channels, outlink->channel_layout);
 
-    av_log(ctx, AV_LOG_VERBOSE, "chl:%s fmt:%s r:%dHz -> chl:%s fmt:%s r:%dHz\n",
-           inchl_buf,  av_get_sample_fmt_name(inlink->format),  inlink->sample_rate,
-           outchl_buf, av_get_sample_fmt_name(outlink->format), outlink->sample_rate);
+    av_log(ctx, AV_LOG_VERBOSE, "ch:%d chl:%s fmt:%s r:%dHz -> ch:%d chl:%s fmt:%s r:%dHz\n",
+           inlink ->channels, inchl_buf,  av_get_sample_fmt_name(inlink->format),  inlink->sample_rate,
+           outlink->channels, outchl_buf, av_get_sample_fmt_name(outlink->format), outlink->sample_rate);
     return 0;
 }
 
@@ -174,7 +178,7 @@
 {
     AResampleContext *aresample = inlink->dst->priv;
     const int n_in  = insamplesref->audio->nb_samples;
-    int n_out       = FFMAX(n_in * aresample->ratio * 2, 1);
+    int n_out       = n_in * aresample->ratio * 2 + 256;
     AVFilterLink *const outlink = inlink->dst->outputs[0];
     AVFilterBufferRef *outsamplesref = ff_get_audio_buffer(outlink, AV_PERM_WRITE, n_out);
     int ret;
@@ -184,6 +188,7 @@
 
     avfilter_copy_buffer_ref_props(outsamplesref, insamplesref);
     outsamplesref->format                = outlink->format;
+    outsamplesref->audio->channels       = outlink->channels;
     outsamplesref->audio->channel_layout = outlink->channel_layout;
     outsamplesref->audio->sample_rate    = outlink->sample_rate;
 
diff --git a/libavfilter/af_asyncts.c b/libavfilter/af_asyncts.c
index b5d0aea..500be0f 100644
--- a/libavfilter/af_asyncts.c
+++ b/libavfilter/af_asyncts.c
@@ -33,6 +33,8 @@
     AVAudioResampleContext *avr;
     int64_t pts;            ///< timestamp in samples of the first sample in fifo
     int min_delta;          ///< pad/trim min threshold in samples
+    int first_frame;        ///< 1 until filter_frame() has processed at least 1 frame with a pts != AV_NOPTS_VALUE
+    int64_t first_pts;      ///< user-specified first expected pts, in samples
 
     /* options */
     int resample;
@@ -51,7 +53,7 @@
     { "min_delta",  "Minimum difference between timestamps and audio data "
                     "(in seconds) to trigger padding/trimmin the data.",        OFFSET(min_delta_sec), AV_OPT_TYPE_FLOAT, { .dbl = 0.1 }, 0, INT_MAX, A|F },
     { "max_comp",   "Maximum compensation in samples per second.",              OFFSET(max_comp),      AV_OPT_TYPE_INT,   { .i64 = 500 }, 0, INT_MAX, A|F },
-    { "first_pts",  "Assume the first pts should be this value.",               OFFSET(pts),           AV_OPT_TYPE_INT64, { .i64 = AV_NOPTS_VALUE }, INT64_MIN, INT64_MAX, A|F },
+    { "first_pts",  "Assume the first pts should be this value.",               OFFSET(first_pts),     AV_OPT_TYPE_INT64, { .i64 = AV_NOPTS_VALUE }, INT64_MIN, INT64_MAX, A|F },
     { NULL },
 };
 
@@ -69,6 +71,9 @@
         return ret;
     av_opt_free(s);
 
+    s->pts         = AV_NOPTS_VALUE;
+    s->first_frame = 1;
+
     return 0;
 }
 
@@ -110,6 +115,26 @@
     return 0;
 }
 
+/* get amount of data currently buffered, in samples */
+static int64_t get_delay(ASyncContext *s)
+{
+    return avresample_available(s->avr) + avresample_get_delay(s->avr);
+}
+
+static void handle_trimming(AVFilterContext *ctx)
+{
+    ASyncContext *s = ctx->priv;
+
+    if (s->pts < s->first_pts) {
+        int delta = FFMIN(s->first_pts - s->pts, avresample_available(s->avr));
+        av_log(ctx, AV_LOG_VERBOSE, "Trimming %d samples from start\n",
+               delta);
+        avresample_read(s->avr, NULL, delta);
+        s->pts += delta;
+    } else if (s->first_frame)
+        s->pts = s->first_pts;
+}
+
 static int request_frame(AVFilterLink *link)
 {
     AVFilterContext *ctx = link->src;
@@ -122,20 +147,25 @@
         ret = ff_request_frame(ctx->inputs[0]);
 
     /* flush the fifo */
-    if (ret == AVERROR_EOF && (nb_samples = avresample_get_delay(s->avr))) {
-        AVFilterBufferRef *buf = ff_get_audio_buffer(link, AV_PERM_WRITE,
-                                                     nb_samples);
-        if (!buf)
-            return AVERROR(ENOMEM);
-        ret = avresample_convert(s->avr, buf->extended_data,
-                                 buf->linesize[0], nb_samples, NULL, 0, 0);
-        if (ret <= 0) {
-            avfilter_unref_bufferp(&buf);
-            return (ret < 0) ? ret : AVERROR_EOF;
-        }
+    if (ret == AVERROR_EOF) {
+        if (s->first_pts != AV_NOPTS_VALUE)
+            handle_trimming(ctx);
 
-        buf->pts = s->pts;
-        return ff_filter_frame(link, buf);
+        if (nb_samples = get_delay(s)) {
+            AVFilterBufferRef *buf = ff_get_audio_buffer(link, AV_PERM_WRITE,
+                                                         nb_samples);
+            if (!buf)
+                return AVERROR(ENOMEM);
+            ret = avresample_convert(s->avr, buf->extended_data,
+                                     buf->linesize[0], nb_samples, NULL, 0, 0);
+            if (ret <= 0) {
+                avfilter_unref_bufferp(&buf);
+                return (ret < 0) ? ret : AVERROR_EOF;
+            }
+
+            buf->pts = s->pts;
+            return ff_filter_frame(link, buf);
+        }
     }
 
     return ret;
@@ -149,12 +179,6 @@
     return ret;
 }
 
-/* get amount of data currently buffered, in samples */
-static int64_t get_delay(ASyncContext *s)
-{
-    return avresample_available(s->avr) + avresample_get_delay(s->avr);
-}
-
 static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
 {
     AVFilterContext  *ctx = inlink->dst;
@@ -166,17 +190,18 @@
     int out_size, ret;
     int64_t delta;
 
-    /* buffer data until we get the first timestamp */
-    if (s->pts == AV_NOPTS_VALUE) {
+    /* buffer data until we get the next timestamp */
+    if (s->pts == AV_NOPTS_VALUE || pts == AV_NOPTS_VALUE) {
         if (pts != AV_NOPTS_VALUE) {
             s->pts = pts - get_delay(s);
         }
         return write_to_fifo(s, buf);
     }
 
-    /* now wait for the next timestamp */
-    if (pts == AV_NOPTS_VALUE) {
-        return write_to_fifo(s, buf);
+    if (s->first_pts != AV_NOPTS_VALUE) {
+        handle_trimming(ctx);
+        if (!avresample_available(s->avr))
+            return write_to_fifo(s, buf);
     }
 
     /* when we have two timestamps, compute how many samples would we have
@@ -184,14 +209,15 @@
     delta    = pts - s->pts - get_delay(s);
     out_size = avresample_available(s->avr);
 
-    if (labs(delta) > s->min_delta) {
+    if (labs(delta) > s->min_delta ||
+        (s->first_frame && delta && s->first_pts != AV_NOPTS_VALUE)) {
         av_log(ctx, AV_LOG_VERBOSE, "Discontinuity - %"PRId64" samples.\n", delta);
         out_size = av_clipl_int32((int64_t)out_size + delta);
     } else {
         if (s->resample) {
             int comp = av_clip(delta, -s->max_comp, s->max_comp);
             av_log(ctx, AV_LOG_VERBOSE, "Compensating %d samples per second.\n", comp);
-            avresample_set_compensation(s->avr, delta, inlink->sample_rate);
+            avresample_set_compensation(s->avr, comp, inlink->sample_rate);
         }
         delta = 0;
     }
@@ -204,18 +230,33 @@
             goto fail;
         }
 
-        avresample_read(s->avr, buf_out->extended_data, out_size);
-        buf_out->pts = s->pts;
+        if (s->first_frame && delta > 0) {
+            int ch;
 
-        if (delta > 0) {
-            av_samples_set_silence(buf_out->extended_data, out_size - delta,
-                                   delta, nb_channels, buf->format);
+            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;
+
+            avresample_read(s->avr, buf_out->extended_data, out_size);
+
+            for (ch = 0; ch < nb_channels; ch++)
+                buf_out->extended_data[ch] -= delta;
+        } else {
+            avresample_read(s->avr, buf_out->extended_data, out_size);
+
+            if (delta > 0) {
+                av_samples_set_silence(buf_out->extended_data, out_size - delta,
+                                       delta, nb_channels, buf->format);
+            }
         }
+        buf_out->pts = s->pts;
         ret = ff_filter_frame(outlink, buf_out);
         if (ret < 0)
             goto fail;
         s->got_output = 1;
-    } else {
+    } else if (avresample_available(s->avr)) {
         av_log(ctx, AV_LOG_WARNING, "Non-monotonous timestamps, dropping "
                "whole buffer.\n");
     }
@@ -227,6 +268,7 @@
     ret = avresample_convert(s->avr, NULL, 0, 0, buf->extended_data,
                              buf->linesize[0], buf->audio->nb_samples);
 
+    s->first_frame = 0;
 fail:
     avfilter_unref_buffer(buf);
 
diff --git a/libavfilter/af_atempo.c b/libavfilter/af_atempo.c
index 74bf9cc..d186aaf 100644
--- a/libavfilter/af_atempo.c
+++ b/libavfilter/af_atempo.c
@@ -978,7 +978,7 @@
     // Planar sample formats are too cumbersome to store in a ring buffer,
     // therefore planar sample formats are not supported.
     //
-    enum AVSampleFormat sample_fmts[] = {
+    static const enum AVSampleFormat sample_fmts[] = {
         AV_SAMPLE_FMT_U8,
         AV_SAMPLE_FMT_S16,
         AV_SAMPLE_FMT_S32,
diff --git a/libavfilter/af_biquads.c b/libavfilter/af_biquads.c
new file mode 100644
index 0000000..cae3e02
--- /dev/null
+++ b/libavfilter/af_biquads.c
@@ -0,0 +1,627 @@
+/*
+ * Copyright (c) 2013 Paul B Mahol
+ * Copyright (c) 2006-2008 Rob Sykes <robs@users.sourceforge.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
+ */
+
+/*
+ * 2-pole filters designed by Robert Bristow-Johnson <rbj@audioimagination.com>
+ *   see http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt
+ *
+ * 1-pole filters based on code (c) 2000 Chris Bagwell <cbagwell@sprynet.com>
+ *   Algorithms: Recursive single pole low/high pass filter
+ *   Reference: The Scientist and Engineer's Guide to Digital Signal Processing
+ *
+ *   low-pass: output[N] = input[N] * A + output[N-1] * B
+ *     X = exp(-2.0 * pi * Fc)
+ *     A = 1 - X
+ *     B = X
+ *     Fc = cutoff freq / sample rate
+ *
+ *     Mimics an RC low-pass filter:
+ *
+ *     ---/\/\/\/\----------->
+ *                   |
+ *                  --- C
+ *                  ---
+ *                   |
+ *                   |
+ *                   V
+ *
+ *   high-pass: output[N] = A0 * input[N] + A1 * input[N-1] + B1 * output[N-1]
+ *     X  = exp(-2.0 * pi * Fc)
+ *     A0 = (1 + X) / 2
+ *     A1 = -(1 + X) / 2
+ *     B1 = X
+ *     Fc = cutoff freq / sample rate
+ *
+ *     Mimics an RC high-pass filter:
+ *
+ *         || C
+ *     ----||--------->
+ *         ||    |
+ *               <
+ *               > R
+ *               <
+ *               |
+ *               V
+ */
+
+#include "libavutil/opt.h"
+#include "libavutil/avassert.h"
+#include "audio.h"
+#include "avfilter.h"
+#include "internal.h"
+
+enum FilterType {
+    biquad,
+    equalizer,
+    bass,
+    treble,
+    band,
+    bandpass,
+    bandreject,
+    allpass,
+    highpass,
+    lowpass,
+};
+
+enum WidthType {
+    NONE,
+    HZ,
+    OCTAVE,
+    QFACTOR,
+    SLOPE,
+};
+
+typedef struct ChanCache {
+    double i1, i2;
+    double o1, o2;
+} ChanCache;
+
+typedef struct {
+    const AVClass *class;
+
+    enum FilterType filter_type;
+    enum WidthType width_type;
+    int poles;
+    int csg;
+
+    double gain;
+    double frequency;
+    double width;
+
+    double a0, a1, a2;
+    double b0, b1, b2;
+
+    ChanCache *cache;
+
+    void (*filter)(const void *ibuf, void *obuf, int len,
+                   double *i1, double *i2, double *o1, double *o2,
+                   double b0, double b1, double b2, double a1, double a2);
+} BiquadsContext;
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    BiquadsContext *p = ctx->priv;
+    int ret;
+
+    av_opt_set_defaults(p);
+
+    if ((ret = av_set_options_string(p, args, "=", ":")) < 0)
+        return ret;
+
+    if (p->filter_type != biquad) {
+        if (p->frequency <= 0 || p->width <= 0) {
+            av_log(ctx, AV_LOG_ERROR, "Invalid frequency %f and/or width %f <= 0\n",
+                   p->frequency, p->width);
+            return AVERROR(EINVAL);
+        }
+    }
+
+    return 0;
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    AVFilterFormats *formats;
+    AVFilterChannelLayouts *layouts;
+    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 BIQUAD_FILTER(name, type, min, max)                                   \
+static void biquad_## name (const void *input, void *output, int len,         \
+                            double *in1, double *in2,                         \
+                            double *out1, double *out2,                       \
+                            double b0, double b1, double b2,                  \
+                            double a1, double a2)                             \
+{                                                                             \
+    const type *ibuf = input;                                                 \
+    type *obuf = output;                                                      \
+    double i1 = *in1;                                                         \
+    double i2 = *in2;                                                         \
+    double o1 = *out1;                                                        \
+    double o2 = *out2;                                                        \
+    int i;                                                                    \
+    a1 = -a1;                                                                 \
+    a2 = -a2;                                                                 \
+                                                                              \
+    for (i = 0; i+1 < len; i++) {                                             \
+        o2 = i2 * b2 + i1 * b1 + ibuf[i] * b0 + o2 * a2 + o1 * a1;            \
+        i2 = ibuf[i];                                                         \
+        if (o2 < min) {                                                       \
+            av_log(NULL, AV_LOG_WARNING, "clipping\n");                       \
+            obuf[i] = min;                                                    \
+        } else if (o2 > max) {                                                \
+            av_log(NULL, AV_LOG_WARNING, "clipping\n");                       \
+            obuf[i] = max;                                                    \
+        } else {                                                              \
+            obuf[i] = o2;                                                     \
+        }                                                                     \
+        i++;                                                                  \
+        o1 = i1 * b2 + i2 * b1 + ibuf[i] * b0 + o1 * a2 + o2 * a1;            \
+        i1 = ibuf[i];                                                         \
+        if (o1 < min) {                                                       \
+            av_log(NULL, AV_LOG_WARNING, "clipping\n");                       \
+            obuf[i] = min;                                                    \
+        } else if (o1 > max) {                                                \
+            av_log(NULL, AV_LOG_WARNING, "clipping\n");                       \
+            obuf[i] = max;                                                    \
+        } else {                                                              \
+            obuf[i] = o1;                                                     \
+        }                                                                     \
+    }                                                                         \
+    if (i < len) {                                                            \
+        double o0 = ibuf[i] * b0 + i1 * b1 + i2 * b2 + o1 * a1 + o2 * a2;     \
+        i2 = i1;                                                              \
+        i1 = ibuf[i];                                                         \
+        o2 = o1;                                                              \
+        o1 = o0;                                                              \
+        if (o0 < min) {                                                       \
+            av_log(NULL, AV_LOG_WARNING, "clipping\n");                       \
+            obuf[i] = min;                                                    \
+        } else if (o0 > max) {                                                \
+            av_log(NULL, AV_LOG_WARNING, "clipping\n");                       \
+            obuf[i] = max;                                                    \
+        } else {                                                              \
+            obuf[i] = o0;                                                     \
+        }                                                                     \
+    }                                                                         \
+    *in1  = i1;                                                               \
+    *in2  = i2;                                                               \
+    *out1 = o1;                                                               \
+    *out2 = o2;                                                               \
+}
+
+BIQUAD_FILTER(s16, int16_t, INT16_MIN, INT16_MAX)
+BIQUAD_FILTER(s32, int32_t, INT32_MIN, INT32_MAX)
+BIQUAD_FILTER(flt, float,   -1., 1.)
+BIQUAD_FILTER(dbl, double,  -1., 1.)
+
+static int config_output(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx    = outlink->src;
+    BiquadsContext *p       = ctx->priv;
+    AVFilterLink *inlink    = ctx->inputs[0];
+    double A = exp(p->gain / 40 * log(10.));
+    double w0 = 2 * M_PI * p->frequency / inlink->sample_rate;
+    double alpha;
+
+    if (w0 > M_PI) {
+        av_log(ctx, AV_LOG_ERROR,
+               "Invalid frequency %f. Frequency must be less than half the sample-rate %d.\n",
+               p->frequency, inlink->sample_rate);
+        return AVERROR(EINVAL);
+    }
+
+    switch (p->width_type) {
+    case NONE:
+        alpha = 0.0;
+        break;
+    case HZ:
+        alpha = sin(w0) / (2 * p->frequency / p->width);
+        break;
+    case OCTAVE:
+        alpha = sin(w0) * sinh(log(2.) / 2 * p->width * w0 / sin(w0));
+        break;
+    case QFACTOR:
+        alpha = sin(w0) / (2 * p->width);
+        break;
+    case SLOPE:
+        alpha = sin(w0) / 2 * sqrt((A + 1 / A) * (1 / p->width - 1) + 2);
+        break;
+    default:
+        av_assert0(0);
+    }
+
+    switch (p->filter_type) {
+    case biquad:
+        break;
+    case equalizer:
+        p->a0 =   1 + alpha / A;
+        p->a1 =  -2 * cos(w0);
+        p->a2 =   1 - alpha / A;
+        p->b0 =   1 + alpha * A;
+        p->b1 =  -2 * cos(w0);
+        p->b2 =   1 - alpha * A;
+        break;
+    case bass:
+        p->a0 =          (A + 1) + (A - 1) * cos(w0) + 2 * sqrt(A) * alpha;
+        p->a1 =    -2 * ((A - 1) + (A + 1) * cos(w0));
+        p->a2 =          (A + 1) + (A - 1) * cos(w0) - 2 * sqrt(A) * alpha;
+        p->b0 =     A * ((A + 1) - (A - 1) * cos(w0) + 2 * sqrt(A) * alpha);
+        p->b1 = 2 * A * ((A - 1) - (A + 1) * cos(w0));
+        p->b2 =     A * ((A + 1) - (A - 1) * cos(w0) - 2 * sqrt(A) * alpha);
+        break;
+    case treble:
+        p->a0 =          (A + 1) - (A - 1) * cos(w0) + 2 * sqrt(A) * alpha;
+        p->a1 =     2 * ((A - 1) - (A + 1) * cos(w0));
+        p->a2 =          (A + 1) - (A - 1) * cos(w0) - 2 * sqrt(A) * alpha;
+        p->b0 =     A * ((A + 1) + (A - 1) * cos(w0) + 2 * sqrt(A) * alpha);
+        p->b1 =-2 * A * ((A - 1) + (A + 1) * cos(w0));
+        p->b2 =     A * ((A + 1) + (A - 1) * cos(w0) - 2 * sqrt(A) * alpha);
+        break;
+    case bandpass:
+        if (p->csg) {
+            p->a0 =  1 + alpha;
+            p->a1 = -2 * cos(w0);
+            p->a2 =  1 - alpha;
+            p->b0 =  sin(w0) / 2;
+            p->b1 =  0;
+            p->b2 = -sin(w0) / 2;
+        } else {
+            p->a0 =  1 + alpha;
+            p->a1 = -2 * cos(w0);
+            p->a2 =  1 - alpha;
+            p->b0 =  alpha;
+            p->b1 =  0;
+            p->b2 = -alpha;
+        }
+        break;
+    case bandreject:
+        p->a0 =  1 + alpha;
+        p->a1 = -2 * cos(w0);
+        p->a2 =  1 - alpha;
+        p->b0 =  1;
+        p->b1 = -2 * cos(w0);
+        p->b2 =  1;
+        break;
+    case lowpass:
+        if (p->poles == 1) {
+            p->a0 = 1;
+            p->a1 = -exp(-w0);
+            p->a2 = 0;
+            p->b0 = 1 + p->a1;
+            p->b1 = 0;
+            p->b2 = 0;
+        } else {
+            p->a0 =  1 + alpha;
+            p->a1 = -2 * cos(w0);
+            p->a2 =  1 - alpha;
+            p->b0 = (1 - cos(w0)) / 2;
+            p->b1 =  1 - cos(w0);
+            p->b2 = (1 - cos(w0)) / 2;
+        }
+        break;
+    case highpass:
+        if (p->poles == 1) {
+            p->a0 = 1;
+            p->a1 = -exp(-w0);
+            p->a2 = 0;
+            p->b0 = (1 - p->a1) / 2;
+            p->b1 = -p->b0;
+            p->b2 = 0;
+        } else {
+            p->a0 =   1 + alpha;
+            p->a1 =  -2 * cos(w0);
+            p->a2 =   1 - alpha;
+            p->b0 =  (1 + cos(w0)) / 2;
+            p->b1 = -(1 + cos(w0));
+            p->b2 =  (1 + cos(w0)) / 2;
+        }
+        break;
+    case allpass:
+        p->a0 =  1 + alpha;
+        p->a1 = -2 * cos(w0);
+        p->a2 =  1 - alpha;
+        p->b0 =  1 - alpha;
+        p->b1 = -2 * cos(w0);
+        p->b2 =  1 + alpha;
+        break;
+    default:
+        av_assert0(0);
+    }
+
+    p->a1 /= p->a0;
+    p->a2 /= p->a0;
+    p->b0 /= p->a0;
+    p->b1 /= p->a0;
+    p->b2 /= p->a0;
+
+    p->cache = av_realloc_f(p->cache, sizeof(ChanCache), inlink->channels);
+    if (!p->cache)
+        return AVERROR(ENOMEM);
+    memset(p->cache, 0, sizeof(ChanCache) * inlink->channels);
+
+    switch (inlink->format) {
+    case AV_SAMPLE_FMT_S16P: p->filter = biquad_s16; break;
+    case AV_SAMPLE_FMT_S32P: p->filter = biquad_s32; break;
+    case AV_SAMPLE_FMT_FLTP: p->filter = biquad_flt; break;
+    case AV_SAMPLE_FMT_DBLP: p->filter = biquad_dbl; break;
+    default: av_assert0(0);
+    }
+
+    return 0;
+}
+
+static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
+{
+    BiquadsContext *p       = inlink->dst->priv;
+    AVFilterLink *outlink   = inlink->dst->outputs[0];
+    AVFilterBufferRef *out_buf;
+    int nb_samples = buf->audio->nb_samples;
+    int ch;
+
+    if (buf->perms & AV_PERM_WRITE) {
+        out_buf = buf;
+    } else {
+        out_buf = ff_get_audio_buffer(inlink, AV_PERM_WRITE, nb_samples);
+        if (!out_buf)
+            return AVERROR(ENOMEM);
+        out_buf->pts = buf->pts;
+    }
+
+    for (ch = 0; ch < buf->audio->channels; ch++)
+        p->filter(buf->extended_data[ch],
+                  out_buf->extended_data[ch], nb_samples,
+                  &p->cache[ch].i1, &p->cache[ch].i2,
+                  &p->cache[ch].o1, &p->cache[ch].o2,
+                  p->b0, p->b1, p->b2, p->a1, p->a2);
+
+    if (buf != out_buf)
+        avfilter_unref_buffer(buf);
+
+    return ff_filter_frame(outlink, out_buf);
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    BiquadsContext *p = ctx->priv;
+
+    av_freep(&p->cache);
+    av_opt_free(p);
+}
+
+static const AVFilterPad inputs[] = {
+    {
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_AUDIO,
+        .filter_frame = filter_frame,
+    },
+    { NULL }
+};
+
+static const AVFilterPad outputs[] = {
+    {
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_AUDIO,
+        .config_props = config_output,
+    },
+    { NULL }
+};
+
+#define OFFSET(x) offsetof(BiquadsContext, x)
+#define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
+
+#define DEFINE_BIQUAD_FILTER(name_, description_)                       \
+AVFILTER_DEFINE_CLASS(name_);                                           \
+static av_cold int name_##_init(AVFilterContext *ctx, const char *args) \
+{                                                                       \
+    BiquadsContext *p = ctx->priv;                                      \
+    p->class = &name_##_class;                                          \
+    p->filter_type = name_;                                             \
+    return init(ctx, args);                                             \
+}                                                                       \
+                                                         \
+AVFilter avfilter_af_##name_ = {                         \
+    .name          = #name_,                             \
+    .description   = NULL_IF_CONFIG_SMALL(description_), \
+    .priv_size     = sizeof(BiquadsContext),             \
+    .init          = name_##_init,                       \
+    .uninit        = uninit,                             \
+    .query_formats = query_formats,                      \
+    .inputs        = inputs,                             \
+    .outputs       = outputs,                            \
+    .priv_class    = &name_##_class,                     \
+}
+
+#if CONFIG_EQUALIZER_FILTER
+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"},
+    {"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"},
+    {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 999, FLAGS},
+    {"w",     "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 999, FLAGS},
+    {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
+    {"g",    "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
+    {NULL},
+};
+
+DEFINE_BIQUAD_FILTER(equalizer, "Apply two-pole peaking equalization (EQ) filter.");
+#endif  /* CONFIG_EQUALIZER_FILTER */
+#if CONFIG_BASS_FILTER
+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"},
+    {"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"},
+    {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
+    {"w",     "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
+    {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
+    {"g",    "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
+    {NULL},
+};
+
+DEFINE_BIQUAD_FILTER(bass, "Boost or cut lower frequencies.");
+#endif  /* CONFIG_BASS_FILTER */
+#if CONFIG_TREBLE_FILTER
+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"},
+    {"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"},
+    {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
+    {"w",     "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
+    {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
+    {"g",    "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
+    {NULL},
+};
+
+DEFINE_BIQUAD_FILTER(treble, "Boost or cut upper frequencies.");
+#endif  /* CONFIG_TREBLE_FILTER */
+#if CONFIG_BANDPASS_FILTER
+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"},
+    {"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"},
+    {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 999, FLAGS},
+    {"w",     "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 999, FLAGS},
+    {"csg",   "use constant skirt gain", OFFSET(csg), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS},
+    {NULL},
+};
+
+DEFINE_BIQUAD_FILTER(bandpass, "Apply a two-pole Butterworth band-pass filter.");
+#endif  /* CONFIG_BANDPASS_FILTER */
+#if CONFIG_BANDREJECT_FILTER
+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"},
+    {"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"},
+    {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 999, FLAGS},
+    {"w",     "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 999, FLAGS},
+    {NULL},
+};
+
+DEFINE_BIQUAD_FILTER(bandreject, "Apply a two-pole Butterworth band-reject filter.");
+#endif  /* CONFIG_BANDREJECT_FILTER */
+#if CONFIG_LOWPASS_FILTER
+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"},
+    {"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"},
+    {"width", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
+    {"w",     "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
+    {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
+    {"p",     "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
+    {NULL},
+};
+
+DEFINE_BIQUAD_FILTER(lowpass, "Apply a low-pass filter with 3dB point frequency.");
+#endif  /* CONFIG_LOWPASS_FILTER */
+#if CONFIG_HIGHPASS_FILTER
+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"},
+    {"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"},
+    {"width", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
+    {"w",     "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
+    {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
+    {"p",     "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
+    {NULL},
+};
+
+DEFINE_BIQUAD_FILTER(highpass, "Apply a high-pass filter with 3dB point frequency.");
+#endif  /* CONFIG_HIGHPASS_FILTER */
+#if CONFIG_ALLPASS_FILTER
+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"},
+    {"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"},
+    {"width", "set filter-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=707.1}, 0, 99999, FLAGS},
+    {"w",     "set filter-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=707.1}, 0, 99999, FLAGS},
+    {NULL},
+};
+
+DEFINE_BIQUAD_FILTER(allpass, "Apply a two-pole all-pass filter.");
+#endif  /* CONFIG_ALLPASS_FILTER */
+#if CONFIG_BIQUAD_FILTER
+static const AVOption biquad_options[] = {
+    {"a0", NULL, OFFSET(a0), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT16_MAX, INT16_MAX, FLAGS},
+    {"a1", NULL, OFFSET(a1), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT16_MAX, INT16_MAX, FLAGS},
+    {"a2", NULL, OFFSET(a2), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT16_MAX, INT16_MAX, FLAGS},
+    {"b0", NULL, OFFSET(b0), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT16_MAX, INT16_MAX, FLAGS},
+    {"b1", NULL, OFFSET(b1), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT16_MAX, INT16_MAX, FLAGS},
+    {"b2", NULL, OFFSET(b2), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT16_MAX, INT16_MAX, FLAGS},
+    {NULL},
+};
+
+DEFINE_BIQUAD_FILTER(biquad, "Apply a biquad IIR filter with the given coefficients.");
+#endif  /* CONFIG_BIQUAD_FILTER */
diff --git a/libavfilter/af_earwax.c b/libavfilter/af_earwax.c
index 4a2b8b7..a169d2a 100644
--- a/libavfilter/af_earwax.c
+++ b/libavfilter/af_earwax.c
@@ -77,7 +77,7 @@
 
 static int query_formats(AVFilterContext *ctx)
 {
-    int sample_rates[] = { 44100, -1 };
+    static const int sample_rates[] = { 44100, -1 };
 
     AVFilterFormats *formats = NULL;
     AVFilterChannelLayouts *layout = NULL;
@@ -91,17 +91,6 @@
     return 0;
 }
 
-static int config_input(AVFilterLink *inlink)
-{
-    if (inlink->sample_rate != 44100) {
-        av_log(inlink->dst, AV_LOG_ERROR,
-               "The earwax filter only works for 44.1kHz audio. Insert "
-               "a resample filter before this\n");
-        return AVERROR(EINVAL);
-    }
-    return 0;
-}
-
 //FIXME: replace with DSPContext.scalarproduct_int16
 static inline int16_t *scalarproduct(const int16_t *in, const int16_t *endin, int16_t *out)
 {
@@ -158,7 +147,6 @@
         .name         = "default",
         .type         = AVMEDIA_TYPE_AUDIO,
         .filter_frame = filter_frame,
-        .config_props = config_input,
         .min_perms    = AV_PERM_READ,
     },
     { NULL }
diff --git a/libavfilter/af_pan.c b/libavfilter/af_pan.c
index 922025a..77ca549 100644
--- a/libavfilter/af_pan.c
+++ b/libavfilter/af_pan.c
@@ -364,6 +364,7 @@
     swr_convert(pan->swr, outsamples->data, n, (void *)insamples->data, n);
     avfilter_copy_buffer_ref_props(outsamples, insamples);
     outsamples->audio->channel_layout = outlink->channel_layout;
+    outsamples->audio->channels       = outlink->channels;
 
     ret = ff_filter_frame(outlink, outsamples);
     avfilter_unref_buffer(insamples);
diff --git a/libavfilter/af_resample.c b/libavfilter/af_resample.c
index c712b46..84ca8f5 100644
--- a/libavfilter/af_resample.c
+++ b/libavfilter/af_resample.c
@@ -25,6 +25,7 @@
 #include "libavutil/avassert.h"
 #include "libavutil/avstring.h"
 #include "libavutil/common.h"
+#include "libavutil/dict.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/opt.h"
 
@@ -37,6 +38,7 @@
 
 typedef struct ResampleContext {
     AVAudioResampleContext *avr;
+    AVDictionary *options;
 
     int64_t next_pts;
 
@@ -44,6 +46,29 @@
     int got_output;
 } ResampleContext;
 
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    ResampleContext *s = ctx->priv;
+
+    if (args) {
+        int ret = av_dict_parse_string(&s->options, args, "=", ":", 0);
+        if (ret < 0) {
+            av_log(ctx, AV_LOG_ERROR, "error setting option string: %s\n", args);
+            return ret;
+        }
+
+        /* do not allow the user to override basic format options */
+        av_dict_set(&s->options,  "in_channel_layout", NULL, 0);
+        av_dict_set(&s->options, "out_channel_layout", NULL, 0);
+        av_dict_set(&s->options,  "in_sample_fmt",     NULL, 0);
+        av_dict_set(&s->options, "out_sample_fmt",     NULL, 0);
+        av_dict_set(&s->options,  "in_sample_rate",    NULL, 0);
+        av_dict_set(&s->options, "out_sample_rate",    NULL, 0);
+    }
+
+    return 0;
+}
+
 static av_cold void uninit(AVFilterContext *ctx)
 {
     ResampleContext *s = ctx->priv;
@@ -52,6 +77,7 @@
         avresample_close(s->avr);
         avresample_free(&s->avr);
     }
+    av_dict_free(&s->options);
 }
 
 static int query_formats(AVFilterContext *ctx)
@@ -103,6 +129,14 @@
     if (!(s->avr = avresample_alloc_context()))
         return AVERROR(ENOMEM);
 
+    if (s->options) {
+        AVDictionaryEntry *e = NULL;
+        while ((e = av_dict_get(s->options, "", e, AV_DICT_IGNORE_SUFFIX)))
+            av_log(ctx, AV_LOG_VERBOSE, "lavr option: %s=%s\n", e->key, e->value);
+
+        av_opt_set_dict(s->avr, &s->options);
+    }
+
     av_opt_set_int(s->avr,  "in_channel_layout", inlink ->channel_layout, 0);
     av_opt_set_int(s->avr, "out_channel_layout", outlink->channel_layout, 0);
     av_opt_set_int(s->avr,  "in_sample_fmt",     inlink ->format,         0);
@@ -264,6 +298,7 @@
     .description   = NULL_IF_CONFIG_SMALL("Audio resampling and conversion."),
     .priv_size     = sizeof(ResampleContext),
 
+    .init           = init,
     .uninit         = uninit,
     .query_formats  = query_formats,
 
diff --git a/libavfilter/af_silencedetect.c b/libavfilter/af_silencedetect.c
index f5fccc5..8a60176 100644
--- a/libavfilter/af_silencedetect.c
+++ b/libavfilter/af_silencedetect.c
@@ -23,6 +23,8 @@
  * Audio silence detector
  */
 
+#include <float.h> /* DBL_MAX */
+
 #include "libavutil/channel_layout.h"
 #include "libavutil/opt.h"
 #include "libavutil/timestamp.h"
@@ -33,7 +35,6 @@
 
 typedef struct {
     const AVClass *class;
-    char *noise_str;            ///< noise option string
     double noise;               ///< noise amplitude ratio
     double duration;            ///< minimum duration of silence until notification
     int64_t nb_null_samples;    ///< current number of continuous zero samples
@@ -44,8 +45,8 @@
 #define OFFSET(x) offsetof(SilenceDetectContext, x)
 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_AUDIO_PARAM
 static const AVOption silencedetect_options[] = {
-    { "n",         "set noise tolerance",              OFFSET(noise_str), AV_OPT_TYPE_STRING, {.str="-60dB"}, CHAR_MIN, CHAR_MAX, FLAGS },
-    { "noise",     "set noise tolerance",              OFFSET(noise_str), AV_OPT_TYPE_STRING, {.str="-60dB"}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "n",         "set noise tolerance",              OFFSET(noise),     AV_OPT_TYPE_DOUBLE, {.dbl=0.001},          0, DBL_MAX,  FLAGS },
+    { "noise",     "set noise tolerance",              OFFSET(noise),     AV_OPT_TYPE_DOUBLE, {.dbl=0.001},          0, DBL_MAX,  FLAGS },
     { "d",         "set minimum duration in seconds",  OFFSET(duration),  AV_OPT_TYPE_DOUBLE, {.dbl=2.},             0, 24*60*60, FLAGS },
     { "duration",  "set minimum duration in seconds",  OFFSET(duration),  AV_OPT_TYPE_DOUBLE, {.dbl=2.},             0, 24*60*60, FLAGS },
     { NULL },
@@ -56,7 +57,6 @@
 static av_cold int init(AVFilterContext *ctx, const char *args)
 {
     int ret;
-    char *tail;
     SilenceDetectContext *silence = ctx->priv;
 
     silence->class = &silencedetect_class;
@@ -65,14 +65,6 @@
     if ((ret = av_set_options_string(silence, args, "=", ":")) < 0)
         return ret;
 
-    silence->noise = strtod(silence->noise_str, &tail);
-    if (!strcmp(tail, "dB")) {
-        silence->noise = pow(10, silence->noise/20);
-    } else if (*tail) {
-        av_log(ctx, AV_LOG_ERROR, "Invalid value '%s' for noise parameter.\n",
-               silence->noise_str);
-        return AVERROR(EINVAL);
-    }
     av_opt_free(silence);
 
     return 0;
@@ -139,7 +131,7 @@
 {
     AVFilterFormats *formats = NULL;
     AVFilterChannelLayouts *layouts = NULL;
-    enum AVSampleFormat sample_fmts[] = {
+    static const enum AVSampleFormat sample_fmts[] = {
         AV_SAMPLE_FMT_DBL,
         AV_SAMPLE_FMT_NONE
     };
diff --git a/libavfilter/af_volume.c b/libavfilter/af_volume.c
index 7608083..5ffa1fe 100644
--- a/libavfilter/af_volume.c
+++ b/libavfilter/af_volume.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2011 Stefano Sabatini
+ * Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
  *
  * This file is part of FFmpeg.
  *
@@ -21,75 +22,95 @@
 /**
  * @file
  * audio volume filter
- * based on ffmpeg.c code
  */
 
-#include "libavutil/channel_layout.h"
+#include "libavutil/audioconvert.h"
+#include "libavutil/common.h"
 #include "libavutil/eval.h"
+#include "libavutil/float_dsp.h"
+#include "libavutil/opt.h"
 #include "audio.h"
 #include "avfilter.h"
 #include "formats.h"
+#include "internal.h"
+#include "af_volume.h"
 
-typedef struct {
-    double volume;
-    int    volume_i;
-} VolumeContext;
+static const char *precision_str[] = {
+    "fixed", "float", "double"
+};
+
+#define OFFSET(x) offsetof(VolumeContext, x)
+#define A AV_OPT_FLAG_AUDIO_PARAM
+#define F AV_OPT_FLAG_FILTERING_PARAM
+
+static const AVOption volume_options[] = {
+    { "volume", "set volume adjustment",
+            OFFSET(volume), AV_OPT_TYPE_DOUBLE, { .dbl = 1.0 }, 0, 0x7fffff, A|F },
+    { "precision", "select mathematical precision",
+            OFFSET(precision), AV_OPT_TYPE_INT, { .i64 = PRECISION_FLOAT }, PRECISION_FIXED, PRECISION_DOUBLE, A|F, "precision" },
+        { "fixed",  "select 8-bit fixed-point",     0, AV_OPT_TYPE_CONST, { .i64 = PRECISION_FIXED  }, INT_MIN, INT_MAX, A|F, "precision" },
+        { "float",  "select 32-bit floating-point", 0, AV_OPT_TYPE_CONST, { .i64 = PRECISION_FLOAT  }, INT_MIN, INT_MAX, A|F, "precision" },
+        { "double", "select 64-bit floating-point", 0, AV_OPT_TYPE_CONST, { .i64 = PRECISION_DOUBLE }, INT_MIN, INT_MAX, A|F, "precision" },
+    { NULL },
+};
+
+AVFILTER_DEFINE_CLASS(volume);
 
 static av_cold int init(AVFilterContext *ctx, const char *args)
 {
     VolumeContext *vol = ctx->priv;
-    char *tail;
-    int ret = 0;
+    static const char *shorthand[] = { "volume", "precision", NULL };
+    int ret;
 
-    vol->volume = 1.0;
+    vol->class = &volume_class;
+    av_opt_set_defaults(vol);
 
-    if (args) {
-        /* parse the number as a decimal number */
-        double d = strtod(args, &tail);
+    if ((ret = av_opt_set_from_string(vol, args, shorthand, "=", ":")) < 0)
+        return ret;
 
-        if (*tail) {
-            if (!strcmp(tail, "dB")) {
-                /* consider the argument an adjustement in decibels */
-                d = pow(10, d/20);
-            } else {
-                /* parse the argument as an expression */
-                ret = av_expr_parse_and_eval(&d, args, NULL, NULL,
-                                             NULL, NULL, NULL, NULL,
-                                             NULL, 0, ctx);
-            }
-        }
-
-        if (ret < 0) {
-            av_log(ctx, AV_LOG_ERROR,
-                   "Invalid volume argument '%s'\n", args);
-            return AVERROR(EINVAL);
-        }
-
-        if (d < 0 || d > 65536) { /* 65536 = INT_MIN / (128 * 256) */
-            av_log(ctx, AV_LOG_ERROR,
-                   "Negative or too big volume value %f\n", d);
-            return AVERROR(EINVAL);
-        }
-
-        vol->volume = d;
+    if (vol->precision == PRECISION_FIXED) {
+        vol->volume_i = (int)(vol->volume * 256 + 0.5);
+        vol->volume   = vol->volume_i / 256.0;
+        av_log(ctx, AV_LOG_VERBOSE, "volume:(%d/256)(%f)(%1.2fdB) precision:fixed\n",
+               vol->volume_i, vol->volume, 20.0*log(vol->volume)/M_LN10);
+    } else {
+        av_log(ctx, AV_LOG_VERBOSE, "volume:(%f)(%1.2fdB) precision:%s\n",
+               vol->volume, 20.0*log(vol->volume)/M_LN10,
+               precision_str[vol->precision]);
     }
 
-    vol->volume_i = (int)(vol->volume * 256 + 0.5);
-    av_log(ctx, AV_LOG_VERBOSE, "volume=%f\n", vol->volume);
-    return 0;
+    av_opt_free(vol);
+    return ret;
 }
 
 static int query_formats(AVFilterContext *ctx)
 {
+    VolumeContext *vol = ctx->priv;
     AVFilterFormats *formats = NULL;
     AVFilterChannelLayouts *layouts;
-    enum AVSampleFormat sample_fmts[] = {
-        AV_SAMPLE_FMT_U8,
-        AV_SAMPLE_FMT_S16,
-        AV_SAMPLE_FMT_S32,
-        AV_SAMPLE_FMT_FLT,
-        AV_SAMPLE_FMT_DBL,
-        AV_SAMPLE_FMT_NONE
+    static const enum AVSampleFormat sample_fmts[][7] = {
+        /* PRECISION_FIXED */
+        {
+            AV_SAMPLE_FMT_U8,
+            AV_SAMPLE_FMT_U8P,
+            AV_SAMPLE_FMT_S16,
+            AV_SAMPLE_FMT_S16P,
+            AV_SAMPLE_FMT_S32,
+            AV_SAMPLE_FMT_S32P,
+            AV_SAMPLE_FMT_NONE
+        },
+        /* PRECISION_FLOAT */
+        {
+            AV_SAMPLE_FMT_FLT,
+            AV_SAMPLE_FMT_FLTP,
+            AV_SAMPLE_FMT_NONE
+        },
+        /* PRECISION_DOUBLE */
+        {
+            AV_SAMPLE_FMT_DBL,
+            AV_SAMPLE_FMT_DBLP,
+            AV_SAMPLE_FMT_NONE
+        }
     };
 
     layouts = ff_all_channel_layouts();
@@ -97,7 +118,7 @@
         return AVERROR(ENOMEM);
     ff_set_common_channel_layouts(ctx, layouts);
 
-    formats = ff_make_format_list(sample_fmts);
+    formats = ff_make_format_list(sample_fmts[vol->precision]);
     if (!formats)
         return AVERROR(ENOMEM);
     ff_set_common_formats(ctx, formats);
@@ -110,84 +131,172 @@
     return 0;
 }
 
-static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *insamples)
+static inline void scale_samples_u8(uint8_t *dst, const uint8_t *src,
+                                    int nb_samples, int volume)
 {
-    VolumeContext *vol = inlink->dst->priv;
-    AVFilterLink *outlink = inlink->dst->outputs[0];
-    const int nb_samples = insamples->audio->nb_samples *
-        av_get_channel_layout_nb_channels(insamples->audio->channel_layout);
-    const double volume   = vol->volume;
-    const int    volume_i = vol->volume_i;
     int i;
-
-    if (volume_i != 256) {
-        switch (insamples->format) {
-        case AV_SAMPLE_FMT_U8:
-        {
-            uint8_t *p = (void *)insamples->data[0];
-            for (i = 0; i < nb_samples; i++) {
-                int v = (((*p - 128) * volume_i + 128) >> 8) + 128;
-                *p++ = av_clip_uint8(v);
-            }
-            break;
-        }
-        case AV_SAMPLE_FMT_S16:
-        {
-            int16_t *p = (void *)insamples->data[0];
-            for (i = 0; i < nb_samples; i++) {
-                int v = ((int64_t)*p * volume_i + 128) >> 8;
-                *p++ = av_clip_int16(v);
-            }
-            break;
-        }
-        case AV_SAMPLE_FMT_S32:
-        {
-            int32_t *p = (void *)insamples->data[0];
-            for (i = 0; i < nb_samples; i++) {
-                int64_t v = (((int64_t)*p * volume_i + 128) >> 8);
-                *p++ = av_clipl_int32(v);
-            }
-            break;
-        }
-        case AV_SAMPLE_FMT_FLT:
-        {
-            float *p = (void *)insamples->data[0];
-            float scale = (float)volume;
-            for (i = 0; i < nb_samples; i++) {
-                *p++ *= scale;
-            }
-            break;
-        }
-        case AV_SAMPLE_FMT_DBL:
-        {
-            double *p = (void *)insamples->data[0];
-            for (i = 0; i < nb_samples; i++) {
-                *p *= volume;
-                p++;
-            }
-            break;
-        }
-        }
-    }
-    return ff_filter_frame(outlink, insamples);
+    for (i = 0; i < nb_samples; i++)
+        dst[i] = av_clip_uint8(((((int64_t)src[i] - 128) * volume + 128) >> 8) + 128);
 }
 
-static const AVFilterPad volume_inputs[] = {
+static inline void scale_samples_u8_small(uint8_t *dst, const uint8_t *src,
+                                          int nb_samples, int volume)
+{
+    int i;
+    for (i = 0; i < nb_samples; i++)
+        dst[i] = av_clip_uint8((((src[i] - 128) * volume + 128) >> 8) + 128);
+}
+
+static inline void scale_samples_s16(uint8_t *dst, const uint8_t *src,
+                                     int nb_samples, int volume)
+{
+    int i;
+    int16_t *smp_dst       = (int16_t *)dst;
+    const int16_t *smp_src = (const int16_t *)src;
+    for (i = 0; i < nb_samples; i++)
+        smp_dst[i] = av_clip_int16(((int64_t)smp_src[i] * volume + 128) >> 8);
+}
+
+static inline void scale_samples_s16_small(uint8_t *dst, const uint8_t *src,
+                                           int nb_samples, int volume)
+{
+    int i;
+    int16_t *smp_dst       = (int16_t *)dst;
+    const int16_t *smp_src = (const int16_t *)src;
+    for (i = 0; i < nb_samples; i++)
+        smp_dst[i] = av_clip_int16((smp_src[i] * volume + 128) >> 8);
+}
+
+static inline void scale_samples_s32(uint8_t *dst, const uint8_t *src,
+                                     int nb_samples, int volume)
+{
+    int i;
+    int32_t *smp_dst       = (int32_t *)dst;
+    const int32_t *smp_src = (const int32_t *)src;
+    for (i = 0; i < nb_samples; i++)
+        smp_dst[i] = av_clipl_int32((((int64_t)smp_src[i] * volume + 128) >> 8));
+}
+
+static void volume_init(VolumeContext *vol)
+{
+    vol->samples_align = 1;
+
+    switch (av_get_packed_sample_fmt(vol->sample_fmt)) {
+    case AV_SAMPLE_FMT_U8:
+        if (vol->volume_i < 0x1000000)
+            vol->scale_samples = scale_samples_u8_small;
+        else
+            vol->scale_samples = scale_samples_u8;
+        break;
+    case AV_SAMPLE_FMT_S16:
+        if (vol->volume_i < 0x10000)
+            vol->scale_samples = scale_samples_s16_small;
+        else
+            vol->scale_samples = scale_samples_s16;
+        break;
+    case AV_SAMPLE_FMT_S32:
+        vol->scale_samples = scale_samples_s32;
+        break;
+    case AV_SAMPLE_FMT_FLT:
+        avpriv_float_dsp_init(&vol->fdsp, 0);
+        vol->samples_align = 4;
+        break;
+    case AV_SAMPLE_FMT_DBL:
+        avpriv_float_dsp_init(&vol->fdsp, 0);
+        vol->samples_align = 8;
+        break;
+    }
+
+    if (ARCH_X86)
+        ff_volume_init_x86(vol);
+}
+
+static int config_output(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx = outlink->src;
+    VolumeContext *vol   = ctx->priv;
+    AVFilterLink *inlink = ctx->inputs[0];
+
+    vol->sample_fmt = inlink->format;
+    vol->channels   = av_get_channel_layout_nb_channels(inlink->channel_layout);
+    vol->planes     = av_sample_fmt_is_planar(inlink->format) ? vol->channels : 1;
+
+    volume_init(vol);
+
+    return 0;
+}
+
+static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
+{
+    VolumeContext *vol    = inlink->dst->priv;
+    AVFilterLink *outlink = inlink->dst->outputs[0];
+    int nb_samples        = buf->audio->nb_samples;
+    AVFilterBufferRef *out_buf;
+
+    if (vol->volume == 1.0 || vol->volume_i == 256)
+        return ff_filter_frame(outlink, buf);
+
+    /* do volume scaling in-place if input buffer is writable */
+    if (buf->perms & AV_PERM_WRITE) {
+        out_buf = buf;
+    } else {
+        out_buf = ff_get_audio_buffer(inlink, AV_PERM_WRITE, nb_samples);
+        if (!out_buf)
+            return AVERROR(ENOMEM);
+        out_buf->pts = buf->pts;
+    }
+
+    if (vol->precision != PRECISION_FIXED || vol->volume_i > 0) {
+        int p, plane_samples;
+
+        if (av_sample_fmt_is_planar(buf->format))
+            plane_samples = FFALIGN(nb_samples, vol->samples_align);
+        else
+            plane_samples = FFALIGN(nb_samples * vol->channels, vol->samples_align);
+
+        if (vol->precision == PRECISION_FIXED) {
+            for (p = 0; p < vol->planes; p++) {
+                vol->scale_samples(out_buf->extended_data[p],
+                                   buf->extended_data[p], plane_samples,
+                                   vol->volume_i);
+            }
+        } else if (av_get_packed_sample_fmt(vol->sample_fmt) == AV_SAMPLE_FMT_FLT) {
+            for (p = 0; p < vol->planes; p++) {
+                vol->fdsp.vector_fmul_scalar((float *)out_buf->extended_data[p],
+                                             (const float *)buf->extended_data[p],
+                                             vol->volume, plane_samples);
+            }
+        } else {
+            for (p = 0; p < vol->planes; p++) {
+                vol->fdsp.vector_dmul_scalar((double *)out_buf->extended_data[p],
+                                             (const double *)buf->extended_data[p],
+                                             vol->volume, plane_samples);
+            }
+        }
+    }
+
+    if (buf != out_buf)
+        avfilter_unref_buffer(buf);
+
+    return ff_filter_frame(outlink, out_buf);
+}
+
+static const AVFilterPad avfilter_af_volume_inputs[] = {
+    {
+        .name           = "default",
+        .type           = AVMEDIA_TYPE_AUDIO,
+        .filter_frame   = filter_frame,
+    },
+    { NULL }
+};
+
+static const AVFilterPad avfilter_af_volume_outputs[] = {
     {
         .name         = "default",
         .type         = AVMEDIA_TYPE_AUDIO,
-        .filter_frame = filter_frame,
-        .min_perms    = AV_PERM_READ | AV_PERM_WRITE,
+        .config_props = config_output,
     },
-    { NULL },
-};
-
-static const AVFilterPad volume_outputs[] = {
-    {
-        .name = "default",
-        .type = AVMEDIA_TYPE_AUDIO,
-    },
-    { NULL },
+    { NULL }
 };
 
 AVFilter avfilter_af_volume = {
@@ -196,6 +305,7 @@
     .query_formats  = query_formats,
     .priv_size      = sizeof(VolumeContext),
     .init           = init,
-    .inputs         = volume_inputs,
-    .outputs        = volume_outputs,
+    .inputs         = avfilter_af_volume_inputs,
+    .outputs        = avfilter_af_volume_outputs,
+    .priv_class     = &volume_class,
 };
diff --git a/libavfilter/af_volume.h b/libavfilter/af_volume.h
new file mode 100644
index 0000000..bd7932e
--- /dev/null
+++ b/libavfilter/af_volume.h
@@ -0,0 +1,55 @@
+/*
+ * 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 volume filter
+ */
+
+#ifndef AVFILTER_AF_VOLUME_H
+#define AVFILTER_AF_VOLUME_H
+
+#include "libavutil/common.h"
+#include "libavutil/float_dsp.h"
+#include "libavutil/opt.h"
+#include "libavutil/samplefmt.h"
+
+enum PrecisionType {
+    PRECISION_FIXED = 0,
+    PRECISION_FLOAT,
+    PRECISION_DOUBLE,
+};
+
+typedef struct VolumeContext {
+    const AVClass *class;
+    AVFloatDSPContext fdsp;
+    enum PrecisionType precision;
+    double volume;
+    int    volume_i;
+    int    channels;
+    int    planes;
+    enum AVSampleFormat sample_fmt;
+
+    void (*scale_samples)(uint8_t *dst, const uint8_t *src, int nb_samples,
+                          int volume);
+    int samples_align;
+} VolumeContext;
+
+void ff_volume_init_x86(VolumeContext *vol);
+
+#endif /* AVFILTER_AF_VOLUME_H */
diff --git a/libavfilter/af_volumedetect.c b/libavfilter/af_volumedetect.c
index 01f30a6..39265c0 100644
--- a/libavfilter/af_volumedetect.c
+++ b/libavfilter/af_volumedetect.c
@@ -35,7 +35,7 @@
 
 static int query_formats(AVFilterContext *ctx)
 {
-    enum AVSampleFormat sample_fmts[] = {
+    static const enum AVSampleFormat sample_fmts[] = {
         AV_SAMPLE_FMT_S16,
         AV_SAMPLE_FMT_S16P,
         AV_SAMPLE_FMT_NONE
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index 746e713..f05f8ae 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -23,13 +23,18 @@
 #include "config.h"
 
 
-#define REGISTER_FILTER(X,x,y) { \
-          extern AVFilter avfilter_##y##_##x ; \
-          if(CONFIG_##X##_FILTER )  avfilter_register(&avfilter_##y##_##x ); }
+#define REGISTER_FILTER(X, x, y)                                        \
+    {                                                                   \
+        extern AVFilter avfilter_##y##_##x;                             \
+        if (CONFIG_##X##_FILTER)                                        \
+            avfilter_register(&avfilter_##y##_##x);                     \
+    }
 
-#define REGISTER_BUILTIN_FILTER(x,y) { \
-          extern AVFilter avfilter_##y##_##x ; \
-          avfilter_register(&avfilter_##y##_##x ); }
+#define REGISTER_FILTER_UNCONDITIONAL(x)                                \
+    {                                                                   \
+        extern AVFilter avfilter_##x;                                   \
+        avfilter_register(&avfilter_##x);                               \
+    }
 
 void avfilter_register_all(void)
 {
@@ -39,148 +44,156 @@
         return;
     initialized = 1;
 
-    REGISTER_FILTER (ACONVERT,    aconvert,    af);
-    REGISTER_FILTER (AFIFO,       afifo,       af);
-    REGISTER_FILTER (AFORMAT,     aformat,     af);
-    REGISTER_FILTER (AMERGE,      amerge,      af);
-    REGISTER_FILTER (AMIX,        amix,        af);
-    REGISTER_FILTER (ANULL,       anull,       af);
-    REGISTER_FILTER (ARESAMPLE,   aresample,   af);
-    REGISTER_FILTER (ASENDCMD,    asendcmd,    af);
-    REGISTER_FILTER (ASETNSAMPLES, asetnsamples, af);
-    REGISTER_FILTER (ASETPTS,     asetpts,     af);
-    REGISTER_FILTER (ASETTB,      asettb,      af);
-    REGISTER_FILTER (ASHOWINFO,   ashowinfo,   af);
-    REGISTER_FILTER (ASPLIT,      asplit,      af);
-    REGISTER_FILTER (ASTREAMSYNC, astreamsync, af);
-    REGISTER_FILTER (ASYNCTS,     asyncts,     af);
-    REGISTER_FILTER (ATEMPO,      atempo,      af);
-    REGISTER_FILTER (CHANNELMAP,  channelmap,  af);
-    REGISTER_FILTER (CHANNELSPLIT,channelsplit,af);
-    REGISTER_FILTER (EARWAX,      earwax,      af);
-    REGISTER_FILTER (EBUR128,     ebur128,     af);
-    REGISTER_FILTER (JOIN,        join,        af);
-    REGISTER_FILTER (PAN,         pan,         af);
-    REGISTER_FILTER (SILENCEDETECT, silencedetect, af);
-    REGISTER_FILTER (VOLUME,      volume,      af);
-    REGISTER_FILTER (VOLUMEDETECT,volumedetect,af);
-    REGISTER_FILTER (RESAMPLE,    resample,    af);
+    REGISTER_FILTER(ACONVERT,       aconvert,       af);
+    REGISTER_FILTER(AFADE,          afade,          af);
+    REGISTER_FILTER(AFORMAT,        aformat,        af);
+    REGISTER_FILTER(ALLPASS,        allpass,        af);
+    REGISTER_FILTER(AMERGE,         amerge,         af);
+    REGISTER_FILTER(AMIX,           amix,           af);
+    REGISTER_FILTER(ANULL,          anull,          af);
+    REGISTER_FILTER(APAD,           apad,           af);
+    REGISTER_FILTER(ARESAMPLE,      aresample,      af);
+    REGISTER_FILTER(ASELECT,        aselect,        af);
+    REGISTER_FILTER(ASENDCMD,       asendcmd,       af);
+    REGISTER_FILTER(ASETNSAMPLES,   asetnsamples,   af);
+    REGISTER_FILTER(ASETPTS,        asetpts,        af);
+    REGISTER_FILTER(ASETTB,         asettb,         af);
+    REGISTER_FILTER(ASHOWINFO,      ashowinfo,      af);
+    REGISTER_FILTER(ASPLIT,         asplit,         af);
+    REGISTER_FILTER(ASTREAMSYNC,    astreamsync,    af);
+    REGISTER_FILTER(ASYNCTS,        asyncts,        af);
+    REGISTER_FILTER(ATEMPO,         atempo,         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(EARWAX,         earwax,         af);
+    REGISTER_FILTER(EBUR128,        ebur128,        af);
+    REGISTER_FILTER(EQUALIZER,      equalizer,      af);
+    REGISTER_FILTER(HIGHPASS,       highpass,       af);
+    REGISTER_FILTER(JOIN,           join,           af);
+    REGISTER_FILTER(LOWPASS,        lowpass,        af);
+    REGISTER_FILTER(PAN,            pan,            af);
+    REGISTER_FILTER(RESAMPLE,       resample,       af);
+    REGISTER_FILTER(SILENCEDETECT,  silencedetect,  af);
+    REGISTER_FILTER(TREBLE,         treble,         af);
+    REGISTER_FILTER(VOLUME,         volume,         af);
+    REGISTER_FILTER(VOLUMEDETECT,   volumedetect,   af);
 
-    REGISTER_FILTER (AEVALSRC,    aevalsrc,    asrc);
-    REGISTER_FILTER (ANULLSRC,    anullsrc,    asrc);
-    REGISTER_FILTER (FLITE,       flite,       asrc);
+    REGISTER_FILTER(AEVALSRC,       aevalsrc,       asrc);
+    REGISTER_FILTER(ANULLSRC,       anullsrc,       asrc);
+    REGISTER_FILTER(FLITE,          flite,          asrc);
 
-    REGISTER_FILTER (ANULLSINK,   anullsink,   asink);
+    REGISTER_FILTER(ANULLSINK,      anullsink,      asink);
 
-    REGISTER_FILTER (ALPHAEXTRACT, alphaextract, vf);
-    REGISTER_FILTER (ALPHAMERGE,  alphamerge,  vf);
-    REGISTER_FILTER (ASS,         ass,         vf);
-    REGISTER_FILTER (BBOX,        bbox,        vf);
-    REGISTER_FILTER (BLACKDETECT, blackdetect, vf);
-    REGISTER_FILTER (BLACKFRAME,  blackframe,  vf);
-    REGISTER_FILTER (BOXBLUR,     boxblur,     vf);
-    REGISTER_FILTER (COLORMATRIX, colormatrix, vf);
-    REGISTER_FILTER (COPY,        copy,        vf);
-    REGISTER_FILTER (CROP,        crop,        vf);
-    REGISTER_FILTER (CROPDETECT,  cropdetect,  vf);
-    REGISTER_FILTER (DECIMATE,    decimate,    vf);
-    REGISTER_FILTER (DELOGO,      delogo,      vf);
-    REGISTER_FILTER (DESHAKE,     deshake,     vf);
-    REGISTER_FILTER (DRAWBOX,     drawbox,     vf);
-    REGISTER_FILTER (DRAWTEXT,    drawtext,    vf);
-    REGISTER_FILTER (EDGEDETECT,  edgedetect,  vf);
-    REGISTER_FILTER (FADE,        fade,        vf);
-    REGISTER_FILTER (FIELD,       field,       vf);
-    REGISTER_FILTER (FIELDORDER,  fieldorder,  vf);
-    REGISTER_FILTER (FIFO,        fifo,        vf);
-    REGISTER_FILTER (FORMAT,      format,      vf);
-    REGISTER_FILTER (FPS,         fps,         vf);
-    REGISTER_FILTER (FRAMESTEP,   framestep,   vf);
-    REGISTER_FILTER (FREI0R,      frei0r,      vf);
-    REGISTER_FILTER (GEQ,         geq,         vf);
-    REGISTER_FILTER (GRADFUN,     gradfun,     vf);
-    REGISTER_FILTER (HFLIP,       hflip,       vf);
-    REGISTER_FILTER (HQDN3D,      hqdn3d,      vf);
-    REGISTER_FILTER (HUE,         hue,         vf);
-    REGISTER_FILTER (IDET,        idet,        vf);
-    REGISTER_FILTER (LUT,         lut,         vf);
-    REGISTER_FILTER (LUTRGB,      lutrgb,      vf);
-    REGISTER_FILTER (LUTYUV,      lutyuv,      vf);
-    REGISTER_FILTER (MP,          mp,          vf);
-    REGISTER_FILTER (NEGATE,      negate,      vf);
-    REGISTER_FILTER (NOFORMAT,    noformat,    vf);
-    REGISTER_FILTER (NULL,        null,        vf);
-    REGISTER_FILTER (OCV,         ocv,         vf);
-    REGISTER_FILTER (OVERLAY,     overlay,     vf);
-    REGISTER_FILTER (PAD,         pad,         vf);
-    REGISTER_FILTER (PIXDESCTEST, pixdesctest, vf);
-    REGISTER_FILTER (REMOVELOGO,  removelogo,  vf);
-    REGISTER_FILTER (SCALE,       scale,       vf);
-    REGISTER_FILTER (SELECT,      select,      vf);
-    REGISTER_FILTER (SENDCMD,     sendcmd,     vf);
-    REGISTER_FILTER (SETDAR,      setdar,      vf);
-    REGISTER_FILTER (SETFIELD,    setfield,    vf);
-    REGISTER_FILTER (SETPTS,      setpts,      vf);
-    REGISTER_FILTER (SETSAR,      setsar,      vf);
-    REGISTER_FILTER (SETTB,       settb,       vf);
-    REGISTER_FILTER (SHOWINFO,    showinfo,    vf);
-    REGISTER_FILTER (SMARTBLUR,   smartblur,   vf);
-    REGISTER_FILTER (SPLIT,       split,       vf);
-    REGISTER_FILTER (SUPER2XSAI,  super2xsai,  vf);
-    REGISTER_FILTER (SWAPUV,      swapuv,      vf);
-    REGISTER_FILTER (THUMBNAIL,   thumbnail,   vf);
-    REGISTER_FILTER (TILE,        tile,        vf);
-    REGISTER_FILTER (TINTERLACE,  tinterlace,  vf);
-    REGISTER_FILTER (TRANSPOSE,   transpose,   vf);
-    REGISTER_FILTER (UNSHARP,     unsharp,     vf);
-    REGISTER_FILTER (VFLIP,       vflip,       vf);
-    REGISTER_FILTER (YADIF,       yadif,       vf);
+    REGISTER_FILTER(ALPHAEXTRACT,   alphaextract,   vf);
+    REGISTER_FILTER(ALPHAMERGE,     alphamerge,     vf);
+    REGISTER_FILTER(ASS,            ass,            vf);
+    REGISTER_FILTER(BBOX,           bbox,           vf);
+    REGISTER_FILTER(BLACKDETECT,    blackdetect,    vf);
+    REGISTER_FILTER(BLACKFRAME,     blackframe,     vf);
+    REGISTER_FILTER(BLEND,          blend,          vf);
+    REGISTER_FILTER(BOXBLUR,        boxblur,        vf);
+    REGISTER_FILTER(COLORMATRIX,    colormatrix,    vf);
+    REGISTER_FILTER(COPY,           copy,           vf);
+    REGISTER_FILTER(CROP,           crop,           vf);
+    REGISTER_FILTER(CROPDETECT,     cropdetect,     vf);
+    REGISTER_FILTER(DECIMATE,       decimate,       vf);
+    REGISTER_FILTER(DELOGO,         delogo,         vf);
+    REGISTER_FILTER(DESHAKE,        deshake,        vf);
+    REGISTER_FILTER(DRAWBOX,        drawbox,        vf);
+    REGISTER_FILTER(DRAWTEXT,       drawtext,       vf);
+    REGISTER_FILTER(EDGEDETECT,     edgedetect,     vf);
+    REGISTER_FILTER(FADE,           fade,           vf);
+    REGISTER_FILTER(FIELD,          field,          vf);
+    REGISTER_FILTER(FIELDORDER,     fieldorder,     vf);
+    REGISTER_FILTER(FORMAT,         format,         vf);
+    REGISTER_FILTER(FPS,            fps,            vf);
+    REGISTER_FILTER(FRAMESTEP,      framestep,      vf);
+    REGISTER_FILTER(FREI0R,         frei0r,         vf);
+    REGISTER_FILTER(GEQ,            geq,            vf);
+    REGISTER_FILTER(GRADFUN,        gradfun,        vf);
+    REGISTER_FILTER(HFLIP,          hflip,          vf);
+    REGISTER_FILTER(HISTEQ,         histeq,         vf);
+    REGISTER_FILTER(HISTOGRAM,      histogram,      vf);
+    REGISTER_FILTER(HQDN3D,         hqdn3d,         vf);
+    REGISTER_FILTER(HUE,            hue,            vf);
+    REGISTER_FILTER(IDET,           idet,           vf);
+    REGISTER_FILTER(IL,             il,             vf);
+    REGISTER_FILTER(KERNDEINT,      kerndeint,      vf);
+    REGISTER_FILTER(LUT,            lut,            vf);
+    REGISTER_FILTER(LUTRGB,         lutrgb,         vf);
+    REGISTER_FILTER(LUTYUV,         lutyuv,         vf);
+    REGISTER_FILTER(MP,             mp,             vf);
+    REGISTER_FILTER(NEGATE,         negate,         vf);
+    REGISTER_FILTER(NOFORMAT,       noformat,       vf);
+    REGISTER_FILTER(NOISE,          noise,          vf);
+    REGISTER_FILTER(NULL,           null,           vf);
+    REGISTER_FILTER(OCV,            ocv,            vf);
+    REGISTER_FILTER(OVERLAY,        overlay,        vf);
+    REGISTER_FILTER(PAD,            pad,            vf);
+    REGISTER_FILTER(PIXDESCTEST,    pixdesctest,    vf);
+    REGISTER_FILTER(PP,             pp,             vf);
+    REGISTER_FILTER(REMOVELOGO,     removelogo,     vf);
+    REGISTER_FILTER(SCALE,          scale,          vf);
+    REGISTER_FILTER(SELECT,         select,         vf);
+    REGISTER_FILTER(SENDCMD,        sendcmd,        vf);
+    REGISTER_FILTER(SETDAR,         setdar,         vf);
+    REGISTER_FILTER(SETFIELD,       setfield,       vf);
+    REGISTER_FILTER(SETPTS,         setpts,         vf);
+    REGISTER_FILTER(SETSAR,         setsar,         vf);
+    REGISTER_FILTER(SETTB,          settb,          vf);
+    REGISTER_FILTER(SHOWINFO,       showinfo,       vf);
+    REGISTER_FILTER(SMARTBLUR,      smartblur,      vf);
+    REGISTER_FILTER(SPLIT,          split,          vf);
+    REGISTER_FILTER(SUBTITLES,      subtitles,      vf);
+    REGISTER_FILTER(SUPER2XSAI,     super2xsai,     vf);
+    REGISTER_FILTER(SWAPUV,         swapuv,         vf);
+    REGISTER_FILTER(THUMBNAIL,      thumbnail,      vf);
+    REGISTER_FILTER(TILE,           tile,           vf);
+    REGISTER_FILTER(TINTERLACE,     tinterlace,     vf);
+    REGISTER_FILTER(TRANSPOSE,      transpose,      vf);
+    REGISTER_FILTER(UNSHARP,        unsharp,        vf);
+    REGISTER_FILTER(VFLIP,          vflip,          vf);
+    REGISTER_FILTER(YADIF,          yadif,          vf);
 
-    REGISTER_FILTER (CELLAUTO,    cellauto,    vsrc);
-    REGISTER_FILTER (COLOR,       color,       vsrc);
-    REGISTER_FILTER (FREI0R,      frei0r_src,  vsrc);
-    REGISTER_FILTER (LIFE,        life,        vsrc);
-    REGISTER_FILTER (MANDELBROT,  mandelbrot,  vsrc);
-    REGISTER_FILTER (MPTESTSRC,   mptestsrc,   vsrc);
-    REGISTER_FILTER (NULLSRC,     nullsrc,     vsrc);
-    REGISTER_FILTER (RGBTESTSRC,  rgbtestsrc,  vsrc);
-    REGISTER_FILTER (SMPTEBARS,   smptebars,   vsrc);
-    REGISTER_FILTER (TESTSRC,     testsrc,     vsrc);
+    REGISTER_FILTER(CELLAUTO,       cellauto,       vsrc);
+    REGISTER_FILTER(COLOR,          color,          vsrc);
+    REGISTER_FILTER(FREI0R,         frei0r_src,     vsrc);
+    REGISTER_FILTER(LIFE,           life,           vsrc);
+    REGISTER_FILTER(MANDELBROT,     mandelbrot,     vsrc);
+    REGISTER_FILTER(MPTESTSRC,      mptestsrc,      vsrc);
+    REGISTER_FILTER(NULLSRC,        nullsrc,        vsrc);
+    REGISTER_FILTER(RGBTESTSRC,     rgbtestsrc,     vsrc);
+    REGISTER_FILTER(SMPTEBARS,      smptebars,      vsrc);
+    REGISTER_FILTER(TESTSRC,        testsrc,        vsrc);
 
-    REGISTER_FILTER (NULLSINK,    nullsink,    vsink);
+    REGISTER_FILTER(NULLSINK,       nullsink,       vsink);
 
     /* multimedia filters */
-    REGISTER_FILTER (CONCAT,      concat,      avf);
-    REGISTER_FILTER (SHOWSPECTRUM,showspectrum,avf);
-    REGISTER_FILTER (SHOWWAVES,   showwaves,   avf);
+    REGISTER_FILTER(CONCAT,         concat,         avf);
+    REGISTER_FILTER(SHOWSPECTRUM,   showspectrum,   avf);
+    REGISTER_FILTER(SHOWWAVES,      showwaves,      avf);
 
     /* multimedia sources */
-    REGISTER_FILTER (AMOVIE,      amovie,      avsrc);
-    REGISTER_FILTER (MOVIE,       movie,       avsrc);
+    REGISTER_FILTER(AMOVIE,         amovie,         avsrc);
+    REGISTER_FILTER(MOVIE,          movie,          avsrc);
 
-    REGISTER_BUILTIN_FILTER (ffbuffersink,  vsink);
-    REGISTER_BUILTIN_FILTER (ffabuffersink, asink);
+    REGISTER_FILTER_UNCONDITIONAL(vsink_ffbuffersink);
+    REGISTER_FILTER_UNCONDITIONAL(asink_ffabuffersink);
 #if !AV_HAVE_INCOMPATIBLE_FORK_ABI
-    REGISTER_BUILTIN_FILTER (buffersink,    vsink);
-    REGISTER_BUILTIN_FILTER (abuffersink,   asink);
+    REGISTER_FILTER_UNCONDITIONAL(vsink_buffersink);
+    REGISTER_FILTER_UNCONDITIONAL(asink_abuffersink);
 #endif
 
     /* those filters are part of public or internal API => registered
      * unconditionally */
-    {
-        extern AVFilter avfilter_vsrc_buffer;
-        avfilter_register(&avfilter_vsrc_buffer);
-    }
-    {
-        extern AVFilter avfilter_asrc_abuffer;
-        avfilter_register(&avfilter_asrc_abuffer);
-    }
-    {
-        extern AVFilter avfilter_vsink_buffer;
-        avfilter_register(&avfilter_vsink_buffer);
-    }
-    {
-        extern AVFilter avfilter_asink_abuffer;
-        avfilter_register(&avfilter_asink_abuffer);
-    }
+    REGISTER_FILTER_UNCONDITIONAL(asrc_abuffer);
+    REGISTER_FILTER_UNCONDITIONAL(vsrc_buffer);
+    REGISTER_FILTER_UNCONDITIONAL(asink_abuffer);
+    REGISTER_FILTER_UNCONDITIONAL(vsink_buffer);
+    REGISTER_FILTER_UNCONDITIONAL(af_afifo);
+    REGISTER_FILTER_UNCONDITIONAL(vf_fifo);
 }
diff --git a/libavfilter/asrc_aevalsrc.c b/libavfilter/asrc_aevalsrc.c
index eaf7975..2e5fa98 100644
--- a/libavfilter/asrc_aevalsrc.c
+++ b/libavfilter/asrc_aevalsrc.c
@@ -198,7 +198,7 @@
 static int query_formats(AVFilterContext *ctx)
 {
     EvalContext *eval = ctx->priv;
-    enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_DBLP, AV_SAMPLE_FMT_NONE };
+    static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_DBLP, AV_SAMPLE_FMT_NONE };
     int64_t chlayouts[] = { eval->chlayout, -1 };
     int sample_rates[] = { eval->sample_rate, -1 };
 
@@ -214,9 +214,9 @@
     EvalContext *eval = outlink->src->priv;
     AVFilterBufferRef *samplesref;
     int i, j;
-    double t = eval->var_values[VAR_N] * (double)1/eval->sample_rate;
+    double t = eval->n * (double)1/eval->sample_rate;
 
-    if (eval->duration >= 0 && t > eval->duration)
+    if (eval->duration >= 0 && t >= eval->duration)
         return AVERROR_EOF;
 
     samplesref = ff_get_audio_buffer(outlink, AV_PERM_WRITE, eval->nb_samples);
diff --git a/libavfilter/audio.c b/libavfilter/audio.c
index f157e87..c72979d 100644
--- a/libavfilter/audio.c
+++ b/libavfilter/audio.c
@@ -27,6 +27,11 @@
 #include "avfilter.h"
 #include "internal.h"
 
+int avfilter_ref_get_channels(AVFilterBufferRef *ref)
+{
+    return ref->audio ? ref->audio->channels : 0;
+}
+
 AVFilterBufferRef *ff_null_get_audio_buffer(AVFilterLink *link, int perms,
                                             int nb_samples)
 {
@@ -39,7 +44,7 @@
     AVFilterBufferRef *samplesref = NULL;
     uint8_t **data;
     int planar      = av_sample_fmt_is_planar(link->format);
-    int nb_channels = av_get_channel_layout_nb_channels(link->channel_layout);
+    int nb_channels = link->channels;
     int planes      = planar ? nb_channels : 1;
     int linesize;
     int full_perms = AV_PERM_READ | AV_PERM_WRITE | AV_PERM_PRESERVE |
@@ -53,9 +58,9 @@
     if (av_samples_alloc(data, &linesize, nb_channels, nb_samples, link->format, 0) < 0)
         goto fail;
 
-    samplesref = avfilter_get_audio_buffer_ref_from_arrays(data, linesize, full_perms,
-                                                           nb_samples, link->format,
-                                                           link->channel_layout);
+    samplesref = avfilter_get_audio_buffer_ref_from_arrays_channels(
+        data, linesize, full_perms, nb_samples, link->format,
+        link->channels, link->channel_layout);
     if (!samplesref)
         goto fail;
 
@@ -87,11 +92,13 @@
     return ret;
 }
 
-AVFilterBufferRef* avfilter_get_audio_buffer_ref_from_arrays(uint8_t **data,
-                                                             int linesize,int perms,
-                                                             int nb_samples,
-                                                             enum AVSampleFormat sample_fmt,
-                                                             uint64_t channel_layout)
+AVFilterBufferRef* avfilter_get_audio_buffer_ref_from_arrays_channels(uint8_t **data,
+                                                                      int linesize,
+                                                                      int perms,
+                                                                      int nb_samples,
+                                                                      enum AVSampleFormat sample_fmt,
+                                                                      int channels,
+                                                                      uint64_t channel_layout)
 {
     int planes;
     AVFilterBuffer    *samples    = av_mallocz(sizeof(*samples));
@@ -100,6 +107,10 @@
     if (!samples || !samplesref)
         goto fail;
 
+    av_assert0(channels);
+    av_assert0(channel_layout == 0 ||
+               channels == av_get_channel_layout_nb_channels(channel_layout));
+
     samplesref->buf         = samples;
     samplesref->buf->free   = ff_avfilter_default_free_buffer;
     if (!(samplesref->audio = av_mallocz(sizeof(*samplesref->audio))))
@@ -107,9 +118,9 @@
 
     samplesref->audio->nb_samples     = nb_samples;
     samplesref->audio->channel_layout = channel_layout;
+    samplesref->audio->channels       = channels;
 
-    planes = av_sample_fmt_is_planar(sample_fmt) ?
-        av_get_channel_layout_nb_channels(channel_layout) : 1;
+    planes = av_sample_fmt_is_planar(sample_fmt) ? channels : 1;
 
     /* make sure the buffer gets read permission or it's useless for output */
     samplesref->perms = perms | AV_PERM_READ;
@@ -157,112 +168,14 @@
     return NULL;
 }
 
-static int default_filter_frame(AVFilterLink *link, AVFilterBufferRef *frame)
+AVFilterBufferRef* avfilter_get_audio_buffer_ref_from_arrays(uint8_t **data,
+                                                             int linesize,int perms,
+                                                             int nb_samples,
+                                                             enum AVSampleFormat sample_fmt,
+                                                             uint64_t channel_layout)
 {
-    return ff_filter_frame(link->dst->outputs[0], frame);
-}
-
-int ff_filter_samples_framed(AVFilterLink *link, AVFilterBufferRef *samplesref)
-{
-    int (*filter_frame)(AVFilterLink *, AVFilterBufferRef *);
-    AVFilterPad *src = link->srcpad;
-    AVFilterPad *dst = link->dstpad;
-    int64_t pts;
-    AVFilterBufferRef *buf_out;
-    int ret;
-
-    FF_TPRINTF_START(NULL, filter_frame); ff_tlog_link(NULL, link, 1);
-
-    if (link->closed) {
-        avfilter_unref_buffer(samplesref);
-        return AVERROR_EOF;
-    }
-
-    if (!(filter_frame = dst->filter_frame))
-        filter_frame = default_filter_frame;
-
-    av_assert1((samplesref->perms & src->min_perms) == src->min_perms);
-    samplesref->perms &= ~ src->rej_perms;
-
-    /* prepare to copy the samples if the buffer has insufficient permissions */
-    if ((dst->min_perms & samplesref->perms) != dst->min_perms ||
-        dst->rej_perms & samplesref->perms) {
-        av_log(link->dst, AV_LOG_DEBUG,
-               "Copying audio data in avfilter (have perms %x, need %x, reject %x)\n",
-               samplesref->perms, link->dstpad->min_perms, link->dstpad->rej_perms);
-
-        buf_out = ff_default_get_audio_buffer(link, dst->min_perms,
-                                              samplesref->audio->nb_samples);
-        if (!buf_out) {
-            avfilter_unref_buffer(samplesref);
-            return AVERROR(ENOMEM);
-        }
-        buf_out->pts                = samplesref->pts;
-        buf_out->audio->sample_rate = samplesref->audio->sample_rate;
-
-        /* Copy actual data into new samples buffer */
-        av_samples_copy(buf_out->extended_data, samplesref->extended_data,
-                        0, 0, samplesref->audio->nb_samples,
-                        av_get_channel_layout_nb_channels(link->channel_layout),
-                        link->format);
-
-        avfilter_unref_buffer(samplesref);
-    } else
-        buf_out = samplesref;
-
-    link->cur_buf = buf_out;
-    pts = buf_out->pts;
-    ret = filter_frame(link, buf_out);
-    ff_update_link_current_pts(link, pts);
-    return ret;
-}
-
-int ff_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref)
-{
-    int insamples = samplesref->audio->nb_samples, inpos = 0, nb_samples;
-    AVFilterBufferRef *pbuf = link->partial_buf;
-    int nb_channels = av_get_channel_layout_nb_channels(link->channel_layout);
-    int ret = 0;
-
-    av_assert1(samplesref->format                == link->format);
-    av_assert1(samplesref->audio->channel_layout == link->channel_layout);
-    av_assert1(samplesref->audio->sample_rate    == link->sample_rate);
-
-    if (!link->min_samples ||
-        (!pbuf &&
-         insamples >= link->min_samples && insamples <= link->max_samples)) {
-        return ff_filter_samples_framed(link, samplesref);
-    }
-    /* Handle framing (min_samples, max_samples) */
-    while (insamples) {
-        if (!pbuf) {
-            AVRational samples_tb = { 1, link->sample_rate };
-            int perms = link->dstpad->min_perms | AV_PERM_WRITE;
-            pbuf = ff_get_audio_buffer(link, perms, link->partial_buf_size);
-            if (!pbuf) {
-                av_log(link->dst, AV_LOG_WARNING,
-                       "Samples dropped due to memory allocation failure.\n");
-                return 0;
-            }
-            avfilter_copy_buffer_ref_props(pbuf, samplesref);
-            pbuf->pts = samplesref->pts +
-                        av_rescale_q(inpos, samples_tb, link->time_base);
-            pbuf->audio->nb_samples = 0;
-        }
-        nb_samples = FFMIN(insamples,
-                           link->partial_buf_size - pbuf->audio->nb_samples);
-        av_samples_copy(pbuf->extended_data, samplesref->extended_data,
-                        pbuf->audio->nb_samples, inpos,
-                        nb_samples, nb_channels, link->format);
-        inpos                   += nb_samples;
-        insamples               -= nb_samples;
-        pbuf->audio->nb_samples += nb_samples;
-        if (pbuf->audio->nb_samples >= link->min_samples) {
-            ret = ff_filter_samples_framed(link, pbuf);
-            pbuf = NULL;
-        }
-    }
-    avfilter_unref_buffer(samplesref);
-    link->partial_buf = pbuf;
-    return ret;
+    int channels = av_get_channel_layout_nb_channels(channel_layout);
+    return avfilter_get_audio_buffer_ref_from_arrays_channels(data, linesize, perms,
+                                                              nb_samples, sample_fmt,
+                                                              channels, channel_layout);
 }
diff --git a/libavfilter/avcodec.c b/libavfilter/avcodec.c
index 688f1b3..dd3c886 100644
--- a/libavfilter/avcodec.c
+++ b/libavfilter/avcodec.c
@@ -92,10 +92,18 @@
 AVFilterBufferRef *avfilter_get_audio_buffer_ref_from_frame(const AVFrame *frame,
                                                             int perms)
 {
-    AVFilterBufferRef *samplesref =
-        avfilter_get_audio_buffer_ref_from_arrays((uint8_t **)frame->data, frame->linesize[0], perms,
-                                                  frame->nb_samples, frame->format,
-                                                  av_frame_get_channel_layout(frame));
+    AVFilterBufferRef *samplesref;
+    int channels = av_frame_get_channels(frame);
+    int64_t layout = av_frame_get_channel_layout(frame);
+
+    if (layout && av_get_channel_layout_nb_channels(layout) != av_frame_get_channels(frame)) {
+        av_log(0, AV_LOG_ERROR, "Layout indicates a different number of channels than actually present\n");
+        return NULL;
+    }
+
+    samplesref = avfilter_get_audio_buffer_ref_from_arrays_channels(
+        (uint8_t **)frame->extended_data, frame->linesize[0], perms,
+        frame->nb_samples, frame->format, channels, layout);
     if (!samplesref)
         return NULL;
     if (avfilter_copy_frame_props(samplesref, frame) < 0) {
diff --git a/libavfilter/avf_concat.c b/libavfilter/avf_concat.c
index 6be2c53..079d55d 100644
--- a/libavfilter/avf_concat.c
+++ b/libavfilter/avf_concat.c
@@ -78,8 +78,8 @@
 {
     ConcatContext *cat = ctx->priv;
     unsigned type, nb_str, idx0 = 0, idx, str, seg;
-    AVFilterFormats *formats, *rates;
-    AVFilterChannelLayouts *layouts;
+    AVFilterFormats *formats, *rates = NULL;
+    AVFilterChannelLayouts *layouts = NULL;
 
     for (type = 0; type < TYPE_ALL; type++) {
         nb_str = cat->nb_streams[type];
diff --git a/libavfilter/avf_showspectrum.c b/libavfilter/avf_showspectrum.c
index 977fca9..bb8b62f 100644
--- a/libavfilter/avf_showspectrum.c
+++ b/libavfilter/avf_showspectrum.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2012 Clément Bœsch
+ * Copyright (c) 2013 Rudolf Polzer <divverent@xonotic.org>
  *
  * This file is part of FFmpeg.
  *
@@ -27,38 +28,75 @@
 #include <math.h>
 
 #include "libavcodec/avfft.h"
+#include "libavutil/avassert.h"
 #include "libavutil/channel_layout.h"
 #include "libavutil/opt.h"
 #include "avfilter.h"
 #include "internal.h"
 
+enum DisplayMode  { COMBINED, SEPARATE, NB_MODES };
+enum DisplayScale { LINEAR, SQRT, CBRT, LOG, NB_SCALES };
+enum ColorMode    { CHANNEL, INTENSITY, NB_CLMODES };
+
 typedef struct {
     const AVClass *class;
     int w, h;
     AVFilterBufferRef *outpicref;
     int req_fullfilled;
+    int nb_display_channels;
+    int channel_height;
     int sliding;                ///< 1 if sliding mode, 0 otherwise
+    enum DisplayMode mode;      ///< channel display mode
+    enum ColorMode color_mode;  ///< display color scheme
+    enum DisplayScale scale;
+    float saturation;           ///< color saturation multiplier
     int xpos;                   ///< x position (current column)
     RDFTContext *rdft;          ///< Real Discrete Fourier Transform context
     int rdft_bits;              ///< number of bits (RDFT window size = 1<<rdft_bits)
-    FFTSample *rdft_data;       ///< bins holder for each (displayed) channels
+    FFTSample **rdft_data;      ///< bins holder for each (displayed) channels
     int filled;                 ///< number of samples (per channel) filled in current rdft_buffer
     int consumed;               ///< number of samples (per channel) consumed from the input frame
     float *window_func_lut;     ///< Window function LUT
+    float *combine_buffer;      ///< color combining buffer (3 * h items)
 } ShowSpectrumContext;
 
 #define OFFSET(x) offsetof(ShowSpectrumContext, x)
 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
 
 static const AVOption showspectrum_options[] = {
-    { "size", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "640x480"}, 0, 0, FLAGS },
-    { "s",    "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "640x480"}, 0, 0, FLAGS },
+    { "size", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "640x512"}, 0, 0, FLAGS },
+    { "s",    "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "640x512"}, 0, 0, FLAGS },
     { "slide", "set sliding mode", OFFSET(sliding), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, FLAGS },
+    { "mode", "set channel display mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=COMBINED}, COMBINED, NB_MODES-1, FLAGS, "mode" },
+    { "combined", "combined mode", 0, AV_OPT_TYPE_CONST, {.i64=COMBINED}, 0, 0, FLAGS, "mode" },
+    { "separate", "separate mode", 0, AV_OPT_TYPE_CONST, {.i64=SEPARATE}, 0, 0, FLAGS, "mode" },
+    { "color", "set channel coloring", OFFSET(color_mode), AV_OPT_TYPE_INT, {.i64=CHANNEL}, CHANNEL, NB_CLMODES-1, FLAGS, "color" },
+    { "channel",   "separate color for each channel", 0, AV_OPT_TYPE_CONST, {.i64=CHANNEL},   0, 0, FLAGS, "color" },
+    { "intensity", "intensity based coloring",        0, AV_OPT_TYPE_CONST, {.i64=INTENSITY}, 0, 0, FLAGS, "color" },
+    { "scale", "set display scale", OFFSET(scale), AV_OPT_TYPE_INT, {.i64=SQRT}, LINEAR, NB_SCALES-1, FLAGS, "scale" },
+    { "sqrt", "square root", 0, AV_OPT_TYPE_CONST, {.i64=SQRT},   0, 0, FLAGS, "scale" },
+    { "cbrt", "cubic root",  0, AV_OPT_TYPE_CONST, {.i64=CBRT},   0, 0, FLAGS, "scale" },
+    { "log",  "logarithmic", 0, AV_OPT_TYPE_CONST, {.i64=LOG},    0, 0, FLAGS, "scale" },
+    { "lin",  "linear",      0, AV_OPT_TYPE_CONST, {.i64=LINEAR}, 0, 0, FLAGS, "scale" },
+    { "saturation", "color saturation multiplier", OFFSET(saturation), AV_OPT_TYPE_FLOAT, {.dbl = 1}, -10, 10, FLAGS },
     { NULL },
 };
 
 AVFILTER_DEFINE_CLASS(showspectrum);
 
+static const struct {
+    float a, y, u, v;
+} intensity_color_table[] = {
+    {    0,                  0,                  0,                   0 },
+    { 0.13, .03587126228984074,  .1573300977624594, -.02548747583751842 },
+    { 0.30, .18572281794568020,  .1772436246393981,  .17475554840414750 },
+    { 0.60, .28184980583656130, -.1593064119945782,  .47132074554608920 },
+    { 0.73, .65830621175547810, -.3716070802232764,  .24352759331252930 },
+    { 0.78, .76318535758242900, -.4307467689263783,  .16866496622310430 },
+    { 0.91, .95336363636363640, -.2045454545454546,  .03313636363636363 },
+    {    1,                  1,                  0,                   0 }
+};
+
 static av_cold int init(AVFilterContext *ctx, const char *args)
 {
     ShowSpectrumContext *showspectrum = ctx->priv;
@@ -76,8 +114,12 @@
 static av_cold void uninit(AVFilterContext *ctx)
 {
     ShowSpectrumContext *showspectrum = ctx->priv;
+    int i;
 
+    av_freep(&showspectrum->combine_buffer);
     av_rdft_end(showspectrum->rdft);
+    for (i = 0; i < showspectrum->nb_display_channels; i++)
+        av_freep(&showspectrum->rdft_data[i]);
     av_freep(&showspectrum->rdft_data);
     av_freep(&showspectrum->window_func_lut);
     avfilter_unref_bufferp(&showspectrum->outpicref);
@@ -90,7 +132,7 @@
     AVFilterLink *inlink = ctx->inputs[0];
     AVFilterLink *outlink = ctx->outputs[0];
     static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_NONE };
-    static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_RGB24, AV_PIX_FMT_NONE };
+    static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_NONE };
 
     /* set input audio formats */
     formats = ff_make_format_list(sample_fmts);
@@ -120,19 +162,23 @@
 static int config_output(AVFilterLink *outlink)
 {
     AVFilterContext *ctx = outlink->src;
+    AVFilterLink *inlink = ctx->inputs[0];
     ShowSpectrumContext *showspectrum = ctx->priv;
-    int i, rdft_bits, win_size;
+    int i, rdft_bits, win_size, h;
 
     outlink->w = showspectrum->w;
     outlink->h = showspectrum->h;
 
+    h = (showspectrum->mode == COMBINED) ? outlink->h : outlink->h / inlink->channels;
+    showspectrum->channel_height = h;
+
     /* RDFT window size (precision) according to the requested output frame height */
-    for (rdft_bits = 1; 1<<rdft_bits < 2*outlink->h; rdft_bits++);
+    for (rdft_bits = 1; 1 << rdft_bits < 2 * h; rdft_bits++);
     win_size = 1 << rdft_bits;
 
     /* (re-)configuration if the video output changed (or first init) */
     if (rdft_bits != showspectrum->rdft_bits) {
-        size_t rdft_size;
+        size_t rdft_size, rdft_listsize;
         AVFilterBufferRef *outpicref;
 
         av_rdft_end(showspectrum->rdft);
@@ -142,12 +188,25 @@
         /* RDFT buffers: x2 for each (display) channel buffer.
          * Note: we use free and malloc instead of a realloc-like function to
          * make sure the buffer is aligned in memory for the FFT functions. */
+        for (i = 0; i < showspectrum->nb_display_channels; i++)
+            av_freep(&showspectrum->rdft_data[i]);
         av_freep(&showspectrum->rdft_data);
-        if (av_size_mult(sizeof(*showspectrum->rdft_data), 2 * win_size, &rdft_size) < 0)
+        showspectrum->nb_display_channels = inlink->channels;
+
+        if (av_size_mult(sizeof(*showspectrum->rdft_data),
+                         showspectrum->nb_display_channels, &rdft_listsize) < 0)
             return AVERROR(EINVAL);
-        showspectrum->rdft_data = av_malloc(rdft_size);
+        if (av_size_mult(sizeof(**showspectrum->rdft_data),
+                         win_size, &rdft_size) < 0)
+            return AVERROR(EINVAL);
+        showspectrum->rdft_data = av_malloc(rdft_listsize);
         if (!showspectrum->rdft_data)
             return AVERROR(ENOMEM);
+        for (i = 0; i < showspectrum->nb_display_channels; i++) {
+            showspectrum->rdft_data[i] = av_malloc(rdft_size);
+            if (!showspectrum->rdft_data[i])
+                return AVERROR(ENOMEM);
+        }
         showspectrum->filled = 0;
 
         /* pre-calc windowing function (hann here) */
@@ -173,6 +232,10 @@
     if (showspectrum->xpos >= outlink->w)
         showspectrum->xpos = 0;
 
+    showspectrum->combine_buffer =
+        av_realloc_f(showspectrum->combine_buffer, outlink->h * 3,
+                     sizeof(*showspectrum->combine_buffer));
+
     av_log(ctx, AV_LOG_VERBOSE, "s:%dx%d RDFT window size:%d\n",
            showspectrum->w, showspectrum->h, win_size);
     return 0;
@@ -213,62 +276,180 @@
     AVFilterLink *outlink = ctx->outputs[0];
     ShowSpectrumContext *showspectrum = ctx->priv;
     AVFilterBufferRef *outpicref = showspectrum->outpicref;
-    const int nb_channels = av_get_channel_layout_nb_channels(insamples->audio->channel_layout);
 
     /* nb_freq contains the power of two superior or equal to the output image
      * height (or half the RDFT window size) */
     const int nb_freq = 1 << (showspectrum->rdft_bits - 1);
     const int win_size = nb_freq << 1;
+    const double w = 1. / (sqrt(nb_freq) * 32768.);
 
-    int ch, n, y;
-    FFTSample *data[2];
-    const int nb_display_channels = FFMIN(nb_channels, 2);
+    int ch, plane, n, y;
     const int start = showspectrum->filled;
     const int add_samples = FFMIN(win_size - start, nb_samples);
 
     /* fill RDFT input with the number of samples available */
-    for (ch = 0; ch < nb_display_channels; ch++) {
+    for (ch = 0; ch < showspectrum->nb_display_channels; ch++) {
         const int16_t *p = (int16_t *)insamples->extended_data[ch];
 
         p += showspectrum->consumed;
-        data[ch] = showspectrum->rdft_data + win_size * ch; // select channel buffer
         for (n = 0; n < add_samples; n++)
-            data[ch][start + n] = p[n] * showspectrum->window_func_lut[start + n];
+            showspectrum->rdft_data[ch][start + n] = p[n] * showspectrum->window_func_lut[start + n];
     }
     showspectrum->filled += add_samples;
 
     /* complete RDFT window size? */
     if (showspectrum->filled == win_size) {
 
+        /* channel height */
+        int h = showspectrum->channel_height;
+
         /* run RDFT on each samples set */
-        for (ch = 0; ch < nb_display_channels; ch++)
-            av_rdft_calc(showspectrum->rdft, data[ch]);
+        for (ch = 0; ch < showspectrum->nb_display_channels; ch++)
+            av_rdft_calc(showspectrum->rdft, showspectrum->rdft_data[ch]);
 
         /* fill a new spectrum column */
-#define RE(ch) data[ch][2*y + 0]
-#define IM(ch) data[ch][2*y + 1]
-#define MAGNITUDE(re, im) sqrt((re)*(re) + (im)*(im))
+#define RE(y, ch) showspectrum->rdft_data[ch][2 * y + 0]
+#define IM(y, ch) showspectrum->rdft_data[ch][2 * y + 1]
+#define MAGNITUDE(y, ch) hypot(RE(y, ch), IM(y, ch))
 
+        /* initialize buffer for combining to black */
         for (y = 0; y < outlink->h; y++) {
-            // FIXME: bin[0] contains first and last bins
-            uint8_t *p = outpicref->data[0] + (outlink->h - y - 1) * outpicref->linesize[0];
-            const double w = 1. / sqrt(nb_freq);
-            int a =                           sqrt(w * MAGNITUDE(RE(0), IM(0)));
-            int b = nb_display_channels > 1 ? sqrt(w * MAGNITUDE(RE(1), IM(1))) : a;
+            showspectrum->combine_buffer[3 * y    ] = 0;
+            showspectrum->combine_buffer[3 * y + 1] = 127.5;
+            showspectrum->combine_buffer[3 * y + 2] = 127.5;
+        }
 
-            if (showspectrum->sliding) {
-                memmove(p, p + 3, (outlink->w - 1) * 3);
-                p += (outlink->w - 1) * 3;
-            } else {
-                p += showspectrum->xpos * 3;
+        for (ch = 0; ch < showspectrum->nb_display_channels; ch++) {
+            float yf, uf, vf;
+
+            /* decide color range */
+            switch (showspectrum->mode) {
+            case COMBINED:
+                // reduce range by channel count
+                yf = 256.0f / showspectrum->nb_display_channels;
+                switch (showspectrum->color_mode) {
+                case INTENSITY:
+                    uf = yf;
+                    vf = yf;
+                    break;
+                case CHANNEL:
+                    /* adjust saturation for mixed UV coloring */
+                    /* this factor is correct for infinite channels, an approximation otherwise */
+                    uf = yf * M_PI;
+                    vf = yf * M_PI;
+                    break;
+                default:
+                    av_assert0(0);
+                }
+                break;
+            case SEPARATE:
+                // full range
+                yf = 256.0f;
+                uf = 256.0f;
+                vf = 256.0f;
+                break;
+            default:
+                av_assert0(0);
             }
 
-            a = FFMIN(a, 255);
-            b = FFMIN(b, 255);
-            p[0] = a;
-            p[1] = b;
-            p[2] = (a + b) / 2;
+            if (showspectrum->color_mode == CHANNEL) {
+                if (showspectrum->nb_display_channels > 1) {
+                    uf *= 0.5 * sin((2 * M_PI * ch) / showspectrum->nb_display_channels);
+                    vf *= 0.5 * cos((2 * M_PI * ch) / showspectrum->nb_display_channels);
+                } else {
+                    uf = 0.0f;
+                    vf = 0.0f;
+                }
+            }
+            uf *= showspectrum->saturation;
+            vf *= showspectrum->saturation;
+
+            /* draw the channel */
+            for (y = 0; y < h; y++) {
+                int row = (showspectrum->mode == COMBINED) ? y : ch * h + y;
+                float *out = &showspectrum->combine_buffer[3 * row];
+
+                /* get magnitude */
+                float a = w * MAGNITUDE(y, ch);
+
+                /* apply scale */
+                switch (showspectrum->scale) {
+                case LINEAR:
+                    break;
+                case SQRT:
+                    a = sqrt(a);
+                    break;
+                case CBRT:
+                    a = cbrt(a);
+                    break;
+                case LOG:
+                    a = 1 - log(FFMAX(FFMIN(1, a), 1e-6)) / log(1e-6); // zero = -120dBFS
+                    break;
+                default:
+                    av_assert0(0);
+                }
+
+                if (showspectrum->color_mode == INTENSITY) {
+                    float y, u, v;
+                    int i;
+
+                    for (i = 1; i < sizeof(intensity_color_table) / sizeof(*intensity_color_table) - 1; i++)
+                        if (intensity_color_table[i].a >= a)
+                            break;
+                    // i now is the first item >= the color
+                    // now we know to interpolate between item i - 1 and i
+                    if (a <= intensity_color_table[i - 1].a) {
+                        y = intensity_color_table[i - 1].y;
+                        u = intensity_color_table[i - 1].u;
+                        v = intensity_color_table[i - 1].v;
+                    } else if (a >= intensity_color_table[i].a) {
+                        y = intensity_color_table[i].y;
+                        u = intensity_color_table[i].u;
+                        v = intensity_color_table[i].v;
+                    } else {
+                        float start = intensity_color_table[i - 1].a;
+                        float end = intensity_color_table[i].a;
+                        float lerpfrac = (a - start) / (end - start);
+                        y = intensity_color_table[i - 1].y * (1.0f - lerpfrac)
+                          + intensity_color_table[i].y * lerpfrac;
+                        u = intensity_color_table[i - 1].u * (1.0f - lerpfrac)
+                          + intensity_color_table[i].u * lerpfrac;
+                        v = intensity_color_table[i - 1].v * (1.0f - lerpfrac)
+                          + intensity_color_table[i].v * lerpfrac;
+                    }
+
+                    out[0] += y * yf;
+                    out[1] += u * uf;
+                    out[2] += v * vf;
+                } else {
+                    out[0] += a * yf;
+                    out[1] += a * uf;
+                    out[2] += a * vf;
+                }
+            }
         }
+
+        /* copy to output */
+        if (showspectrum->sliding) {
+            for (plane = 0; plane < 3; plane++) {
+                for (y = 0; y < outlink->h; y++) {
+                    uint8_t *p = outpicref->data[plane] +
+                                 y * outpicref->linesize[plane];
+                    memmove(p, p + 1, outlink->w - 1);
+                }
+            }
+            showspectrum->xpos = outlink->w - 1;
+        }
+        for (plane = 0; plane < 3; plane++) {
+            uint8_t *p = outpicref->data[plane] +
+                         (outlink->h - 1) * outpicref->linesize[plane] +
+                         showspectrum->xpos;
+            for (y = 0; y < outlink->h; y++) {
+                *p = rint(FFMAX(0, FFMIN(showspectrum->combine_buffer[3 * y + plane], 255)));
+                p -= outpicref->linesize[plane];
+            }
+        }
+
         outpicref->pts = insamples->pts +
             av_rescale_q(showspectrum->consumed,
                          (AVRational){ 1, inlink->sample_rate },
diff --git a/libavfilter/avf_showwaves.c b/libavfilter/avf_showwaves.c
index 30a8e1e..1b9d28d 100644
--- a/libavfilter/avf_showwaves.c
+++ b/libavfilter/avf_showwaves.c
@@ -32,6 +32,12 @@
 #include "video.h"
 #include "internal.h"
 
+enum ShowWavesMode {
+    MODE_POINT,
+    MODE_LINE,
+    MODE_NB,
+};
+
 typedef struct {
     const AVClass *class;
     int w, h;
@@ -42,6 +48,7 @@
     int req_fullfilled;
     int n;
     int sample_count_mod;
+    enum ShowWavesMode mode;
 } ShowWavesContext;
 
 #define OFFSET(x) offsetof(ShowWavesContext, x)
@@ -53,6 +60,10 @@
     { "size", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "600x240"}, 0, 0, FLAGS },
     { "s",    "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "600x240"}, 0, 0, FLAGS },
     { "n",    "set how many samples to show in the same point", OFFSET(n), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, FLAGS },
+
+    {"mode",  "select display mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=MODE_POINT}, 0, MODE_NB-1, FLAGS, "mode"},
+    {"point", "draw a point for each sample", 0, AV_OPT_TYPE_CONST, {.i64=MODE_POINT}, .flags=FLAGS, .unit="mode"},
+    {"line",  "draw a line for each sample",  0, AV_OPT_TYPE_CONST, {.i64=MODE_LINE},  .flags=FLAGS, .unit="mode"},
     { NULL },
 };
 
@@ -149,14 +160,16 @@
     return 0;
 }
 
-inline static void push_frame(AVFilterLink *outlink)
+inline static int push_frame(AVFilterLink *outlink)
 {
     ShowWavesContext *showwaves = outlink->src->priv;
+    int ret;
 
-    ff_filter_frame(outlink, showwaves->outpicref);
-    showwaves->req_fullfilled = 1;
+    if ((ret = ff_filter_frame(outlink, showwaves->outpicref)) >= 0)
+        showwaves->req_fullfilled = 1;
     showwaves->outpicref = NULL;
     showwaves->buf_idx = 0;
+    return ret;
 }
 
 static int request_frame(AVFilterLink *outlink)
@@ -187,13 +200,13 @@
     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->audio->channel_layout);
-    int i, j, h;
+    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 */
 
     /* draw data in the buffer */
     for (i = 0; i < nb_samples; i++) {
-        if (!outpicref) {
+        if (!showwaves->outpicref) {
             showwaves->outpicref = outpicref =
                 ff_get_video_buffer(outlink, AV_PERM_WRITE|AV_PERM_ALIGN,
                                     outlink->w, outlink->h);
@@ -210,20 +223,36 @@
         }
         for (j = 0; j < nb_channels; j++) {
             h = showwaves->h/2 - av_rescale(*p++, showwaves->h/2, MAX_INT16);
-            if (h >= 0 && h < outlink->h)
-                *(outpicref->data[0] + showwaves->buf_idx + h * linesize) += x;
+            switch (showwaves->mode) {
+            case MODE_POINT:
+                if (h >= 0 && h < outlink->h)
+                    *(outpicref->data[0] + showwaves->buf_idx + h * linesize) += x;
+                break;
+
+            case MODE_LINE:
+            {
+                int start = showwaves->h/2, end = av_clip(h, 0, outlink->h-1);
+                if (start > end) FFSWAP(int16_t, start, end);
+                for (k = start; k < end; k++)
+                    *(outpicref->data[0] + showwaves->buf_idx + k * linesize) += x;
+                break;
+            }
+            }
         }
+
         showwaves->sample_count_mod++;
         if (showwaves->sample_count_mod == n) {
             showwaves->sample_count_mod = 0;
             showwaves->buf_idx++;
         }
         if (showwaves->buf_idx == showwaves->w)
-            push_frame(outlink);
+            if ((ret = push_frame(outlink)) < 0)
+                break;
+        outpicref = showwaves->outpicref;
     }
 
     avfilter_unref_buffer(insamples);
-    return 0;
+    return ret;
 }
 
 static const AVFilterPad showwaves_inputs[] = {
diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index 31580f6..ffd1b4e 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -34,6 +34,8 @@
 #include "internal.h"
 #include "audio.h"
 
+static int ff_filter_frame_framed(AVFilterLink *link, AVFilterBufferRef *frame);
+
 char *ff_get_ref_perms_string(char *buf, size_t buf_size, int perms)
 {
     snprintf(buf, buf_size, "%s%s%s%s%s%s",
@@ -164,6 +166,11 @@
     av_freep(link);
 }
 
+int avfilter_link_get_channels(AVFilterLink *link)
+{
+    return link->channels;
+}
+
 void avfilter_link_set_closed(AVFilterLink *link, int closed)
 {
     link->closed = closed;
@@ -215,11 +222,11 @@
 
     for (i = 0; i < filter->nb_inputs; i ++) {
         AVFilterLink *link = filter->inputs[i];
-        AVFilterLink *inlink = link->src->nb_inputs ?
-            link->src->inputs[0] : NULL;
+        AVFilterLink *inlink;
 
         if (!link) continue;
 
+        inlink = link->src->nb_inputs ? link->src->inputs[0] : NULL;
         link->current_pts = AV_NOPTS_VALUE;
 
         switch (link->init_state) {
@@ -276,17 +283,8 @@
 
             case AVMEDIA_TYPE_AUDIO:
                 if (inlink) {
-                    if (!link->sample_rate)
-                        link->sample_rate = inlink->sample_rate;
                     if (!link->time_base.num && !link->time_base.den)
                         link->time_base = inlink->time_base;
-                    if (!link->channel_layout)
-                        link->channel_layout = inlink->channel_layout;
-                } else if (!link->sample_rate) {
-                    av_log(link->src, AV_LOG_ERROR,
-                           "Audio source filters must set their output link's "
-                           "sample_rate\n");
-                    return AVERROR(EINVAL);
                 }
 
                 if (!link->time_base.num && !link->time_base.den)
@@ -346,7 +344,7 @@
     if (ret == AVERROR_EOF && link->partial_buf) {
         AVFilterBufferRef *pbuf = link->partial_buf;
         link->partial_buf = NULL;
-        ff_filter_samples_framed(link, pbuf);
+        ff_filter_frame_framed(link, pbuf);
         return 0;
     }
     if (ret == AVERROR_EOF)
@@ -393,7 +391,7 @@
     return AVERROR(ENOSYS);
 }
 
-#define MAX_REGISTERED_AVFILTERS_NB 128
+#define MAX_REGISTERED_AVFILTERS_NB 256
 
 static AVFilter *registered_avfilters[MAX_REGISTERED_AVFILTERS_NB + 1];
 
@@ -425,7 +423,7 @@
     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 && !input->draw_slice));
+                    || (!input->start_frame && !input->end_frame));
     }
 
     registered_avfilters[next_registered_avfilter_idx++] = filter;
@@ -635,22 +633,161 @@
     return pads[pad_idx].type;
 }
 
+static int default_filter_frame(AVFilterLink *link, AVFilterBufferRef *frame)
+{
+    return ff_filter_frame(link->dst->outputs[0], frame);
+}
+
+static int ff_filter_frame_framed(AVFilterLink *link, AVFilterBufferRef *frame)
+{
+    int (*filter_frame)(AVFilterLink *, AVFilterBufferRef *);
+    AVFilterPad *src = link->srcpad;
+    AVFilterPad *dst = link->dstpad;
+    AVFilterBufferRef *out;
+    int perms, ret;
+    AVFilterCommand *cmd= link->dst->command_queue;
+    int64_t pts;
+
+    if (link->closed) {
+        avfilter_unref_buffer(frame);
+        return AVERROR_EOF;
+    }
+
+    if (!(filter_frame = dst->filter_frame))
+        filter_frame = default_filter_frame;
+
+    av_assert1((frame->perms & src->min_perms) == src->min_perms);
+    frame->perms &= ~ src->rej_perms;
+    perms = frame->perms;
+
+    if (frame->linesize[0] < 0)
+        perms |= AV_PERM_NEG_LINESIZES;
+
+    /* prepare to copy the frame if the buffer has insufficient permissions */
+    if ((dst->min_perms & perms) != dst->min_perms ||
+        dst->rej_perms & perms) {
+        av_log(link->dst, AV_LOG_DEBUG,
+               "Copying data in avfilter (have perms %x, need %x, reject %x)\n",
+               perms, link->dstpad->min_perms, link->dstpad->rej_perms);
+
+        /* Maybe use ff_copy_buffer_ref instead? */
+        switch (link->type) {
+        case AVMEDIA_TYPE_VIDEO:
+            out = ff_get_video_buffer(link, dst->min_perms,
+                                      link->w, link->h);
+            break;
+        case AVMEDIA_TYPE_AUDIO:
+            out = ff_get_audio_buffer(link, dst->min_perms,
+                                      frame->audio->nb_samples);
+            break;
+        default: return AVERROR(EINVAL);
+        }
+        if (!out) {
+            avfilter_unref_buffer(frame);
+            return AVERROR(ENOMEM);
+        }
+        avfilter_copy_buffer_ref_props(out, frame);
+
+        switch (link->type) {
+        case AVMEDIA_TYPE_VIDEO:
+            av_image_copy(out->data, out->linesize, (const uint8_t **)frame->data, frame->linesize,
+                          frame->format, frame->video->w, frame->video->h);
+            break;
+        case AVMEDIA_TYPE_AUDIO:
+            av_samples_copy(out->extended_data, frame->extended_data,
+                            0, 0, frame->audio->nb_samples,
+                            av_get_channel_layout_nb_channels(frame->audio->channel_layout),
+                            frame->format);
+            break;
+        default: return AVERROR(EINVAL);
+        }
+
+        avfilter_unref_buffer(frame);
+    } else
+        out = frame;
+
+    while(cmd && cmd->time <= out->pts * av_q2d(link->time_base)){
+        av_log(link->dst, AV_LOG_DEBUG,
+               "Processing command time:%f command:%s arg:%s\n",
+               cmd->time, cmd->command, cmd->arg);
+        avfilter_process_command(link->dst, cmd->command, cmd->arg, 0, 0, cmd->flags);
+        ff_command_queue_pop(link->dst);
+        cmd= link->dst->command_queue;
+    }
+
+    pts = out->pts;
+    ret = filter_frame(link, out);
+    ff_update_link_current_pts(link, pts);
+    return ret;
+}
+
+static int ff_filter_frame_needs_framing(AVFilterLink *link, AVFilterBufferRef *frame)
+{
+    int insamples = frame->audio->nb_samples, inpos = 0, nb_samples;
+    AVFilterBufferRef *pbuf = link->partial_buf;
+    int nb_channels = frame->audio->channels;
+    int ret = 0;
+
+    /* Handle framing (min_samples, max_samples) */
+    while (insamples) {
+        if (!pbuf) {
+            AVRational samples_tb = { 1, link->sample_rate };
+            int perms = link->dstpad->min_perms | AV_PERM_WRITE;
+            pbuf = ff_get_audio_buffer(link, perms, link->partial_buf_size);
+            if (!pbuf) {
+                av_log(link->dst, AV_LOG_WARNING,
+                       "Samples dropped due to memory allocation failure.\n");
+                return 0;
+            }
+            avfilter_copy_buffer_ref_props(pbuf, frame);
+            pbuf->pts = frame->pts +
+                        av_rescale_q(inpos, samples_tb, link->time_base);
+            pbuf->audio->nb_samples = 0;
+        }
+        nb_samples = FFMIN(insamples,
+                           link->partial_buf_size - pbuf->audio->nb_samples);
+        av_samples_copy(pbuf->extended_data, frame->extended_data,
+                        pbuf->audio->nb_samples, inpos,
+                        nb_samples, nb_channels, link->format);
+        inpos                   += nb_samples;
+        insamples               -= nb_samples;
+        pbuf->audio->nb_samples += nb_samples;
+        if (pbuf->audio->nb_samples >= link->min_samples) {
+            ret = ff_filter_frame_framed(link, pbuf);
+            pbuf = NULL;
+        }
+    }
+    avfilter_unref_buffer(frame);
+    link->partial_buf = pbuf;
+    return ret;
+}
+
 int ff_filter_frame(AVFilterLink *link, AVFilterBufferRef *frame)
 {
-    int ret;
     FF_TPRINTF_START(NULL, filter_frame); ff_tlog_link(NULL, link, 1); ff_tlog(NULL, " "); ff_tlog_ref(NULL, frame, 1);
 
-    switch (link->type) {
-    case AVMEDIA_TYPE_VIDEO:
-        if((ret = ff_start_frame(link, frame)) < 0)
-            return ret;
-        if((ret = ff_draw_slice(link, 0, frame->video->h, 1)) < 0)
-            return ret;
-        if((ret = ff_end_frame(link)) < 0)
-            return ret;
-        return ret;
-    case AVMEDIA_TYPE_AUDIO:
-        return ff_filter_samples(link, frame);
-    default: return AVERROR(EINVAL);
+    /* Consistency checks */
+    if (link->type == AVMEDIA_TYPE_VIDEO) {
+        if (strcmp(link->dst->filter->name, "scale")) {
+            av_assert1(frame->format                 == link->format);
+            av_assert1(frame->video->w               == link->w);
+            av_assert1(frame->video->h               == link->h);
+        }
+    } else {
+        av_assert1(frame->format                == link->format);
+        av_assert1(frame->audio->channels       == link->channels);
+        av_assert1(frame->audio->channel_layout == link->channel_layout);
+        av_assert1(frame->audio->sample_rate    == link->sample_rate);
+    }
+
+    /* Go directly to actual filtering if possible */
+    if (link->type == AVMEDIA_TYPE_AUDIO &&
+        link->min_samples &&
+        (link->partial_buf ||
+         frame->audio->nb_samples < link->min_samples ||
+         frame->audio->nb_samples > link->max_samples)) {
+        return ff_filter_frame_needs_framing(link, frame);
+    } else {
+        return ff_filter_frame_framed(link, frame);
     }
 }
diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
index f194d33..1c80167 100644
--- a/libavfilter/avfilter.h
+++ b/libavfilter/avfilter.h
@@ -22,6 +22,17 @@
 #ifndef AVFILTER_AVFILTER_H
 #define AVFILTER_AVFILTER_H
 
+/**
+ * @file
+ * @ingroup lavfi
+ * external API header
+ */
+
+/**
+ * @defgroup lavfi Libavfilter
+ * @{
+ */
+
 #include <stddef.h>
 
 #include "libavutil/avutil.h"
@@ -117,7 +128,7 @@
     uint64_t channel_layout;    ///< channel layout of audio buffer
     int nb_samples;             ///< number of audio samples per channel
     int sample_rate;            ///< audio buffer sample rate
-    int channels;               ///< number of channels
+    int channels;               ///< number of channels (do not access directly)
 } AVFilterBufferRefAudioProps;
 
 /**
@@ -222,6 +233,11 @@
  */
 void avfilter_unref_bufferp(AVFilterBufferRef **ref);
 
+/**
+ * Get the number of channels of a buffer reference.
+ */
+int avfilter_ref_get_channels(AVFilterBufferRef *ref);
+
 #if FF_API_AVFILTERPAD_PUBLIC
 /**
  * A filter pad used for either input or output.
@@ -567,51 +583,6 @@
         AVLINK_INIT             ///< complete
     } init_state;
 
-    /**
-     * The buffer reference currently being sent across the link by the source
-     * filter. This is used internally by the filter system to allow
-     * automatic copying of buffers which do not have sufficient permissions
-     * for the destination. This should not be accessed directly by the
-     * filters.
-     */
-    AVFilterBufferRef *src_buf;
-
-    /**
-     * The buffer reference to the frame sent across the link by the
-     * source filter, which is read by the destination filter. It is
-     * automatically set up by ff_start_frame().
-     *
-     * Depending on the permissions, it may either be the same as
-     * src_buf or an automatic copy of it.
-     *
-     * It is automatically freed by the filter system when calling
-     * ff_end_frame(). In case you save the buffer reference
-     * internally (e.g. if you cache it for later reuse), or give it
-     * away (e.g. if you pass the reference to the next filter) it
-     * must be set to NULL before calling ff_end_frame().
-     */
-    AVFilterBufferRef *cur_buf;
-
-    /**
-     * The buffer reference to the frame which is sent to output by
-     * the source filter.
-     *
-     * If no start_frame callback is defined on a link,
-     * ff_start_frame() will automatically request a new buffer on the
-     * first output link of the destination filter. The reference to
-     * the buffer so obtained is stored in the out_buf field on the
-     * output link.
-     *
-     * It can also be set by the filter code in case the filter needs
-     * to access the output buffer later. For example the filter code
-     * may set it in a custom start_frame, and access it in
-     * draw_slice.
-     *
-     * It is automatically freed by the filter system in
-     * ff_end_frame().
-     */
-    AVFilterBufferRef *out_buf;
-
     struct AVFilterPool *pool;
 
     /**
@@ -688,6 +659,11 @@
      * filter.
      */
     int closed;
+
+    /**
+     * Number of channels.
+     */
+    int channels;
 };
 
 /**
@@ -708,6 +684,11 @@
 void avfilter_link_free(AVFilterLink **link);
 
 /**
+ * Get the number of channels of a link.
+ */
+int avfilter_link_get_channels(AVFilterLink *link);
+
+/**
  * Set the closed field of a link.
  */
 void avfilter_link_set_closed(AVFilterLink *link, int closed);
@@ -739,6 +720,9 @@
  * Create an audio buffer reference wrapped around an already
  * allocated samples buffer.
  *
+ * See avfilter_get_audio_buffer_ref_from_arrays_channels() for a version
+ * that can handle unknown channel layouts.
+ *
  * @param data           pointers to the samples plane buffers
  * @param linesize       linesize for the samples plane buffers
  * @param perms          the required access permissions
@@ -752,6 +736,27 @@
                                                              int nb_samples,
                                                              enum AVSampleFormat sample_fmt,
                                                              uint64_t channel_layout);
+/**
+ * Create an audio buffer reference wrapped around an already
+ * allocated samples buffer.
+ *
+ * @param data           pointers to the samples plane buffers
+ * @param linesize       linesize for the samples plane buffers
+ * @param perms          the required access permissions
+ * @param nb_samples     number of samples per channel
+ * @param sample_fmt     the format of each sample in the buffer to allocate
+ * @param channels       the number of channels of the buffer
+ * @param channel_layout the channel layout of the buffer,
+ *                       must be either 0 or consistent with channels
+ */
+AVFilterBufferRef *avfilter_get_audio_buffer_ref_from_arrays_channels(uint8_t **data,
+                                                                      int linesize,
+                                                                      int perms,
+                                                                      int nb_samples,
+                                                                      enum AVSampleFormat sample_fmt,
+                                                                      int channels,
+                                                                      uint64_t channel_layout);
+
 
 
 #define AVFILTER_CMD_FLAG_ONE   1 ///< Stop once a filter understood the command (for target=all for example), fast filters are favored automatically
@@ -840,4 +845,8 @@
 int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt,
                            unsigned filt_srcpad_idx, unsigned filt_dstpad_idx);
 
+/**
+ * @}
+ */
+
 #endif /* AVFILTER_AVFILTER_H */
diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
index 52af2ad..8b18c6f 100644
--- a/libavfilter/avfiltergraph.c
+++ b/libavfilter/avfiltergraph.c
@@ -68,6 +68,7 @@
     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);
 }
@@ -185,9 +186,24 @@
     return NULL;
 }
 
+static void sanitize_channel_layouts(void *log, AVFilterChannelLayouts *l)
+{
+    if (!l)
+        return;
+    if (l->nb_channel_layouts) {
+        if (l->all_layouts || l->all_counts)
+            av_log(log, AV_LOG_WARNING, "All layouts set on non-empty list\n");
+        l->all_layouts = l->all_counts = 0;
+    } else {
+        if (l->all_counts && !l->all_layouts)
+            av_log(log, AV_LOG_WARNING, "All counts without all layouts\n");
+        l->all_layouts = 1;
+    }
+}
+
 static int filter_query_formats(AVFilterContext *ctx)
 {
-    int ret;
+    int ret, i;
     AVFilterFormats *formats;
     AVFilterChannelLayouts *chlayouts;
     AVFilterFormats *samplerates;
@@ -195,8 +211,16 @@
                             ctx->outputs && ctx->outputs[0] ? ctx->outputs[0]->type :
                             AVMEDIA_TYPE_VIDEO;
 
-    if ((ret = ctx->filter->query_formats(ctx)) < 0)
+    if ((ret = ctx->filter->query_formats(ctx)) < 0) {
+        av_log(ctx, AV_LOG_ERROR, "Query format failed for '%s': %s\n",
+               ctx->name, av_err2str(ret));
         return ret;
+    }
+
+    for (i = 0; i < ctx->nb_inputs; i++)
+        sanitize_channel_layouts(ctx, ctx->inputs[i]->out_channel_layouts);
+    for (i = 0; i < ctx->nb_outputs; i++)
+        sanitize_channel_layouts(ctx, ctx->outputs[i]->in_channel_layouts);
 
     formats = ff_all_formats(type);
     if (!formats)
@@ -215,66 +239,9 @@
     return 0;
 }
 
-static int insert_conv_filter(AVFilterGraph *graph, AVFilterLink *link,
-                              const char *filt_name, const char *filt_args)
-{
-    static int auto_count = 0, ret;
-    char inst_name[32];
-    AVFilterContext *filt_ctx;
-
-    if (graph->disable_auto_convert) {
-        av_log(NULL, AV_LOG_ERROR,
-               "The filters '%s' and '%s' do not have a common format "
-               "and automatic conversion is disabled.\n",
-               link->src->name, link->dst->name);
-        return AVERROR(EINVAL);
-    }
-
-    snprintf(inst_name, sizeof(inst_name), "auto-inserted %s %d",
-            filt_name, auto_count++);
-
-    if ((ret = avfilter_graph_create_filter(&filt_ctx,
-                                            avfilter_get_by_name(filt_name),
-                                            inst_name, filt_args, NULL, graph)) < 0)
-        return ret;
-    if ((ret = avfilter_insert_filter(link, filt_ctx, 0, 0)) < 0)
-        return ret;
-
-    filter_query_formats(filt_ctx);
-
-    if ( ((link = filt_ctx-> inputs[0]) &&
-           !ff_merge_formats(link->in_formats, link->out_formats)) ||
-         ((link = filt_ctx->outputs[0]) &&
-           !ff_merge_formats(link->in_formats, link->out_formats))
-       ) {
-        av_log(NULL, AV_LOG_ERROR,
-               "Impossible to convert between the formats supported by the filter "
-               "'%s' and the filter '%s'\n", link->src->name, link->dst->name);
-        return AVERROR(EINVAL);
-    }
-
-    if (link->type == AVMEDIA_TYPE_AUDIO &&
-         (((link = filt_ctx-> inputs[0]) &&
-           !ff_merge_channel_layouts(link->in_channel_layouts, link->out_channel_layouts)) ||
-         ((link = filt_ctx->outputs[0]) &&
-           !ff_merge_channel_layouts(link->in_channel_layouts, link->out_channel_layouts)))
-       ) {
-        av_log(NULL, AV_LOG_ERROR,
-               "Impossible to convert between the channel layouts formats supported by the filter "
-               "'%s' and the filter '%s'\n", link->src->name, link->dst->name);
-        return AVERROR(EINVAL);
-    }
-
-    return 0;
-}
-
 static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
 {
     int i, j, ret;
-    char filt_args[128];
-    AVFilterFormats *formats;
-    AVFilterChannelLayouts *chlayouts;
-    AVFilterFormats *samplerates;
     int scaler_count = 0, resampler_count = 0;
 
     for (j = 0; j < 2; j++) {
@@ -300,44 +267,14 @@
 
         for (j = 0; j < filter->nb_inputs; j++) {
             AVFilterLink *link = filter->inputs[j];
-#if 0
-            if (!link) continue;
-
-            if (!link->in_formats || !link->out_formats)
-                return AVERROR(EINVAL);
-
-            if (link->type == AVMEDIA_TYPE_VIDEO &&
-                !ff_merge_formats(link->in_formats, link->out_formats)) {
-
-                /* couldn't merge format lists, auto-insert scale filter */
-                snprintf(filt_args, sizeof(filt_args), "0:0:%s",
-                         graph->scale_sws_opts);
-                if (ret = insert_conv_filter(graph, link, "scale", filt_args))
-                    return ret;
-            }
-            else if (link->type == AVMEDIA_TYPE_AUDIO) {
-                if (!link->in_channel_layouts || !link->out_channel_layouts)
-                    return AVERROR(EINVAL);
-
-                /* Merge all three list before checking: that way, in all
-                 * three categories, aconvert will use a common format
-                 * whenever possible. */
-                formats     = ff_merge_formats(link->in_formats,   link->out_formats);
-                chlayouts   = ff_merge_channel_layouts(link->in_channel_layouts  , link->out_channel_layouts);
-                samplerates = ff_merge_samplerates    (link->in_samplerates, link->out_samplerates);
-
-                if (!formats || !chlayouts || !samplerates)
-                    if (ret = insert_conv_filter(graph, link, "aresample", NULL))
-                       return ret;
-#else
             int convert_needed = 0;
 
             if (!link)
                 continue;
 
             if (link->in_formats != link->out_formats &&
-                !ff_merge_formats(link->in_formats,
-                                        link->out_formats))
+                !ff_merge_formats(link->in_formats, link->out_formats,
+                                  link->type))
                 convert_needed = 1;
             if (link->type == AVMEDIA_TYPE_AUDIO) {
                 if (link->in_channel_layouts != link->out_channel_layouts &&
@@ -387,8 +324,13 @@
 
                     snprintf(inst_name, sizeof(inst_name), "auto-inserted resampler %d",
                              resampler_count++);
+                    scale_args[0] = '\0';
+                    if (graph->aresample_swr_opts)
+                        snprintf(scale_args, sizeof(scale_args), "%s",
+                                 graph->aresample_swr_opts);
                     if ((ret = avfilter_graph_create_filter(&convert, filter,
-                                                            inst_name, graph->aresample_swr_opts, NULL, graph)) < 0)
+                                                            inst_name, graph->aresample_swr_opts,
+                                                            NULL, graph)) < 0)
                         return ret;
                     break;
                 default:
@@ -401,8 +343,8 @@
                 filter_query_formats(convert);
                 inlink  = convert->inputs[0];
                 outlink = convert->outputs[0];
-                if (!ff_merge_formats( inlink->in_formats,  inlink->out_formats) ||
-                    !ff_merge_formats(outlink->in_formats, outlink->out_formats))
+                if (!ff_merge_formats( inlink->in_formats,  inlink->out_formats,  inlink->type) ||
+                    !ff_merge_formats(outlink->in_formats, outlink->out_formats, outlink->type))
                     ret |= AVERROR(ENOSYS);
                 if (inlink->type == AVMEDIA_TYPE_AUDIO &&
                     (!ff_merge_samplerates(inlink->in_samplerates,
@@ -423,7 +365,6 @@
                            "'%s' and the filter '%s'\n", link->src->name, link->dst->name);
                     return ret;
                 }
-#endif
             }
         }
     }
@@ -465,14 +406,18 @@
         link->in_samplerates->format_count = 1;
         link->sample_rate = link->in_samplerates->formats[0];
 
-        if (!link->in_channel_layouts->nb_channel_layouts) {
+        if (link->in_channel_layouts->all_layouts) {
             av_log(link->src, AV_LOG_ERROR, "Cannot select channel layout for"
-                   "the link between filters %s and %s.\n", link->src->name,
+                   " the link between filters %s and %s.\n", link->src->name,
                    link->dst->name);
             return AVERROR(EINVAL);
         }
         link->in_channel_layouts->nb_channel_layouts = 1;
         link->channel_layout = link->in_channel_layouts->channel_layouts[0];
+        if ((link->channels = FF_LAYOUT2COUNT(link->channel_layout)))
+            link->channel_layout = 0;
+        else
+            link->channels = av_get_channel_layout_nb_channels(link->channel_layout);
     }
 
     ff_formats_unref(&link->in_formats);
@@ -528,8 +473,42 @@
                    format_count, ff_add_format);
     REDUCE_FORMATS(int,      AVFilterFormats,        samplerates,     formats,
                    format_count, ff_add_format);
-    REDUCE_FORMATS(uint64_t, AVFilterChannelLayouts, channel_layouts,
-                   channel_layouts, nb_channel_layouts, ff_add_channel_layout);
+
+    /* reduce channel layouts */
+    for (i = 0; i < filter->nb_inputs; i++) {
+        AVFilterLink *inlink = filter->inputs[i];
+        uint64_t fmt;
+
+        if (!inlink->out_channel_layouts ||
+            inlink->out_channel_layouts->nb_channel_layouts != 1)
+            continue;
+        fmt = inlink->out_channel_layouts->channel_layouts[0];
+
+        for (j = 0; j < filter->nb_outputs; j++) {
+            AVFilterLink *outlink = filter->outputs[j];
+            AVFilterChannelLayouts *fmts;
+
+            fmts = outlink->in_channel_layouts;
+            if (inlink->type != outlink->type || fmts->nb_channel_layouts == 1)
+                continue;
+
+            if (fmts->all_layouts) {
+                /* Turn the infinite list into a singleton */
+                fmts->all_layouts = fmts->all_counts  = 0;
+                ff_add_channel_layout(&outlink->in_channel_layouts, fmt);
+                break;
+            }
+
+            for (k = 0; k < outlink->in_channel_layouts->nb_channel_layouts; k++) {
+                if (fmts->channel_layouts[k] == fmt) {
+                    fmts->channel_layouts[0]  = fmt;
+                    fmts->nb_channel_layouts = 1;
+                    ret = 1;
+                    break;
+                }
+            }
+        }
+    }
 
     return ret;
 }
@@ -657,7 +636,23 @@
             int out_channels      = av_get_channel_layout_nb_channels(out_chlayout);
             int count_diff        = out_channels - in_channels;
             int matched_channels, extra_channels;
-            int score = 0;
+            int score = 100000;
+
+            if (FF_LAYOUT2COUNT(in_chlayout) || FF_LAYOUT2COUNT(out_chlayout)) {
+                /* Compute score in case the input or output layout encodes
+                   a channel count; in this case the score is not altered by
+                   the computation afterwards, as in_chlayout and
+                   out_chlayout have both been set to 0 */
+                if (FF_LAYOUT2COUNT(in_chlayout))
+                    in_channels = FF_LAYOUT2COUNT(in_chlayout);
+                if (FF_LAYOUT2COUNT(out_chlayout))
+                    out_channels = FF_LAYOUT2COUNT(out_chlayout);
+                score -= 10000 + FFABS(out_channels - in_channels) +
+                         (in_channels > out_channels ? 10000 : 0);
+                in_chlayout = out_chlayout = 0;
+                /* Let the remaining computation run, even if the score
+                   value is not altered */
+            }
 
             /* channel substitution */
             for (k = 0; k < FF_ARRAY_ELEMS(ch_subst); k++) {
@@ -789,7 +784,8 @@
             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) {
-                        pick_format(filter->inputs[j], NULL);
+                        if ((ret = pick_format(filter->inputs[j], NULL)) < 0)
+                            return ret;
                         change = 1;
                     }
                 }
@@ -797,7 +793,8 @@
             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) {
-                        pick_format(filter->outputs[j], NULL);
+                        if ((ret = pick_format(filter->outputs[j], NULL)) < 0)
+                            return ret;
                         change = 1;
                     }
                 }
@@ -805,7 +802,8 @@
             if (filter->nb_inputs && filter->nb_outputs && filter->inputs[0]->format>=0) {
                 for (j = 0; j < filter->nb_outputs; j++) {
                     if(filter->outputs[j]->format<0) {
-                        pick_format(filter->outputs[j], filter->inputs[0]);
+                        if ((ret = pick_format(filter->outputs[j], filter->inputs[0])) < 0)
+                            return ret;
                         change = 1;
                     }
                 }
@@ -992,16 +990,16 @@
     for (i = 0; i < graph->filter_count; i++) {
         AVFilterContext *filter = graph->filters[i];
         if(filter && (!strcmp(target, "all") || !strcmp(target, filter->name) || !strcmp(target, filter->filter->name))){
-            AVFilterCommand **que = &filter->command_queue, *next;
-            while(*que && (*que)->time <= ts)
-                que = &(*que)->next;
-            next= *que;
-            *que= av_mallocz(sizeof(AVFilterCommand));
-            (*que)->command = av_strdup(command);
-            (*que)->arg     = av_strdup(arg);
-            (*que)->time    = ts;
-            (*que)->flags   = flags;
-            (*que)->next    = next;
+            AVFilterCommand **queue = &filter->command_queue, *next;
+            while (*queue && (*queue)->time <= ts)
+                queue = &(*queue)->next;
+            next = *queue;
+            *queue = av_mallocz(sizeof(AVFilterCommand));
+            (*queue)->command = av_strdup(command);
+            (*queue)->arg     = av_strdup(arg);
+            (*queue)->time    = ts;
+            (*queue)->flags   = flags;
+            (*queue)->next    = next;
             if(flags & AVFILTER_CMD_FLAG_ONE)
                 return 0;
         }
diff --git a/libavfilter/avfiltergraph.h b/libavfilter/avfiltergraph.h
index 728bbb5..3965412 100644
--- a/libavfilter/avfiltergraph.h
+++ b/libavfilter/avfiltergraph.h
@@ -31,7 +31,7 @@
     AVFilterContext **filters;
 
     char *scale_sws_opts; ///< sws options to use for the auto-inserted scale filters
-
+    char *resample_lavr_opts;   ///< libavresample options to use for the auto-inserted resample filters
     char *aresample_swr_opts; ///< swr options to use for the auto-inserted aresample filters, Access ONLY through AVOptions
 
     /**
diff --git a/libavfilter/buffer.c b/libavfilter/buffer.c
index a8155ef..9a3f131 100644
--- a/libavfilter/buffer.c
+++ b/libavfilter/buffer.c
@@ -230,7 +230,7 @@
                                         ref->audio->nb_samples);
         if(!buf)
             return NULL;
-        channels = av_get_channel_layout_nb_channels(ref->audio->channel_layout);
+        channels = ref->audio->channels;
         av_samples_copy(buf->extended_data, ref->buf->extended_data,
                         0, 0, ref->audio->nb_samples,
                         channels,
diff --git a/libavfilter/bufferqueue.h b/libavfilter/bufferqueue.h
index a27fb86..34c4c0f 100644
--- a/libavfilter/bufferqueue.h
+++ b/libavfilter/bufferqueue.h
@@ -55,6 +55,14 @@
 #define BUCKET(i) queue->queue[(queue->head + (i)) % FF_BUFQUEUE_SIZE]
 
 /**
+ * Test if a buffer queue is full.
+ */
+static inline int ff_bufqueue_is_full(struct FFBufQueue *queue)
+{
+    return queue->available == FF_BUFQUEUE_SIZE;
+}
+
+/**
  * Add a buffer to the queue.
  *
  * If the queue is already full, then the current last buffer is dropped
@@ -63,7 +71,7 @@
 static inline void ff_bufqueue_add(void *log, struct FFBufQueue *queue,
                                    AVFilterBufferRef *buf)
 {
-    if (queue->available == FF_BUFQUEUE_SIZE) {
+    if (ff_bufqueue_is_full(queue)) {
         av_log(log, AV_LOG_WARNING, "Buffer queue overflow, dropping.\n");
         avfilter_unref_buffer(BUCKET(--queue->available));
     }
diff --git a/libavfilter/buffersink.h b/libavfilter/buffersink.h
index a401937..6f8ac5c 100644
--- a/libavfilter/buffersink.h
+++ b/libavfilter/buffersink.h
@@ -46,6 +46,9 @@
 typedef struct {
     const enum AVSampleFormat *sample_fmts; ///< list of allowed sample formats, terminated by AV_SAMPLE_FMT_NONE
     const int64_t *channel_layouts;         ///< list of allowed channel layouts, terminated by -1
+    const int *channel_counts;              ///< list of allowed channel counts, terminated by -1
+    int all_channel_counts;                 ///< if not 0, accept any channel count or layout
+    int *sample_rates;                      ///< list of allowed sample rates, terminated by -1
 } AVABufferSinkParams;
 
 /**
diff --git a/libavfilter/buffersrc.c b/libavfilter/buffersrc.c
index 7949098..d150357 100644
--- a/libavfilter/buffersrc.c
+++ b/libavfilter/buffersrc.c
@@ -55,6 +55,7 @@
     int sample_rate;
     enum AVSampleFormat sample_fmt;
     char               *sample_fmt_str;
+    int channels;
     uint64_t channel_layout;
     char    *channel_layout_str;
 
@@ -120,6 +121,8 @@
             CHECK_VIDEO_PARAM_CHANGE(s, c, buf->video->w, buf->video->h, buf->format);
             break;
         case AVMEDIA_TYPE_AUDIO:
+            if (!buf->audio->channel_layout)
+                buf->audio->channel_layout = c->channel_layout;
             CHECK_AUDIO_PARAM_CHANGE(s, c, buf->audio->sample_rate, buf->audio->channel_layout,
                                      buf->format);
             break;
@@ -240,6 +243,7 @@
     { "time_base",      NULL, OFFSET(time_base),           AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, 0, INT_MAX, FLAGS },
     { "sample_rate",    NULL, OFFSET(sample_rate),         AV_OPT_TYPE_INT,      { .i64 = 0 }, 0, INT_MAX, FLAGS },
     { "sample_fmt",     NULL, OFFSET(sample_fmt_str),      AV_OPT_TYPE_STRING, .flags = FLAGS },
+    { "channels",       NULL, OFFSET(channels),            AV_OPT_TYPE_INT,      { .i64 = 0 }, 0, INT_MAX, FLAGS },
     { "channel_layout", NULL, OFFSET(channel_layout_str),  AV_OPT_TYPE_STRING, .flags = FLAGS },
     { NULL },
 };
@@ -265,6 +269,9 @@
         goto fail;
     }
 
+    if (s->channel_layout_str) {
+        int n;
+        /* TODO reindent */
     s->channel_layout = av_get_channel_layout(s->channel_layout_str);
     if (!s->channel_layout) {
         av_log(ctx, AV_LOG_ERROR, "Invalid channel layout '%s'\n",
@@ -272,6 +279,24 @@
         ret = AVERROR(EINVAL);
         goto fail;
     }
+        n = av_get_channel_layout_nb_channels(s->channel_layout);
+        if (s->channels) {
+            if (n != s->channels) {
+                av_log(ctx, AV_LOG_ERROR,
+                       "Mismatching channel count %d and layout '%s' "
+                       "(%d channels)\n",
+                       s->channels, s->channel_layout_str, n);
+                ret = AVERROR(EINVAL);
+                goto fail;
+            }
+        }
+        s->channels = n;
+    } else if (!s->channels) {
+        av_log(ctx, AV_LOG_ERROR, "Neither number of channels nor "
+                                  "channel layout specified\n");
+        ret = AVERROR(EINVAL);
+        goto fail;
+    }
 
     if (!(s->fifo = av_fifo_alloc(sizeof(AVFilterBufferRef*)))) {
         ret = AVERROR(ENOMEM);
@@ -324,7 +349,9 @@
         ff_add_format(&samplerates,       c->sample_rate);
         ff_set_common_samplerates(ctx, samplerates);
 
-        ff_add_channel_layout(&channel_layouts, c->channel_layout);
+        ff_add_channel_layout(&channel_layouts,
+                              c->channel_layout ? c->channel_layout :
+                              FF_COUNT2LAYOUT(c->channels));
         ff_set_common_channel_layouts(ctx, channel_layouts);
         break;
     default:
@@ -345,8 +372,8 @@
         link->sample_aspect_ratio = c->pixel_aspect;
         break;
     case AVMEDIA_TYPE_AUDIO:
-        link->channel_layout = c->channel_layout;
-        link->sample_rate    = c->sample_rate;
+        if (!c->channel_layout)
+            c->channel_layout = link->channel_layout;
         break;
     default:
         return AVERROR(EINVAL);
@@ -361,7 +388,6 @@
 {
     BufferSourceContext *c = link->src->priv;
     AVFilterBufferRef *buf;
-    int ret = 0;
 
     if (!av_fifo_size(c->fifo)) {
         if (c->eof)
@@ -371,9 +397,7 @@
     }
     av_fifo_generic_read(c->fifo, &buf, sizeof(buf), NULL);
 
-    ff_filter_frame(link, buf);
-
-    return ret;
+    return ff_filter_frame(link, buf);
 }
 
 static int poll_frame(AVFilterLink *link)
diff --git a/libavfilter/drawutils.c b/libavfilter/drawutils.c
index aefd09d..aebc000 100644
--- a/libavfilter/drawutils.c
+++ b/libavfilter/drawutils.c
@@ -313,7 +313,6 @@
     unsigned tau = 0x1010101 - alpha;
     int x;
 
-    src *= alpha;
     if (left) {
         unsigned suba = (left * alpha) >> hsub;
         *dst = (*dst * (0x1010101 - suba) + src * suba) >> 24;
diff --git a/libavfilter/drawutils.h b/libavfilter/drawutils.h
index df41695..5ffffe7 100644
--- a/libavfilter/drawutils.h
+++ b/libavfilter/drawutils.h
@@ -51,8 +51,8 @@
     unsigned nb_planes;
     int pixelstep[MAX_PLANES]; /*< offset between pixels */
     uint8_t comp_mask[MAX_PLANES]; /*< bitmask of used non-alpha components */
-    uint8_t hsub[MAX_PLANES];  /*< horizontal subsamling */
-    uint8_t vsub[MAX_PLANES];  /*< vertical subsamling */
+    uint8_t hsub[MAX_PLANES];  /*< horizontal subsampling */
+    uint8_t vsub[MAX_PLANES];  /*< vertical subsampling */
     uint8_t hsub_max;
     uint8_t vsub_max;
 } FFDrawContext;
diff --git a/libavfilter/f_ebur128.c b/libavfilter/f_ebur128.c
index f9da80d..66cc133 100644
--- a/libavfilter/f_ebur128.c
+++ b/libavfilter/f_ebur128.c
@@ -314,12 +314,15 @@
 static int config_audio_output(AVFilterLink *outlink)
 {
     int i;
+    int idx_bitposn = 0;
     AVFilterContext *ctx = outlink->src;
     EBUR128Context *ebur128 = ctx->priv;
     const int nb_channels = av_get_channel_layout_nb_channels(outlink->channel_layout);
 
 #define BACK_MASK (AV_CH_BACK_LEFT    |AV_CH_BACK_CENTER    |AV_CH_BACK_RIGHT| \
-                   AV_CH_TOP_BACK_LEFT|AV_CH_TOP_BACK_CENTER|AV_CH_TOP_BACK_RIGHT)
+                   AV_CH_TOP_BACK_LEFT|AV_CH_TOP_BACK_CENTER|AV_CH_TOP_BACK_RIGHT| \
+                   AV_CH_SIDE_LEFT                          |AV_CH_SIDE_RIGHT| \
+                   AV_CH_SURROUND_DIRECT_LEFT               |AV_CH_SURROUND_DIRECT_RIGHT)
 
     ebur128->nb_channels  = nb_channels;
     ebur128->ch_weighting = av_calloc(nb_channels, sizeof(*ebur128->ch_weighting));
@@ -328,13 +331,24 @@
 
     for (i = 0; i < nb_channels; i++) {
 
+        /* find the next bit that is set starting from the right */
+        while ((outlink->channel_layout & 1ULL<<idx_bitposn) == 0 && idx_bitposn < 63)
+            idx_bitposn++;
+
         /* channel weighting */
-        if ((outlink->channel_layout & 1ULL<<i) == AV_CH_LOW_FREQUENCY)
-            continue;
-        if (outlink->channel_layout & 1ULL<<i & BACK_MASK)
+        if ((1ULL<<idx_bitposn & AV_CH_LOW_FREQUENCY) ||
+            (1ULL<<idx_bitposn & AV_CH_LOW_FREQUENCY_2)) {
+            ebur128->ch_weighting[i] = 0;
+        } else if (1ULL<<idx_bitposn & BACK_MASK) {
             ebur128->ch_weighting[i] = 1.41;
-        else
+        } else {
             ebur128->ch_weighting[i] = 1.0;
+        }
+
+        idx_bitposn++;
+
+        if (!ebur128->ch_weighting[i])
+            continue;
 
         /* bins buffer for the two integration window (400ms and 3s) */
         ebur128->i400.cache[i]  = av_calloc(I400_BINS,  sizeof(*ebur128->i400.cache[0]));
@@ -438,7 +452,7 @@
 
 static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *insamples)
 {
-    int i, ch;
+    int i, ch, idx_insample;
     AVFilterContext *ctx = inlink->dst;
     EBUR128Context *ebur128 = ctx->priv;
     const int nb_channels = ebur128->nb_channels;
@@ -446,7 +460,7 @@
     const double *samples = (double *)insamples->data[0];
     AVFilterBufferRef *pic = ebur128->outpicref;
 
-    for (i = 0; i < nb_samples; i++) {
+    for (idx_insample = 0; idx_insample < nb_samples; idx_insample++) {
         const int bin_id_400  = ebur128->i400.cache_pos;
         const int bin_id_3000 = ebur128->i3000.cache_pos;
 
@@ -464,6 +478,8 @@
         for (ch = 0; ch < nb_channels; ch++) {
             double bin;
 
+            ebur128->x[ch * 3] = *samples++; // set X[i]
+
             if (!ebur128->ch_weighting[ch])
                 continue;
 
@@ -477,8 +493,6 @@
                                       - dst[1]*name##_A1 - dst[2]*name##_A2;    \
 } while (0)
 
-            ebur128->x[ch * 3] = *samples++; // set X[i]
-
             // TODO: merge both filters in one?
             FILTER(y, x, PRE);  // apply pre-filter
             ebur128->x[ch * 3 + 2] = ebur128->x[ch * 3 + 1];
@@ -505,7 +519,7 @@
             double power_400 = 1e-12, power_3000 = 1e-12;
             AVFilterLink *outlink = ctx->outputs[0];
             const int64_t pts = insamples->pts +
-                av_rescale_q(i, (AVRational){ 1, inlink->sample_rate },
+                av_rescale_q(idx_insample, (AVRational){ 1, inlink->sample_rate },
                              outlink->time_base);
 
             ebur128->sample_count = 0;
diff --git a/libavfilter/vf_select.c b/libavfilter/f_select.c
similarity index 61%
rename from libavfilter/vf_select.c
rename to libavfilter/f_select.c
index e0e1863..0f21145 100644
--- a/libavfilter/vf_select.c
+++ b/libavfilter/f_select.c
@@ -26,7 +26,9 @@
 #include "libavutil/eval.h"
 #include "libavutil/fifo.h"
 #include "libavutil/internal.h"
+#include "libavutil/opt.h"
 #include "avfilter.h"
+#include "audio.h"
 #include "formats.h"
 #include "internal.h"
 #include "video.h"
@@ -62,6 +64,10 @@
     "TOPFIRST",
     "BOTTOMFIRST",
 
+    "consumed_samples_n",///< number of samples consumed by the filter (only audio)
+    "samples_n",         ///< number of samples in the current frame (only audio)
+    "sample_rate",       ///< sample rate (only audio)
+
     "n",                 ///< frame number (starting from zero)
     "selected_n",        ///< selected frame number (starting from zero)
     "prev_selected_n",   ///< number of the last selected frame
@@ -101,6 +107,10 @@
     VAR_INTERLACE_TYPE_T,
     VAR_INTERLACE_TYPE_B,
 
+    VAR_CONSUMED_SAMPLES_N,
+    VAR_SAMPLES_N,
+    VAR_SAMPLE_RATE,
+
     VAR_N,
     VAR_SELECTED_N,
     VAR_PREV_SELECTED_N,
@@ -113,10 +123,10 @@
     VAR_VARS_NB
 };
 
-#define FIFO_SIZE 8
-
 typedef struct {
+    const AVClass *class;
     AVExpr *expr;
+    char *expr_str;
     double var_values[VAR_VARS_NB];
     int do_scene_detect;            ///< 1 if the expression requires scene detection variables, 0 otherwise
 #if CONFIG_AVCODEC
@@ -126,32 +136,35 @@
 #endif
     AVFilterBufferRef *prev_picref; ///< previous frame                            (scene detect only)
     double select;
-    int cache_frames;
-    AVFifoBuffer *pending_frames; ///< FIFO buffer of video frames
 } SelectContext;
 
-static av_cold int init(AVFilterContext *ctx, const char *args)
+#define OFFSET(x) offsetof(SelectContext, x)
+#define FLAGS AV_OPT_FLAG_FILTERING_PARAM
+static const AVOption options[] = {
+    { "expr", "set selection expression", OFFSET(expr_str), AV_OPT_TYPE_STRING, {.str = "1"}, 0, 0, FLAGS },
+    { "e",    "set selection expression", OFFSET(expr_str), AV_OPT_TYPE_STRING, {.str = "1"}, 0, 0, FLAGS },
+    {NULL},
+};
+
+static av_cold int init(AVFilterContext *ctx, const char *args, const AVClass *class)
 {
     SelectContext *select = ctx->priv;
+    const char *shorthand[] = { "expr", NULL };
     int ret;
 
-    if ((ret = av_expr_parse(&select->expr, args ? args : "1",
+    select->class = class;
+    av_opt_set_defaults(select);
+
+    if ((ret = av_opt_set_from_string(select, args, shorthand, "=", ":")) < 0)
+        return ret;
+
+    if ((ret = av_expr_parse(&select->expr, select->expr_str,
                              var_names, NULL, NULL, NULL, NULL, 0, ctx)) < 0) {
-        av_log(ctx, AV_LOG_ERROR, "Error while parsing expression '%s'\n", args);
+        av_log(ctx, AV_LOG_ERROR, "Error while parsing expression '%s'\n", select->expr_str);
         return ret;
     }
+    select->do_scene_detect = !!strstr(select->expr_str, "scene");
 
-    select->pending_frames = av_fifo_alloc(FIFO_SIZE*sizeof(AVFilterBufferRef*));
-    if (!select->pending_frames) {
-        av_log(ctx, AV_LOG_ERROR, "Failed to allocate pending frames buffer.\n");
-        return AVERROR(ENOMEM);
-    }
-
-    select->do_scene_detect = args && strstr(args, "scene");
-    if (select->do_scene_detect && !CONFIG_AVCODEC) {
-        av_log(ctx, AV_LOG_ERROR, "Scene detection is not available without libavcodec.\n");
-        return AVERROR(EINVAL);
-    }
     return 0;
 }
 
@@ -171,6 +184,7 @@
     select->var_values[VAR_PREV_PTS]          = NAN;
     select->var_values[VAR_PREV_SELECTED_PTS] = NAN;
     select->var_values[VAR_PREV_SELECTED_T]   = NAN;
+    select->var_values[VAR_PREV_T]            = NAN;
     select->var_values[VAR_START_PTS]         = NAN;
     select->var_values[VAR_START_T]           = NAN;
 
@@ -184,12 +198,23 @@
     select->var_values[VAR_INTERLACE_TYPE_T] = INTERLACE_TYPE_T;
     select->var_values[VAR_INTERLACE_TYPE_B] = INTERLACE_TYPE_B;
 
-    if (CONFIG_AVCODEC && select->do_scene_detect) {
+    select->var_values[VAR_PICT_TYPE]         = NAN;
+    select->var_values[VAR_INTERLACE_TYPE]    = NAN;
+    select->var_values[VAR_SCENE]             = NAN;
+    select->var_values[VAR_CONSUMED_SAMPLES_N] = NAN;
+    select->var_values[VAR_SAMPLES_N]          = NAN;
+
+    select->var_values[VAR_SAMPLE_RATE] =
+        inlink->type == AVMEDIA_TYPE_AUDIO ? inlink->sample_rate : NAN;
+
+#if CONFIG_AVCODEC
+    if (select->do_scene_detect) {
         select->avctx = avcodec_alloc_context3(NULL);
         if (!select->avctx)
             return AVERROR(ENOMEM);
         dsputil_init(&select->c, select->avctx);
     }
+#endif
     return 0;
 }
 
@@ -235,57 +260,83 @@
 #define D2TS(d)  (isnan(d) ? AV_NOPTS_VALUE : (int64_t)(d))
 #define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts))
 
-static int select_frame(AVFilterContext *ctx, AVFilterBufferRef *picref)
+static int select_frame(AVFilterContext *ctx, AVFilterBufferRef *ref)
 {
     SelectContext *select = ctx->priv;
     AVFilterLink *inlink = ctx->inputs[0];
     double res;
 
-    if (CONFIG_AVCODEC && select->do_scene_detect) {
-        char buf[32];
-        select->var_values[VAR_SCENE] = get_scene_score(ctx, picref);
-        // TODO: document metadata
-        snprintf(buf, sizeof(buf), "%f", select->var_values[VAR_SCENE]);
-        av_dict_set(&picref->metadata, "lavfi.scene_score", buf, 0);
-    }
     if (isnan(select->var_values[VAR_START_PTS]))
-        select->var_values[VAR_START_PTS] = TS2D(picref->pts);
+        select->var_values[VAR_START_PTS] = TS2D(ref->pts);
     if (isnan(select->var_values[VAR_START_T]))
-        select->var_values[VAR_START_T] = TS2D(picref->pts) * av_q2d(inlink->time_base);
+        select->var_values[VAR_START_T] = TS2D(ref->pts) * av_q2d(inlink->time_base);
 
-    select->var_values[VAR_PTS] = TS2D(picref->pts);
-    select->var_values[VAR_T  ] = TS2D(picref->pts) * av_q2d(inlink->time_base);
-    select->var_values[VAR_POS] = picref->pos == -1 ? NAN : picref->pos;
-    select->var_values[VAR_PREV_PTS] = TS2D(picref ->pts);
+    select->var_values[VAR_PTS] = TS2D(ref->pts);
+    select->var_values[VAR_T  ] = TS2D(ref->pts) * av_q2d(inlink->time_base);
+    select->var_values[VAR_POS] = ref->pos == -1 ? NAN : ref->pos;
 
-    select->var_values[VAR_INTERLACE_TYPE] =
-        !picref->video->interlaced     ? INTERLACE_TYPE_P :
-        picref->video->top_field_first ? INTERLACE_TYPE_T : INTERLACE_TYPE_B;
-    select->var_values[VAR_PICT_TYPE] = picref->video->pict_type;
+    switch (inlink->type) {
+    case AVMEDIA_TYPE_AUDIO:
+        select->var_values[VAR_SAMPLES_N] = ref->audio->nb_samples;
+        break;
+
+    case AVMEDIA_TYPE_VIDEO:
+        select->var_values[VAR_INTERLACE_TYPE] =
+            !ref->video->interlaced ? INTERLACE_TYPE_P :
+        ref->video->top_field_first ? INTERLACE_TYPE_T : INTERLACE_TYPE_B;
+        select->var_values[VAR_PICT_TYPE] = ref->video->pict_type;
+#if CONFIG_AVCODEC
+        if (select->do_scene_detect) {
+            char buf[32];
+            select->var_values[VAR_SCENE] = get_scene_score(ctx, ref);
+            // TODO: document metadata
+            snprintf(buf, sizeof(buf), "%f", select->var_values[VAR_SCENE]);
+            av_dict_set(&ref->metadata, "lavfi.scene_score", buf, 0);
+        }
+#endif
+        break;
+    }
 
     res = av_expr_eval(select->expr, select->var_values, NULL);
     av_log(inlink->dst, AV_LOG_DEBUG,
-           "n:%d pts:%d t:%f pos:%d interlace_type:%c key:%d pict_type:%c "
-           "-> select:%f\n",
-           (int)select->var_values[VAR_N],
-           (int)select->var_values[VAR_PTS],
+           "n:%f pts:%f t:%f pos:%f key:%d",
+           select->var_values[VAR_N],
+           select->var_values[VAR_PTS],
            select->var_values[VAR_T],
-           (int)select->var_values[VAR_POS],
-           select->var_values[VAR_INTERLACE_TYPE] == INTERLACE_TYPE_P ? 'P' :
-           select->var_values[VAR_INTERLACE_TYPE] == INTERLACE_TYPE_T ? 'T' :
-           select->var_values[VAR_INTERLACE_TYPE] == INTERLACE_TYPE_B ? 'B' : '?',
-           (int)select->var_values[VAR_KEY],
-           av_get_picture_type_char(select->var_values[VAR_PICT_TYPE]),
-           res);
+           select->var_values[VAR_POS],
+           (int)select->var_values[VAR_KEY]);
 
-    select->var_values[VAR_N] += 1.0;
+    switch (inlink->type) {
+    case AVMEDIA_TYPE_VIDEO:
+        av_log(inlink->dst, AV_LOG_DEBUG, " interlace_type:%c pict_type:%c scene:%f",
+               select->var_values[VAR_INTERLACE_TYPE] == INTERLACE_TYPE_P ? 'P' :
+               select->var_values[VAR_INTERLACE_TYPE] == INTERLACE_TYPE_T ? 'T' :
+               select->var_values[VAR_INTERLACE_TYPE] == INTERLACE_TYPE_B ? 'B' : '?',
+               av_get_picture_type_char(select->var_values[VAR_PICT_TYPE]),
+               select->var_values[VAR_SCENE]);
+        break;
+    case AVMEDIA_TYPE_AUDIO:
+        av_log(inlink->dst, AV_LOG_DEBUG, " samples_n:%d consumed_samples_n:%d",
+               (int)select->var_values[VAR_SAMPLES_N],
+               (int)select->var_values[VAR_CONSUMED_SAMPLES_N]);
+        break;
+    }
+
+    av_log(inlink->dst, AV_LOG_DEBUG, " -> select:%f\n", res);
 
     if (res) {
         select->var_values[VAR_PREV_SELECTED_N]   = select->var_values[VAR_N];
         select->var_values[VAR_PREV_SELECTED_PTS] = select->var_values[VAR_PTS];
         select->var_values[VAR_PREV_SELECTED_T]   = select->var_values[VAR_T];
         select->var_values[VAR_SELECTED_N] += 1.0;
+        if (inlink->type == AVMEDIA_TYPE_AUDIO)
+            select->var_values[VAR_CONSUMED_SAMPLES_N] += ref->audio->nb_samples;
     }
+
+    select->var_values[VAR_N] += 1.0;
+    select->var_values[VAR_PREV_PTS] = select->var_values[VAR_PTS];
+    select->var_values[VAR_PREV_T]   = select->var_values[VAR_T];
+
     return res;
 }
 
@@ -294,20 +345,8 @@
     SelectContext *select = inlink->dst->priv;
 
     select->select = select_frame(inlink->dst, frame);
-    if (select->select) {
-        /* frame was requested through poll_frame */
-        if (select->cache_frames) {
-            if (!av_fifo_space(select->pending_frames)) {
-                av_log(inlink->dst, AV_LOG_ERROR,
-                       "Buffering limit reached, cannot cache more frames\n");
-                avfilter_unref_bufferp(&frame);
-            } else
-                av_fifo_generic_write(select->pending_frames, &frame,
-                                      sizeof(frame), NULL);
-            return 0;
-        }
+    if (select->select)
         return ff_filter_frame(inlink->dst->outputs[0], frame);
-    }
 
     avfilter_unref_bufferp(&frame);
     return 0;
@@ -320,58 +359,24 @@
     AVFilterLink *inlink = outlink->src->inputs[0];
     select->select = 0;
 
-    if (av_fifo_size(select->pending_frames)) {
-        AVFilterBufferRef *picref;
-
-        av_fifo_generic_read(select->pending_frames, &picref, sizeof(picref), NULL);
-        return ff_filter_frame(outlink, picref);
-    }
-
-    while (!select->select) {
+    do {
         int ret = ff_request_frame(inlink);
         if (ret < 0)
             return ret;
-    }
+    } while (!select->select);
 
     return 0;
 }
 
-static int poll_frame(AVFilterLink *outlink)
-{
-    SelectContext *select = outlink->src->priv;
-    AVFilterLink *inlink = outlink->src->inputs[0];
-    int count, ret;
-
-    if (!av_fifo_size(select->pending_frames)) {
-        if ((count = ff_poll_frame(inlink)) <= 0)
-            return count;
-        /* request frame from input, and apply select condition to it */
-        select->cache_frames = 1;
-        while (count-- && av_fifo_space(select->pending_frames)) {
-            ret = ff_request_frame(inlink);
-            if (ret < 0)
-                break;
-        }
-        select->cache_frames = 0;
-    }
-
-    return av_fifo_size(select->pending_frames)/sizeof(AVFilterBufferRef *);
-}
-
 static av_cold void uninit(AVFilterContext *ctx)
 {
     SelectContext *select = ctx->priv;
-    AVFilterBufferRef *picref;
 
     av_expr_free(select->expr);
     select->expr = NULL;
+    av_opt_free(select);
 
-    while (select->pending_frames &&
-           av_fifo_generic_read(select->pending_frames, &picref, sizeof(picref), NULL) == sizeof(picref))
-        avfilter_unref_buffer(picref);
-    av_fifo_free(select->pending_frames);
-    select->pending_frames = NULL;
-
+#if CONFIG_AVCODEC
     if (select->do_scene_detect) {
         avfilter_unref_bufferp(&select->prev_picref);
         if (select->avctx) {
@@ -379,6 +384,7 @@
             av_freep(&select->avctx);
         }
     }
+#endif
 }
 
 static int query_formats(AVFilterContext *ctx)
@@ -397,6 +403,79 @@
     return 0;
 }
 
+#if CONFIG_ASELECT_FILTER
+
+#define aselect_options options
+AVFILTER_DEFINE_CLASS(aselect);
+
+static av_cold int aselect_init(AVFilterContext *ctx, const char *args)
+{
+    SelectContext *select = ctx->priv;
+    int ret;
+
+    if ((ret = init(ctx, args, &aselect_class)) < 0)
+        return ret;
+
+    if (select->do_scene_detect) {
+        av_log(ctx, AV_LOG_ERROR, "Scene detection is ignored in aselect filter\n");
+        return AVERROR(EINVAL);
+    }
+
+    return 0;
+}
+
+static const AVFilterPad avfilter_af_aselect_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_aselect_outputs[] = {
+    {
+        .name = "default",
+        .type = AVMEDIA_TYPE_AUDIO,
+    },
+    { NULL }
+};
+
+AVFilter avfilter_af_aselect = {
+    .name      = "aselect",
+    .description = NULL_IF_CONFIG_SMALL("Select audio frames to pass in output."),
+    .init      = aselect_init,
+    .uninit    = uninit,
+    .priv_size = sizeof(SelectContext),
+    .inputs    = avfilter_af_aselect_inputs,
+    .outputs   = avfilter_af_aselect_outputs,
+    .priv_class = &aselect_class,
+};
+#endif /* CONFIG_ASELECT_FILTER */
+
+#if CONFIG_SELECT_FILTER
+
+#define select_options options
+AVFILTER_DEFINE_CLASS(select);
+
+static av_cold int select_init(AVFilterContext *ctx, const char *args)
+{
+    SelectContext *select = ctx->priv;
+    int ret;
+
+    if ((ret = init(ctx, args, &select_class)) < 0)
+        return ret;
+
+    if (select->do_scene_detect && !CONFIG_AVCODEC) {
+        av_log(ctx, AV_LOG_ERROR, "Scene detection is not available without libavcodec.\n");
+        return AVERROR(EINVAL);
+    }
+
+    return 0;
+}
+
 static const AVFilterPad avfilter_vf_select_inputs[] = {
     {
         .name             = "default",
@@ -413,7 +492,6 @@
     {
         .name          = "default",
         .type          = AVMEDIA_TYPE_VIDEO,
-        .poll_frame    = poll_frame,
         .request_frame = request_frame,
     },
     { NULL }
@@ -421,8 +499,8 @@
 
 AVFilter avfilter_vf_select = {
     .name      = "select",
-    .description = NULL_IF_CONFIG_SMALL("Select frames to pass in output."),
-    .init      = init,
+    .description = NULL_IF_CONFIG_SMALL("Select video frames to pass in output."),
+    .init      = select_init,
     .uninit    = uninit,
     .query_formats = query_formats,
 
@@ -430,4 +508,6 @@
 
     .inputs    = avfilter_vf_select_inputs,
     .outputs   = avfilter_vf_select_outputs,
+    .priv_class = &select_class,
 };
+#endif /* CONFIG_SELECT_FILTER */
diff --git a/libavfilter/f_sendcmd.c b/libavfilter/f_sendcmd.c
index 790c8be..b5cf01c 100644
--- a/libavfilter/f_sendcmd.c
+++ b/libavfilter/f_sendcmd.c
@@ -448,7 +448,7 @@
     av_freep(&sendcmd->intervals);
 }
 
-static int process_frame(AVFilterLink *inlink, AVFilterBufferRef *ref)
+static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *ref)
 {
     AVFilterContext *ctx = inlink->dst;
     SendCmdContext *sendcmd = ctx->priv;
@@ -504,13 +504,12 @@
     }
 
 end:
-    /* give the reference away, do not store in cur_buf */
-    inlink->cur_buf = NULL;
-
     switch (inlink->type) {
-    case AVMEDIA_TYPE_VIDEO: return ff_start_frame   (inlink->dst->outputs[0], ref);
-    case AVMEDIA_TYPE_AUDIO: return ff_filter_frame(inlink->dst->outputs[0], ref);
+    case AVMEDIA_TYPE_VIDEO:
+    case AVMEDIA_TYPE_AUDIO:
+        return ff_filter_frame(inlink->dst->outputs[0], ref);
     }
+
     return AVERROR(ENOSYS);
 }
 
@@ -529,8 +528,7 @@
         .name             = "default",
         .type             = AVMEDIA_TYPE_VIDEO,
         .get_video_buffer = ff_null_get_video_buffer,
-        .start_frame      = process_frame,
-        .end_frame        = ff_null_end_frame,
+        .filter_frame     = filter_frame,
     },
     { NULL }
 };
@@ -572,7 +570,7 @@
         .name             = "default",
         .type             = AVMEDIA_TYPE_AUDIO,
         .get_audio_buffer = ff_null_get_audio_buffer,
-        .filter_frame     = process_frame,
+        .filter_frame     = filter_frame,
     },
     { NULL }
 };
diff --git a/libavfilter/f_setpts.c b/libavfilter/f_setpts.c
index e5636e2..1c2edb8 100644
--- a/libavfilter/f_setpts.c
+++ b/libavfilter/f_setpts.c
@@ -24,11 +24,10 @@
  * video presentation timestamp (PTS) modification filter
  */
 
-/* #define DEBUG */
-
 #include "libavutil/eval.h"
 #include "libavutil/internal.h"
 #include "libavutil/mathematics.h"
+#include "libavutil/time.h"
 #include "avfilter.h"
 #include "internal.h"
 #include "audio.h"
@@ -51,6 +50,8 @@
     "STARTT",      ///< time at start of movie
     "T",           ///< original time in the file of the frame
     "TB",          ///< timebase
+    "RTCTIME",     ///< wallclock (RTC) time in micro seconds
+    "RTCSTART",    ///< wallclock (RTC) time at the start of the movie in micro seconds
     NULL
 };
 
@@ -71,6 +72,8 @@
     VAR_STARTT,
     VAR_T,
     VAR_TB,
+    VAR_RTCTIME,
+    VAR_RTCSTART,
     VAR_VARS_NB
 };
 
@@ -105,6 +108,7 @@
 
     setpts->type = inlink->type;
     setpts->var_values[VAR_TB] = av_q2d(inlink->time_base);
+    setpts->var_values[VAR_RTCSTART] = av_gettime();
 
     setpts->var_values[VAR_SAMPLE_RATE] =
         setpts->type == AVMEDIA_TYPE_AUDIO ? inlink->sample_rate : NAN;
@@ -123,6 +127,17 @@
 #define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts))
 #define TS2T(ts, tb) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts)*av_q2d(tb))
 
+#define BUF_SIZE 64
+
+static inline char *double2int64str(char *buf, double v)
+{
+    if (isnan(v)) snprintf(buf, BUF_SIZE, "nan");
+    else          snprintf(buf, BUF_SIZE, "%"PRId64, (int64_t)v);
+    return buf;
+}
+
+#define d2istr(v) double2int64str((char[BUF_SIZE]){0}, v)
+
 static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
 {
     SetPTSContext *setpts = inlink->dst->priv;
@@ -136,6 +151,7 @@
     setpts->var_values[VAR_PTS       ] = TS2D(frame->pts);
     setpts->var_values[VAR_T         ] = TS2T(frame->pts, inlink->time_base);
     setpts->var_values[VAR_POS       ] = frame->pos == -1 ? NAN : frame->pos;
+    setpts->var_values[VAR_RTCTIME   ] = av_gettime();
 
     switch (inlink->type) {
     case AVMEDIA_TYPE_VIDEO:
@@ -148,26 +164,32 @@
     }
 
     d = av_expr_eval(setpts->expr, setpts->var_values, NULL);
+
+    av_log(inlink->dst, AV_LOG_DEBUG,
+           "N:%"PRId64" PTS:%s T:%f POS:%s",
+           (int64_t)setpts->var_values[VAR_N],
+           d2istr(setpts->var_values[VAR_PTS]),
+           setpts->var_values[VAR_T],
+           d2istr(setpts->var_values[VAR_POS]));
+    switch (inlink->type) {
+    case AVMEDIA_TYPE_VIDEO:
+        av_log(inlink->dst, AV_LOG_DEBUG, " INTERLACED:%"PRId64,
+               (int64_t)setpts->var_values[VAR_INTERLACED]);
+        break;
+    case AVMEDIA_TYPE_AUDIO:
+        av_log(inlink->dst, AV_LOG_DEBUG, " NB_SAMPLES:%"PRId64" NB_CONSUMED_SAMPLES:%"PRId64,
+               (int64_t)setpts->var_values[VAR_NB_SAMPLES],
+               (int64_t)setpts->var_values[VAR_NB_CONSUMED_SAMPLES]);
+        break;
+    }
+    av_log(inlink->dst, AV_LOG_DEBUG, " -> PTS:%s T:%f\n", d2istr(d), TS2T(d, inlink->time_base));
+
     frame->pts = D2TS(d);
 
     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);
-
-    av_dlog(inlink->dst,
-            "n:%"PRId64" interlaced:%d nb_samples:%d nb_consumed_samples:%d "
-            "pos:%"PRId64" pts:%"PRId64" t:%f -> pts:%"PRId64" t:%f\n",
-            (int64_t)setpts->var_values[VAR_N],
-            (int)setpts->var_values[VAR_INTERLACED],
-            (int)setpts->var_values[VAR_NB_SAMPLES],
-            (int)setpts->var_values[VAR_NB_CONSUMED_SAMPLES],
-            (int64_t)setpts->var_values[VAR_POS],
-            (int64_t)setpts->var_values[VAR_PREV_INPTS],
-            setpts->var_values[VAR_PREV_INT],
-            (int64_t)setpts->var_values[VAR_PREV_OUTPTS],
-            setpts->var_values[VAR_PREV_OUTT]);
-
     setpts->var_values[VAR_N] += 1.0;
     if (setpts->type == AVMEDIA_TYPE_AUDIO) {
         setpts->var_values[VAR_NB_CONSUMED_SAMPLES] += frame->audio->nb_samples;
diff --git a/libavfilter/filtfmts.c b/libavfilter/filtfmts.c
index 14417cb..7286729 100644
--- a/libavfilter/filtfmts.c
+++ b/libavfilter/filtfmts.c
@@ -26,9 +26,6 @@
 #include "libavfilter/avfilter.h"
 #include "libavfilter/formats.h"
 
-#undef fprintf
-#undef printf
-
 static void print_formats(AVFilterContext *filter_ctx)
 {
     int i, j;
diff --git a/libavfilter/formats.c b/libavfilter/formats.c
index ea9a184..43718e4 100644
--- a/libavfilter/formats.c
+++ b/libavfilter/formats.c
@@ -19,6 +19,7 @@
  * 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/eval.h"
@@ -28,6 +29,8 @@
 #include "internal.h"
 #include "formats.h"
 
+#define KNOWN(l) (!FF_LAYOUT2COUNT(l)) /* for readability */
+
 /**
  * Add all refs from a to ret and destroy a.
  */
@@ -86,13 +89,41 @@
     MERGE_REF(ret, b, fmts, type, fail);                                        \
 } while (0)
 
-AVFilterFormats *ff_merge_formats(AVFilterFormats *a, AVFilterFormats *b)
+AVFilterFormats *ff_merge_formats(AVFilterFormats *a, AVFilterFormats *b,
+                                  enum AVMediaType type)
 {
     AVFilterFormats *ret = NULL;
+    int i, j;
+    int alpha1=0, alpha2=0;
+    int chroma1=0, chroma2=0;
 
     if (a == b)
         return a;
 
+    /* Do not lose chroma or alpha in merging.
+       It happens if both lists have formats with chroma (resp. alpha), but
+       the only formats in common do not have it (e.g. YUV+gray vs.
+       RGB+gray): in that case, the merging would select the gray format,
+       possibly causing a lossy conversion elsewhere in the graph.
+       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++) {
+                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;
+                chroma2|= adesc->nb_components > 1 && bdesc->nb_components > 1;
+                if (a->formats[i] == b->formats[j]) {
+                    alpha1 |= adesc->flags & PIX_FMT_ALPHA;
+                    chroma1|= adesc->nb_components > 1;
+                }
+            }
+
+    // If chroma or alpha can be lost through merging then do not merge
+    if (alpha2 > alpha1 || chroma2 > chroma1)
+        return NULL;
+
     MERGE_FORMATS(ret, a, b, formats, format_count, AVFilterFormats, fail);
 
     return ret;
@@ -136,21 +167,77 @@
                                                  AVFilterChannelLayouts *b)
 {
     AVFilterChannelLayouts *ret = NULL;
+    unsigned a_all = a->all_layouts + a->all_counts;
+    unsigned b_all = b->all_layouts + b->all_counts;
+    int ret_max, ret_nb = 0, i, j, round;
 
     if (a == b) return a;
 
-    if (a->nb_channel_layouts && b->nb_channel_layouts) {
-        MERGE_FORMATS(ret, a, b, channel_layouts, nb_channel_layouts,
-                      AVFilterChannelLayouts, fail);
-    } else if (a->nb_channel_layouts) {
-        MERGE_REF(a, b, channel_layouts, AVFilterChannelLayouts, fail);
-        ret = a;
-    } else {
+    /* Put the most generic set in a, to avoid doing everything twice */
+    if (a_all < b_all) {
+        FFSWAP(AVFilterChannelLayouts *, a, b);
+        FFSWAP(unsigned, a_all, b_all);
+    }
+    if (a_all) {
+        if (a_all == 1 && !b_all) {
+            /* keep only known layouts in b; works also for b_all = 1 */
+            for (i = j = 0; i < b->nb_channel_layouts; i++)
+                if (KNOWN(b->channel_layouts[i]))
+                    b->channel_layouts[j++] = b->channel_layouts[i];
+            b->nb_channel_layouts = j;
+        }
         MERGE_REF(b, a, channel_layouts, AVFilterChannelLayouts, fail);
-        ret = b;
+        return b;
     }
 
+    ret_max = a->nb_channel_layouts + b->nb_channel_layouts;
+    if (!(ret = av_mallocz(sizeof(*ret))) ||
+        !(ret->channel_layouts = av_malloc(sizeof(*ret->channel_layouts) *
+                                           ret_max)))
+        goto fail;
+
+    /* a[known] intersect b[known] */
+    for (i = 0; i < a->nb_channel_layouts; i++) {
+        if (!KNOWN(a->channel_layouts[i]))
+            continue;
+        for (j = 0; j < b->nb_channel_layouts; j++) {
+            if (a->channel_layouts[i] == b->channel_layouts[j]) {
+                ret->channel_layouts[ret_nb++] = a->channel_layouts[i];
+                a->channel_layouts[i] = b->channel_layouts[j] = 0;
+            }
+        }
+    }
+    /* 1st round: a[known] intersect b[generic]
+       2nd round: a[generic] intersect b[known] */
+    for (round = 0; round < 2; round++) {
+        for (i = 0; i < a->nb_channel_layouts; i++) {
+            uint64_t fmt = a->channel_layouts[i], bfmt;
+            if (!fmt || !KNOWN(fmt))
+                continue;
+            bfmt = FF_COUNT2LAYOUT(av_get_channel_layout_nb_channels(fmt));
+            for (j = 0; j < b->nb_channel_layouts; j++)
+                if (b->channel_layouts[j] == bfmt)
+                    ret->channel_layouts[ret_nb++] = a->channel_layouts[i];
+        }
+        /* 1st round: swap to prepare 2nd round; 2nd round: put it back */
+        FFSWAP(AVFilterChannelLayouts *, a, b);
+    }
+    /* a[generic] intersect b[generic] */
+    for (i = 0; i < a->nb_channel_layouts; i++) {
+        if (KNOWN(a->channel_layouts[i]))
+            continue;
+        for (j = 0; j < b->nb_channel_layouts; j++)
+            if (a->channel_layouts[i] == b->channel_layouts[j])
+                ret->channel_layouts[ret_nb++] = a->channel_layouts[i];
+    }
+
+    ret->nb_channel_layouts = ret_nb;
+    if (!ret->nb_channel_layouts)
+        goto fail;
+    MERGE_REF(ret, a, channel_layouts, AVFilterChannelLayouts, fail);
+    MERGE_REF(ret, b, channel_layouts, AVFilterChannelLayouts, fail);
     return ret;
+
 fail:
     if (ret) {
         av_freep(&ret->refs);
@@ -248,17 +335,19 @@
                                                             \
     (*f)->list = fmts;                                      \
     (*f)->list[(*f)->nb++] = fmt;                           \
-    return 0;                                               \
 } while (0)
 
 int ff_add_format(AVFilterFormats **avff, int64_t fmt)
 {
     ADD_FORMAT(avff, fmt, int, formats, format_count);
+    return 0;
 }
 
 int ff_add_channel_layout(AVFilterChannelLayouts **l, uint64_t channel_layout)
 {
+    av_assert1(!(*l && (*l)->all_layouts));
     ADD_FORMAT(l, channel_layout, uint64_t, channel_layouts, nb_channel_layouts);
+    return 0;
 }
 
 AVFilterFormats *ff_all_formats(enum AVMediaType type)
@@ -309,6 +398,18 @@
 AVFilterChannelLayouts *ff_all_channel_layouts(void)
 {
     AVFilterChannelLayouts *ret = av_mallocz(sizeof(*ret));
+    if (!ret)
+        return NULL;
+    ret->all_layouts = 1;
+    return ret;
+}
+
+AVFilterChannelLayouts *ff_all_channel_counts(void)
+{
+    AVFilterChannelLayouts *ret = av_mallocz(sizeof(*ret));
+    if (!ret)
+        return NULL;
+    ret->all_layouts = ret->all_counts = 1;
     return ret;
 }
 
@@ -443,7 +544,8 @@
                        ff_formats_ref, formats);
 }
 
-int ff_default_query_formats(AVFilterContext *ctx)
+static int default_query_formats_common(AVFilterContext *ctx,
+                                        AVFilterChannelLayouts *(layouts)(void))
 {
     enum AVMediaType type = ctx->inputs  && ctx->inputs [0] ? ctx->inputs [0]->type :
                             ctx->outputs && ctx->outputs[0] ? ctx->outputs[0]->type :
@@ -451,13 +553,23 @@
 
     ff_set_common_formats(ctx, ff_all_formats(type));
     if (type == AVMEDIA_TYPE_AUDIO) {
-        ff_set_common_channel_layouts(ctx, ff_all_channel_layouts());
+        ff_set_common_channel_layouts(ctx, layouts());
         ff_set_common_samplerates(ctx, ff_all_samplerates());
     }
 
     return 0;
 }
 
+int ff_default_query_formats(AVFilterContext *ctx)
+{
+    return default_query_formats_common(ctx, ff_all_channel_layouts);
+}
+
+int ff_query_formats_all(AVFilterContext *ctx)
+{
+    return default_query_formats_common(ctx, ff_all_channel_counts);
+}
+
 /* internal functions for parsing audio format arguments */
 
 int ff_parse_pixel_format(enum AVPixelFormat *ret, const char *arg, void *log_ctx)
diff --git a/libavfilter/formats.h b/libavfilter/formats.h
index c5a4e3d..c06f6df 100644
--- a/libavfilter/formats.h
+++ b/libavfilter/formats.h
@@ -69,15 +69,46 @@
     struct AVFilterFormats ***refs; ///< references to this list
 };
 
+/**
+ * A list of supported channel layouts.
+ *
+ * The list works the same as AVFilterFormats, except for the following
+ * differences:
+ * - A list with all_layouts = 1 means all channel layouts with a known
+ *   disposition; nb_channel_layouts must then be 0.
+ * - A list with all_counts = 1 means all channel counts, with a known or
+ *   unknown disposition; nb_channel_layouts must then be 0 and all_layouts 1.
+ * - The list must not contain a layout with a known disposition and a
+ *   channel count with unknown disposition with the same number of channels
+ *   (e.g. AV_CH_LAYOUT_STEREO and FF_COUNT2LAYOUT(2).
+ */
 typedef struct AVFilterChannelLayouts {
     uint64_t *channel_layouts;  ///< list of channel layouts
     int    nb_channel_layouts;  ///< number of channel layouts
+    char all_layouts;           ///< accept any known channel layout
+    char all_counts;            ///< accept any channel layout or count
 
     unsigned refcount;          ///< number of references to this list
     struct AVFilterChannelLayouts ***refs; ///< references to this list
 } AVFilterChannelLayouts;
 
 /**
+ * Encode a channel count as a channel layout.
+ * FF_COUNT2LAYOUT(c) means any channel layout with c channels, with a known
+ * or unknown disposition.
+ * The result is only valid inside AVFilterChannelLayouts and immediately
+ * related functions.
+ */
+#define FF_COUNT2LAYOUT(c) (0x8000000000000000ULL | (c))
+
+/**
+ * Decode a channel count encoded as a channel layout.
+ * Return 0 if the channel layout was a real one.
+ */
+#define FF_LAYOUT2COUNT(l) (((l) & 0x8000000000000000ULL) ? \
+                           (int)((l) & 0x7FFFFFFF) : 0)
+
+/**
  * Return a channel layouts/samplerates list which contains the intersection of
  * the layouts/samplerates of a and b. Also, all the references of a, all the
  * references of b, and a and b themselves will be deallocated.
@@ -92,11 +123,17 @@
 
 /**
  * Construct an empty AVFilterChannelLayouts/AVFilterFormats struct --
- * representing any channel layout/sample rate.
+ * representing any channel layout (with known disposition)/sample rate.
  */
 AVFilterChannelLayouts *ff_all_channel_layouts(void);
 AVFilterFormats *ff_all_samplerates(void);
 
+/**
+ * Construct an AVFilterChannelLayouts coding for any channel layout, with
+ * known or unknown disposition.
+ */
+AVFilterChannelLayouts *ff_all_channel_counts(void);
+
 AVFilterChannelLayouts *avfilter_make_format64_list(const int64_t *fmts);
 
 
@@ -135,6 +172,14 @@
 
 int ff_default_query_formats(AVFilterContext *ctx);
 
+/**
+ * Set the formats list to all existing formats.
+ * This function behaves like ff_default_query_formats(), except it also
+ * accepts channel layouts with unknown disposition. It should only be used
+ * with audio filters.
+ */
+int ff_query_formats_all(AVFilterContext *ctx);
+
 
 /**
  * Create a list of supported formats. This is intended for use in
@@ -173,7 +218,8 @@
  * If a and b do not share any common formats, neither is modified, and NULL
  * is returned.
  */
-AVFilterFormats *ff_merge_formats(AVFilterFormats *a, AVFilterFormats *b);
+AVFilterFormats *ff_merge_formats(AVFilterFormats *a, AVFilterFormats *b,
+                                  enum AVMediaType type);
 
 /**
  * Add *ref as a new reference to formats.
diff --git a/libavfilter/gradfun.h b/libavfilter/gradfun.h
index 939b129..801dddd 100644
--- a/libavfilter/gradfun.h
+++ b/libavfilter/gradfun.h
@@ -26,6 +26,8 @@
 
 /// Holds instance-specific information for gradfun.
 typedef struct GradFunContext {
+    const AVClass *class;
+    double strength;    ///< user specified strength, used to define thresh
     int thresh;    ///< threshold for gradient algorithm
     int radius;    ///< blur radius
     int chroma_w;  ///< width of the chroma planes
diff --git a/libavfilter/internal.h b/libavfilter/internal.h
index d098156..d03de56 100644
--- a/libavfilter/internal.h
+++ b/libavfilter/internal.h
@@ -88,18 +88,6 @@
     int rej_perms;
 
     /**
-     * Callback called before passing the first slice of a new frame. If
-     * NULL, the filter layer will default to storing a reference to the
-     * picture inside the link structure.
-     *
-     * Input video pads only.
-     *
-     * @return >= 0 on success, a negative AVERROR on error. picref will be
-     * unreferenced by the caller in case of error.
-     */
-    void (*start_frame)(AVFilterLink *link, AVFilterBufferRef *picref);
-
-    /**
      * Callback function to get a video buffer. If NULL, the filter system will
      * use ff_default_get_video_buffer().
      *
@@ -117,27 +105,6 @@
                                            int nb_samples);
 
     /**
-     * Callback called after the slices of a frame are completely sent. If
-     * NULL, the filter layer will default to releasing the reference stored
-     * in the link structure during start_frame().
-     *
-     * Input video pads only.
-     *
-     * @return >= 0 on success, a negative AVERROR on error.
-     */
-    int (*end_frame)(AVFilterLink *link);
-
-    /**
-     * Slice drawing callback. This is where a filter receives video data
-     * and should do its processing.
-     *
-     * Input video pads only.
-     *
-     * @return >= 0 on success, a negative AVERROR on error.
-     */
-    int (*draw_slice)(AVFilterLink *link, int y, int height, int slice_dir);
-
-    /**
      * Filtering callback. This is where a filter receives a frame with
      * audio/video data and should do its processing.
      *
diff --git a/libavfilter/libmpcodecs/vd_ffmpeg.h b/libavfilter/libmpcodecs/av_helpers.h
similarity index 80%
rename from libavfilter/libmpcodecs/vd_ffmpeg.h
rename to libavfilter/libmpcodecs/av_helpers.h
index 004d477..90b67d5 100644
--- a/libavfilter/libmpcodecs/vd_ffmpeg.h
+++ b/libavfilter/libmpcodecs/av_helpers.h
@@ -1,4 +1,6 @@
 /*
+ * Generic libav* helpers
+ *
  * This file is part of MPlayer.
  *
  * MPlayer is free software; you can redistribute it and/or modify
@@ -16,9 +18,10 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#ifndef MPLAYER_VD_FFMPEG_H
-#define MPLAYER_VD_FFMPEG_H
+#ifndef MPLAYER_AV_HELPERS_H
+#define MPLAYER_AV_HELPERS_H
 
-void init_avcodec(void);
+void ff_init_avcodec(void);
+void ff_init_avformat(void);
 
-#endif /* MPLAYER_VD_FFMPEG_H */
+#endif /* MPLAYER_AV_HELPERS_H */
diff --git a/libavfilter/libmpcodecs/cpudetect.h b/libavfilter/libmpcodecs/cpudetect.h
index 0f433e7..710f6e6 100644
--- a/libavfilter/libmpcodecs/cpudetect.h
+++ b/libavfilter/libmpcodecs/cpudetect.h
@@ -19,8 +19,6 @@
 #ifndef MPLAYER_CPUDETECT_H
 #define MPLAYER_CPUDETECT_H
 
-//#include "config.h"
-
 #define CPUTYPE_I386    3
 #define CPUTYPE_I486    4
 #define CPUTYPE_I586    5
@@ -40,20 +38,23 @@
     int hasSSE2;
     int hasSSE3;
     int hasSSSE3;
+    int hasSSE4;
+    int hasSSE42;
     int hasSSE4a;
+    int hasAVX;
     int isX86;
     unsigned cl_size; /* size of cache line */
     int hasAltiVec;
     int hasTSC;
 } CpuCaps;
 
-extern CpuCaps gCpuCaps;
+extern CpuCaps ff_gCpuCaps;
 
-void do_cpuid(unsigned int ax, unsigned int *p);
+void ff_do_cpuid(unsigned int ax, unsigned int *p);
 
-void GetCpuCaps(CpuCaps *caps);
+void ff_GetCpuCaps(CpuCaps *caps);
 
 /* returned value is malloc()'ed so free() it after use */
-char *GetCpuFriendlyName(unsigned int regs[], unsigned int regs2[]);
+char *ff_GetCpuFriendlyName(unsigned int regs[], unsigned int regs2[]);
 
 #endif /* MPLAYER_CPUDETECT_H */
diff --git a/libavfilter/libmpcodecs/help_mp.h b/libavfilter/libmpcodecs/help_mp.h
index 87b828d..6ceb630 100644
--- a/libavfilter/libmpcodecs/help_mp.h
+++ b/libavfilter/libmpcodecs/help_mp.h
@@ -70,12 +70,14 @@
 #define MSGTR_NoHomeDir "Cannot find HOME directory.\n"
 #define MSGTR_GetpathProblem "get_path(\"config\") problem\n"
 #define MSGTR_CreatingCfgFile "Creating config file: %s\n"
-#define MSGTR_BuiltinCodecsConf "Using built-in default codecs.conf.\n"
-#define MSGTR_CantLoadFont "Cannot load bitmap font: %s\n"
-#define MSGTR_CantLoadSub "Cannot load subtitles: %s\n"
+#define MSGTR_CantLoadFont "Cannot load bitmap font '%s'.\n"
+#define MSGTR_CantLoadSub "Cannot load subtitles '%s'.\n"
 #define MSGTR_DumpSelectedStreamMissing "dump: FATAL: Selected stream missing!\n"
 #define MSGTR_CantOpenDumpfile "Cannot open dump file.\n"
 #define MSGTR_CoreDumped "Core dumped ;)\n"
+#define MSGTR_DumpBytesWrittenPercent "dump: %"PRIu64" bytes written (~%.1f%%)\r"
+#define MSGTR_DumpBytesWritten "dump: %"PRIu64" bytes written\r"
+#define MSGTR_DumpBytesWrittenTo "dump: %"PRIu64" bytes written to '%s'.\n"
 #define MSGTR_FPSnotspecified "FPS not specified in the header or invalid, use the -fps option.\n"
 #define MSGTR_TryForceAudioFmtStr "Trying to force audio codec driver family %s...\n"
 #define MSGTR_CantFindAudioCodec "Cannot find codec for audio format 0x%X.\n"
@@ -112,8 +114,6 @@
 #define MSGTR_Playing "\nPlaying %s.\n"
 #define MSGTR_NoSound "Audio: no sound\n"
 #define MSGTR_FPSforced "FPS forced to be %5.3f  (ftime: %5.3f).\n"
-#define MSGTR_CompiledWithRuntimeDetection "Compiled with runtime CPU detection.\n"
-#define MSGTR_CompiledWithCPUExtensions "Compiled for x86 CPU with extensions:"
 #define MSGTR_AvailableVideoOutputDrivers "Available video output drivers:\n"
 #define MSGTR_AvailableAudioOutputDrivers "Available audio output drivers:\n"
 #define MSGTR_AvailableAudioCodecs "Available audio codecs:\n"
@@ -121,7 +121,6 @@
 #define MSGTR_AvailableAudioFm "Available (compiled-in) audio codec families/drivers:\n"
 #define MSGTR_AvailableVideoFm "Available (compiled-in) video codec families/drivers:\n"
 #define MSGTR_AvailableFsType "Available fullscreen layer change modes:\n"
-#define MSGTR_UsingRTCTiming "Using Linux hardware RTC timing (%ldHz).\n"
 #define MSGTR_CannotReadVideoProperties "Video: Cannot read properties.\n"
 #define MSGTR_NoStreamFound "No stream found.\n"
 #define MSGTR_ErrorInitializingVODevice "Error opening/initializing the selected video_out (-vo) device.\n"
@@ -129,7 +128,7 @@
 #define MSGTR_ForcedAudioCodec "Forced audio codec: %s\n"
 #define MSGTR_Video_NoVideo "Video: no video\n"
 #define MSGTR_NotInitializeVOPorVO "\nFATAL: Could not initialize video filters (-vf) or video output (-vo).\n"
-#define MSGTR_Paused "\n  =====  PAUSE  =====\r" // no more than 23 characters (status line for audio files)
+#define MSGTR_Paused "  =====  PAUSE  =====" // no more than 23 characters (status line for audio files)
 #define MSGTR_PlaylistLoadUnable "\nUnable to load playlist %s.\n"
 #define MSGTR_Exit_SIGILL_RTCpuSel \
 "- MPlayer crashed by an 'Illegal Instruction'.\n"\
@@ -156,15 +155,11 @@
 #define MSGTR_AddedSubtitleFile "SUB: Added subtitle file (%d): %s\n"
 #define MSGTR_RemovedSubtitleFile "SUB: Removed subtitle file (%d): %s\n"
 #define MSGTR_ErrorOpeningOutputFile "Error opening file [%s] for writing!\n"
-#define MSGTR_CommandLine "CommandLine:"
 #define MSGTR_RTCDeviceNotOpenable "Failed to open %s: %s (it should be readable by the user.)\n"
 #define MSGTR_LinuxRTCInitErrorIrqpSet "Linux RTC init error in ioctl (rtc_irqp_set %lu): %s\n"
 #define MSGTR_IncreaseRTCMaxUserFreq "Try adding \"echo %lu > /proc/sys/dev/rtc/max-user-freq\" to your system startup scripts.\n"
 #define MSGTR_LinuxRTCInitErrorPieOn "Linux RTC init error in ioctl (rtc_pie_on): %s\n"
 #define MSGTR_UsingTimingType "Using %s timing.\n"
-#define MSGTR_NoIdleAndGui "The -idle option cannot be used with GMPlayer.\n"
-#define MSGTR_MenuInitialized "Menu initialized: %s\n"
-#define MSGTR_MenuInitFailed "Menu init failed.\n"
 #define MSGTR_Getch2InitializedTwice "WARNING: getch2_init called twice!\n"
 #define MSGTR_DumpstreamFdUnavailable "Cannot dump this stream - no file descriptor available.\n"
 #define MSGTR_CantOpenLibmenuFilterWithThisRootMenu "Can't open libmenu video filter with root menu %s.\n"
@@ -188,6 +183,17 @@
 #define MSGTR_MenuCall "Menu call\n"
 #define MSGTR_MasterQuit "Option -udp-slave: exiting because master exited\n"
 #define MSGTR_InvalidIP "Option -udp-ip: invalid IP address\n"
+#define MSGTR_Forking "Forking...\n"
+#define MSGTR_Forked "Forked...\n"
+#define MSGTR_CouldntStartGdb "Couldn't start gdb\n"
+#define MSGTR_CouldntFork "Couldn't fork\n"
+#define MSGTR_FilenameTooLong "Filename is too long, can not load file or directory specific config files\n"
+#define MSGTR_AudioDeviceStuck "Audio device got stuck!\n"
+#define MSGTR_AudioOutputTruncated "Audio output truncated at end.\n"
+#define MSGTR_ASSCannotAddVideoFilter "ASS: cannot add video filter\n"
+#define MSGTR_PtsAfterFiltersMissing "pts after filters MISSING\n"
+#define MSGTR_CommandLine "CommandLine:"
+#define MSGTR_MenuInitFailed "Menu init failed.\n"
 
 // --- edit decision lists
 #define MSGTR_EdlOutOfMem "Can't allocate enough memory to hold EDL data.\n"
@@ -205,7 +211,6 @@
 #define MSGTR_EdloutBadStop "EDL skip canceled, last start > stop\n"
 #define MSGTR_EdloutStartSkip "EDL skip start, press 'i' again to end block.\n"
 #define MSGTR_EdloutEndSkip "EDL skip end, line written.\n"
-#define MSGTR_MPEndposNoSizeBased "Option -endpos in MPlayer does not yet support size units.\n"
 
 // mplayer.c OSD
 #define MSGTR_OSDenabled "enabled"
@@ -219,6 +224,8 @@
 #define MSGTR_OSDChapter "Chapter: (%d) %s"
 #define MSGTR_OSDAngle "Angle: %d/%d"
 #define MSGTR_OSDDeinterlace "Deinterlace: %s"
+#define MSGTR_OSDCapturing "Capturing: %s"
+#define MSGTR_OSDCapturingFailure "Capturing failed"
 
 // property values
 #define MSGTR_Enabled "enabled"
@@ -298,12 +305,9 @@
 #define MSGTR_CannotAllocateBytes "Couldn't allocate %d bytes.\n"
 #define MSGTR_SettingAudioDelay "Setting audio delay to %5.3fs.\n"
 #define MSGTR_SettingVideoDelay "Setting video delay to %5.3fs.\n"
-#define MSGTR_SettingAudioInputGain "Setting audio input gain to %f.\n"
-#define MSGTR_LamePresetEquals "\npreset=%s\n\n"
 #define MSGTR_LimitingAudioPreload "Limiting audio preload to 0.4s.\n"
 #define MSGTR_IncreasingAudioDensity "Increasing audio density to 4.\n"
 #define MSGTR_ZeroingAudioPreloadAndMaxPtsCorrection "Forcing audio preload to 0, max pts correction to 0.\n"
-#define MSGTR_CBRAudioByterate "\n\nCBR audio: %d bytes/sec, %d bytes/block\n"
 #define MSGTR_LameVersion "LAME version %s (%s)\n\n"
 #define MSGTR_InvalidBitrateForLamePreset "Error: The bitrate specified is out of the valid range for this preset.\n"\
 "\n"\
@@ -411,7 +415,7 @@
 "Cannot set LAME options, check bitrate/samplerate, some very low bitrates\n"\
 "(<32) need lower samplerates (i.e. -srate 8000).\n"\
 "If everything else fails, try a preset."
-#define MSGTR_ConfigFileError "config file error"
+#define MSGTR_ConfigFileError "Config file error"
 #define MSGTR_ErrorParsingCommandLine "error parsing command line"
 #define MSGTR_VideoStreamRequired "Video stream is mandatory!\n"
 #define MSGTR_ForcingInputFPS "Input fps will be interpreted as %5.3f instead.\n"
@@ -490,8 +494,6 @@
 #define MSGTR_CodecNeedsOutfmt "\ncodec(%s) needs an 'outfmt'!\n"
 #define MSGTR_CantAllocateComment "Can't allocate memory for comment. "
 #define MSGTR_GetTokenMaxNotLessThanMAX_NR_TOKEN "get_token(): max >= MAX_MR_TOKEN!"
-#define MSGTR_ReadingFile "Reading %s: "
-#define MSGTR_CantOpenFileError "Can't open '%s': %s\n"
 #define MSGTR_CantGetMemoryForLine "Can't get memory for 'line': %s\n"
 #define MSGTR_CantReallocCodecsp "Can't realloc '*codecsp': %s\n"
 #define MSGTR_CodecNameNotUnique "Codec name '%s' isn't unique."
@@ -557,10 +559,40 @@
 #define MSGTR_Preferences "Preferences"
 #define MSGTR_AudioPreferences "Audio driver configuration"
 #define MSGTR_NoMediaOpened "No media opened."
-#define MSGTR_VCDTrack "VCD track %d"
+#define MSGTR_Title "Title %d"
 #define MSGTR_NoChapter "No chapter"
 #define MSGTR_Chapter "Chapter %d"
 #define MSGTR_NoFileLoaded "No file loaded."
+#define MSGTR_Filter_UTF8Subtitles "UTF-8 encoded subtitles (*.utf, *.utf-8, *.utf8)"
+#define MSGTR_Filter_AllSubtitles "All subtitles"
+#define MSGTR_Filter_AllFiles "All files"
+#define MSGTR_Filter_TTF "True Type fonts (*.ttf)"
+#define MSGTR_Filter_Type1 "Type1 fonts (*.pfb)"
+#define MSGTR_Filter_AllFonts "All fonts"
+#define MSGTR_Filter_FontFiles "Font files (*.desc)"
+#define MSGTR_Filter_DDRawAudio "Dolby Digital / PCM (*.ac3, *.pcm)"
+#define MSGTR_Filter_MPEGAudio "MPEG audio (*.mp2, *.mp3, *.mpga, *.m4a, *.aac, *.f4a)"
+#define MSGTR_Filter_MatroskaAudio "Matroska audio (*.mka)"
+#define MSGTR_Filter_OGGAudio "Ogg audio (*.oga, *.ogg, *.spx)"
+#define MSGTR_Filter_WAVAudio "WAV audio (*.wav)"
+#define MSGTR_Filter_WMAAudio "Windows Media audio (*.wma)"
+#define MSGTR_Filter_AllAudioFiles "All audio files"
+#define MSGTR_Filter_AllVideoFiles "All video files"
+#define MSGTR_Filter_AVIFiles "AVI files"
+#define MSGTR_Filter_DivXFiles "DivX files"
+#define MSGTR_Filter_FlashVideo "Flash Video"
+#define MSGTR_Filter_MP3Files "MP3 files"
+#define MSGTR_Filter_MP4Files "MP4 files"
+#define MSGTR_Filter_MPEGFiles "MPEG files"
+#define MSGTR_Filter_MP2TS "MPEG-2 transport streams"
+#define MSGTR_Filter_MatroskaMedia "Matroska media"
+#define MSGTR_Filter_OGGMedia "Ogg media"
+#define MSGTR_Filter_QTMedia "QuickTime media"
+#define MSGTR_Filter_RNMedia "RealNetworks media"
+#define MSGTR_Filter_VideoCDImages "VCD/SVCD images"
+#define MSGTR_Filter_WAVFiles "WAV files"
+#define MSGTR_Filter_WindowsMedia "Windows media"
+#define MSGTR_Filter_Playlists "Playlists"
 
 // --- buttons ---
 #define MSGTR_Ok "OK"
@@ -573,43 +605,43 @@
 #define MSGTR_Browse "Browse"
 
 // --- error messages ---
-#define MSGTR_NEMDB "Sorry, not enough memory to draw buffer."
+#define MSGTR_NEMDB "Sorry, not enough memory to draw buffer.\n"
 #define MSGTR_NEMFMR "Sorry, not enough memory for menu rendering."
-#define MSGTR_IDFGCVD "Sorry, I did not find a GUI-compatible video output driver."
+#define MSGTR_IDFGCVD "Sorry, no GUI-compatible video output driver found.\n"
 #define MSGTR_NEEDLAVC "Sorry, you cannot play non-MPEG files with your DXR3/H+ device without reencoding.\nPlease enable lavc in the DXR3/H+ configuration box."
-#define MSGTR_UNKNOWNWINDOWTYPE "Unknown window type found ..."
+#define MSGTR_ICONERROR "Icon '%s' (size %d) not found or unsupported format.\n"
 
 // --- skin loader error messages
-#define MSGTR_SKIN_ERRORMESSAGE "[skin] error in skin config file on line %d: %s"
-#define MSGTR_SKIN_WARNING1 "[skin] warning: in config file line %d:\nwidget (%s) found but no \"section\" found before"
-#define MSGTR_SKIN_WARNING2 "[skin] warning: in config file line %d:\nwidget (%s) found but no \"subsection\" found before"
-#define MSGTR_SKIN_WARNING3 "[skin] warning: in config file line %d:\nthis subsection is not supported by widget (%s)"
-#define MSGTR_SKIN_SkinFileNotFound "[skin] file ( %s ) not found.\n"
-#define MSGTR_SKIN_SkinFileNotReadable "[skin] file ( %s ) not readable.\n"
-#define MSGTR_SKIN_BITMAP_16bit  "Bitmaps of 16 bits or less depth not supported (%s).\n"
-#define MSGTR_SKIN_BITMAP_FileNotFound  "File not found (%s)\n"
-#define MSGTR_SKIN_BITMAP_BMPReadError "BMP read error (%s)\n"
-#define MSGTR_SKIN_BITMAP_TGAReadError "TGA read error (%s)\n"
-#define MSGTR_SKIN_BITMAP_PNGReadError "PNG read error (%s)\n"
-#define MSGTR_SKIN_BITMAP_RLENotSupported "RLE packed TGA not supported (%s)\n"
-#define MSGTR_SKIN_BITMAP_UnknownFileType "unknown file type (%s)\n"
-#define MSGTR_SKIN_BITMAP_ConversionError "24 bit to 32 bit conversion error (%s)\n"
-#define MSGTR_SKIN_BITMAP_UnknownMessage "unknown message: %s\n"
-#define MSGTR_SKIN_FONT_NotEnoughtMemory "not enough memory\n"
+#define MSGTR_SKIN_ERRORMESSAGE "Error in skin config file on line %d: %s"
+#define MSGTR_SKIN_ERROR_SECTION "No section specified for '%s'.\n"
+#define MSGTR_SKIN_ERROR_WINDOW "No window specified for '%s'.\n"
+#define MSGTR_SKIN_ERROR_ITEM "This item is not supported by '%s'.\n"
+#define MSGTR_SKIN_UNKNOWN_ITEM "Unknown item '%s'\n"
+#define MSGTR_SKIN_UNKNOWN_NAME "Unknown name '%s'\n"
+#define MSGTR_SKIN_SkinFileNotFound "Skin file %s not found.\n"
+#define MSGTR_SKIN_SkinFileNotReadable "Skin file %s not readable.\n"
+#define MSGTR_SKIN_BITMAP_16bit  "Color depth of bitmap %s is 16 bits or less which is not supported.\n"
+#define MSGTR_SKIN_BITMAP_FileNotFound  "Bitmap %s not found.\n"
+#define MSGTR_SKIN_BITMAP_PNGReadError "PNG read error in %s\n"
+#define MSGTR_SKIN_BITMAP_ConversionError "24 bit to 32 bit conversion error in %s\n"
+#define MSGTR_SKIN_UnknownMessage "Unknown message '%s'\n"
+#define MSGTR_SKIN_NotEnoughMemory "Not enough memory\n"
+#define MSGTR_SKIN_TooManyItemsDeclared "Too many items declared.\n"
 #define MSGTR_SKIN_FONT_TooManyFontsDeclared "Too many fonts declared.\n"
-#define MSGTR_SKIN_FONT_FontFileNotFound "Font file not found.\n"
+#define MSGTR_SKIN_FONT_FontFileNotFound "Font description file not found.\n"
 #define MSGTR_SKIN_FONT_FontImageNotFound "Font image file not found.\n"
-#define MSGTR_SKIN_FONT_NonExistentFontID "non-existent font identifier (%s)\n"
-#define MSGTR_SKIN_UnknownParameter "unknown parameter (%s)\n"
-#define MSGTR_SKIN_SKINCFG_SkinNotFound "Skin not found (%s).\n"
-#define MSGTR_SKIN_SKINCFG_SelectedSkinNotFound "Selected skin ( %s ) not found, trying 'default'...\n"
-#define MSGTR_SKIN_SKINCFG_SkinCfgReadError "skin config file read error (%s)\n"
+#define MSGTR_SKIN_FONT_NonExistentFont "Font '%s' not found.\n"
+#define MSGTR_SKIN_UnknownParameter "Unknown parameter '%s'\n"
+#define MSGTR_SKIN_SKINCFG_SkinNotFound "Skin '%s' not found.\n"
+#define MSGTR_SKIN_SKINCFG_SelectedSkinNotFound "Selected skin '%s' not found, trying skin 'default'...\n"
+#define MSGTR_SKIN_SKINCFG_SkinCfgError "Config file processing error with skin '%s'\n"
 #define MSGTR_SKIN_LABEL "Skins:"
 
 // --- GTK menus
 #define MSGTR_MENU_AboutMPlayer "About MPlayer"
 #define MSGTR_MENU_Open "Open..."
 #define MSGTR_MENU_PlayFile "Play file..."
+#define MSGTR_MENU_PlayCD "Play CD..."
 #define MSGTR_MENU_PlayVCD "Play VCD..."
 #define MSGTR_MENU_PlayDVD "Play DVD..."
 #define MSGTR_MENU_PlayURL "Play URL..."
@@ -627,6 +659,7 @@
 #define MSGTR_MENU_NormalSize "Normal size"
 #define MSGTR_MENU_DoubleSize "Double size"
 #define MSGTR_MENU_FullScreen "Fullscreen"
+#define MSGTR_MENU_CD "CD"
 #define MSGTR_MENU_DVD "DVD"
 #define MSGTR_MENU_VCD "VCD"
 #define MSGTR_MENU_PlayDisc "Open disc..."
@@ -641,7 +674,7 @@
 #define MSGTR_MENU_PlayList MSGTR_PlayList
 #define MSGTR_MENU_SkinBrowser "Skin browser"
 #define MSGTR_MENU_Preferences MSGTR_Preferences
-#define MSGTR_MENU_Exit "Exit..."
+#define MSGTR_MENU_Exit "Exit"
 #define MSGTR_MENU_Mute "Mute"
 #define MSGTR_MENU_Original "Original"
 #define MSGTR_MENU_AspectRatio "Aspect ratio"
@@ -702,9 +735,10 @@
 #define MSGTR_PREFERENCES_HFrameDrop "Enable HARD frame dropping (dangerous)"
 #define MSGTR_PREFERENCES_Flip "Flip image upside down"
 #define MSGTR_PREFERENCES_Panscan "Panscan: "
-#define MSGTR_PREFERENCES_OSDTimer "Timer and indicators"
-#define MSGTR_PREFERENCES_OSDProgress "Progressbars only"
-#define MSGTR_PREFERENCES_OSDTimerPercentageTotalTime "Timer, percentage and total time"
+#define MSGTR_PREFERENCES_OSD_LEVEL0 "Subtitles only"
+#define MSGTR_PREFERENCES_OSD_LEVEL1 "Volume and seek"
+#define MSGTR_PREFERENCES_OSD_LEVEL2 "Volume, seek, timer and percentage"
+#define MSGTR_PREFERENCES_OSD_LEVEL3 "Volume, seek, timer, percentage and total time"
 #define MSGTR_PREFERENCES_Subtitle "Subtitle:"
 #define MSGTR_PREFERENCES_SUB_Delay "Delay: "
 #define MSGTR_PREFERENCES_SUB_FPS "FPS:"
@@ -777,6 +811,7 @@
 #define MSGTR_PREFERENCES_SaveWinPos "Save window position"
 #define MSGTR_PREFERENCES_XSCREENSAVER "Stop XScreenSaver"
 #define MSGTR_PREFERENCES_PlayBar "Enable playbar"
+#define MSGTR_PREFERENCES_NoIdle "Quit after playing"
 #define MSGTR_PREFERENCES_AutoSync "AutoSync on/off"
 #define MSGTR_PREFERENCES_AutoSyncValue "Autosync: "
 #define MSGTR_PREFERENCES_CDROMDevice "CD-ROM device:"
@@ -798,39 +833,62 @@
 #define MSGTR_MSGBOX_LABEL_Error "Error!"
 #define MSGTR_MSGBOX_LABEL_Warning "Warning!"
 
-// bitmap.c
-#define MSGTR_NotEnoughMemoryC32To1 "[c32to1] not enough memory for image\n"
-#define MSGTR_NotEnoughMemoryC1To32 "[c1to32] not enough memory for image\n"
-
 // cfg.c
-#define MSGTR_ConfigFileReadError "[cfg] config file read error ...\n"
-#define MSGTR_UnableToSaveOption "[cfg] Unable to save the '%s' option.\n"
+#define MSGTR_UnableToSaveOption "Unable to save option '%s'.\n"
 
 // interface.c
-#define MSGTR_DeletingSubtitles "[GUI] Deleting subtitles.\n"
-#define MSGTR_LoadingSubtitles "[GUI] Loading subtitles: %s\n"
-#define MSGTR_AddingVideoFilter "[GUI] Adding video filter: %s\n"
-#define MSGTR_RemovingVideoFilter "[GUI] Removing video filter: %s\n"
+#define MSGTR_DeletingSubtitles "Deleting subtitles.\n"
+#define MSGTR_LoadingSubtitles "Loading subtitles '%s'.\n"
+#define MSGTR_AddingVideoFilter "Adding video filter '%s'.\n"
 
 // mw.c
 #define MSGTR_NotAFile "This does not seem to be a file: %s !\n"
 
 // ws.c
-#define MSGTR_WS_CouldNotOpenDisplay "[ws] Could not open the display.\n"
-#define MSGTR_WS_RemoteDisplay "[ws] Remote display, disabling XMITSHM.\n"
-#define MSGTR_WS_NoXshm "[ws] Sorry, your system does not support the X shared memory extension.\n"
-#define MSGTR_WS_NoXshape "[ws] Sorry, your system does not support the XShape extension.\n"
-#define MSGTR_WS_ColorDepthTooLow "[ws] Sorry, the color depth is too low.\n"
-#define MSGTR_WS_TooManyOpenWindows "[ws] There are too many open windows.\n"
-#define MSGTR_WS_ShmError "[ws] shared memory extension error\n"
-#define MSGTR_WS_NotEnoughMemoryDrawBuffer "[ws] Sorry, not enough memory to draw buffer.\n"
+#define MSGTR_WS_RemoteDisplay "Remote display, disabling XMITSHM.\n"
+#define MSGTR_WS_NoXshm "Sorry, your system does not support the X shared memory extension.\n"
+#define MSGTR_WS_NoXshape "Sorry, your system does not support the XShape extension.\n"
+#define MSGTR_WS_ColorDepthTooLow "Sorry, the color depth is too low.\n"
+#define MSGTR_WS_TooManyOpenWindows "There are too many open windows.\n"
+#define MSGTR_WS_ShmError "shared memory extension error\n"
+#define MSGTR_WS_NotEnoughMemoryDrawBuffer "Sorry, not enough memory to draw buffer.\n"
 #define MSGTR_WS_DpmsUnavailable "DPMS not available?\n"
 #define MSGTR_WS_DpmsNotEnabled "Could not enable DPMS.\n"
+#define MSGTR_WS_XError "An X11 Error has occurred!\n"
 
 // wsxdnd.c
 #define MSGTR_WS_NotAFile "This does not seem to be a file...\n"
 #define MSGTR_WS_DDNothing "D&D: Nothing returned!\n"
 
+// Win32 GUI
+#define MSGTR_Close "Close"
+#define MSGTR_Default "Defaults"
+#define MSGTR_Down "Down"
+#define MSGTR_Load "Load"
+#define MSGTR_Save "Save"
+#define MSGTR_Up "Up"
+#define MSGTR_DirectorySelect "Select directory..."
+#define MSGTR_PlaylistSave "Save playlist..."
+#define MSGTR_PlaylistSelect "Select playlist..."
+#define MSGTR_SelectTitleChapter "Select title/chapter..."
+#define MSGTR_MENU_DebugConsole "Debug Console"
+#define MSGTR_MENU_OnlineHelp "Online Help"
+#define MSGTR_MENU_PlayDirectory "Play directory..."
+#define MSGTR_MENU_SeekBack "Seek Backwards"
+#define MSGTR_MENU_SeekForw "Seek Forwards"
+#define MSGTR_MENU_ShowHide "Show/Hide"
+#define MSGTR_MENU_SubtitlesOnOff "Subtitle Visibility On/Off"
+#define MSGTR_PLAYLIST_AddFile "Add File..."
+#define MSGTR_PLAYLIST_AddURL "Add URL..."
+#define MSGTR_PREFERENCES_Priority "Priority:"
+#define MSGTR_PREFERENCES_PriorityHigh "high"
+#define MSGTR_PREFERENCES_PriorityLow "low"
+#define MSGTR_PREFERENCES_PriorityNormal "normal"
+#define MSGTR_PREFERENCES_PriorityNormalAbove "above normal"
+#define MSGTR_PREFERENCES_PriorityNormalBelow "below normal"
+#define MSGTR_PREFERENCES_ShowInVideoWin "Display in the video window (DirectX only)"
+
+
 // ======================= video output drivers ========================
 
 #define MSGTR_VOincompCodec "The selected video_out device is incompatible with this codec.\n"\
@@ -984,7 +1042,6 @@
 // vo_sdl.c
 #define MSGTR_LIBVO_SDL_CouldntGetAnyAcceptableSDLModeForOutput "[VO_SDL] Couldn't get any acceptable SDL Mode for output.\n"
 #define MSGTR_LIBVO_SDL_SetVideoModeFailed "[VO_SDL] set_video_mode: SDL_SetVideoMode failed: %s.\n"
-#define MSGTR_LIBVO_SDL_SetVideoModeFailedFull "[VO_SDL] Set_fullmode: SDL_SetVideoMode failed: %s.\n"
 #define MSGTR_LIBVO_SDL_MappingI420ToIYUV "[VO_SDL] Mapping I420 to IYUV.\n"
 #define MSGTR_LIBVO_SDL_UnsupportedImageFormat "[VO_SDL] Unsupported image format (0x%X).\n"
 #define MSGTR_LIBVO_SDL_InfoPleaseUseVmOrZoom "[VO_SDL] Info - please use -vm or -zoom to switch to the best resolution.\n"
@@ -1151,16 +1208,15 @@
 // old vo drivers that have been replaced
 #define MSGTR_VO_PGM_HasBeenReplaced "The pgm video output driver has been replaced by -vo pnm:pgmyuv.\n"
 #define MSGTR_VO_MD5_HasBeenReplaced "The md5 video output driver has been replaced by -vo md5sum.\n"
+#define MSGTR_VO_GL2_HasBeenRenamed "The gl2 video output driver has been renamed to -vo gl_tiled, but you really should be using -vo gl instead.\n"
 
 
 // ======================= audio output drivers ========================
 
 // audio_out.c
 #define MSGTR_AO_ALSA9_1x_Removed "audio_out: alsa9 and alsa1x modules were removed, use -ao alsa instead.\n"
-#define MSGTR_AO_TryingPreferredAudioDriver "Trying preferred audio driver '%.*s', options '%s'\n"
 #define MSGTR_AO_NoSuchDriver "No such audio driver '%.*s'\n"
 #define MSGTR_AO_FailedInit "Failed to initialize audio driver '%s'\n"
-#define MSGTR_AO_TryingEveryKnown "Trying every known audio driver...\n"
 
 // ao_oss.c
 #define MSGTR_AO_OSS_CantOpenMixer "[AO OSS] audio_setup: Can't open mixer device %s: %s\n"
@@ -1196,7 +1252,7 @@
 
 // ao_pcm.c
 #define MSGTR_AO_PCM_FileInfo "[AO PCM] File: %s (%s)\nPCM: Samplerate: %iHz Channels: %s Format %s\n"
-#define MSGTR_AO_PCM_HintInfo "[AO PCM] Info: Faster dumping is achieved with -vc null -vo null -ao pcm:fast\n[AO PCM] Info: To write WAVE files use -ao pcm:waveheader (default).\n"
+#define MSGTR_AO_PCM_HintInfo "[AO PCM] Info: Faster dumping is achieved with -benchmark -vc null -vo null -ao pcm:fast\n[AO PCM] Info: To write WAVE files use -ao pcm:waveheader (default).\n"
 #define MSGTR_AO_PCM_CantOpenOutputFile "[AO PCM] Failed to open %s for writing!\n"
 
 // ao_sdl.c
@@ -1213,7 +1269,7 @@
 #define MSGTR_AO_SGI_CantSetParms_Samplerate "[AO SGI] init: setparams failed: %s\nCould not set desired samplerate.\n"
 #define MSGTR_AO_SGI_CantSetAlRate "[AO SGI] init: AL_RATE was not accepted on the given resource.\n"
 #define MSGTR_AO_SGI_CantGetParms "[AO SGI] init: getparams failed: %s\n"
-#define MSGTR_AO_SGI_SampleRateInfo "[AO SGI] init: samplerate is now %lf (desired rate is %lf)\n"
+#define MSGTR_AO_SGI_SampleRateInfo "[AO SGI] init: samplerate is now %f (desired rate is %f)\n"
 #define MSGTR_AO_SGI_InitConfigError "[AO SGI] init: %s\n"
 #define MSGTR_AO_SGI_InitOpenAudioFailed "[AO SGI] init: Unable to open audio channel: %s\n"
 #define MSGTR_AO_SGI_Uninit "[AO SGI] uninit: ...\n"
@@ -1229,31 +1285,6 @@
 #define MSGTR_AO_SUN_CantUseSelect "[AO SUN]\n   ***  Your audio driver DOES NOT support select()  ***\nRecompile MPlayer with #undef HAVE_AUDIO_SELECT in config.h !\n\n"
 #define MSGTR_AO_SUN_CantReopenReset "[AO SUN]\nFatal error: *** CANNOT REOPEN / RESET AUDIO DEVICE (%s) ***\n"
 
-// ao_alsa5.c
-#define MSGTR_AO_ALSA5_InitInfo "[AO ALSA5] alsa-init: requested format: %d Hz, %d channels, %s\n"
-#define MSGTR_AO_ALSA5_SoundCardNotFound "[AO ALSA5] alsa-init: no soundcards found.\n"
-#define MSGTR_AO_ALSA5_InvalidFormatReq "[AO ALSA5] alsa-init: invalid format (%s) requested - output disabled.\n"
-#define MSGTR_AO_ALSA5_PlayBackError "[AO ALSA5] alsa-init: playback open error: %s\n"
-#define MSGTR_AO_ALSA5_PcmInfoError "[AO ALSA5] alsa-init: PCM info error: %s\n"
-#define MSGTR_AO_ALSA5_SoundcardsFound "[AO ALSA5] alsa-init: %d soundcard(s) found, using: %s\n"
-#define MSGTR_AO_ALSA5_PcmChanInfoError "[AO ALSA5] alsa-init: PCM channel info error: %s\n"
-#define MSGTR_AO_ALSA5_CantSetParms "[AO ALSA5] alsa-init: error setting parameters: %s\n"
-#define MSGTR_AO_ALSA5_CantSetChan "[AO ALSA5] alsa-init: error setting up channel: %s\n"
-#define MSGTR_AO_ALSA5_ChanPrepareError "[AO ALSA5] alsa-init: channel prepare error: %s\n"
-#define MSGTR_AO_ALSA5_DrainError "[AO ALSA5] alsa-uninit: playback drain error: %s\n"
-#define MSGTR_AO_ALSA5_FlushError "[AO ALSA5] alsa-uninit: playback flush error: %s\n"
-#define MSGTR_AO_ALSA5_PcmCloseError "[AO ALSA5] alsa-uninit: PCM close error: %s\n"
-#define MSGTR_AO_ALSA5_ResetDrainError "[AO ALSA5] alsa-reset: playback drain error: %s\n"
-#define MSGTR_AO_ALSA5_ResetFlushError "[AO ALSA5] alsa-reset: playback flush error: %s\n"
-#define MSGTR_AO_ALSA5_ResetChanPrepareError "[AO ALSA5] alsa-reset: channel prepare error: %s\n"
-#define MSGTR_AO_ALSA5_PauseDrainError "[AO ALSA5] alsa-pause: playback drain error: %s\n"
-#define MSGTR_AO_ALSA5_PauseFlushError "[AO ALSA5] alsa-pause: playback flush error: %s\n"
-#define MSGTR_AO_ALSA5_ResumePrepareError "[AO ALSA5] alsa-resume: channel prepare error: %s\n"
-#define MSGTR_AO_ALSA5_Underrun "[AO ALSA5] alsa-play: alsa underrun, resetting stream.\n"
-#define MSGTR_AO_ALSA5_PlaybackPrepareError "[AO ALSA5] alsa-play: playback prepare error: %s\n"
-#define MSGTR_AO_ALSA5_WriteErrorAfterReset "[AO ALSA5] alsa-play: write error after reset: %s - giving up.\n"
-#define MSGTR_AO_ALSA5_OutPutError "[AO ALSA5] alsa-play: output error: %s\n"
-
 // ao_alsa.c
 #define MSGTR_AO_ALSA_InvalidMixerIndexDefaultingToZero "[AO_ALSA] Invalid mixer index. Defaulting to 0.\n"
 #define MSGTR_AO_ALSA_MixerOpenError "[AO_ALSA] Mixer open error: %s\n"
@@ -1337,7 +1368,6 @@
 // ========================== INPUT =========================================
 
 // joystick.c
-#define MSGTR_INPUT_JOYSTICK_Opening "Opening joystick device %s\n"
 #define MSGTR_INPUT_JOYSTICK_CantOpen "Can't open joystick device %s: %s\n"
 #define MSGTR_INPUT_JOYSTICK_ErrReading "Error while reading joystick device: %s\n"
 #define MSGTR_INPUT_JOYSTICK_LoosingBytes "Joystick: We lose %d bytes of data\n"
@@ -1345,8 +1375,6 @@
 #define MSGTR_INPUT_JOYSTICK_WarnUnknownEvent "Joystick warning unknown event type %d\n"
 
 // appleir.c
-#define MSGTR_INPUT_APPLE_IR_Init "Initializing Apple IR on %s\n"
-#define MSGTR_INPUT_APPLE_IR_Detect "Detected Apple IR on %s\n"
 #define MSGTR_INPUT_APPLE_IR_CantOpen "Can't open Apple IR device: %s\n"
 
 // input.c
@@ -1373,12 +1401,10 @@
 #define MSGTR_INPUT_INPUT_ErrBuffer2SmallForCmd "Buffer is too small for command %s\n"
 #define MSGTR_INPUT_INPUT_ErrWhyHere "What are we doing here?\n"
 #define MSGTR_INPUT_INPUT_ErrCantInitJoystick "Can't init input joystick\n"
-#define MSGTR_INPUT_INPUT_ErrCantStatFile "Can't stat %s: %s\n"
 #define MSGTR_INPUT_INPUT_ErrCantOpenFile "Can't open %s: %s\n"
 #define MSGTR_INPUT_INPUT_ErrCantInitAppleRemote "Can't init Apple Remote.\n"
 
 // lirc.c
-#define MSGTR_SettingUpLIRC "Setting up LIRC support...\n"
 #define MSGTR_LIRCopenfailed "Failed to open LIRC support. You will not be able to use your remote control.\n"
 #define MSGTR_LIRCcfgerr "Failed to read LIRC config file %s.\n"
 
@@ -1393,7 +1419,6 @@
 #define MSGTR_WarningLenIsntDivisible "Warning, len isn't divisible by samplesize!\n"
 #define MSGTR_MuxbufMallocErr "Muxer frame buffer cannot allocate memory!\n"
 #define MSGTR_MuxbufReallocErr "Muxer frame buffer cannot reallocate memory!\n"
-#define MSGTR_MuxbufSending "Muxer frame buffer sending %d frame(s) to the muxer.\n"
 #define MSGTR_WritingHeader "Writing header...\n"
 #define MSGTR_WritingTrailer "Writing index...\n"
 
@@ -1411,7 +1436,6 @@
 #define MSGTR_ON2AviFormat "ON2 AVI format"
 #define MSGTR_Detected_XXX_FileFormat "%s file format detected.\n"
 #define MSGTR_DetectedAudiofile "Audio file detected.\n"
-#define MSGTR_NotSystemStream "Not MPEG System Stream format... (maybe Transport Stream?)\n"
 #define MSGTR_InvalidMPEGES "Invalid MPEG-ES stream??? Contact the author, it may be a bug :(\n"
 #define MSGTR_FormatNotRecognized "============ Sorry, this file format is not recognized/supported =============\n"\
                                   "=== If this file is an AVI, ASF or MPEG stream, please contact the author! ===\n"
@@ -1436,11 +1460,8 @@
 #define MSGTR_MOVcomprhdr "MOV: Compressed headers support requires ZLIB!\n"
 #define MSGTR_MOVvariableFourCC "MOV: WARNING: Variable FourCC detected!?\n"
 #define MSGTR_MOVtooManyTrk "MOV: WARNING: too many tracks"
-#define MSGTR_FoundAudioStream "==> Found audio stream: %d\n"
-#define MSGTR_FoundVideoStream "==> Found video stream: %d\n"
 #define MSGTR_DetectedTV "TV detected! ;-)\n"
 #define MSGTR_ErrorOpeningOGGDemuxer "Unable to open the Ogg demuxer.\n"
-#define MSGTR_ASFSearchingForAudioStream "ASF: Searching for audio stream (id:%d).\n"
 #define MSGTR_CannotOpenAudioStream "Cannot open audio stream: %s\n"
 #define MSGTR_CannotOpenSubtitlesStream "Cannot open subtitle stream: %s\n"
 #define MSGTR_OpeningAudioDemuxerFailed "Failed to open audio demuxer: %s\n"
@@ -1453,7 +1474,7 @@
 #define MSGTR_EnterTelecineMode "\ndemux_mpg: 24000/1001fps progressive NTSC content detected, switching framerate.\n"
 
 #define MSGTR_CacheFill "\rCache fill: %5.2f%% (%"PRId64" bytes)   "
-#define MSGTR_NoBindFound "No bind found for key '%s'."
+#define MSGTR_NoBindFound "No bind found for key '%s'.\n"
 #define MSGTR_FailedToOpen "Failed to open %s.\n"
 
 #define MSGTR_VideoID "[%s] Video stream found, -vid %d\n"
@@ -1473,17 +1494,7 @@
 
 // aviheader.c
 #define MSGTR_MPDEMUX_AVIHDR_EmptyList "** empty list?!\n"
-#define MSGTR_MPDEMUX_AVIHDR_FoundMovieAt "Found movie at 0x%X - 0x%X\n"
-#define MSGTR_MPDEMUX_AVIHDR_FoundBitmapInfoHeader "Found 'bih', %u bytes of %d\n"
-#define MSGTR_MPDEMUX_AVIHDR_RegeneratingKeyfTableForMPG4V1 "Regenerating keyframe table for M$ mpg4v1 video.\n"
-#define MSGTR_MPDEMUX_AVIHDR_RegeneratingKeyfTableForDIVX3 "Regenerating keyframe table for DIVX3 video.\n"
-#define MSGTR_MPDEMUX_AVIHDR_RegeneratingKeyfTableForMPEG4 "Regenerating keyframe table for MPEG-4 video.\n"
-#define MSGTR_MPDEMUX_AVIHDR_FoundWaveFmt "Found 'wf', %d bytes of %d\n"
-#define MSGTR_MPDEMUX_AVIHDR_FoundAVIV2Header "AVI: dmlh found (size=%d) (total_frames=%d)\n"
-#define MSGTR_MPDEMUX_AVIHDR_ReadingIndexBlockChunksForFrames "Reading INDEX block, %d chunks for %d frames (fpos=%"PRId64").\n"
-#define MSGTR_MPDEMUX_AVIHDR_AdditionalRIFFHdr "Additional RIFF header...\n"
 #define MSGTR_MPDEMUX_AVIHDR_WarnNotExtendedAVIHdr "** Warning: this is no extended AVI header..\n"
-#define MSGTR_MPDEMUX_AVIHDR_BrokenChunk "Broken chunk?  chunksize=%d  (id=%.4s)\n"
 #define MSGTR_MPDEMUX_AVIHDR_BuildingODMLidx "AVI: ODML: Building ODML index (%d superindexchunks).\n"
 #define MSGTR_MPDEMUX_AVIHDR_BrokenODMLfile "AVI: ODML: Broken (incomplete?) file detected. Will use traditional index.\n"
 #define MSGTR_MPDEMUX_AVIHDR_CantReadIdxFile "Can't read index file %s: %s\n"
@@ -1497,6 +1508,8 @@
 #define MSGTR_MPDEMUX_AVIHDR_IdxFileSaved "Saved index file: %s\n"
 
 // demux_audio.c
+#define MSGTR_MPDEMUX_AUDIO_BadID3v2TagSize "Audio demuxer: bad ID3v2 tag size: larger than stream (%u).\n"
+#define MSGTR_MPDEMUX_AUDIO_DamagedAppendedID3v2Tag "Audio demuxer: damaged appended ID3v2 tag detected.\n"
 #define MSGTR_MPDEMUX_AUDIO_UnknownFormat "Audio demuxer: unknown format %d.\n"
 
 // demux_demuxers.c
@@ -1615,21 +1628,15 @@
 
 #define MSGTR_UsingExternalPP "[PP] Using external postprocessing filter, max q = %d.\n"
 #define MSGTR_UsingCodecPP "[PP] Using codec's postprocessing, max q = %d.\n"
-#define MSGTR_VideoAttributeNotSupportedByVO_VD "Video attribute '%s' is not supported by selected vo & vd.\n"
 #define MSGTR_VideoCodecFamilyNotAvailableStr "Requested video codec family [%s] (vfm=%s) not available.\nEnable it at compilation.\n"
 #define MSGTR_AudioCodecFamilyNotAvailableStr "Requested audio codec family [%s] (afm=%s) not available.\nEnable it at compilation.\n"
 #define MSGTR_OpeningVideoDecoder "Opening video decoder: [%s] %s\n"
 #define MSGTR_SelectedVideoCodec "Selected video codec: [%s] vfm: %s (%s)\n"
 #define MSGTR_OpeningAudioDecoder "Opening audio decoder: [%s] %s\n"
 #define MSGTR_SelectedAudioCodec "Selected audio codec: [%s] afm: %s (%s)\n"
-#define MSGTR_BuildingAudioFilterChain "Building audio filter chain for %dHz/%dch/%s -> %dHz/%dch/%s...\n"
-#define MSGTR_UninitVideoStr "Uninit video: %s\n"
-#define MSGTR_UninitAudioStr "Uninit audio: %s\n"
 #define MSGTR_VDecoderInitFailed "VDecoder init failed :(\n"
 #define MSGTR_ADecoderInitFailed "ADecoder init failed :(\n"
 #define MSGTR_ADecoderPreinitFailed "ADecoder preinit failed :(\n"
-#define MSGTR_AllocatingBytesForInputBuffer "dec_audio: Allocating %d bytes for input buffer.\n"
-#define MSGTR_AllocatingBytesForOutputBuffer "dec_audio: Allocating %d + %d = %d bytes for output buffer.\n"
 
 // ad_dvdpcm.c:
 #define MSGTR_SamplesWanted "Samples of this format are needed to improve support. Please contact the developers.\n"
@@ -1645,8 +1652,6 @@
 
 // vd_dshow.c, vd_dmo.c
 #define MSGTR_DownloadCodecPackage "You need to upgrade/install the binary codecs package.\nGo to http://www.mplayerhq.hu/dload.html\n"
-#define MSGTR_DShowInitOK "INFO: Win32/DShow video codec init OK.\n"
-#define MSGTR_DMOInitOK "INFO: Win32/DMO video codec init OK.\n"
 
 // libmpcodecs/vd_dmo.c vd_dshow.c vd_vfw.c
 #define MSGTR_MPCODECS_CouldntAllocateImageForCinepakCodec "[VD_DMO] Couldn't allocate image for cinepak codec.\n"
@@ -1774,12 +1779,12 @@
 
 // ================================== stream ====================================
 
-// ai_alsa1x.c
-#define MSGTR_MPDEMUX_AIALSA1X_CannotSetSamplerate "Cannot set samplerate.\n"
-#define MSGTR_MPDEMUX_AIALSA1X_CannotSetBufferTime "Cannot set buffer time.\n"
-#define MSGTR_MPDEMUX_AIALSA1X_CannotSetPeriodTime "Cannot set period time.\n"
+// ai_alsa.c
+#define MSGTR_MPDEMUX_AIALSA_CannotSetSamplerate "Cannot set samplerate.\n"
+#define MSGTR_MPDEMUX_AIALSA_CannotSetBufferTime "Cannot set buffer time.\n"
+#define MSGTR_MPDEMUX_AIALSA_CannotSetPeriodTime "Cannot set period time.\n"
 
-// ai_alsa1x.c / ai_alsa.c
+// ai_alsa.c
 #define MSGTR_MPDEMUX_AIALSA_PcmBrokenConfig "Broken configuration for this PCM: no configurations available.\n"
 #define MSGTR_MPDEMUX_AIALSA_UnavailableAccessType "Access type not available.\n"
 #define MSGTR_MPDEMUX_AIALSA_UnavailableSampleFmt "Sample format not available.\n"
@@ -1790,7 +1795,6 @@
 #define MSGTR_MPDEMUX_AIALSA_ErrorOpeningAudio "Error opening audio: %s\n"
 #define MSGTR_MPDEMUX_AIALSA_AlsaStatusError "ALSA status error: %s"
 #define MSGTR_MPDEMUX_AIALSA_AlsaXRUN "ALSA xrun!!! (at least %.3f ms long)\n"
-#define MSGTR_MPDEMUX_AIALSA_AlsaStatus "ALSA Status:\n"
 #define MSGTR_MPDEMUX_AIALSA_AlsaXRUNPrepareError "ALSA xrun: prepare error: %s"
 #define MSGTR_MPDEMUX_AIALSA_AlsaReadWriteError "ALSA read/write error"
 
@@ -1850,7 +1854,7 @@
 #define MSGTR_MPDEMUX_ASF_UnknownASFStreamType "unknown ASF stream type\n"
 #define MSGTR_MPDEMUX_ASF_Failed2ParseHTTPResponse "Failed to parse HTTP response.\n"
 #define MSGTR_MPDEMUX_ASF_ServerReturn "Server returned %d:%s\n"
-#define MSGTR_MPDEMUX_ASF_ASFHTTPParseWarnCuttedPragma "ASF HTTP PARSE WARNING : Pragma %s cut from %zd bytes to %d\n"
+#define MSGTR_MPDEMUX_ASF_ASFHTTPParseWarnCuttedPragma "ASF HTTP PARSE WARNING : Pragma %s cut from %zu bytes to %zu\n"
 #define MSGTR_MPDEMUX_ASF_SocketWriteError "socket write error: %s\n"
 #define MSGTR_MPDEMUX_ASF_HeaderParseFailed "Failed to parse header.\n"
 #define MSGTR_MPDEMUX_ASF_NoStreamFound "No stream found.\n"
@@ -1907,6 +1911,17 @@
 #define MSGTR_CantOpenBluray "Couldn't open Blu-ray device: %s\n"
 #define MSGTR_CantOpenDVD "Couldn't open DVD device: %s (%s)\n"
 
+#define MSGTR_URLParsingFailed "URL parsing failed on url %s\n"
+#define MSGTR_FailedSetStreamOption "Failed to set stream option %s=%s\n"
+#define MSGTR_StreamNeedType "Streams need a type!\n"
+#define MSGTR_StreamProtocolNULL "Stream type %s has protocols == NULL, it's a bug\n"
+#define MSGTR_StreamCantHandleURL "No stream found to handle url %s\n"
+#define MSGTR_StreamNULLFilename "open_output_stream(), NULL filename, report this bug\n"
+#define MSGTR_StreamErrorWritingCapture "Error writing capture file: %s\n"
+#define MSGTR_StreamSeekFailed "Seek failed\n"
+#define MSGTR_StreamNotSeekable "Stream not seekable!\n"
+#define MSGTR_StreamCannotSeekBackward "Cannot seek backward in linear streams!\n"
+
 // stream_cdda.c
 #define MSGTR_MPDEMUX_CDDA_CantOpenCDDADevice "Can't open CDDA device.\n"
 #define MSGTR_MPDEMUX_CDDA_CantOpenDisc "Can't open disc.\n"
@@ -1979,21 +1994,16 @@
 // stream_bluray.c
 #define MSGTR_BlurayNoDevice "No Blu-ray device/location was specified ...\n"
 #define MSGTR_BlurayNoTitles "Can't find any Blu-ray-compatible title here.\n"
-#define MSGTR_BlurayOK "Blu-ray successfully opened.\n"
 
 // stream_radio.c
 #define MSGTR_RADIO_ChannelNamesDetected "[radio] Radio channel names detected.\n"
-#define MSGTR_RADIO_FreqRange "[radio] Allowed frequency range is %.2f-%.2f MHz.\n"
 #define MSGTR_RADIO_WrongFreqForChannel "[radio] Wrong frequency for channel %s\n"
 #define MSGTR_RADIO_WrongChannelNumberFloat "[radio] Wrong channel number: %.2f\n"
 #define MSGTR_RADIO_WrongChannelNumberInt "[radio] Wrong channel number: %d\n"
 #define MSGTR_RADIO_WrongChannelName "[radio] Wrong channel name: %s\n"
 #define MSGTR_RADIO_FreqParameterDetected "[radio] Radio frequency parameter detected.\n"
-#define MSGTR_RADIO_DoneParsingChannels "[radio] Done parsing channels.\n"
 #define MSGTR_RADIO_GetTunerFailed "[radio] Warning: ioctl get tuner failed: %s. Setting frac to %d.\n"
 #define MSGTR_RADIO_NotRadioDevice "[radio] %s is no radio device!\n"
-#define MSGTR_RADIO_TunerCapLowYes "[radio] tuner is low:yes frac=%d\n"
-#define MSGTR_RADIO_TunerCapLowNo "[radio] tuner is low:no frac=%d\n"
 #define MSGTR_RADIO_SetFreqFailed "[radio] ioctl set frequency 0x%x (%.2f) failed: %s\n"
 #define MSGTR_RADIO_GetFreqFailed "[radio] ioctl get frequency failed: %s\n"
 #define MSGTR_RADIO_SetMuteFailed "[radio] ioctl set mute failed: %s\n"
@@ -2003,27 +2013,22 @@
 #define MSGTR_RADIO_DroppingFrame "\n[radio] too bad - dropping audio frame (%d bytes)!\n"
 #define MSGTR_RADIO_BufferEmpty "[radio] grab_audio_frame: buffer empty, waiting for %d data bytes.\n"
 #define MSGTR_RADIO_AudioInitFailed "[radio] audio_in_init failed: %s\n"
-#define MSGTR_RADIO_AudioBuffer "[radio] Audio capture - buffer=%d bytes (block=%d bytes).\n"
 #define MSGTR_RADIO_AllocateBufferFailed "[radio] cannot allocate audio buffer (block=%d,buf=%d): %s\n"
 #define MSGTR_RADIO_CurrentFreq "[radio] Current frequency: %.2f\n"
 #define MSGTR_RADIO_SelectedChannel "[radio] Selected channel: %d - %s (freq: %.2f)\n"
 #define MSGTR_RADIO_ChangeChannelNoChannelList "[radio] Can not change channel: no channel list given.\n"
 #define MSGTR_RADIO_UnableOpenDevice "[radio] Unable to open '%s': %s\n"
-#define MSGTR_RADIO_RadioDevice "[radio] Radio fd: %d, %s\n"
 #define MSGTR_RADIO_InitFracFailed "[radio] init_frac failed.\n"
 #define MSGTR_RADIO_WrongFreq "[radio] Wrong frequency: %.2f\n"
 #define MSGTR_RADIO_UsingFreq "[radio] Using frequency: %.2f.\n"
 #define MSGTR_RADIO_AudioInInitFailed "[radio] audio_in_init failed.\n"
-#define MSGTR_RADIO_BufferString "[radio] %s: in buffer=%d dropped=%d\n"
 #define MSGTR_RADIO_AudioInSetupFailed "[radio] audio_in_setup call failed: %s\n"
-#define MSGTR_RADIO_CaptureStarting "[radio] Starting capture stuff.\n"
 #define MSGTR_RADIO_ClearBufferFailed "[radio] Clearing buffer failed: %s\n"
 #define MSGTR_RADIO_StreamEnableCacheFailed "[radio] Call to stream_enable_cache failed: %s\n"
 #define MSGTR_RADIO_DriverUnknownStr "[radio] Unknown driver name: %s\n"
 #define MSGTR_RADIO_DriverV4L2 "[radio] Using V4Lv2 radio interface.\n"
 #define MSGTR_RADIO_DriverV4L "[radio] Using V4Lv1 radio interface.\n"
 #define MSGTR_RADIO_DriverBSDBT848 "[radio] Using *BSD BT848 radio interface.\n"
-#define MSGTR_RADIO_AvailableDrivers "[radio] Available drivers: "
 
 //tv.c
 #define MSGTR_TV_BogusNormParameter "tv.c: norm_from_string(%s): Bogus norm parameter, setting %s.\n"
@@ -2035,30 +2040,23 @@
 " be ignored! You should try again with YV12 (which is the default\n"\
 " colorspace) and read the documentation!\n"\
 "==================================================================\n"
-#define MSGTR_TV_SelectedNormId "Selected norm id: %d\n"
-#define MSGTR_TV_SelectedNorm "Selected norm : %s\n"
 #define MSGTR_TV_CannotSetNorm "Error: Cannot set norm!\n"
 #define MSGTR_TV_MJP_WidthHeight "  MJP: width %d height %d\n"
 #define MSGTR_TV_UnableToSetWidth "Unable to set requested width: %d\n"
 #define MSGTR_TV_UnableToSetHeight "Unable to set requested height: %d\n"
 #define MSGTR_TV_NoTuner "Selected input hasn't got a tuner!\n"
 #define MSGTR_TV_UnableFindChanlist "Unable to find selected channel list! (%s)\n"
-#define MSGTR_TV_SelectedChanlist "Selected channel list: %s (including %d channels)\n"
 #define MSGTR_TV_ChannelFreqParamConflict "You can't set frequency and channel simultaneously!\n"
 #define MSGTR_TV_ChannelNamesDetected "TV channel names detected.\n"
 #define MSGTR_TV_NoFreqForChannel "Couldn't find frequency for channel %s (%s)\n"
 #define MSGTR_TV_SelectedChannel3 "Selected channel: %s - %s (freq: %.3f)\n"
 #define MSGTR_TV_SelectedChannel2 "Selected channel: %s (freq: %.3f)\n"
-#define MSGTR_TV_SelectedFrequency "Selected frequency: %lu (%.3f)\n"
-#define MSGTR_TV_RequestedChannel "Requested channel: %s\n"
 #define MSGTR_TV_UnsupportedAudioType "Audio type '%s (%x)' unsupported!\n"
-#define MSGTR_TV_AudioFormat "  TV audio: %d channels, %d bits, %d Hz\n"
 #define MSGTR_TV_AvailableDrivers "Available drivers:\n"
 #define MSGTR_TV_DriverInfo "Selected driver: %s\n name: %s\n author: %s\n comment: %s\n"
 #define MSGTR_TV_NoSuchDriver "No such driver: %s\n"
 #define MSGTR_TV_DriverAutoDetectionFailed "TV driver autodetection failed.\n"
 #define MSGTR_TV_UnknownColorOption "Unknown color option (%d) specified!\n"
-#define MSGTR_TV_CurrentFrequency "Current frequency: %lu (%.3f)\n"
 #define MSGTR_TV_NoTeletext "No teletext"
 #define MSGTR_TV_Bt848IoctlFailed "tvi_bsdbt848: Call to %s ioctl failed. Error: %s\n"
 #define MSGTR_TV_Bt848InvalidAudioRate "tvi_bsdbt848: Invalid audio rate. Error: %s\n"
@@ -2086,14 +2084,7 @@
 #define MSGTR_TVI_DS_DeviceNotFound "tvi_dshow: Device #%d not found\n"
 #define MSGTR_TVI_DS_UnableGetDeviceName "tvi_dshow: Unable to get name for device #%d\n"
 #define MSGTR_TVI_DS_UsingDevice "tvi_dshow: Using device #%d: %s\n"
-#define MSGTR_TVI_DS_DeviceName  "tvi_dshow: Device #%d: %s\n"
 #define MSGTR_TVI_DS_DirectGetFreqFailed "tvi_dshow: Unable to get frequency directly. OS built-in channels table will be used.\n"
-#define MSGTR_TVI_DS_DirectSetFreqFailed "tvi_dshow: Unable to set frequency directly. OS built-in channels table will be used.\n"
-#define MSGTR_TVI_DS_SupportedNorms "tvi_dshow: supported norms:"
-#define MSGTR_TVI_DS_AvailableVideoInputs "tvi_dshow: available video inputs:"
-#define MSGTR_TVI_DS_AvailableAudioInputs "tvi_dshow: available audio inputs:"
-//following phrase will be printed near the selected audio/video input
-#define MSGTR_TVI_DS_InputSelected "(selected)"
 #define MSGTR_TVI_DS_UnableExtractFreqTable "tvi_dshow: Unable to load frequency table from kstvtune.ax\n"
 #define MSGTR_TVI_DS_WrongDeviceParam "tvi_dshow: Wrong device parameter: %s\n"
 #define MSGTR_TVI_DS_WrongDeviceIndex "tvi_dshow: Wrong device index: %d\n"
@@ -2105,7 +2096,6 @@
 
 #define MSGTR_TVI_DS_ChangingWidthHeightNotSupported "tvi_dshow: Changing video width/height is not supported by device.\n"
 #define MSGTR_TVI_DS_SelectingInputNotSupported  "tvi_dshow: Selection of capture source is not supported by device\n"
-#define MSGTR_TVI_DS_FreqTableLoaded "tvi_dshow: loaded system (%s) frequency table for country id=%d (channels:%d).\n"
 #define MSGTR_TVI_DS_ErrorParsingAudioFormatStruct "tvi_dshow: Unable to parse audio format structure.\n"
 #define MSGTR_TVI_DS_ErrorParsingVideoFormatStruct "tvi_dshow: Unable to parse video format structure.\n"
 #define MSGTR_TVI_DS_UnableSetAudioMode "tvi_dshow: Unable to set audio mode %d. Error:0x%x\n"
diff --git a/libavfilter/libmpcodecs/img_format.c b/libavfilter/libmpcodecs/img_format.c
index ba87042..61bf898 100644
--- a/libavfilter/libmpcodecs/img_format.c
+++ b/libavfilter/libmpcodecs/img_format.c
@@ -19,53 +19,88 @@
 #include "config.h"
 #include "img_format.h"
 #include "stdio.h"
+#include "libavutil/bswap.h"
 
-const char *vo_format_name(int format)
+const char *ff_vo_format_name(int format)
 {
     static char unknown_format[20];
     switch(format)
     {
-    case IMGFMT_RGB1: return "RGB 1-bit";
-    case IMGFMT_RGB4: return "RGB 4-bit";
-    case IMGFMT_RG4B: return "RGB 4-bit per byte";
-    case IMGFMT_RGB8: return "RGB 8-bit";
-    case IMGFMT_RGB12: return "RGB 12-bit";
-    case IMGFMT_RGB15: return "RGB 15-bit";
-    case IMGFMT_RGB16: return "RGB 16-bit";
-    case IMGFMT_RGB24: return "RGB 24-bit";
-//  case IMGFMT_RGB32: return "RGB 32-bit";
+    case IMGFMT_RGB1:    return "RGB 1-bit";
+    case IMGFMT_RGB4:    return "RGB 4-bit";
+    case IMGFMT_RG4B:    return "RGB 4-bit per byte";
+    case IMGFMT_RGB8:    return "RGB 8-bit";
+    case IMGFMT_RGB12:   return "RGB 12-bit";
+    case IMGFMT_RGB15:   return "RGB 15-bit";
+    case IMGFMT_RGB16:   return "RGB 16-bit";
+    case IMGFMT_RGB24:   return "RGB 24-bit";
+//  case IMGFMT_RGB32:   return "RGB 32-bit";
     case IMGFMT_RGB48LE: return "RGB 48-bit LE";
     case IMGFMT_RGB48BE: return "RGB 48-bit BE";
-    case IMGFMT_BGR1: return "BGR 1-bit";
-    case IMGFMT_BGR4: return "BGR 4-bit";
-    case IMGFMT_BG4B: return "BGR 4-bit per byte";
-    case IMGFMT_BGR8: return "BGR 8-bit";
-    case IMGFMT_BGR12: return "BGR 12-bit";
-    case IMGFMT_BGR15: return "BGR 15-bit";
-    case IMGFMT_BGR16: return "BGR 16-bit";
-    case IMGFMT_BGR24: return "BGR 24-bit";
-//  case IMGFMT_BGR32: return "BGR 32-bit";
-    case IMGFMT_ABGR: return "ABGR";
-    case IMGFMT_BGRA: return "BGRA";
-    case IMGFMT_ARGB: return "ARGB";
-    case IMGFMT_RGBA: return "RGBA";
-    case IMGFMT_YVU9: return "Planar YVU9";
-    case IMGFMT_IF09: return "Planar IF09";
-    case IMGFMT_YV12: return "Planar YV12";
-    case IMGFMT_I420: return "Planar I420";
-    case IMGFMT_IYUV: return "Planar IYUV";
-    case IMGFMT_CLPL: return "Planar CLPL";
-    case IMGFMT_Y800: return "Planar Y800";
-    case IMGFMT_Y8: return "Planar Y8";
+    case IMGFMT_RGB64LE: return "RGB 64-bit LE";
+    case IMGFMT_RGB64BE: return "RGB 64-bit BE";
+    case IMGFMT_BGR1:    return "BGR 1-bit";
+    case IMGFMT_BGR4:    return "BGR 4-bit";
+    case IMGFMT_BG4B:    return "BGR 4-bit per byte";
+    case IMGFMT_BGR8:    return "BGR 8-bit";
+    case IMGFMT_BGR12:   return "BGR 12-bit";
+    case IMGFMT_BGR15:   return "BGR 15-bit";
+    case IMGFMT_BGR16:   return "BGR 16-bit";
+    case IMGFMT_BGR24:   return "BGR 24-bit";
+//  case IMGFMT_BGR32:   return "BGR 32-bit";
+    case IMGFMT_ABGR:    return "ABGR";
+    case IMGFMT_BGRA:    return "BGRA";
+    case IMGFMT_ARGB:    return "ARGB";
+    case IMGFMT_RGBA:    return "RGBA";
+    case IMGFMT_GBR24P:  return "Planar GBR 24-bit";
+    case IMGFMT_GBR12P:  return "Planar GBR 36-bit";
+    case IMGFMT_GBR14P:  return "Planar GBR 42-bit";
+    case IMGFMT_YVU9:    return "Planar YVU9";
+    case IMGFMT_IF09:    return "Planar IF09";
+    case IMGFMT_YV12:    return "Planar YV12";
+    case IMGFMT_I420:    return "Planar I420";
+    case IMGFMT_IYUV:    return "Planar IYUV";
+    case IMGFMT_CLPL:    return "Planar CLPL";
+    case IMGFMT_Y800:    return "Planar Y800";
+    case IMGFMT_Y8:      return "Planar Y8";
+    case IMGFMT_Y8A:     return "Planar Y8 with alpha";
+    case IMGFMT_Y16_LE:  return "Planar Y16 little-endian";
+    case IMGFMT_Y16_BE:  return "Planar Y16 big-endian";
     case IMGFMT_420P16_LE: return "Planar 420P 16-bit little-endian";
     case IMGFMT_420P16_BE: return "Planar 420P 16-bit big-endian";
+    case IMGFMT_420P14_LE: return "Planar 420P 14-bit little-endian";
+    case IMGFMT_420P14_BE: return "Planar 420P 14-bit big-endian";
+    case IMGFMT_420P12_LE: return "Planar 420P 12-bit little-endian";
+    case IMGFMT_420P12_BE: return "Planar 420P 12-bit big-endian";
+    case IMGFMT_420P10_LE: return "Planar 420P 10-bit little-endian";
+    case IMGFMT_420P10_BE: return "Planar 420P 10-bit big-endian";
+    case IMGFMT_420P9_LE:  return "Planar 420P 9-bit little-endian";
+    case IMGFMT_420P9_BE:  return "Planar 420P 9-bit big-endian";
     case IMGFMT_422P16_LE: return "Planar 422P 16-bit little-endian";
     case IMGFMT_422P16_BE: return "Planar 422P 16-bit big-endian";
+    case IMGFMT_422P14_LE: return "Planar 422P 14-bit little-endian";
+    case IMGFMT_422P14_BE: return "Planar 422P 14-bit big-endian";
+    case IMGFMT_422P12_LE: return "Planar 422P 12-bit little-endian";
+    case IMGFMT_422P12_BE: return "Planar 422P 12-bit big-endian";
+    case IMGFMT_422P10_LE: return "Planar 422P 10-bit little-endian";
+    case IMGFMT_422P10_BE: return "Planar 422P 10-bit big-endian";
+    case IMGFMT_422P9_LE:  return "Planar 422P 9-bit little-endian";
+    case IMGFMT_422P9_BE:  return "Planar 422P 9-bit big-endian";
     case IMGFMT_444P16_LE: return "Planar 444P 16-bit little-endian";
     case IMGFMT_444P16_BE: return "Planar 444P 16-bit big-endian";
+    case IMGFMT_444P14_LE: return "Planar 444P 14-bit little-endian";
+    case IMGFMT_444P14_BE: return "Planar 444P 14-bit big-endian";
+    case IMGFMT_444P12_LE: return "Planar 444P 12-bit little-endian";
+    case IMGFMT_444P12_BE: return "Planar 444P 12-bit big-endian";
+    case IMGFMT_444P10_LE: return "Planar 444P 10-bit little-endian";
+    case IMGFMT_444P10_BE: return "Planar 444P 10-bit big-endian";
+    case IMGFMT_444P9_LE:  return "Planar 444P 9-bit little-endian";
+    case IMGFMT_444P9_BE:  return "Planar 444P 9-bit big-endian";
     case IMGFMT_420A: return "Planar 420P with alpha";
     case IMGFMT_444P: return "Planar 444P";
+    case IMGFMT_444A: return "Planar 444P with alpha";
     case IMGFMT_422P: return "Planar 422P";
+    case IMGFMT_422A: return "Planar 422P with alpha";
     case IMGFMT_411P: return "Planar 411P";
     case IMGFMT_NV12: return "Planar NV12";
     case IMGFMT_NV21: return "Planar NV21";
@@ -90,33 +125,82 @@
     case IMGFMT_CLJR: return "Packed CLJR";
     case IMGFMT_YUVP: return "Packed YUVP";
     case IMGFMT_UYVP: return "Packed UYVP";
-    case IMGFMT_MPEGPES: return "Mpeg PES";
-    case IMGFMT_ZRMJPEGNI: return "Zoran MJPEG non-interlaced";
-    case IMGFMT_ZRMJPEGIT: return "Zoran MJPEG top field first";
-    case IMGFMT_ZRMJPEGIB: return "Zoran MJPEG bottom field first";
+    case IMGFMT_MPEGPES:         return "Mpeg PES";
+    case IMGFMT_ZRMJPEGNI:       return "Zoran MJPEG non-interlaced";
+    case IMGFMT_ZRMJPEGIT:       return "Zoran MJPEG top field first";
+    case IMGFMT_ZRMJPEGIB:       return "Zoran MJPEG bottom field first";
     case IMGFMT_XVMC_MOCO_MPEG2: return "MPEG1/2 Motion Compensation";
     case IMGFMT_XVMC_IDCT_MPEG2: return "MPEG1/2 Motion Compensation and IDCT";
-    case IMGFMT_VDPAU_MPEG1: return "MPEG1 VDPAU acceleration";
-    case IMGFMT_VDPAU_MPEG2: return "MPEG2 VDPAU acceleration";
-    case IMGFMT_VDPAU_H264: return "H.264 VDPAU acceleration";
-    case IMGFMT_VDPAU_MPEG4: return "MPEG-4 Part 2 VDPAU acceleration";
-    case IMGFMT_VDPAU_WMV3: return "WMV3 VDPAU acceleration";
-    case IMGFMT_VDPAU_VC1: return "VC1 VDPAU acceleration";
+    case IMGFMT_VDPAU_MPEG1:     return "MPEG1 VDPAU acceleration";
+    case IMGFMT_VDPAU_MPEG2:     return "MPEG2 VDPAU acceleration";
+    case IMGFMT_VDPAU_H264:      return "H.264 VDPAU acceleration";
+    case IMGFMT_VDPAU_MPEG4:     return "MPEG-4 Part 2 VDPAU acceleration";
+    case IMGFMT_VDPAU_WMV3:      return "WMV3 VDPAU acceleration";
+    case IMGFMT_VDPAU_VC1:       return "VC1 VDPAU acceleration";
     }
     snprintf(unknown_format,20,"Unknown 0x%04x",format);
     return unknown_format;
 }
 
-int mp_get_chroma_shift(int format, int *x_shift, int *y_shift)
+int ff_mp_get_chroma_shift(int format, int *x_shift, int *y_shift, int *component_bits)
 {
     int xs = 0, ys = 0;
     int bpp;
-    int bpp_factor = 1;
     int err = 0;
-    switch (format) {
-    case IMGFMT_420P16_LE:
-    case IMGFMT_420P16_BE:
-        bpp_factor = 2;
+    int bits = 8;
+    if ((format & 0xff0000f0) == 0x34000050)
+        format = av_bswap32(format);
+    if ((format & 0xf00000ff) == 0x50000034) {
+        switch (format >> 24) {
+        case 0x50:
+            break;
+        case 0x51:
+            bits = 16;
+            break;
+        case 0x52:
+            bits = 10;
+            break;
+        case 0x53:
+            bits = 9;
+            break;
+        default:
+            err = 1;
+            break;
+        }
+        switch (format & 0x00ffffff) {
+        case 0x00343434: // 444
+            xs = 0;
+            ys = 0;
+            break;
+        case 0x00323234: // 422
+            xs = 1;
+            ys = 0;
+            break;
+        case 0x00303234: // 420
+            xs = 1;
+            ys = 1;
+            break;
+        case 0x00313134: // 411
+            xs = 2;
+            ys = 0;
+            break;
+        case 0x00303434: // 440
+            xs = 0;
+            ys = 1;
+            break;
+        default:
+            err = 1;
+            break;
+        }
+    } else switch (format) {
+    case IMGFMT_444A:
+        xs = 0;
+        ys = 0;
+        break;
+    case IMGFMT_422A:
+        xs = 1;
+        ys = 0;
+        break;
     case IMGFMT_420A:
     case IMGFMT_I420:
     case IMGFMT_IYUV:
@@ -129,28 +213,6 @@
         xs = 2;
         ys = 2;
         break;
-    case IMGFMT_444P16_LE:
-    case IMGFMT_444P16_BE:
-        bpp_factor = 2;
-    case IMGFMT_444P:
-        xs = 0;
-        ys = 0;
-        break;
-    case IMGFMT_422P16_LE:
-    case IMGFMT_422P16_BE:
-        bpp_factor = 2;
-    case IMGFMT_422P:
-        xs = 1;
-        ys = 0;
-        break;
-    case IMGFMT_411P:
-        xs = 2;
-        ys = 0;
-        break;
-    case IMGFMT_440P:
-        xs = 0;
-        ys = 1;
-        break;
     case IMGFMT_Y8:
     case IMGFMT_Y800:
         xs = 31;
@@ -162,9 +224,10 @@
     }
     if (x_shift) *x_shift = xs;
     if (y_shift) *y_shift = ys;
+    if (component_bits) *component_bits = bits;
     bpp = 8 + ((16 >> xs) >> ys);
-    if (format == IMGFMT_420A)
+    if (format == IMGFMT_420A || format == IMGFMT_422A || format == IMGFMT_444A)
         bpp += 8;
-    bpp *= bpp_factor;
+    bpp *= (bits + 7) >> 3;
     return err ? 0 : bpp;
 }
diff --git a/libavfilter/libmpcodecs/img_format.h b/libavfilter/libmpcodecs/img_format.h
index c95ed4d..d4d64d8 100644
--- a/libavfilter/libmpcodecs/img_format.h
+++ b/libavfilter/libmpcodecs/img_format.h
@@ -36,55 +36,69 @@
 #define IMGFMT_RGB32 (IMGFMT_RGB|32)
 #define IMGFMT_RGB48LE (IMGFMT_RGB|48)
 #define IMGFMT_RGB48BE (IMGFMT_RGB|48|128)
+#define IMGFMT_RGB64LE (IMGFMT_RGB|64)
+#define IMGFMT_RGB64BE (IMGFMT_RGB|64|128)
 
 #define IMGFMT_BGR_MASK 0xFFFFFF00
 #define IMGFMT_BGR (('B'<<24)|('G'<<16)|('R'<<8))
-#define IMGFMT_BGR1 (IMGFMT_BGR|1)
-#define IMGFMT_BGR4 (IMGFMT_BGR|4)
+#define IMGFMT_BGR1  (IMGFMT_BGR|1)
+#define IMGFMT_BGR4  (IMGFMT_BGR|4)
 #define IMGFMT_BGR4_CHAR (IMGFMT_BGR|4|128) // BGR4 with 1 pixel per byte
-#define IMGFMT_BGR8 (IMGFMT_BGR|8)
+#define IMGFMT_BGR8  (IMGFMT_BGR|8)
 #define IMGFMT_BGR12 (IMGFMT_BGR|12)
 #define IMGFMT_BGR15 (IMGFMT_BGR|15)
 #define IMGFMT_BGR16 (IMGFMT_BGR|16)
 #define IMGFMT_BGR24 (IMGFMT_BGR|24)
 #define IMGFMT_BGR32 (IMGFMT_BGR|32)
 
+#define IMGFMT_GBR24P (('G'<<24)|('B'<<16)|('R'<<8)|24)
+#define IMGFMT_GBR12PLE (('G'<<24)|('B'<<16)|('R'<<8)|36)
+#define IMGFMT_GBR12PBE (('G'<<24)|('B'<<16)|('R'<<8)|36|128)
+#define IMGFMT_GBR14PLE (('G'<<24)|('B'<<16)|('R'<<8)|42)
+#define IMGFMT_GBR14PBE (('G'<<24)|('B'<<16)|('R'<<8)|42|128)
+
 #if HAVE_BIGENDIAN
-#define IMGFMT_ABGR IMGFMT_RGB32
-#define IMGFMT_BGRA (IMGFMT_RGB32|64)
-#define IMGFMT_ARGB IMGFMT_BGR32
-#define IMGFMT_RGBA (IMGFMT_BGR32|64)
+#define IMGFMT_ABGR    IMGFMT_RGB32
+#define IMGFMT_BGRA    (IMGFMT_RGB32|128)
+#define IMGFMT_ARGB    IMGFMT_BGR32
+#define IMGFMT_RGBA    (IMGFMT_BGR32|128)
+#define IMGFMT_RGB64NE IMGFMT_RGB64BE
 #define IMGFMT_RGB48NE IMGFMT_RGB48BE
 #define IMGFMT_RGB12BE IMGFMT_RGB12
-#define IMGFMT_RGB12LE (IMGFMT_RGB12|64)
+#define IMGFMT_RGB12LE (IMGFMT_RGB12|128)
 #define IMGFMT_RGB15BE IMGFMT_RGB15
-#define IMGFMT_RGB15LE (IMGFMT_RGB15|64)
+#define IMGFMT_RGB15LE (IMGFMT_RGB15|128)
 #define IMGFMT_RGB16BE IMGFMT_RGB16
-#define IMGFMT_RGB16LE (IMGFMT_RGB16|64)
+#define IMGFMT_RGB16LE (IMGFMT_RGB16|128)
 #define IMGFMT_BGR12BE IMGFMT_BGR12
-#define IMGFMT_BGR12LE (IMGFMT_BGR12|64)
+#define IMGFMT_BGR12LE (IMGFMT_BGR12|128)
 #define IMGFMT_BGR15BE IMGFMT_BGR15
-#define IMGFMT_BGR15LE (IMGFMT_BGR15|64)
+#define IMGFMT_BGR15LE (IMGFMT_BGR15|128)
 #define IMGFMT_BGR16BE IMGFMT_BGR16
-#define IMGFMT_BGR16LE (IMGFMT_BGR16|64)
+#define IMGFMT_BGR16LE (IMGFMT_BGR16|128)
+#define IMGFMT_GBR12P IMGFMT_GBR12PBE
+#define IMGFMT_GBR14P IMGFMT_GBR14PBE
 #else
-#define IMGFMT_ABGR (IMGFMT_BGR32|64)
+#define IMGFMT_ABGR (IMGFMT_BGR32|128)
 #define IMGFMT_BGRA IMGFMT_BGR32
-#define IMGFMT_ARGB (IMGFMT_RGB32|64)
+#define IMGFMT_ARGB (IMGFMT_RGB32|128)
 #define IMGFMT_RGBA IMGFMT_RGB32
+#define IMGFMT_RGB64NE IMGFMT_RGB64LE
 #define IMGFMT_RGB48NE IMGFMT_RGB48LE
-#define IMGFMT_RGB12BE (IMGFMT_RGB12|64)
+#define IMGFMT_RGB12BE (IMGFMT_RGB12|128)
 #define IMGFMT_RGB12LE IMGFMT_RGB12
-#define IMGFMT_RGB15BE (IMGFMT_RGB15|64)
+#define IMGFMT_RGB15BE (IMGFMT_RGB15|128)
 #define IMGFMT_RGB15LE IMGFMT_RGB15
-#define IMGFMT_RGB16BE (IMGFMT_RGB16|64)
+#define IMGFMT_RGB16BE (IMGFMT_RGB16|128)
 #define IMGFMT_RGB16LE IMGFMT_RGB16
-#define IMGFMT_BGR12BE (IMGFMT_BGR12|64)
+#define IMGFMT_BGR12BE (IMGFMT_BGR12|128)
 #define IMGFMT_BGR12LE IMGFMT_BGR12
-#define IMGFMT_BGR15BE (IMGFMT_BGR15|64)
+#define IMGFMT_BGR15BE (IMGFMT_BGR15|128)
 #define IMGFMT_BGR15LE IMGFMT_BGR15
-#define IMGFMT_BGR16BE (IMGFMT_BGR16|64)
+#define IMGFMT_BGR16BE (IMGFMT_BGR16|128)
 #define IMGFMT_BGR16LE IMGFMT_BGR16
+#define IMGFMT_GBR12P IMGFMT_GBR12PLE
+#define IMGFMT_GBR14P IMGFMT_GBR14PLE
 #endif
 
 /* old names for compatibility */
@@ -94,8 +108,8 @@
 #define IMGFMT_IS_RGB(fmt) (((fmt)&IMGFMT_RGB_MASK)==IMGFMT_RGB)
 #define IMGFMT_IS_BGR(fmt) (((fmt)&IMGFMT_BGR_MASK)==IMGFMT_BGR)
 
-#define IMGFMT_RGB_DEPTH(fmt) ((fmt)&0x3F)
-#define IMGFMT_BGR_DEPTH(fmt) ((fmt)&0x3F)
+#define IMGFMT_RGB_DEPTH(fmt) ((fmt)&0x7F)
+#define IMGFMT_BGR_DEPTH(fmt) ((fmt)&0x7F)
 
 
 /* Planar YUV Formats */
@@ -110,6 +124,7 @@
 #define IMGFMT_Y8   0x20203859
 #define IMGFMT_NV12 0x3231564E
 #define IMGFMT_NV21 0x3132564E
+#define IMGFMT_Y16_LE 0x20363159
 
 /* unofficial Planar Formats, FIXME if official 4CC exists */
 #define IMGFMT_444P 0x50343434
@@ -117,53 +132,123 @@
 #define IMGFMT_411P 0x50313134
 #define IMGFMT_440P 0x50303434
 #define IMGFMT_HM12 0x32314D48
+#define IMGFMT_Y16_BE 0x59313620
 
+// Gray with alpha
+#define IMGFMT_Y8A 0x59320008
 // 4:2:0 planar with alpha
 #define IMGFMT_420A 0x41303234
+// 4:2:2 planar with alpha
+#define IMGFMT_422A 0x41323234
+// 4:4:4 planar with alpha
+#define IMGFMT_444A 0x41343434
 
 #define IMGFMT_444P16_LE 0x51343434
 #define IMGFMT_444P16_BE 0x34343451
+#define IMGFMT_444P14_LE 0x54343434
+#define IMGFMT_444P14_BE 0x34343454
+#define IMGFMT_444P12_LE 0x55343434
+#define IMGFMT_444P12_BE 0x34343455
+#define IMGFMT_444P10_LE 0x52343434
+#define IMGFMT_444P10_BE 0x34343452
+#define IMGFMT_444P9_LE  0x53343434
+#define IMGFMT_444P9_BE  0x34343453
 #define IMGFMT_422P16_LE 0x51323234
 #define IMGFMT_422P16_BE 0x34323251
+#define IMGFMT_422P14_LE 0x54323234
+#define IMGFMT_422P14_BE 0x34323254
+#define IMGFMT_422P12_LE 0x55323234
+#define IMGFMT_422P12_BE 0x34323255
+#define IMGFMT_422P10_LE 0x52323234
+#define IMGFMT_422P10_BE 0x34323252
+#define IMGFMT_422P9_LE  0x53323234
+#define IMGFMT_422P9_BE  0x34323253
 #define IMGFMT_420P16_LE 0x51303234
 #define IMGFMT_420P16_BE 0x34323051
+#define IMGFMT_420P14_LE 0x54303234
+#define IMGFMT_420P14_BE 0x34323054
+#define IMGFMT_420P12_LE 0x55303234
+#define IMGFMT_420P12_BE 0x34323055
+#define IMGFMT_420P10_LE 0x52303234
+#define IMGFMT_420P10_BE 0x34323052
+#define IMGFMT_420P9_LE  0x53303234
+#define IMGFMT_420P9_BE  0x34323053
 #if HAVE_BIGENDIAN
 #define IMGFMT_444P16 IMGFMT_444P16_BE
+#define IMGFMT_444P14 IMGFMT_444P14_BE
+#define IMGFMT_444P12 IMGFMT_444P12_BE
+#define IMGFMT_444P10 IMGFMT_444P10_BE
+#define IMGFMT_444P9  IMGFMT_444P9_BE
 #define IMGFMT_422P16 IMGFMT_422P16_BE
+#define IMGFMT_422P14 IMGFMT_422P14_BE
+#define IMGFMT_422P12 IMGFMT_422P12_BE
+#define IMGFMT_422P10 IMGFMT_422P10_BE
+#define IMGFMT_422P9  IMGFMT_422P9_BE
 #define IMGFMT_420P16 IMGFMT_420P16_BE
+#define IMGFMT_420P14 IMGFMT_420P14_BE
+#define IMGFMT_420P12 IMGFMT_420P12_BE
+#define IMGFMT_420P10 IMGFMT_420P10_BE
+#define IMGFMT_420P9  IMGFMT_420P9_BE
+#define IMGFMT_Y16    IMGFMT_Y16_BE
+#define IMGFMT_IS_YUVP16_NE(fmt) IMGFMT_IS_YUVP16_BE(fmt)
 #else
 #define IMGFMT_444P16 IMGFMT_444P16_LE
+#define IMGFMT_444P14 IMGFMT_444P14_LE
+#define IMGFMT_444P12 IMGFMT_444P12_LE
+#define IMGFMT_444P10 IMGFMT_444P10_LE
+#define IMGFMT_444P9  IMGFMT_444P9_LE
 #define IMGFMT_422P16 IMGFMT_422P16_LE
+#define IMGFMT_422P14 IMGFMT_422P14_LE
+#define IMGFMT_422P12 IMGFMT_422P12_LE
+#define IMGFMT_422P10 IMGFMT_422P10_LE
+#define IMGFMT_422P9  IMGFMT_422P9_LE
 #define IMGFMT_420P16 IMGFMT_420P16_LE
+#define IMGFMT_420P14 IMGFMT_420P14_LE
+#define IMGFMT_420P12 IMGFMT_420P12_LE
+#define IMGFMT_420P10 IMGFMT_420P10_LE
+#define IMGFMT_420P9  IMGFMT_420P9_LE
+#define IMGFMT_Y16    IMGFMT_Y16_LE
+#define IMGFMT_IS_YUVP16_NE(fmt) IMGFMT_IS_YUVP16_LE(fmt)
 #endif
 
-#define IMGFMT_IS_YUVP16_LE(fmt) (((fmt  ^ IMGFMT_420P16_LE) & 0xff0000ff) == 0)
-#define IMGFMT_IS_YUVP16_BE(fmt) (((fmt  ^ IMGFMT_420P16_BE) & 0xff0000ff) == 0)
-#define IMGFMT_IS_YUVP16_NE(fmt) (((fmt  ^ IMGFMT_420P16   ) & 0xff0000ff) == 0)
+#define IMGFMT_IS_YUVP16_LE(fmt) (((fmt - 0x51000034) & 0xfc0000ff) == 0)
+#define IMGFMT_IS_YUVP16_BE(fmt) (((fmt - 0x34000051) & 0xff0000fc) == 0)
 #define IMGFMT_IS_YUVP16(fmt)    (IMGFMT_IS_YUVP16_LE(fmt) || IMGFMT_IS_YUVP16_BE(fmt))
 
+/**
+ * \brief Find the corresponding full 16 bit format, i.e. IMGFMT_420P10_LE -> IMGFMT_420P16_LE
+ * \return normalized format ID or 0 if none exists.
+ */
+static inline int normalize_yuvp16(int fmt) {
+    if (IMGFMT_IS_YUVP16_LE(fmt))
+        return (fmt & 0x00ffffff) | 0x51000000;
+    if (IMGFMT_IS_YUVP16_BE(fmt))
+        return (fmt & 0xffffff00) | 0x00000051;
+    return 0;
+}
+
 /* Packed YUV Formats */
 
-#define IMGFMT_IUYV 0x56595549
-#define IMGFMT_IY41 0x31435949
+#define IMGFMT_IUYV 0x56595549 // Interlaced UYVY
+#define IMGFMT_IY41 0x31435949 // Interlaced Y41P
 #define IMGFMT_IYU1 0x31555949
 #define IMGFMT_IYU2 0x32555949
 #define IMGFMT_UYVY 0x59565955
-#define IMGFMT_UYNV 0x564E5955
-#define IMGFMT_cyuv 0x76757963
-#define IMGFMT_Y422 0x32323459
+#define IMGFMT_UYNV 0x564E5955 // Exactly same as UYVY
+#define IMGFMT_cyuv 0x76757963 // upside-down UYVY
+#define IMGFMT_Y422 0x32323459 // Exactly same as UYVY
 #define IMGFMT_YUY2 0x32595559
-#define IMGFMT_YUNV 0x564E5559
+#define IMGFMT_YUNV 0x564E5559 // Exactly same as YUY2
 #define IMGFMT_YVYU 0x55595659
 #define IMGFMT_Y41P 0x50313459
 #define IMGFMT_Y211 0x31313259
-#define IMGFMT_Y41T 0x54313459
-#define IMGFMT_Y42T 0x54323459
-#define IMGFMT_V422 0x32323456
+#define IMGFMT_Y41T 0x54313459 // Y41P, Y lsb = transparency
+#define IMGFMT_Y42T 0x54323459 // UYVY, Y lsb = transparency
+#define IMGFMT_V422 0x32323456 // upside-down UYVY?
 #define IMGFMT_V655 0x35353656
 #define IMGFMT_CLJR 0x524A4C43
-#define IMGFMT_YUVP 0x50565559
-#define IMGFMT_UYVP 0x50565955
+#define IMGFMT_YUVP 0x50565559 // 10-bit YUYV
+#define IMGFMT_UYVP 0x50565955 // 10-bit UYVY
 
 /* Compressed Formats */
 #define IMGFMT_MPEGPES (('M'<<24)|('P'<<16)|('E'<<8)|('S'))
@@ -202,13 +287,14 @@
     int timestamp; // pts, 90000 Hz counter based
 } vo_mpegpes_t;
 
-const char *vo_format_name(int format);
+const char *ff_vo_format_name(int format);
 
 /**
  * Calculates the scale shifts for the chroma planes for planar YUV
  *
+ * \param component_bits bits per component
  * \return bits-per-pixel for format if successful (i.e. format is 3 or 4-planes planar YUV), 0 otherwise
  */
-int mp_get_chroma_shift(int format, int *x_shift, int *y_shift);
+int ff_mp_get_chroma_shift(int format, int *x_shift, int *y_shift, int *component_bits);
 
 #endif /* MPLAYER_IMG_FORMAT_H */
diff --git a/libavfilter/libmpcodecs/mp_image.c b/libavfilter/libmpcodecs/mp_image.c
index bd6d33f..100ace9 100644
--- a/libavfilter/libmpcodecs/mp_image.c
+++ b/libavfilter/libmpcodecs/mp_image.c
@@ -31,8 +31,13 @@
 
 #include "libvo/fastmemcpy.h"
 //#include "libavutil/mem.h"
+#include "libavutil/imgutils.h"
 
-void mp_image_alloc_planes(mp_image_t *mpi) {
+void ff_mp_image_alloc_planes(mp_image_t *mpi) {
+    uint32_t temp[256];
+    if (avpriv_set_systematic_pal2(temp, ff_mp2ff_pix_fmt(mpi->imgfmt)) >= 0)
+        mpi->flags |= MP_IMGFLAG_RGB_PALETTE;
+
   // IF09 - allocate space for 4. plane delta info - unused
   if (mpi->imgfmt == IMGFMT_IF09) {
     mpi->planes[0]=av_malloc(mpi->bpp*mpi->width*(mpi->height+2)/8+
@@ -65,22 +70,24 @@
     }
   } else {
     mpi->stride[0]=mpi->width*mpi->bpp/8;
-    if (mpi->flags & MP_IMGFLAG_RGB_PALETTE)
+    if (mpi->flags & MP_IMGFLAG_RGB_PALETTE) {
       mpi->planes[1] = av_malloc(1024);
+      memcpy(mpi->planes[1], temp, 1024);
+    }
   }
   mpi->flags|=MP_IMGFLAG_ALLOCATED;
 }
 
-mp_image_t* alloc_mpi(int w, int h, unsigned long int fmt) {
-  mp_image_t* mpi = new_mp_image(w,h);
+mp_image_t* ff_alloc_mpi(int w, int h, unsigned long int fmt) {
+  mp_image_t* mpi = ff_new_mp_image(w,h);
 
-  mp_image_setfmt(mpi,fmt);
-  mp_image_alloc_planes(mpi);
+  ff_mp_image_setfmt(mpi,fmt);
+  ff_mp_image_alloc_planes(mpi);
 
   return mpi;
 }
 
-void copy_mpi(mp_image_t *dmpi, mp_image_t *mpi) {
+void ff_copy_mpi(mp_image_t *dmpi, mp_image_t *mpi) {
   if(mpi->flags&MP_IMGFLAG_PLANAR){
     memcpy_pic(dmpi->planes[0],mpi->planes[0], mpi->w, mpi->h,
                dmpi->stride[0],mpi->stride[0]);
@@ -95,7 +102,7 @@
   }
 }
 
-void mp_image_setfmt(mp_image_t* mpi,unsigned int out_fmt){
+void ff_mp_image_setfmt(mp_image_t* mpi,unsigned int out_fmt){
     mpi->flags&=~(MP_IMGFLAG_PLANAR|MP_IMGFLAG_YUV|MP_IMGFLAG_SWAPPED);
     mpi->imgfmt=out_fmt;
     // compressed formats
@@ -121,11 +128,24 @@
         mpi->flags|=MP_IMGFLAG_SWAPPED;
         return;
     }
-    mpi->flags|=MP_IMGFLAG_YUV;
     mpi->num_planes=3;
-    if (mp_get_chroma_shift(out_fmt, NULL, NULL)) {
+    if (out_fmt == IMGFMT_GBR24P) {
+        mpi->bpp=24;
         mpi->flags|=MP_IMGFLAG_PLANAR;
-        mpi->bpp = mp_get_chroma_shift(out_fmt, &mpi->chroma_x_shift, &mpi->chroma_y_shift);
+        return;
+    } else if (out_fmt == IMGFMT_GBR12P) {
+        mpi->bpp=36;
+        mpi->flags|=MP_IMGFLAG_PLANAR;
+        return;
+    } else if (out_fmt == IMGFMT_GBR14P) {
+        mpi->bpp=42;
+        mpi->flags|=MP_IMGFLAG_PLANAR;
+        return;
+    }
+    mpi->flags|=MP_IMGFLAG_YUV;
+    if (ff_mp_get_chroma_shift(out_fmt, NULL, NULL, NULL)) {
+        mpi->flags|=MP_IMGFLAG_PLANAR;
+        mpi->bpp = ff_mp_get_chroma_shift(out_fmt, &mpi->chroma_x_shift, &mpi->chroma_y_shift, NULL);
         mpi->chroma_width  = mpi->width  >> mpi->chroma_x_shift;
         mpi->chroma_height = mpi->height >> mpi->chroma_y_shift;
     }
@@ -136,6 +156,8 @@
     case IMGFMT_YV12:
         return;
     case IMGFMT_420A:
+    case IMGFMT_422A:
+    case IMGFMT_444A:
     case IMGFMT_IF09:
         mpi->num_planes=4;
     case IMGFMT_YVU9:
@@ -145,20 +167,51 @@
     case IMGFMT_440P:
     case IMGFMT_444P16_LE:
     case IMGFMT_444P16_BE:
+    case IMGFMT_444P14_LE:
+    case IMGFMT_444P14_BE:
+    case IMGFMT_444P12_LE:
+    case IMGFMT_444P12_BE:
+    case IMGFMT_444P10_LE:
+    case IMGFMT_444P10_BE:
+    case IMGFMT_444P9_LE:
+    case IMGFMT_444P9_BE:
     case IMGFMT_422P16_LE:
     case IMGFMT_422P16_BE:
+    case IMGFMT_422P14_LE:
+    case IMGFMT_422P14_BE:
+    case IMGFMT_422P12_LE:
+    case IMGFMT_422P12_BE:
+    case IMGFMT_422P10_LE:
+    case IMGFMT_422P10_BE:
+    case IMGFMT_422P9_LE:
+    case IMGFMT_422P9_BE:
     case IMGFMT_420P16_LE:
     case IMGFMT_420P16_BE:
+    case IMGFMT_420P14_LE:
+    case IMGFMT_420P14_BE:
+    case IMGFMT_420P12_LE:
+    case IMGFMT_420P12_BE:
+    case IMGFMT_420P10_LE:
+    case IMGFMT_420P10_BE:
+    case IMGFMT_420P9_LE:
+    case IMGFMT_420P9_BE:
         return;
+    case IMGFMT_Y16_LE:
+    case IMGFMT_Y16_BE:
+        mpi->bpp=16;
     case IMGFMT_Y800:
     case IMGFMT_Y8:
         /* they're planar ones, but for easier handling use them as packed */
         mpi->flags&=~MP_IMGFLAG_PLANAR;
         mpi->num_planes=1;
         return;
+    case IMGFMT_Y8A:
+        mpi->num_planes=2;
+        return;
     case IMGFMT_UYVY:
         mpi->flags|=MP_IMGFLAG_SWAPPED;
     case IMGFMT_YUY2:
+        mpi->chroma_x_shift = 1;
         mpi->bpp=16;
         mpi->num_planes=1;
         return;
@@ -174,11 +227,11 @@
         mpi->chroma_y_shift=1;
         return;
     }
-    mp_msg(MSGT_DECVIDEO,MSGL_WARN,"mp_image: unknown out_fmt: 0x%X\n",out_fmt);
+    ff_mp_msg(MSGT_DECVIDEO,MSGL_WARN,"mp_image: unknown out_fmt: 0x%X\n",out_fmt);
     mpi->bpp=0;
 }
 
-mp_image_t* new_mp_image(int w,int h){
+mp_image_t* ff_new_mp_image(int w,int h){
     mp_image_t* mpi = malloc(sizeof(mp_image_t));
     if(!mpi) return NULL; // error!
     memset(mpi,0,sizeof(mp_image_t));
@@ -187,7 +240,7 @@
     return mpi;
 }
 
-void free_mp_image(mp_image_t* mpi){
+void ff_free_mp_image(mp_image_t* mpi){
     if(!mpi) return;
     if(mpi->flags&MP_IMGFLAG_ALLOCATED){
         /* becouse we allocate the whole image in once */
diff --git a/libavfilter/libmpcodecs/mp_image.h b/libavfilter/libmpcodecs/mp_image.h
index 162f57a..aedf451 100644
--- a/libavfilter/libmpcodecs/mp_image.h
+++ b/libavfilter/libmpcodecs/mp_image.h
@@ -37,12 +37,21 @@
 #define ASMALIGN(ZEROBITS) ".p2align " #ZEROBITS "\n\t"
 #define CODEC_FLAG2_MEMC_ONLY     0x00001000 ///< Only do ME/MC (I frames -> ref, P frame -> ME+MC).
 
+enum AVPixelFormat ff_mp2ff_pix_fmt(int mp);
+
 //--------- codec's requirements (filled by the codec/vf) ---------
 
 //--- buffer content restrictions:
 // set if buffer content shouldn't be modified:
 #define MP_IMGFLAG_PRESERVE 0x01
-// set if buffer content will be READ for next frame's MC: (I/P mpeg frames)
+// set if buffer content will be READ.
+// This can be e.g. for next frame's MC: (I/P mpeg frames) -
+// then in combination with MP_IMGFLAG_PRESERVE - or it
+// can be because a video filter or codec will read a significant
+// amount of data while processing that frame (e.g. blending something
+// onto the frame, MV based intra prediction).
+// A frame marked like this should not be placed in to uncachable
+// video RAM for example.
 #define MP_IMGFLAG_READABLE 0x02
 
 //--- buffer width/stride/plane restrictions: (used for direct rendering)
@@ -62,14 +71,14 @@
 
 #define MP_IMGFLAGMASK_RESTRICTIONS 0xFF
 
-//--------- color info (filled by mp_image_setfmt() ) -----------
+//--------- color info (filled by ff_mp_image_setfmt() ) -----------
 // set if number of planes > 1
 #define MP_IMGFLAG_PLANAR 0x100
 // set if it's YUV colorspace
 #define MP_IMGFLAG_YUV 0x200
 // set if it's swapped (BGR or YVU) plane/byteorder
 #define MP_IMGFLAG_SWAPPED 0x400
-// set if you want memory for palette allocated and managed by vf_get_image etc.
+// set if you want memory for palette allocated and managed by ff_vf_get_image etc.
 #define MP_IMGFLAG_RGB_PALETTE 0x800
 
 #define MP_IMGFLAGMASK_COLORS 0xF00
@@ -139,12 +148,12 @@
     void* priv;
 } mp_image_t;
 
-void mp_image_setfmt(mp_image_t* mpi,unsigned int out_fmt);
-mp_image_t* new_mp_image(int w,int h);
-void free_mp_image(mp_image_t* mpi);
+void ff_mp_image_setfmt(mp_image_t* mpi,unsigned int out_fmt);
+mp_image_t* ff_new_mp_image(int w,int h);
+void ff_free_mp_image(mp_image_t* mpi);
 
-mp_image_t* alloc_mpi(int w, int h, unsigned long int fmt);
-void mp_image_alloc_planes(mp_image_t *mpi);
-void copy_mpi(mp_image_t *dmpi, mp_image_t *mpi);
+mp_image_t* ff_alloc_mpi(int w, int h, unsigned long int fmt);
+void ff_mp_image_alloc_planes(mp_image_t *mpi);
+void ff_copy_mpi(mp_image_t *dmpi, mp_image_t *mpi);
 
 #endif /* MPLAYER_MP_IMAGE_H */
diff --git a/libavfilter/libmpcodecs/mp_msg.h b/libavfilter/libmpcodecs/mp_msg.h
index 7b6405b..51cdff3 100644
--- a/libavfilter/libmpcodecs/mp_msg.h
+++ b/libavfilter/libmpcodecs/mp_msg.h
@@ -129,36 +129,38 @@
 #define MSGT_MAX 64
 
 
-extern char *mp_msg_charset;
-extern int mp_msg_color;
-extern int mp_msg_module;
+extern char *ff_mp_msg_charset;
+extern int ff_mp_msg_color;
+extern int ff_mp_msg_module;
 
-extern int mp_msg_levels[MSGT_MAX];
-extern int mp_msg_level_all;
+extern int ff_mp_msg_levels[MSGT_MAX];
+extern int ff_mp_msg_level_all;
 
 
-void mp_msg_init(void);
-int mp_msg_test(int mod, int lev);
+void ff_mp_msg_init(void);
+int ff_mp_msg_test(int mod, int lev);
 
 #include "config.h"
 
-void mp_msg_va(int mod, int lev, const char *format, va_list va);
+void ff_mp_msg_va(int mod, int lev, const char *format, va_list va);
 #ifdef __GNUC__
-void mp_msg(int mod, int lev, const char *format, ... ) __attribute__ ((format (printf, 3, 4)));
+void ff_mp_msg(int mod, int lev, const char *format, ... ) __attribute__ ((format (printf, 3, 4)));
 #   ifdef MP_DEBUG
-#      define mp_dbg(mod,lev, args... ) mp_msg(mod, lev, ## args )
+#      define mp_dbg(mod,lev, args... ) ff_mp_msg(mod, lev, ## args )
 #   else
-#      define mp_dbg(mod,lev, args... ) /* only useful for developers */
+       // only useful for developers, disable but check syntax
+#      define mp_dbg(mod,lev, args... ) do { if (0) ff_mp_msg(mod, lev, ## args ); } while (0)
 #   endif
 #else // not GNU C
-void mp_msg(int mod, int lev, const char *format, ... );
+void ff_mp_msg(int mod, int lev, const char *format, ... );
 #   ifdef MP_DEBUG
-#      define mp_dbg(mod,lev, ... ) mp_msg(mod, lev, __VA_ARGS__)
+#      define mp_dbg(mod,lev, ... ) ff_mp_msg(mod, lev, __VA_ARGS__)
 #   else
-#      define mp_dbg(mod,lev, ... ) /* only useful for developers */
+       // only useful for developers, disable but check syntax
+#      define mp_dbg(mod,lev, ... ) do { if (0) ff_mp_msg(mod, lev, __VA_ARGS__); } while (0)
 #   endif
 #endif /* __GNUC__ */
 
-const char* filename_recode(const char* filename);
+const char* ff_filename_recode(const char* filename);
 
 #endif /* MPLAYER_MP_MSG_H */
diff --git a/libavfilter/libmpcodecs/pullup.c b/libavfilter/libmpcodecs/pullup.c
index c1c4e0f..b5fae9b 100644
--- a/libavfilter/libmpcodecs/pullup.c
+++ b/libavfilter/libmpcodecs/pullup.c
@@ -19,9 +19,10 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+
+#include "libavutil/x86/asm.h"
 #include "config.h"
 #include "pullup.h"
-#include "cpudetect.h"
 
 
 
@@ -288,7 +289,7 @@
     }
 }
 
-struct pullup_buffer *pullup_lock_buffer(struct pullup_buffer *b, int parity)
+struct pullup_buffer *ff_pullup_lock_buffer(struct pullup_buffer *b, int parity)
 {
     if (!b) return 0;
     if ((parity+1) & 1) b->lock[0]++;
@@ -296,14 +297,14 @@
     return b;
 }
 
-void pullup_release_buffer(struct pullup_buffer *b, int parity)
+void ff_pullup_release_buffer(struct pullup_buffer *b, int parity)
 {
     if (!b) return;
     if ((parity+1) & 1) b->lock[0]--;
     if ((parity+1) & 2) b->lock[1]--;
 }
 
-struct pullup_buffer *pullup_get_buffer(struct pullup_context *c, int parity)
+struct pullup_buffer *ff_pullup_get_buffer(struct pullup_context *c, int parity)
 {
     int i;
 
@@ -311,7 +312,7 @@
     if (parity < 2 && c->last && parity != c->last->parity
         && !c->last->buffer->lock[parity]) {
         alloc_buffer(c, c->last->buffer);
-        return pullup_lock_buffer(c->last->buffer, parity);
+        return ff_pullup_lock_buffer(c->last->buffer, parity);
     }
 
     /* Prefer a buffer with both fields open */
@@ -319,7 +320,7 @@
         if (c->buffers[i].lock[0]) continue;
         if (c->buffers[i].lock[1]) continue;
         alloc_buffer(c, &c->buffers[i]);
-        return pullup_lock_buffer(&c->buffers[i], parity);
+        return ff_pullup_lock_buffer(&c->buffers[i], parity);
     }
 
     if (parity == 2) return 0;
@@ -329,7 +330,7 @@
         if (((parity+1) & 1) && c->buffers[i].lock[0]) continue;
         if (((parity+1) & 2) && c->buffers[i].lock[1]) continue;
         alloc_buffer(c, &c->buffers[i]);
-        return pullup_lock_buffer(&c->buffers[i], parity);
+        return ff_pullup_lock_buffer(&c->buffers[i], parity);
     }
 
     return 0;
@@ -412,7 +413,7 @@
     }
 }
 
-void pullup_submit_field(struct pullup_context *c, struct pullup_buffer *b, int parity)
+void ff_pullup_submit_field(struct pullup_context *c, struct pullup_buffer *b, int parity)
 {
     struct pullup_field *f;
 
@@ -424,7 +425,7 @@
 
     f = c->head;
     f->parity = parity;
-    f->buffer = pullup_lock_buffer(b, parity);
+    f->buffer = ff_pullup_lock_buffer(b, parity);
     f->flags = 0;
     f->breaks = 0;
     f->affinity = 0;
@@ -439,12 +440,12 @@
     c->head = c->head->next;
 }
 
-void pullup_flush_fields(struct pullup_context *c)
+void ff_pullup_flush_fields(struct pullup_context *c)
 {
     struct pullup_field *f;
 
     for (f = c->first; f && f != c->head; f = f->next) {
-        pullup_release_buffer(f->buffer, f->parity);
+        ff_pullup_release_buffer(f->buffer, f->parity);
         f->buffer = 0;
     }
     c->first = c->last = 0;
@@ -644,7 +645,7 @@
 
 
 
-struct pullup_frame *pullup_get_frame(struct pullup_context *c)
+struct pullup_frame *ff_pullup_get_frame(struct pullup_context *c)
 {
     int i;
     struct pullup_frame *fr = c->frame;
@@ -683,12 +684,12 @@
         fr->ofields[fr->parity] = fr->ifields[1+aff];
         fr->ofields[fr->parity^1] = fr->ifields[1];
     }
-    pullup_lock_buffer(fr->ofields[0], 0);
-    pullup_lock_buffer(fr->ofields[1], 1);
+    ff_pullup_lock_buffer(fr->ofields[0], 0);
+    ff_pullup_lock_buffer(fr->ofields[1], 1);
 
     if (fr->ofields[0] == fr->ofields[1]) {
         fr->buffer = fr->ofields[0];
-        pullup_lock_buffer(fr->buffer, 2);
+        ff_pullup_lock_buffer(fr->buffer, 2);
         return fr;
     }
     return fr;
@@ -710,7 +711,7 @@
     }
 }
 
-void pullup_pack_frame(struct pullup_context *c, struct pullup_frame *fr)
+void ff_pullup_pack_frame(struct pullup_context *c, struct pullup_frame *fr)
 {
     int i;
     if (fr->buffer) return;
@@ -719,23 +720,23 @@
     {
         if (fr->ofields[i]->lock[i^1]) continue;
         fr->buffer = fr->ofields[i];
-        pullup_lock_buffer(fr->buffer, 2);
+        ff_pullup_lock_buffer(fr->buffer, 2);
         copy_field(c, fr->buffer, fr->ofields[i^1], i^1);
         return;
     }
-    fr->buffer = pullup_get_buffer(c, 2);
+    fr->buffer = ff_pullup_get_buffer(c, 2);
     copy_field(c, fr->buffer, fr->ofields[0], 0);
     copy_field(c, fr->buffer, fr->ofields[1], 1);
 }
 
-void pullup_release_frame(struct pullup_frame *fr)
+void ff_pullup_release_frame(struct pullup_frame *fr)
 {
     int i;
     for (i = 0; i < fr->length; i++)
-        pullup_release_buffer(fr->ifields[i], fr->parity ^ (i&1));
-    pullup_release_buffer(fr->ofields[0], 0);
-    pullup_release_buffer(fr->ofields[1], 1);
-    if (fr->buffer) pullup_release_buffer(fr->buffer, 2);
+        ff_pullup_release_buffer(fr->ifields[i], fr->parity ^ (i&1));
+    ff_pullup_release_buffer(fr->ofields[0], 0);
+    ff_pullup_release_buffer(fr->ofields[1], 1);
+    if (fr->buffer) ff_pullup_release_buffer(fr->buffer, 2);
     fr->lock--;
 }
 
@@ -744,7 +745,7 @@
 
 
 
-struct pullup_context *pullup_alloc_context(void)
+struct pullup_context *ff_pullup_alloc_context(void)
 {
     struct pullup_context *c;
 
@@ -753,7 +754,7 @@
     return c;
 }
 
-void pullup_preinit_context(struct pullup_context *c)
+void ff_pullup_preinit_context(struct pullup_context *c)
 {
     c->bpp = calloc(c->nplanes, sizeof(int));
     c->w = calloc(c->nplanes, sizeof(int));
@@ -762,7 +763,7 @@
     c->background = calloc(c->nplanes, sizeof(int));
 }
 
-void pullup_init_context(struct pullup_context *c)
+void ff_pullup_init_context(struct pullup_context *c)
 {
     int mp = c->metric_plane;
     if (c->nbuffers < 10) c->nbuffers = 10;
@@ -805,7 +806,7 @@
     }
 }
 
-void pullup_free_context(struct pullup_context *c)
+void ff_pullup_free_context(struct pullup_context *c)
 {
     struct pullup_field *f;
     free(c->buffers);
diff --git a/libavfilter/libmpcodecs/pullup.h b/libavfilter/libmpcodecs/pullup.h
index 9c74fb5..cd6ec00 100644
--- a/libavfilter/libmpcodecs/pullup.h
+++ b/libavfilter/libmpcodecs/pullup.h
@@ -83,20 +83,20 @@
 };
 
 
-struct pullup_buffer *pullup_lock_buffer(struct pullup_buffer *b, int parity);
-void pullup_release_buffer(struct pullup_buffer *b, int parity);
-struct pullup_buffer *pullup_get_buffer(struct pullup_context *c, int parity);
+struct pullup_buffer *ff_pullup_lock_buffer(struct pullup_buffer *b, int parity);
+void ff_pullup_release_buffer(struct pullup_buffer *b, int parity);
+struct pullup_buffer *ff_pullup_get_buffer(struct pullup_context *c, int parity);
 
-void pullup_submit_field(struct pullup_context *c, struct pullup_buffer *b, int parity);
-void pullup_flush_fields(struct pullup_context *c);
+void ff_pullup_submit_field(struct pullup_context *c, struct pullup_buffer *b, int parity);
+void ff_pullup_flush_fields(struct pullup_context *c);
 
-struct pullup_frame *pullup_get_frame(struct pullup_context *c);
-void pullup_pack_frame(struct pullup_context *c, struct pullup_frame *fr);
-void pullup_release_frame(struct pullup_frame *fr);
+struct pullup_frame *ff_pullup_get_frame(struct pullup_context *c);
+void ff_pullup_pack_frame(struct pullup_context *c, struct pullup_frame *fr);
+void ff_pullup_release_frame(struct pullup_frame *fr);
 
-struct pullup_context *pullup_alloc_context(void);
-void pullup_preinit_context(struct pullup_context *c);
-void pullup_init_context(struct pullup_context *c);
-void pullup_free_context(struct pullup_context *c);
+struct pullup_context *ff_pullup_alloc_context(void);
+void ff_pullup_preinit_context(struct pullup_context *c);
+void ff_pullup_init_context(struct pullup_context *c);
+void ff_pullup_free_context(struct pullup_context *c);
 
 #endif /* MPLAYER_PULLUP_H */
diff --git a/libavfilter/libmpcodecs/vf.h b/libavfilter/libmpcodecs/vf.h
index 9119b62..0d26296 100644
--- a/libavfilter/libmpcodecs/vf.h
+++ b/libavfilter/libmpcodecs/vf.h
@@ -119,35 +119,35 @@
 
 
 // functions:
-void vf_mpi_clear(mp_image_t* mpi,int x0,int y0,int w,int h);
-mp_image_t* vf_get_image(vf_instance_t* vf, unsigned int outfmt, int mp_imgtype, int mp_imgflag, int w, int h);
+void ff_vf_mpi_clear(mp_image_t* mpi,int x0,int y0,int w,int h);
+mp_image_t* ff_vf_get_image(vf_instance_t* vf, unsigned int outfmt, int mp_imgtype, int mp_imgflag, int w, int h);
 
 vf_instance_t* vf_open_plugin(const vf_info_t* const* filter_list, vf_instance_t* next, const char *name, char **args);
 vf_instance_t* vf_open_filter(vf_instance_t* next, const char *name, char **args);
-vf_instance_t* vf_add_before_vo(vf_instance_t **vf, char *name, char **args);
+vf_instance_t* ff_vf_add_before_vo(vf_instance_t **vf, char *name, char **args);
 vf_instance_t* vf_open_encoder(vf_instance_t* next, const char *name, char *args);
 
-unsigned int vf_match_csp(vf_instance_t** vfp,const unsigned int* list,unsigned int preferred);
-void vf_clone_mpi_attributes(mp_image_t* dst, mp_image_t* src);
-void vf_queue_frame(vf_instance_t *vf, int (*)(vf_instance_t *));
-int vf_output_queued_frame(vf_instance_t *vf);
+unsigned int ff_vf_match_csp(vf_instance_t** vfp,const unsigned int* list,unsigned int preferred);
+void ff_vf_clone_mpi_attributes(mp_image_t* dst, mp_image_t* src);
+void ff_vf_queue_frame(vf_instance_t *vf, int (*)(vf_instance_t *));
+int ff_vf_output_queued_frame(vf_instance_t *vf);
 
 // default wrappers:
-int vf_next_config(struct vf_instance *vf,
+int ff_vf_next_config(struct vf_instance *vf,
         int width, int height, int d_width, int d_height,
         unsigned int flags, unsigned int outfmt);
-int vf_next_control(struct vf_instance *vf, int request, void* data);
-void vf_extra_flip(struct vf_instance *vf);
-int vf_next_query_format(struct vf_instance *vf, unsigned int fmt);
-int vf_next_put_image(struct vf_instance *vf,mp_image_t *mpi, double pts);
-void vf_next_draw_slice (struct vf_instance *vf, unsigned char** src, int* stride, int w,int h, int x, int y);
+int ff_vf_next_control(struct vf_instance *vf, int request, void* data);
+void ff_vf_extra_flip(struct vf_instance *vf);
+int ff_vf_next_query_format(struct vf_instance *vf, unsigned int fmt);
+int ff_vf_next_put_image(struct vf_instance *vf,mp_image_t *mpi, double pts);
+void ff_vf_next_draw_slice (struct vf_instance *vf, unsigned char** src, int* stride, int w,int h, int x, int y);
 
-vf_instance_t* append_filters(vf_instance_t* last);
+vf_instance_t* ff_append_filters(vf_instance_t* last);
 
-void vf_uninit_filter(vf_instance_t* vf);
-void vf_uninit_filter_chain(vf_instance_t* vf);
+void ff_vf_uninit_filter(vf_instance_t* vf);
+void ff_vf_uninit_filter_chain(vf_instance_t* vf);
 
-int vf_config_wrapper(struct vf_instance *vf,
+int ff_vf_config_wrapper(struct vf_instance *vf,
                       int width, int height, int d_width, int d_height,
                       unsigned int flags, unsigned int outfmt);
 
diff --git a/libavfilter/libmpcodecs/vf_denoise3d.c b/libavfilter/libmpcodecs/vf_denoise3d.c
deleted file mode 100644
index a952a22..0000000
--- a/libavfilter/libmpcodecs/vf_denoise3d.c
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Copyright (C) 2003 Daniel Moreno <comac@comac.darktech.org>
- *
- * 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 <math.h>
-
-#include "mp_msg.h"
-#include "img_format.h"
-#include "mp_image.h"
-#include "vf.h"
-
-#define PARAM1_DEFAULT 4.0
-#define PARAM2_DEFAULT 3.0
-#define PARAM3_DEFAULT 6.0
-
-//===========================================================================//
-
-struct vf_priv_s {
-        int Coefs[4][512];
-        unsigned char *Line;
-        mp_image_t *pmpi;
-};
-
-
-/***************************************************************************/
-
-
-static int config(struct vf_instance *vf,
-        int width, int height, int d_width, int d_height,
-        unsigned int flags, unsigned int outfmt){
-
-        free(vf->priv->Line);
-        vf->priv->Line = malloc(width);
-        vf->priv->pmpi=NULL;
-//        vf->default_caps &= !VFCAP_ACCEPT_STRIDE;
-
-        return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
-}
-
-
-static void uninit(struct vf_instance *vf)
-{
-    free(vf->priv->Line);
-}
-
-#define LowPass(Prev, Curr, Coef) (Curr + Coef[Prev - Curr])
-
-static void deNoise(unsigned char *Frame,        // mpi->planes[x]
-                    unsigned char *FramePrev,    // pmpi->planes[x]
-                    unsigned char *FrameDest,    // dmpi->planes[x]
-                    unsigned char *LineAnt,      // vf->priv->Line (width bytes)
-                    int W, int H, int sStride, int pStride, int dStride,
-                    int *Horizontal, int *Vertical, int *Temporal)
-{
-    int X, Y;
-    int sLineOffs = 0, pLineOffs = 0, dLineOffs = 0;
-    unsigned char PixelAnt;
-
-    /* First pixel has no left nor top neighbor. Only previous frame */
-    LineAnt[0] = PixelAnt = Frame[0];
-    FrameDest[0] = LowPass(FramePrev[0], LineAnt[0], Temporal);
-
-    /* Fist line has no top neighbor. Only left one for each pixel and
-     * last frame */
-    for (X = 1; X < W; X++)
-    {
-        PixelAnt = LowPass(PixelAnt, Frame[X], Horizontal);
-        LineAnt[X] = PixelAnt;
-        FrameDest[X] = LowPass(FramePrev[X], LineAnt[X], Temporal);
-    }
-
-    for (Y = 1; Y < H; Y++)
-    {
-        sLineOffs += sStride, pLineOffs += pStride, dLineOffs += dStride;
-        /* First pixel on each line doesn't have previous pixel */
-        PixelAnt = Frame[sLineOffs];
-        LineAnt[0] = LowPass(LineAnt[0], PixelAnt, Vertical);
-        FrameDest[dLineOffs] = LowPass(FramePrev[pLineOffs], LineAnt[0], Temporal);
-
-        for (X = 1; X < W; X++)
-        {
-            /* The rest are normal */
-            PixelAnt = LowPass(PixelAnt, Frame[sLineOffs+X], Horizontal);
-            LineAnt[X] = LowPass(LineAnt[X], PixelAnt, Vertical);
-            FrameDest[dLineOffs+X] = LowPass(FramePrev[pLineOffs+X], LineAnt[X], Temporal);
-        }
-    }
-}
-
-
-
-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;
-        int W = mpi->w, H = mpi->h;
-
-        mp_image_t *dmpi=vf_get_image(vf->next,mpi->imgfmt,
-                MP_IMGTYPE_IP, MP_IMGFLAG_ACCEPT_STRIDE |
-                MP_IMGFLAG_PRESERVE | MP_IMGFLAG_READABLE,
-                mpi->w,mpi->h);
-
-        if(!dmpi) return 0;
-        if (!vf->priv->pmpi) vf->priv->pmpi=mpi;
-
-        deNoise(mpi->planes[0], vf->priv->pmpi->planes[0], dmpi->planes[0],
-                vf->priv->Line, W, H,
-                mpi->stride[0], vf->priv->pmpi->stride[0], dmpi->stride[0],
-                vf->priv->Coefs[0] + 256,
-                vf->priv->Coefs[0] + 256,
-                vf->priv->Coefs[1] + 256);
-        deNoise(mpi->planes[1], vf->priv->pmpi->planes[1], dmpi->planes[1],
-                vf->priv->Line, cw, ch,
-                mpi->stride[1], vf->priv->pmpi->stride[1], dmpi->stride[1],
-                vf->priv->Coefs[2] + 256,
-                vf->priv->Coefs[2] + 256,
-                vf->priv->Coefs[3] + 256);
-        deNoise(mpi->planes[2], vf->priv->pmpi->planes[2], dmpi->planes[2],
-                vf->priv->Line, cw, ch,
-                mpi->stride[2], vf->priv->pmpi->stride[2], dmpi->stride[2],
-                vf->priv->Coefs[2] + 256,
-                vf->priv->Coefs[2] + 256,
-                vf->priv->Coefs[3] + 256);
-
-        vf->priv->pmpi=dmpi; // save reference image
-        return 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 vf_next_query_format(vf, fmt);
-        }
-        return 0;
-}
-
-
-#define ABS(A) ( (A) > 0 ? (A) : -(A) )
-
-static void PrecalcCoefs(int *Ct, double Dist25)
-{
-    int i;
-    double Gamma, Simil, C;
-
-    Gamma = log(0.25) / log(1.0 - Dist25/255.0);
-
-    for (i = -256; i <= 255; i++)
-    {
-        Simil = 1.0 - ABS(i) / 255.0;
-//        Ct[256+i] = lround(pow(Simil, Gamma) * (double)i);
-        C = pow(Simil, Gamma) * (double)i;
-        Ct[256+i] = (C<0) ? (C-0.5) : (C+0.5);
-    }
-}
-
-
-static int vf_open(vf_instance_t *vf, char *args){
-        double LumSpac, LumTmp, ChromSpac, ChromTmp;
-        double Param1, Param2, Param3;
-
-        vf->config=config;
-        vf->put_image=put_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)
-        {
-            switch(sscanf(args, "%lf:%lf:%lf",
-                          &Param1, &Param2, &Param3
-                         ))
-            {
-            case 0:
-                LumSpac = PARAM1_DEFAULT;
-                LumTmp = PARAM3_DEFAULT;
-
-                ChromSpac = PARAM2_DEFAULT;
-                ChromTmp = LumTmp * ChromSpac / LumSpac;
-                break;
-
-            case 1:
-                LumSpac = Param1;
-                LumTmp = PARAM3_DEFAULT * Param1 / PARAM1_DEFAULT;
-
-                ChromSpac = PARAM2_DEFAULT * Param1 / PARAM1_DEFAULT;
-                ChromTmp = LumTmp * ChromSpac / LumSpac;
-                break;
-
-            case 2:
-                LumSpac = Param1;
-                LumTmp = PARAM3_DEFAULT * Param1 / PARAM1_DEFAULT;
-
-                ChromSpac = Param2;
-                ChromTmp = LumTmp * ChromSpac / LumSpac;
-                break;
-
-            case 3:
-                LumSpac = Param1;
-                LumTmp = Param3;
-
-                ChromSpac = Param2;
-                ChromTmp = LumTmp * ChromSpac / LumSpac;
-                break;
-
-            default:
-                LumSpac = PARAM1_DEFAULT;
-                LumTmp = PARAM3_DEFAULT;
-
-                ChromSpac = PARAM2_DEFAULT;
-                ChromTmp = LumTmp * ChromSpac / LumSpac;
-            }
-        }
-        else
-        {
-            LumSpac = PARAM1_DEFAULT;
-            LumTmp = PARAM3_DEFAULT;
-
-            ChromSpac = PARAM2_DEFAULT;
-            ChromTmp = LumTmp * ChromSpac / LumSpac;
-        }
-
-        PrecalcCoefs(vf->priv->Coefs[0], LumSpac);
-        PrecalcCoefs(vf->priv->Coefs[1], LumTmp);
-        PrecalcCoefs(vf->priv->Coefs[2], ChromSpac);
-        PrecalcCoefs(vf->priv->Coefs[3], ChromTmp);
-
-        return 1;
-}
-
-const vf_info_t vf_info_denoise3d = {
-    "3D Denoiser (variable lowpass filter)",
-    "denoise3d",
-    "Daniel Moreno",
-    "",
-    vf_open,
-    NULL
-};
-
-//===========================================================================//
diff --git a/libavfilter/libmpcodecs/vf_detc.c b/libavfilter/libmpcodecs/vf_detc.c
index 28d20e0..751e2b8 100644
--- a/libavfilter/libmpcodecs/vf_detc.c
+++ b/libavfilter/libmpcodecs/vf_detc.c
@@ -140,14 +140,14 @@
 
 static void status(int f, struct metrics *m)
 {
-        mp_msg(MSGT_VFILTER, MSGL_V, "frame %d: e=%d o=%d n=%d t=%d\n",
+        ff_mp_msg(MSGT_VFILTER, MSGL_V, "frame %d: e=%d o=%d n=%d t=%d\n",
                 f, m->even, m->odd, m->noise, m->temp);
 }
 
 static int analyze_fixed_pattern(struct vf_priv_s *p, mp_image_t *new, mp_image_t *old)
 {
         if (p->frame >= 0) p->frame = (p->frame+1)%5;
-        mp_msg(MSGT_VFILTER, MSGL_V, "frame %d\n", p->frame);
+        ff_mp_msg(MSGT_VFILTER, MSGL_V, "frame %d\n", p->frame);
         switch (p->frame) {
         case -1: case 0: case 1: case 2:
                 return TC_PROG;
@@ -176,30 +176,30 @@
                 /* We need to break at scene changes, but is this a valid test? */
                 if ((m.even > p->thres[2]) && (m.odd > p->thres[2]) && (m.temp > p->thres[3])
                         && (m.temp > 5*pm.temp) && (m.temp*2 > m.noise)) {
-                        mp_msg(MSGT_VFILTER, MSGL_V, "scene change breaking telecine!\n");
+                        ff_mp_msg(MSGT_VFILTER, MSGL_V, "scene change breaking telecine!\n");
                         p->frame = -1;
                         return TC_DROP;
                 }
                 /* Thres. is to compensate for quantization errors when noise is low */
                 if (m.noise - m.temp > -p->thres[4]) {
                         if (COMPARABLE(m.even, pm.odd)) {
-                                //mp_msg(MSGT_VFILTER, MSGL_V, "confirmed field match!\n");
+                                //ff_mp_msg(MSGT_VFILTER, MSGL_V, "confirmed field match!\n");
                                 return TC_IL2;
                         } else if ((m.even < p->thres[0]) && (m.odd < p->thres[0]) && VERYCLOSE(m.even, m.odd)
                                 && VERYCLOSE(m.noise,m.temp) && VERYCLOSE(m.noise,pm.noise)) {
-                                mp_msg(MSGT_VFILTER, MSGL_V, "interlaced frame appears in duplicate!!!\n");
+                                ff_mp_msg(MSGT_VFILTER, MSGL_V, "interlaced frame appears in duplicate!!!\n");
                                 p->pm = pm; /* hack :) */
                                 p->frame = 3;
                                 return TC_IL1;
                         }
                 } else {
-                        mp_msg(MSGT_VFILTER, MSGL_V, "mismatched telecine fields!\n");
+                        ff_mp_msg(MSGT_VFILTER, MSGL_V, "mismatched telecine fields!\n");
                         p->frame = -1;
                 }
         }
 
         if (2*m.even*m.temp < m.odd*m.noise) {
-                mp_msg(MSGT_VFILTER, MSGL_V, "caught telecine sync!\n");
+                ff_mp_msg(MSGT_VFILTER, MSGL_V, "caught telecine sync!\n");
                 p->frame = 3;
                 return TC_IL1;
         }
@@ -207,11 +207,11 @@
         if (p->frame < 3) {
                 if (m.noise > p->thres[3]) {
                         if (m.noise > 2*m.temp) {
-                                mp_msg(MSGT_VFILTER, MSGL_V, "merging fields out of sequence!\n");
+                                ff_mp_msg(MSGT_VFILTER, MSGL_V, "merging fields out of sequence!\n");
                                 return TC_IL2;
                         }
                         if ((m.noise > 2*pm.noise) && (m.even > p->thres[2]) && (m.odd > p->thres[2])) {
-                                mp_msg(MSGT_VFILTER, MSGL_V, "dropping horrible interlaced frame!\n");
+                                ff_mp_msg(MSGT_VFILTER, MSGL_V, "dropping horrible interlaced frame!\n");
                                 return TC_DROP;
                         }
                 }
@@ -220,7 +220,7 @@
         switch (p->frame) {
         case -1:
                 if (4*m.noise > 5*m.temp) {
-                        mp_msg(MSGT_VFILTER, MSGL_V, "merging fields out of sequence!\n");
+                        ff_mp_msg(MSGT_VFILTER, MSGL_V, "merging fields out of sequence!\n");
                         return TC_IL2;
                 }
         case 0:
@@ -229,7 +229,7 @@
                 return TC_PROG;
         case 3:
                 if ((m.even > p->thres[1]) && (m.even > m.odd) && (m.temp > m.noise)) {
-                        mp_msg(MSGT_VFILTER, MSGL_V, "lost telecine tracking!\n");
+                        ff_mp_msg(MSGT_VFILTER, MSGL_V, "lost telecine tracking!\n");
                         p->frame = -1;
                         return TC_PROG;
                 }
@@ -303,14 +303,14 @@
         }
 
         if (dropflag) {
-                mp_msg(MSGT_VFILTER, MSGL_V, "drop! [%d/%d=%g]\n",
+                ff_mp_msg(MSGT_VFILTER, MSGL_V, "drop! [%d/%d=%g]\n",
                         p->outframes, p->inframes, (float)p->outframes/p->inframes);
                 p->lastdrop = 0;
                 return 0;
         }
 
         p->outframes++;
-        return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
+        return ff_vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
 }
 
 static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
@@ -321,12 +321,12 @@
 
         p->inframes++;
 
-        if (p->needread) dmpi = vf_get_image(vf->next, mpi->imgfmt,
+        if (p->needread) dmpi = ff_vf_get_image(vf->next, mpi->imgfmt,
                 MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE |
                 MP_IMGFLAG_PRESERVE | MP_IMGFLAG_READABLE,
                 mpi->width, mpi->height);
         /* FIXME: is there a good way to get rid of static type? */
-        else dmpi = vf_get_image(vf->next, mpi->imgfmt,
+        else dmpi = ff_vf_get_image(vf->next, mpi->imgfmt,
                 MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE |
                 MP_IMGFLAG_PRESERVE, mpi->width, mpi->height);
 
@@ -364,7 +364,7 @@
         case IMGFMT_YV12:
         case IMGFMT_IYUV:
         case IMGFMT_I420:
-                return vf_next_query_format(vf, fmt);
+                return ff_vf_next_query_format(vf, fmt);
         }
         return 0;
 }
@@ -373,7 +373,7 @@
         int width, int height, int d_width, int d_height,
         unsigned int flags, unsigned int outfmt)
 {
-        return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
+        return ff_vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
 }
 
 static void uninit(struct vf_instance *vf)
@@ -412,7 +412,7 @@
 static void parse_args(struct vf_priv_s *p, char *args)
 {
         char *next, *orig;
-        for (args=orig=av_strdup(args); args; args=next) {
+        for (args=orig=strdup(args); args; args=next) {
                 next = strchr(args, ':');
                 if (next) *next++ = 0;
                 parse_var(p, args);
@@ -443,7 +443,7 @@
         return 1;
 }
 
-const vf_info_t vf_info_detc = {
+const vf_info_t ff_vf_info_detc = {
     "de-telecine filter",
     "detc",
     "Rich Felker",
diff --git a/libavfilter/libmpcodecs/vf_dint.c b/libavfilter/libmpcodecs/vf_dint.c
index ac5bf54..950e835 100644
--- a/libavfilter/libmpcodecs/vf_dint.c
+++ b/libavfilter/libmpcodecs/vf_dint.c
@@ -48,14 +48,14 @@
 {
     int rowsize;
 
-    vf->priv->pmpi = vf_get_image (vf->next, outfmt, MP_IMGTYPE_TEMP,
+    vf->priv->pmpi = ff_vf_get_image (vf->next, outfmt, MP_IMGTYPE_TEMP,
                                    0, width, height);
     if (!(vf->priv->pmpi->flags & MP_IMGFLAG_PLANAR) &&
         outfmt != IMGFMT_RGB32 && outfmt != IMGFMT_BGR32 &&
         outfmt != IMGFMT_RGB24 && outfmt != IMGFMT_BGR24 &&
         outfmt != IMGFMT_RGB16 && outfmt != IMGFMT_BGR16)
     {
-      mp_msg (MSGT_VFILTER, MSGL_WARN, "Drop-interlaced filter doesn't support this outfmt :(\n");
+      ff_mp_msg (MSGT_VFILTER, MSGL_WARN, "Drop-interlaced filter doesn't support this outfmt :(\n");
       return 0;
     }
     vf->priv->imgfmt = outfmt;
@@ -71,12 +71,12 @@
     if (!(vf->priv->pmpi->flags & MP_IMGFLAG_PLANAR) &&
         vf->priv->pmpi->bpp < 24 && vf->priv->diff > 31)
       vf->priv->diff = 31;
-    mp_msg (MSGT_VFILTER, MSGL_INFO, "Drop-interlaced: %dx%d diff %d / level %u\n",
+    ff_mp_msg (MSGT_VFILTER, MSGL_INFO, "Drop-interlaced: %dx%d diff %d / level %u\n",
            vf->priv->pmpi->width, vf->priv->pmpi->height,
            vf->priv->diff, (unsigned int)vf->priv->max);
 //    vf->priv->rdfr = vf->priv->dfr = 0;
     vf->priv->was_dint = 0;
-    return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
+    return ff_vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
 }
 
 static int put_image (struct vf_instance *vf, mp_image_t *mpi, double pts)
@@ -182,13 +182,13 @@
       {
         vf->priv->was_dint++;
 //      vf->priv->rdfr++;
-//      mp_msg (MSGT_VFILTER, MSGL_INFO, "DI:%d/%d ", vf->priv->rdfr, vf->priv->dfr);
+//      ff_mp_msg (MSGT_VFILTER, MSGL_INFO, "DI:%d/%d ", vf->priv->rdfr, vf->priv->dfr);
         return 0;
       }
     }
     vf->priv->was_dint = 0;
-//    mp_msg (MSGT_VFILTER, MSGL_INFO, "DI:%d/%d ", vf->priv->rdfr, vf->priv->dfr);
-    return vf_next_put_image (vf, mpi, pts);
+//    ff_mp_msg (MSGT_VFILTER, MSGL_INFO, "DI:%d/%d ", vf->priv->rdfr, vf->priv->dfr);
+    return ff_vf_next_put_image (vf, mpi, pts);
 }
 
 static int vf_open(vf_instance_t *vf, char *args){
@@ -204,7 +204,7 @@
     return 1;
 }
 
-const vf_info_t vf_info_dint = {
+const vf_info_t ff_vf_info_dint = {
     "drop interlaced frames",
     "dint",
     "A.G.",
diff --git a/libavfilter/libmpcodecs/vf_divtc.c b/libavfilter/libmpcodecs/vf_divtc.c
index 32064a5..61f6e35 100644
--- a/libavfilter/libmpcodecs/vf_divtc.c
+++ b/libavfilter/libmpcodecs/vf_divtc.c
@@ -26,6 +26,7 @@
 #include "mp_msg.h"
 #include "cpudetect.h"
 #include "libavutil/common.h"
+#include "libavutil/x86/asm.h"
 #include "mpbswap.h"
 
 #include "img_format.h"
@@ -34,7 +35,7 @@
 
 #include "libvo/fastmemcpy.h"
 
-const vf_info_t vf_info_divtc;
+const vf_info_t ff_vf_info_divtc;
 
 struct vf_priv_s
    {
@@ -265,11 +266,11 @@
    unsigned int checksum;
    double d;
 
-   dmpi=vf_get_image(vf->next, mpi->imgfmt,
+   dmpi=ff_vf_get_image(vf->next, mpi->imgfmt,
                      MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE |
                      MP_IMGFLAG_PRESERVE | MP_IMGFLAG_READABLE,
                      mpi->width, mpi->height);
-   vf_clone_mpi_attributes(dmpi, mpi);
+   ff_vf_clone_mpi_attributes(dmpi, mpi);
 
    newphase=p->phase;
 
@@ -284,7 +285,7 @@
       case 2:
          if(p->frameno/5>p->bcount)
             {
-            mp_msg(MSGT_VFILTER, MSGL_ERR,
+            ff_mp_msg(MSGT_VFILTER, MSGL_ERR,
                    "\n%s: Log file ends prematurely! "
                    "Switching to one pass mode.\n", vf->info->name);
             p->pass=0;
@@ -306,7 +307,7 @@
 
             if(f<100)
                {
-               mp_msg(MSGT_VFILTER, MSGL_INFO,
+               ff_mp_msg(MSGT_VFILTER, MSGL_INFO,
                       "\n%s: Mismatch with pass-1: %+d frame(s).\n",
                       vf->info->name, f);
 
@@ -315,7 +316,7 @@
                }
             else if(p->misscount++>=30)
                {
-               mp_msg(MSGT_VFILTER, MSGL_ERR,
+               ff_mp_msg(MSGT_VFILTER, MSGL_ERR,
                       "\n%s: Sync with pass-1 lost! "
                       "Switching to one pass mode.\n", vf->info->name);
                p->pass=0;
@@ -350,7 +351,7 @@
    if(newphase!=p->phase && ((p->phase+4)%5<n)==((newphase+4)%5<n))
       {
       p->phase=newphase;
-      mp_msg(MSGT_VFILTER, MSGL_STATUS,
+      ff_mp_msg(MSGT_VFILTER, MSGL_STATUS,
              "\n%s: Telecine phase %d.\n", vf->info->name, p->phase);
       }
 
@@ -363,21 +364,21 @@
       case 4:
          if(p->deghost>0)
             {
-            tmpi=vf_get_image(vf->next, mpi->imgfmt,
+            tmpi=ff_vf_get_image(vf->next, mpi->imgfmt,
                               MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE |
                               MP_IMGFLAG_READABLE,
                               mpi->width, mpi->height);
-            vf_clone_mpi_attributes(tmpi, mpi);
+            ff_vf_clone_mpi_attributes(tmpi, mpi);
 
             imgop(copyop, tmpi, mpi, 0);
             imgop(deghost_plane, tmpi, dmpi, p->deghost);
             imgop(copyop, dmpi, mpi, 0);
-            return vf_next_put_image(vf, tmpi, MP_NOPTS_VALUE);
+            return ff_vf_next_put_image(vf, tmpi, MP_NOPTS_VALUE);
             }
       }
 
    imgop(copyop, dmpi, mpi, 0);
-   return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
+   return ff_vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
    }
 
 static int analyze(struct vf_priv_s *p)
@@ -402,8 +403,8 @@
 
          if(!bp || !cp)
             {
-            mp_msg(MSGT_VFILTER, MSGL_FATAL, "%s: Not enough memory.\n",
-                   vf_info_divtc.name);
+            ff_mp_msg(MSGT_VFILTER, MSGL_FATAL, "%s: Not enough memory.\n",
+                   ff_vf_info_divtc.name);
             free(buf);
             free(cbuf);
             return 0;
@@ -415,8 +416,8 @@
 
    if(n <= 15)
       {
-      mp_msg(MSGT_VFILTER, MSGL_FATAL, "%s: Empty 2-pass log file.\n",
-             vf_info_divtc.name);
+      ff_mp_msg(MSGT_VFILTER, MSGL_FATAL, "%s: Empty 2-pass log file.\n",
+             ff_vf_info_divtc.name);
       free(buf);
       free(cbuf);
       return 0;
@@ -459,9 +460,9 @@
 
       p->deghost=s1>s0?deghost:0;
 
-      mp_msg(MSGT_VFILTER, MSGL_INFO,
+      ff_mp_msg(MSGT_VFILTER, MSGL_INFO,
              "%s: Deghosting %-3s (relative pattern strength %+.2fdB).\n",
-             vf_info_divtc.name,
+             ff_vf_info_divtc.name,
              p->deghost?"ON":"OFF",
              10.0*log10(s1/s0));
       }
@@ -492,8 +493,8 @@
    if(f==b)
       {
       free(buf-15);
-      mp_msg(MSGT_VFILTER, MSGL_FATAL, "%s: No telecine pattern found!\n",
-             vf_info_divtc.name);
+      ff_mp_msg(MSGT_VFILTER, MSGL_FATAL, "%s: No telecine pattern found!\n",
+             ff_vf_info_divtc.name);
       return 0;
       }
 
@@ -577,7 +578,7 @@
       case IMGFMT_411P: case IMGFMT_YUY2: case IMGFMT_IF09:
       case IMGFMT_YV12: case IMGFMT_I420: case IMGFMT_YVU9:
       case IMGFMT_IUYV: case IMGFMT_Y800: case IMGFMT_Y8:
-         return vf_next_query_format(vf,fmt);
+         return ff_vf_next_query_format(vf,fmt);
       }
 
    return 0;
@@ -601,10 +602,10 @@
    const char *filename="framediff.log";
    char *ap, *q, *a;
 
-   if(args && !(args=av_strdup(args)))
+   if(args && !(args=strdup(args)))
       {
    nomem:
-      mp_msg(MSGT_VFILTER, MSGL_FATAL,
+      ff_mp_msg(MSGT_VFILTER, MSGL_FATAL,
              "%s: Not enough memory.\n", vf->info->name);
    fail:
       uninit(vf);
@@ -643,7 +644,7 @@
                break;
 
             case 'h':
-               mp_msg(MSGT_VFILTER, MSGL_INFO,
+               ff_mp_msg(MSGT_VFILTER, MSGL_INFO,
                       "\n%s options:\n\n"
                       "pass=1|2         - Use 2-pass mode.\n"
                       "file=filename    - Set the 2-pass log file name "
@@ -663,7 +664,7 @@
                break;
 
             default:
-               mp_msg(MSGT_VFILTER, MSGL_FATAL,
+               ff_mp_msg(MSGT_VFILTER, MSGL_FATAL,
                       "%s: Unknown argument %s.\n", vf->info->name, q);
                goto fail;
             }
@@ -674,7 +675,7 @@
       case 1:
          if(!(p->file=fopen(filename, "w")))
             {
-            mp_msg(MSGT_VFILTER, MSGL_FATAL,
+            ff_mp_msg(MSGT_VFILTER, MSGL_FATAL,
                    "%s: Can't create file %s.\n", vf->info->name, filename);
             goto fail;
             }
@@ -684,7 +685,7 @@
       case 2:
          if(!(p->file=fopen(filename, "r")))
             {
-            mp_msg(MSGT_VFILTER, MSGL_FATAL,
+            ff_mp_msg(MSGT_VFILTER, MSGL_FATAL,
                    "%s: Can't open file %s.\n", vf->info->name, filename);
             goto fail;
             }
@@ -703,14 +704,14 @@
 
    diff = diff_C;
 #if HAVE_MMX && HAVE_EBX_AVAILABLE
-   if(gCpuCaps.hasMMX) diff = diff_MMX;
+   if(ff_gCpuCaps.hasMMX) diff = diff_MMX;
 #endif
 
    free(args);
    return 1;
    }
 
-const vf_info_t vf_info_divtc =
+const vf_info_t ff_vf_info_divtc =
    {
    "inverse telecine for deinterlaced video",
    "divtc",
diff --git a/libavfilter/libmpcodecs/vf_down3dright.c b/libavfilter/libmpcodecs/vf_down3dright.c
index f1e1f49..5c95ce6 100644
--- a/libavfilter/libmpcodecs/vf_down3dright.c
+++ b/libavfilter/libmpcodecs/vf_down3dright.c
@@ -101,7 +101,7 @@
         mp_image_t *dmpi;
 
         // hope we'll get DR buffer:
-        dmpi=vf_get_image(vf->next, IMGFMT_YV12,
+        dmpi=ff_vf_get_image(vf->next, IMGFMT_YV12,
                           MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE |
                           ((vf->priv->scaleh == 1) ? MP_IMGFLAG_READABLE : 0),
                           mpi->w * vf->priv->scalew,
@@ -110,7 +110,7 @@
         toright(dmpi->planes, mpi->planes, dmpi->stride,
                 mpi->stride, mpi->w, mpi->h, vf->priv);
 
-        return vf_next_put_image(vf,dmpi, pts);
+        return ff_vf_next_put_image(vf,dmpi, pts);
 }
 
 static int config(struct vf_instance *vf,
@@ -118,7 +118,7 @@
                   unsigned int flags, unsigned int outfmt)
 {
         /* FIXME - also support UYVY output? */
-        return vf_next_config(vf, width * vf->priv->scalew,
+        return ff_vf_next_config(vf, width * vf->priv->scalew,
                               height / vf->priv->scaleh - vf->priv->skipline, d_width, d_height, flags, IMGFMT_YV12);
 }
 
@@ -130,7 +130,7 @@
         case IMGFMT_YV12:
         case IMGFMT_IYUV:
         case IMGFMT_I420:
-                return vf_next_query_format(vf, IMGFMT_YV12);
+                return ff_vf_next_query_format(vf, IMGFMT_YV12);
         }
         return 0;
 }
@@ -156,7 +156,7 @@
         return 1;
 }
 
-const vf_info_t vf_info_down3dright = {
+const vf_info_t ff_vf_info_down3dright = {
         "convert stereo movie from top-bottom to left-right field",
         "down3dright",
         "Zdenek Kabelac",
diff --git a/libavfilter/libmpcodecs/vf_dsize.c b/libavfilter/libmpcodecs/vf_dsize.c
deleted file mode 100644
index 7772b37..0000000
--- a/libavfilter/libmpcodecs/vf_dsize.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * 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 "config.h"
-#include "mp_msg.h"
-
-#include "img_format.h"
-#include "mp_image.h"
-#include "vf.h"
-
-struct vf_priv_s {
-    int w, h;
-    int method; // aspect method, 0 -> downscale, 1-> upscale. +2 -> original aspect.
-    int round;
-    float aspect;
-};
-
-static int config(struct vf_instance *vf,
-    int width, int height, int d_width, int d_height,
-    unsigned int flags, unsigned int outfmt)
-{
-    if (vf->priv->aspect < 0.001) { // did the user input aspect or w,h params
-        if (vf->priv->w == 0) vf->priv->w = d_width;
-        if (vf->priv->h == 0) vf->priv->h = d_height;
-        if (vf->priv->w == -1) vf->priv->w = width;
-        if (vf->priv->h == -1) vf->priv->h = height;
-        if (vf->priv->w == -2) vf->priv->w = vf->priv->h * (double)d_width / d_height;
-        if (vf->priv->w == -3) vf->priv->w = vf->priv->h * (double)width / height;
-        if (vf->priv->h == -2) vf->priv->h = vf->priv->w * (double)d_height / d_width;
-        if (vf->priv->h == -3) vf->priv->h = vf->priv->w * (double)height / width;
-        if (vf->priv->method > -1) {
-            double aspect = (vf->priv->method & 2) ? ((double)height / width) : ((double)d_height / d_width);
-            if ((vf->priv->h > vf->priv->w * aspect) ^ (vf->priv->method & 1)) {
-                vf->priv->h = vf->priv->w * aspect;
-            } else {
-                vf->priv->w = vf->priv->h / aspect;
-            }
-        }
-        if (vf->priv->round > 1) { // round up
-            vf->priv->w += (vf->priv->round - 1 - (vf->priv->w - 1) % vf->priv->round);
-            vf->priv->h += (vf->priv->round - 1 - (vf->priv->h - 1) % vf->priv->round);
-        }
-        d_width = vf->priv->w;
-        d_height = vf->priv->h;
-    } else {
-        if (vf->priv->aspect * height > width) {
-            d_width = height * vf->priv->aspect + .5;
-            d_height = height;
-        } else {
-            d_height = width / vf->priv->aspect + .5;
-            d_width = width;
-        }
-    }
-    return vf_next_config(vf, width, height, d_width, d_height, flags, outfmt);
-}
-
-static void uninit(vf_instance_t *vf) {
-    free(vf->priv);
-    vf->priv = NULL;
-}
-
-static int vf_open(vf_instance_t *vf, char *args)
-{
-    vf->config = config;
-    vf->draw_slice = vf_next_draw_slice;
-    vf->uninit = uninit;
-    //vf->default_caps = 0;
-    vf->priv = calloc(sizeof(struct vf_priv_s), 1);
-    vf->priv->aspect = 0.;
-    vf->priv->w = -1;
-    vf->priv->h = -1;
-    vf->priv->method = -1;
-    vf->priv->round = 1;
-    if (args) {
-        if (strchr(args, '/')) {
-            int w, h;
-            sscanf(args, "%d/%d", &w, &h);
-            vf->priv->aspect = (float)w/h;
-        } else if (strchr(args, '.')) {
-            sscanf(args, "%f", &vf->priv->aspect);
-        } else {
-            sscanf(args, "%d:%d:%d:%d", &vf->priv->w, &vf->priv->h, &vf->priv->method, &vf->priv->round);
-        }
-    }
-    if ((vf->priv->aspect < 0.) || (vf->priv->w < -3) || (vf->priv->h < -3) ||
-            ((vf->priv->w < -1) && (vf->priv->h < -1)) ||
-            (vf->priv->method < -1) || (vf->priv->method > 3) ||
-            (vf->priv->round < 0)) {
-        mp_msg(MSGT_VFILTER, MSGL_ERR, "[dsize] Illegal value(s): aspect: %f w: %d h: %d aspect_method: %d round: %d\n", vf->priv->aspect, vf->priv->w, vf->priv->h, vf->priv->method, vf->priv->round);
-        free(vf->priv); vf->priv = NULL;
-        return -1;
-    }
-    return 1;
-}
-
-const vf_info_t vf_info_dsize = {
-    "reset displaysize/aspect",
-    "dsize",
-    "Rich Felker",
-    "",
-    vf_open,
-    NULL
-};
diff --git a/libavfilter/libmpcodecs/vf_eq.c b/libavfilter/libmpcodecs/vf_eq.c
index df4e851..4e256d9 100644
--- a/libavfilter/libmpcodecs/vf_eq.c
+++ b/libavfilter/libmpcodecs/vf_eq.c
@@ -129,7 +129,7 @@
 {
         mp_image_t *dmpi;
 
-        dmpi=vf_get_image(vf->next, mpi->imgfmt,
+        dmpi=ff_vf_get_image(vf->next, mpi->imgfmt,
                           MP_IMGTYPE_EXPORT, 0,
                           mpi->w, mpi->h);
 
@@ -151,7 +151,7 @@
                         vf->priv->contrast);
         }
 
-        return vf_next_put_image(vf,dmpi, pts);
+        return ff_vf_next_put_image(vf,dmpi, pts);
 }
 
 static int control(struct vf_instance *vf, int request, void* data)
@@ -182,7 +182,7 @@
                 }
                 break;
         }
-        return vf_next_control(vf, request, data);
+        return ff_vf_next_control(vf, request, data);
 }
 
 static int query_format(struct vf_instance *vf, unsigned int fmt)
@@ -201,7 +201,7 @@
         case IMGFMT_444P:
         case IMGFMT_422P:
         case IMGFMT_411P:
-                return vf_next_query_format(vf, fmt);
+                return ff_vf_next_query_format(vf, fmt);
         }
         return 0;
 }
@@ -225,13 +225,13 @@
 
         process = process_C;
 #if HAVE_MMX
-        if(gCpuCaps.hasMMX) process = process_MMX;
+        if(ff_gCpuCaps.hasMMX) process = process_MMX;
 #endif
 
         return 1;
 }
 
-const vf_info_t vf_info_eq = {
+const vf_info_t ff_vf_info_eq = {
         "soft video equalizer",
         "eq",
         "Richard Felker",
diff --git a/libavfilter/libmpcodecs/vf_eq2.c b/libavfilter/libmpcodecs/vf_eq2.c
index fe4a89f..7a3ef31 100644
--- a/libavfilter/libmpcodecs/vf_eq2.c
+++ b/libavfilter/libmpcodecs/vf_eq2.c
@@ -262,7 +262,7 @@
       eq2->buf[0] = realloc (eq2->buf[0], img_n);
   }
 
-  dst = vf_get_image (vf->next, src->imgfmt, MP_IMGTYPE_EXPORT, 0, src->w, src->h);
+  dst = ff_vf_get_image (vf->next, src->imgfmt, MP_IMGTYPE_EXPORT, 0, src->w, src->h);
 
   for (i = 0; i < ((src->num_planes>1)?3:1); i++) {
     if (eq2->param[i].adjust != NULL) {
@@ -278,7 +278,7 @@
     }
   }
 
-  return vf_next_put_image (vf, dst, pts);
+  return ff_vf_next_put_image (vf, dst, pts);
 }
 
 static
@@ -290,7 +290,7 @@
     par->adjust = NULL;
   }
 #if HAVE_MMX
-  else if (par->g == 1.0 && gCpuCaps.hasMMX) {
+  else if (par->g == 1.0 && ff_gCpuCaps.hasMMX) {
     par->adjust = &affine_1d_MMX;
   }
 #endif
@@ -302,7 +302,7 @@
 static
 void print_values (vf_eq2_t *eq2)
 {
-  mp_msg (MSGT_VFILTER, MSGL_V, "vf_eq2: c=%.2f b=%.2f g=%.4f s=%.2f \n",
+  ff_mp_msg (MSGT_VFILTER, MSGL_V, "vf_eq2: c=%.2f b=%.2f g=%.4f s=%.2f \n",
     eq2->contrast, eq2->brightness, eq2->gamma, eq2->saturation
   );
 }
@@ -413,7 +413,7 @@
       break;
   }
 
-  return vf_next_control (vf, request, data);
+  return ff_vf_next_control (vf, request, data);
 }
 
 static
@@ -430,7 +430,7 @@
     case IMGFMT_444P:
     case IMGFMT_422P:
     case IMGFMT_411P:
-      return vf_next_query_format (vf, fmt);
+      return ff_vf_next_query_format (vf, fmt);
   }
 
   return 0;
@@ -509,7 +509,7 @@
   return 1;
 }
 
-const vf_info_t vf_info_eq2 = {
+const vf_info_t ff_vf_info_eq2 = {
   "Software equalizer",
   "eq2",
   "Hampa Hug, Daniel Moreno, Richard Felker",
diff --git a/libavfilter/libmpcodecs/vf_fil.c b/libavfilter/libmpcodecs/vf_fil.c
index 7df7eb0..80c6648 100644
--- a/libavfilter/libmpcodecs/vf_fil.c
+++ b/libavfilter/libmpcodecs/vf_fil.c
@@ -59,17 +59,17 @@
     }
 //printf("hX %d %d %d\n", vf->priv->width,vf->priv->height,vf->priv->stridefactor);
 
-    return vf_next_config(vf, vf->priv->width, vf->priv->height,
+    return ff_vf_next_config(vf, vf->priv->width, vf->priv->height,
         (d_width*vf->priv->stridefactor)>>1, 2*d_height/vf->priv->stridefactor, flags, outfmt);
 }
 
 static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
     if(mpi->flags&MP_IMGFLAG_DIRECT){
         // we've used DR, so we're ready...
-        return vf_next_put_image(vf,(mp_image_t*)mpi->priv, pts);
+        return ff_vf_next_put_image(vf,(mp_image_t*)mpi->priv, pts);
     }
 
-    vf->dmpi=vf_get_image(vf->next,mpi->imgfmt,
+    vf->dmpi=ff_vf_get_image(vf->next,mpi->imgfmt,
         MP_IMGTYPE_EXPORT, MP_IMGFLAG_ACCEPT_STRIDE,
         vf->priv->width, vf->priv->height);
 
@@ -84,7 +84,7 @@
     } else
         vf->dmpi->planes[1]=mpi->planes[1]; // passthru bgr8 palette!!!
 
-    return vf_next_put_image(vf,vf->dmpi, pts);
+    return ff_vf_next_put_image(vf,vf->dmpi, pts);
 }
 
 //===========================================================================//
@@ -104,7 +104,7 @@
     return 1;
 }
 
-const vf_info_t vf_info_fil = {
+const vf_info_t ff_vf_info_fil = {
     "fast (de)interleaver",
     "fil",
     "Michael Niedermayer",
diff --git a/libavfilter/libmpcodecs/vf_filmdint.c b/libavfilter/libmpcodecs/vf_filmdint.c
index 70db246..93354e2 100644
--- a/libavfilter/libmpcodecs/vf_filmdint.c
+++ b/libavfilter/libmpcodecs/vf_filmdint.c
@@ -30,7 +30,7 @@
 #include "vd.h"
 #include "vf.h"
 #include "cmmx.h"
-
+#include "libavutil/x86/asm.h"
 #include "libvo/fastmemcpy.h"
 
 #define NUM_STORED 4
@@ -450,7 +450,7 @@
 {
     struct metrics tm;
 #if !HAVE_AMD3DNOW
-    mp_msg(MSGT_VFILTER, MSGL_FATAL, "block_metrics_3dnow: internal error\n");
+    ff_mp_msg(MSGT_VFILTER, MSGL_FATAL, "block_metrics_3dnow: internal error\n");
 #else
     static const unsigned long long ones = 0x0101010101010101ull;
 
@@ -479,7 +479,7 @@
 {
     struct metrics tm;
 #if !HAVE_MMX
-    mp_msg(MSGT_VFILTER, MSGL_FATAL, "block_metrics_mmx2: internal error\n");
+    ff_mp_msg(MSGT_VFILTER, MSGL_FATAL, "block_metrics_mmx2: internal error\n");
 #else
     static const unsigned long long ones = 0x0101010101010101ull;
     x86_reg interlaced;
@@ -587,10 +587,10 @@
         b -= 7*bs;
         cm = block_metrics_c(a, b, as, bs, 4, p, &ts);
         if (!MEQ(tm, cm))
-            mp_msg(MSGT_VFILTER, MSGL_WARN, "Bad metrics\n");
+            ff_mp_msg(MSGT_VFILTER, MSGL_WARN, "Bad metrics\n");
         if (s) {
 #           define CHECK(X) if (!MEQ(s->X, ts.X)) \
-                mp_msg(MSGT_VFILTER, MSGL_WARN, "Bad " #X "\n");
+                ff_mp_msg(MSGT_VFILTER, MSGL_WARN, "Bad " #X "\n");
             CHECK(tiny);
             CHECK(low);
             CHECK(high);
@@ -608,7 +608,7 @@
                     long cos, int ds, int ss, int w, int t)
 {
 #if !HAVE_MMX
-    mp_msg(MSGT_VFILTER, MSGL_FATAL, "dint_copy_line_mmx2: internal error\n");
+    ff_mp_msg(MSGT_VFILTER, MSGL_FATAL, "dint_copy_line_mmx2: internal error\n");
     return 0;
 #else
     unsigned long len = (w+7) >> 3;
@@ -770,7 +770,7 @@
                         p->chroma_stride, threshold, field, p->mmx2);
     }
     if (dint_pixels > 0 && p->verbose)
-        mp_msg(MSGT_VFILTER,MSGL_INFO,"Deinterlaced %lu pixels\n",dint_pixels);
+        ff_mp_msg(MSGT_VFILTER,MSGL_INFO,"Deinterlaced %lu pixels\n",dint_pixels);
 }
 
 static void diff_planes(struct vf_priv_s *p, struct frame_stats *s,
@@ -826,7 +826,7 @@
     s->sad.noise = (s->sad.noise * 16ul) / s->num_blocks;
     s->sad.temp  = (s->sad.temp  * 16ul) / s->num_blocks;
     if (p->verbose)
-        mp_msg(MSGT_VFILTER, MSGL_INFO, "%lu%c M:%d/%d/%d/%d - %d, "
+        ff_mp_msg(MSGT_VFILTER, MSGL_INFO, "%lu%c M:%d/%d/%d/%d - %d, "
                "t:%d/%d/%d/%d, l:%d/%d/%d/%d, h:%d/%d/%d/%d, bg:%d/%d/%d/%d, "
                "2x:%d/%d/%d/%d, sad:%d/%d/%d/%d, lil:%d, hil:%d, ios:%.1f\n",
                p->inframes, p->chflag, METRICS(s->max), s->num_blocks,
@@ -995,7 +995,7 @@
     unsigned long ret = 8;
 
     if (cmpe(s->sad.temp, s->sad.even, 512, 1) > 0)
-        mp_msg(MSGT_VFILTER, MSGL_WARN,
+        ff_mp_msg(MSGT_VFILTER, MSGL_WARN,
                "@@@@@@@@ Bottom-first field??? @@@@@@@@\n");
     if (s->sad.temp > 1000 && s->sad.noise > 1000)
         return 3;
@@ -1294,7 +1294,7 @@
              (ps->low.noise + ps->interlaced_low < (s->num_blocks>>8) ||
               ps->sad.noise < 160))) {
             p->export_count++;
-            dmpi = vf_get_image(vf->next, mpi->imgfmt, MP_IMGTYPE_EXPORT,
+            dmpi = ff_vf_get_image(vf->next, mpi->imgfmt, MP_IMGTYPE_EXPORT,
                                 MP_IMGFLAG_PRESERVE|MP_IMGFLAG_READABLE,
                                 p->w, p->h);
             if ((show_fields & 3) != 3) planes = old_planes;
@@ -1309,7 +1309,7 @@
             }
         } else {
             p->merge_count++;
-            dmpi = vf_get_image(vf->next, mpi->imgfmt,
+            dmpi = ff_vf_get_image(vf->next, mpi->imgfmt,
                                 MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
                                 p->w, p->h);
             copy_merge_fields(p, dmpi, old_planes, planes, show_fields);
@@ -1319,7 +1319,7 @@
         p->notout += 2;
 
     if (p->verbose)
-        mp_msg(MSGT_VFILTER, MSGL_INFO, "%lu %lu: %x %c %c %lu%s%s%c%s\n",
+        ff_mp_msg(MSGT_VFILTER, MSGL_INFO, "%lu %lu: %x %c %c %lu%s%s%c%s\n",
                p->inframes, p->outframes,
                breaks, breaks<8 && breaks>0 ? (int) p->prev_fields+'0' : ' ',
                ITOC(show_fields),
@@ -1331,7 +1331,7 @@
                "" : " @@@@@@@@@@@@@@@@@");
 
     p->merge_time += get_time() - diff_time;
-    return show_fields ? vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE) : 0;
+    return show_fields ? ff_vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE) : 0;
 }
 
 static int query_format(struct vf_instance *vf, unsigned int fmt)
@@ -1344,7 +1344,7 @@
       case IMGFMT_411P:
       case IMGFMT_422P:
       case IMGFMT_444P:
-        return vf_next_query_format(vf, fmt);
+        return ff_vf_next_query_format(vf, fmt);
     }
     return 0;
 }
@@ -1391,13 +1391,13 @@
         d_width = d_width * p->w/width;
         d_height = d_height * p->h/height;
     }
-    return vf_next_config(vf, p->w, p->h, d_width, d_height, flags, outfmt);
+    return ff_vf_next_config(vf, p->w, p->h, d_width, d_height, flags, outfmt);
 }
 
 static void uninit(struct vf_instance *vf)
 {
     struct vf_priv_s *p = vf->priv;
-    mp_msg(MSGT_VFILTER, MSGL_INFO, "diff_time: %.3f, merge_time: %.3f, "
+    ff_mp_msg(MSGT_VFILTER, MSGL_INFO, "diff_time: %.3f, merge_time: %.3f, "
            "export: %lu, merge: %lu, copy: %lu\n", p->diff_time, p->merge_time,
            p->export_count, p->merge_count, p->num_copies);
     free(p->memory_allocated);
@@ -1422,16 +1422,16 @@
     p->dint_thres = 4;
     p->luma_only = 0;
     p->fast = 3;
-    p->mmx2 = gCpuCaps.hasMMX2 ? 1 : gCpuCaps.has3DNow ? 2 : 0;
+    p->mmx2 = ff_gCpuCaps.hasMMX2 ? 1 : ff_gCpuCaps.has3DNow ? 2 : 0;
     if (args) {
         const char *args_remain = parse_args(p, args);
         if (args_remain) {
-            mp_msg(MSGT_VFILTER, MSGL_FATAL,
+            ff_mp_msg(MSGT_VFILTER, MSGL_FATAL,
                    "filmdint: unknown suboption: %s\n", args_remain);
             return 0;
         }
         if (p->out_dec < p->in_inc) {
-            mp_msg(MSGT_VFILTER, MSGL_FATAL,
+            ff_mp_msg(MSGT_VFILTER, MSGL_FATAL,
                    "filmdint: increasing the frame rate is not supported\n");
             return 0;
         }
@@ -1451,7 +1451,7 @@
     return 1;
 }
 
-const vf_info_t vf_info_filmdint = {
+const vf_info_t ff_vf_info_filmdint = {
     "Advanced inverse telecine filer",
     "filmdint",
     "Zoltan Hidvegi",
diff --git a/libavfilter/libmpcodecs/vf_fspp.c b/libavfilter/libmpcodecs/vf_fspp.c
index 3653187..a8a33e2 100644
--- a/libavfilter/libmpcodecs/vf_fspp.c
+++ b/libavfilter/libmpcodecs/vf_fspp.c
@@ -45,12 +45,13 @@
 #include "img_format.h"
 #include "mp_image.h"
 #include "vf.h"
-#include "vd_ffmpeg.h"
+#include "av_helpers.h"
 #include "libvo/fastmemcpy.h"
 
 #include "libavutil/internal.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/mem.h"
+#include "libavutil/x86/asm.h"
 #include "libavcodec/avcodec.h"
 #include "libavcodec/dsputil.h"
 
@@ -164,10 +165,10 @@
         ((short*)p->threshold_mtx)[a]=q * ((short*)p->threshold_mtx_noq)[a];//ints faster in C
 }
 
-static void column_fidct_c(int16_t* thr_adr, DCTELEM *data, DCTELEM *output, int cnt);
-static void row_idct_c(DCTELEM* workspace,
+static void column_fidct_c(int16_t* thr_adr, int16_t *data, int16_t *output, int cnt);
+static void row_idct_c(int16_t* workspace,
                        int16_t* output_adr, int output_stride, int cnt);
-static void row_fdct_c(DCTELEM *data, const uint8_t *pixels, int line_size, int cnt);
+static void row_fdct_c(int16_t *data, const uint8_t *pixels, int line_size, int cnt);
 
 //this is rather ugly, but there is no need for function pointers
 #define store_slice_s store_slice_c
@@ -393,10 +394,10 @@
         );
 }
 
-static void column_fidct_mmx(int16_t* thr_adr,  DCTELEM *data,  DCTELEM *output,  int cnt);
-static void row_idct_mmx(DCTELEM* workspace,
+static void column_fidct_mmx(int16_t* thr_adr,  int16_t *data,  int16_t *output,  int cnt);
+static void row_idct_mmx(int16_t* workspace,
                          int16_t* output_adr,  int output_stride,  int cnt);
-static void row_fdct_mmx(DCTELEM *data,  const uint8_t *pixels,  int line_size,  int cnt);
+static void row_fdct_mmx(int16_t *data,  const uint8_t *pixels,  int line_size,  int cnt);
 
 #define store_slice_s store_slice_mmx
 #define store_slice2_s store_slice2_mmx
@@ -416,8 +417,8 @@
     const int step=6-p->log2_count;
     const int qps= 3 + is_luma;
     int32_t __attribute__((aligned(32))) block_align[4*8*BLOCKSZ+ 4*8*BLOCKSZ];
-    DCTELEM *block= (DCTELEM *)block_align;
-    DCTELEM *block3=(DCTELEM *)(block_align+4*8*BLOCKSZ);
+    int16_t *block= (int16_t *)block_align;
+    int16_t *block3=(int16_t *)(block_align+4*8*BLOCKSZ);
 
     memset(block3, 0, 4*8*BLOCKSZ);
 
@@ -460,8 +461,8 @@
                     column_fidct_s((int16_t*)(&p->threshold_mtx[0]), block+x*8, block3+x*8, 8); //yes, this is a HOTSPOT
                 }
             row_idct_s(block3+0*8, p->temp + (y&15)*stride+x0+2-(y&1), stride, 2*(BLOCKSZ-1));
-            memmove(block, block+(BLOCKSZ-1)*64, 8*8*sizeof(DCTELEM)); //cycling
-            memmove(block3, block3+(BLOCKSZ-1)*64, 6*8*sizeof(DCTELEM));
+            memmove(block, block+(BLOCKSZ-1)*64, 8*8*sizeof(int16_t)); //cycling
+            memmove(block3, block3+(BLOCKSZ-1)*64, 6*8*sizeof(int16_t));
         }
         //
         es=width+8-x0; //  8, ...
@@ -497,14 +498,14 @@
     //this can also be avoided, see above
     vf->priv->src = (uint8_t*)av_malloc(vf->priv->temp_stride*h*sizeof(uint8_t));
 
-    return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
+    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=vf_get_image(vf->next,mpi->imgfmt,
+    vf->dmpi=ff_vf_get_image(vf->next,mpi->imgfmt,
                           mpi->type, mpi->flags, mpi->width, mpi->height);
     mpi->planes[0]=vf->dmpi->planes[0];
     mpi->stride[0]=vf->dmpi->stride[0];
@@ -523,11 +524,11 @@
     mp_image_t *dmpi;
     if(!(mpi->flags&MP_IMGFLAG_DIRECT)){
         // no DR, so get a new image! hope we'll get DR buffer:
-        dmpi=vf_get_image(vf->next,mpi->imgfmt,
+        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);
-        vf_clone_mpi_attributes(dmpi, mpi);
+        ff_vf_clone_mpi_attributes(dmpi, mpi);
     }else{
         dmpi=vf->dmpi;
     }
@@ -564,12 +565,12 @@
     }
 
 #if HAVE_MMX
-    if(gCpuCaps.hasMMX) __asm__ volatile ("emms\n\t");
+    if(ff_gCpuCaps.hasMMX) __asm__ volatile ("emms\n\t");
 #endif
 #if HAVE_MMX2
-    if(gCpuCaps.hasMMX2) __asm__ volatile ("sfence\n\t");
+    if(ff_gCpuCaps.hasMMX2) __asm__ volatile ("sfence\n\t");
 #endif
-    return vf_next_put_image(vf,dmpi, pts);
+    return ff_vf_next_put_image(vf,dmpi, pts);
 }
 
 static void uninit(struct vf_instance *vf)
@@ -605,7 +606,7 @@
     case IMGFMT_444P:
     case IMGFMT_422P:
     case IMGFMT_411P:
-        return vf_next_query_format(vf,fmt);
+        return ff_vf_next_query_format(vf,fmt);
     }
     return 0;
 }
@@ -620,7 +621,7 @@
         if (vf->priv->log2_count < 4) vf->priv->log2_count=4;
         return CONTROL_TRUE;
     }
-    return vf_next_control(vf,request,data);
+    return ff_vf_next_control(vf,request,data);
 }
 
 static int vf_open(vf_instance_t *vf, char *args)
@@ -637,7 +638,7 @@
     vf->control= control;
     vf->priv=av_mallocz(sizeof(struct vf_priv_s));//assumes align 16 !
 
-    init_avcodec();
+    ff_init_avcodec();
 
     //vf->priv->avctx= avcodec_alloc_context();
     //dsputil_init(&vf->priv->dsp, vf->priv->avctx);
@@ -679,7 +680,7 @@
     return 1;
 }
 
-const vf_info_t vf_info_fspp = {
+const vf_info_t ff_vf_info_fspp = {
     "fast simple postprocess",
     "fspp",
     "Michael Niedermayer, Nikolaj Poroshin",
@@ -694,7 +695,7 @@
 
 //#define MANGLE(a) #a
 
-//typedef int16_t DCTELEM; //! only int16_t
+//typedef int16_t int16_t; //! only int16_t
 
 #define DCTSIZE 8
 #define DCTSIZE_S "8"
@@ -745,15 +746,15 @@
 
 #if !HAVE_MMX
 
-static void column_fidct_c(int16_t* thr_adr, DCTELEM *data, DCTELEM *output, int cnt)
+static void column_fidct_c(int16_t* thr_adr, int16_t *data, int16_t *output, int cnt)
 {
     int_simd16_t tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
     int_simd16_t tmp10, tmp11, tmp12, tmp13;
     int_simd16_t z1,z2,z3,z4,z5, z10, z11, z12, z13;
     int_simd16_t d0, d1, d2, d3, d4, d5, d6, d7;
 
-    DCTELEM* dataptr;
-    DCTELEM* wsptr;
+    int16_t* dataptr;
+    int16_t* wsptr;
     int16_t *threshold;
     int ctr;
 
@@ -870,7 +871,7 @@
 
 #else /* HAVE_MMX */
 
-static void column_fidct_mmx(int16_t* thr_adr,  DCTELEM *data,  DCTELEM *output,  int cnt)
+static void column_fidct_mmx(int16_t* thr_adr,  int16_t *data,  int16_t *output,  int cnt)
 {
     uint64_t __attribute__((aligned(8))) temps[4];
     __asm__ volatile(
@@ -1605,14 +1606,14 @@
 
 #if !HAVE_MMX
 
-static void row_idct_c(DCTELEM* workspace,
+static void row_idct_c(int16_t* workspace,
                        int16_t* output_adr, int output_stride, int cnt)
 {
     int_simd16_t tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
     int_simd16_t tmp10, tmp11, tmp12, tmp13;
     int_simd16_t z5, z10, z11, z12, z13;
     int16_t* outptr;
-    DCTELEM* wsptr;
+    int16_t* wsptr;
 
     cnt*=4;
     wsptr = workspace;
@@ -1670,7 +1671,7 @@
 
 #else /* HAVE_MMX */
 
-static void row_idct_mmx (DCTELEM* workspace,
+static void row_idct_mmx (int16_t* workspace,
                           int16_t* output_adr,  int output_stride,  int cnt)
 {
     uint64_t __attribute__((aligned(8))) temps[4];
@@ -1874,12 +1875,12 @@
 
 #if !HAVE_MMX
 
-static void row_fdct_c(DCTELEM *data, const uint8_t *pixels, int line_size, int cnt)
+static void row_fdct_c(int16_t *data, const uint8_t *pixels, int line_size, int cnt)
 {
     int_simd16_t tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
     int_simd16_t tmp10, tmp11, tmp12, tmp13;
     int_simd16_t z1, z2, z3, z4, z5, z11, z13;
-    DCTELEM *dataptr;
+    int16_t *dataptr;
 
     cnt*=4;
     // Pass 1: process rows.
@@ -1937,7 +1938,7 @@
 
 #else /* HAVE_MMX */
 
-static void row_fdct_mmx(DCTELEM *data,  const uint8_t *pixels,  int line_size,  int cnt)
+static void row_fdct_mmx(int16_t *data,  const uint8_t *pixels,  int line_size,  int cnt)
 {
     uint64_t __attribute__((aligned(8))) temps[4];
     __asm__ volatile(
diff --git a/libavfilter/libmpcodecs/vf_harddup.c b/libavfilter/libmpcodecs/vf_harddup.c
index 5b6c2ff..7ba62d4 100644
--- a/libavfilter/libmpcodecs/vf_harddup.c
+++ b/libavfilter/libmpcodecs/vf_harddup.c
@@ -37,7 +37,7 @@
 
     vf->priv->last_mpi = mpi;
 
-    dmpi = vf_get_image(vf->next, mpi->imgfmt,
+    dmpi = ff_vf_get_image(vf->next, mpi->imgfmt,
         MP_IMGTYPE_EXPORT, 0, mpi->width, mpi->height);
 
     dmpi->planes[0] = mpi->planes[0];
@@ -49,7 +49,7 @@
         dmpi->stride[2] = mpi->stride[2];
     }
 
-    return vf_next_put_image(vf, dmpi, pts);
+    return ff_vf_next_put_image(vf, dmpi, pts);
 }
 
 static int control(struct vf_instance *vf, int request, void* data)
@@ -65,7 +65,7 @@
             return CONTROL_TRUE;
         break;
     }
-    return vf_next_control(vf, request, data);
+    return ff_vf_next_control(vf, request, data);
 }
 
 static void uninit(struct vf_instance *vf)
@@ -82,7 +82,7 @@
     return 1;
 }
 
-const vf_info_t vf_info_harddup = {
+const vf_info_t ff_vf_info_harddup = {
     "resubmit duplicate frames for encoding",
     "harddup",
     "Rich Felker",
diff --git a/libavfilter/libmpcodecs/vf_il.c b/libavfilter/libmpcodecs/vf_il.c
deleted file mode 100644
index 210e30d..0000000
--- a/libavfilter/libmpcodecs/vf_il.c
+++ /dev/null
@@ -1,148 +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 "mp_msg.h"
-#include "img_format.h"
-#include "mp_image.h"
-#include "vf.h"
-#include "libvo/fastmemcpy.h"
-
-
-//===========================================================================//
-
-typedef struct FilterParam{
-    int interleave;
-    int swap;
-}FilterParam;
-
-struct vf_priv_s {
-    FilterParam lumaParam;
-    FilterParam chromaParam;
-};
-
-/***************************************************************************/
-
-static void interleave(uint8_t *dst, uint8_t *src, int w, int h, int dstStride, int srcStride, int interleave, int swap){
-    const int a= swap;
-    const int b= 1-a;
-    const int m= h>>1;
-    int y;
-
-    switch(interleave){
-    case -1:
-        for(y=0; y < m; y++){
-            fast_memcpy(dst + dstStride* y     , src + srcStride*(y*2 + a), w);
-            fast_memcpy(dst + dstStride*(y + m), src + srcStride*(y*2 + b), w);
-        }
-        break;
-    case 0:
-        for(y=0; y < m; y++){
-            fast_memcpy(dst + dstStride* y*2   , src + srcStride*(y*2 + a), w);
-            fast_memcpy(dst + dstStride*(y*2+1), src + srcStride*(y*2 + b), w);
-        }
-        break;
-    case 1:
-        for(y=0; y < m; y++){
-            fast_memcpy(dst + dstStride*(y*2+a), src + srcStride* y     , w);
-            fast_memcpy(dst + dstStride*(y*2+b), src + srcStride*(y + m), w);
-        }
-        break;
-    }
-}
-
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
-    int w;
-    FilterParam *luma  = &vf->priv->lumaParam;
-    FilterParam *chroma= &vf->priv->chromaParam;
-
-    mp_image_t *dmpi=vf_get_image(vf->next,mpi->imgfmt,
-        MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
-        mpi->w,mpi->h);
-
-    if(mpi->flags&MP_IMGFLAG_PLANAR)
-        w= mpi->w;
-    else
-        w= mpi->w * mpi->bpp/8;
-
-    interleave(dmpi->planes[0], mpi->planes[0],
-        w, mpi->h, dmpi->stride[0], mpi->stride[0], luma->interleave, luma->swap);
-
-    if(mpi->flags&MP_IMGFLAG_PLANAR){
-        int cw= mpi->w >> mpi->chroma_x_shift;
-        int ch= mpi->h >> mpi->chroma_y_shift;
-
-        interleave(dmpi->planes[1], mpi->planes[1], cw,ch,
-            dmpi->stride[1], mpi->stride[1], chroma->interleave, luma->swap);
-        interleave(dmpi->planes[2], mpi->planes[2], cw,ch,
-            dmpi->stride[2], mpi->stride[2], chroma->interleave, luma->swap);
-    }
-
-    return vf_next_put_image(vf,dmpi, pts);
-}
-
-//===========================================================================//
-
-static void parse(FilterParam *fp, char* args){
-    char *pos;
-    char *max= strchr(args, ':');
-
-    if(!max) max= args + strlen(args);
-
-    pos= strchr(args, 's');
-    if(pos && pos<max) fp->swap=1;
-    pos= strchr(args, 'i');
-    if(pos && pos<max) fp->interleave=1;
-    pos= strchr(args, 'd');
-    if(pos && pos<max) fp->interleave=-1;
-}
-
-static int vf_open(vf_instance_t *vf, char *args){
-
-    vf->put_image=put_image;
-//    vf->get_image=get_image;
-    vf->priv=malloc(sizeof(struct vf_priv_s));
-    memset(vf->priv, 0, sizeof(struct vf_priv_s));
-
-    if(args)
-    {
-        char *arg2= strchr(args,':');
-        if(arg2) parse(&vf->priv->chromaParam, arg2+1);
-        parse(&vf->priv->lumaParam, args);
-    }
-
-    return 1;
-}
-
-const vf_info_t vf_info_il = {
-    "(de)interleave",
-    "il",
-    "Michael Niedermayer",
-    "",
-    vf_open,
-    NULL
-};
-
-//===========================================================================//
diff --git a/libavfilter/libmpcodecs/vf_ilpack.c b/libavfilter/libmpcodecs/vf_ilpack.c
index e98d70d..4db6c0a 100644
--- a/libavfilter/libmpcodecs/vf_ilpack.c
+++ b/libavfilter/libmpcodecs/vf_ilpack.c
@@ -29,6 +29,7 @@
 #include "mp_image.h"
 #include "vf.h"
 #include "libavutil/attributes.h"
+#include "libavutil/x86/asm.h"
 
 typedef void (pack_func_t)(unsigned char *dst, unsigned char *y,
     unsigned char *u, unsigned char *v, int w, int us, int vs);
@@ -377,13 +378,13 @@
     mp_image_t *dmpi;
 
     // hope we'll get DR buffer:
-    dmpi=vf_get_image(vf->next, IMGFMT_YUY2,
+    dmpi=ff_vf_get_image(vf->next, IMGFMT_YUY2,
               MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
               mpi->w, mpi->h);
 
     ilpack(dmpi->planes[0], mpi->planes, dmpi->stride[0], mpi->stride, mpi->w, mpi->h, vf->priv->pack);
 
-    return vf_next_put_image(vf,dmpi, pts);
+    return ff_vf_next_put_image(vf,dmpi, pts);
 }
 
 static int config(struct vf_instance *vf,
@@ -391,7 +392,7 @@
           unsigned int flags, unsigned int outfmt)
 {
     /* FIXME - also support UYVY output? */
-    return vf_next_config(vf, width, height, d_width, d_height, flags, IMGFMT_YUY2);
+    return ff_vf_next_config(vf, width, height, d_width, d_height, flags, IMGFMT_YUY2);
 }
 
 
@@ -402,7 +403,7 @@
     case IMGFMT_YV12:
     case IMGFMT_IYUV:
     case IMGFMT_I420:
-        return vf_next_query_format(vf,IMGFMT_YUY2);
+        return ff_vf_next_query_format(vf,IMGFMT_YUY2);
     }
     return 0;
 }
@@ -420,7 +421,7 @@
     pack_li_0 = pack_li_0_C;
     pack_li_1 = pack_li_1_C;
 #if HAVE_MMX
-    if(gCpuCaps.hasMMX) {
+    if(ff_gCpuCaps.hasMMX) {
         pack_nn = pack_nn_MMX;
 #if HAVE_EBX_AVAILABLE
         pack_li_0 = pack_li_0_MMX;
@@ -434,7 +435,7 @@
         vf->priv->pack[0] = vf->priv->pack[1] = pack_nn;
         break;
     default:
-        mp_msg(MSGT_VFILTER, MSGL_WARN,
+        ff_mp_msg(MSGT_VFILTER, MSGL_WARN,
             "ilpack: unknown mode %d (fallback to linear)\n",
             vf->priv->mode);
         /* Fallthrough */
@@ -447,7 +448,7 @@
     return 1;
 }
 
-const vf_info_t vf_info_ilpack = {
+const vf_info_t ff_vf_info_ilpack = {
     "4:2:0 planar -> 4:2:2 packed reinterlacer",
     "ilpack",
     "Richard Felker",
diff --git a/libavfilter/libmpcodecs/vf_ivtc.c b/libavfilter/libmpcodecs/vf_ivtc.c
index b10e505..8a47a57 100644
--- a/libavfilter/libmpcodecs/vf_ivtc.c
+++ b/libavfilter/libmpcodecs/vf_ivtc.c
@@ -27,7 +27,7 @@
 #include "img_format.h"
 #include "mp_image.h"
 #include "vf.h"
-
+#include "libavutil/x86/asm.h"
 #include "libvo/fastmemcpy.h"
 
 
@@ -329,7 +329,7 @@
 
 static void stats(struct frameinfo *f)
 {
-    mp_msg(MSGT_VFILTER, MSGL_V, "       pd=%d re=%d ro=%d rp=%d rt=%d rs=%d rd=%d pp=%d pt=%d ps=%d\r",
+    ff_mp_msg(MSGT_VFILTER, MSGL_V, "       pd=%d re=%d ro=%d rp=%d rt=%d rs=%d rd=%d pp=%d pt=%d ps=%d\r",
         f->p.d, f->r.e, f->r.o, f->r.p, f->r.t, f->r.s, f->r.d, f->p.p, f->p.t, f->p.s);
 }
 
@@ -444,15 +444,15 @@
     }
 
     if (dropflag) {
-        //mp_msg(MSGT_VFILTER, MSGL_V, "drop! [%d/%d=%g]\n",
+        //ff_mp_msg(MSGT_VFILTER, MSGL_V, "drop! [%d/%d=%g]\n",
         //    p->outframes, p->inframes, (float)p->outframes/p->inframes);
-        mp_msg(MSGT_VFILTER, MSGL_V, "!");
+        ff_mp_msg(MSGT_VFILTER, MSGL_V, "!");
         p->lastdrop = 0;
         return 0;
     }
 
     p->outframes++;
-    return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
+    return ff_vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
 }
 
 static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
@@ -467,7 +467,7 @@
         return 1;
     }
 
-    if (!p->dmpi) p->dmpi = vf_get_image(vf->next, mpi->imgfmt,
+    if (!p->dmpi) p->dmpi = ff_vf_get_image(vf->next, mpi->imgfmt,
         MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE |
         MP_IMGFLAG_PRESERVE | MP_IMGFLAG_READABLE,
         mpi->width, mpi->height);
@@ -481,25 +481,25 @@
         copy_image(p->dmpi, mpi, 2);
         ret = 0;
         p->lastdrop = 0;
-        mp_msg(MSGT_VFILTER, MSGL_V, "DROP\n");
+        ff_mp_msg(MSGT_VFILTER, MSGL_V, "DROP\n");
         break;
     case F_MERGE:
         copy_image(p->dmpi, mpi, 0);
         ret = do_put_image(vf, p->dmpi);
         copy_image(p->dmpi, mpi, 1);
-        mp_msg(MSGT_VFILTER, MSGL_V, "MERGE\n");
+        ff_mp_msg(MSGT_VFILTER, MSGL_V, "MERGE\n");
         p->dmpi = NULL;
         break;
     case F_NEXT:
         copy_image(p->dmpi, mpi, 2);
         ret = do_put_image(vf, p->dmpi);
-        mp_msg(MSGT_VFILTER, MSGL_V, "NEXT\n");
+        ff_mp_msg(MSGT_VFILTER, MSGL_V, "NEXT\n");
         p->dmpi = NULL;
         break;
     case F_SHOW:
         ret = do_put_image(vf, p->dmpi);
         copy_image(p->dmpi, mpi, 2);
-        mp_msg(MSGT_VFILTER, MSGL_V, "OK\n");
+        ff_mp_msg(MSGT_VFILTER, MSGL_V, "OK\n");
         p->dmpi = NULL;
         break;
     }
@@ -512,7 +512,7 @@
     case IMGFMT_YV12:
     case IMGFMT_IYUV:
     case IMGFMT_I420:
-        return vf_next_query_format(vf, fmt);
+        return ff_vf_next_query_format(vf, fmt);
     }
     return 0;
 }
@@ -535,12 +535,12 @@
     if (args) sscanf(args, "%d", &p->drop);
     block_diffs = block_diffs_C;
 #if HAVE_MMX && HAVE_EBX_AVAILABLE
-    if(gCpuCaps.hasMMX) block_diffs = block_diffs_MMX;
+    if(ff_gCpuCaps.hasMMX) block_diffs = block_diffs_MMX;
 #endif
     return 1;
 }
 
-const vf_info_t vf_info_ivtc = {
+const vf_info_t ff_vf_info_ivtc = {
     "inverse telecine, take 2",
     "ivtc",
     "Rich Felker",
diff --git a/libavfilter/libmpcodecs/vf_kerndeint.c b/libavfilter/libmpcodecs/vf_kerndeint.c
deleted file mode 100644
index c5197fc..0000000
--- a/libavfilter/libmpcodecs/vf_kerndeint.c
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * Original AVISynth Filter Copyright (C) 2003 Donald A. Graft
- *  Adapted to MPlayer by Tobias Diedrich
- *
- * 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 <math.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    frame;
-    int    map;
-    int    order;
-    int    thresh;
-    int    sharp;
-    int    twoway;
-    int    do_deinterlace;
-};
-
-
-/***************************************************************************/
-
-
-static int config(struct vf_instance *vf,
-    int width, int height, int d_width, int d_height,
-    unsigned int flags, unsigned int outfmt){
-
-    return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
-}
-
-
-static void uninit(struct vf_instance *vf)
-{
-    free(vf->priv);
-}
-
-static inline int IsRGB(mp_image_t *mpi)
-{
-    return mpi->imgfmt == IMGFMT_RGB;
-}
-
-static inline int IsYUY2(mp_image_t *mpi)
-{
-    return mpi->imgfmt == IMGFMT_YUY2;
-}
-
-#define PLANAR_Y 0
-#define PLANAR_U 1
-#define PLANAR_V 2
-
-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;
-    int W = mpi->w, H = mpi->h;
-    const unsigned char *prvp, *prvpp, *prvpn, *prvpnn, *prvppp, *prvp4p, *prvp4n;
-    const unsigned char *srcp_saved;
-    const unsigned char *srcp, *srcpp, *srcpn, *srcpnn, *srcppp, *srcp3p, *srcp3n, *srcp4p, *srcp4n;
-    unsigned char *dstp, *dstp_saved;
-    int src_pitch;
-    int psrc_pitch;
-    int dst_pitch;
-    int x, y, z;
-    int n = vf->priv->frame++;
-    int val, hi, lo, w, h;
-    double valf;
-    int plane;
-    int threshold = vf->priv->thresh;
-    int order = vf->priv->order;
-    int map = vf->priv->map;
-    int sharp = vf->priv->sharp;
-    int twoway = vf->priv->twoway;
-    mp_image_t *dmpi, *pmpi;
-
-    if(!vf->priv->do_deinterlace)
-        return vf_next_put_image(vf, mpi, pts);
-
-    dmpi=vf_get_image(vf->next,mpi->imgfmt,
-        MP_IMGTYPE_IP, MP_IMGFLAG_ACCEPT_STRIDE,
-        mpi->w,mpi->h);
-    pmpi=vf_get_image(vf->next,mpi->imgfmt,
-        MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
-        mpi->w,mpi->h);
-    if(!dmpi) return 0;
-
-    for (z=0; z<mpi->num_planes; z++) {
-        if (z == 0) plane = PLANAR_Y;
-        else if (z == 1) plane = PLANAR_U;
-        else plane = PLANAR_V;
-
-        h = plane == PLANAR_Y ? H : ch;
-        w = plane == PLANAR_Y ? W : cw;
-
-        srcp = srcp_saved = mpi->planes[z];
-        src_pitch = mpi->stride[z];
-        psrc_pitch = pmpi->stride[z];
-        dstp = dstp_saved = dmpi->planes[z];
-        dst_pitch = dmpi->stride[z];
-        srcp = srcp_saved + (1-order) * src_pitch;
-        dstp = dstp_saved + (1-order) * dst_pitch;
-
-        for (y=0; y<h; y+=2) {
-            fast_memcpy(dstp, srcp, w);
-            srcp += 2*src_pitch;
-            dstp += 2*dst_pitch;
-        }
-
-        // Copy through the lines that will be missed below.
-        fast_memcpy(dstp_saved + order*dst_pitch, srcp_saved + (1-order)*src_pitch, w);
-        fast_memcpy(dstp_saved + (2+order)*dst_pitch, srcp_saved + (3-order)*src_pitch, w);
-        fast_memcpy(dstp_saved + (h-2+order)*dst_pitch, srcp_saved + (h-1-order)*src_pitch, w);
-        fast_memcpy(dstp_saved + (h-4+order)*dst_pitch, srcp_saved + (h-3-order)*src_pitch, w);
-        /* For the other field choose adaptively between using the previous field
-           or the interpolant from the current field. */
-
-        prvp = pmpi->planes[z] + 5*psrc_pitch - (1-order)*psrc_pitch;
-        prvpp = prvp - psrc_pitch;
-        prvppp = prvp - 2*psrc_pitch;
-        prvp4p = prvp - 4*psrc_pitch;
-        prvpn = prvp + psrc_pitch;
-        prvpnn = prvp + 2*psrc_pitch;
-        prvp4n = prvp + 4*psrc_pitch;
-        srcp = srcp_saved + 5*src_pitch - (1-order)*src_pitch;
-        srcpp = srcp - src_pitch;
-        srcppp = srcp - 2*src_pitch;
-        srcp3p = srcp - 3*src_pitch;
-        srcp4p = srcp - 4*src_pitch;
-        srcpn = srcp + src_pitch;
-        srcpnn = srcp + 2*src_pitch;
-        srcp3n = srcp + 3*src_pitch;
-        srcp4n = srcp + 4*src_pitch;
-        dstp =  dstp_saved  + 5*dst_pitch - (1-order)*dst_pitch;
-        for (y = 5 - (1-order); y <= h - 5 - (1-order); y+=2)
-        {
-            for (x = 0; x < w; x++)
-            {
-                if ((threshold == 0) || (n == 0) ||
-                    (abs((int)prvp[x] - (int)srcp[x]) > threshold) ||
-                    (abs((int)prvpp[x] - (int)srcpp[x]) > threshold) ||
-                    (abs((int)prvpn[x] - (int)srcpn[x]) > threshold))
-                {
-                    if (map == 1)
-                    {
-                        int g = x & ~3;
-                        if (IsRGB(mpi) == 1)
-                        {
-                            dstp[g++] = 255;
-                            dstp[g++] = 255;
-                            dstp[g++] = 255;
-                            dstp[g] = 255;
-                            x = g;
-                        }
-                        else if (IsYUY2(mpi) == 1)
-                        {
-                            dstp[g++] = 235;
-                            dstp[g++] = 128;
-                            dstp[g++] = 235;
-                            dstp[g] = 128;
-                            x = g;
-                        }
-                        else
-                        {
-                            if (plane == PLANAR_Y) dstp[x] = 235;
-                            else dstp[x] = 128;
-                        }
-                    }
-                    else
-                    {
-                        if (IsRGB(mpi))
-                        {
-                            hi = 255;
-                            lo = 0;
-                        }
-                        else if (IsYUY2(mpi))
-                        {
-                            hi = (x & 1) ? 240 : 235;
-                            lo = 16;
-                        }
-                        else
-                        {
-                            hi = (plane == PLANAR_Y) ? 235 : 240;
-                            lo = 16;
-                        }
-
-                        if (sharp == 1)
-                        {
-                            if (twoway == 1)
-                                valf = + 0.526*((int)srcpp[x] + (int)srcpn[x])
-                                   + 0.170*((int)srcp[x] + (int)prvp[x])
-                                   - 0.116*((int)srcppp[x] + (int)srcpnn[x] + (int)prvppp[x] + (int)prvpnn[x])
-                                   - 0.026*((int)srcp3p[x] + (int)srcp3n[x])
-                                   + 0.031*((int)srcp4p[x] + (int)srcp4n[x] + (int)prvp4p[x] + (int)prvp4n[x]);
-                            else
-                                valf = + 0.526*((int)srcpp[x] + (int)srcpn[x])
-                                   + 0.170*((int)prvp[x])
-                                   - 0.116*((int)prvppp[x] + (int)prvpnn[x])
-                                   - 0.026*((int)srcp3p[x] + (int)srcp3n[x])
-                                   + 0.031*((int)prvp4p[x] + (int)prvp4p[x]);
-                            if (valf > hi) valf = hi;
-                            else if (valf < lo) valf = lo;
-                            dstp[x] = (int) valf;
-                        }
-                        else
-                        {
-                            if (twoway == 1)
-                                val = (8*((int)srcpp[x] + (int)srcpn[x]) + 2*((int)srcp[x] + (int)prvp[x]) -
-                                    (int)(srcppp[x]) - (int)(srcpnn[x]) -
-                                    (int)(prvppp[x]) - (int)(prvpnn[x])) >> 4;
-                            else
-                                val = (8*((int)srcpp[x] + (int)srcpn[x]) + 2*((int)prvp[x]) -
-                                    (int)(prvppp[x]) - (int)(prvpnn[x])) >> 4;
-                            if (val > hi) val = hi;
-                            else if (val < lo) val = lo;
-                            dstp[x] = (int) val;
-                        }
-                    }
-                }
-                else
-                {
-                    dstp[x] = srcp[x];
-                }
-            }
-            prvp  += 2*psrc_pitch;
-            prvpp  += 2*psrc_pitch;
-            prvppp  += 2*psrc_pitch;
-            prvpn  += 2*psrc_pitch;
-            prvpnn  += 2*psrc_pitch;
-            prvp4p  += 2*psrc_pitch;
-            prvp4n  += 2*psrc_pitch;
-            srcp  += 2*src_pitch;
-            srcpp += 2*src_pitch;
-            srcppp += 2*src_pitch;
-            srcp3p += 2*src_pitch;
-            srcp4p += 2*src_pitch;
-            srcpn += 2*src_pitch;
-            srcpnn += 2*src_pitch;
-            srcp3n += 2*src_pitch;
-            srcp4n += 2*src_pitch;
-            dstp  += 2*dst_pitch;
-        }
-
-        srcp = mpi->planes[z];
-        dstp = pmpi->planes[z];
-        for (y=0; y<h; y++) {
-            fast_memcpy(dstp, srcp, w);
-            srcp += src_pitch;
-            dstp += psrc_pitch;
-        }
-    }
-
-    return 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_RGB:
-    case IMGFMT_YUY2:
-        return vf_next_query_format(vf, fmt);
-    }
-    return 0;
-}
-
-static int control(struct vf_instance *vf, int request, void* data){
-    switch (request)
-    {
-    case VFCTRL_GET_DEINTERLACE:
-        *(int*)data = vf->priv->do_deinterlace;
-        return CONTROL_OK;
-    case VFCTRL_SET_DEINTERLACE:
-        vf->priv->do_deinterlace = *(int*)data;
-        return CONTROL_OK;
-    }
-    return vf_next_control (vf, request, data);
-}
-
-static int vf_open(vf_instance_t *vf, char *args){
-
-    vf->control=control;
-    vf->config=config;
-    vf->put_image=put_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->frame = 0;
-
-    vf->priv->map = 0;
-    vf->priv->order = 0;
-    vf->priv->thresh = 10;
-    vf->priv->sharp = 0;
-    vf->priv->twoway = 0;
-    vf->priv->do_deinterlace=1;
-
-        if (args)
-        {
-            sscanf(args, "%d:%d:%d:%d:%d",
-        &vf->priv->thresh, &vf->priv->map,
-        &vf->priv->order, &vf->priv->sharp,
-        &vf->priv->twoway);
-        }
-    if (vf->priv->order > 1) vf->priv->order = 1;
-
-    return 1;
-}
-
-const vf_info_t vf_info_kerndeint = {
-    "Kernel Deinterlacer",
-    "kerndeint",
-    "Donald Graft",
-    "",
-    vf_open,
-    NULL
-};
-
-//===========================================================================//
diff --git a/libavfilter/libmpcodecs/vf_mcdeint.c b/libavfilter/libmpcodecs/vf_mcdeint.c
index 01a3cb3..b9ffaf2 100644
--- a/libavfilter/libmpcodecs/vf_mcdeint.c
+++ b/libavfilter/libmpcodecs/vf_mcdeint.c
@@ -54,6 +54,7 @@
 #include "mp_msg.h"
 #include "cpudetect.h"
 
+#include "libavutil/common.h"
 #include "libavutil/internal.h"
 #include "libavutil/intreadwrite.h"
 #include "libavcodec/avcodec.h"
@@ -66,7 +67,7 @@
 #include "img_format.h"
 #include "mp_image.h"
 #include "vf.h"
-#include "vd_ffmpeg.h"
+#include "av_helpers.h"
 
 #define MIN(a,b) ((a) > (b) ? (b) : (a))
 #define MAX(a,b) ((a) < (b) ? (b) : (a))
@@ -186,6 +187,7 @@
 
         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;
@@ -196,7 +198,7 @@
             vf->priv->src [i]= malloc(vf->priv->temp_stride[i]*h*sizeof(uint8_t));
 #endif
             avctx_enc=
-            vf->priv->avctx_enc= avcodec_alloc_context();
+            vf->priv->avctx_enc= avcodec_alloc_context3(enc);
             avctx_enc->width = width;
             avctx_enc->height = height;
             avctx_enc->time_base= (AVRational){1,25};  // meaningless
@@ -206,7 +208,7 @@
             avctx_enc->flags = CODEC_FLAG_QSCALE | CODEC_FLAG_LOW_DELAY;
             avctx_enc->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
             avctx_enc->global_quality= 1;
-            avctx_enc->flags2= CODEC_FLAG2_MEMC_ONLY;
+            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;
@@ -224,7 +226,8 @@
                 avctx_enc->flags |= CODEC_FLAG_QPEL;
             }
 
-            avcodec_open(avctx_enc, enc);
+            avcodec_open2(avctx_enc, enc, &opts);
+            av_dict_free(&opts);
 
         }
         vf->priv->frame= avcodec_alloc_frame();
@@ -232,14 +235,14 @@
         vf->priv->outbuf_size= width*height*10;
         vf->priv->outbuf= malloc(vf->priv->outbuf_size);
 
-        return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
+        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=vf_get_image(vf->next,mpi->imgfmt,
+    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];
@@ -258,18 +261,18 @@
 
     if(!(mpi->flags&MP_IMGFLAG_DIRECT)){
         // no DR, so get a new image! hope we'll get DR buffer:
-        dmpi=vf_get_image(vf->next,mpi->imgfmt,
+        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);
-        vf_clone_mpi_attributes(dmpi, mpi);
+        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 vf_next_put_image(vf,dmpi, pts);
+    return ff_vf_next_put_image(vf,dmpi, pts);
 }
 
 static void uninit(struct vf_instance *vf){
@@ -301,7 +304,7 @@
         case IMGFMT_IYUV:
         case IMGFMT_Y800:
         case IMGFMT_Y8:
-            return vf_next_query_format(vf,fmt);
+            return ff_vf_next_query_format(vf,fmt);
     }
     return 0;
 }
@@ -316,7 +319,7 @@
     vf->priv=malloc(sizeof(struct vf_priv_s));
     memset(vf->priv, 0, sizeof(struct vf_priv_s));
 
-    init_avcodec();
+    ff_init_avcodec();
 
     vf->priv->mode=0;
     vf->priv->parity= -1;
@@ -327,7 +330,7 @@
     return 1;
 }
 
-const vf_info_t vf_info_mcdeint = {
+const vf_info_t ff_vf_info_mcdeint = {
     "motion compensating deinterlacer",
     "mcdeint",
     "Michael Niedermayer",
diff --git a/libavfilter/libmpcodecs/vf_noise.c b/libavfilter/libmpcodecs/vf_noise.c
index 9521619..3b946e9 100644
--- a/libavfilter/libmpcodecs/vf_noise.c
+++ b/libavfilter/libmpcodecs/vf_noise.c
@@ -37,6 +37,7 @@
 #include "vf.h"
 #include "libvo/fastmemcpy.h"
 #include "libavutil/mem.h"
+#include "libavutil/x86/asm.h"
 
 #define MAX_NOISE 4096
 #define MAX_SHIFT 1024
@@ -317,14 +318,14 @@
         int width, int height, int d_width, int d_height,
         unsigned int flags, unsigned int outfmt){
 
-        return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
+        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
     if(mpi->imgfmt!=vf->priv->outfmt) return; // colorspace differ
     // ok, we can do pp in-place (or pp disabled):
-    vf->dmpi=vf_get_image(vf->next,mpi->imgfmt,
+    vf->dmpi=ff_vf_get_image(vf->next,mpi->imgfmt,
         mpi->type, mpi->flags, mpi->w, mpi->h);
     mpi->planes[0]=vf->dmpi->planes[0];
     mpi->stride[0]=vf->dmpi->stride[0];
@@ -343,7 +344,7 @@
 
         if(!(mpi->flags&MP_IMGFLAG_DIRECT)){
                 // no DR, so get a new image! hope we'll get DR buffer:
-                vf->dmpi=vf_get_image(vf->next,vf->priv->outfmt,
+                vf->dmpi=ff_vf_get_image(vf->next,vf->priv->outfmt,
                 MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
                 mpi->w,mpi->h);
 //printf("nodr\n");
@@ -355,16 +356,16 @@
         noise(dmpi->planes[1], mpi->planes[1], dmpi->stride[1], mpi->stride[1], mpi->w/2, mpi->h/2, &vf->priv->chromaParam);
         noise(dmpi->planes[2], mpi->planes[2], dmpi->stride[2], mpi->stride[2], mpi->w/2, mpi->h/2, &vf->priv->chromaParam);
 
-        vf_clone_mpi_attributes(dmpi, mpi);
+        ff_vf_clone_mpi_attributes(dmpi, mpi);
 
 #if HAVE_MMX
-        if(gCpuCaps.hasMMX) __asm__ volatile ("emms\n\t");
+        if(ff_gCpuCaps.hasMMX) __asm__ volatile ("emms\n\t");
 #endif
 #if HAVE_MMX2
-        if(gCpuCaps.hasMMX2) __asm__ volatile ("sfence\n\t");
+        if(ff_gCpuCaps.hasMMX2) __asm__ volatile ("sfence\n\t");
 #endif
 
-        return vf_next_put_image(vf,dmpi, pts);
+        return ff_vf_next_put_image(vf,dmpi, pts);
 }
 
 static void uninit(struct vf_instance *vf){
@@ -388,7 +389,7 @@
         case IMGFMT_YV12:
         case IMGFMT_I420:
         case IMGFMT_IYUV:
-                return vf_next_query_format(vf,vf->priv->outfmt);
+                return ff_vf_next_query_format(vf,vf->priv->outfmt);
         }
         return 0;
 }
@@ -440,7 +441,7 @@
     }
 
     // check csp:
-    vf->priv->outfmt=vf_match_csp(&vf->next,fmt_list,IMGFMT_YV12);
+    vf->priv->outfmt=ff_vf_match_csp(&vf->next,fmt_list,IMGFMT_YV12);
     if(!vf->priv->outfmt)
     {
         uninit(vf);
@@ -449,20 +450,20 @@
 
 
 #if HAVE_MMX
-    if(gCpuCaps.hasMMX){
+    if(ff_gCpuCaps.hasMMX){
         lineNoise= lineNoise_MMX;
         lineNoiseAvg= lineNoiseAvg_MMX;
     }
 #endif
 #if HAVE_MMX2
-    if(gCpuCaps.hasMMX2) lineNoise= lineNoise_MMX2;
-//    if(gCpuCaps.hasMMX) lineNoiseAvg= lineNoiseAvg_MMX2;
+    if(ff_gCpuCaps.hasMMX2) lineNoise= lineNoise_MMX2;
+//    if(ff_gCpuCaps.hasMMX) lineNoiseAvg= lineNoiseAvg_MMX2;
 #endif
 
     return 1;
 }
 
-const vf_info_t vf_info_noise = {
+const vf_info_t ff_vf_info_noise = {
     "noise generator",
     "noise",
     "Michael Niedermayer",
diff --git a/libavfilter/libmpcodecs/vf_ow.c b/libavfilter/libmpcodecs/vf_ow.c
index f7fb02d..69b07ef 100644
--- a/libavfilter/libmpcodecs/vf_ow.c
+++ b/libavfilter/libmpcodecs/vf_ow.c
@@ -213,13 +213,13 @@
             vf->priv->plane[i][j]= malloc(vf->priv->stride*h*sizeof(vf->priv->plane[0][0][0]));
     }
 
-    return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
+    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=vf_get_image(vf->next,mpi->imgfmt,
+    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];
@@ -238,11 +238,11 @@
 
     if(!(mpi->flags&MP_IMGFLAG_DIRECT)){
         // no DR, so get a new image! hope we'll get DR buffer:
-        dmpi=vf_get_image(vf->next,mpi->imgfmt,
+        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);
-        vf_clone_mpi_attributes(dmpi, mpi);
+        ff_vf_clone_mpi_attributes(dmpi, mpi);
     }else{
         dmpi=vf->dmpi;
     }
@@ -251,7 +251,7 @@
     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 vf_next_put_image(vf,dmpi, pts);
+    return ff_vf_next_put_image(vf,dmpi, pts);
 }
 
 static void uninit(struct vf_instance *vf){
@@ -283,7 +283,7 @@
         case IMGFMT_444P:
         case IMGFMT_422P:
         case IMGFMT_411P:
-            return vf_next_query_format(vf,fmt);
+            return ff_vf_next_query_format(vf,fmt);
     }
     return 0;
 }
@@ -312,7 +312,7 @@
     return 1;
 }
 
-const vf_info_t vf_info_ow = {
+const vf_info_t ff_vf_info_ow = {
     "overcomplete wavelet denoiser",
     "ow",
     "Michael Niedermayer",
diff --git a/libavfilter/libmpcodecs/vf_perspective.c b/libavfilter/libmpcodecs/vf_perspective.c
index f5a9d6b..aed5c4d 100644
--- a/libavfilter/libmpcodecs/vf_perspective.c
+++ b/libavfilter/libmpcodecs/vf_perspective.c
@@ -128,7 +128,7 @@
             vf->priv->coeff[i][j]= (int)floor((1<<COEFF_BITS)*temp[j]/sum + 0.5);
     }
 
-    return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
+    return ff_vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
 }
 
 static void uninit(struct vf_instance *vf){
@@ -264,7 +264,7 @@
     int cw= mpi->w >> mpi->chroma_x_shift;
     int ch= mpi->h >> mpi->chroma_y_shift;
 
-    mp_image_t *dmpi=vf_get_image(vf->next,mpi->imgfmt,
+    mp_image_t *dmpi=ff_vf_get_image(vf->next,mpi->imgfmt,
         MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
         mpi->w,mpi->h);
 
@@ -286,7 +286,7 @@
                 vf->priv, mpi->chroma_x_shift, mpi->chroma_y_shift);
     }
 
-    return vf_next_put_image(vf,dmpi, pts);
+    return ff_vf_next_put_image(vf,dmpi, pts);
 }
 
 //===========================================================================//
@@ -301,7 +301,7 @@
     case IMGFMT_444P:
     case IMGFMT_422P:
     case IMGFMT_411P:
-        return vf_next_query_format(vf, fmt);
+        return ff_vf_next_query_format(vf, fmt);
     }
     return 0;
 }
@@ -333,7 +333,7 @@
     return 1;
 }
 
-const vf_info_t vf_info_perspective = {
+const vf_info_t ff_vf_info_perspective = {
     "perspective correcture",
     "perspective",
     "Michael Niedermayer",
diff --git a/libavfilter/libmpcodecs/vf_phase.c b/libavfilter/libmpcodecs/vf_phase.c
index 101290d..25abc5b 100644
--- a/libavfilter/libmpcodecs/vf_phase.c
+++ b/libavfilter/libmpcodecs/vf_phase.c
@@ -184,13 +184,13 @@
          mode=PROGRESSIVE;
       }
 
-   if( mp_msg_test(MSGT_VFILTER,MSGL_V) )
+   if( ff_mp_msg_test(MSGT_VFILTER,MSGL_V) )
       {
-      mp_msg(MSGT_VFILTER, MSGL_INFO, "%c", mode==BOTTOM_FIRST?'b':mode==TOP_FIRST?'t':'p');
-      if(tdiff==65536.0) mp_msg(MSGT_VFILTER, MSGL_INFO,"     N/A "); else mp_msg(MSGT_VFILTER, MSGL_INFO," %8.2f", tdiff);
-      if(bdiff==65536.0) mp_msg(MSGT_VFILTER, MSGL_INFO,"     N/A "); else mp_msg(MSGT_VFILTER, MSGL_INFO," %8.2f", bdiff);
-      if(pdiff==65536.0) mp_msg(MSGT_VFILTER, MSGL_INFO,"     N/A "); else mp_msg(MSGT_VFILTER, MSGL_INFO," %8.2f", pdiff);
-      mp_msg(MSGT_VFILTER, MSGL_INFO,"        \n");
+      ff_mp_msg(MSGT_VFILTER, MSGL_INFO, "%c", mode==BOTTOM_FIRST?'b':mode==TOP_FIRST?'t':'p');
+      if(tdiff==65536.0) ff_mp_msg(MSGT_VFILTER, MSGL_INFO,"     N/A "); else ff_mp_msg(MSGT_VFILTER, MSGL_INFO," %8.2f", tdiff);
+      if(bdiff==65536.0) ff_mp_msg(MSGT_VFILTER, MSGL_INFO,"     N/A "); else ff_mp_msg(MSGT_VFILTER, MSGL_INFO," %8.2f", bdiff);
+      if(pdiff==65536.0) ff_mp_msg(MSGT_VFILTER, MSGL_INFO,"     N/A "); else ff_mp_msg(MSGT_VFILTER, MSGL_INFO," %8.2f", pdiff);
+      ff_mp_msg(MSGT_VFILTER, MSGL_INFO,"        \n");
       }
 
    return mode;
@@ -202,7 +202,7 @@
    int w;
    enum mode mode;
 
-   if(!(dmpi=vf_get_image(vf->next, mpi->imgfmt,
+   if(!(dmpi=ff_vf_get_image(vf->next, mpi->imgfmt,
                           MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
                           mpi->w, mpi->h)))
       return 0;
@@ -237,7 +237,7 @@
                &vf->priv->buf[2], mode);
       }
 
-   return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
+   return ff_vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
    }
 
 static void uninit(struct vf_instance *vf)
@@ -292,7 +292,7 @@
    return 1;
    }
 
-const vf_info_t vf_info_phase =
+const vf_info_t ff_vf_info_phase =
    {
    "phase shift fields",
    "phase",
diff --git a/libavfilter/libmpcodecs/vf_pp.c b/libavfilter/libmpcodecs/vf_pp.c
deleted file mode 100644
index 713056f..0000000
--- a/libavfilter/libmpcodecs/vf_pp.c
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * 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 <errno.h>
-
-#include "config.h"
-#include "mp_msg.h"
-#include "cpudetect.h"
-
-#if HAVE_MALLOC_H
-#include <malloc.h>
-#endif
-
-#include "img_format.h"
-#include "mp_image.h"
-#include "vf.h"
-#include "libpostproc/postprocess.h"
-
-#ifdef CONFIG_FFMPEG_A
-#define EMU_OLD
-#include "libpostproc/postprocess_internal.h"
-#endif
-
-#undef malloc
-
-struct vf_priv_s {
-    int pp;
-    pp_mode *ppMode[PP_QUALITY_MAX+1];
-    void *context;
-    unsigned int outfmt;
-};
-
-//===========================================================================//
-
-static int config(struct vf_instance *vf,
-        int width, int height, int d_width, int d_height,
-        unsigned int voflags, unsigned int outfmt){
-    int flags= PP_CPU_CAPS_AUTO;
-
-    switch(outfmt){
-    case IMGFMT_444P: flags|= PP_FORMAT_444; break;
-    case IMGFMT_422P: flags|= PP_FORMAT_422; break;
-    case IMGFMT_411P: flags|= PP_FORMAT_411; break;
-    default:          flags|= PP_FORMAT_420; break;
-    }
-
-    if(vf->priv->context) pp_free_context(vf->priv->context);
-    vf->priv->context= pp_get_context(width, height, flags);
-
-    return vf_next_config(vf,width,height,d_width,d_height,voflags,outfmt);
-}
-
-static void uninit(struct vf_instance *vf){
-    int i;
-    for(i=0; i<=PP_QUALITY_MAX; i++){
-        if(vf->priv->ppMode[i])
-            pp_free_mode(vf->priv->ppMode[i]);
-    }
-    if(vf->priv->context) pp_free_context(vf->priv->context);
-    free(vf->priv);
-}
-
-static int query_format(struct vf_instance *vf, unsigned int fmt){
-    switch(fmt){
-    case IMGFMT_YV12:
-    case IMGFMT_I420:
-    case IMGFMT_IYUV:
-    case IMGFMT_444P:
-    case IMGFMT_422P:
-    case IMGFMT_411P:
-        return 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 PP_QUALITY_MAX;
-    case VFCTRL_SET_PP_LEVEL:
-        vf->priv->pp= *((unsigned int*)data);
-        return CONTROL_TRUE;
-    }
-    return vf_next_control(vf,request,data);
-}
-
-static void get_image(struct vf_instance *vf, mp_image_t *mpi){
-    if(vf->priv->pp&0xFFFF) return; // non-local filters enabled
-    if((mpi->type==MP_IMGTYPE_IPB || vf->priv->pp) &&
-        mpi->flags&MP_IMGFLAG_PRESERVE) return; // don't change
-    if(!(mpi->flags&MP_IMGFLAG_ACCEPT_STRIDE) && mpi->imgfmt!=vf->priv->outfmt)
-        return; // colorspace differ
-    // ok, we can do pp in-place (or pp disabled):
-    vf->dmpi=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){
-    if(!(mpi->flags&MP_IMGFLAG_DIRECT)){
-        // no DR, so get a new image! hope we'll get DR buffer:
-        vf->dmpi=vf_get_image(vf->next,mpi->imgfmt,
-            MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE |
-            MP_IMGFLAG_PREFER_ALIGNED_STRIDE | MP_IMGFLAG_READABLE,
-//            MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
-//            mpi->w,mpi->h);
-            (mpi->width+7)&(~7),(mpi->height+7)&(~7));
-        vf->dmpi->w=mpi->w; vf->dmpi->h=mpi->h; // display w;h
-    }
-
-    if(vf->priv->pp || !(mpi->flags&MP_IMGFLAG_DIRECT)){
-        // do the postprocessing! (or copy if no DR)
-        pp_postprocess(mpi->planes           ,mpi->stride,
-                    vf->dmpi->planes,vf->dmpi->stride,
-                    (mpi->w+7)&(~7),mpi->h,
-                    mpi->qscale, mpi->qstride,
-                    vf->priv->ppMode[ vf->priv->pp ], vf->priv->context,
-#ifdef PP_PICT_TYPE_QP2
-                    mpi->pict_type | (mpi->qscale_type ? PP_PICT_TYPE_QP2 : 0));
-#else
-                    mpi->pict_type);
-#endif
-    }
-    return vf_next_put_image(vf,vf->dmpi, pts);
-}
-
-//===========================================================================//
-
-static const unsigned int fmt_list[]={
-    IMGFMT_YV12,
-    IMGFMT_I420,
-    IMGFMT_IYUV,
-    IMGFMT_444P,
-    IMGFMT_422P,
-    IMGFMT_411P,
-    0
-};
-
-static int vf_open(vf_instance_t *vf, char *args){
-    char *endptr, *name;
-    int i;
-    int hex_mode=0;
-
-    vf->query_format=query_format;
-    vf->control=control;
-    vf->config=config;
-    vf->get_image=get_image;
-    vf->put_image=put_image;
-    vf->uninit=uninit;
-    vf->default_caps=VFCAP_ACCEPT_STRIDE|VFCAP_POSTPROC;
-    vf->priv=malloc(sizeof(struct vf_priv_s));
-    vf->priv->context=NULL;
-
-    // check csp:
-    vf->priv->outfmt=vf_match_csp(&vf->next,fmt_list,IMGFMT_YV12);
-    if(!vf->priv->outfmt) return 0; // no csp match :(
-
-    if(args && *args){
-        hex_mode= strtol(args, &endptr, 0);
-        if(*endptr){
-            name= args;
-        }else
-            name= NULL;
-    }else{
-        name="de";
-    }
-
-#ifdef EMU_OLD
-    if(name){
-#endif
-        for(i=0; i<=PP_QUALITY_MAX; i++){
-            vf->priv->ppMode[i]= pp_get_mode_by_name_and_quality(name, i);
-            if(vf->priv->ppMode[i]==NULL) return -1;
-        }
-#ifdef EMU_OLD
-    }else{
-        /* hex mode for compatibility */
-        for(i=0; i<=PP_QUALITY_MAX; i++){
-            PPMode *ppMode;
-
-            ppMode = av_malloc(sizeof(PPMode));
-
-            ppMode->lumMode= hex_mode;
-            ppMode->chromMode= ((hex_mode&0xFF)>>4) | (hex_mode&0xFFFFFF00);
-            ppMode->maxTmpNoise[0]= 700;
-            ppMode->maxTmpNoise[1]= 1500;
-            ppMode->maxTmpNoise[2]= 3000;
-            ppMode->maxAllowedY= 234;
-            ppMode->minAllowedY= 16;
-            ppMode->baseDcDiff= 256/4;
-            ppMode->flatnessThreshold=40;
-
-            vf->priv->ppMode[i]= ppMode;
-        }
-    }
-#endif
-
-    vf->priv->pp=PP_QUALITY_MAX;
-    return 1;
-}
-
-const vf_info_t vf_info_pp = {
-    "postprocessing",
-    "pp",
-    "A'rpi",
-    "",
-    vf_open,
-    NULL
-};
-
-//===========================================================================//
diff --git a/libavfilter/libmpcodecs/vf_pp7.c b/libavfilter/libmpcodecs/vf_pp7.c
index eae30bf..30f9530 100644
--- a/libavfilter/libmpcodecs/vf_pp7.c
+++ b/libavfilter/libmpcodecs/vf_pp7.c
@@ -44,8 +44,6 @@
 #define XMIN(a,b) ((a) < (b) ? (a) : (b))
 #define XMAX(a,b) ((a) > (b) ? (a) : (b))
 
-typedef short DCTELEM;
-
 //===========================================================================//
 static const uint8_t  __attribute__((aligned(8))) dither[8][8]={
 {  0,  48,  12,  60,   3,  51,  15,  63, },
@@ -66,7 +64,7 @@
     uint8_t *src;
 };
 #if 0
-static inline void dct7_c(DCTELEM *dst, int s0, int s1, int s2, int s3, int step){
+static inline void dct7_c(int16_t *dst, int s0, int s1, int s2, int s3, int step){
     int s, d;
     int dst2[64];
 //#define S0 (1024/0.37796447300922719759)
@@ -113,7 +111,7 @@
 }
 #endif
 
-static inline void dctA_c(DCTELEM *dst, uint8_t *src, int stride){
+static inline void dctA_c(int16_t *dst, uint8_t *src, int stride){
     int i;
 
     for(i=0; i<4; i++){
@@ -135,7 +133,7 @@
     }
 }
 
-static void dctB_c(DCTELEM *dst, DCTELEM *src){
+static void dctB_c(int16_t *dst, int16_t *src){
     int i;
 
     for(i=0; i<4; i++){
@@ -158,7 +156,7 @@
 }
 
 #if HAVE_MMX
-static void dctB_mmx(DCTELEM *dst, DCTELEM *src){
+static void dctB_mmx(int16_t *dst, int16_t *src){
     __asm__ volatile (
         "movq  (%0), %%mm0      \n\t"
         "movq  1*4*2(%0), %%mm1 \n\t"
@@ -191,7 +189,7 @@
 }
 #endif
 
-static void (*dctB)(DCTELEM *dst, DCTELEM *src)= dctB_c;
+static void (*dctB)(int16_t *dst, int16_t *src)= dctB_c;
 
 #define N0 4
 #define N1 5
@@ -228,7 +226,7 @@
     }
 }
 
-static int hardthresh_c(DCTELEM *src, int qp){
+static int hardthresh_c(int16_t *src, int qp){
     int i;
     int a;
 
@@ -244,7 +242,7 @@
     return (a + (1<<11))>>12;
 }
 
-static int mediumthresh_c(DCTELEM *src, int qp){
+static int mediumthresh_c(int16_t *src, int qp){
     int i;
     int a;
 
@@ -265,7 +263,7 @@
     return (a + (1<<11))>>12;
 }
 
-static int softthresh_c(DCTELEM *src, int qp){
+static int softthresh_c(int16_t *src, int qp){
     int i;
     int a;
 
@@ -282,14 +280,14 @@
     return (a + (1<<11))>>12;
 }
 
-static int (*requantize)(DCTELEM *src, int qp)= hardthresh_c;
+static int (*requantize)(int16_t *src, int qp)= 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;
     const int stride= is_luma ? p->temp_stride : ((width+16+15)&(~15));
     uint8_t  *p_src= p->src + 8*stride;
-    DCTELEM *block= (DCTELEM *)p->src;
-    DCTELEM *temp= (DCTELEM *)(p->src + 32);
+    int16_t *block= (int16_t *)p->src;
+    int16_t *temp= (int16_t *)(p->src + 32);
 
     if (!src || !dst) return; // HACK avoid crash for Y8 colourspace
     for(y=0; y<height; y++){
@@ -310,7 +308,7 @@
         for(x=-8; x<0; x+=4){
             const int index= x + y*stride + (8-3)*(1+stride) + 8; //FIXME silly offset
             uint8_t *src  = p_src + index;
-            DCTELEM *tp= temp+4*x;
+            int16_t *tp= temp+4*x;
 
             dctA_c(tp+4*8, src, stride);
         }
@@ -328,7 +326,7 @@
             for(; x<end; x++){
                 const int index= x + y*stride + (8-3)*(1+stride) + 8; //FIXME silly offset
                 uint8_t *src  = p_src + index;
-                DCTELEM *tp= temp+4*x;
+                int16_t *tp= temp+4*x;
                 int v;
 
                 if((x&3)==0)
@@ -354,13 +352,13 @@
     vf->priv->temp_stride= (width+16+15)&(~15);
     vf->priv->src = av_malloc(vf->priv->temp_stride*(h+8)*sizeof(uint8_t));
 
-    return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
+    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=vf_get_image(vf->next,mpi->imgfmt,
+    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];
@@ -381,11 +379,11 @@
         dmpi=vf->dmpi;
     }else{
         // no DR, so get a new image! hope we'll get DR buffer:
-        dmpi=vf_get_image(vf->next,mpi->imgfmt,
+        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);
-        vf_clone_mpi_attributes(dmpi, mpi);
+        ff_vf_clone_mpi_attributes(dmpi, mpi);
     }
 
     vf->priv->mpeg2= mpi->qscale_type;
@@ -400,13 +398,13 @@
     }
 
 #if HAVE_MMX
-    if(gCpuCaps.hasMMX) __asm__ volatile ("emms\n\t");
+    if(ff_gCpuCaps.hasMMX) __asm__ volatile ("emms\n\t");
 #endif
 #if HAVE_MMX2
-    if(gCpuCaps.hasMMX2) __asm__ volatile ("sfence\n\t");
+    if(ff_gCpuCaps.hasMMX2) __asm__ volatile ("sfence\n\t");
 #endif
 
-    return vf_next_put_image(vf,dmpi, pts);
+    return ff_vf_next_put_image(vf,dmpi, pts);
 }
 
 static void uninit(struct vf_instance *vf){
@@ -433,13 +431,13 @@
     case IMGFMT_444P:
     case IMGFMT_422P:
     case IMGFMT_411P:
-        return vf_next_query_format(vf,fmt);
+        return ff_vf_next_query_format(vf,fmt);
     }
     return 0;
 }
 
 static int control(struct vf_instance *vf, int request, void* data){
-    return vf_next_control(vf,request,data);
+    return ff_vf_next_control(vf,request,data);
 }
 
 static int vf_open(vf_instance_t *vf, char *args){
@@ -467,12 +465,12 @@
     }
 
 #if HAVE_MMX
-    if(gCpuCaps.hasMMX){
+    if(ff_gCpuCaps.hasMMX){
         dctB= dctB_mmx;
     }
 #endif
 #if 0
-    if(gCpuCaps.hasMMX){
+    if(ff_gCpuCaps.hasMMX){
         switch(vf->priv->mode){
             case 0: requantize= hardthresh_mmx; break;
             case 1: requantize= softthresh_mmx; break;
@@ -483,7 +481,7 @@
     return 1;
 }
 
-const vf_info_t vf_info_pp7 = {
+const vf_info_t ff_vf_info_pp7 = {
     "postprocess 7",
     "pp7",
     "Michael Niedermayer",
diff --git a/libavfilter/libmpcodecs/vf_pullup.c b/libavfilter/libmpcodecs/vf_pullup.c
index ba4ae02..e4a28c4 100644
--- a/libavfilter/libmpcodecs/vf_pullup.c
+++ b/libavfilter/libmpcodecs/vf_pullup.c
@@ -49,7 +49,7 @@
     if (mpi->flags & MP_IMGFLAG_PLANAR) {
         c->format = PULLUP_FMT_Y;
         c->nplanes = 4;
-        pullup_preinit_context(c);
+        ff_pullup_preinit_context(c);
         c->bpp[0] = c->bpp[1] = c->bpp[2] = 8;
         c->w[0] = mpi->w;
         c->h[0] = mpi->h;
@@ -63,14 +63,14 @@
         c->background[1] = c->background[2] = 128;
     }
 
-    if (gCpuCaps.hasMMX) c->cpu |= PULLUP_CPU_MMX;
-    if (gCpuCaps.hasMMX2) c->cpu |= PULLUP_CPU_MMX2;
-    if (gCpuCaps.has3DNow) c->cpu |= PULLUP_CPU_3DNOW;
-    if (gCpuCaps.has3DNowExt) c->cpu |= PULLUP_CPU_3DNOWEXT;
-    if (gCpuCaps.hasSSE) c->cpu |= PULLUP_CPU_SSE;
-    if (gCpuCaps.hasSSE2) c->cpu |= PULLUP_CPU_SSE2;
+    if (ff_gCpuCaps.hasMMX) c->cpu |= PULLUP_CPU_MMX;
+    if (ff_gCpuCaps.hasMMX2) c->cpu |= PULLUP_CPU_MMX2;
+    if (ff_gCpuCaps.has3DNow) c->cpu |= PULLUP_CPU_3DNOW;
+    if (ff_gCpuCaps.has3DNowExt) c->cpu |= PULLUP_CPU_3DNOWEXT;
+    if (ff_gCpuCaps.hasSSE) c->cpu |= PULLUP_CPU_SSE;
+    if (ff_gCpuCaps.hasSSE2) c->cpu |= PULLUP_CPU_SSE2;
 
-    pullup_init_context(c);
+    ff_pullup_init_context(c);
 
     vf->priv->init = 1;
     vf->priv->qbuf = malloc(c->w[3]);
@@ -87,7 +87,7 @@
 
     if (!vf->priv->init) init_pullup(vf, mpi);
 
-    b = pullup_get_buffer(c, 2);
+    b = ff_pullup_get_buffer(c, 2);
     if (!b) return; /* shouldn't happen... */
 
     mpi->priv = b;
@@ -120,11 +120,11 @@
         b = mpi->priv;
         mpi->priv = 0;
     } else {
-        b = pullup_get_buffer(c, 2);
+        b = ff_pullup_get_buffer(c, 2);
         if (!b) {
-            mp_msg(MSGT_VFILTER,MSGL_ERR,"Could not get buffer from pullup!\n");
-            f = pullup_get_frame(c);
-            pullup_release_frame(f);
+            ff_mp_msg(MSGT_VFILTER,MSGL_ERR,"Could not get buffer from pullup!\n");
+            f = ff_pullup_get_frame(c);
+            ff_pullup_release_frame(f);
             return 0;
         }
         memcpy_pic(b->planes[0], mpi->planes[0], mpi->w, mpi->h,
@@ -145,31 +145,31 @@
 
     p = mpi->fields & MP_IMGFIELD_TOP_FIRST ? 0 :
         (mpi->fields & MP_IMGFIELD_ORDERED ? 1 : 0);
-    pullup_submit_field(c, b, p);
-    pullup_submit_field(c, b, p^1);
+    ff_pullup_submit_field(c, b, p);
+    ff_pullup_submit_field(c, b, p^1);
     if (mpi->fields & MP_IMGFIELD_REPEAT_FIRST)
-        pullup_submit_field(c, b, p);
+        ff_pullup_submit_field(c, b, p);
 
-    pullup_release_buffer(b, 2);
+    ff_pullup_release_buffer(b, 2);
 
-    f = pullup_get_frame(c);
+    f = ff_pullup_get_frame(c);
 
     /* Fake yes for first few frames (buffer depth) to keep from
      * breaking A/V sync with G1's bad architecture... */
     if (!f) return vf->priv->fakecount ? (--vf->priv->fakecount,1) : 0;
 
     if (f->length < 2) {
-        pullup_release_frame(f);
-        f = pullup_get_frame(c);
+        ff_pullup_release_frame(f);
+        f = ff_pullup_get_frame(c);
         if (!f) return 0;
         if (f->length < 2) {
-            pullup_release_frame(f);
+            ff_pullup_release_frame(f);
             if (!(mpi->fields & MP_IMGFIELD_REPEAT_FIRST))
                 return 0;
-            f = pullup_get_frame(c);
+            f = ff_pullup_get_frame(c);
             if (!f) return 0;
             if (f->length < 2) {
-                pullup_release_frame(f);
+                ff_pullup_release_frame(f);
                 return 0;
             }
         }
@@ -194,12 +194,12 @@
 
     /* If the frame isn't already exportable... */
     while (!f->buffer) {
-        dmpi = vf_get_image(vf->next, mpi->imgfmt,
+        dmpi = ff_vf_get_image(vf->next, mpi->imgfmt,
             MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
             mpi->width, mpi->height);
         /* FIXME: Is it ok to discard dmpi if it's not direct? */
         if (!(dmpi->flags & MP_IMGFLAG_DIRECT)) {
-            pullup_pack_frame(c, f);
+            ff_pullup_pack_frame(c, f);
             break;
         }
         /* Direct render fields into output buffer */
@@ -224,15 +224,15 @@
                 mpi->chroma_width, mpi->chroma_height/2,
                 dmpi->stride[2]*2, c->stride[2]*2);
         }
-        pullup_release_frame(f);
+        ff_pullup_release_frame(f);
         if (mpi->qscale) {
             dmpi->qscale = vf->priv->qbuf;
             dmpi->qstride = mpi->qstride;
             dmpi->qscale_type = mpi->qscale_type;
         }
-        return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
+        return ff_vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
     }
-    dmpi = vf_get_image(vf->next, mpi->imgfmt,
+    dmpi = ff_vf_get_image(vf->next, mpi->imgfmt,
         MP_IMGTYPE_EXPORT, MP_IMGFLAG_ACCEPT_STRIDE,
         mpi->width, mpi->height);
 
@@ -249,8 +249,8 @@
         dmpi->qstride = mpi->qstride;
         dmpi->qscale_type = mpi->qscale_type;
     }
-    ret = vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
-    pullup_release_frame(f);
+    ret = ff_vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
+    ff_pullup_release_frame(f);
     return ret;
 }
 
@@ -261,7 +261,7 @@
     case IMGFMT_YV12:
     case IMGFMT_IYUV:
     case IMGFMT_I420:
-        return vf_next_query_format(vf, fmt);
+        return ff_vf_next_query_format(vf, fmt);
     }
     return 0;
 }
@@ -270,13 +270,16 @@
     int width, int height, int d_width, int d_height,
     unsigned int flags, unsigned int outfmt)
 {
-    if (height&3) return 0;
-    return vf_next_config(vf, width, height, d_width, d_height, flags, outfmt);
+    if (height&3) {
+        ff_mp_msg(MSGT_VFILTER, MSGL_ERR, "height must be divisible by four\n");
+        return 0;
+    }
+    return ff_vf_next_config(vf, width, height, d_width, d_height, flags, outfmt);
 }
 
 static void uninit(struct vf_instance *vf)
 {
-    pullup_free_context(vf->priv->ctx);
+    ff_pullup_free_context(vf->priv->ctx);
     free(vf->priv);
 }
 
@@ -291,7 +294,7 @@
     vf->uninit = uninit;
     vf->default_reqs = VFCAP_ACCEPT_STRIDE;
     vf->priv = p = calloc(1, sizeof(struct vf_priv_s));
-    p->ctx = c = pullup_alloc_context();
+    p->ctx = c = ff_pullup_alloc_context();
     p->fakecount = 1;
     c->junk_left = c->junk_right = 1;
     c->junk_top = c->junk_bottom = 4;
@@ -303,7 +306,7 @@
     return 1;
 }
 
-const vf_info_t vf_info_pullup = {
+const vf_info_t ff_vf_info_pullup = {
     "pullup (from field sequence to frames)",
     "pullup",
     "Rich Felker",
diff --git a/libavfilter/libmpcodecs/vf_qp.c b/libavfilter/libmpcodecs/vf_qp.c
index d74f138..579ec1c 100644
--- a/libavfilter/libmpcodecs/vf_qp.c
+++ b/libavfilter/libmpcodecs/vf_qp.c
@@ -33,6 +33,7 @@
 
 #include "libavcodec/avcodec.h"
 #include "libavutil/eval.h"
+#include "libavutil/mem.h"
 
 
 struct vf_priv_s {
@@ -72,19 +73,19 @@
             res= av_expr_parse_and_eval(&temp_val, vf->priv->eq, const_names, const_values, NULL, NULL, NULL, NULL, NULL, 0, NULL);
 
             if (res < 0){
-                mp_msg(MSGT_VFILTER, MSGL_ERR, "qp: Error evaluating \"%s\" \n", vf->priv->eq);
+                ff_mp_msg(MSGT_VFILTER, MSGL_ERR, "qp: Error evaluating \"%s\" \n", vf->priv->eq);
                 return 0;
             }
             vf->priv->lut[i+129]= lrintf(temp_val);
         }
 
-        return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
+        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=vf_get_image(vf->next,mpi->imgfmt,
+    vf->dmpi=ff_vf_get_image(vf->next,mpi->imgfmt,
         mpi->type, mpi->flags, mpi->w, mpi->h);
     mpi->planes[0]=vf->dmpi->planes[0];
     mpi->stride[0]=vf->dmpi->stride[0];
@@ -104,7 +105,7 @@
 
         if(!(mpi->flags&MP_IMGFLAG_DIRECT)){
                 // no DR, so get a new image! hope we'll get DR buffer:
-                vf->dmpi=vf_get_image(vf->next,mpi->imgfmt,
+                vf->dmpi=ff_vf_get_image(vf->next,mpi->imgfmt,
                 MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE|MP_IMGFLAG_PREFER_ALIGNED_STRIDE,
                 mpi->w,mpi->h);
         }
@@ -118,7 +119,7 @@
                     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]);
                 }
         }
-        vf_clone_mpi_attributes(dmpi, mpi);
+        ff_vf_clone_mpi_attributes(dmpi, mpi);
 
         dmpi->qscale = vf->priv->qp;
         dmpi->qstride= vf->priv->qp_stride;
@@ -138,7 +139,7 @@
             }
         }
 
-        return vf_next_put_image(vf,dmpi, pts);
+        return ff_vf_next_put_image(vf,dmpi, pts);
 }
 
 static void uninit(struct vf_instance *vf){
@@ -167,7 +168,7 @@
     return 1;
 }
 
-const vf_info_t vf_info_qp = {
+const vf_info_t ff_vf_info_qp = {
     "QP changer",
     "qp",
     "Michael Niedermayer",
diff --git a/libavfilter/libmpcodecs/vf_sab.c b/libavfilter/libmpcodecs/vf_sab.c
index 807b726..2928a85 100644
--- a/libavfilter/libmpcodecs/vf_sab.c
+++ b/libavfilter/libmpcodecs/vf_sab.c
@@ -32,6 +32,7 @@
 #endif
 
 #include "libavutil/avutil.h"
+#include "libavutil/mem.h"
 #include "img_format.h"
 #include "mp_image.h"
 #include "vf.h"
@@ -148,7 +149,7 @@
     getSubSampleFactors(&sw, &sh, outfmt);
     allocStuff(&vf->priv->chroma, width>>sw, height>>sh);
 
-    return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
+    return ff_vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
 }
 
 static void freeBuffers(FilterParam *f){
@@ -244,7 +245,7 @@
     int cw= mpi->w >> mpi->chroma_x_shift;
     int ch= mpi->h >> mpi->chroma_y_shift;
 
-    mp_image_t *dmpi=vf_get_image(vf->next,mpi->imgfmt,
+    mp_image_t *dmpi=ff_vf_get_image(vf->next,mpi->imgfmt,
         MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
         mpi->w,mpi->h);
 
@@ -254,7 +255,7 @@
     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 vf_next_put_image(vf,dmpi, pts);
+    return ff_vf_next_put_image(vf,dmpi, pts);
 }
 
 //===========================================================================//
@@ -269,7 +270,7 @@
     case IMGFMT_444P:
     case IMGFMT_422P:
     case IMGFMT_411P:
-        return vf_next_query_format(vf, fmt);
+        return ff_vf_next_query_format(vf, fmt);
     }
     return 0;
 }
@@ -311,7 +312,7 @@
     return 1;
 }
 
-const vf_info_t vf_info_sab = {
+const vf_info_t ff_vf_info_sab = {
     "shape adaptive blur",
     "sab",
     "Michael Niedermayer",
diff --git a/libavfilter/libmpcodecs/vf_scale.h b/libavfilter/libmpcodecs/vf_scale.h
index 4de3b48..177fbe5 100644
--- a/libavfilter/libmpcodecs/vf_scale.h
+++ b/libavfilter/libmpcodecs/vf_scale.h
@@ -19,16 +19,16 @@
 #ifndef MPLAYER_VF_SCALE_H
 #define MPLAYER_VF_SCALE_H
 
-extern int sws_chr_vshift;
-extern int sws_chr_hshift;
+extern int ff_sws_chr_vshift;
+extern int ff_sws_chr_hshift;
 
-extern float sws_chr_gblur;
-extern float sws_lum_gblur;
-extern float sws_chr_sharpen;
-extern float sws_lum_sharpen;
+extern float ff_sws_chr_gblur;
+extern float ff_sws_lum_gblur;
+extern float ff_sws_chr_sharpen;
+extern float ff_sws_lum_sharpen;
 
-extern int sws_flags;
+extern int ff_sws_flags;
 
-struct SwsContext *sws_getContextFromCmdLine(int srcW, int srcH, int srcFormat, int dstW, int dstH, int dstFormat);
+struct SwsContext *ff_sws_getContextFromCmdLine(int srcW, int srcH, int srcFormat, int dstW, int dstH, int dstFormat);
 
 #endif /* MPLAYER_VF_SCALE_H */
diff --git a/libavfilter/libmpcodecs/vf_softpulldown.c b/libavfilter/libmpcodecs/vf_softpulldown.c
index 1a66e56..556374e 100644
--- a/libavfilter/libmpcodecs/vf_softpulldown.c
+++ b/libavfilter/libmpcodecs/vf_softpulldown.c
@@ -42,7 +42,7 @@
     int flags = mpi->fields;
     int state = vf->priv->state;
 
-    dmpi = vf_get_image(vf->next, mpi->imgfmt,
+    dmpi = ff_vf_get_image(vf->next, mpi->imgfmt,
                         MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE |
                         MP_IMGFLAG_PRESERVE, mpi->width, mpi->height);
 
@@ -52,7 +52,7 @@
          !(flags & MP_IMGFIELD_TOP_FIRST)) ||
         (state == 1 &&
          flags & MP_IMGFIELD_TOP_FIRST)) {
-        mp_msg(MSGT_VFILTER, MSGL_WARN,
+        ff_mp_msg(MSGT_VFILTER, MSGL_WARN,
                "softpulldown: Unexpected field flags: state=%d top_field_first=%d repeat_first_field=%d\n",
                state,
                (flags & MP_IMGFIELD_TOP_FIRST) != 0,
@@ -61,7 +61,7 @@
     }
 
     if (state == 0) {
-        ret = vf_next_put_image(vf, mpi, MP_NOPTS_VALUE);
+        ret = ff_vf_next_put_image(vf, mpi, MP_NOPTS_VALUE);
         vf->priv->out++;
         if (flags & MP_IMGFIELD_REPEAT_FIRST) {
             my_memcpy_pic(dmpi->planes[0],
@@ -97,10 +97,10 @@
                           mpi->chroma_width, mpi->chroma_height/2,
                           dmpi->stride[2]*2, mpi->stride[2]*2);
         }
-        ret = vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
+        ret = ff_vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
         vf->priv->out++;
         if (flags & MP_IMGFIELD_REPEAT_FIRST) {
-            ret |= vf_next_put_image(vf, mpi, MP_NOPTS_VALUE);
+            ret |= ff_vf_next_put_image(vf, mpi, MP_NOPTS_VALUE);
             vf->priv->out++;
             state=0;
         } else {
@@ -133,12 +133,12 @@
     int width, int height, int d_width, int d_height,
     unsigned int flags, unsigned int outfmt)
 {
-    return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
+    return ff_vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
 }
 
 static void uninit(struct vf_instance *vf)
 {
-    mp_msg(MSGT_VFILTER, MSGL_INFO, "softpulldown: %lld frames in, %lld frames out\n", vf->priv->in, vf->priv->out);
+    ff_mp_msg(MSGT_VFILTER, MSGL_INFO, "softpulldown: %lld frames in, %lld frames out\n", vf->priv->in, vf->priv->out);
     free(vf->priv);
 }
 
@@ -153,7 +153,7 @@
     return 1;
 }
 
-const vf_info_t vf_info_softpulldown = {
+const vf_info_t ff_vf_info_softpulldown = {
     "mpeg2 soft 3:2 pulldown",
     "softpulldown",
     "Tobias Diedrich <ranma+mplayer@tdiedrich.de>",
diff --git a/libavfilter/libmpcodecs/vf_softskip.c b/libavfilter/libmpcodecs/vf_softskip.c
deleted file mode 100644
index 150c3e7..0000000
--- a/libavfilter/libmpcodecs/vf_softskip.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * 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"
-
-struct vf_priv_s {
-    int skipflag;
-};
-
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
-{
-    mp_image_t *dmpi;
-
-    if (vf->priv->skipflag)
-        return vf->priv->skipflag = 0;
-
-    dmpi = vf_get_image(vf->next, mpi->imgfmt,
-        MP_IMGTYPE_EXPORT, 0, mpi->width, mpi->height);
-    vf_clone_mpi_attributes(dmpi, mpi);
-
-    dmpi->planes[0] = mpi->planes[0];
-    dmpi->stride[0] = mpi->stride[0];
-    if (dmpi->flags&MP_IMGFLAG_PLANAR) {
-        dmpi->planes[1] = mpi->planes[1];
-        dmpi->stride[1] = mpi->stride[1];
-        dmpi->planes[2] = mpi->planes[2];
-        dmpi->stride[2] = mpi->stride[2];
-    }
-
-    return vf_next_put_image(vf, dmpi, pts);
-}
-
-static int control(struct vf_instance *vf, int request, void* data)
-{
-    switch (request) {
-    case VFCTRL_SKIP_NEXT_FRAME:
-        vf->priv->skipflag = 1;
-        return CONTROL_TRUE;
-    }
-    return vf_next_control(vf, request, data);
-}
-
-#if 0
-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 vf_next_query_format(vf, fmt);
-    }
-    return 0;
-}
-#endif
-
-static void uninit(struct vf_instance *vf)
-{
-    free(vf->priv);
-}
-
-static int vf_open(vf_instance_t *vf, char *args)
-{
-    vf->put_image = put_image;
-    vf->control = control;
-    vf->uninit = uninit;
-    vf->priv = calloc(1, sizeof(struct vf_priv_s));
-    return 1;
-}
-
-const vf_info_t vf_info_softskip = {
-    "soft (post-filter) frame skipping for encoding",
-    "softskip",
-    "Rich Felker",
-    "",
-    vf_open,
-    NULL
-};
diff --git a/libavfilter/libmpcodecs/vf_spp.c b/libavfilter/libmpcodecs/vf_spp.c
index 0b4b230..75ede23 100644
--- a/libavfilter/libmpcodecs/vf_spp.c
+++ b/libavfilter/libmpcodecs/vf_spp.c
@@ -37,6 +37,7 @@
 #include "mp_msg.h"
 #include "cpudetect.h"
 
+#include "libavutil/common.h"
 #include "libavutil/internal.h"
 #include "libavutil/intreadwrite.h"
 #include "libavcodec/avcodec.h"
@@ -49,7 +50,7 @@
 #include "img_format.h"
 #include "mp_image.h"
 #include "vf.h"
-#include "vd_ffmpeg.h"
+#include "av_helpers.h"
 #include "libvo/fastmemcpy.h"
 
 #define XMIN(a,b) ((a) < (b) ? (a) : (b))
@@ -105,7 +106,7 @@
 
 #define SHIFT 22
 
-static void hardthresh_c(DCTELEM dst[64], DCTELEM src[64], int qp, uint8_t *permutation){
+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;
@@ -113,7 +114,7 @@
         threshold1= qp*((1<<4) - bias) - 1;
         threshold2= (threshold1<<1);
 
-        memset(dst, 0, 64*sizeof(DCTELEM));
+        memset(dst, 0, 64*sizeof(int16_t));
         dst[0]= (src[0] + 4)>>3;
 
         for(i=1; i<64; i++){
@@ -125,7 +126,7 @@
         }
 }
 
-static void softthresh_c(DCTELEM dst[64], DCTELEM src[64], int qp, uint8_t *permutation){
+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;
@@ -133,7 +134,7 @@
         threshold1= qp*((1<<4) - bias) - 1;
         threshold2= (threshold1<<1);
 
-        memset(dst, 0, 64*sizeof(DCTELEM));
+        memset(dst, 0, 64*sizeof(int16_t));
         dst[0]= (src[0] + 4)>>3;
 
         for(i=1; i<64; i++){
@@ -149,7 +150,7 @@
 }
 
 #if HAVE_MMX
-static void hardthresh_mmx(DCTELEM dst[64], DCTELEM src[64], int qp, uint8_t *permutation){
+static void hardthresh_mmx(int16_t dst[64], int16_t src[64], int qp, uint8_t *permutation){
         int bias= 0; //FIXME
         unsigned int threshold1;
 
@@ -217,7 +218,7 @@
         dst[0]= (src[0] + 4)>>3;
 }
 
-static void softthresh_mmx(DCTELEM dst[64], DCTELEM src[64], int qp, uint8_t *permutation){
+static void softthresh_mmx(int16_t dst[64], int16_t src[64], int qp, uint8_t *permutation){
         int bias= 0; //FIXME
         unsigned int threshold1;
 
@@ -294,7 +295,7 @@
 }
 #endif
 
-static inline void add_block(int16_t *dst, int stride, DCTELEM block[64]){
+static inline void add_block(int16_t *dst, int stride, int16_t block[64]){
         int y;
 
         for(y=0; y<8; y++){
@@ -372,15 +373,15 @@
 
 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)(DCTELEM dst[64], DCTELEM src[64], int qp, uint8_t *permutation)= hardthresh_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];
-        DCTELEM *block = (DCTELEM *)block_align;
-        DCTELEM *block2= (DCTELEM *)(block_align+16);
+        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++){
@@ -445,13 +446,13 @@
         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 vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
+        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=vf_get_image(vf->next,mpi->imgfmt,
+    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];
@@ -470,11 +471,11 @@
 
         if(!(mpi->flags&MP_IMGFLAG_DIRECT)){
                 // no DR, so get a new image! hope we'll get DR buffer:
-                dmpi=vf_get_image(vf->next,mpi->imgfmt,
+                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);
-                vf_clone_mpi_attributes(dmpi, mpi);
+                ff_vf_clone_mpi_attributes(dmpi, mpi);
         }else{
            dmpi=vf->dmpi;
         }
@@ -508,13 +509,13 @@
         }
 
 #if HAVE_MMX
-        if(gCpuCaps.hasMMX) __asm__ volatile ("emms\n\t");
+        if(ff_gCpuCaps.hasMMX) __asm__ volatile ("emms\n\t");
 #endif
 #if HAVE_MMX2
-        if(gCpuCaps.hasMMX2) __asm__ volatile ("sfence\n\t");
+        if(ff_gCpuCaps.hasMMX2) __asm__ volatile ("sfence\n\t");
 #endif
 
-        return vf_next_put_image(vf,dmpi, pts);
+        return ff_vf_next_put_image(vf,dmpi, pts);
 }
 
 static void uninit(struct vf_instance *vf){
@@ -547,7 +548,7 @@
         case IMGFMT_444P:
         case IMGFMT_422P:
         case IMGFMT_411P:
-            return vf_next_query_format(vf,fmt);
+            return ff_vf_next_query_format(vf,fmt);
     }
     return 0;
 }
@@ -560,7 +561,7 @@
         vf->priv->log2_count= *((unsigned int*)data);
         return CONTROL_TRUE;
     }
-    return vf_next_control(vf,request,data);
+    return ff_vf_next_control(vf,request,data);
 }
 
 static int vf_open(vf_instance_t *vf, char *args){
@@ -576,10 +577,10 @@
     vf->priv=malloc(sizeof(struct vf_priv_s));
     memset(vf->priv, 0, sizeof(struct vf_priv_s));
 
-    init_avcodec();
+    ff_init_avcodec();
 
-    vf->priv->avctx= avcodec_alloc_context();
-    dsputil_init(&vf->priv->dsp, vf->priv->avctx);
+    vf->priv->avctx= avcodec_alloc_context3(NULL);
+    ff_dsputil_init(&vf->priv->dsp, vf->priv->avctx);
 
     vf->priv->log2_count= 3;
 
@@ -598,7 +599,7 @@
     }
 
 #if HAVE_MMX
-    if(gCpuCaps.hasMMX){
+    if(ff_gCpuCaps.hasMMX){
         store_slice= store_slice_mmx;
         switch(vf->priv->mode&3){
             case 0: requantize= hardthresh_mmx; break;
@@ -610,7 +611,7 @@
     return 1;
 }
 
-const vf_info_t vf_info_spp = {
+const vf_info_t ff_vf_info_spp = {
     "simple postprocess",
     "spp",
     "Michael Niedermayer",
diff --git a/libavfilter/libmpcodecs/vf_stereo3d.c b/libavfilter/libmpcodecs/vf_stereo3d.c
index b8bc390..fe75bd0 100644
--- a/libavfilter/libmpcodecs/vf_stereo3d.c
+++ b/libavfilter/libmpcodecs/vf_stereo3d.c
@@ -43,9 +43,11 @@
     ANAGLYPH_GM_GRAY,   //anaglyph green/magenta gray
     ANAGLYPH_GM_HALF,   //anaglyph green/magenta half colored
     ANAGLYPH_GM_COLOR,  //anaglyph green/magenta colored
+    ANAGLYPH_GM_DUBOIS, //anaglyph green/magenta dubois
     ANAGLYPH_YB_GRAY,   //anaglyph yellow/blue gray
     ANAGLYPH_YB_HALF,   //anaglyph yellow/blue half colored
     ANAGLYPH_YB_COLOR,  //anaglyph yellow/blue colored
+    ANAGLYPH_YB_DUBOIS, //anaglyph yellow/blue dubois
     MONO_L,             //mono output for debugging (left eye only)
     MONO_R,             //mono output for debugging (right eye only)
     SIDE_BY_SIDE_LR,    //side by side parallel (left eye left, right eye right)
@@ -72,37 +74,55 @@
 } component;
 
 //==global variables==//
-static const int ana_coeff[10][3][6] = {
-    {{19595, 38470,  7471,     0,     0,     0},    //ANAGLYPH_RC_GRAY
+static const int ana_coeff[][3][6] = {
+  [ANAGLYPH_RC_GRAY]   =
+    {{19595, 38470,  7471,     0,     0,     0},
      {    0,     0,     0, 19595, 38470,  7471},
      {    0,     0,     0, 19595, 38470,  7471}},
-    {{19595, 38470,  7471,     0,     0,     0},    //ANAGLYPH_RC_HALF
+  [ANAGLYPH_RC_HALF]   =
+    {{19595, 38470,  7471,     0,     0,     0},
      {    0,     0,     0,     0, 65536,     0},
      {    0,     0,     0,     0,     0, 65536}},
-    {{65536,     0,     0,     0,     0,     0},    //ANAGLYPH_RC_COLOR
+  [ANAGLYPH_RC_COLOR]  =
+    {{65536,     0,     0,     0,     0,     0},
      {    0,     0,     0,     0, 65536,     0},
      {    0,     0,     0,     0,     0, 65536}},
-    {{29891, 32800, 11559, -2849, -5763,  -102},    //ANAGLYPH_RC_DUBOIS
+  [ANAGLYPH_RC_DUBOIS] =
+    {{29891, 32800, 11559, -2849, -5763,  -102},
      {-2627, -2479, -1033, 24804, 48080, -1209},
      { -997, -1350,  -358, -4729, -7403, 80373}},
-    {{    0,     0,     0, 19595, 38470,  7471},    //ANAGLYPH_GM_GRAY
+  [ANAGLYPH_GM_GRAY]   =
+    {{    0,     0,     0, 19595, 38470,  7471},
      {19595, 38470,  7471,     0,     0,     0},
      {    0,     0,     0, 19595, 38470,  7471}},
-    {{    0,     0,     0, 65536,     0,     0},    //ANAGLYPH_GM_HALF
+  [ANAGLYPH_GM_HALF]   =
+    {{    0,     0,     0, 65536,     0,     0},
      {19595, 38470,  7471,     0,     0,     0},
      {    0,     0,     0,     0,     0, 65536}},
-    {{    0,     0,     0, 65536,     0,     0},    //ANAGLYPH_GM_COLOR
+  [ANAGLYPH_GM_COLOR]  =
+    {{    0,     0,     0, 65536,     0,     0},
      {    0, 65536,     0,     0,     0,     0},
      {    0,     0,     0,     0,     0, 65536}},
-    {{    0,     0,     0, 19595, 38470,  7471},    //ANAGLYPH_YB_GRAY
+  [ANAGLYPH_GM_DUBOIS]  =
+    {{-4063,-10354, -2556, 34669, 46203,  1573},
+     {18612, 43778,  9372, -1049,  -983, -4260},
+     { -983, -1769,  1376,   590,  4915, 61407}},
+  [ANAGLYPH_YB_GRAY]   =
+    {{    0,     0,     0, 19595, 38470,  7471},
      {    0,     0,     0, 19595, 38470,  7471},
      {19595, 38470,  7471,     0,     0,     0}},
-    {{    0,     0,     0, 65536,     0,     0},    //ANAGLYPH_YB_HALF
+  [ANAGLYPH_YB_HALF]   =
+    {{    0,     0,     0, 65536,     0,     0},
      {    0,     0,     0,     0, 65536,     0},
      {19595, 38470,  7471,     0,     0,     0}},
-    {{    0,     0,     0, 65536,     0,     0},    //ANAGLYPH_YB_COLOR
+  [ANAGLYPH_YB_COLOR]  =
+    {{    0,     0,     0, 65536,     0,     0},
      {    0,     0,     0,     0, 65536,     0},
-     {    0,     0, 65536,     0,     0,     0}}
+     {    0,     0, 65536,     0,     0,     0}},
+  [ANAGLYPH_YB_DUBOIS] =
+    {{65535,-12650,18451,   -987, -7590, -1049},
+     {-1604, 56032, 4196,    370,  3826, -1049},
+     {-2345,-10676, 1358,   5801, 11416, 56217}},
 };
 
 struct vf_priv_s {
@@ -112,7 +132,7 @@
     unsigned int width;
     unsigned int height;
     unsigned int row_step;
-} const vf_priv_default = {
+} const ff_vf_priv_default = {
   {SIDE_BY_SIDE_LR},
   {ANAGLYPH_RC_DUBOIS}
 };
@@ -132,7 +152,7 @@
                   int d_height, unsigned int flags, unsigned int outfmt)
 {
     if ((width & 1) || (height & 1)) {
-        mp_msg(MSGT_VFILTER, MSGL_WARN, "[stereo3d] invalid height or width\n");
+        ff_mp_msg(MSGT_VFILTER, MSGL_WARN, "[stereo3d] invalid height or width\n");
         return 0;
     }
     //default input values
@@ -173,7 +193,7 @@
         vf->priv->in.row_left   = vf->priv->height;
         break;
     default:
-        mp_msg(MSGT_VFILTER, MSGL_WARN,
+        ff_mp_msg(MSGT_VFILTER, MSGL_WARN,
                "[stereo3d] stereo format of input is not supported\n");
         return 0;
         break;
@@ -195,9 +215,11 @@
     case ANAGLYPH_GM_GRAY:
     case ANAGLYPH_GM_HALF:
     case ANAGLYPH_GM_COLOR:
+    case ANAGLYPH_GM_DUBOIS:
     case ANAGLYPH_YB_GRAY:
     case ANAGLYPH_YB_HALF:
     case ANAGLYPH_YB_COLOR:
+    case ANAGLYPH_YB_DUBOIS:
         memcpy(vf->priv->ana_matrix, ana_coeff[vf->priv->out.fmt],
                sizeof(vf->priv->ana_matrix));
         break;
@@ -246,7 +268,7 @@
         //use default settings
         break;
     default:
-        mp_msg(MSGT_VFILTER, MSGL_WARN,
+        ff_mp_msg(MSGT_VFILTER, MSGL_WARN,
             "[stereo3d] stereo format of output is not supported\n");
         return 0;
         break;
@@ -256,7 +278,7 @@
         d_height    = d_height * vf->priv->out.height / height;
 //    }
 
-    return vf_next_config(vf, vf->priv->out.width, vf->priv->out.height,
+    return ff_vf_next_config(vf, vf->priv->out.width, vf->priv->out.height,
                           d_width, d_height, flags, outfmt);
 }
 
@@ -272,7 +294,7 @@
         int in_off_right = vf->priv->in.row_right  * mpi->stride[0]  +
                            vf->priv->in.off_right;
 
-        dmpi = vf_get_image(vf->next, IMGFMT_RGB24, MP_IMGTYPE_TEMP,
+        dmpi = ff_vf_get_image(vf->next, IMGFMT_RGB24, MP_IMGTYPE_TEMP,
                             MP_IMGFLAG_ACCEPT_STRIDE,
                             vf->priv->out.width, vf->priv->out.height);
         out_off_left   = vf->priv->out.row_left  * dmpi->stride[0] +
@@ -322,9 +344,11 @@
         case ANAGLYPH_GM_GRAY:
         case ANAGLYPH_GM_HALF:
         case ANAGLYPH_GM_COLOR:
+        case ANAGLYPH_GM_DUBOIS:
         case ANAGLYPH_YB_GRAY:
         case ANAGLYPH_YB_HALF:
-        case ANAGLYPH_YB_COLOR: {
+        case ANAGLYPH_YB_COLOR:
+        case ANAGLYPH_YB_DUBOIS: {
             int i,x,y,il,ir,o;
             unsigned char *source     = mpi->planes[0];
             unsigned char *dest       = dmpi->planes[0];
@@ -353,20 +377,20 @@
             break;
         }
         default:
-            mp_msg(MSGT_VFILTER, MSGL_WARN,
+            ff_mp_msg(MSGT_VFILTER, MSGL_WARN,
                    "[stereo3d] stereo format of output is not supported\n");
             return 0;
             break;
         }
     }
-    return vf_next_put_image(vf, dmpi, pts);
+    return ff_vf_next_put_image(vf, dmpi, pts);
 }
 
 static int query_format(struct vf_instance *vf, unsigned int fmt)
 {
     switch (fmt)
     case IMGFMT_RGB24:
-        return vf_next_query_format(vf, fmt);
+        return ff_vf_next_query_format(vf, fmt);
     return 0;
 }
 
@@ -410,12 +434,16 @@
     {"anaglyph_green_magenta_half_color",ANAGLYPH_GM_HALF},
     {"agmc",                             ANAGLYPH_GM_COLOR},
     {"anaglyph_green_magenta_color",     ANAGLYPH_GM_COLOR},
+    {"agmd",                             ANAGLYPH_GM_DUBOIS},
+    {"anaglyph_green_magenta_dubois",    ANAGLYPH_GM_DUBOIS},
     {"aybg",                             ANAGLYPH_YB_GRAY},
     {"anaglyph_yellow_blue_gray",        ANAGLYPH_YB_GRAY},
     {"aybh",                             ANAGLYPH_YB_HALF},
     {"anaglyph_yellow_blue_half_color",  ANAGLYPH_YB_HALF},
     {"aybc",                             ANAGLYPH_YB_COLOR},
     {"anaglyph_yellow_blue_color",       ANAGLYPH_YB_COLOR},
+    {"aybd",                             ANAGLYPH_YB_DUBOIS},
+    {"anaglyph_yellow_blue_dubois",      ANAGLYPH_YB_DUBOIS},
     {"ml",                               MONO_L},
     {"mono_left",                        MONO_L},
     {"mr",                               MONO_R},
@@ -496,13 +524,13 @@
 static const m_struct_t vf_opts = {
   "stereo3d",
   sizeof(struct vf_priv_s),
-  &vf_priv_default,
+  &ff_vf_priv_default,
   vf_opts_fields
 };
 #endif
 
 //==info struct==//
-const vf_info_t vf_info_stereo3d = {
+const vf_info_t ff_vf_info_stereo3d = {
     "stereoscopic 3d view",
     "stereo3d",
     "Gordon Schmidt",
diff --git a/libavfilter/libmpcodecs/vf_telecine.c b/libavfilter/libmpcodecs/vf_telecine.c
index 3ffa87f..77f75f0 100644
--- a/libavfilter/libmpcodecs/vf_telecine.c
+++ b/libavfilter/libmpcodecs/vf_telecine.c
@@ -42,7 +42,7 @@
 
     vf->priv->frame = (vf->priv->frame+1)%4;
 
-    dmpi = vf_get_image(vf->next, mpi->imgfmt,
+    dmpi = ff_vf_get_image(vf->next, mpi->imgfmt,
         MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE |
         MP_IMGFLAG_PRESERVE, mpi->width, mpi->height);
 
@@ -63,7 +63,7 @@
                 chroma_width, mpi->chroma_height/2,
                 dmpi->stride[2]*2, mpi->stride[2]*2);
         }
-        ret = vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
+        ret = ff_vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
         /* Fallthrough */
     case 1:
     case 2:
@@ -77,7 +77,7 @@
                 chroma_width, mpi->chroma_height,
                 dmpi->stride[2], mpi->stride[2]);
         }
-        return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE) || ret;
+        return ff_vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE) || ret;
     case 3:
         my_memcpy_pic(dmpi->planes[0]+dmpi->stride[0],
             mpi->planes[0]+mpi->stride[0], w, mpi->h/2,
@@ -92,7 +92,7 @@
                 chroma_width, mpi->chroma_height/2,
                 dmpi->stride[2]*2, mpi->stride[2]*2);
         }
-        ret = vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
+        ret = ff_vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
         my_memcpy_pic(dmpi->planes[0], mpi->planes[0], w, mpi->h/2,
             dmpi->stride[0]*2, mpi->stride[0]*2);
         if (mpi->flags & MP_IMGFLAG_PLANAR) {
@@ -116,7 +116,7 @@
     case IMGFMT_YV12:
     case IMGFMT_IYUV:
     case IMGFMT_I420:
-        return vf_next_query_format(vf, fmt);
+        return ff_vf_next_query_format(vf, fmt);
     }
     return 0;
 }
@@ -125,7 +125,7 @@
         int width, int height, int d_width, int d_height,
     unsigned int flags, unsigned int outfmt)
 {
-    return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
+    return ff_vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
 }
 #endif
 
@@ -148,7 +148,7 @@
     return 1;
 }
 
-const vf_info_t vf_info_telecine = {
+const vf_info_t ff_vf_info_telecine = {
     "telecine filter",
     "telecine",
     "Rich Felker",
diff --git a/libavfilter/libmpcodecs/vf_tinterlace.c b/libavfilter/libmpcodecs/vf_tinterlace.c
index 8cd6ac8..6c7dbab 100644
--- a/libavfilter/libmpcodecs/vf_tinterlace.c
+++ b/libavfilter/libmpcodecs/vf_tinterlace.c
@@ -46,7 +46,7 @@
     case 0:
         dmpi = vf->priv->dmpi;
         if (dmpi == NULL) {
-            dmpi = vf_get_image(vf->next, mpi->imgfmt,
+            dmpi = ff_vf_get_image(vf->next, mpi->imgfmt,
                         MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE |
                         MP_IMGFLAG_PRESERVE,
                         mpi->width, mpi->height*2);
@@ -76,23 +76,23 @@
                        mpi->chroma_width, mpi->chroma_height,
                        dmpi->stride[2]*2, mpi->stride[2]);
             }
-            ret = vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
+            ret = ff_vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
         }
         break;
     case 1:
         if (vf->priv->frame & 1)
-            ret = vf_next_put_image(vf, mpi, MP_NOPTS_VALUE);
+            ret = ff_vf_next_put_image(vf, mpi, MP_NOPTS_VALUE);
         break;
     case 2:
         if ((vf->priv->frame & 1) == 0)
-            ret = vf_next_put_image(vf, mpi, MP_NOPTS_VALUE);
+            ret = ff_vf_next_put_image(vf, mpi, MP_NOPTS_VALUE);
         break;
     case 3:
-        dmpi = vf_get_image(vf->next, mpi->imgfmt,
+        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 */
-        vf_mpi_clear(dmpi, 0, 0, dmpi->w, dmpi->h);
+        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]);
@@ -116,7 +116,7 @@
                        dmpi->stride[2]*2, mpi->stride[2]);
             }
         }
-        ret = vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
+        ret = ff_vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
         break;
     case 4:
         // Interleave even lines (only) from Frame 'i' with odd
@@ -132,7 +132,7 @@
         // etc.
 
         if (dmpi == NULL) {
-            dmpi = vf_get_image(vf->next, mpi->imgfmt,
+            dmpi = ff_vf_get_image(vf->next, mpi->imgfmt,
                         MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE |
                         MP_IMGFLAG_PRESERVE,
                         mpi->width, mpi->height);
@@ -166,7 +166,7 @@
                           mpi->chroma_width, mpi->chroma_height/2,
                           dmpi->stride[2]*2, mpi->stride[2]*2);
             }
-            ret = vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
+            ret = ff_vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
         }
         break;
     }
@@ -183,7 +183,7 @@
     case IMGFMT_YV12:
     case IMGFMT_IYUV:
     case IMGFMT_I420:
-        return vf_next_query_format(vf, fmt);
+        return ff_vf_next_query_format(vf, fmt);
     }
     return 0;
 }
@@ -195,11 +195,11 @@
     switch (vf->priv->mode) {
     case 0:
     case 3:
-        return vf_next_config(vf,width,height*2,d_width,d_height*2,flags,outfmt);
+        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 vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
+        return ff_vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
     }
     return 0;
 }
@@ -225,7 +225,7 @@
     return 1;
 }
 
-const vf_info_t vf_info_tinterlace = {
+const vf_info_t ff_vf_info_tinterlace = {
     "temporal field interlacing",
     "tinterlace",
     "Michael Zucchi",
diff --git a/libavfilter/libmpcodecs/vf_unsharp.c b/libavfilter/libmpcodecs/vf_unsharp.c
deleted file mode 100644
index db22f78..0000000
--- a/libavfilter/libmpcodecs/vf_unsharp.c
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * Copyright (C) 2002 Remi Guyomarch <rguyom@pobox.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 <inttypes.h>
-#include <math.h>
-
-#include "config.h"
-#include "mp_msg.h"
-#include "cpudetect.h"
-
-#if HAVE_MALLOC_H
-#include <malloc.h>
-#endif
-
-#include "img_format.h"
-#include "mp_image.h"
-#include "vf.h"
-#include "libvo/fastmemcpy.h"
-#include "libavutil/common.h"
-
-//===========================================================================//
-
-#define MIN_MATRIX_SIZE 3
-#define MAX_MATRIX_SIZE 63
-
-typedef struct FilterParam {
-    int msizeX, msizeY;
-    double amount;
-    uint32_t *SC[MAX_MATRIX_SIZE-1];
-} FilterParam;
-
-struct vf_priv_s {
-    FilterParam lumaParam;
-    FilterParam chromaParam;
-    unsigned int outfmt;
-};
-
-
-//===========================================================================//
-
-/* This code is based on :
-
-An Efficient algorithm for Gaussian blur using finite-state machines
-Frederick M. Waltz and John W. V. Miller
-
-SPIE Conf. on Machine Vision Systems for Inspection and Metrology VII
-Originally published Boston, Nov 98
-
-*/
-
-static void unsharp( uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int width, int height, FilterParam *fp ) {
-
-    uint32_t **SC = fp->SC;
-    uint32_t SR[MAX_MATRIX_SIZE-1], Tmp1, Tmp2;
-    uint8_t* src2 = src; // avoid gcc warning
-
-    int32_t res;
-    int x, y, z;
-    int amount = fp->amount * 65536.0;
-    int stepsX = fp->msizeX/2;
-    int stepsY = fp->msizeY/2;
-    int scalebits = (stepsX+stepsY)*2;
-    int32_t halfscale = 1 << ((stepsX+stepsY)*2-1);
-
-    if( !fp->amount ) {
-        if( src == dst )
-            return;
-        if( dstStride == srcStride )
-            fast_memcpy( dst, src, srcStride*height );
-        else
-            for( y=0; y<height; y++, dst+=dstStride, src+=srcStride )
-                fast_memcpy( dst, src, width );
-        return;
-    }
-
-    for( y=0; y<2*stepsY; y++ )
-        memset( SC[y], 0, sizeof(SC[y][0]) * (width+2*stepsX) );
-
-    for( y=-stepsY; y<height+stepsY; y++ ) {
-        if( y < height ) src2 = src;
-        memset( SR, 0, sizeof(SR[0]) * (2*stepsX-1) );
-        for( x=-stepsX; x<width+stepsX; x++ ) {
-            Tmp1 = x<=0 ? src2[0] : x>=width ? src2[width-1] : src2[x];
-            for( z=0; z<stepsX*2; z+=2 ) {
-                Tmp2 = SR[z+0] + Tmp1; SR[z+0] = Tmp1;
-                Tmp1 = SR[z+1] + Tmp2; SR[z+1] = Tmp2;
-            }
-            for( z=0; z<stepsY*2; z+=2 ) {
-                Tmp2 = SC[z+0][x+stepsX] + Tmp1; SC[z+0][x+stepsX] = Tmp1;
-                Tmp1 = SC[z+1][x+stepsX] + Tmp2; SC[z+1][x+stepsX] = Tmp2;
-            }
-            if( x>=stepsX && y>=stepsY ) {
-                uint8_t* srx = src - stepsY*srcStride + x - stepsX;
-                uint8_t* dsx = dst - stepsY*dstStride + x - stepsX;
-
-                res = (int32_t)*srx + ( ( ( (int32_t)*srx - (int32_t)((Tmp1+halfscale) >> scalebits) ) * amount ) >> 16 );
-                *dsx = res>255 ? 255 : res<0 ? 0 : (uint8_t)res;
-            }
-        }
-        if( y >= 0 ) {
-            dst += dstStride;
-            src += srcStride;
-        }
-    }
-}
-
-//===========================================================================//
-
-static int config( struct vf_instance *vf,
-                   int width, int height, int d_width, int d_height,
-                   unsigned int flags, unsigned int outfmt ) {
-
-    int z, stepsX, stepsY;
-    FilterParam *fp;
-    const char *effect;
-
-    // allocate buffers
-
-    fp = &vf->priv->lumaParam;
-    effect = fp->amount == 0 ? "don't touch" : fp->amount < 0 ? "blur" : "sharpen";
-    mp_msg( MSGT_VFILTER, MSGL_INFO, "unsharp: %dx%d:%0.2f (%s luma) \n", fp->msizeX, fp->msizeY, fp->amount, effect );
-    memset( fp->SC, 0, sizeof( fp->SC ) );
-    stepsX = fp->msizeX/2;
-    stepsY = fp->msizeY/2;
-    for( z=0; z<2*stepsY; z++ )
-        fp->SC[z] = av_malloc(sizeof(*(fp->SC[z])) * (width+2*stepsX));
-
-    fp = &vf->priv->chromaParam;
-    effect = fp->amount == 0 ? "don't touch" : fp->amount < 0 ? "blur" : "sharpen";
-    mp_msg( MSGT_VFILTER, MSGL_INFO, "unsharp: %dx%d:%0.2f (%s chroma)\n", fp->msizeX, fp->msizeY, fp->amount, effect );
-    memset( fp->SC, 0, sizeof( fp->SC ) );
-    stepsX = fp->msizeX/2;
-    stepsY = fp->msizeY/2;
-    for( z=0; z<2*stepsY; z++ )
-        fp->SC[z] = av_malloc(sizeof(*(fp->SC[z])) * (width+2*stepsX));
-
-    return 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
-    if( mpi->imgfmt!=vf->priv->outfmt )
-        return; // colorspace differ
-
-    vf->dmpi = vf_get_image( vf->next, mpi->imgfmt, mpi->type, mpi->flags, mpi->w, mpi->h );
-    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:
-        vf->dmpi = vf_get_image( vf->next,vf->priv->outfmt, MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, mpi->w, mpi->h);
-    dmpi= vf->dmpi;
-
-    unsharp( dmpi->planes[0], mpi->planes[0], dmpi->stride[0], mpi->stride[0], mpi->w,   mpi->h,   &vf->priv->lumaParam );
-    unsharp( dmpi->planes[1], mpi->planes[1], dmpi->stride[1], mpi->stride[1], mpi->w/2, mpi->h/2, &vf->priv->chromaParam );
-    unsharp( dmpi->planes[2], mpi->planes[2], dmpi->stride[2], mpi->stride[2], mpi->w/2, mpi->h/2, &vf->priv->chromaParam );
-
-    vf_clone_mpi_attributes(dmpi, mpi);
-
-#if HAVE_MMX
-    if(gCpuCaps.hasMMX)
-        __asm__ volatile ("emms\n\t");
-#endif
-#if HAVE_MMX2
-    if(gCpuCaps.hasMMX2)
-        __asm__ volatile ("sfence\n\t");
-#endif
-
-    return vf_next_put_image( vf, dmpi, pts);
-}
-
-static void uninit( struct vf_instance *vf ) {
-    unsigned int z;
-    FilterParam *fp;
-
-    if( !vf->priv ) return;
-
-    fp = &vf->priv->lumaParam;
-    for( z=0; z<sizeof(fp->SC)/sizeof(fp->SC[0]); z++ ) {
-        av_free( fp->SC[z] );
-        fp->SC[z] = NULL;
-    }
-    fp = &vf->priv->chromaParam;
-    for( z=0; z<sizeof(fp->SC)/sizeof(fp->SC[0]); z++ ) {
-        av_free( fp->SC[z] );
-        fp->SC[z] = NULL;
-    }
-
-    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:
-        return vf_next_query_format( vf, vf->priv->outfmt );
-    }
-    return 0;
-}
-
-//===========================================================================//
-
-static void parse( FilterParam *fp, char* args ) {
-
-    // l7x5:0.8:c3x3:-0.2
-
-    char *z;
-    char *pos = args;
-    char *max = args + strlen(args);
-
-    // parse matrix sizes
-    fp->msizeX = ( pos && pos+1<max ) ? atoi( pos+1 ) : 0;
-    z = strchr( pos+1, 'x' );
-    fp->msizeY = ( z && z+1<max ) ? atoi( pos=z+1 ) : fp->msizeX;
-
-    // min/max & odd
-    fp->msizeX = 1 | av_clip(fp->msizeX, MIN_MATRIX_SIZE, MAX_MATRIX_SIZE);
-    fp->msizeY = 1 | av_clip(fp->msizeY, MIN_MATRIX_SIZE, MAX_MATRIX_SIZE);
-
-    // parse amount
-    pos = strchr( pos+1, ':' );
-    fp->amount = ( pos && pos+1<max ) ? atof( pos+1 ) : 0;
-}
-
-//===========================================================================//
-
-static const unsigned int fmt_list[] = {
-    IMGFMT_YV12,
-    IMGFMT_I420,
-    IMGFMT_IYUV,
-    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) );
-
-    if( args ) {
-        char *args2 = strchr( args, 'l' );
-        if( args2 )
-            parse( &vf->priv->lumaParam, args2 );
-        else {
-            vf->priv->lumaParam.amount =
-            vf->priv->lumaParam.msizeX =
-            vf->priv->lumaParam.msizeY = 0;
-        }
-
-        args2 = strchr( args, 'c' );
-        if( args2 )
-            parse( &vf->priv->chromaParam, args2 );
-        else {
-            vf->priv->chromaParam.amount =
-            vf->priv->chromaParam.msizeX =
-            vf->priv->chromaParam.msizeY = 0;
-        }
-
-        if( !vf->priv->lumaParam.msizeX && !vf->priv->chromaParam.msizeX )
-            return 0; // nothing to do
-    }
-
-    // check csp:
-    vf->priv->outfmt = vf_match_csp( &vf->next, fmt_list, IMGFMT_YV12 );
-    if( !vf->priv->outfmt ) {
-        uninit( vf );
-        return 0; // no csp match :(
-    }
-
-    return 1;
-}
-
-const vf_info_t vf_info_unsharp = {
-    "unsharp mask & gaussian blur",
-    "unsharp",
-    "Remi Guyomarch",
-    "",
-    vf_open,
-    NULL
-};
-
-//===========================================================================//
diff --git a/libavfilter/libmpcodecs/vf_uspp.c b/libavfilter/libmpcodecs/vf_uspp.c
index 1c683f7..54cc0f9 100644
--- a/libavfilter/libmpcodecs/vf_uspp.c
+++ b/libavfilter/libmpcodecs/vf_uspp.c
@@ -30,12 +30,13 @@
 #include "mp_msg.h"
 #include "cpudetect.h"
 
+#include "libavutil/mem.h"
 #include "libavcodec/avcodec.h"
 
 #include "img_format.h"
 #include "mp_image.h"
 #include "vf.h"
-#include "vd_ffmpeg.h"
+#include "av_helpers.h"
 #include "libvo/fastmemcpy.h"
 
 #define XMIN(a,b) ((a) < (b) ? (a) : (b))
@@ -94,7 +95,9 @@
 { 7, 1}, {15, 1}, { 7, 9}, {15, 9}, { 7, 3}, {15, 3}, { 7,11}, {15,11},
 { 7, 5}, {15, 5}, { 7,13}, {15,13}, { 7, 7}, {15, 7}, { 7,15}, {15,15},
 
-{ 0, 0}, { 8, 0}, { 0, 8}, { 8, 8}, { 4, 4}, {12, 4}, { 4,12}, {12,12}, { 0, 4}, { 8, 4}, { 0,12}, { 8,12}, { 4, 0}, {12, 0}, { 4, 8}, {12, 8}, { 2, 2}, {10, 2}, { 2,10}, {10,10}, { 6, 6}, {14, 6}, { 6,14}, {14,14}, { 2, 6}, {10, 6}, { 2,14}, {10,14}, { 6, 2}, {14, 2}, { 6,10}, {14,10}, { 0, 2}, { 8, 2}, { 0,10}, { 8,10}, { 4, 6}, {12, 6}, { 4,14}, {12,14}, { 0, 6}, { 8, 6}, { 0,14}, { 8,14}, { 4, 2}, {12, 2}, { 4,10}, {12,10}, { 2, 0}, {10, 0}, { 2, 8}, {10, 8}, { 6, 4}, {14, 4}, { 6,12}, {14,12}, { 2, 4}, {10, 4}, { 2,12}, {10,12}, { 6, 0}, {14, 0}, { 6, 8}, {14, 8}, { 1, 1}, { 9, 1}, { 1, 9}, { 9, 9}, { 5, 5}, {13, 5}, { 5,13}, {13,13}, { 1, 5}, { 9, 5}, { 1,13}, { 9,13}, { 5, 1}, {13, 1}, { 5, 9}, {13, 9}, { 3, 3}, {11, 3}, { 3,11}, {11,11}, { 7, 7}, {15, 7}, { 7,15}, {15,15}, { 3, 7}, {11, 7}, { 3,15}, {11,15}, { 7, 3}, {15, 3}, { 7,11}, {15,11}, { 1, 3}, { 9, 3}, { 1,11}, { 9,11}, { 5, 7}, {13, 7}, { 5,15}, {13,15}, { 1, 7}, { 9, 7}, { 1,15}, { 9,15}, { 5, 3}, {13, 3}, { 5,11}, {13,11}, { 3, 1}, {11,1}, { 3, 9}, {11, 9}, { 7, 5}, {15, 5}, { 7,13}, {15,13}, { 3, 5}, {11, 5}, { 3,13}, {11,13}, { 7, 1}, {15, 1}, { 7, 9}, {15, 9}, { 0, 1}, { 8, 1}, { 0, 9}, { 8, 9}, { 4, 5}, {12, 5}, { 4,13}, {12,13}, { 0, 5}, { 8, 5}, { 0,13}, { 8,13}, { 4, 1}, {12, 1}, { 4, 9}, {12, 9}, { 2, 3}, {10, 3}, { 2,11}, {10,11}, { 6, 7}, {14, 7}, { 6,15}, {14,15}, { 2, 7}, {10, 7}, { 2,15}, {10,15}, { 6, 3}, {14, 3}, { 6,11}, {14,11}, { 0, 3}, { 8, 3}, { 0,11}, { 8,11}, { 4, 7}, {12, 7}, { 4,15}, {12,15}, { 0, 7}, { 8, 7}, { 0,15}, { 8,15}, { 4, 3}, {12, 3}, { 4,11}, {12,11}, { 2, 1}, {10, 1}, { 2, 9}, {10, 9}, { 6, 5}, {14, 5}, { 6,13}, {14,13}, { 2, 5}, {10, 5}, { 2,13}, {10,13}, { 6, 1}, {14, 1}, { 6, 9}, {14, 9}, { 1, 0}, { 9, 0}, { 1, 8}, { 9, 8}, { 5, 4}, {13, 4}, { 5,12}, {13,12}, { 1, 4}, { 9, 4}, { 1,12}, { 9,12}, { 5, 0}, {13, 0}, { 5, 8}, {13, 8}, { 3, 2}, {11, 2}, { 3,10}, {11,10}, { 7, 6}, {15, 6}, { 7,14}, {15,14}, { 3, 6}, {11, 6}, { 3,14}, {11,14}, { 7, 2}, {15, 2}, { 7,10}, {15,10}, { 1, 2}, { 9, 2}, { 1,10}, {9,10}, { 5, 6}, {13, 6}, { 5,14}, {13,14}, { 1, 6}, { 9, 6}, { 1,14}, { 9,14}, { 5, 2}, {13, 2}, { 5,10}, {13,10}, { 3, 0}, {11, 0}, { 3, 8}, {11, 8}, { 7, 4}, {15, 4}, { 7,12}, {15,12}, { 3, 4}, {11, 4}, { 3,12}, {11,12}, { 7, 0}, {15, 0}, { 7, 8}, {15, 8},
+{ 0, 0}, { 8, 0}, { 0, 8}, { 8, 8}, { 4, 4}, {12, 4}, { 4,12}, {12,12}, { 0, 4}, { 8, 4}, { 0,12}, { 8,12}, { 4, 0}, {12, 0}, { 4, 8}, {12, 8}, { 2, 2}, {10, 2}, { 2,10}, {10,10}, { 6, 6}, {14, 6}, { 6,14}, {14,14}, { 2, 6}, {10, 6}, { 2,14}, {10,14}, { 6, 2}, {14, 2}, { 6,10}, {14,10}, { 0, 2}, { 8, 2}, { 0,10}, { 8,10}, { 4, 6}, {12, 6}, { 4,14}, {12,14}, { 0, 6}, { 8, 6}, { 0,14}, { 8,14}, { 4, 2}, {12, 2}, { 4,10}, {12,10}, { 2, 0}, {10, 0}, { 2, 8}, {10, 8}, { 6, 4}, {14, 4}, { 6,12}, {14,12}, { 2, 4}, {10, 4}, { 2,12}, {10,12}, { 6, 0}, {14, 0}, { 6, 8}, {14, 8}, { 1, 1}, { 9, 1}, { 1, 9}, { 9, 9}, { 5, 5}, {13, 5}, { 5,13}, {13,13}, { 1, 5}, { 9, 5}, { 1,13}, { 9,13}, { 5, 1}, {13, 1}, { 5, 9}, {13, 9}, { 3, 3}, {11, 3}, { 3,11}, {11,11}, { 7, 7}, {15, 7}, { 7,15}, {15,15}, { 3, 7}, {11, 7}, { 3,15}, {11,15}, { 7, 3}, {15, 3}, { 7,11}, {15,11}, { 1, 3}, { 9, 3}, { 1,11}, { 9,11}, { 5, 7}, {13, 7}, { 5,15}, {13,15}, { 1, 7}, { 9, 7}, { 1,15}, { 9,15}, { 5, 3}, {13, 3}, { 5,11}, {13,11}, { 3, 1}, {11, 1}
+, { 3, 9}, {11, 9}, { 7, 5}, {15, 5}, { 7,13}, {15,13}, { 3, 5}, {11, 5}, { 3,13}, {11,13}, { 7, 1}, {15, 1}, { 7, 9}, {15, 9}, { 0, 1}, { 8, 1}, { 0, 9}, { 8, 9}, { 4, 5}, {12, 5}, { 4,13}, {12,13}, { 0, 5}, { 8, 5}, { 0,13}, { 8,13}, { 4, 1}, {12, 1}, { 4, 9}, {12, 9}, { 2, 3}, {10, 3}, { 2,11}, {10,11}, { 6, 7}, {14, 7}, { 6,15}, {14,15}, { 2, 7}, {10, 7}, { 2,15}, {10,15}, { 6, 3}, {14, 3}, { 6,11}, {14,11}, { 0, 3}, { 8, 3}, { 0,11}, { 8,11}, { 4, 7}, {12, 7}, { 4,15}, {12,15}, { 0, 7}, { 8, 7}, { 0,15}, { 8,15}, { 4, 3}, {12, 3}, { 4,11}, {12,11}, { 2, 1}, {10, 1}, { 2, 9}, {10, 9}, { 6, 5}, {14, 5}, { 6,13}, {14,13}, { 2, 5}, {10, 5}, { 2,13}, {10,13}, { 6, 1}, {14, 1}, { 6, 9}, {14, 9}, { 1, 0}, { 9, 0}, { 1, 8}, { 9, 8}, { 5, 4}, {13, 4}, { 5,12}, {13,12}, { 1, 4}, { 9, 4}, { 1,12}, { 9,12}, { 5, 0}, {13, 0}, { 5, 8}, {13, 8}, { 3, 2}, {11, 2}, { 3,10}, {11,10}, { 7, 6}, {15, 6}, { 7,14}, {15,14}, { 3, 6}, {11, 6}, { 3,14}, {11,14}, { 7, 2}, {15, 2}, { 7,10}, {15,10}, { 1, 2}, { 9, 2}, { 1,10}, { 9,
+10}, { 5, 6}, {13, 6}, { 5,14}, {13,14}, { 1, 6}, { 9, 6}, { 1,14}, { 9,14}, { 5, 2}, {13, 2}, { 5,10}, {13,10}, { 3, 0}, {11, 0}, { 3, 8}, {11, 8}, { 7, 4}, {15, 4}, { 7,12}, {15,12}, { 3, 4}, {11, 4}, { 3,12}, {11,12}, { 7, 0}, {15, 0}, { 7, 8}, {15, 8},
 };
 
 struct vf_priv_s {
@@ -201,6 +204,8 @@
 
     for(j=0; j<3; j++){
         int is_chroma= !!j;
+        if (!dst[j])
+            continue; // HACK avoid crash for Y8 colourspace
         store_slice_c(dst[j], p->temp[j], dst_stride[j], p->temp_stride[j], width>>is_chroma, height>>is_chroma, 8-p->log2_count);
     }
 }
@@ -222,9 +227,10 @@
         }
         for(i=0; i< (1<<vf->priv->log2_count); i++){
             AVCodecContext *avctx_enc;
+            AVDictionary *opts = NULL;
 
             avctx_enc=
-            vf->priv->avctx_enc[i]= avcodec_alloc_context();
+            vf->priv->avctx_enc[i]= avcodec_alloc_context3(NULL);
             avctx_enc->width = width + BLOCK;
             avctx_enc->height = height + BLOCK;
             avctx_enc->time_base= (AVRational){1,25};  // meaningless
@@ -234,7 +240,9 @@
             avctx_enc->flags = CODEC_FLAG_QSCALE | CODEC_FLAG_LOW_DELAY;
             avctx_enc->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
             avctx_enc->global_quality= 123;
-            avcodec_open(avctx_enc, enc);
+            av_dict_set(&opts, "no_bitstream", "1", 0);
+            avcodec_open2(avctx_enc, enc, &opts);
+            av_dict_free(&opts);
             assert(avctx_enc->codec);
         }
         vf->priv->frame= avcodec_alloc_frame();
@@ -243,13 +251,13 @@
         vf->priv->outbuf_size= (width + BLOCK)*(height + BLOCK)*10;
         vf->priv->outbuf= malloc(vf->priv->outbuf_size);
 
-        return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
+        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=vf_get_image(vf->next,mpi->imgfmt,
+    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];
@@ -268,11 +276,11 @@
 
     if(!(mpi->flags&MP_IMGFLAG_DIRECT)){
         // no DR, so get a new image! hope we'll get DR buffer:
-        dmpi=vf_get_image(vf->next,mpi->imgfmt,
+        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);
-        vf_clone_mpi_attributes(dmpi, mpi);
+        ff_vf_clone_mpi_attributes(dmpi, mpi);
     }else{
         dmpi=vf->dmpi;
     }
@@ -289,13 +297,13 @@
     }
 
 #if HAVE_MMX
-    if(gCpuCaps.hasMMX) __asm__ volatile ("emms\n\t");
+    if(ff_gCpuCaps.hasMMX) __asm__ volatile ("emms\n\t");
 #endif
 #if HAVE_MMX2
-    if(gCpuCaps.hasMMX2) __asm__ volatile ("sfence\n\t");
+    if(ff_gCpuCaps.hasMMX2) __asm__ volatile ("sfence\n\t");
 #endif
 
-    return vf_next_put_image(vf,dmpi, pts);
+    return ff_vf_next_put_image(vf,dmpi, pts);
 }
 
 static void uninit(struct vf_instance *vf){
@@ -324,7 +332,7 @@
         case IMGFMT_IYUV:
         case IMGFMT_Y800:
         case IMGFMT_Y8:
-            return vf_next_query_format(vf,fmt);
+            return ff_vf_next_query_format(vf,fmt);
     }
     return 0;
 }
@@ -338,7 +346,7 @@
         //FIXME we have to realloc a few things here
         return CONTROL_TRUE;
     }
-    return vf_next_control(vf,request,data);
+    return ff_vf_next_control(vf,request,data);
 }
 
 static int vf_open(vf_instance_t *vf, char *args){
@@ -354,7 +362,7 @@
     vf->priv=malloc(sizeof(struct vf_priv_s));
     memset(vf->priv, 0, sizeof(struct vf_priv_s));
 
-    init_avcodec();
+    ff_init_avcodec();
 
     vf->priv->log2_count= 4;
 
@@ -367,7 +375,7 @@
         vf->priv->qp = 0;
 
 // #if HAVE_MMX
-//     if(gCpuCaps.hasMMX){
+//     if(ff_gCpuCaps.hasMMX){
 //         store_slice= store_slice_mmx;
 //     }
 // #endif
@@ -375,7 +383,7 @@
     return 1;
 }
 
-const vf_info_t vf_info_uspp = {
+const vf_info_t ff_vf_info_uspp = {
     "ultra simple/slow postprocess",
     "uspp",
     "Michael Niedermayer",
diff --git a/libavfilter/sink_buffer.c b/libavfilter/sink_buffer.c
index 88fefba..9a99b56 100644
--- a/libavfilter/sink_buffer.c
+++ b/libavfilter/sink_buffer.c
@@ -44,15 +44,10 @@
 
 AVABufferSinkParams *av_abuffersink_params_alloc(void)
 {
-    static const int sample_fmts[] = { AV_SAMPLE_FMT_NONE };
-    static const int64_t channel_layouts[] = { -1 };
-    AVABufferSinkParams *params = av_malloc(sizeof(AVABufferSinkParams));
+    AVABufferSinkParams *params = av_mallocz(sizeof(AVABufferSinkParams));
 
     if (!params)
         return NULL;
-
-    params->sample_fmts = sample_fmts;
-    params->channel_layouts = channel_layouts;
     return params;
 }
 
@@ -66,6 +61,8 @@
     /* only used for audio */
     enum AVSampleFormat *sample_fmts;       ///< list of accepted sample formats, terminated by AV_SAMPLE_FMT_NONE
     int64_t *channel_layouts;               ///< list of accepted channel layouts, terminated by -1
+    int all_channel_counts;
+    int *sample_rates;                      ///< list of accepted sample rates, terminated by -1
 } BufferSinkContext;
 
 #define FIFO_INIT_SIZE 8
@@ -117,16 +114,14 @@
     return 0;
 }
 
-static int end_frame(AVFilterLink *inlink)
+static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *ref)
 {
     AVFilterContext *ctx = inlink->dst;
     BufferSinkContext *buf = inlink->dst->priv;
     int ret;
 
-    av_assert1(inlink->cur_buf);
-    if ((ret = add_buffer_ref(ctx, inlink->cur_buf)) < 0)
+    if ((ret = add_buffer_ref(ctx, ref)) < 0)
         return ret;
-    inlink->cur_buf = NULL;
     if (buf->warning_limit &&
         av_fifo_size(buf->fifo) / sizeof(AVFilterBufferRef *) >= buf->warning_limit) {
         av_log(ctx, AV_LOG_WARNING,
@@ -238,7 +233,7 @@
     {
         .name      = "default",
         .type      = AVMEDIA_TYPE_VIDEO,
-        .end_frame = end_frame,
+        .filter_frame = filter_frame,
         .min_perms = AV_PERM_READ | AV_PERM_PRESERVE,
     },
     { NULL },
@@ -260,7 +255,7 @@
     {
         .name      = "default",
         .type      = AVMEDIA_TYPE_VIDEO,
-        .end_frame = end_frame,
+        .filter_frame = filter_frame,
         .min_perms = AV_PERM_READ | AV_PERM_PRESERVE,
     },
     { NULL },
@@ -278,10 +273,25 @@
     .outputs       = NULL,
 };
 
-static int filter_frame(AVFilterLink *link, AVFilterBufferRef *samplesref)
+static int64_t *concat_channels_lists(const int64_t *layouts, const int *counts)
 {
-    end_frame(link);
-    return 0;
+    int nb_layouts = 0, nb_counts = 0, i;
+    int64_t *list;
+
+    if (layouts)
+        for (; layouts[nb_layouts] != -1; nb_layouts++);
+    if (counts)
+        for (; counts[nb_counts] != -1; nb_counts++);
+    if (nb_counts > INT_MAX - 1 - nb_layouts)
+        return NULL;
+    if (!(list = av_calloc(nb_layouts + nb_counts + 1, sizeof(*list))))
+        return NULL;
+    for (i = 0; i < nb_layouts; i++)
+        list[i] = layouts[i];
+    for (i = 0; i < nb_counts; i++)
+        list[nb_layouts + i] = FF_COUNT2LAYOUT(counts[i]);
+    list[nb_layouts + nb_counts] = -1;
+    return list;
 }
 
 static av_cold int asink_init(AVFilterContext *ctx, const char *args, void *opaque)
@@ -290,22 +300,29 @@
     AVABufferSinkParams *params = opaque;
 
     if (params && params->sample_fmts) {
-        buf->sample_fmts     = ff_copy_int_list  (params->sample_fmts);
+        buf->sample_fmts = ff_copy_int_list(params->sample_fmts);
         if (!buf->sample_fmts)
-            goto fail_enomem;
+            return AVERROR(ENOMEM);
     }
-    if (params && params->channel_layouts) {
-        buf->channel_layouts = ff_copy_int64_list(params->channel_layouts);
+    if (params && params->sample_rates) {
+        buf->sample_rates = ff_copy_int_list(params->sample_rates);
+        if (!buf->sample_rates)
+            return AVERROR(ENOMEM);
+    }
+    if (params && (params->channel_layouts || params->channel_counts)) {
+        if (params->all_channel_counts) {
+            av_log(ctx, AV_LOG_ERROR,
+                   "Conflicting all_channel_counts and list in parameters\n");
+            return AVERROR(EINVAL);
+        }
+        buf->channel_layouts = concat_channels_lists(params->channel_layouts,
+                                                     params->channel_counts);
         if (!buf->channel_layouts)
-            goto fail_enomem;
+            return AVERROR(ENOMEM);
     }
-    if (!common_init(ctx))
-        return 0;
-
-fail_enomem:
-    av_freep(&buf->sample_fmts);
-    av_freep(&buf->channel_layouts);
-    return AVERROR(ENOMEM);
+    if (params)
+        buf->all_channel_counts = params->all_channel_counts;
+    return common_init(ctx);
 }
 
 static av_cold void asink_uninit(AVFilterContext *ctx)
@@ -313,6 +330,7 @@
     BufferSinkContext *buf = ctx->priv;
 
     av_freep(&buf->sample_fmts);
+    av_freep(&buf->sample_rates);
     av_freep(&buf->channel_layouts);
     common_uninit(ctx);
 }
@@ -324,15 +342,24 @@
     AVFilterChannelLayouts *layouts = NULL;
 
     if (buf->sample_fmts) {
-    if (!(formats = ff_make_format_list(buf->sample_fmts)))
-        return AVERROR(ENOMEM);
-    ff_set_common_formats(ctx, formats);
+        if (!(formats = ff_make_format_list(buf->sample_fmts)))
+            return AVERROR(ENOMEM);
+        ff_set_common_formats(ctx, formats);
     }
 
-    if (buf->channel_layouts) {
-    if (!(layouts = avfilter_make_format64_list(buf->channel_layouts)))
-        return AVERROR(ENOMEM);
-    ff_set_common_channel_layouts(ctx, layouts);
+    if (buf->channel_layouts || buf->all_channel_counts) {
+            layouts = buf->all_channel_counts ? ff_all_channel_counts() :
+                      avfilter_make_format64_list(buf->channel_layouts);
+        if (!layouts)
+            return AVERROR(ENOMEM);
+        ff_set_common_channel_layouts(ctx, layouts);
+    }
+
+    if (buf->sample_rates) {
+        formats = ff_make_format_list(buf->sample_rates);
+        if (!formats)
+            return AVERROR(ENOMEM);
+        ff_set_common_samplerates(ctx, formats);
     }
 
     return 0;
diff --git a/libavfilter/src_buffer.c b/libavfilter/src_buffer.c
index acd490b..a997034 100644
--- a/libavfilter/src_buffer.c
+++ b/libavfilter/src_buffer.c
@@ -81,6 +81,8 @@
 {
     AVFilterBufferRef *samplesref;
 
+    if (!channel_layout)
+        return AVERROR(EINVAL);
     samplesref = avfilter_get_audio_buffer_ref_from_arrays(
                      data, linesize[0], AV_PERM_WRITE,
                      nb_samples,
diff --git a/libavfilter/version.h b/libavfilter/version.h
index a4a2e37..93bdf91 100644
--- a/libavfilter/version.h
+++ b/libavfilter/version.h
@@ -29,8 +29,8 @@
 #include "libavutil/avutil.h"
 
 #define LIBAVFILTER_VERSION_MAJOR  3
-#define LIBAVFILTER_VERSION_MINOR  23
-#define LIBAVFILTER_VERSION_MICRO 105
+#define LIBAVFILTER_VERSION_MINOR  41
+#define LIBAVFILTER_VERSION_MICRO 100
 
 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
                                                LIBAVFILTER_VERSION_MINOR, \
@@ -48,9 +48,6 @@
  * the public API and may change, break or disappear at any time.
  */
 
-#ifndef FF_API_OLD_ALL_FORMATS_API
-#define FF_API_OLD_ALL_FORMATS_API (LIBAVFILTER_VERSION_MAJOR < 3)
-#endif
 #ifndef FF_API_AVFILTERPAD_PUBLIC
 #define FF_API_AVFILTERPAD_PUBLIC           (LIBAVFILTER_VERSION_MAJOR < 4)
 #endif
diff --git a/libavfilter/vf_alphaextract.c b/libavfilter/vf_alphaextract.c
index 35402f6..45d3dd4 100644
--- a/libavfilter/vf_alphaextract.c
+++ b/libavfilter/vf_alphaextract.c
@@ -28,6 +28,7 @@
 #include "libavutil/pixfmt.h"
 #include "avfilter.h"
 #include "drawutils.h"
+#include "internal.h"
 #include "formats.h"
 #include "video.h"
 
@@ -40,12 +41,12 @@
 
 static int query_formats(AVFilterContext *ctx)
 {
-    enum AVPixelFormat in_fmts[] = {
+    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
     };
-    enum AVPixelFormat out_fmts[] = { AV_PIX_FMT_GRAY8, 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;
@@ -59,39 +60,47 @@
     return 0;
 }
 
-static int draw_slice(AVFilterLink *inlink, int y0, int h, int slice_dir)
+static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *cur_buf)
 {
     AlphaExtractContext *extract = inlink->dst->priv;
-    AVFilterBufferRef *cur_buf = inlink->cur_buf;
-    AVFilterBufferRef *out_buf = inlink->dst->outputs[0]->out_buf;
+    AVFilterLink *outlink = inlink->dst->outputs[0];
+    AVFilterBufferRef *out_buf =
+        ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
+    int ret;
+
+    if (!out_buf) {
+        ret = AVERROR(ENOMEM);
+        goto end;
+    }
+    avfilter_copy_buffer_ref_props(out_buf, cur_buf);
 
     if (extract->is_packed_rgb) {
         int x, y;
-        uint8_t *pin, *pout;
-        for (y = y0; y < (y0 + h); y++) {
-            pin = cur_buf->data[0] + y * cur_buf->linesize[0] + extract->rgba_map[A];
+        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 < out_buf->video->w; x++) {
-                *pout = *pin;
+            for (x = 0; x < outlink->w; x++) {
+                *pout = *pcur;
                 pout += 1;
-                pin += 4;
+                pcur += 4;
             }
         }
-    } else if (cur_buf->linesize[A] == out_buf->linesize[Y]) {
-        const int linesize = cur_buf->linesize[A];
-        memcpy(out_buf->data[Y] + y0 * linesize,
-               cur_buf->data[A] + y0 * linesize,
-               linesize * h);
     } else {
-        const int linesize = FFMIN(out_buf->linesize[Y], cur_buf->linesize[A]);
+        const int linesize = abs(FFMIN(out_buf->linesize[Y], cur_buf->linesize[A]));
         int y;
-        for (y = y0; y < (y0 + h); 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);
         }
     }
-    return ff_draw_slice(inlink->dst->outputs[0], y0, h, slice_dir);
+
+    ret = ff_filter_frame(outlink, out_buf);
+
+end:
+    avfilter_unref_buffer(cur_buf);
+    return ret;
 }
 
 static const AVFilterPad alphaextract_inputs[] = {
@@ -99,7 +108,7 @@
         .name         = "default",
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_input,
-        .draw_slice   = draw_slice,
+        .filter_frame = filter_frame,
         .min_perms    = AV_PERM_READ,
     },
     { NULL }
diff --git a/libavfilter/vf_alphamerge.c b/libavfilter/vf_alphamerge.c
index f3800db..99fd61e 100644
--- a/libavfilter/vf_alphamerge.c
+++ b/libavfilter/vf_alphamerge.c
@@ -52,12 +52,12 @@
 
 static int query_formats(AVFilterContext *ctx)
 {
-    enum AVPixelFormat main_fmts[] = {
+    static const enum AVPixelFormat main_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
     };
-    enum AVPixelFormat alpha_fmts[] = { AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE };
+    static const enum AVPixelFormat alpha_fmts[] = { AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE };
     AVFilterFormats *main_formats = ff_make_format_list(main_fmts);
     AVFilterFormats *alpha_formats = ff_make_format_list(alpha_fmts);
     ff_formats_ref(main_formats, &ctx->inputs[0]->out_formats);
diff --git a/libavfilter/vf_aspect.c b/libavfilter/vf_aspect.c
index 7869d22..8e19162 100644
--- a/libavfilter/vf_aspect.c
+++ b/libavfilter/vf_aspect.c
@@ -59,7 +59,7 @@
     aspect->class = class;
     av_opt_set_defaults(aspect);
 
-    if (sscanf(args, "%d:%d%c", &q.num, &q.den, &c) == 2) {
+    if (args && sscanf(args, "%d:%d%c", &q.num, &q.den, &c) == 2) {
         aspect->ratio_str = av_strdup(args);
         av_log(ctx, AV_LOG_WARNING,
                "num:den syntax is deprecated, please use num/den or named options instead\n");
diff --git a/libavfilter/vf_ass.c b/libavfilter/vf_ass.c
deleted file mode 100644
index 5f96202..0000000
--- a/libavfilter/vf_ass.c
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright (c) 2011 Baptiste Coudurier
- * Copyright (c) 2011 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
- * Libass subtitles burning filter.
- *
- * @see{http://www.matroska.org/technical/specs/subtitles/ssa.html}
- */
-
-#include <ass/ass.h>
-
-#include "libavutil/avstring.h"
-#include "libavutil/imgutils.h"
-#include "libavutil/opt.h"
-#include "libavutil/parseutils.h"
-#include "drawutils.h"
-#include "avfilter.h"
-#include "internal.h"
-#include "formats.h"
-#include "video.h"
-
-typedef struct {
-    const AVClass *class;
-    ASS_Library  *library;
-    ASS_Renderer *renderer;
-    ASS_Track    *track;
-    char *filename;
-    uint8_t rgba_map[4];
-    int     pix_step[4];       ///< steps per pixel for each plane of the main output
-    int original_w, original_h;
-    FFDrawContext draw;
-} AssContext;
-
-#define OFFSET(x) offsetof(AssContext, x)
-#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
-
-static const AVOption ass_options[] = {
-    {"filename",       "set the filename of the ASS file to read",                 OFFSET(filename),   AV_OPT_TYPE_STRING,     {.str = NULL},  CHAR_MIN, CHAR_MAX, FLAGS },
-    {"f",              "set the filename of the ASS file to read",                 OFFSET(filename),   AV_OPT_TYPE_STRING,     {.str = NULL},  CHAR_MIN, CHAR_MAX, FLAGS },
-    {"original_size",  "set the size of the original video (used to scale fonts)", OFFSET(original_w), AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL},  CHAR_MIN, CHAR_MAX, FLAGS },
-    {NULL},
-};
-
-AVFILTER_DEFINE_CLASS(ass);
-
-/* libass supports a log level ranging from 0 to 7 */
-static const int ass_libavfilter_log_level_map[] = {
-    AV_LOG_QUIET,               /* 0 */
-    AV_LOG_PANIC,               /* 1 */
-    AV_LOG_FATAL,               /* 2 */
-    AV_LOG_ERROR,               /* 3 */
-    AV_LOG_WARNING,             /* 4 */
-    AV_LOG_INFO,                /* 5 */
-    AV_LOG_VERBOSE,             /* 6 */
-    AV_LOG_DEBUG,               /* 7 */
-};
-
-static void ass_log(int ass_level, const char *fmt, va_list args, void *ctx)
-{
-    int level = ass_libavfilter_log_level_map[ass_level];
-
-    av_vlog(ctx, level, fmt, args);
-    av_log(ctx, level, "\n");
-}
-
-static av_cold int init(AVFilterContext *ctx, const char *args)
-{
-    AssContext *ass = ctx->priv;
-    static const char *shorthand[] = { "filename", NULL };
-    int ret;
-
-    ass->class = &ass_class;
-    av_opt_set_defaults(ass);
-
-    if ((ret = av_opt_set_from_string(ass, args, shorthand, "=", ":")) < 0)
-        return ret;
-
-    if (!ass->filename) {
-        av_log(ctx, AV_LOG_ERROR, "No filename provided!\n");
-        return AVERROR(EINVAL);
-    }
-
-    ass->library = ass_library_init();
-    if (!ass->library) {
-        av_log(ctx, AV_LOG_ERROR, "Could not initialize libass.\n");
-        return AVERROR(EINVAL);
-    }
-    ass_set_message_cb(ass->library, ass_log, ctx);
-
-    ass->renderer = ass_renderer_init(ass->library);
-    if (!ass->renderer) {
-        av_log(ctx, AV_LOG_ERROR, "Could not initialize libass renderer.\n");
-        return AVERROR(EINVAL);
-    }
-
-    ass->track = ass_read_file(ass->library, ass->filename, NULL);
-    if (!ass->track) {
-        av_log(ctx, AV_LOG_ERROR,
-               "Could not create a libass track when reading file '%s'\n",
-               ass->filename);
-        return AVERROR(EINVAL);
-    }
-
-    ass_set_fonts(ass->renderer, NULL, NULL, 1, NULL, 1);
-    return 0;
-}
-
-static av_cold void uninit(AVFilterContext *ctx)
-{
-    AssContext *ass = ctx->priv;
-
-    av_opt_free(ass);
-    if (ass->track)
-        ass_free_track(ass->track);
-    if (ass->renderer)
-        ass_renderer_done(ass->renderer);
-    if (ass->library)
-        ass_library_done(ass->library);
-}
-
-static int query_formats(AVFilterContext *ctx)
-{
-    ff_set_common_formats(ctx, ff_draw_supported_pixel_formats(0));
-    return 0;
-}
-
-static int config_input(AVFilterLink *inlink)
-{
-    AssContext *ass = inlink->dst->priv;
-
-    ff_draw_init(&ass->draw, inlink->format, 0);
-
-    ass_set_frame_size  (ass->renderer, inlink->w, inlink->h);
-    if (ass->original_w && ass->original_h)
-        ass_set_aspect_ratio(ass->renderer, (double)inlink->w / inlink->h,
-                             (double)ass->original_w / ass->original_h);
-
-    return 0;
-}
-
-/* libass stores an RGBA color in the format RRGGBBTT, where TT is the transparency level */
-#define AR(c)  ( (c)>>24)
-#define AG(c)  (((c)>>16)&0xFF)
-#define AB(c)  (((c)>>8) &0xFF)
-#define AA(c)  ((0xFF-c) &0xFF)
-
-static void overlay_ass_image(AssContext *ass, AVFilterBufferRef *picref,
-                              const ASS_Image *image)
-{
-    for (; image; image = image->next) {
-        uint8_t rgba_color[] = {AR(image->color), AG(image->color), AB(image->color), AA(image->color)};
-        FFDrawColor color;
-        ff_draw_color(&ass->draw, &color, rgba_color);
-        ff_blend_mask(&ass->draw, &color,
-                      picref->data, picref->linesize,
-                      picref->video->w, picref->video->h,
-                      image->bitmap, image->stride, image->w, image->h,
-                      3, 0, image->dst_x, image->dst_y);
-    }
-}
-
-static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
-{
-    AVFilterContext *ctx = inlink->dst;
-    AVFilterLink *outlink = ctx->outputs[0];
-    AssContext *ass = ctx->priv;
-    int detect_change = 0;
-    double time_ms = picref->pts * av_q2d(inlink->time_base) * 1000;
-    ASS_Image *image = ass_render_frame(ass->renderer, ass->track,
-                                        time_ms, &detect_change);
-
-    if (detect_change)
-        av_log(ctx, AV_LOG_DEBUG, "Change happened at time ms:%f\n", time_ms);
-
-    overlay_ass_image(ass, picref, image);
-
-    return ff_filter_frame(outlink, picref);
-}
-
-static const AVFilterPad ass_inputs[] = {
-    {
-        .name             = "default",
-        .type             = AVMEDIA_TYPE_VIDEO,
-        .filter_frame     = filter_frame,
-        .config_props     = config_input,
-        .min_perms        = AV_PERM_READ | AV_PERM_WRITE,
-    },
-    { NULL }
-};
-
-static const AVFilterPad ass_outputs[] = {
-    {
-        .name = "default",
-        .type = AVMEDIA_TYPE_VIDEO,
-    },
-    { NULL }
-};
-
-AVFilter avfilter_vf_ass = {
-    .name          = "ass",
-    .description   = NULL_IF_CONFIG_SMALL("Render subtitles onto input video using the libass library."),
-    .priv_size     = sizeof(AssContext),
-    .init          = init,
-    .uninit        = uninit,
-    .query_formats = query_formats,
-    .inputs        = ass_inputs,
-    .outputs       = ass_outputs,
-    .priv_class    = &ass_class,
-};
diff --git a/libavfilter/vf_blend.c b/libavfilter/vf_blend.c
new file mode 100644
index 0000000..27d94b4
--- /dev/null
+++ b/libavfilter/vf_blend.c
@@ -0,0 +1,474 @@
+/*
+ * 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/imgutils.h"
+#include "libavutil/eval.h"
+#include "libavutil/opt.h"
+#include "libavutil/pixfmt.h"
+#include "avfilter.h"
+#include "bufferqueue.h"
+#include "formats.h"
+#include "internal.h"
+#include "video.h"
+
+#define TOP    0
+#define BOTTOM 1
+
+enum BlendMode {
+    BLEND_UNSET = -1,
+    BLEND_NORMAL,
+    BLEND_ADDITION,
+    BLEND_AND,
+    BLEND_AVERAGE,
+    BLEND_BURN,
+    BLEND_DARKEN,
+    BLEND_DIFFERENCE,
+    BLEND_DIVIDE,
+    BLEND_DODGE,
+    BLEND_EXCLUSION,
+    BLEND_HARDLIGHT,
+    BLEND_LIGHTEN,
+    BLEND_MULTIPLY,
+    BLEND_NEGATION,
+    BLEND_OR,
+    BLEND_OVERLAY,
+    BLEND_PHOENIX,
+    BLEND_PINLIGHT,
+    BLEND_REFLECT,
+    BLEND_SCREEN,
+    BLEND_SOFTLIGHT,
+    BLEND_SUBTRACT,
+    BLEND_VIVIDLIGHT,
+    BLEND_XOR,
+    BLEND_NB
+};
+
+static const char *const var_names[] = {   "X",   "Y",   "W",   "H",   "SW",   "SH",   "T",     "A",        "B",   "TOP",   "BOTTOM",        NULL };
+enum                                   { VAR_X, VAR_Y, VAR_W, VAR_H, VAR_SW, VAR_SH, VAR_T,   VAR_A,      VAR_B, VAR_TOP, VAR_BOTTOM, VAR_VARS_NB };
+
+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);
+} FilterParams;
+
+typedef struct {
+    const AVClass *class;
+    struct FFBufQueue queue_top;
+    struct FFBufQueue queue_bottom;
+    int hsub, vsub;             ///< chroma subsampling values
+    int frame_requested;
+    char *all_expr;
+    enum BlendMode all_mode;
+    double all_opacity;
+
+    FilterParams params[4];
+} BlendContext;
+
+#define OFFSET(x) offsetof(BlendContext, x)
+#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
+
+static const AVOption blend_options[] = {
+    { "c0_mode", "set component #0 blend mode", OFFSET(params[0].mode), AV_OPT_TYPE_INT, {.i64=0}, 0, BLEND_NB-1, FLAGS, "mode"},
+    { "c1_mode", "set component #1 blend mode", OFFSET(params[1].mode), AV_OPT_TYPE_INT, {.i64=0}, 0, BLEND_NB-1, FLAGS, "mode"},
+    { "c2_mode", "set component #2 blend mode", OFFSET(params[2].mode), AV_OPT_TYPE_INT, {.i64=0}, 0, BLEND_NB-1, FLAGS, "mode"},
+    { "c3_mode", "set component #3 blend mode", OFFSET(params[3].mode), AV_OPT_TYPE_INT, {.i64=0}, 0, BLEND_NB-1, FLAGS, "mode"},
+    { "all_mode", "set blend mode for all components", OFFSET(all_mode), AV_OPT_TYPE_INT, {.i64=-1},-1, BLEND_NB-1, FLAGS, "mode"},
+    { "addition",   "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_ADDITION},   0, 0, FLAGS, "mode" },
+    { "and",        "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_AND},        0, 0, FLAGS, "mode" },
+    { "average",    "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_AVERAGE},    0, 0, FLAGS, "mode" },
+    { "burn",       "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_BURN},       0, 0, FLAGS, "mode" },
+    { "darken",     "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_DARKEN},     0, 0, FLAGS, "mode" },
+    { "difference", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_DIFFERENCE}, 0, 0, FLAGS, "mode" },
+    { "divide",     "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_DIVIDE},     0, 0, FLAGS, "mode" },
+    { "dodge",      "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_DODGE},      0, 0, FLAGS, "mode" },
+    { "exclusion",  "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_EXCLUSION},  0, 0, FLAGS, "mode" },
+    { "hardlight",  "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_HARDLIGHT},  0, 0, FLAGS, "mode" },
+    { "lighten",    "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_LIGHTEN},    0, 0, FLAGS, "mode" },
+    { "multiply",   "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_MULTIPLY},   0, 0, FLAGS, "mode" },
+    { "negation",   "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_NEGATION},   0, 0, FLAGS, "mode" },
+    { "normal",     "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_NORMAL},     0, 0, FLAGS, "mode" },
+    { "or",         "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_OR},         0, 0, FLAGS, "mode" },
+    { "overlay",    "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_OVERLAY},    0, 0, FLAGS, "mode" },
+    { "phoenix",    "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_PHOENIX},    0, 0, FLAGS, "mode" },
+    { "pinlight",   "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_PINLIGHT},   0, 0, FLAGS, "mode" },
+    { "reflect",    "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_REFLECT},    0, 0, FLAGS, "mode" },
+    { "screen",     "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_SCREEN},     0, 0, FLAGS, "mode" },
+    { "softlight",  "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_SOFTLIGHT},  0, 0, FLAGS, "mode" },
+    { "subtract",   "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_SUBTRACT},   0, 0, FLAGS, "mode" },
+    { "vividlight", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_VIVIDLIGHT}, 0, 0, FLAGS, "mode" },
+    { "xor",        "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_XOR},        0, 0, FLAGS, "mode" },
+    { "c0_expr",  "set color component #0 expression", OFFSET(params[0].expr_str), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "c1_expr",  "set color component #1 expression", OFFSET(params[1].expr_str), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "c2_expr",  "set color component #2 expression", OFFSET(params[2].expr_str), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "c3_expr",  "set color component #3 expression", OFFSET(params[3].expr_str), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "all_expr", "set expression for all color components", OFFSET(all_expr), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "c0_opacity",  "set color component #0 opacity", OFFSET(params[0].opacity), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS },
+    { "c1_opacity",  "set color component #1 opacity", OFFSET(params[1].opacity), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS },
+    { "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},
+    { NULL },
+};
+
+AVFILTER_DEFINE_CLASS(blend);
+
+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)
+{
+    av_image_copy_plane(dst, dst_linesize, top, top_linesize, width, height);
+}
+
+#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) \
+{                                                                     \
+    double opacity = param->opacity;                                  \
+    int i, j;                                                         \
+                                                                      \
+    for (i = 0; i < height; i++) {                                    \
+        for (j = 0; j < width; j++) {                                 \
+            dst[j] = top[j] + ((expr) - top[j]) * opacity;            \
+        }                                                             \
+        dst    += dst_linesize;                                       \
+        top    += top_linesize;                                       \
+        bottom += bottom_linesize;                                    \
+    }                                                                 \
+}
+
+#define A top[j]
+#define B bottom[j]
+
+#define MULTIPLY(x, a, b) (x * ((a * b) / 255))
+#define SCREEN(x, a, b)   (255 - x * ((255 - a) * (255 - b) / 255))
+#define BURN(a, b)        ((a == 0) ? a : FFMAX(0, 255 - ((255 - b) << 8) / a))
+#define DODGE(a, b)       ((a == 255) ? a : FFMIN(255, ((b << 8) / (255 - a))))
+
+DEFINE_BLEND(addition,   FFMIN(255, A + B))
+DEFINE_BLEND(average,    (A + B) / 2)
+DEFINE_BLEND(subtract,   FFMAX(0, A - B))
+DEFINE_BLEND(multiply,   MULTIPLY(1, A, B))
+DEFINE_BLEND(negation,   255 - FFABS(255 - A - B))
+DEFINE_BLEND(difference, FFABS(A - B))
+DEFINE_BLEND(screen,     SCREEN(1, A, B))
+DEFINE_BLEND(overlay,    (A < 128) ? MULTIPLY(2, A, B) : SCREEN(2, A, B))
+DEFINE_BLEND(hardlight,  (B < 128) ? MULTIPLY(2, B, A) : SCREEN(2, B, A))
+DEFINE_BLEND(darken,     FFMIN(A, B))
+DEFINE_BLEND(lighten,    FFMAX(A, B))
+DEFINE_BLEND(divide,     ((float)A / ((float)B) * 255))
+DEFINE_BLEND(dodge,      DODGE(A, B))
+DEFINE_BLEND(burn,       BURN(A, B))
+DEFINE_BLEND(softlight,  (A > 127) ? B + (255 - B) * (A - 127.5) / 127.5 * (0.5 - FFABS(B - 127.5) / 255): B - B * ((127.5 - A) / 127.5) * (0.5 - FFABS(B - 127.5)/255))
+DEFINE_BLEND(exclusion,  A + B - 2 * A * B / 255)
+DEFINE_BLEND(pinlight,   (B < 128) ? FFMIN(A, 2 * B) : FFMAX(A, 2 * (B - 128)))
+DEFINE_BLEND(phoenix,    FFMIN(A, B) - FFMAX(A, B) + 255)
+DEFINE_BLEND(reflect,    (B == 255) ? B : FFMIN(255, (A * A / (255 - B))))
+DEFINE_BLEND(and,        A & B)
+DEFINE_BLEND(or,         A | B)
+DEFINE_BLEND(xor,        A ^ B)
+DEFINE_BLEND(vividlight, (B < 128) ? BURN(A, 2 * B) : DODGE(A, 2 * (B - 128)))
+
+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)
+{
+    AVExpr *e = param->e;
+    double *values = param->values;
+    int y, x;
+
+    for (y = 0; y < height; y++) {
+        values[VAR_Y] = y;
+        for (x = 0; x < width; x++) {
+            values[VAR_X]      = x;
+            values[VAR_TOP]    = values[VAR_A] = top[x];
+            values[VAR_BOTTOM] = values[VAR_B] = bottom[x];
+            dst[x] = av_expr_eval(e, values, NULL);
+        }
+        dst    += dst_linesize;
+        top    += top_linesize;
+        bottom += bottom_linesize;
+    }
+}
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    BlendContext *b = ctx->priv;
+    int ret, plane;
+
+    b->class = &blend_class;
+    av_opt_set_defaults(b);
+
+    if ((ret = av_set_options_string(b, args, "=", ":")) < 0)
+        return ret;
+
+    for (plane = 0; plane < FF_ARRAY_ELEMS(b->params); plane++) {
+        FilterParams *param = &b->params[plane];
+
+        if (b->all_mode >= 0)
+            param->mode = b->all_mode;
+        if (b->all_opacity < 1)
+            param->opacity = b->all_opacity;
+
+        switch (param->mode) {
+        case BLEND_ADDITION:   param->blend = blend_addition;   break;
+        case BLEND_AND:        param->blend = blend_and;        break;
+        case BLEND_AVERAGE:    param->blend = blend_average;    break;
+        case BLEND_BURN:       param->blend = blend_burn;       break;
+        case BLEND_DARKEN:     param->blend = blend_darken;     break;
+        case BLEND_DIFFERENCE: param->blend = blend_difference; break;
+        case BLEND_DIVIDE:     param->blend = blend_divide;     break;
+        case BLEND_DODGE:      param->blend = blend_dodge;      break;
+        case BLEND_EXCLUSION:  param->blend = blend_exclusion;  break;
+        case BLEND_HARDLIGHT:  param->blend = blend_hardlight;  break;
+        case BLEND_LIGHTEN:    param->blend = blend_lighten;    break;
+        case BLEND_MULTIPLY:   param->blend = blend_multiply;   break;
+        case BLEND_NEGATION:   param->blend = blend_negation;   break;
+        case BLEND_NORMAL:     param->blend = blend_normal;     break;
+        case BLEND_OR:         param->blend = blend_or;         break;
+        case BLEND_OVERLAY:    param->blend = blend_overlay;    break;
+        case BLEND_PHOENIX:    param->blend = blend_phoenix;    break;
+        case BLEND_PINLIGHT:   param->blend = blend_pinlight;   break;
+        case BLEND_REFLECT:    param->blend = blend_reflect;    break;
+        case BLEND_SCREEN:     param->blend = blend_screen;     break;
+        case BLEND_SOFTLIGHT:  param->blend = blend_softlight;  break;
+        case BLEND_SUBTRACT:   param->blend = blend_subtract;   break;
+        case BLEND_VIVIDLIGHT: param->blend = blend_vividlight; break;
+        case BLEND_XOR:        param->blend = blend_xor;        break;
+        }
+
+        if (b->all_expr && !param->expr_str) {
+            param->expr_str = av_strdup(b->all_expr);
+            if (!param->expr_str)
+                return AVERROR(ENOMEM);
+        }
+        if (param->expr_str) {
+            ret = av_expr_parse(&param->e, param->expr_str, var_names,
+                                NULL, NULL, NULL, NULL, 0, ctx);
+            if (ret < 0)
+                return ret;
+            param->blend = blend_expr;
+        }
+    }
+
+    return 0;
+}
+
+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_YUV444P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P,
+        AV_PIX_FMT_GBRP, AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE
+    };
+
+    ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
+    return 0;
+}
+
+static int config_output(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx = outlink->src;
+    AVFilterLink *toplink = ctx->inputs[TOP];
+    AVFilterLink *bottomlink = ctx->inputs[BOTTOM];
+
+    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 ||
+        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 "
+               "(size %dx%d, SAR %d:%d) do not match the corresponding "
+               "second input link %s parameters (%dx%d, SAR %d:%d)\n",
+               ctx->input_pads[TOP].name, toplink->w, toplink->h,
+               toplink->sample_aspect_ratio.num,
+               toplink->sample_aspect_ratio.den,
+               ctx->input_pads[BOTTOM].name, bottomlink->w, bottomlink->h,
+               bottomlink->sample_aspect_ratio.num,
+               bottomlink->sample_aspect_ratio.den);
+        return AVERROR(EINVAL);
+    }
+
+    outlink->w = toplink->w;
+    outlink->h = bottomlink->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;
+    return 0;
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    BlendContext *b = ctx->priv;
+    int i;
+
+    av_opt_free(b);
+    ff_bufqueue_discard_all(&b->queue_top);
+    ff_bufqueue_discard_all(&b->queue_bottom);
+
+    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, TOP) ? BOTTOM : TOP;
+        ret = ff_request_frame(ctx->inputs[in]);
+        if (ret < 0)
+            return ret;
+    }
+    return 0;
+}
+
+static void blend_frame(AVFilterContext *ctx,
+                        AVFilterBufferRef *top_buf,
+                        AVFilterBufferRef *bottom_buf,
+                        AVFilterBufferRef *dst_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->video->w >> hsub;
+        int outh = dst_buf->video->h >> 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_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->video->w;
+        param->values[VAR_SH] = outh / dst_buf->video->h;
+        param->blend(top, top_buf->linesize[plane],
+                     bottom, bottom_buf->linesize[plane],
+                     dst, dst_buf->linesize[plane], outw, outh, param);
+    }
+}
+
+static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *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) {
+        AVFilterBufferRef *top_buf, *bottom_buf, *out_buf;
+
+        if (!ff_bufqueue_peek(&b->queue_top, TOP) ||
+            !ff_bufqueue_peek(&b->queue_bottom, BOTTOM)) break;
+
+        top_buf = ff_bufqueue_get(&b->queue_top);
+        bottom_buf = ff_bufqueue_get(&b->queue_bottom);
+
+        out_buf = ff_get_video_buffer(outlink, AV_PERM_WRITE,
+                                      outlink->w, outlink->h);
+        if (!out_buf) {
+            return AVERROR(ENOMEM);
+        }
+        avfilter_copy_buffer_ref_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);
+        avfilter_unref_buffer(top_buf);
+        avfilter_unref_buffer(bottom_buf);
+    }
+    return ret;
+}
+
+static const AVFilterPad blend_inputs[] = {
+    {
+        .name             = "top",
+        .type             = AVMEDIA_TYPE_VIDEO,
+        .config_props     = config_input_top,
+        .filter_frame     = filter_frame,
+        .min_perms        = AV_PERM_READ | AV_PERM_PRESERVE,
+    },{
+        .name             = "bottom",
+        .type             = AVMEDIA_TYPE_VIDEO,
+        .filter_frame     = filter_frame,
+        .min_perms        = AV_PERM_READ | AV_PERM_PRESERVE,
+    },
+    { NULL }
+};
+
+static const AVFilterPad blend_outputs[] = {
+    {
+        .name          = "default",
+        .type          = AVMEDIA_TYPE_VIDEO,
+        .config_props  = config_output,
+        .request_frame = request_frame,
+    },
+    { NULL }
+};
+
+AVFilter avfilter_vf_blend = {
+    .name          = "blend",
+    .description   = NULL_IF_CONFIG_SMALL("Blend two video frames into each other."),
+    .init          = init,
+    .uninit        = uninit,
+    .priv_size     = sizeof(BlendContext),
+    .query_formats = query_formats,
+    .inputs        = blend_inputs,
+    .outputs       = blend_outputs,
+    .priv_class    = &blend_class,
+};
diff --git a/libavfilter/vf_boxblur.c b/libavfilter/vf_boxblur.c
index df250c8..a4ac50a 100644
--- a/libavfilter/vf_boxblur.c
+++ b/libavfilter/vf_boxblur.c
@@ -28,6 +28,7 @@
 #include "libavutil/avstring.h"
 #include "libavutil/common.h"
 #include "libavutil/eval.h"
+#include "libavutil/opt.h"
 #include "libavutil/pixdesc.h"
 #include "avfilter.h"
 #include "formats.h"
@@ -57,15 +58,14 @@
 typedef struct {
     int radius;
     int power;
+    char *radius_expr;
 } FilterParam;
 
 typedef struct {
+    const AVClass *class;
     FilterParam luma_param;
     FilterParam chroma_param;
     FilterParam alpha_param;
-    char luma_radius_expr  [256];
-    char chroma_radius_expr[256];
-    char alpha_radius_expr [256];
 
     int hsub, vsub;
     int radius[4];
@@ -73,6 +73,30 @@
     uint8_t *temp[2]; ///< temporary buffer used in blur_power()
 } BoxBlurContext;
 
+#define OFFSET(x) offsetof(BoxBlurContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
+
+static const AVOption boxblur_options[] = {
+    { "luma_radius", "set luma radius", OFFSET(luma_param.radius_expr), AV_OPT_TYPE_STRING, {.str="2"}, .flags = FLAGS },
+    { "lr",          "set luma radius", OFFSET(luma_param.radius_expr), AV_OPT_TYPE_STRING, {.str="2"}, .flags = FLAGS },
+    { "luma_power",  "set luma power",  OFFSET(luma_param.power), AV_OPT_TYPE_INT, {.i64=2}, 0, INT_MAX, .flags = FLAGS },
+    { "lp",          "set luma power",  OFFSET(luma_param.power), AV_OPT_TYPE_INT, {.i64=2}, 0, INT_MAX, .flags = FLAGS },
+
+    { "chroma_radius", "set chroma radius", OFFSET(chroma_param.radius_expr), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
+    { "cr",            "set chroma radius", OFFSET(chroma_param.radius_expr), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
+    { "chroma_power",  "set chroma power",  OFFSET(chroma_param.power), AV_OPT_TYPE_INT, {.i64=-1}, -1, INT_MAX, .flags = FLAGS },
+    { "cp",            "set chroma power",  OFFSET(chroma_param.power), AV_OPT_TYPE_INT, {.i64=-1}, -1, INT_MAX, .flags = FLAGS },
+
+    { "alpha_radius", "set alpha radius", OFFSET(alpha_param.radius_expr), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
+    { "ar",           "set alpha radius", OFFSET(alpha_param.radius_expr), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
+    { "alpha_power",  "set alpha power",  OFFSET(alpha_param.power), AV_OPT_TYPE_INT, {.i64=-1}, -1, INT_MAX, .flags = FLAGS },
+    { "ap",           "set alpha power",  OFFSET(alpha_param.power), AV_OPT_TYPE_INT, {.i64=-1}, -1, INT_MAX, .flags = FLAGS },
+
+    { NULL }
+};
+
+AVFILTER_DEFINE_CLASS(boxblur);
+
 #define Y 0
 #define U 1
 #define V 2
@@ -81,35 +105,36 @@
 static av_cold int init(AVFilterContext *ctx, const char *args)
 {
     BoxBlurContext *boxblur = ctx->priv;
-    int e;
+    static const char *shorthand[] = {
+        "luma_radius",   "luma_power",
+        "chroma_radius", "chroma_power",
+        "alpha_radius",  "alpha_power",
+        NULL
+    };
+    int ret;
 
-    if (!args) {
-        av_log(ctx, AV_LOG_ERROR,
-               "Filter expects 2 or 4 or 6 arguments, none provided\n");
-        return AVERROR(EINVAL);
+    boxblur->class = &boxblur_class;
+    av_opt_set_defaults(boxblur);
+
+    if ((ret = av_opt_set_from_string(boxblur, args, shorthand, "=", ":")) < 0)
+        return ret;
+
+    /* 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)
+            return AVERROR(ENOMEM);
     }
-
-    e = sscanf(args, "%255[^:]:%d:%255[^:]:%d:%255[^:]:%d",
-               boxblur->luma_radius_expr,   &boxblur->luma_param  .power,
-               boxblur->chroma_radius_expr, &boxblur->chroma_param.power,
-               boxblur->alpha_radius_expr,  &boxblur->alpha_param .power);
-
-    if (e != 2 && e != 4 && e != 6) {
-        av_log(ctx, AV_LOG_ERROR,
-               "Filter expects 2 or 4 or 6 params, provided %d\n", e);
-        return AVERROR(EINVAL);
-    }
-
-    if (e < 4) {
+    if (boxblur->chroma_param.power < 0)
         boxblur->chroma_param.power = boxblur->luma_param.power;
-        av_strlcpy(boxblur->chroma_radius_expr, boxblur->luma_radius_expr,
-                   sizeof(boxblur->chroma_radius_expr));
+
+    if (!boxblur->alpha_param.radius_expr) {
+        boxblur->alpha_param.radius_expr = av_strdup(boxblur->luma_param.radius_expr);
+        if (!boxblur->alpha_param.radius_expr)
+            return AVERROR(ENOMEM);
     }
-    if (e < 6) {
+    if (boxblur->alpha_param.power < 0)
         boxblur->alpha_param.power = boxblur->luma_param.power;
-        av_strlcpy(boxblur->alpha_radius_expr, boxblur->luma_radius_expr,
-                   sizeof(boxblur->alpha_radius_expr));
-    }
 
     return 0;
 }
@@ -120,11 +145,12 @@
 
     av_freep(&boxblur->temp[0]);
     av_freep(&boxblur->temp[1]);
+    av_opt_free(boxblur);
 }
 
 static int query_formats(AVFilterContext *ctx)
 {
-    enum AVPixelFormat pix_fmts[] = {
+    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_YUVA420P,
         AV_PIX_FMT_YUV440P,  AV_PIX_FMT_GRAY8,
@@ -163,7 +189,7 @@
     var_values[VAR_VSUB]    = 1<<boxblur->vsub;
 
 #define EVAL_RADIUS_EXPR(comp)                                          \
-    expr = boxblur->comp##_radius_expr;                                 \
+    expr = boxblur->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;                                 \
@@ -366,4 +392,6 @@
 
     .inputs    = avfilter_vf_boxblur_inputs,
     .outputs   = avfilter_vf_boxblur_outputs,
+
+    .priv_class = &boxblur_class,
 };
diff --git a/libavfilter/vf_crop.c b/libavfilter/vf_crop.c
index d0f464f..8df9595 100644
--- a/libavfilter/vf_crop.c
+++ b/libavfilter/vf_crop.c
@@ -37,6 +37,7 @@
 #include "libavutil/libm.h"
 #include "libavutil/imgutils.h"
 #include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
 
 static const char *const var_names[] = {
     "in_w", "iw",   ///< width  of the input video
@@ -75,6 +76,7 @@
 };
 
 typedef struct {
+    const AVClass *class;
     int  x;             ///< x offset of the non-cropped area with respect to the input area
     int  y;             ///< y offset of the non-cropped area with respect to the input area
     int  w;             ///< width of the cropped area
@@ -85,11 +87,47 @@
 
     int max_step[4];    ///< max pixel step for each plane, expressed as a number of bytes
     int hsub, vsub;     ///< chroma subsampling
-    char x_expr[256], y_expr[256], ow_expr[256], oh_expr[256];
+    char *x_expr, *y_expr, *w_expr, *h_expr;
     AVExpr *x_pexpr, *y_pexpr;  /* parsed expressions for x and y */
     double var_values[VAR_VARS_NB];
 } CropContext;
 
+#define OFFSET(x) offsetof(CropContext, x)
+#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
+
+static const AVOption crop_options[] = {
+    { "x",           "set the x crop area expression",       OFFSET(x_expr), AV_OPT_TYPE_STRING, {.str = "(in_w-out_w)/2"}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "y",           "set the y crop area expression",       OFFSET(y_expr), AV_OPT_TYPE_STRING, {.str = "(in_h-out_h)/2"}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "out_w",       "set the width crop area expression",   OFFSET(w_expr), AV_OPT_TYPE_STRING, {.str = "iw"}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "w",           "set the width crop area expression",   OFFSET(w_expr), AV_OPT_TYPE_STRING, {.str = "iw"}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "out_h",       "set the height crop area expression",  OFFSET(h_expr), AV_OPT_TYPE_STRING, {.str = "ih"}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "h",           "set the height crop area expression",  OFFSET(h_expr), AV_OPT_TYPE_STRING, {.str = "ih"}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "keep_aspect", "keep aspect ratio",                    OFFSET(keep_aspect), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS },
+    {NULL}
+};
+
+AVFILTER_DEFINE_CLASS(crop);
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    CropContext *crop = ctx->priv;
+    static const char *shorthand[] = { "w", "h", "x", "y", "keep_aspect", NULL };
+
+    crop->class = &crop_class;
+    av_opt_set_defaults(crop);
+
+    return av_opt_set_from_string(crop, args, shorthand, "=", ":");
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    CropContext *crop = ctx->priv;
+
+    av_expr_free(crop->x_pexpr); crop->x_pexpr = NULL;
+    av_expr_free(crop->y_pexpr); crop->y_pexpr = NULL;
+    av_opt_free(crop);
+}
+
 static int query_formats(AVFilterContext *ctx)
 {
     static const enum AVPixelFormat pix_fmts[] = {
@@ -123,29 +161,6 @@
     return 0;
 }
 
-static av_cold int init(AVFilterContext *ctx, const char *args)
-{
-    CropContext *crop = ctx->priv;
-
-    av_strlcpy(crop->ow_expr, "iw", sizeof(crop->ow_expr));
-    av_strlcpy(crop->oh_expr, "ih", sizeof(crop->oh_expr));
-    av_strlcpy(crop->x_expr, "(in_w-out_w)/2", sizeof(crop->x_expr));
-    av_strlcpy(crop->y_expr, "(in_h-out_h)/2", sizeof(crop->y_expr));
-
-    if (args)
-        sscanf(args, "%255[^:]:%255[^:]:%255[^:]:%255[^:]:%d", crop->ow_expr, crop->oh_expr, crop->x_expr, crop->y_expr, &crop->keep_aspect);
-
-    return 0;
-}
-
-static av_cold void uninit(AVFilterContext *ctx)
-{
-    CropContext *crop = ctx->priv;
-
-    av_expr_free(crop->x_pexpr); crop->x_pexpr = NULL;
-    av_expr_free(crop->y_pexpr); crop->y_pexpr = NULL;
-}
-
 static inline int normalize_double(int *n, double d)
 {
     int ret = 0;
@@ -189,16 +204,16 @@
     crop->hsub = pix_desc->log2_chroma_w;
     crop->vsub = pix_desc->log2_chroma_h;
 
-    if ((ret = av_expr_parse_and_eval(&res, (expr = crop->ow_expr),
+    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->oh_expr),
+    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;
     /* evaluate again ow as it may depend on oh */
-    if ((ret = av_expr_parse_and_eval(&res, (expr = crop->ow_expr),
+    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;
@@ -207,7 +222,7 @@
         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->ow_expr, crop->oh_expr);
+               crop->w_expr, crop->h_expr);
         return AVERROR(EINVAL);
     }
     crop->w &= ~((1 << crop->hsub) - 1);
@@ -348,4 +363,5 @@
 
     .inputs    = avfilter_vf_crop_inputs,
     .outputs   = avfilter_vf_crop_outputs,
+    .priv_class = &crop_class,
 };
diff --git a/libavfilter/vf_decimate.c b/libavfilter/vf_decimate.c
index 267a435..c5761ad 100644
--- a/libavfilter/vf_decimate.c
+++ b/libavfilter/vf_decimate.c
@@ -24,6 +24,7 @@
  * Rich Felker.
  */
 
+#include "libavutil/opt.h"
 #include "libavutil/pixdesc.h"
 #include "libavutil/timestamp.h"
 #include "libavcodec/dsputil.h"
@@ -33,6 +34,7 @@
 #include "video.h"
 
 typedef struct {
+    const AVClass *class;
     int lo, hi;                    ///< lower and higher threshold number of differences
                                    ///< values for 8x8 blocks
 
@@ -50,6 +52,20 @@
     AVCodecContext *avctx;         ///< codec context required for the DSPContext
 } DecimateContext;
 
+#define OFFSET(x) offsetof(DecimateContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
+
+static const AVOption decimate_options[] = {
+    { "max",  "set the maximum number of consecutive dropped frames (positive), or the minimum interval between dropped frames (negative)",
+      OFFSET(max_drop_count), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGS },
+    { "hi",   "set high dropping threshold", OFFSET(hi), AV_OPT_TYPE_INT, {.i64=64*12}, INT_MIN, INT_MAX, FLAGS },
+    { "lo",   "set low dropping threshold", OFFSET(lo), AV_OPT_TYPE_INT, {.i64=64*5}, INT_MIN, INT_MAX, FLAGS },
+    { "frac", "set fraction dropping threshold",  OFFSET(frac), AV_OPT_TYPE_FLOAT, {.dbl=0.33}, 0, 1, FLAGS },
+    { NULL }
+};
+
+AVFILTER_DEFINE_CLASS(decimate);
+
 /**
  * Return 1 if the two planes are different, 0 otherwise.
  */
@@ -63,7 +79,7 @@
     int x, y;
     int d, c = 0;
     int t = (w/16)*(h/16)*decimate->frac;
-    DCTELEM block[8*8];
+    int16_t block[8*8];
 
     /* compute difference for blocks of 8x8 bytes */
     for (y = 0; y < h-7; y += 4) {
@@ -116,29 +132,14 @@
 static av_cold int init(AVFilterContext *ctx, const char *args)
 {
     DecimateContext *decimate = ctx->priv;
+    static const char *shorthand[] = { "max", "hi", "lo", "frac", NULL };
+    int ret;
 
-    /* set default values */
-    decimate->drop_count = decimate->max_drop_count = 0;
-    decimate->lo = 64*5;
-    decimate->hi = 64*12;
-    decimate->frac = 0.33;
+    decimate->class = &decimate_class;
+    av_opt_set_defaults(decimate);
 
-    if (args) {
-        char c1, c2, c3, c4;
-        int n = sscanf(args, "%d%c%d%c%d%c%f%c",
-                       &decimate->max_drop_count, &c1,
-                       &decimate->hi, &c2, &decimate->lo, &c3,
-                       &decimate->frac, &c4);
-        if (n != 1 &&
-            (n != 3 || c1 != ':') &&
-            (n != 5 || c1 != ':' || c2 != ':') &&
-            (n != 7 || c1 != ':' || c2 != ':' || c3 != ':')) {
-            av_log(ctx, AV_LOG_ERROR,
-                   "Invalid syntax for argument '%s': "
-                   "must be in the form 'max:hi:lo:frac'\n", args);
-            return AVERROR(EINVAL);
-        }
-    }
+    if ((ret = av_opt_set_from_string(decimate, args, shorthand, "=", ":")) < 0)
+        return ret;
 
     av_log(ctx, AV_LOG_VERBOSE, "max_drop_count:%d hi:%d lo:%d frac:%f\n",
            decimate->max_drop_count, decimate->hi, decimate->lo, decimate->frac);
@@ -156,6 +157,7 @@
     DecimateContext *decimate = ctx->priv;
     avfilter_unref_bufferp(&decimate->ref);
     avcodec_close(decimate->avctx);
+    av_opt_free(decimate);
     av_freep(&decimate->avctx);
 }
 
@@ -198,7 +200,6 @@
     } else {
         avfilter_unref_buffer(decimate->ref);
         decimate->ref = cur;
-        inlink->cur_buf = NULL;
         decimate->drop_count = FFMIN(-1, decimate->drop_count-1);
 
         if (ret = ff_filter_frame(outlink, avfilter_ref_buffer(cur, ~AV_PERM_WRITE)) < 0)
@@ -261,4 +262,5 @@
     .query_formats = query_formats,
     .inputs        = decimate_inputs,
     .outputs       = decimate_outputs,
+    .priv_class    = &decimate_class,
 };
diff --git a/libavfilter/vf_delogo.c b/libavfilter/vf_delogo.c
index 3c9843f..bf0ac62 100644
--- a/libavfilter/vf_delogo.c
+++ b/libavfilter/vf_delogo.c
@@ -83,8 +83,8 @@
     if (!direct)
         av_image_copy_plane(dst, dst_linesize, src, src_linesize, w, h);
 
-    dst += (logo_y1+1)*dst_linesize;
-    src += (logo_y1+1)*src_linesize;
+    dst += (logo_y1 + 1) * dst_linesize;
+    src += (logo_y1 + 1) * src_linesize;
 
     for (y = logo_y1+1; y < logo_y2-1; y++) {
         for (x = logo_x1+1,
@@ -157,7 +157,7 @@
 
 static int query_formats(AVFilterContext *ctx)
 {
-    enum AVPixelFormat pix_fmts[] = {
+    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_YUVA420P, AV_PIX_FMT_GRAY8,
@@ -229,11 +229,7 @@
             avfilter_unref_bufferp(&in);
             return AVERROR(ENOMEM);
         }
-
         avfilter_copy_buffer_ref_props(out, in);
-
-        out->video->w = outlink->w;
-        out->video->h = outlink->h;
     }
 
     for (plane = 0; plane < 4 && in->data[plane]; plane++) {
diff --git a/libavfilter/vf_deshake.c b/libavfilter/vf_deshake.c
index 92fb1ea..c03919c 100644
--- a/libavfilter/vf_deshake.c
+++ b/libavfilter/vf_deshake.c
@@ -51,6 +51,7 @@
 
 #include "avfilter.h"
 #include "formats.h"
+#include "internal.h"
 #include "video.h"
 #include "libavutil/common.h"
 #include "libavutil/mem.h"
@@ -89,10 +90,10 @@
     AVFilterBufferRef *ref;    ///< Previous frame
     int rx;                    ///< Maximum horizontal shift
     int ry;                    ///< Maximum vertical shift
-    enum FillMethod edge;      ///< Edge fill method
+    int edge;                  ///< Edge fill method
     int blocksize;             ///< Size of blocks to compare
     int contrast;              ///< Contrast threshold
-    enum SearchMethod search;  ///< Motion search method
+    int search;                ///< Motion search method
     AVCodecContext *avctx;
     DSPContext c;              ///< Context providing optimized SAD methods
     Transform last;            ///< Transform from last frame
@@ -352,8 +353,8 @@
     if (args) {
         sscanf(args, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%255s",
                &deshake->cx, &deshake->cy, &deshake->cw, &deshake->ch,
-               &deshake->rx, &deshake->ry, (int *)&deshake->edge,
-               &deshake->blocksize, &deshake->contrast, (int *)&deshake->search, filename);
+               &deshake->rx, &deshake->ry, &deshake->edge,
+               &deshake->blocksize, &deshake->contrast, &deshake->search, filename);
 
         deshake->blocksize /= 2;
 
@@ -386,7 +387,7 @@
 
 static int query_formats(AVFilterContext *ctx)
 {
-    enum AVPixelFormat pix_fmts[] = {
+    static const enum AVPixelFormat pix_fmts[] = {
         AV_PIX_FMT_YUV420P,  AV_PIX_FMT_YUV422P,  AV_PIX_FMT_YUV444P,  AV_PIX_FMT_YUV410P,
         AV_PIX_FMT_YUV411P,  AV_PIX_FMT_YUV440P,  AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P,
         AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ440P, AV_PIX_FMT_NONE
@@ -425,17 +426,23 @@
     av_freep(&deshake->avctx);
 }
 
-static int end_frame(AVFilterLink *link)
+static int filter_frame(AVFilterLink *link, AVFilterBufferRef *in)
 {
     DeshakeContext *deshake = link->dst->priv;
-    AVFilterBufferRef *in  = link->cur_buf;
-    AVFilterBufferRef *out = link->dst->outputs[0]->out_buf;
+    AVFilterLink *outlink = link->dst->outputs[0];
+    AVFilterBufferRef *out;
     Transform t = {{0},0}, orig = {{0},0};
     float matrix[9];
     float alpha = 2.0 / deshake->refcount;
     char tmp[256];
 
-    link->cur_buf = NULL; /* it is in 'in' now */
+    out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
+    if (!out) {
+        avfilter_unref_bufferp(&in);
+        return AVERROR(ENOMEM);
+    }
+    avfilter_copy_buffer_ref_props(out, in);
+
     if (deshake->cx < 0 || deshake->cy < 0 || deshake->cw < 0 || deshake->ch < 0) {
         // Find the most likely global motion for the current frame
         find_motion(deshake, (deshake->ref == NULL) ? in->data[0] : deshake->ref->data[0], in->data[0], link->w, link->h, in->linesize[0], &t);
@@ -520,30 +527,21 @@
     avfilter_transform(in->data[1], out->data[1], in->linesize[1], out->linesize[1], CHROMA_WIDTH(link), CHROMA_HEIGHT(link), matrix, INTERPOLATE_BILINEAR, deshake->edge);
     avfilter_transform(in->data[2], out->data[2], in->linesize[2], out->linesize[2], CHROMA_WIDTH(link), CHROMA_HEIGHT(link), matrix, INTERPOLATE_BILINEAR, deshake->edge);
 
+    // Cleanup the old reference frame
+    avfilter_unref_buffer(deshake->ref);
+
     // Store the current frame as the reference frame for calculating the
     // motion of the next frame
-    if (deshake->ref != NULL)
-        avfilter_unref_buffer(deshake->ref);
-
-    // Cleanup the old reference frame
     deshake->ref = in;
 
-    // Draw the transformed frame information
-    ff_draw_slice(link->dst->outputs[0], 0, link->h, 1);
-    return ff_end_frame(link->dst->outputs[0]);
-}
-
-static int draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
-{
-    return 0;
+    return ff_filter_frame(outlink, out);
 }
 
 static const AVFilterPad deshake_inputs[] = {
     {
         .name         = "default",
         .type         = AVMEDIA_TYPE_VIDEO,
-        .draw_slice   = draw_slice,
-        .end_frame    = end_frame,
+        .filter_frame = filter_frame,
         .config_props = config_props,
         .min_perms    = AV_PERM_READ | AV_PERM_PRESERVE,
     },
@@ -559,13 +557,11 @@
 };
 
 AVFilter avfilter_vf_deshake = {
-    .name      = "deshake",
-    .description = NULL_IF_CONFIG_SMALL("Stabilize shaky video."),
-
-    .priv_size = sizeof(DeshakeContext),
-
-    .init = init,
-    .uninit = uninit,
+    .name          = "deshake",
+    .description   = NULL_IF_CONFIG_SMALL("Stabilize shaky video."),
+    .priv_size     = sizeof(DeshakeContext),
+    .init          = init,
+    .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = deshake_inputs,
     .outputs       = deshake_outputs,
diff --git a/libavfilter/vf_drawbox.c b/libavfilter/vf_drawbox.c
index 5046e7e..af8eca4 100644
--- a/libavfilter/vf_drawbox.c
+++ b/libavfilter/vf_drawbox.c
@@ -100,7 +100,7 @@
 
 static int query_formats(AVFilterContext *ctx)
 {
-    enum AVPixelFormat pix_fmts[] = {
+    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_YUVJ444P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ420P,
diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c
index 5fff9bf..2358e35 100644
--- a/libavfilter/vf_drawtext.c
+++ b/libavfilter/vf_drawtext.c
@@ -47,8 +47,6 @@
 #include "internal.h"
 #include "video.h"
 
-#undef time
-
 #include <ft2build.h>
 #include <freetype/config/ftheader.h>
 #include FT_FREETYPE_H
@@ -167,6 +165,7 @@
     AVTimecode  tc;                 ///< timecode context
     int tc24hmax;                   ///< 1 if timecode is wrapped to 24 hours, 0 otherwise
     int frame_id;
+    int reload;                     ///< reload text file for each frame
 } DrawTextContext;
 
 #define OFFSET(x) offsetof(DrawTextContext, x)
@@ -189,7 +188,7 @@
 {"basetime", "set base time",        OFFSET(basetime),           AV_OPT_TYPE_INT64,  {.i64=AV_NOPTS_VALUE}, INT64_MIN, INT64_MAX , FLAGS},
 {"draw",     "if false do not draw", OFFSET(draw_expr),          AV_OPT_TYPE_STRING, {.str="1"},   CHAR_MIN, CHAR_MAX, FLAGS},
 
-{"expansion","set the expansion mode", OFFSET(exp_mode),         AV_OPT_TYPE_INT,    {.i64=EXP_STRFTIME}, 0,        2, FLAGS, "expansion"},
+{"expansion","set the expansion mode", OFFSET(exp_mode),         AV_OPT_TYPE_INT,    {.i64=EXP_NORMAL},   0,        2, FLAGS, "expansion"},
 {"none",     "set no expansion",     OFFSET(exp_mode),           AV_OPT_TYPE_CONST,  {.i64=EXP_NONE},     0,        0, FLAGS, "expansion"},
 {"normal",   "set normal expansion", OFFSET(exp_mode),           AV_OPT_TYPE_CONST,  {.i64=EXP_NORMAL},   0,        0, FLAGS, "expansion"},
 {"strftime", "set strftime expansion (deprecated)", OFFSET(exp_mode), AV_OPT_TYPE_CONST, {.i64=EXP_STRFTIME}, 0,    0, FLAGS, "expansion"},
@@ -199,6 +198,7 @@
 {"timecode_rate", "set rate (timecode only)", OFFSET(tc_rate),   AV_OPT_TYPE_RATIONAL, {.dbl=0},          0,  INT_MAX, FLAGS},
 {"r",        "set rate (timecode only)", OFFSET(tc_rate),        AV_OPT_TYPE_RATIONAL, {.dbl=0},          0,  INT_MAX, FLAGS},
 {"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},
 
 /* FT_LOAD_* flags */
@@ -393,6 +393,29 @@
     return err;
 }
 
+static int load_textfile(AVFilterContext *ctx)
+{
+    DrawTextContext *dtext = ctx->priv;
+    int err;
+    uint8_t *textbuf;
+    size_t textbuf_size;
+
+    if ((err = av_file_map(dtext->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);
+        return err;
+    }
+
+    if (!(dtext->text = av_realloc(dtext->text, textbuf_size + 1)))
+        return AVERROR(ENOMEM);
+    memcpy(dtext->text, textbuf, textbuf_size);
+    dtext->text[textbuf_size] = 0;
+    av_file_unmap(textbuf, textbuf_size);
+
+    return 0;
+}
+
 static av_cold int init(AVFilterContext *ctx, const char *args)
 {
     int err;
@@ -411,28 +434,18 @@
     }
 
     if (dtext->textfile) {
-        uint8_t *textbuf;
-        size_t textbuf_size;
-
         if (dtext->text) {
             av_log(ctx, AV_LOG_ERROR,
                    "Both text and text file provided. Please provide only one\n");
             return AVERROR(EINVAL);
         }
-        if ((err = av_file_map(dtext->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);
+        if ((err = load_textfile(ctx)) < 0)
             return err;
-        }
-
-        if (!(dtext->text = av_malloc(textbuf_size+1)))
-            return AVERROR(ENOMEM);
-        memcpy(dtext->text, textbuf, textbuf_size);
-        dtext->text[textbuf_size] = 0;
-        av_file_unmap(textbuf, textbuf_size);
     }
 
+    if (dtext->reload && !dtext->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);
@@ -972,6 +985,10 @@
     DrawTextContext *dtext = ctx->priv;
     int ret;
 
+    if (dtext->reload)
+        if ((ret = load_textfile(ctx)) < 0)
+            return ret;
+
     dtext->var_values[VAR_T] = frame->pts == AV_NOPTS_VALUE ?
         NAN : frame->pts * av_q2d(inlink->time_base);
 
@@ -984,7 +1001,7 @@
 
     dtext->var_values[VAR_N] += 1.0;
 
-    return ff_filter_frame(inlink->dst->outputs[0], frame);
+    return ff_filter_frame(outlink, frame);
 }
 
 static const AVFilterPad avfilter_vf_drawtext_inputs[] = {
diff --git a/libavfilter/vf_fade.c b/libavfilter/vf_fade.c
index 5be0ec1..df22274 100644
--- a/libavfilter/vf_fade.c
+++ b/libavfilter/vf_fade.c
@@ -78,41 +78,14 @@
 static av_cold int init(AVFilterContext *ctx, const char *args)
 {
     FadeContext *fade = ctx->priv;
-    int ret = 0;
-    char *args1, *expr, *bufptr = NULL;
+    static const char *shorthand[] = { "type", "start_frame", "nb_frames", NULL };
+    int ret;
 
     fade->class = &fade_class;
     av_opt_set_defaults(fade);
 
-    if (!(args1 = av_strdup(args))) {
-        ret = AVERROR(ENOMEM);
-        goto end;
-    }
-
-    if (expr = av_strtok(args1, ":", &bufptr)) {
-        av_free(fade->type);
-        if (!(fade->type = av_strdup(expr))) {
-            ret = AVERROR(ENOMEM);
-            goto end;
-        }
-    }
-    if (expr = av_strtok(NULL, ":", &bufptr)) {
-        if ((ret = av_opt_set(fade, "start_frame", expr, 0)) < 0) {
-            av_log(ctx, AV_LOG_ERROR,
-                   "Invalid value '%s' for start_frame option\n", expr);
-            goto end;
-        }
-    }
-    if (expr = av_strtok(NULL, ":", &bufptr)) {
-        if ((ret = av_opt_set(fade, "nb_frames", expr, 0)) < 0) {
-            av_log(ctx, AV_LOG_ERROR,
-                   "Invalid value '%s' for nb_frames option\n", expr);
-            goto end;
-        }
-    }
-
-    if (bufptr && (ret = av_set_options_string(fade, bufptr, "=", ":")) < 0)
-        goto end;
+    if ((ret = av_opt_set_from_string(fade, args, shorthand, "=", ":")) < 0)
+        return ret;
 
     fade->fade_per_frame = (1 << 16) / fade->nb_frames;
     if (!strcmp(fade->type, "in"))
@@ -123,25 +96,21 @@
     } else {
         av_log(ctx, AV_LOG_ERROR,
                "Type argument must be 'in' or 'out' but '%s' was specified\n", fade->type);
-        ret = AVERROR(EINVAL);
-        goto end;
+        return AVERROR(EINVAL);
     }
     fade->stop_frame = fade->start_frame + fade->nb_frames;
 
     av_log(ctx, AV_LOG_VERBOSE,
            "type:%s start_frame:%d nb_frames:%d alpha:%d\n",
            fade->type, fade->start_frame, fade->nb_frames, fade->alpha);
-
-end:
-    av_free(args1);
-    return ret;
+    return 0;
 }
 
 static av_cold void uninit(AVFilterContext *ctx)
 {
     FadeContext *fade = ctx->priv;
 
-    av_freep(&fade->type);
+    av_opt_free(fade);
 }
 
 static int query_formats(AVFilterContext *ctx)
@@ -151,7 +120,7 @@
         AV_PIX_FMT_YUV411P,  AV_PIX_FMT_YUV410P,
         AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ420P,
         AV_PIX_FMT_YUV440P,  AV_PIX_FMT_YUVJ440P,
-        AV_PIX_FMT_YUVA420P,
+        AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA444P,
         AV_PIX_FMT_RGB24,    AV_PIX_FMT_BGR24,
         AV_PIX_FMT_ARGB,     AV_PIX_FMT_ABGR,
         AV_PIX_FMT_RGBA,     AV_PIX_FMT_BGRA,
@@ -169,13 +138,6 @@
     AV_PIX_FMT_NONE
 };
 
-static enum AVPixelFormat alpha_pix_fmts[] = {
-    AV_PIX_FMT_YUVA420P,
-    AV_PIX_FMT_ARGB, AV_PIX_FMT_ABGR,
-    AV_PIX_FMT_RGBA, AV_PIX_FMT_BGRA,
-    AV_PIX_FMT_NONE
-};
-
 static int config_props(AVFilterLink *inlink)
 {
     FadeContext *fade = inlink->dst->priv;
@@ -185,7 +147,7 @@
     fade->vsub = pixdesc->log2_chroma_h;
 
     fade->bpp = av_get_bits_per_pixel(pixdesc) >> 3;
-    fade->alpha = fade->alpha ? ff_fmt_is_in(inlink->format, alpha_pix_fmts) : 0;
+    fade->alpha &= pixdesc->flags & PIX_FMT_ALPHA;
     fade->is_packed_rgb = ff_fill_rgba_map(fade->rgba_map, inlink->format) >= 0;
 
     /* use CCIR601/709 black level for studio-level pixel non-alpha components */
diff --git a/libavfilter/vf_field.c b/libavfilter/vf_field.c
index c9ac42b..67c0025 100644
--- a/libavfilter/vf_field.c
+++ b/libavfilter/vf_field.c
@@ -82,33 +82,21 @@
     return 0;
 }
 
-static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
+static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
 {
     FieldContext *field = inlink->dst->priv;
-    AVFilterBufferRef *outpicref = avfilter_ref_buffer(inpicref, ~0);
     AVFilterLink *outlink = inlink->dst->outputs[0];
     int i;
 
-    if (!outpicref)
-        return AVERROR(ENOMEM);
-
-    outpicref->video->h = outlink->h;
-    outpicref->video->interlaced = 0;
+    inpicref->video->h = outlink->h;
+    inpicref->video->interlaced = 0;
 
     for (i = 0; i < field->nb_planes; i++) {
         if (field->type == FIELD_TYPE_BOTTOM)
-            outpicref->data[i] = inpicref->data[i] + inpicref->linesize[i];
-        outpicref->linesize[i] = 2 * inpicref->linesize[i];
+            inpicref->data[i] = inpicref->data[i] + inpicref->linesize[i];
+        inpicref->linesize[i] = 2 * inpicref->linesize[i];
     }
-    return ff_start_frame(outlink, outpicref);
-}
-
-static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
-{
-    FieldContext *field = inlink->dst->priv;
-    int y1 = (y + (field->type == FIELD_TYPE_TOP)) / 2;
-    int h1 = (h + (field->type == FIELD_TYPE_TOP)) / 2;
-    return ff_draw_slice(inlink->dst->outputs[0], y1, h1, slice_dir);
+    return ff_filter_frame(outlink, inpicref);
 }
 
 static const AVFilterPad field_inputs[] = {
@@ -116,9 +104,7 @@
         .name             = "default",
         .type             = AVMEDIA_TYPE_VIDEO,
         .get_video_buffer = ff_null_get_video_buffer,
-        .start_frame      = start_frame,
-        .draw_slice       = draw_slice,
-        .end_frame        = ff_null_end_frame,
+        .filter_frame     = filter_frame,
     },
     { NULL }
 };
diff --git a/libavfilter/vf_fps.c b/libavfilter/vf_fps.c
index 8e7880c..29eedc7 100644
--- a/libavfilter/vf_fps.c
+++ b/libavfilter/vf_fps.c
@@ -74,16 +74,14 @@
 static av_cold int init(AVFilterContext *ctx, const char *args)
 {
     FPSContext *s = ctx->priv;
+    const char *shorthand[] = { "fps", "round", NULL };
     int ret;
 
     s->class = &fps_class;
     av_opt_set_defaults(s);
 
-    if ((ret = av_set_options_string(s, args, "=", ":")) < 0) {
-        av_log(ctx, AV_LOG_ERROR, "Error parsing the options string %s.\n",
-               args);
+    if ((ret = av_opt_set_from_string(s, args, shorthand, "=", ":")) < 0)
         return ret;
-    }
 
     if ((ret = av_parse_video_rate(&s->framerate, s->fps)) < 0) {
         av_log(ctx, AV_LOG_ERROR, "Error parsing framerate %s.\n", s->fps);
@@ -111,6 +109,7 @@
 {
     FPSContext *s = ctx->priv;
     if (s->fifo) {
+        s->drop += av_fifo_size(s->fifo) / sizeof(AVFilterBufferRef*);
         flush_fifo(s->fifo);
         av_fifo_free(s->fifo);
     }
diff --git a/libavfilter/vf_frei0r.c b/libavfilter/vf_frei0r.c
index 0fb86b4..7ed78fa 100644
--- a/libavfilter/vf_frei0r.c
+++ b/libavfilter/vf_frei0r.c
@@ -189,7 +189,7 @@
         case F0R_PARAM_POSITION:
             v = &pos;
             frei0r->get_param_value(frei0r->instance, v, i);
-            av_log(ctx, AV_LOG_DEBUG, "%lf/%lf", pos.x, pos.y);
+            av_log(ctx, AV_LOG_DEBUG, "%f/%f", pos.x, pos.y);
             break;
         default: /* F0R_PARAM_STRING */
             v = s;
diff --git a/libavfilter/vf_geq.c b/libavfilter/vf_geq.c
index 2f7b50b..72ecda0 100644
--- a/libavfilter/vf_geq.c
+++ b/libavfilter/vf_geq.c
@@ -34,20 +34,22 @@
 
 typedef struct {
     const AVClass *class;
-    AVExpr *e[3];               ///< expressions for each plane
-    char *expr_str[3];          ///< expression strings for each plane
+    AVExpr *e[4];               ///< expressions for each plane
+    char *expr_str[4];          ///< expression strings for each plane
     int framenum;               ///< frame counter
     AVFilterBufferRef *picref;  ///< current input buffer
     int hsub, vsub;             ///< chroma subsampling
+    int planes;                 ///< number of planes
 } GEQContext;
 
 #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),                   AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS },
-    { "cb_expr",    "set chroma blue expression", OFFSET(expr_str) +   sizeof(char*), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS },
-    { "cr_expr",    "set chroma red expression",  OFFSET(expr_str) + 2*sizeof(char*), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "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 },
     {NULL},
 };
 
@@ -60,8 +62,11 @@
     AVFilterBufferRef *picref = geq->picref;
     const uint8_t *src = picref->data[plane];
     const int linesize = picref->linesize[plane];
-    const int w = picref->video->w >> (plane ? geq->hsub : 0);
-    const int h = picref->video->h >> (plane ? geq->vsub : 0);
+    const int w = picref->video->w >> ((plane == 1 || plane == 2) ? geq->hsub : 0);
+    const int h = picref->video->h >> ((plane == 1 || plane == 2) ? geq->vsub : 0);
+
+    if (!src)
+        return 0;
 
     xi = x = av_clipf(x, 0, w - 2);
     yi = y = av_clipf(y, 0, h - 2);
@@ -78,6 +83,7 @@
 static double lum(void *priv, double x, double y) { return getpix(priv, x, y, 0); }
 static double  cb(void *priv, double x, double y) { return getpix(priv, x, y, 1); }
 static double  cr(void *priv, double x, double y) { return getpix(priv, x, y, 2); }
+static double alpha(void *priv, double x, double y) { return getpix(priv, x, y, 3); }
 
 static const char *const var_names[] = {   "X",   "Y",   "W",   "H",   "N",   "SW",   "SH",   "T",        NULL };
 enum                                   { VAR_X, VAR_Y, VAR_W, VAR_H, VAR_N, VAR_SW, VAR_SH, VAR_T, VAR_VARS_NB };
@@ -86,7 +92,7 @@
 {
     GEQContext *geq = ctx->priv;
     int plane, ret = 0;
-    static const char *shorthand[] = { "lum_expr", "cb_expr", "cr_expr", NULL };
+    static const char *shorthand[] = { "lum_expr", "cb_expr", "cr_expr", "alpha_expr", NULL };
 
     geq->class = &geq_class;
     av_opt_set_defaults(geq);
@@ -110,15 +116,18 @@
         if (!geq->expr_str[2]) geq->expr_str[2] = av_strdup(geq->expr_str[1]);
     }
 
-    if (!geq->expr_str[1] || !geq->expr_str[2]) {
+    if (!geq->expr_str[3])
+        geq->expr_str[3] = av_strdup("255");
+
+    if (!geq->expr_str[1] || !geq->expr_str[2] || !geq->expr_str[3]) {
         ret = AVERROR(ENOMEM);
         goto end;
     }
 
-    for (plane = 0; plane < 3; plane++) {
-        static double (*p[])(void *, double, double) = { lum, cb, cr };
-        static const char *const func2_names[]    = { "lum", "cb", "cr", "p", NULL };
-        double (*func2[])(void *, double, double) = { lum, cb, cr, p[plane], NULL };
+    for (plane = 0; plane < 4; plane++) {
+        static double (*p[])(void *, double, double) = { lum, cb, cr, alpha };
+        static const char *const func2_names[]    = { "lum", "cb", "cr", "alpha", "p", NULL };
+        double (*func2[])(void *, double, double) = { lum, cb, cr, alpha, p[plane], NULL };
 
         ret = av_expr_parse(&geq->e[plane], geq->expr_str[plane], var_names,
                             NULL, NULL, func2_names, func2, 0, ctx);
@@ -135,7 +144,8 @@
     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_YUVA420P,
+        AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA420P,
+        AV_PIX_FMT_GRAY8,
         AV_PIX_FMT_NONE
     };
     ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
@@ -149,6 +159,7 @@
 
     geq->hsub = desc->log2_chroma_w;
     geq->vsub = desc->log2_chroma_h;
+    geq->planes = desc->nb_components;
     return 0;
 }
 
@@ -171,12 +182,12 @@
     }
     avfilter_copy_buffer_ref_props(out, in);
 
-    for (plane = 0; plane < 3; plane++) {
+    for (plane = 0; plane < geq->planes && out->data[plane]; plane++) {
         int x, y;
         uint8_t *dst = out->data[plane];
         const int linesize = out->linesize[plane];
-        const int w = inlink->w >> (plane ? geq->hsub : 0);
-        const int h = inlink->h >> (plane ? geq->vsub : 0);
+        const int w = inlink->w >> ((plane == 1 || plane == 2) ? geq->hsub : 0);
+        const int h = inlink->h >> ((plane == 1 || plane == 2) ? geq->vsub : 0);
 
         values[VAR_W]  = w;
         values[VAR_H]  = h;
diff --git a/libavfilter/vf_gradfun.c b/libavfilter/vf_gradfun.c
index 32d8796..13154f0 100644
--- a/libavfilter/vf_gradfun.c
+++ b/libavfilter/vf_gradfun.c
@@ -36,12 +36,24 @@
 #include "libavutil/common.h"
 #include "libavutil/cpu.h"
 #include "libavutil/pixdesc.h"
+#include "libavutil/opt.h"
 #include "avfilter.h"
 #include "formats.h"
 #include "gradfun.h"
 #include "internal.h"
 #include "video.h"
 
+#define OFFSET(x) offsetof(GradFunContext, x)
+#define F AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
+
+static const AVOption gradfun_options[] = {
+    { "strength", "set the maximum amount by which the filter will change any one pixel", OFFSET(strength), AV_OPT_TYPE_DOUBLE, {.dbl = 1.2}, 0.51, 64, F },
+    { "radius",   "set the neighborhood to fit the gradient to",                          OFFSET(radius),   AV_OPT_TYPE_INT,    {.i64 =  16},    4, 32, F },
+    { NULL }
+};
+
+AVFILTER_DEFINE_CLASS(gradfun);
+
 DECLARE_ALIGNED(16, static const uint16_t, dither)[8][8] = {
     {0x00,0x60,0x18,0x78,0x06,0x66,0x1E,0x7E},
     {0x40,0x20,0x58,0x38,0x46,0x26,0x5E,0x3E},
@@ -56,7 +68,7 @@
 void ff_gradfun_filter_line_c(uint8_t *dst, const uint8_t *src, const uint16_t *dc, int width, int thresh, const uint16_t *dithers)
 {
     int x;
-    for (x = 0; x < width; x++, dc += x & 1) {
+    for (x = 0; x < width; dc += x & 1, x++) {
         int pix = src[x] << 7;
         int delta = dc[0] - pix;
         int m = abs(delta) * thresh >> 16;
@@ -121,24 +133,26 @@
 
 static av_cold int init(AVFilterContext *ctx, const char *args)
 {
+    int ret;
     GradFunContext *gf = ctx->priv;
-    float thresh = 1.2;
-    int radius = 16;
+    static const char *shorthand[] = { "strength", "radius", NULL };
 
-    if (args)
-        sscanf(args, "%f:%d", &thresh, &radius);
+    gf->class = &gradfun_class;
+    av_opt_set_defaults(gf);
 
-    thresh = av_clipf(thresh, 0.51, 255);
-    gf->thresh = (1 << 15) / thresh;
-    gf->radius = av_clip((radius + 1) & ~1, 4, 32);
+    if ((ret = av_opt_set_from_string(gf, args, shorthand, "=", ":")) < 0)
+        return ret;
 
-    gf->blur_line = ff_gradfun_blur_line_c;
+    gf->thresh = (1 << 15) / gf->strength;
+    gf->radius = av_clip((gf->radius + 1) & ~1, 4, 32);
+
+    gf->blur_line   = ff_gradfun_blur_line_c;
     gf->filter_line = ff_gradfun_filter_line_c;
 
     if (ARCH_X86)
         ff_gradfun_init_x86(gf);
 
-    av_log(ctx, AV_LOG_VERBOSE, "threshold:%.2f radius:%d\n", thresh, gf->radius);
+    av_log(ctx, AV_LOG_VERBOSE, "threshold:%.2f radius:%d\n", gf->strength, gf->radius);
 
     return 0;
 }
@@ -156,6 +170,7 @@
         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_YUV440P,
         AV_PIX_FMT_NONE
     };
 
@@ -198,10 +213,7 @@
             avfilter_unref_bufferp(&in);
             return AVERROR(ENOMEM);
         }
-
         avfilter_copy_buffer_ref_props(out, in);
-        out->video->w = outlink->w;
-        out->video->h = outlink->h;
     }
 
     for (p = 0; p < 4 && in->data[p]; p++) {
@@ -252,7 +264,7 @@
     .init          = init,
     .uninit        = uninit,
     .query_formats = query_formats,
-
-    .inputs    = avfilter_vf_gradfun_inputs,
-    .outputs   = avfilter_vf_gradfun_outputs,
+    .inputs        = avfilter_vf_gradfun_inputs,
+    .outputs       = avfilter_vf_gradfun_outputs,
+    .priv_class    = &gradfun_class,
 };
diff --git a/libavfilter/vf_hflip.c b/libavfilter/vf_hflip.c
index c583ffd..c3b92c2 100644
--- a/libavfilter/vf_hflip.c
+++ b/libavfilter/vf_hflip.c
@@ -42,35 +42,19 @@
 
 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_RGB444BE,     AV_PIX_FMT_RGB444LE,
-        AV_PIX_FMT_BGR565BE,     AV_PIX_FMT_BGR565LE,
-        AV_PIX_FMT_BGR555BE,     AV_PIX_FMT_BGR555LE,
-        AV_PIX_FMT_BGR444BE,     AV_PIX_FMT_BGR444LE,
-        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 *pix_fmts = 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 & PIX_FMT_HWACCEL ||
+              desc->flags & PIX_FMT_BITSTREAM ||
+              (desc->log2_chroma_w != desc->log2_chroma_h &&
+               desc->comp[0].plane == desc->comp[1].plane)))
+            ff_add_format(&pix_fmts, fmt);
+    }
+
+    ff_set_common_formats(ctx, pix_fmts);
     return 0;
 }
 
diff --git a/libavfilter/vf_histeq.c b/libavfilter/vf_histeq.c
new file mode 100644
index 0000000..556680c
--- /dev/null
+++ b/libavfilter/vf_histeq.c
@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) 2012 Jeremy Tran
+ * Copyright (c) 2001 Donald A. Graft
+ *
+ * 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
+ * Histogram equalization filter, based on the VirtualDub filter by
+ * Donald A. Graft  <neuron2 AT home DOT com>.
+ * Implements global automatic contrast adjustment by means of
+ * histogram equalization.
+ */
+
+#include "libavutil/common.h"
+#include "libavutil/opt.h"
+#include "libavutil/pixdesc.h"
+
+#include "avfilter.h"
+#include "drawutils.h"
+#include "formats.h"
+#include "internal.h"
+#include "video.h"
+
+// #define DEBUG
+
+// Linear Congruential Generator, see "Numerical Recipes"
+#define LCG_A 4096
+#define LCG_C 150889
+#define LCG_M 714025
+#define LCG(x) (((x) * LCG_A + LCG_C) % LCG_M)
+#define LCG_SEED 739187
+
+enum HisteqAntibanding {
+    HISTEQ_ANTIBANDING_NONE   = 0,
+    HISTEQ_ANTIBANDING_WEAK   = 1,
+    HISTEQ_ANTIBANDING_STRONG = 2,
+    HISTEQ_ANTIBANDING_NB,
+};
+
+typedef struct {
+    const AVClass *class;
+    float strength;
+    float intensity;
+    enum HisteqAntibanding antibanding;
+    char* antibanding_str;
+    int in_histogram [256];        ///< input histogram
+    int out_histogram[256];        ///< output histogram
+    int LUT[256];                  ///< lookup table derived from histogram[]
+    uint8_t rgba_map[4];           ///< components position
+    int bpp;                       ///< bytes per pixel
+} HisteqContext;
+
+#define OFFSET(x) offsetof(HisteqContext, 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 histeq_options[] = {
+    { "strength",    "set the strength", OFFSET(strength), AV_OPT_TYPE_FLOAT, {.dbl=0.2}, 0, 1, FLAGS },
+    { "intensity",   "set the intensity", OFFSET(intensity), AV_OPT_TYPE_FLOAT, {.dbl=0.21}, 0, 1, FLAGS },
+    { "antibanding", "set the antibanding level", OFFSET(antibanding), AV_OPT_TYPE_INT, {.i64=HISTEQ_ANTIBANDING_NONE}, 0, HISTEQ_ANTIBANDING_NB-1, FLAGS, "antibanding" },
+    CONST("none",    "apply no antibanding",     HISTEQ_ANTIBANDING_NONE,   "antibanding"),
+    CONST("weak",    "apply weak antibanding",   HISTEQ_ANTIBANDING_WEAK,   "antibanding"),
+    CONST("strong",  "apply strong antibanding", HISTEQ_ANTIBANDING_STRONG, "antibanding"),
+    { NULL }
+};
+
+AVFILTER_DEFINE_CLASS(histeq);
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    HisteqContext *histeq = ctx->priv;
+    const char *shorthand[] = { "strength", "intensity", "antibanding", NULL };
+    int ret;
+
+    histeq->class = &histeq_class;
+    av_opt_set_defaults(histeq);
+
+    if ((ret = av_opt_set_from_string(histeq, args, shorthand, "=", ":")) < 0)
+        return ret;
+
+    av_log(ctx, AV_LOG_VERBOSE,
+           "strength:%0.3f intensity:%0.3f antibanding:%d\n",
+           histeq->strength, histeq->intensity, histeq->antibanding);
+
+    return 0;
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    HisteqContext *histeq = ctx->priv;
+    av_opt_free(histeq);
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    static const enum PixelFormat pix_fmts[] = {
+        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_NONE
+    };
+
+    ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
+    return 0;
+}
+
+static int config_input(AVFilterLink *inlink)
+{
+    AVFilterContext *ctx = inlink->dst;
+    HisteqContext *histeq = ctx->priv;
+    const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format);
+
+    histeq->bpp = av_get_bits_per_pixel(pix_desc) / 8;
+    ff_fill_rgba_map(histeq->rgba_map, inlink->format);
+
+    return 0;
+}
+
+#define R 0
+#define G 1
+#define B 2
+#define A 3
+
+#define GET_RGB_VALUES(r, g, b, src, map) do { \
+    r = src[x + map[R]];                       \
+    g = src[x + map[G]];                       \
+    b = src[x + map[B]];                       \
+} while (0)
+
+static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *inpic)
+{
+    AVFilterContext   *ctx     = inlink->dst;
+    HisteqContext     *histeq  = ctx->priv;
+    AVFilterLink      *outlink = ctx->outputs[0];
+    int strength  = histeq->strength  * 1000;
+    int intensity = histeq->intensity * 1000;
+    int x, y, i, luthi, lutlo, lut, luma, oluma, m;
+    AVFilterBufferRef *outpic;
+    unsigned int r, g, b, jran;
+    uint8_t *src, *dst;
+
+    outpic = ff_get_video_buffer(outlink, AV_PERM_WRITE|AV_PERM_ALIGN, outlink->w, outlink->h);
+    if (!outpic) {
+        avfilter_unref_bufferp(&inpic);
+        return AVERROR(ENOMEM);
+    }
+    avfilter_copy_buffer_ref_props(outpic, inpic);
+
+    /* Seed random generator for antibanding. */
+    jran = LCG_SEED;
+
+    /* Calculate and store the luminance and calculate the global histogram
+       based on the luminance. */
+    memset(histeq->in_histogram, 0, sizeof(histeq->in_histogram));
+    src = inpic->data[0];
+    dst = outpic->data[0];
+    for (y = 0; y < inlink->h; y++) {
+        for (x = 0; x < inlink->w * histeq->bpp; x += histeq->bpp) {
+            GET_RGB_VALUES(r, g, b, src, histeq->rgba_map);
+            luma = (55 * r + 182 * g + 19 * b) >> 8;
+            dst[x + histeq->rgba_map[A]] = luma;
+            histeq->in_histogram[luma]++;
+        }
+        src += inpic->linesize[0];
+        dst += outpic->linesize[0];
+    }
+
+#ifdef DEBUG
+    for (x = 0; x < 256; x++)
+        av_dlog(ctx, "in[%d]: %u\n", x, histeq->in_histogram[x]);
+#endif
+
+    /* Calculate the lookup table. */
+    histeq->LUT[0] = histeq->in_histogram[0];
+    /* Accumulate */
+    for (x = 1; x < 256; x++)
+        histeq->LUT[x] = histeq->LUT[x-1] + histeq->in_histogram[x];
+
+    /* Normalize */
+    for (x = 0; x < 256; x++)
+        histeq->LUT[x] = (histeq->LUT[x] * intensity) / (inlink->h * inlink->w);
+
+    /* Adjust the LUT based on the selected strength. This is an alpha
+       mix of the calculated LUT and a linear LUT with gain 1. */
+    for (x = 0; x < 256; x++)
+        histeq->LUT[x] = (strength * histeq->LUT[x]) / 255 +
+                         ((255 - strength) * x)      / 255;
+
+    /* Output the equalized frame. */
+    memset(histeq->out_histogram, 0, sizeof(histeq->out_histogram));
+
+    src = inpic->data[0];
+    dst = outpic->data[0];
+    for (y = 0; y < inlink->h; y++) {
+        for (x = 0; x < inlink->w * histeq->bpp; x += histeq->bpp) {
+            luma = dst[x + histeq->rgba_map[A]];
+            if (luma == 0) {
+                for (i = 0; i < histeq->bpp; ++i)
+                    dst[x + i] = 0;
+                histeq->out_histogram[0]++;
+            } else {
+                lut = histeq->LUT[luma];
+                if (histeq->antibanding != HISTEQ_ANTIBANDING_NONE) {
+                    if (luma > 0) {
+                        lutlo = histeq->antibanding == HISTEQ_ANTIBANDING_WEAK ?
+                                (histeq->LUT[luma] + histeq->LUT[luma - 1]) / 2 :
+                                 histeq->LUT[luma - 1];
+                    } else
+                        lutlo = lut;
+
+                    if (luma < 255) {
+                        luthi = (histeq->antibanding == HISTEQ_ANTIBANDING_WEAK) ?
+                            (histeq->LUT[luma] + histeq->LUT[luma + 1]) / 2 :
+                             histeq->LUT[luma + 1];
+                    } else
+                        luthi = lut;
+
+                    if (lutlo != luthi) {
+                        jran = LCG(jran);
+                        lut = lutlo + ((luthi - lutlo + 1) * jran) / LCG_M;
+                    }
+                }
+
+                GET_RGB_VALUES(r, g, b, src, histeq->rgba_map);
+                if (((m = FFMAX3(r, g, b)) * lut) / luma > 255) {
+                    r = (r * 255) / m;
+                    g = (g * 255) / m;
+                    b = (b * 255) / m;
+                } else {
+                    r = (r * lut) / luma;
+                    g = (g * lut) / luma;
+                    b = (b * lut) / luma;
+                }
+                dst[x + histeq->rgba_map[R]] = r;
+                dst[x + histeq->rgba_map[G]] = g;
+                dst[x + histeq->rgba_map[B]] = b;
+                oluma = (55 * r + 182 * g + 19 * b) >> 8;
+                histeq->out_histogram[oluma]++;
+            }
+        }
+        src += inpic->linesize[0];
+        dst += outpic->linesize[0];
+    }
+#ifdef DEBUG
+    for (x = 0; x < 256; x++)
+        av_dlog(ctx, "out[%d]: %u\n", x, histeq->out_histogram[x]);
+#endif
+
+    avfilter_unref_bufferp(&inpic);
+    return ff_filter_frame(outlink, outpic);
+}
+
+static const AVFilterPad histeq_inputs[] = {
+    {
+        .name             = "default",
+        .type             = AVMEDIA_TYPE_VIDEO,
+        .config_props     = config_input,
+        .filter_frame     = filter_frame,
+        .min_perms        = AV_PERM_READ,
+    },
+    { NULL }
+};
+
+static const AVFilterPad histeq_outputs[] = {
+    {
+        .name             = "default",
+        .type             = AVMEDIA_TYPE_VIDEO,
+    },
+    { NULL }
+};
+
+AVFilter avfilter_vf_histeq = {
+    .name          = "histeq",
+    .description   = NULL_IF_CONFIG_SMALL("Apply global color histogram equalization."),
+    .priv_size     = sizeof(HisteqContext),
+    .init          = init,
+    .uninit        = uninit,
+    .query_formats = query_formats,
+
+    .inputs        = histeq_inputs,
+    .outputs       = histeq_outputs,
+    .priv_class    = &histeq_class,
+};
diff --git a/libavfilter/vf_histogram.c b/libavfilter/vf_histogram.c
new file mode 100644
index 0000000..279e44a
--- /dev/null
+++ b/libavfilter/vf_histogram.c
@@ -0,0 +1,347 @@
+/*
+ * Copyright (c) 2012-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/avassert.h"
+#include "libavutil/opt.h"
+#include "libavutil/parseutils.h"
+#include "libavutil/pixdesc.h"
+#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
+#include "video.h"
+
+enum HistogramMode {
+    MODE_LEVELS,
+    MODE_WAVEFORM,
+    MODE_COLOR,
+    MODE_COLOR2,
+    MODE_NB
+};
+
+typedef struct HistogramContext {
+    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;
+    int            level_height;
+    int            scale_height;
+    int            step;
+    int            waveform_mode;
+    int            display_mode;
+} HistogramContext;
+
+#define OFFSET(x) offsetof(HistogramContext, x)
+#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
+
+static const AVOption histogram_options[] = {
+    { "mode", "set histogram mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=MODE_LEVELS}, 0, MODE_NB-1, FLAGS, "mode"},
+    { "levels", "standard histogram", 0, AV_OPT_TYPE_CONST, {.i64=MODE_LEVELS}, 0, 0, FLAGS, "mode" },
+    { "waveform", "per row/column luminance graph", 0, AV_OPT_TYPE_CONST, {.i64=MODE_WAVEFORM}, 0, 0, FLAGS, "mode" },
+    { "color", "chroma values in vectorscope", 0, AV_OPT_TYPE_CONST, {.i64=MODE_COLOR}, 0, 0, FLAGS, "mode" },
+    { "color2", "chroma values in vectorscope", 0, AV_OPT_TYPE_CONST, {.i64=MODE_COLOR2}, 0, 0, FLAGS, "mode" },
+    { "level_height", "set level height", OFFSET(level_height), AV_OPT_TYPE_INT, {.i64=200}, 50, 2048, FLAGS},
+    { "scale_height", "set scale height", OFFSET(scale_height), AV_OPT_TYPE_INT, {.i64=12}, 0, 40, FLAGS},
+    { "step", "set waveform step value", OFFSET(step), AV_OPT_TYPE_INT, {.i64=10}, 1, 255, FLAGS},
+    { "waveform_mode", "set waveform mode", OFFSET(waveform_mode), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, "waveform_mode"},
+    { "row",   NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "waveform_mode" },
+    { "column", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "waveform_mode" },
+    { "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" },
+    { NULL },
+};
+
+AVFILTER_DEFINE_CLASS(histogram);
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    HistogramContext *h = ctx->priv;
+    int ret;
+
+    h->class = &histogram_class;
+    av_opt_set_defaults(h);
+
+    if ((ret = (av_set_options_string(h, args, "=", ":"))) < 0)
+        return ret;
+
+    return 0;
+}
+
+static const enum AVPixelFormat color_pix_fmts[] = {
+    AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUVJ444P,
+    AV_PIX_FMT_NONE
+};
+
+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
+};
+
+static int query_formats(AVFilterContext *ctx)
+{
+    HistogramContext *h = ctx->priv;
+    const enum AVPixelFormat *pix_fmts;
+
+    switch (h->mode) {
+    case MODE_WAVEFORM:
+    case MODE_LEVELS:
+        pix_fmts = levels_pix_fmts;
+        break;
+    case MODE_COLOR:
+    case MODE_COLOR2:
+        pix_fmts = color_pix_fmts;
+        break;
+    default:
+        av_assert0(0);
+    }
+
+    ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
+
+    return 0;
+}
+
+static const uint8_t black_yuva_color[4] = { 0, 127, 127, 255 };
+static const uint8_t black_gbrp_color[4] = { 0, 0, 0, 255 };
+static const uint8_t white_yuva_color[4] = { 255, 127, 127, 255 };
+static const uint8_t white_gbrp_color[4] = { 255, 255, 255, 255 };
+
+static int config_input(AVFilterLink *inlink)
+{
+    HistogramContext *h = inlink->dst->priv;
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
+
+    h->ncomp = desc->nb_components;
+
+    switch (inlink->format) {
+    case AV_PIX_FMT_GBRP:
+        h->bg_color = black_gbrp_color;
+        h->fg_color = white_gbrp_color;
+        break;
+    default:
+        h->bg_color = black_yuva_color;
+        h->fg_color = white_yuva_color;
+    }
+
+    return 0;
+}
+
+static int config_output(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx = outlink->src;
+    HistogramContext *h = ctx->priv;
+
+    switch (h->mode) {
+    case MODE_LEVELS:
+        outlink->w = 256;
+        outlink->h = (h->level_height + h->scale_height) * FFMAX(h->ncomp * h->display_mode, 1);
+        break;
+    case MODE_WAVEFORM:
+        if (h->waveform_mode)
+            outlink->h = 256 * FFMAX(h->ncomp * h->display_mode, 1);
+        else
+            outlink->w = 256 * FFMAX(h->ncomp * h->display_mode, 1);
+        break;
+    case MODE_COLOR:
+    case MODE_COLOR2:
+        outlink->h = outlink->w = 256;
+        break;
+    default:
+        av_assert0(0);
+    }
+
+    outlink->sample_aspect_ratio = (AVRational){1,1};
+
+    return 0;
+}
+
+static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
+{
+    HistogramContext *h   = inlink->dst->priv;
+    AVFilterContext *ctx  = inlink->dst;
+    AVFilterLink *outlink = ctx->outputs[0];
+    AVFilterBufferRef *out;
+    const uint8_t *src;
+    uint8_t *dst;
+    int i, j, k, l, ret;
+
+    out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
+    if (!out) {
+        avfilter_unref_bufferp(&in);
+        return AVERROR(ENOMEM);
+    }
+
+    out->pts = in->pts;
+    out->pos = in->pos;
+
+    for (k = 0; k < h->ncomp; k++)
+        for (i = 0; i < outlink->h; i++)
+            memset(out->data[k] + i * out->linesize[k], h->bg_color[k], outlink->w);
+
+    switch (h->mode) {
+    case MODE_LEVELS:
+        for (k = 0; k < h->ncomp; k++) {
+            int start = k * (h->level_height + h->scale_height) * h->display_mode;
+
+            for (i = 0; i < in->video->h; i++) {
+                src = in->data[k] + i * in->linesize[k];
+                for (j = 0; j < in->video->w; j++)
+                    h->histogram[src[j]]++;
+            }
+
+            for (i = 0; i < 256; i++)
+                h->max_hval = FFMAX(h->max_hval, h->histogram[i]);
+
+            for (i = 0; i < outlink->w; i++) {
+                int col_height = h->level_height - (float)h->histogram[i] / h->max_hval * h->level_height;
+
+                for (j = h->level_height - 1; j >= col_height; j--) {
+                    if (h->display_mode) {
+                        for (l = 0; l < h->ncomp; l++)
+                            out->data[l][(j + start) * out->linesize[l] + i] = h->fg_color[l];
+                    } else {
+                        out->data[k][(j + start) * out->linesize[k] + i] = 255;
+                    }
+                }
+                for (j = h->level_height + h->scale_height - 1; j >= h->level_height; j--)
+                    out->data[k][(j + start) * out->linesize[k] + i] = i;
+            }
+
+            memset(h->histogram, 0, 256 * sizeof(unsigned));
+            h->max_hval = 0;
+        }
+        break;
+    case MODE_WAVEFORM:
+        if (h->waveform_mode) {
+            for (k = 0; k < h->ncomp; k++) {
+                int offset = k * 256 * h->display_mode;
+                for (i = 0; i < inlink->w; i++) {
+                    for (j = 0; j < inlink->h; j++) {
+                        int pos = (offset +
+                                   in->data[k][j * in->linesize[k] + i]) *
+                                  out->linesize[k] + i;
+                        unsigned value = out->data[k][pos];
+                        value = FFMIN(value + h->step, 255);
+                        out->data[k][pos] = value;
+                    }
+                }
+            }
+        } else {
+            for (k = 0; k < h->ncomp; k++) {
+                int offset = k * 256 * h->display_mode;
+                for (i = 0; i < inlink->h; i++) {
+                    src = in ->data[k] + i * in ->linesize[k];
+                    dst = out->data[k] + i * out->linesize[k];
+                    for (j = 0; j < inlink->w; j++) {
+                        int pos = src[j] + offset;
+                        unsigned value = dst[pos];
+                        value = FFMIN(value + h->step, 255);
+                        dst[pos] = value;
+                    }
+                }
+            }
+        }
+        break;
+    case MODE_COLOR:
+        for (i = 0; i < inlink->h; i++) {
+            int iw1 = i * in->linesize[1];
+            int iw2 = i * in->linesize[2];
+            for (j = 0; j < inlink->w; j++) {
+                int pos = in->data[1][iw1 + j] * out->linesize[0] + in->data[2][iw2 + j];
+                if (out->data[0][pos] < 255)
+                    out->data[0][pos]++;
+            }
+        }
+        for (i = 0; i < 256; i++) {
+            dst = out->data[0] + i * out->linesize[0];
+            for (j = 0; j < 256; j++) {
+                if (!dst[j]) {
+                    out->data[1][i * out->linesize[0] + j] = i;
+                    out->data[2][i * out->linesize[0] + j] = j;
+                }
+            }
+        }
+        break;
+    case MODE_COLOR2:
+        for (i = 0; i < inlink->h; i++) {
+            int iw1 = i * in->linesize[1];
+            int iw2 = i * in->linesize[2];
+            for (j = 0; j < inlink->w; j++) {
+                int u = in->data[1][iw1 + j];
+                int v = in->data[2][iw2 + j];
+                int pos = u * out->linesize[0] + v;
+                if (!out->data[0][pos])
+                    out->data[0][pos] = FFABS(128 - u) + FFABS(128 - v);
+                out->data[1][pos] = u;
+                out->data[2][pos] = v;
+            }
+        }
+        break;
+    default:
+        av_assert0(0);
+    }
+
+    ret = ff_filter_frame(outlink, out);
+    avfilter_unref_bufferp(&in);
+    if (ret < 0)
+        return ret;
+    return 0;
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    HistogramContext *h = ctx->priv;
+
+    av_opt_free(h);
+}
+
+static const AVFilterPad inputs[] = {
+    {
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_VIDEO,
+        .filter_frame = filter_frame,
+        .config_props = config_input,
+        .min_perms    = AV_PERM_READ,
+    },
+    { NULL }
+};
+
+static const AVFilterPad outputs[] = {
+    {
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_VIDEO,
+        .config_props = config_output,
+    },
+    { NULL }
+};
+
+AVFilter avfilter_vf_histogram = {
+    .name          = "histogram",
+    .description   = NULL_IF_CONFIG_SMALL("Compute and draw a histogram."),
+    .priv_size     = sizeof(HistogramContext),
+    .init          = init,
+    .uninit        = uninit,
+    .query_formats = query_formats,
+    .inputs        = inputs,
+    .outputs       = outputs,
+    .priv_class    = &histogram_class,
+};
diff --git a/libavfilter/vf_hqdn3d.c b/libavfilter/vf_hqdn3d.c
index 939a31d..4381586 100644
--- a/libavfilter/vf_hqdn3d.c
+++ b/libavfilter/vf_hqdn3d.c
@@ -26,6 +26,7 @@
  * libmpcodecs/vf_hqdn3d.c.
  */
 
+#include "config.h"
 #include "libavutil/common.h"
 #include "libavutil/pixdesc.h"
 #include "libavutil/intreadwrite.h"
@@ -33,21 +34,7 @@
 #include "formats.h"
 #include "internal.h"
 #include "video.h"
-
-typedef struct {
-    int16_t *coefs[4];
-    uint16_t *line;
-    uint16_t *frame_prev[3];
-    double strength[4];
-    int hsub, vsub;
-    int depth;
-    void (*denoise_row[17])(uint8_t *src, uint8_t *dst, uint16_t *line_ant, uint16_t *frame_ant, ptrdiff_t w, int16_t *spatial, int16_t *temporal);
-} HQDN3DContext;
-
-void ff_hqdn3d_row_8_x86(uint8_t *src, uint8_t *dst, uint16_t *line_ant, uint16_t *frame_ant, ptrdiff_t w, int16_t *spatial, int16_t *temporal);
-void ff_hqdn3d_row_9_x86(uint8_t *src, uint8_t *dst, uint16_t *line_ant, uint16_t *frame_ant, ptrdiff_t w, int16_t *spatial, int16_t *temporal);
-void ff_hqdn3d_row_10_x86(uint8_t *src, uint8_t *dst, uint16_t *line_ant, uint16_t *frame_ant, ptrdiff_t w, int16_t *spatial, int16_t *temporal);
-void ff_hqdn3d_row_16_x86(uint8_t *src, uint8_t *dst, uint16_t *line_ant, uint16_t *frame_ant, ptrdiff_t w, int16_t *spatial, int16_t *temporal);
+#include "vf_hqdn3d.h"
 
 #define LUT_BITS (depth==16 ? 8 : 4)
 #define LOAD(x) (((depth==8 ? src[x] : AV_RN16A(src+(x)*2)) << (16-depth)) + (((1<<(16-depth))-1)>>1))
@@ -235,7 +222,7 @@
     hqdn3d->strength[2] = chrom_spac;
     hqdn3d->strength[3] = chrom_tmp;
 
-    av_log(ctx, AV_LOG_VERBOSE, "ls:%lf cs:%lf lt:%lf ct:%lf\n",
+    av_log(ctx, AV_LOG_VERBOSE, "ls:%f cs:%f lt:%f ct:%f\n",
            lum_spac, chrom_spac, lum_tmp, chrom_tmp);
     if (lum_spac < 0 || chrom_spac < 0 || isnan(chrom_tmp)) {
         av_log(ctx, AV_LOG_ERROR,
@@ -311,12 +298,8 @@
             return AVERROR(ENOMEM);
     }
 
-#if HAVE_YASM
-    hqdn3d->denoise_row[ 8] = ff_hqdn3d_row_8_x86;
-    hqdn3d->denoise_row[ 9] = ff_hqdn3d_row_9_x86;
-    hqdn3d->denoise_row[10] = ff_hqdn3d_row_10_x86;
-    hqdn3d->denoise_row[16] = ff_hqdn3d_row_16_x86;
-#endif
+    if (ARCH_X86)
+        ff_hqdn3d_init_x86(hqdn3d);
 
     return 0;
 }
@@ -338,10 +321,7 @@
             avfilter_unref_bufferp(&in);
             return AVERROR(ENOMEM);
         }
-
         avfilter_copy_buffer_ref_props(out, in);
-        out->video->w = outlink->w;
-        out->video->h = outlink->h;
     }
 
     for (c = 0; c < 3; c++) {
diff --git a/libavfilter/vf_hqdn3d.h b/libavfilter/vf_hqdn3d.h
new file mode 100644
index 0000000..dfc69e1
--- /dev/null
+++ b/libavfilter/vf_hqdn3d.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2003 Daniel Moreno <comac AT comac DOT darktech DOT org>
+ * Copyright (c) 2010 Baptiste Coudurier
+ * Copyright (c) 2012 Loren Merritt
+ *
+ * This file is part of FFmpeg, ported from MPlayer.
+ *
+ * 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_VF_HQDN3D_H
+#define AVFILTER_VF_HQDN3D_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+typedef struct {
+    int16_t *coefs[4];
+    uint16_t *line;
+    uint16_t *frame_prev[3];
+    double strength[4];
+    int hsub, vsub;
+    int depth;
+    void (*denoise_row[17])(uint8_t *src, uint8_t *dst, uint16_t *line_ant, uint16_t *frame_ant, ptrdiff_t w, int16_t *spatial, int16_t *temporal);
+} HQDN3DContext;
+
+void ff_hqdn3d_init_x86(HQDN3DContext *hqdn3d);
+
+#endif /* AVFILTER_VF_HQDN3D_H */
diff --git a/libavfilter/vf_hue.c b/libavfilter/vf_hue.c
index 7bc3d37..59fc62c 100644
--- a/libavfilter/vf_hue.c
+++ b/libavfilter/vf_hue.c
@@ -130,75 +130,44 @@
 static inline int set_options(AVFilterContext *ctx, const char *args)
 {
     HueContext *hue = ctx->priv;
-    int n, ret;
-    char c1 = 0, c2 = 0;
+    int ret;
     char   *old_hue_expr,  *old_hue_deg_expr,  *old_saturation_expr;
     AVExpr *old_hue_pexpr, *old_hue_deg_pexpr, *old_saturation_pexpr;
+    static const char *shorthand[] = { "h", "s", NULL };
+    old_hue_expr        = hue->hue_expr;
+    old_hue_deg_expr    = hue->hue_deg_expr;
+    old_saturation_expr = hue->saturation_expr;
 
-    if (args) {
-        /* named options syntax */
-        if (strchr(args, '=')) {
-            old_hue_expr        = hue->hue_expr;
-            old_hue_deg_expr    = hue->hue_deg_expr;
-            old_saturation_expr = hue->saturation_expr;
+    old_hue_pexpr        = hue->hue_pexpr;
+    old_hue_deg_pexpr    = hue->hue_deg_pexpr;
+    old_saturation_pexpr = hue->saturation_pexpr;
 
-            old_hue_pexpr        = hue->hue_pexpr;
-            old_hue_deg_pexpr    = hue->hue_deg_pexpr;
-            old_saturation_pexpr = hue->saturation_pexpr;
+    hue->hue_expr     = NULL;
+    hue->hue_deg_expr = NULL;
+    hue->saturation_expr = NULL;
 
-            hue->hue_expr     = NULL;
-            hue->hue_deg_expr = NULL;
-            hue->saturation_expr = NULL;
+    if ((ret = av_opt_set_from_string(hue, args, shorthand, "=", ":")) < 0)
+        return ret;
+    if (hue->hue_expr && hue->hue_deg_expr) {
+        av_log(ctx, AV_LOG_ERROR,
+               "H and h options are incompatible and cannot be specified "
+               "at the same time\n");
+        hue->hue_expr     = old_hue_expr;
+        hue->hue_deg_expr = old_hue_deg_expr;
 
-            if ((ret = av_set_options_string(hue, args, "=", ":")) < 0)
-                return ret;
-            if (hue->hue_expr && hue->hue_deg_expr) {
-                av_log(ctx, AV_LOG_ERROR,
-                       "H and h options are incompatible and cannot be specified "
-                       "at the same time\n");
-                hue->hue_expr     = old_hue_expr;
-                hue->hue_deg_expr = old_hue_deg_expr;
-
-                return AVERROR(EINVAL);
-            }
-
-            SET_EXPRESSION(hue_deg, h);
-            SET_EXPRESSION(hue, H);
-            SET_EXPRESSION(saturation, s);
-
-            hue->flat_syntax = 0;
-
-            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);
-
-        /* compatibility h:s syntax */
-        } else {
-            n = sscanf(args, "%f%c%f%c", &hue->hue_deg, &c1, &hue->saturation, &c2);
-            if (n != 1 && (n != 3 || c1 != ':')) {
-                av_log(ctx, AV_LOG_ERROR,
-                       "Invalid syntax for argument '%s': "
-                       "must be in the form 'hue[:saturation]'\n", args);
-                return AVERROR(EINVAL);
-            }
-
-            if (hue->saturation < SAT_MIN_VAL || hue->saturation > SAT_MAX_VAL) {
-                av_log(ctx, AV_LOG_ERROR,
-                       "Invalid value for saturation %0.1f: "
-                       "must be included between range %d and +%d\n",
-                       hue->saturation, SAT_MIN_VAL, SAT_MAX_VAL);
-                return AVERROR(EINVAL);
-            }
-
-            hue->hue = hue->hue_deg * M_PI / 180;
-            hue->flat_syntax = 1;
-
-            av_log(ctx, AV_LOG_VERBOSE,
-                   "H:%0.1f h:%0.1f s:%0.1f\n",
-                   hue->hue, hue->hue_deg, hue->saturation);
-        }
+        return AVERROR(EINVAL);
     }
 
+    SET_EXPRESSION(hue_deg, h);
+    SET_EXPRESSION(hue, H);
+    SET_EXPRESSION(saturation, s);
+
+    hue->flat_syntax = 0;
+
+    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);
+
     compute_sin_and_cos(hue);
 
     return 0;
diff --git a/libavfilter/vf_idet.c b/libavfilter/vf_idet.c
index cc20fac..5023630 100644
--- a/libavfilter/vf_idet.c
+++ b/libavfilter/vf_idet.c
@@ -18,15 +18,15 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <float.h> /* FLT_MAX */
+
 #include "libavutil/cpu.h"
 #include "libavutil/common.h"
+#include "libavutil/opt.h"
 #include "libavutil/pixdesc.h"
 #include "avfilter.h"
 #include "internal.h"
 
-#undef NDEBUG
-#include <assert.h>
-
 #define HIST_SIZE 4
 
 typedef enum {
@@ -37,12 +37,13 @@
 } Type;
 
 typedef struct {
+    const AVClass *class;
     float interlace_threshold;
     float progressive_threshold;
 
     Type last_type;
-    Type prestat[4];
-    Type poststat[4];
+    int prestat[4];
+    int poststat[4];
 
     uint8_t history[HIST_SIZE];
 
@@ -54,6 +55,17 @@
     const AVPixFmtDescriptor *csp;
 } IDETContext;
 
+#define OFFSET(x) offsetof(IDETContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
+
+static const AVOption idet_options[] = {
+    { "intl_thres", "set interlacing threshold", OFFSET(interlace_threshold),   AV_OPT_TYPE_FLOAT, {.dbl = 1.04}, -1, FLT_MAX, FLAGS },
+    { "prog_thres", "set progressive threshold", OFFSET(progressive_threshold), AV_OPT_TYPE_FLOAT, {.dbl = 1.5},  -1, FLT_MAX, FLAGS },
+    { NULL }
+};
+
+AVFILTER_DEFINE_CLASS(idet);
+
 static const char *type2str(Type type)
 {
     switch(type) {
@@ -71,7 +83,8 @@
     int ret=0;
 
     for(x=0; x<w; x++){
-        ret += FFABS((*a++ + *c++) - 2 * *b++);
+        int v = (*a++ + *c++) - 2 * *b++;
+        ret += FFABS(v);
     }
 
     return ret;
@@ -83,7 +96,8 @@
     int ret=0;
 
     for(x=0; x<w; x++){
-        ret += FFABS((*a++ + *c++) - 2 * *b++);
+        int v = (*a++ + *c++) - 2 * *b++;
+        ret += FFABS(v);
     }
 
     return ret;
@@ -165,7 +179,7 @@
     av_log(ctx, AV_LOG_DEBUG, "Single frame:%s, Multi frame:%s\n", type2str(type), type2str(idet->last_type));
 }
 
-static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
+static int filter_frame(AVFilterLink *link, AVFilterBufferRef *picref)
 {
     AVFilterContext *ctx = link->dst;
     IDETContext *idet = ctx->priv;
@@ -175,7 +189,6 @@
     idet->prev = idet->cur;
     idet->cur  = idet->next;
     idet->next = picref;
-    link->cur_buf = NULL;
 
     if (!idet->cur)
         return 0;
@@ -183,17 +196,6 @@
     if (!idet->prev)
         idet->prev = avfilter_ref_buffer(idet->cur, ~0);
 
-    return ff_start_frame(ctx->outputs[0], avfilter_ref_buffer(idet->cur, ~0));
-}
-
-static int end_frame(AVFilterLink *link)
-{
-    AVFilterContext *ctx = link->dst;
-    IDETContext *idet = ctx->priv;
-
-    if (!idet->cur)
-        return 0;
-
     if (!idet->csp)
         idet->csp = av_pix_fmt_desc_get(link->format);
     if (idet->csp->comp[0].depth_minus1 / 8 == 1)
@@ -201,8 +203,7 @@
 
     filter(ctx);
 
-    ff_draw_slice(ctx->outputs[0], 0, link->h, 1);
-    return ff_end_frame(ctx->outputs[0]);
+    return ff_filter_frame(ctx->outputs[0], avfilter_ref_buffer(idet->cur, ~0));
 }
 
 static int request_frame(AVFilterLink *link)
@@ -220,23 +221,6 @@
     return 0;
 }
 
-static int poll_frame(AVFilterLink *link)
-{
-    IDETContext *idet = link->src->priv;
-    int ret, val;
-
-    val = ff_poll_frame(link->src->inputs[0]);
-
-    if (val >= 1 && !idet->next) { //FIXME change API to not requre this red tape
-        if ((ret = ff_request_frame(link->src->inputs[0])) < 0)
-            return ret;
-        val = ff_poll_frame(link->src->inputs[0]);
-    }
-    assert(idet->next || !val);
-
-    return val;
-}
-
 static av_cold void uninit(AVFilterContext *ctx)
 {
     IDETContext *idet = ctx->priv;
@@ -292,13 +276,14 @@
 static av_cold int init(AVFilterContext *ctx, const char *args)
 {
     IDETContext *idet = ctx->priv;
+    static const char *shorthand[] = { "intl_thres", "prog_thres", NULL };
+    int ret;
 
-    idet->csp = NULL;
+    idet->class = &idet_class;
+    av_opt_set_defaults(idet);
 
-    idet->interlace_threshold   = 1.01;
-    idet->progressive_threshold = 2.5;
-
-    if (args) sscanf(args, "%f:%f", &idet->interlace_threshold, &idet->progressive_threshold);
+    if ((ret = av_opt_set_from_string(idet, args, shorthand, "=", ":")) < 0)
+        return ret;
 
     idet->last_type = UNDETERMINED;
     memset(idet->history, UNDETERMINED, HIST_SIZE);
@@ -308,15 +293,12 @@
     return 0;
 }
 
-static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { return 0; }
 
 static const AVFilterPad idet_inputs[] = {
     {
         .name         = "default",
         .type         = AVMEDIA_TYPE_VIDEO,
-        .start_frame  = start_frame,
-        .draw_slice   = null_draw_slice,
-        .end_frame    = end_frame,
+        .filter_frame = filter_frame,
         .min_perms    = AV_PERM_PRESERVE,
     },
     { NULL }
@@ -327,7 +309,6 @@
         .name          = "default",
         .type          = AVMEDIA_TYPE_VIDEO,
         .rej_perms     = AV_PERM_WRITE,
-        .poll_frame    = poll_frame,
         .request_frame = request_frame,
     },
     { NULL }
@@ -343,4 +324,5 @@
     .query_formats = query_formats,
     .inputs        = idet_inputs,
     .outputs       = idet_outputs,
+    .priv_class    = &idet_class,
 };
diff --git a/libavfilter/vf_il.c b/libavfilter/vf_il.c
new file mode 100644
index 0000000..44b5a3b
--- /dev/null
+++ b/libavfilter/vf_il.c
@@ -0,0 +1,230 @@
+/*
+ * 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 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
+ * (de)interleave fields filter
+ */
+
+#include "libavutil/opt.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/pixdesc.h"
+#include "avfilter.h"
+#include "internal.h"
+
+enum FilterMode {
+    MODE_NONE,
+    MODE_INTERLEAVE,
+    MODE_DEINTERLEAVE
+};
+
+typedef struct {
+    const AVClass *class;
+    enum FilterMode luma_mode, chroma_mode, alpha_mode;
+    int luma_swap, chroma_swap, alpha_swap;
+    int nb_planes;
+    int linesize[4], chroma_height;
+    int has_alpha;
+} IlContext;
+
+#define OFFSET(x) offsetof(IlContext, x)
+#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
+
+static const AVOption il_options[] = {
+    {"luma_mode",   "select luma mode", OFFSET(luma_mode), AV_OPT_TYPE_INT, {.i64=MODE_NONE}, MODE_NONE, MODE_DEINTERLEAVE, FLAGS, "luma_mode"},
+    {"l",           "select luma mode", OFFSET(luma_mode), AV_OPT_TYPE_INT, {.i64=MODE_NONE}, MODE_NONE, MODE_DEINTERLEAVE, FLAGS, "luma_mode"},
+    {"none",         NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_NONE},         0, 0, FLAGS, "luma_mode"},
+    {"interleave",   NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_INTERLEAVE},   0, 0, FLAGS, "luma_mode"},
+    {"i",            NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_INTERLEAVE},   0, 0, FLAGS, "luma_mode"},
+    {"deinterleave", NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_DEINTERLEAVE}, 0, 0, FLAGS, "luma_mode"},
+    {"d",            NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_DEINTERLEAVE}, 0, 0, FLAGS, "luma_mode"},
+    {"chroma_mode", "select chroma mode", OFFSET(chroma_mode), AV_OPT_TYPE_INT, {.i64=MODE_NONE}, MODE_NONE, MODE_DEINTERLEAVE, FLAGS, "chroma_mode"},
+    {"c",           "select chroma mode", OFFSET(chroma_mode), AV_OPT_TYPE_INT, {.i64=MODE_NONE}, MODE_NONE, MODE_DEINTERLEAVE, FLAGS, "chroma_mode"},
+    {"none",         NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_NONE},         0, 0, FLAGS, "chroma_mode"},
+    {"interleave",   NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_INTERLEAVE},   0, 0, FLAGS, "chroma_mode"},
+    {"i",            NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_INTERLEAVE},   0, 0, FLAGS, "chroma_mode"},
+    {"deinterleave", NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_DEINTERLEAVE}, 0, 0, FLAGS, "chroma_mode"},
+    {"d",            NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_DEINTERLEAVE}, 0, 0, FLAGS, "chroma_mode"},
+    {"alpha_mode", "select alpha mode", OFFSET(alpha_mode), AV_OPT_TYPE_INT, {.i64=MODE_NONE}, MODE_NONE, MODE_DEINTERLEAVE, FLAGS, "alpha_mode"},
+    {"a",          "select alpha mode", OFFSET(alpha_mode), AV_OPT_TYPE_INT, {.i64=MODE_NONE}, MODE_NONE, MODE_DEINTERLEAVE, FLAGS, "alpha_mode"},
+    {"none",         NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_NONE},         0, 0, FLAGS, "alpha_mode"},
+    {"interleave",   NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_INTERLEAVE},   0, 0, FLAGS, "alpha_mode"},
+    {"i",            NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_INTERLEAVE},   0, 0, FLAGS, "alpha_mode"},
+    {"deinterleave", NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_DEINTERLEAVE}, 0, 0, FLAGS, "alpha_mode"},
+    {"d",            NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_DEINTERLEAVE}, 0, 0, FLAGS, "alpha_mode"},
+    {"luma_swap",   "swap luma fields",   OFFSET(luma_swap),   AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS},
+    {"ls",          "swap luma fields",   OFFSET(luma_swap),   AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS},
+    {"chroma_swap", "swap chroma fields", OFFSET(chroma_swap), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS},
+    {"cs",          "swap chroma fields", OFFSET(chroma_swap), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS},
+    {"alpha_swap",  "swap alpha fields",  OFFSET(alpha_swap),  AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS},
+    {"as",          "swap alpha fields",  OFFSET(alpha_swap),  AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS},
+    {NULL}
+};
+
+AVFILTER_DEFINE_CLASS(il);
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    IlContext *il = ctx->priv;
+    int ret;
+
+    il->class = &il_class;
+    av_opt_set_defaults(il);
+
+    if ((ret = av_set_options_string(il, args, "=", ":")) < 0)
+        return ret;
+
+    return 0;
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    AVFilterFormats *formats = NULL;
+    int fmt;
+
+    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))
+            ff_add_format(&formats, fmt);
+    }
+
+    ff_set_common_formats(ctx, formats);
+    return 0;
+}
+
+static int config_input(AVFilterLink *inlink)
+{
+    IlContext *il = inlink->dst->priv;
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
+    int i, ret;
+
+    for (i = 0; i < desc->nb_components; i++)
+        il->nb_planes = FFMAX(il->nb_planes, desc->comp[i].plane);
+    il->nb_planes++;
+
+    il->has_alpha = !!(desc->flags & PIX_FMT_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;
+
+    return 0;
+}
+
+static void interleave(uint8_t *dst, uint8_t *src, int w, int h,
+                       int dst_linesize, int src_linesize,
+                       enum FilterMode mode, int swap)
+{
+    const int a = swap;
+    const int b = 1 - a;
+    const int m = h >> 1;
+    int y;
+
+    switch (mode) {
+    case MODE_DEINTERLEAVE:
+        for (y = 0; y < m; y++) {
+            memcpy(dst + dst_linesize *  y     , src + src_linesize * (y * 2 + a), w);
+            memcpy(dst + dst_linesize * (y + m), src + src_linesize * (y * 2 + b), w);
+        }
+        break;
+    case MODE_NONE:
+        for (y = 0; y < m; y++) {
+            memcpy(dst + dst_linesize *  y * 2     , src + src_linesize * (y * 2 + a), w);
+            memcpy(dst + dst_linesize * (y * 2 + 1), src + src_linesize * (y * 2 + b), w);
+        }
+        break;
+    case MODE_INTERLEAVE:
+        for (y = 0; y < m; y++) {
+            memcpy(dst + dst_linesize * (y * 2 + a), src + src_linesize *  y     , w);
+            memcpy(dst + dst_linesize * (y * 2 + b), src + src_linesize * (y + m), w);
+        }
+        break;
+    }
+}
+
+static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
+{
+    IlContext *il = inlink->dst->priv;
+    AVFilterLink *outlink = inlink->dst->outputs[0];
+    AVFilterBufferRef *out;
+    int ret, comp;
+
+    out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
+    if (!out) {
+        avfilter_unref_bufferp(&inpicref);
+        return AVERROR(ENOMEM);
+    }
+    avfilter_copy_buffer_ref_props(out, inpicref);
+
+    interleave(out->data[0], inpicref->data[0],
+               il->linesize[0], inlink->h,
+               out->linesize[0], inpicref->linesize[0],
+               il->luma_mode, il->luma_swap);
+
+    for (comp = 1; comp < (il->nb_planes - il->has_alpha); comp++) {
+        interleave(out->data[comp], inpicref->data[comp],
+                   il->linesize[comp], il->chroma_height,
+                   out->linesize[comp], inpicref->linesize[comp],
+                   il->chroma_mode, il->chroma_swap);
+    }
+
+    if (il->has_alpha) {
+        int comp = il->nb_planes - 1;
+        interleave(out->data[comp], inpicref->data[comp],
+                   il->linesize[comp], inlink->h,
+                   out->linesize[comp], inpicref->linesize[comp],
+                   il->alpha_mode, il->alpha_swap);
+    }
+
+    ret = ff_filter_frame(outlink, out);
+    avfilter_unref_bufferp(&inpicref);
+    return ret;
+}
+
+static const AVFilterPad inputs[] = {
+    {
+        .name             = "default",
+        .type             = AVMEDIA_TYPE_VIDEO,
+        .get_video_buffer = ff_null_get_video_buffer,
+        .filter_frame     = filter_frame,
+        .config_props     = config_input,
+    },
+    { NULL }
+};
+
+static const AVFilterPad outputs[] = {
+    {
+        .name          = "default",
+        .type          = AVMEDIA_TYPE_VIDEO,
+    },
+    { NULL }
+};
+
+AVFilter avfilter_vf_il = {
+    .name          = "il",
+    .description   = NULL_IF_CONFIG_SMALL("Deinterleave or interleave fields."),
+    .priv_size     = sizeof(IlContext),
+    .init          = init,
+    .query_formats = query_formats,
+    .inputs        = inputs,
+    .outputs       = outputs,
+    .priv_class    = &il_class,
+};
diff --git a/libavfilter/vf_kerndeint.c b/libavfilter/vf_kerndeint.c
new file mode 100644
index 0000000..9b77e09
--- /dev/null
+++ b/libavfilter/vf_kerndeint.c
@@ -0,0 +1,333 @@
+/*
+ * Copyright (c) 2012 Jeremy Tran
+ * Copyright (c) 2004 Tobias Diedrich
+ * Copyright (c) 2003 Donald A. Graft
+ *
+ * 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
+ * Kernel Deinterlacer
+ * Ported from MPlayer libmpcodecs/vf_kerndeint.c.
+ */
+
+#include "libavutil/imgutils.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/opt.h"
+#include "libavutil/pixdesc.h"
+
+#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
+
+typedef struct {
+    const AVClass *class;
+    int           frame; ///< frame count, starting from 0
+    int           thresh, map, order, sharp, twoway;
+    int           vsub;
+    int           is_packed_rgb;
+    uint8_t       *tmp_data    [4];  ///< temporary plane data buffer
+    int            tmp_linesize[4];  ///< temporary plane byte linesize
+    int            tmp_bwidth  [4];  ///< temporary plane byte width
+} KerndeintContext;
+
+#define OFFSET(x) offsetof(KerndeintContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
+static const AVOption kerndeint_options[] = {
+    { "thresh", "set the threshold", OFFSET(thresh), AV_OPT_TYPE_INT, {.i64=10}, 0, 255, FLAGS },
+    { "map",    "set the map", OFFSET(map), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS },
+    { "order",  "set the order", OFFSET(order), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS },
+    { "sharp",  "enable sharpening", OFFSET(sharp), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS },
+    { "twoway", "enable twoway", OFFSET(twoway), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS },
+    { NULL }
+};
+
+AVFILTER_DEFINE_CLASS(kerndeint);
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    KerndeintContext *kerndeint = ctx->priv;
+    const char const * shorthand[] = { "thresh", "map", "order", "sharp", "twoway", NULL };
+
+    kerndeint->class = &kerndeint_class;
+    av_opt_set_defaults(kerndeint);
+
+    return av_opt_set_from_string(kerndeint, args, shorthand, "=", ":");
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    KerndeintContext *kerndeint = ctx->priv;
+
+    av_free(kerndeint->tmp_data[0]);
+    av_opt_free(kerndeint);
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    static const enum PixelFormat pix_fmts[] = {
+        AV_PIX_FMT_YUV420P,
+        AV_PIX_FMT_YUYV422,
+        AV_PIX_FMT_ARGB, AV_PIX_FMT_0RGB,
+        AV_PIX_FMT_ABGR, AV_PIX_FMT_0BGR,
+        AV_PIX_FMT_RGBA, AV_PIX_FMT_RGB0,
+        AV_PIX_FMT_BGRA, AV_PIX_FMT_BGR0,
+        AV_PIX_FMT_NONE
+    };
+
+    ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
+
+    return 0;
+}
+
+static int config_props(AVFilterLink *inlink)
+{
+    KerndeintContext *kerndeint = inlink->dst->priv;
+    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->vsub = desc->log2_chroma_h;
+
+    ret = av_image_alloc(kerndeint->tmp_data, kerndeint->tmp_linesize,
+                         inlink->w, inlink->h, inlink->format, 16);
+    if (ret < 0)
+        return ret;
+    memset(kerndeint->tmp_data[0], 0, ret);
+
+    if ((ret = av_image_fill_linesizes(kerndeint->tmp_bwidth, inlink->format, inlink->w)) < 0)
+        return ret;
+
+    return 0;
+}
+
+static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *inpic)
+{
+    KerndeintContext *kerndeint = inlink->dst->priv;
+    AVFilterLink *outlink = inlink->dst->outputs[0];
+    AVFilterBufferRef *outpic;
+    const uint8_t *prvp;   ///< Previous field's pixel line number n
+    const uint8_t *prvpp;  ///< Previous field's pixel line number (n - 1)
+    const uint8_t *prvpn;  ///< Previous field's pixel line number (n + 1)
+    const uint8_t *prvppp; ///< Previous field's pixel line number (n - 2)
+    const uint8_t *prvpnn; ///< Previous field's pixel line number (n + 2)
+    const uint8_t *prvp4p; ///< Previous field's pixel line number (n - 4)
+    const uint8_t *prvp4n; ///< Previous field's pixel line number (n + 4)
+
+    const uint8_t *srcp;   ///< Current field's pixel line number n
+    const uint8_t *srcpp;  ///< Current field's pixel line number (n - 1)
+    const uint8_t *srcpn;  ///< Current field's pixel line number (n + 1)
+    const uint8_t *srcppp; ///< Current field's pixel line number (n - 2)
+    const uint8_t *srcpnn; ///< Current field's pixel line number (n + 2)
+    const uint8_t *srcp3p; ///< Current field's pixel line number (n - 3)
+    const uint8_t *srcp3n; ///< Current field's pixel line number (n + 3)
+    const uint8_t *srcp4p; ///< Current field's pixel line number (n - 4)
+    const uint8_t *srcp4n; ///< Current field's pixel line number (n + 4)
+
+    uint8_t *dstp, *dstp_saved;
+    const uint8_t *srcp_saved;
+
+    int src_linesize, psrc_linesize, dst_linesize, bwidth;
+    int x, y, plane, val, hi, lo, g, h, n = kerndeint->frame++;
+    double valf;
+
+    const int thresh = kerndeint->thresh;
+    const int order  = kerndeint->order;
+    const int map    = kerndeint->map;
+    const int sharp  = kerndeint->sharp;
+    const int twoway = kerndeint->twoway;
+
+    const int is_packed_rgb = kerndeint->is_packed_rgb;
+
+    outpic = ff_get_video_buffer(outlink, AV_PERM_WRITE|AV_PERM_ALIGN, outlink->w, outlink->h);
+    if (!outpic) {
+        avfilter_unref_bufferp(&inpic);
+        return AVERROR(ENOMEM);
+    }
+    avfilter_copy_buffer_ref_props(outpic, inpic);
+    outpic->video->interlaced = 0;
+
+    for (plane = 0; inpic->data[plane] && plane < 4; plane++) {
+        h = plane == 0 ? inlink->h : inlink->h >> kerndeint->vsub;
+        bwidth = kerndeint->tmp_bwidth[plane];
+
+        srcp = srcp_saved = inpic->data[plane];
+        src_linesize      = inpic->linesize[plane];
+        psrc_linesize     = kerndeint->tmp_linesize[plane];
+        dstp = dstp_saved = outpic->data[plane];
+        dst_linesize      = outpic->linesize[plane];
+        srcp              = srcp_saved + (1 - order) * src_linesize;
+        dstp              = dstp_saved + (1 - order) * dst_linesize;
+
+        for (y = 0; y < h; y += 2) {
+            memcpy(dstp, srcp, bwidth);
+            srcp += 2 * src_linesize;
+            dstp += 2 * dst_linesize;
+        }
+
+        // Copy through the lines that will be missed below.
+        memcpy(dstp_saved + order            * dst_linesize, srcp_saved + (1 -     order) * src_linesize, bwidth);
+        memcpy(dstp_saved + (2 + order    )  * dst_linesize, srcp_saved + (3 -     order) * src_linesize, bwidth);
+        memcpy(dstp_saved + (h - 2 + order)  * dst_linesize, srcp_saved + (h - 1 - order) * src_linesize, bwidth);
+        memcpy(dstp_saved + (h - 4 + order)  * dst_linesize, srcp_saved + (h - 3 - order) * src_linesize, bwidth);
+
+        /* For the other field choose adaptively between using the previous field
+           or the interpolant from the current field. */
+        prvp   = kerndeint->tmp_data[plane] + 5 * psrc_linesize - (1 - order) * psrc_linesize;
+        prvpp  = prvp - psrc_linesize;
+        prvppp = prvp - 2 * psrc_linesize;
+        prvp4p = prvp - 4 * psrc_linesize;
+        prvpn  = prvp + psrc_linesize;
+        prvpnn = prvp + 2 * psrc_linesize;
+        prvp4n = prvp + 4 * psrc_linesize;
+
+        srcp   = srcp_saved + 5 * src_linesize - (1 - order) * src_linesize;
+        srcpp  = srcp - src_linesize;
+        srcppp = srcp - 2 * src_linesize;
+        srcp3p = srcp - 3 * src_linesize;
+        srcp4p = srcp - 4 * src_linesize;
+
+        srcpn  = srcp + src_linesize;
+        srcpnn = srcp + 2 * src_linesize;
+        srcp3n = srcp + 3 * src_linesize;
+        srcp4n = srcp + 4 * src_linesize;
+
+        dstp   = dstp_saved + 5 * dst_linesize - (1 - order) * dst_linesize;
+
+        for (y = 5 - (1 - order); y <= h - 5 - (1 - order); y += 2) {
+            for (x = 0; x < bwidth; x++) {
+                if (thresh == 0 || n == 0 ||
+                    (abs((int)prvp[x]  - (int)srcp[x])  > thresh) ||
+                    (abs((int)prvpp[x] - (int)srcpp[x]) > thresh) ||
+                    (abs((int)prvpn[x] - (int)srcpn[x]) > thresh)) {
+                    if (map) {
+                        g = x & ~3;
+
+                        if (is_packed_rgb) {
+                            AV_WB32(dstp + g, 0xffffffff);
+                            x = g + 3;
+                        } else if (inlink->format == AV_PIX_FMT_YUYV422) {
+                            // y <- 235, u <- 128, y <- 235, v <- 128
+                            AV_WB32(dstp + g, 0xeb80eb80);
+                            x = g + 3;
+                        } else {
+                            dstp[x] = plane == 0 ? 235 : 128;
+                        }
+                    } else {
+                        if (is_packed_rgb) {
+                            hi = 255;
+                            lo = 0;
+                        } else if (inlink->format == AV_PIX_FMT_YUYV422) {
+                            hi = x & 1 ? 240 : 235;
+                            lo = 16;
+                        } else {
+                            hi = plane == 0 ? 235 : 240;
+                            lo = 16;
+                        }
+
+                        if (sharp) {
+                            if (twoway) {
+                                valf = + 0.526 * ((int)srcpp[x] + (int)srcpn[x])
+                                    + 0.170 * ((int)srcp[x] + (int)prvp[x])
+                                    - 0.116 * ((int)srcppp[x] + (int)srcpnn[x] + (int)prvppp[x] + (int)prvpnn[x])
+                                    - 0.026 * ((int)srcp3p[x] + (int)srcp3n[x])
+                                    + 0.031 * ((int)srcp4p[x] + (int)srcp4n[x] + (int)prvp4p[x] + (int)prvp4n[x]);
+                            } else {
+                                valf = + 0.526 * ((int)srcpp[x] + (int)srcpn[x])
+                                    + 0.170 * ((int)prvp[x])
+                                    - 0.116 * ((int)prvppp[x] + (int)prvpnn[x])
+                                    - 0.026 * ((int)srcp3p[x] + (int)srcp3n[x])
+                                    + 0.031 * ((int)prvp4p[x] + (int)prvp4p[x]);
+                            }
+                            dstp[x] = av_clip(valf, lo, hi);
+                        } else {
+                            if (twoway) {
+                                val = (8 * ((int)srcpp[x] + (int)srcpn[x]) + 2 * ((int)srcp[x] + (int)prvp[x])
+                                       - (int)(srcppp[x]) - (int)(srcpnn[x])
+                                       - (int)(prvppp[x]) - (int)(prvpnn[x])) >> 4;
+                            } else {
+                                val = (8 * ((int)srcpp[x] + (int)srcpn[x]) + 2 * ((int)prvp[x])
+                                       - (int)(prvppp[x]) - (int)(prvpnn[x])) >> 4;
+                            }
+                            dstp[x] = av_clip(val, lo, hi);
+                        }
+                    }
+                } else {
+                    dstp[x] = srcp[x];
+                }
+            }
+            prvp   += 2 * psrc_linesize;
+            prvpp  += 2 * psrc_linesize;
+            prvppp += 2 * psrc_linesize;
+            prvpn  += 2 * psrc_linesize;
+            prvpnn += 2 * psrc_linesize;
+            prvp4p += 2 * psrc_linesize;
+            prvp4n += 2 * psrc_linesize;
+            srcp   += 2 * src_linesize;
+            srcpp  += 2 * src_linesize;
+            srcppp += 2 * src_linesize;
+            srcp3p += 2 * src_linesize;
+            srcp4p += 2 * src_linesize;
+            srcpn  += 2 * src_linesize;
+            srcpnn += 2 * src_linesize;
+            srcp3n += 2 * src_linesize;
+            srcp4n += 2 * src_linesize;
+            dstp   += 2 * dst_linesize;
+        }
+
+        srcp = inpic->data[plane];
+        dstp = kerndeint->tmp_data[plane];
+        av_image_copy_plane(dstp, psrc_linesize, srcp, src_linesize, bwidth, h);
+    }
+
+    avfilter_unref_buffer(inpic);
+    return ff_filter_frame(outlink, outpic);
+}
+
+static const AVFilterPad kerndeint_inputs[] = {
+    {
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_VIDEO,
+        .filter_frame = filter_frame,
+        .config_props = config_props,
+        .min_perms    = AV_PERM_READ,
+    },
+    { NULL }
+};
+
+static const AVFilterPad kerndeint_outputs[] = {
+    {
+        .name = "default",
+        .type = AVMEDIA_TYPE_VIDEO,
+    },
+    { NULL }
+};
+
+AVFilter avfilter_vf_kerndeint = {
+    .name          = "kerndeint",
+    .description   = NULL_IF_CONFIG_SMALL("Apply kernel deinterlacing to the input."),
+    .priv_size     = sizeof(KerndeintContext),
+    .init          = init,
+    .uninit        = uninit,
+    .query_formats = query_formats,
+
+    .inputs        = kerndeint_inputs,
+    .outputs       = kerndeint_outputs,
+
+    .priv_class = &kerndeint_class,
+};
diff --git a/libavfilter/vf_lut.c b/libavfilter/vf_lut.c
index 543785a..bdfe712 100644
--- a/libavfilter/vf_lut.c
+++ b/libavfilter/vf_lut.c
@@ -29,6 +29,7 @@
 #include "libavutil/opt.h"
 #include "libavutil/pixdesc.h"
 #include "avfilter.h"
+#include "drawutils.h"
 #include "formats.h"
 #include "internal.h"
 #include "video.h"
@@ -175,9 +176,9 @@
     AVFilterContext *ctx = inlink->dst;
     LutContext *lut = ctx->priv;
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
-    int rgba_map[4]; /* component index -> RGBA color index map */
+    uint8_t rgba_map[4]; /* component index -> RGBA color index map */
     int min[4], max[4];
-    int val, comp, ret;
+    int val, color, ret;
 
     lut->hsub = desc->log2_chroma_w;
     lut->vsub = desc->log2_chroma_h;
@@ -208,20 +209,13 @@
     else if (ff_fmt_is_in(inlink->format, rgb_pix_fmts)) lut->is_rgb = 1;
 
     if (lut->is_rgb) {
-        switch (inlink->format) {
-        case AV_PIX_FMT_ARGB:  rgba_map[0] = A; rgba_map[1] = R; rgba_map[2] = G; rgba_map[3] = B; break;
-        case AV_PIX_FMT_ABGR:  rgba_map[0] = A; rgba_map[1] = B; rgba_map[2] = G; rgba_map[3] = R; break;
-        case AV_PIX_FMT_RGBA:
-        case AV_PIX_FMT_RGB24: rgba_map[0] = R; rgba_map[1] = G; rgba_map[2] = B; rgba_map[3] = A; break;
-        case AV_PIX_FMT_BGRA:
-        case AV_PIX_FMT_BGR24: rgba_map[0] = B; rgba_map[1] = G; rgba_map[2] = R; rgba_map[3] = A; break;
-        }
+        ff_fill_rgba_map(rgba_map, inlink->format);
         lut->step = av_get_bits_per_pixel(desc) >> 3;
     }
 
-    for (comp = 0; comp < desc->nb_components; comp++) {
+    for (color = 0; color < desc->nb_components; color++) {
         double res;
-        int color = lut->is_rgb ? rgba_map[comp] : comp;
+        int comp = lut->is_rgb ? rgba_map[color] : color;
 
         /* create the parsed expression */
         ret = av_expr_parse(&lut->comp_expr[color], lut->comp_expr_str[color],
diff --git a/libavfilter/vf_mp.c b/libavfilter/vf_mp.c
index c70ab28..8edb20f 100644
--- a/libavfilter/vf_mp.c
+++ b/libavfilter/vf_mp.c
@@ -36,7 +36,7 @@
 #include "libmpcodecs/vf.h"
 #include "libmpcodecs/img_format.h"
 #include "libmpcodecs/cpudetect.h"
-#include "libmpcodecs/vd_ffmpeg.h"
+#include "libmpcodecs/av_helpers.h"
 #include "libmpcodecs/vf_scale.h"
 #include "libmpcodecs/libvo/fastmemcpy.h"
 
@@ -122,96 +122,63 @@
     {0, AV_PIX_FMT_NONE}
 };
 
-//copied from vf.c
-extern const vf_info_t vf_info_1bpp;
-extern const vf_info_t vf_info_ass;
-extern const vf_info_t vf_info_bmovl;
-extern const vf_info_t vf_info_crop;
-extern const vf_info_t vf_info_denoise3d;
-extern const vf_info_t vf_info_detc;
-extern const vf_info_t vf_info_dint;
-extern const vf_info_t vf_info_divtc;
-extern const vf_info_t vf_info_down3dright;
-extern const vf_info_t vf_info_dsize;
-extern const vf_info_t vf_info_dvbscale;
-extern const vf_info_t vf_info_eq2;
-extern const vf_info_t vf_info_eq;
-extern const vf_info_t vf_info_expand;
-extern const vf_info_t vf_info_fil;
-extern const vf_info_t vf_info_filmdint;
-extern const vf_info_t vf_info_flip;
-extern const vf_info_t vf_info_format;
-extern const vf_info_t vf_info_fspp;
-extern const vf_info_t vf_info_halfpack;
-extern const vf_info_t vf_info_harddup;
-extern const vf_info_t vf_info_il;
-extern const vf_info_t vf_info_ilpack;
-extern const vf_info_t vf_info_ivtc;
-extern const vf_info_t vf_info_kerndeint;
-extern const vf_info_t vf_info_lavc;
-extern const vf_info_t vf_info_lavcdeint;
-extern const vf_info_t vf_info_mcdeint;
-extern const vf_info_t vf_info_noformat;
-extern const vf_info_t vf_info_noise;
-extern const vf_info_t vf_info_ow;
-extern const vf_info_t vf_info_perspective;
-extern const vf_info_t vf_info_phase;
-extern const vf_info_t vf_info_pp7;
-extern const vf_info_t vf_info_pp;
-extern const vf_info_t vf_info_pullup;
-extern const vf_info_t vf_info_qp;
-extern const vf_info_t vf_info_sab;
-extern const vf_info_t vf_info_scale;
-extern const vf_info_t vf_info_softpulldown;
-extern const vf_info_t vf_info_softskip;
-extern const vf_info_t vf_info_spp;
-extern const vf_info_t vf_info_stereo3d;
-extern const vf_info_t vf_info_telecine;
-extern const vf_info_t vf_info_test;
-extern const vf_info_t vf_info_tfields;
-extern const vf_info_t vf_info_tinterlace;
-extern const vf_info_t vf_info_unsharp;
-extern const vf_info_t vf_info_uspp;
-extern const vf_info_t vf_info_vo;
-extern const vf_info_t vf_info_yadif;
-extern const vf_info_t vf_info_zrmjpeg;
+extern const vf_info_t ff_vf_info_detc;
+extern const vf_info_t ff_vf_info_dint;
+extern const vf_info_t ff_vf_info_divtc;
+extern const vf_info_t ff_vf_info_down3dright;
+extern const vf_info_t ff_vf_info_eq2;
+extern const vf_info_t ff_vf_info_eq;
+extern const vf_info_t ff_vf_info_fil;
+//extern const vf_info_t ff_vf_info_filmdint;
+extern const vf_info_t ff_vf_info_fspp;
+extern const vf_info_t ff_vf_info_harddup;
+extern const vf_info_t ff_vf_info_ilpack;
+extern const vf_info_t ff_vf_info_ivtc;
+extern const vf_info_t ff_vf_info_mcdeint;
+extern const vf_info_t ff_vf_info_noise;
+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_stereo3d;
+extern const vf_info_t ff_vf_info_telecine;
+extern const vf_info_t ff_vf_info_tinterlace;
+extern const vf_info_t ff_vf_info_uspp;
 
 
 static const vf_info_t* const filters[]={
-    &vf_info_denoise3d,
-    &vf_info_detc,
-    &vf_info_dint,
-    &vf_info_divtc,
-    &vf_info_down3dright,
-    &vf_info_dsize,
-    &vf_info_eq2,
-    &vf_info_eq,
-    &vf_info_fil,
-//    &vf_info_filmdint, cmmx.h vd.h ‘opt_screen_size_x’
-    &vf_info_fspp,
-    &vf_info_harddup,
-    &vf_info_il,
-    &vf_info_ilpack,
-    &vf_info_ivtc,
-    &vf_info_kerndeint,
-    &vf_info_mcdeint,
-    &vf_info_noise,
-    &vf_info_ow,
-    &vf_info_perspective,
-    &vf_info_phase,
-    &vf_info_pp,
-    &vf_info_pp7,
-    &vf_info_pullup,
-    &vf_info_qp,
-    &vf_info_sab,
-    &vf_info_softpulldown,
-    &vf_info_softskip,
-    &vf_info_spp,
-    &vf_info_stereo3d,
-    &vf_info_telecine,
-    &vf_info_tinterlace,
-    &vf_info_unsharp,
-    &vf_info_uspp,
+    &ff_vf_info_detc,
+    &ff_vf_info_dint,
+    &ff_vf_info_divtc,
+    &ff_vf_info_down3dright,
+    &ff_vf_info_eq2,
+    &ff_vf_info_eq,
+    &ff_vf_info_fil,
+//    &ff_vf_info_filmdint, cmmx.h vd.h ‘opt_screen_size_x’
+    &ff_vf_info_fspp,
+    &ff_vf_info_harddup,
+    &ff_vf_info_ilpack,
+    &ff_vf_info_ivtc,
+    &ff_vf_info_mcdeint,
+    &ff_vf_info_noise,
+    &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_stereo3d,
+    &ff_vf_info_telecine,
+    &ff_vf_info_tinterlace,
+    &ff_vf_info_uspp,
 
     NULL
 };
@@ -238,16 +205,22 @@
 zrmjpeg
 */
 
-CpuCaps gCpuCaps; //FIXME initialize this so optims work
+CpuCaps ff_gCpuCaps; //FIXME initialize this so optims work
 
+enum AVPixelFormat ff_mp2ff_pix_fmt(int mp){
+    int i;
+    for(i=0; conversion_map[i].fmt && mp != conversion_map[i].fmt; i++)
+        ;
+    return mp == conversion_map[i].fmt ? conversion_map[i].pix_fmt : AV_PIX_FMT_NONE;
+}
 
-static void sws_getFlagsAndFilterFromCmdLine(int *flags, SwsFilter **srcFilterParam, SwsFilter **dstFilterParam)
+static void ff_sws_getFlagsAndFilterFromCmdLine(int *flags, SwsFilter **srcFilterParam, SwsFilter **dstFilterParam)
 {
         static int firstTime=1;
         *flags=0;
 
 #if ARCH_X86
-        if(gCpuCaps.hasMMX)
+        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)
@@ -255,7 +228,7 @@
                 firstTime=0;
                 *flags= SWS_PRINT_INFO;
         }
-        else if( mp_msg_test(MSGT_VFILTER,MSGL_DBG2) ) *flags= SWS_PRINT_INFO;
+        else if( ff_mp_msg_test(MSGT_VFILTER,MSGL_DBG2) ) *flags= SWS_PRINT_INFO;
 
         switch(SWS_BILINEAR)
         {
@@ -279,7 +252,7 @@
 
 //exact copy from vf_scale.c
 // will use sws_flags & src_filter (from cmd line)
-struct SwsContext *sws_getContextFromCmdLine(int srcW, int srcH, int srcFormat, int dstW, int dstH, int dstFormat)
+struct SwsContext *ff_sws_getContextFromCmdLine(int srcW, int srcH, int srcFormat, int dstW, int dstH, int dstFormat)
 {
         int flags, i;
         SwsFilter *dstFilterParam, *srcFilterParam;
@@ -291,7 +264,7 @@
         sfmt= conversion_map[i].pix_fmt;
 
         if (srcFormat == IMGFMT_RGB8 || srcFormat == IMGFMT_BGR8) sfmt = AV_PIX_FMT_PAL8;
-        sws_getFlagsAndFilterFromCmdLine(&flags, &srcFilterParam, &dstFilterParam);
+        ff_sws_getFlagsAndFilterFromCmdLine(&flags, &srcFilterParam, &dstFilterParam);
 
         return sws_getContext(srcW, srcH, sfmt, dstW, dstH, dfmt, flags , srcFilterParam, dstFilterParam, NULL);
 }
@@ -303,7 +276,7 @@
     int frame_returned;
 } MPContext;
 
-void mp_msg(int mod, int lev, const char *format, ... ){
+void ff_mp_msg(int mod, int lev, const char *format, ... ){
     va_list va;
     va_start(va, format);
     //FIXME convert lev/mod
@@ -311,17 +284,17 @@
     va_end(va);
 }
 
-int mp_msg_test(int mod, int lev){
+int ff_mp_msg_test(int mod, int lev){
     return 123;
 }
 
-void init_avcodec(void)
+void ff_init_avcodec(void)
 {
     //we maybe should init but its kinda 1. unneeded 2. a bit inpolite from here
 }
 
 //Exact copy of vf.c
-void vf_clone_mpi_attributes(mp_image_t* dst, mp_image_t* src){
+void ff_vf_clone_mpi_attributes(mp_image_t* dst, mp_image_t* src){
     dst->pict_type= src->pict_type;
     dst->fields = src->fields;
     dst->qscale_type= src->qscale_type;
@@ -332,13 +305,13 @@
 }
 
 //Exact copy of vf.c
-void vf_next_draw_slice(struct vf_instance *vf,unsigned char** src, int * stride,int w, int h, int x, int y){
+void ff_vf_next_draw_slice(struct vf_instance *vf,unsigned char** src, int * stride,int w, int h, int x, int y){
     if (vf->next->draw_slice) {
         vf->next->draw_slice(vf->next,src,stride,w,h,x,y);
         return;
     }
     if (!vf->dmpi) {
-        mp_msg(MSGT_VFILTER,MSGL_ERR,"draw_slice: dmpi not stored by vf_%s\n", vf->info->name);
+        ff_mp_msg(MSGT_VFILTER,MSGL_ERR,"draw_slice: dmpi not stored by vf_%s\n", vf->info->name);
         return;
     }
     if (!(vf->dmpi->flags & MP_IMGFLAG_PLANAR)) {
@@ -355,7 +328,7 @@
 }
 
 //Exact copy of vf.c
-void vf_mpi_clear(mp_image_t* mpi,int x0,int y0,int w,int h){
+void ff_vf_mpi_clear(mp_image_t* mpi,int x0,int y0,int w,int h){
     int y;
     if(mpi->flags&MP_IMGFLAG_PLANAR){
         y0&=~1;h+=h&1;
@@ -399,16 +372,16 @@
     }
 }
 
-int vf_next_query_format(struct vf_instance *vf, unsigned int fmt){
+int ff_vf_next_query_format(struct vf_instance *vf, unsigned int fmt){
     return 1;
 }
 
 //used by delogo
-unsigned int vf_match_csp(vf_instance_t** vfp,const unsigned int* list,unsigned int preferred){
+unsigned int ff_vf_match_csp(vf_instance_t** vfp,const unsigned int* list,unsigned int preferred){
     return preferred;
 }
 
-mp_image_t* vf_get_image(vf_instance_t* vf, unsigned int outfmt, int mp_imgtype, int mp_imgflag, int w, int h){
+mp_image_t* ff_vf_get_image(vf_instance_t* vf, unsigned int outfmt, int mp_imgtype, int mp_imgflag, int w, int h){
     MPContext *m= (MPContext*)(((uint8_t*)vf) - offsetof(MPContext, next_vf));
   mp_image_t* mpi=NULL;
   int w2;
@@ -416,7 +389,7 @@
 
   av_assert0(vf->next == NULL); // all existing filters call this just on next
 
-  //vf_dint needs these as it calls vf_get_image() before configuring the output
+  //vf_dint needs these as it calls ff_vf_get_image() before configuring the output
   if(vf->w==0 && w>0) vf->w=w;
   if(vf->h==0 && h>0) vf->h=h;
 
@@ -436,25 +409,25 @@
   // and if not, then fallback to software buffers:
   switch(mp_imgtype & 0xff){
   case MP_IMGTYPE_EXPORT:
-    if(!vf->imgctx.export_images[0]) vf->imgctx.export_images[0]=new_mp_image(w2,h);
+    if(!vf->imgctx.export_images[0]) vf->imgctx.export_images[0]=ff_new_mp_image(w2,h);
     mpi=vf->imgctx.export_images[0];
     break;
   case MP_IMGTYPE_STATIC:
-    if(!vf->imgctx.static_images[0]) vf->imgctx.static_images[0]=new_mp_image(w2,h);
+    if(!vf->imgctx.static_images[0]) vf->imgctx.static_images[0]=ff_new_mp_image(w2,h);
     mpi=vf->imgctx.static_images[0];
     break;
   case MP_IMGTYPE_TEMP:
-    if(!vf->imgctx.temp_images[0]) vf->imgctx.temp_images[0]=new_mp_image(w2,h);
+    if(!vf->imgctx.temp_images[0]) vf->imgctx.temp_images[0]=ff_new_mp_image(w2,h);
     mpi=vf->imgctx.temp_images[0];
     break;
   case MP_IMGTYPE_IPB:
     if(!(mp_imgflag&MP_IMGFLAG_READABLE)){ // B frame:
-      if(!vf->imgctx.temp_images[0]) vf->imgctx.temp_images[0]=new_mp_image(w2,h);
+      if(!vf->imgctx.temp_images[0]) vf->imgctx.temp_images[0]=ff_new_mp_image(w2,h);
       mpi=vf->imgctx.temp_images[0];
       break;
     }
   case MP_IMGTYPE_IP:
-    if(!vf->imgctx.static_images[vf->imgctx.static_idx]) vf->imgctx.static_images[vf->imgctx.static_idx]=new_mp_image(w2,h);
+    if(!vf->imgctx.static_images[vf->imgctx.static_idx]) vf->imgctx.static_images[vf->imgctx.static_idx]=ff_new_mp_image(w2,h);
     mpi=vf->imgctx.static_images[vf->imgctx.static_idx];
     vf->imgctx.static_idx^=1;
     break;
@@ -467,7 +440,7 @@
       number = i;
     }
     if (number < 0 || number >= NUM_NUMBERED_MPI) return NULL;
-    if (!vf->imgctx.numbered_images[number]) vf->imgctx.numbered_images[number] = new_mp_image(w2,h);
+    if (!vf->imgctx.numbered_images[number]) vf->imgctx.numbered_images[number] = ff_new_mp_image(w2,h);
     mpi = vf->imgctx.numbered_images[number];
     mpi->number = number;
     break;
@@ -488,7 +461,7 @@
                 // need to re-allocate buffer memory:
                 av_free(mpi->planes[0]);
                 mpi->flags&=~MP_IMGFLAG_ALLOCATED;
-                mp_msg(MSGT_VFILTER,MSGL_V,"vf.c: have to REALLOCATE buffer memory :(\n");
+                ff_mp_msg(MSGT_VFILTER,MSGL_V,"vf.c: have to REALLOCATE buffer memory :(\n");
             }
 //      } else {
         } {
@@ -496,7 +469,7 @@
             mpi->height=h; mpi->chroma_height=(h + (1<<mpi->chroma_y_shift) - 1)>>mpi->chroma_y_shift;
         }
     }
-    if(!mpi->bpp) mp_image_setfmt(mpi,outfmt);
+    if(!mpi->bpp) ff_mp_image_setfmt(mpi,outfmt);
     if(!(mpi->flags&MP_IMGFLAG_ALLOCATED) && mpi->type>MP_IMGTYPE_EXPORT){
 
         av_assert0(!vf->get_image);
@@ -506,8 +479,8 @@
         if(!(mpi->flags&MP_IMGFLAG_DIRECT)){
           // non-direct and not yet allocated image. allocate it!
           if (!mpi->bpp) { // no way we can allocate this
-              mp_msg(MSGT_DECVIDEO, MSGL_FATAL,
-                     "vf_get_image: Tried to allocate a format that can not be allocated!\n");
+              ff_mp_msg(MSGT_DECVIDEO, MSGL_FATAL,
+                     "ff_vf_get_image: Tried to allocate a format that can not be allocated!\n");
               return NULL;
           }
 
@@ -521,7 +494,7 @@
 #if 0
                   // we have to change width... check if we CAN co it:
                   int flags=vf->query_format(vf,outfmt); // should not fail
-                  if(!(flags&3)) mp_msg(MSGT_DECVIDEO,MSGL_WARN,"??? vf_get_image{vf->query_format(outfmt)} failed!\n");
+                  if(!(flags&3)) ff_mp_msg(MSGT_DECVIDEO,MSGL_WARN,"??? ff_vf_get_image{vf->query_format(outfmt)} failed!\n");
 //                printf("query -> 0x%X    \n",flags);
                   if(flags&VFCAP_ACCEPT_STRIDE){
 #endif
@@ -531,16 +504,16 @@
               }
           }
 
-          mp_image_alloc_planes(mpi);
+          ff_mp_image_alloc_planes(mpi);
 //        printf("clearing img!\n");
-          vf_mpi_clear(mpi,0,0,mpi->width,mpi->height);
+          ff_vf_mpi_clear(mpi,0,0,mpi->width,mpi->height);
         }
     }
     av_assert0(!vf->start_slice);
     if(mpi->flags&MP_IMGFLAG_DRAW_CALLBACK)
         if(vf->start_slice) vf->start_slice(vf,mpi);
     if(!(mpi->flags&MP_IMGFLAG_TYPE_DISPLAYED)){
-            mp_msg(MSGT_DECVIDEO,MSGL_V,"*** [%s] %s%s mp_image_t, %dx%dx%dbpp %s %s, %d bytes\n",
+            ff_mp_msg(MSGT_DECVIDEO,MSGL_V,"*** [%s] %s%s mp_image_t, %dx%dx%dbpp %s %s, %d bytes\n",
                   "NULL"/*vf->info->name*/,
                   (mpi->type==MP_IMGTYPE_EXPORT)?"Exporting":
                   ((mpi->flags&MP_IMGFLAG_DIRECT)?"Direct Rendering":"Allocating"),
@@ -549,7 +522,7 @@
                   (mpi->flags&MP_IMGFLAG_YUV)?"YUV":((mpi->flags&MP_IMGFLAG_SWAPPED)?"BGR":"RGB"),
                   (mpi->flags&MP_IMGFLAG_PLANAR)?"planar":"packed",
                   mpi->bpp*mpi->width*mpi->height/8);
-            mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"(imgfmt: %x, planes: %p,%p,%p strides: %d,%d,%d, chroma: %dx%d, shift: h:%d,v:%d)\n",
+            ff_mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"(imgfmt: %x, planes: %p,%p,%p strides: %d,%d,%d, chroma: %dx%d, shift: h:%d,v:%d)\n",
                 mpi->imgfmt, mpi->planes[0], mpi->planes[1], mpi->planes[2],
                 mpi->stride[0], mpi->stride[1], mpi->stride[2],
                 mpi->chroma_width, mpi->chroma_height, mpi->chroma_x_shift, mpi->chroma_y_shift);
@@ -566,7 +539,7 @@
 }
 
 
-int vf_next_put_image(struct vf_instance *vf,mp_image_t *mpi, double pts){
+int ff_vf_next_put_image(struct vf_instance *vf,mp_image_t *mpi, double pts){
     MPContext *m= (void*)vf;
     AVFilterLink *outlink     = m->avfctx->outputs[0];
     AVFilterBuffer    *pic    = av_mallocz(sizeof(AVFilterBuffer));
@@ -575,13 +548,13 @@
 
     av_assert0(vf->next);
 
-    av_log(m->avfctx, AV_LOG_DEBUG, "vf_next_put_image\n");
+    av_log(m->avfctx, AV_LOG_DEBUG, "ff_vf_next_put_image\n");
 
     if (!pic || !picref)
         goto fail;
 
     picref->buf = pic;
-    picref->buf->please_use_av_free= (void*)av_free;
+    picref->buf->free= (void*)av_free;
     if (!(picref->video = av_mallocz(sizeof(AVFilterBufferRefVideoProps))))
         goto fail;
 
@@ -608,10 +581,7 @@
     if(pts != MP_NOPTS_VALUE)
         picref->pts= pts * av_q2d(outlink->time_base);
 
-    ff_start_frame(outlink, avfilter_ref_buffer(picref, ~0));
-    ff_draw_slice(outlink, 0, picref->video->h, 1);
-    ff_end_frame(outlink);
-    avfilter_unref_buffer(picref);
+    ff_filter_frame(outlink, picref);
     m->frame_returned++;
 
     return 1;
@@ -623,7 +593,7 @@
     return 0;
 }
 
-int vf_next_config(struct vf_instance *vf,
+int ff_vf_next_config(struct vf_instance *vf,
         int width, int height, int d_width, int d_height,
         unsigned int voflags, unsigned int outfmt){
 
@@ -638,7 +608,7 @@
         //this is fatal for us ATM
         return 0;
     }
-    mp_msg(MSGT_VFILTER,MSGL_V,"REQ: flags=0x%X  req=0x%X  \n",flags,vf->default_reqs);
+    ff_mp_msg(MSGT_VFILTER,MSGL_V,"REQ: flags=0x%X  req=0x%X  \n",flags,vf->default_reqs);
     miss=vf->default_reqs - (flags&vf->default_reqs);
     if(miss&VFCAP_ACCEPT_STRIDE){
         // vf requires stride support but vf->next doesn't support it!
@@ -652,7 +622,7 @@
 #endif
 }
 
-int vf_next_control(struct vf_instance *vf, int request, void* data){
+int ff_vf_next_control(struct vf_instance *vf, int request, void* data){
     MPContext *m= (void*)vf;
     av_log(m->avfctx, AV_LOG_DEBUG, "Received control %d\n", request);
     return 0;
@@ -683,7 +653,9 @@
         av_log(ctx, AV_LOG_ERROR, "Invalid parameter.\n");
         return AVERROR(EINVAL);
     }
-    args+= strlen(name)+1;
+    args += strlen(name);
+    if (args[0] == '=')
+        args++;
 
     for(i=0; ;i++){
         if(!filters[i] || !strcmp(name, filters[i]->name))
@@ -703,10 +675,10 @@
     m->vf.info= filters[i];
 
     m->vf.next        = &m->next_vf;
-    m->vf.put_image   = vf_next_put_image;
-    m->vf.config      = vf_next_config;
+    m->vf.put_image   = ff_vf_next_put_image;
+    m->vf.config      = ff_vf_next_config;
     m->vf.query_format= vf_default_query_format;
-    m->vf.control     = vf_next_control;
+    m->vf.control     = ff_vf_next_control;
     m->vf.default_caps=VFCAP_ACCEPT_STRIDE;
     m->vf.default_reqs=0;
     if(m->vf.info->opts)
@@ -726,7 +698,7 @@
       else
         args = NULL;
 #endif
-    if(m->vf.info->vf_open(&m->vf, args)<=0){
+    if(m->vf.info->vf_open(&m->vf, (char*)args)<=0){
         av_log(ctx, AV_LOG_ERROR, "vf_open() of %s with arg=%s failed\n", name, args);
         return -1;
     }
@@ -743,10 +715,10 @@
         vf_instance_t *next = vf->next;
         if(vf->uninit)
             vf->uninit(vf);
-        free_mp_image(vf->imgctx.static_images[0]);
-        free_mp_image(vf->imgctx.static_images[1]);
-        free_mp_image(vf->imgctx.temp_images[0]);
-        free_mp_image(vf->imgctx.export_images[0]);
+        ff_free_mp_image(vf->imgctx.static_images[0]);
+        ff_free_mp_image(vf->imgctx.static_images[1]);
+        ff_free_mp_image(vf->imgctx.temp_images[0]);
+        ff_free_mp_image(vf->imgctx.export_images[0]);
         vf = next;
     }
 }
@@ -823,29 +795,18 @@
     return ret;
 }
 
-static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
-{
-    return 0;
-}
-
-static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
-{
-    return 0;
-}
-
-static int end_frame(AVFilterLink *inlink)
+static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *inpic)
 {
     MPContext *m = inlink->dst->priv;
-    AVFilterBufferRef *inpic  = inlink->cur_buf;
     int i;
     double pts= MP_NOPTS_VALUE;
-    mp_image_t* mpi = new_mp_image(inpic->video->w, inpic->video->h);
+    mp_image_t* mpi = ff_new_mp_image(inpic->video->w, inpic->video->h);
 
     if(inpic->pts != AV_NOPTS_VALUE)
         pts= inpic->pts / av_q2d(inlink->time_base);
 
     for(i=0; conversion_map[i].fmt && conversion_map[i].pix_fmt != inlink->format; i++);
-    mp_image_setfmt(mpi,conversion_map[i].fmt);
+    ff_mp_image_setfmt(mpi,conversion_map[i].fmt);
 
     memcpy(mpi->planes, inpic->data,     FFMIN(sizeof(inpic->data)    , sizeof(mpi->planes)));
     memcpy(mpi->stride, inpic->linesize, FFMIN(sizeof(inpic->linesize), sizeof(mpi->stride)));
@@ -858,8 +819,10 @@
         mpi->flags |= MP_IMGFLAG_PRESERVE;
     if(m->vf.put_image(&m->vf, mpi, pts) == 0){
         av_log(m->avfctx, AV_LOG_DEBUG, "put_image() says skip\n");
+    }else{
+        avfilter_unref_buffer(inpic);
     }
-    free_mp_image(mpi);
+    ff_free_mp_image(mpi);
     return 0;
 }
 
@@ -867,9 +830,7 @@
     {
         .name         = "default",
         .type         = AVMEDIA_TYPE_VIDEO,
-        .start_frame  = start_frame,
-        .draw_slice   = null_draw_slice,
-        .end_frame    = end_frame,
+        .filter_frame = filter_frame,
         .config_props = config_inprops,
         .min_perms    = AV_PERM_READ,
     },
diff --git a/libavfilter/vf_noise.c b/libavfilter/vf_noise.c
new file mode 100644
index 0000000..d3e443b
--- /dev/null
+++ b/libavfilter/vf_noise.c
@@ -0,0 +1,369 @@
+/*
+ * 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
+ */
+
+/**
+ * @file
+ * noise generator
+ */
+
+#include "libavutil/opt.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/lfg.h"
+#include "libavutil/parseutils.h"
+#include "libavutil/pixdesc.h"
+#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
+#include "video.h"
+
+#define MAX_NOISE 4096
+#define MAX_SHIFT 1024
+#define MAX_RES (MAX_NOISE-MAX_SHIFT)
+
+#define NOISE_UNIFORM  1
+#define NOISE_TEMPORAL 2
+#define NOISE_QUALITY  4
+#define NOISE_AVERAGED 8
+#define NOISE_PATTERN  16
+
+typedef struct {
+    int strength;
+    unsigned flags;
+    int shiftptr;
+    AVLFG lfg;
+    int seed;
+    int8_t *noise;
+    int8_t *prev_shift[MAX_RES][3];
+} FilterParams;
+
+typedef struct {
+    const AVClass *class;
+    int nb_planes;
+    int linesize[4];
+    int height[4];
+    FilterParams all;
+    FilterParams param[4];
+    int rand_shift[MAX_RES];
+    int rand_shift_init;
+} NoiseContext;
+
+#define OFFSET(x) offsetof(NoiseContext, x)
+#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
+
+#define NOISE_PARAMS(name, x, param)                                                                                             \
+    {#name"_seed", "set component #"#x" noise seed", OFFSET(param.seed), AV_OPT_TYPE_INT, {.i64=-1}, -1, INT_MAX, FLAGS},        \
+    {#name"_strength", "set component #"#x" strength", OFFSET(param.strength), AV_OPT_TYPE_INT, {.i64=0}, 0, 100, FLAGS},        \
+    {#name"s",         "set component #"#x" strength", OFFSET(param.strength), AV_OPT_TYPE_INT, {.i64=0}, 0, 100, FLAGS},        \
+    {#name"_flags", "set component #"#x" flags", OFFSET(param.flags), AV_OPT_TYPE_FLAGS, {.i64=0}, 0, 31, FLAGS, #name"_flags"}, \
+    {#name"f", "set component #"#x" flags", OFFSET(param.flags), AV_OPT_TYPE_FLAGS, {.i64=0}, 0, 31, FLAGS, #name"_flags"},      \
+    {"a", "averaged noise", 0, AV_OPT_TYPE_CONST, {.i64=NOISE_AVERAGED}, 0, 0, FLAGS, #name"_flags"},                            \
+    {"p", "(semi)regular pattern", 0, AV_OPT_TYPE_CONST, {.i64=NOISE_PATTERN},  0, 0, FLAGS, #name"_flags"},                     \
+    {"q", "high quality",   0, AV_OPT_TYPE_CONST, {.i64=NOISE_QUALITY},  0, 0, FLAGS, #name"_flags"},                            \
+    {"t", "temporal noise", 0, AV_OPT_TYPE_CONST, {.i64=NOISE_TEMPORAL}, 0, 0, FLAGS, #name"_flags"},                            \
+    {"u", "uniform noise",  0, AV_OPT_TYPE_CONST, {.i64=NOISE_UNIFORM},  0, 0, FLAGS, #name"_flags"},
+
+static const AVOption noise_options[] = {
+    NOISE_PARAMS(all, 0, all)
+    NOISE_PARAMS(c0,  0, param[0])
+    NOISE_PARAMS(c1,  1, param[1])
+    NOISE_PARAMS(c2,  2, param[2])
+    NOISE_PARAMS(c3,  3, param[3])
+    {NULL}
+};
+
+AVFILTER_DEFINE_CLASS(noise);
+
+static const int8_t patt[4] = { -1, 0, 1, 0 };
+
+#define RAND_N(range) ((int) ((double) range * av_lfg_get(lfg) / (UINT_MAX + 1.0)))
+static int init_noise(NoiseContext *n, int comp)
+{
+    int8_t *noise = av_malloc(MAX_NOISE * sizeof(int8_t));
+    FilterParams *fp = &n->param[comp];
+    AVLFG *lfg = &n->param[comp].lfg;
+    int strength = fp->strength;
+    int flags = fp->flags;
+    int i, j;
+
+    if (!noise)
+        return AVERROR(ENOMEM);
+
+    av_lfg_init(&fp->lfg, fp->seed);
+
+    for (i = 0, j = 0; i < MAX_NOISE; i++, j++) {
+        if (flags & NOISE_UNIFORM) {
+            if (flags & NOISE_AVERAGED) {
+                if (flags & NOISE_PATTERN) {
+                    noise[i] = (RAND_N(strength) - strength / 2) / 6
+                        + patt[j % 4] * strength * 0.25 / 3;
+                } else {
+                    noise[i] = (RAND_N(strength) - strength / 2) / 3;
+                }
+            } else {
+                if (flags & NOISE_PATTERN) {
+                    noise[i] = (RAND_N(strength) - strength / 2) / 2
+                        + patt[j % 4] * strength * 0.25;
+                } else {
+                    noise[i] = RAND_N(strength) - strength / 2;
+                }
+            }
+        } else {
+            double x1, x2, w, y1;
+            do {
+                x1 = 2.0 * av_lfg_get(lfg) / (float)RAND_MAX - 1.0;
+                x2 = 2.0 * av_lfg_get(lfg) / (float)RAND_MAX - 1.0;
+                w = x1 * x1 + x2 * x2;
+            } while (w >= 1.0);
+
+            w   = sqrt((-2.0 * log(w)) / w);
+            y1  = x1 * w;
+            y1 *= strength / sqrt(3.0);
+            if (flags & NOISE_PATTERN) {
+                y1 /= 2;
+                y1 += patt[j % 4] * strength * 0.35;
+            }
+            y1 = av_clipf(y1, -128, 127);
+            if (flags & NOISE_AVERAGED)
+                y1 /= 3.0;
+            noise[i] = (int)y1;
+        }
+        if (RAND_N(6) == 0)
+            j--;
+    }
+
+    for (i = 0; i < MAX_RES; i++)
+        for (j = 0; j < 3; j++)
+            fp->prev_shift[i][j] = noise + (av_lfg_get(lfg) & (MAX_SHIFT - 1));
+
+    if (!n->rand_shift_init) {
+        for (i = 0; i < MAX_RES; i++)
+            n->rand_shift[i] = av_lfg_get(lfg) & (MAX_SHIFT - 1);
+        n->rand_shift_init = 1;
+    }
+
+    fp->noise = noise;
+    fp->shiftptr = 0;
+    return 0;
+}
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    NoiseContext *n = ctx->priv;
+    int ret, i;
+
+    n->class = &noise_class;
+    av_opt_set_defaults(n);
+
+    if ((ret = av_set_options_string(n, args, "=", ":")) < 0)
+        return ret;
+
+    for (i = 0; i < 4; i++) {
+        if (n->all.seed >= 0)
+            n->param[i].seed = n->all.seed;
+        else
+            n->param[i].seed = 123457;
+        if (n->all.strength)
+            n->param[i].strength = n->all.strength;
+        if (n->all.flags)
+            n->param[i].flags = n->all.flags;
+    }
+
+    for (i = 0; i < 4; i++) {
+        if (n->param[i].strength && ((ret = init_noise(n, i)) < 0))
+            return ret;
+    }
+
+    return 0;
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    AVFilterFormats *formats = NULL;
+    int fmt;
+
+    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))
+            ff_add_format(&formats, fmt);
+    }
+
+    ff_set_common_formats(ctx, formats);
+    return 0;
+}
+
+static int config_input(AVFilterLink *inlink)
+{
+    NoiseContext *n = inlink->dst->priv;
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
+    int i, ret;
+
+    for (i = 0; i < desc->nb_components; i++)
+        n->nb_planes = FFMAX(n->nb_planes, desc->comp[i].plane);
+    n->nb_planes++;
+
+    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[0] = n->height[3] = inlink->h;
+
+    return 0;
+}
+
+static void line_noise(uint8_t *dst, const uint8_t *src, int8_t *noise,
+                       int len, int shift)
+{
+    int i;
+
+    noise += shift;
+    for (i = 0; i < len; i++) {
+        int v = src[i] + noise[i];
+
+        dst[i] = av_clip_uint8(v);
+    }
+}
+
+static void line_noise_avg(uint8_t *dst, const uint8_t *src,
+                           int len, int8_t **shift)
+{
+    int i;
+    int8_t *src2 = (int8_t*)src;
+
+    for (i = 0; i < len; i++) {
+        const int n = shift[0][i] + shift[1][i] + shift[2][i];
+        dst[i] = src2[i] + ((n * src2[i]) >> 7);
+    }
+}
+
+static void noise(uint8_t *dst, const uint8_t *src,
+                  int dst_linesize, int src_linesize,
+                  int width, int height, NoiseContext *n, int comp)
+{
+    int8_t *noise = n->param[comp].noise;
+    int flags = n->param[comp].flags;
+    AVLFG *lfg = &n->param[comp].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;
+            }
+        }
+
+        return;
+    }
+
+    for (y = 0; y < height; y++) {
+        if (flags & NOISE_TEMPORAL)
+            shift = av_lfg_get(lfg) & (MAX_SHIFT - 1);
+        else
+            shift = n->rand_shift[y];
+
+        if (!(flags & NOISE_QUALITY))
+            shift &= ~7;
+
+        if (flags & NOISE_AVERAGED) {
+            line_noise_avg(dst, src, width, n->param[comp].prev_shift[y]);
+            n->param[comp].prev_shift[y][n->param[comp].shiftptr] = noise + shift;
+        } else {
+            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_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
+{
+    NoiseContext *n = inlink->dst->priv;
+    AVFilterLink *outlink = inlink->dst->outputs[0];
+    AVFilterBufferRef *out;
+    int ret, i;
+
+    if (inpicref->perms & AV_PERM_WRITE) {
+        out = inpicref;
+    } else {
+        out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
+        if (!out) {
+            avfilter_unref_bufferp(&inpicref);
+            return AVERROR(ENOMEM);
+        }
+        avfilter_copy_buffer_ref_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);
+
+    ret = ff_filter_frame(outlink, out);
+    if (inpicref != out)
+        avfilter_unref_buffer(inpicref);
+    return ret;
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    NoiseContext *n = ctx->priv;
+    int i;
+
+    for (i = 0; i < 4; i++)
+        av_freep(&n->param[i].noise);
+    av_opt_free(n);
+}
+
+static const AVFilterPad noise_inputs[] = {
+    {
+        .name             = "default",
+        .type             = AVMEDIA_TYPE_VIDEO,
+        .get_video_buffer = ff_null_get_video_buffer,
+        .filter_frame     = filter_frame,
+        .config_props     = config_input,
+        .min_perms        = AV_PERM_READ,
+    },
+    { NULL }
+};
+
+static const AVFilterPad noise_outputs[] = {
+    {
+        .name          = "default",
+        .type          = AVMEDIA_TYPE_VIDEO,
+    },
+    { NULL }
+};
+
+AVFilter avfilter_vf_noise = {
+    .name          = "noise",
+    .description   = NULL_IF_CONFIG_SMALL("Add noise."),
+    .priv_size     = sizeof(NoiseContext),
+    .init          = init,
+    .uninit        = uninit,
+    .query_formats = query_formats,
+    .inputs        = noise_inputs,
+    .outputs       = noise_outputs,
+    .priv_class    = &noise_class,
+};
diff --git a/libavfilter/vf_overlay.c b/libavfilter/vf_overlay.c
index d61d18e..9812255 100644
--- a/libavfilter/vf_overlay.c
+++ b/libavfilter/vf_overlay.c
@@ -83,6 +83,7 @@
     uint8_t overlay_is_packed_rgb;
     uint8_t overlay_rgba_map[4];
     uint8_t overlay_has_alpha;
+    enum OverlayFormat { OVERLAY_FORMAT_YUV420, OVERLAY_FORMAT_YUV444, OVERLAY_FORMAT_RGB, OVERLAY_FORMAT_NB} format;
 
     AVFilterBufferRef *overpicref;
     struct FFBufQueue queue_main;
@@ -91,6 +92,7 @@
     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
 
     char *x_expr, *y_expr;
 } OverlayContext;
@@ -101,8 +103,15 @@
 static const AVOption overlay_options[] = {
     { "x", "set the x expression", OFFSET(x_expr), AV_OPT_TYPE_STRING, {.str = "0"}, CHAR_MIN, CHAR_MAX, FLAGS },
     { "y", "set the y expression", OFFSET(y_expr), AV_OPT_TYPE_STRING, {.str = "0"}, CHAR_MIN, CHAR_MAX, FLAGS },
-    {"rgb", "force packed RGB in input and output", OFFSET(allow_packed_rgb), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS },
-    {NULL},
+    { "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 },
+
+    { "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" },
+
+    { NULL }
 };
 
 AVFILTER_DEFINE_CLASS(overlay);
@@ -110,42 +119,29 @@
 static av_cold int init(AVFilterContext *ctx, const char *args)
 {
     OverlayContext *over = ctx->priv;
-    char *args1 = av_strdup(args);
-    char *expr, *bufptr = NULL;
-    int ret = 0;
+    static const char *shorthand[] = { "x", "y", NULL };
+    int ret;
 
     over->class = &overlay_class;
     av_opt_set_defaults(over);
 
-    if (expr = av_strtok(args1, ":", &bufptr)) {
-        av_free(over->x_expr);
-        if (!(over->x_expr = av_strdup(expr))) {
-            ret = AVERROR(ENOMEM);
-            goto end;
-        }
-    }
-    if (expr = av_strtok(NULL, ":", &bufptr)) {
-        av_free(over->y_expr);
-        if (!(over->y_expr = av_strdup(expr))) {
-            ret = AVERROR(ENOMEM);
-            goto end;
-        }
-    }
+    ret = av_opt_set_from_string(over, args, shorthand, "=", ":");
+    if (ret < 0)
+        return ret;
 
-    if (bufptr && (ret = av_set_options_string(over, bufptr, "=", ":")) < 0)
-        goto end;
-
-end:
-    av_free(args1);
-    return ret;
+    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;
 
-    av_freep(&over->x_expr);
-    av_freep(&over->y_expr);
+    av_opt_free(over);
 
     avfilter_unref_bufferp(&over->overpicref);
     ff_bufqueue_discard_all(&over->queue_main);
@@ -157,15 +153,27 @@
     OverlayContext *over = ctx->priv;
 
     /* overlay formats contains alpha, for avoiding conversion with alpha information loss */
-    const enum AVPixelFormat main_pix_fmts_yuv[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVA420P, AV_PIX_FMT_NONE };
-    const enum AVPixelFormat overlay_pix_fmts_yuv[] = { AV_PIX_FMT_YUVA420P, AV_PIX_FMT_NONE };
-    const enum AVPixelFormat main_pix_fmts_rgb[] = {
+    static const enum AVPixelFormat main_pix_fmts_yuv420[] = {
+        AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVA420P, AV_PIX_FMT_NONE
+    };
+    static const enum AVPixelFormat overlay_pix_fmts_yuv420[] = {
+        AV_PIX_FMT_YUVA420P, AV_PIX_FMT_NONE
+    };
+
+    static const enum AVPixelFormat main_pix_fmts_yuv444[] = {
+        AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVA444P, AV_PIX_FMT_NONE
+    };
+    static const enum AVPixelFormat overlay_pix_fmts_yuv444[] = {
+        AV_PIX_FMT_YUVA444P, AV_PIX_FMT_NONE
+    };
+
+    static const enum AVPixelFormat main_pix_fmts_rgb[] = {
         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_NONE
     };
-    const enum AVPixelFormat overlay_pix_fmts_rgb[] = {
+    static const enum AVPixelFormat overlay_pix_fmts_rgb[] = {
         AV_PIX_FMT_ARGB,  AV_PIX_FMT_RGBA,
         AV_PIX_FMT_ABGR,  AV_PIX_FMT_BGRA,
         AV_PIX_FMT_NONE
@@ -174,12 +182,21 @@
     AVFilterFormats *main_formats;
     AVFilterFormats *overlay_formats;
 
-    if (over->allow_packed_rgb) {
+    switch (over->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);
+        break;
+    case OVERLAY_FORMAT_YUV444:
+        main_formats    = ff_make_format_list(main_pix_fmts_yuv444);
+        overlay_formats = ff_make_format_list(overlay_pix_fmts_yuv444);
+        break;
+    case OVERLAY_FORMAT_RGB:
         main_formats    = ff_make_format_list(main_pix_fmts_rgb);
         overlay_formats = ff_make_format_list(overlay_pix_fmts_rgb);
-    } else {
-        main_formats    = ff_make_format_list(main_pix_fmts_yuv);
-        overlay_formats = ff_make_format_list(overlay_pix_fmts_yuv);
+        break;
+    default:
+        av_assert0(0);
     }
 
     ff_formats_ref(main_formats,    &ctx->inputs [MAIN   ]->out_formats);
@@ -190,7 +207,8 @@
 }
 
 static const enum AVPixelFormat alpha_pix_fmts[] = {
-    AV_PIX_FMT_YUVA420P, AV_PIX_FMT_ARGB, AV_PIX_FMT_ABGR, AV_PIX_FMT_RGBA,
+    AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA444P,
+    AV_PIX_FMT_ARGB, AV_PIX_FMT_ABGR, AV_PIX_FMT_RGBA,
     AV_PIX_FMT_BGRA, AV_PIX_FMT_NONE
 };
 
@@ -284,11 +302,6 @@
     return 0;
 }
 
-static AVFilterBufferRef *get_video_buffer(AVFilterLink *link, int perms, int w, int h)
-{
-    return ff_get_video_buffer(link->dst->outputs[0], perms, w, h);
-}
-
 // divide by 255 and round to nearest
 // apply a fast variant: (X+127)/255 = ((X+127)*257+257)>>16 = ((X+128)*257)>>16
 #define FAST_DIV255(x) ((((x) + 128) * 257) >> 16)
@@ -299,26 +312,24 @@
 // ((((x) + (y)) << 8) - ((x) + (y)) - (y) * (x)) is a faster version of: 255 * (x + y)
 #define UNPREMULTIPLY_ALPHA(x, y) ((((x) << 16) - ((x) << 9) + (x)) / ((((x) + (y)) << 8) - ((x) + (y)) - (y) * (x)))
 
-static void blend_slice(AVFilterContext *ctx,
+/**
+ * Blend image in src to destination buffer dst at position (x, y).
+ *
+ * It is assumed that the src image at position (x, y) is contained in
+ * dst.
+ */
+static void blend_image(AVFilterContext *ctx,
                         AVFilterBufferRef *dst, AVFilterBufferRef *src,
-                        int x, int y, int w, int h,
-                        int slice_y, int slice_w, int slice_h)
+                        int x, int y)
 {
     OverlayContext *over = ctx->priv;
     int i, j, k;
-    int width, height;
-    int overlay_end_y = y+h;
-    int slice_end_y = slice_y+slice_h;
-    int end_y, start_y;
-
-    width = FFMIN(slice_w - x, w);
-    end_y = FFMIN(slice_end_y, overlay_end_y);
-    start_y = FFMAX(y, slice_y);
-    height = end_y - start_y;
+    int width   = src->video->w;
+    int height  = src->video->h;
 
     if (over->main_is_packed_rgb) {
         uint8_t *dp = dst->data[0] + x * over->main_pix_step[0] +
-                      start_y * dst->linesize[0];
+                      y * dst->linesize[0];
         uint8_t *sp = src->data[0];
         uint8_t alpha;          ///< the amount of overlay to blend on to main
         const int dr = over->main_rgba_map[R];
@@ -332,8 +343,6 @@
         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;
-        if (slice_y > y)
-            sp += (slice_y - y) * src->linesize[0];
         for (i = 0; i < height; i++) {
             uint8_t *d = dp, *s = sp;
             for (j = 0; j < width; j++) {
@@ -383,11 +392,9 @@
         const int main_has_alpha = over->main_has_alpha;
         if (main_has_alpha) {
             uint8_t *da = dst->data[3] + x * over->main_pix_step[3] +
-                          start_y * dst->linesize[3];
+                          y * dst->linesize[3];
             uint8_t *sa = src->data[3];
             uint8_t alpha;          ///< the amount of overlay to blend on to main
-            if (slice_y > y)
-                sa += (slice_y - y) * src->linesize[3];
             for (i = 0; i < height; i++) {
                 uint8_t *d = da, *s = sa;
                 for (j = 0; j < width; j++) {
@@ -417,15 +424,11 @@
             int hsub = i ? over->hsub : 0;
             int vsub = i ? over->vsub : 0;
             uint8_t *dp = dst->data[i] + (x >> hsub) +
-                (start_y >> vsub) * dst->linesize[i];
+                (y >> vsub) * dst->linesize[i];
             uint8_t *sp = src->data[i];
             uint8_t *ap = src->data[3];
             int wp = FFALIGN(width, 1<<hsub) >> hsub;
             int hp = FFALIGN(height, 1<<vsub) >> vsub;
-            if (slice_y > y) {
-                sp += ((slice_y - y) >> vsub) * src->linesize[i];
-                ap += (slice_y - y) * src->linesize[3];
-            }
             for (j = 0; j < hp; j++) {
                 uint8_t *d = dp, *s = sp, *a = ap;
                 for (k = 0; k < wp; k++) {
@@ -473,14 +476,14 @@
     }
 }
 
-static int try_start_frame(AVFilterContext *ctx, AVFilterBufferRef *mainpic)
+static int try_filter_frame(AVFilterContext *ctx, AVFilterBufferRef *mainpic)
 {
     OverlayContext *over = ctx->priv;
     AVFilterLink *outlink = ctx->outputs[0];
-    AVFilterBufferRef *next_overpic, *outpicref;
+    AVFilterBufferRef *next_overpic;
     int ret;
 
-    /* Discard obsolete overlay frames: if there is a next frame with pts is
+    /* 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);
@@ -491,29 +494,32 @@
         avfilter_unref_buffer(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. */
-    outlink->out_buf = outpicref = avfilter_ref_buffer(mainpic, ~0);
-
     av_dlog(ctx, "main_pts:%s main_pts_time:%s",
-            av_ts2str(outpicref->pts), av_ts2timestr(outpicref->pts, &outlink->time_base));
+            av_ts2str(mainpic->pts), av_ts2timestr(mainpic->pts, &outlink->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, &outlink->time_base));
     av_dlog(ctx, "\n");
 
-    ret = ff_start_frame(ctx->outputs[0], avfilter_ref_buffer(outpicref, ~0));
+    if (over->overpicref)
+        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_start_next_frame(AVFilterContext *ctx)
+static int try_filter_next_frame(AVFilterContext *ctx)
 {
     OverlayContext *over = ctx->priv;
     AVFilterBufferRef *next_mainpic = ff_bufqueue_peek(&over->queue_main, 0);
@@ -521,41 +527,21 @@
 
     if (!next_mainpic)
         return AVERROR(EAGAIN);
-    if ((ret = try_start_frame(ctx, next_mainpic)) == AVERROR(EAGAIN))
+    if ((ret = try_filter_frame(ctx, next_mainpic)) == AVERROR(EAGAIN))
         return ret;
-    avfilter_unref_buffer(ff_bufqueue_get(&over->queue_main));
+    ff_bufqueue_get(&over->queue_main);
     return ret;
 }
 
-static int try_push_frame(AVFilterContext *ctx)
-{
-    OverlayContext *over = ctx->priv;
-    AVFilterLink *outlink = ctx->outputs[0];
-    AVFilterBufferRef *outpicref;
-    int ret;
-
-    if ((ret = try_start_next_frame(ctx)) < 0)
-        return ret;
-    outpicref = outlink->out_buf;
-    if (over->overpicref)
-        blend_slice(ctx, outpicref, over->overpicref, over->x, over->y,
-                    over->overpicref->video->w, over->overpicref->video->h,
-                    0, outpicref->video->w, outpicref->video->h);
-    if ((ret = ff_draw_slice(outlink, 0, outpicref->video->h, +1)) < 0 ||
-        (ret = ff_end_frame(outlink)) < 0)
-        return ret;
-    return 0;
-}
-
 static int flush_frames(AVFilterContext *ctx)
 {
     int ret;
 
-    while (!(ret = try_push_frame(ctx)));
+    while (!(ret = try_filter_next_frame(ctx)));
     return ret == AVERROR(EAGAIN) ? 0 : ret;
 }
 
-static int start_frame_main(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
+static int filter_frame_main(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
 {
     AVFilterContext *ctx = inlink->dst;
     OverlayContext *over = ctx->priv;
@@ -563,64 +549,29 @@
 
     if ((ret = flush_frames(ctx)) < 0)
         return ret;
-    if ((ret = try_start_frame(ctx, inpicref)) < 0) {
+    if ((ret = try_filter_frame(ctx, inpicref)) < 0) {
         if (ret != AVERROR(EAGAIN))
             return ret;
         ff_bufqueue_add(ctx, &over->queue_main, inpicref);
-        av_assert1(inpicref == inlink->cur_buf);
-        inlink->cur_buf = NULL;
     }
-    return 0;
-}
 
-static int draw_slice_main(AVFilterLink *inlink, int y, int h, int slice_dir)
-{
-    AVFilterContext *ctx = inlink->dst;
-    OverlayContext *over = ctx->priv;
-    AVFilterLink *outlink = ctx->outputs[0];
-    AVFilterBufferRef *outpicref = outlink->out_buf;
-
-    if (!outpicref)
+    if (!over->overpicref)
         return 0;
-    if (over->overpicref &&
-        y + h > over->y && y < over->y + over->overpicref->video->h) {
-        blend_slice(ctx, outpicref, over->overpicref, over->x, over->y,
-                    over->overpicref->video->w, over->overpicref->video->h,
-                    y, outpicref->video->w, h);
-    }
-    return ff_draw_slice(outlink, y, h, slice_dir);
-}
-
-static int end_frame_main(AVFilterLink *inlink)
-{
-    AVFilterContext *ctx = inlink->dst;
-    AVFilterLink *outlink = ctx->outputs[0];
-    AVFilterBufferRef *outpicref = outlink->out_buf;
     flush_frames(ctx);
 
-    if (!outpicref)
-        return 0;
-    return ff_end_frame(ctx->outputs[0]);
-}
-
-static int start_frame_over(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
-{
     return 0;
 }
 
-static int end_frame_over(AVFilterLink *inlink)
+static int filter_frame_over(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
 {
     AVFilterContext *ctx = inlink->dst;
     OverlayContext *over = ctx->priv;
-    AVFilterBufferRef *inpicref = inlink->cur_buf;
     int ret;
 
-    inlink->cur_buf = NULL;
-
     if ((ret = flush_frames(ctx)) < 0)
         return ret;
     ff_bufqueue_add(ctx, &over->queue_over, inpicref);
-    ret = try_push_frame(ctx);
+    ret = try_filter_next_frame(ctx);
     return ret == AVERROR(EAGAIN) ? 0 : ret;
 }
 
@@ -630,7 +581,7 @@
     OverlayContext *over = ctx->priv;
     int input, ret;
 
-    if (!try_push_frame(ctx))
+    if (!try_filter_next_frame(ctx))
         return 0;
     over->frame_requested = 1;
     while (over->frame_requested) {
@@ -642,7 +593,9 @@
         /* EOF on main is reported immediately */
         if (ret == AVERROR_EOF && input == OVERLAY) {
             over->overlay_eof = 1;
-            if ((ret = try_start_next_frame(ctx)) != AVERROR(EAGAIN))
+            if (over->shortest)
+                return ret;
+            if ((ret = try_filter_next_frame(ctx)) != AVERROR(EAGAIN))
                 return ret;
             ret = 0; /* continue requesting frames on main */
         }
@@ -652,29 +605,20 @@
     return 0;
 }
 
-static int null_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
-{
-    return 0;
-}
-
 static const AVFilterPad avfilter_vf_overlay_inputs[] = {
     {
         .name         = "main",
         .type         = AVMEDIA_TYPE_VIDEO,
-        .get_video_buffer= get_video_buffer,
+        .get_video_buffer = ff_null_get_video_buffer,
         .config_props = config_input_main,
-        .start_frame  = start_frame_main,
-        .draw_slice   = draw_slice_main,
-        .end_frame    = end_frame_main,
+        .filter_frame = filter_frame_main,
         .min_perms    = AV_PERM_READ | AV_PERM_WRITE | AV_PERM_PRESERVE,
     },
     {
         .name         = "overlay",
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_input_overlay,
-        .start_frame  = start_frame_over,
-        .draw_slice   = null_draw_slice,
-        .end_frame    = end_frame_over,
+        .filter_frame = filter_frame_over,
         .min_perms    = AV_PERM_READ | AV_PERM_PRESERVE,
     },
     { NULL }
diff --git a/libavfilter/vf_pad.c b/libavfilter/vf_pad.c
index bbd37b1..5c146f2 100644
--- a/libavfilter/vf_pad.c
+++ b/libavfilter/vf_pad.c
@@ -35,6 +35,7 @@
 #include "libavutil/colorspace.h"
 #include "libavutil/avassert.h"
 #include "libavutil/imgutils.h"
+#include "libavutil/opt.h"
 #include "libavutil/parseutils.h"
 #include "libavutil/mathematics.h"
 #include "drawutils.h"
@@ -76,40 +77,61 @@
 }
 
 typedef struct {
+    const AVClass *class;
     int w, h;               ///< output dimensions, a value of 0 will result in the input size
     int x, y;               ///< offsets of the input area with respect to the padded area
     int in_w, in_h;         ///< width and height for the padded input video, which has to be aligned to the chroma values in order to avoid chroma issues
 
-    char w_expr[256];       ///< width  expression string
-    char h_expr[256];       ///< height expression string
-    char x_expr[256];       ///< width  expression string
-    char y_expr[256];       ///< height expression string
-
+    char *w_expr;       ///< width  expression string
+    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;
 
+#define OFFSET(x) offsetof(PadContext, x)
+#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
+
+static const AVOption pad_options[] = {
+    { "width",  "set the pad area width expression",       OFFSET(w_expr), AV_OPT_TYPE_STRING, {.str = "iw"}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "w",      "set the pad area width expression",       OFFSET(w_expr), AV_OPT_TYPE_STRING, {.str = "iw"}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "height", "set the pad area height expression",      OFFSET(h_expr), AV_OPT_TYPE_STRING, {.str = "ih"}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "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 },
+    {NULL}
+};
+
+AVFILTER_DEFINE_CLASS(pad);
+
 static av_cold int init(AVFilterContext *ctx, const char *args)
 {
     PadContext *pad = ctx->priv;
-    char color_string[128] = "black";
+    static const char *shorthand[] = { "width", "height", "x", "y", "color", NULL };
+    int ret;
 
-    av_strlcpy(pad->w_expr, "iw", sizeof(pad->w_expr));
-    av_strlcpy(pad->h_expr, "ih", sizeof(pad->h_expr));
-    av_strlcpy(pad->x_expr, "0" , sizeof(pad->w_expr));
-    av_strlcpy(pad->y_expr, "0" , sizeof(pad->h_expr));
+    pad->class = &pad_class;
+    av_opt_set_defaults(pad);
 
-    if (args)
-        sscanf(args, "%255[^:]:%255[^:]:%255[^:]:%255[^:]:%127s",
-               pad->w_expr, pad->h_expr, pad->x_expr, pad->y_expr, color_string);
+    if ((ret = av_opt_set_from_string(pad, args, shorthand, "=", ":")) < 0)
+        return ret;
 
-    if (av_parse_color(pad->rgba_color, color_string, -1, ctx) < 0)
+    if (av_parse_color(pad->rgba_color, pad->color_str, -1, ctx) < 0)
         return AVERROR(EINVAL);
 
     return 0;
 }
 
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    PadContext *pad = ctx->priv;
+    av_opt_free(pad);
+}
+
 static int config_input(AVFilterLink *inlink)
 {
     AVFilterContext *ctx = inlink->dst;
@@ -368,9 +390,11 @@
 
     .priv_size     = sizeof(PadContext),
     .init          = init,
+    .uninit        = uninit,
     .query_formats = query_formats,
 
     .inputs    = avfilter_vf_pad_inputs,
 
     .outputs   = avfilter_vf_pad_outputs,
+    .priv_class = &pad_class,
 };
diff --git a/libavfilter/vf_pp.c b/libavfilter/vf_pp.c
new file mode 100644
index 0000000..bde5ebf
--- /dev/null
+++ b/libavfilter/vf_pp.c
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2002 A'rpi
+ * Copyright (C) 2012 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.
+ */
+
+/**
+ * @file
+ * libpostproc filter, ported from MPlayer.
+ */
+
+#include "libavutil/avassert.h"
+#include "libavutil/opt.h"
+#include "internal.h"
+
+#include "libpostproc/postprocess.h"
+
+typedef struct {
+    int mode_id;
+    pp_mode *modes[PP_QUALITY_MAX + 1];
+    void *pp_ctx;
+} PPFilterContext;
+
+static av_cold int pp_init(AVFilterContext *ctx, const char *args)
+{
+    int i;
+    PPFilterContext *pp = ctx->priv;
+
+    if (!args || !*args)
+        args = "de";
+
+    for (i = 0; i <= PP_QUALITY_MAX; i++) {
+        pp->modes[i] = pp_get_mode_by_name_and_quality(args, i);
+        if (!pp->modes[i])
+            return AVERROR_EXTERNAL;
+    }
+    pp->mode_id = PP_QUALITY_MAX;
+    return 0;
+}
+
+static int pp_process_command(AVFilterContext *ctx, const char *cmd, const char *args,
+                              char *res, int res_len, int flags)
+{
+    PPFilterContext *pp = ctx->priv;
+
+    if (!strcmp(cmd, "quality")) {
+        pp->mode_id = av_clip(strtol(args, NULL, 10), 0, PP_QUALITY_MAX);
+        return 0;
+    }
+    return AVERROR(ENOSYS);
+}
+
+static int pp_query_formats(AVFilterContext *ctx)
+{
+    static const enum PixelFormat pix_fmts[] = {
+        AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVJ420P,
+        AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUVJ422P,
+        AV_PIX_FMT_YUV411P,
+        AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVJ444P,
+        AV_PIX_FMT_NONE
+    };
+    ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
+    return 0;
+}
+
+static int pp_config_props(AVFilterLink *inlink)
+{
+    int flags = PP_CPU_CAPS_AUTO;
+    PPFilterContext *pp = inlink->dst->priv;
+
+    switch (inlink->format) {
+    case AV_PIX_FMT_YUVJ420P:
+    case AV_PIX_FMT_YUV420P: flags |= PP_FORMAT_420; break;
+    case AV_PIX_FMT_YUVJ422P:
+    case AV_PIX_FMT_YUV422P: flags |= PP_FORMAT_422; break;
+    case AV_PIX_FMT_YUV411P: flags |= PP_FORMAT_411; break;
+    case AV_PIX_FMT_YUVJ444P:
+    case AV_PIX_FMT_YUV444P: flags |= PP_FORMAT_444; break;
+    default: av_assert0(0);
+    }
+
+    pp->pp_ctx = pp_get_context(inlink->w, inlink->h, flags);
+    if (!pp->pp_ctx)
+        return AVERROR(ENOMEM);
+    return 0;
+}
+
+static int pp_filter_frame(AVFilterLink *inlink, AVFilterBufferRef *inbuf)
+{
+    AVFilterContext *ctx = inlink->dst;
+    PPFilterContext *pp = ctx->priv;
+    AVFilterLink *outlink = ctx->outputs[0];
+    const int aligned_w = FFALIGN(outlink->w, 8);
+    const int aligned_h = FFALIGN(outlink->h, 8);
+    AVFilterBufferRef *outbuf;
+
+    outbuf = ff_get_video_buffer(outlink, AV_PERM_WRITE, aligned_w, aligned_h);
+    if (!outbuf) {
+        avfilter_unref_buffer(inbuf);
+        return AVERROR(ENOMEM);
+    }
+    avfilter_copy_buffer_ref_props(outbuf, inbuf);
+
+    pp_postprocess((const uint8_t **)inbuf->data, inbuf->linesize,
+                   outbuf->data,                 outbuf->linesize,
+                   aligned_w, outlink->h,
+                   outbuf->video->qp_table,
+                   outbuf->video->qp_table_linesize,
+                   pp->modes[pp->mode_id],
+                   pp->pp_ctx,
+                   outbuf->video->pict_type);
+
+    avfilter_unref_buffer(inbuf);
+    return ff_filter_frame(outlink, outbuf);
+}
+
+static av_cold void pp_uninit(AVFilterContext *ctx)
+{
+    int i;
+    PPFilterContext *pp = ctx->priv;
+
+    for (i = 0; i <= PP_QUALITY_MAX; i++)
+        pp_free_mode(pp->modes[i]);
+    if (pp->pp_ctx)
+        pp_free_context(pp->pp_ctx);
+}
+
+static const AVFilterPad pp_inputs[] = {
+    {
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_VIDEO,
+        .config_props = pp_config_props,
+        .filter_frame = pp_filter_frame,
+        .min_perms    = AV_PERM_READ,
+    },
+    { NULL }
+};
+
+static const AVFilterPad pp_outputs[] = {
+    {
+        .name = "default",
+        .type = AVMEDIA_TYPE_VIDEO,
+    },
+    { NULL }
+};
+
+AVFilter avfilter_vf_pp = {
+    .name            = "pp",
+    .description     = NULL_IF_CONFIG_SMALL("Filter video using libpostproc."),
+    .priv_size       = sizeof(PPFilterContext),
+    .init            = pp_init,
+    .uninit          = pp_uninit,
+    .query_formats   = pp_query_formats,
+    .inputs          = pp_inputs,
+    .outputs         = pp_outputs,
+    .process_command = pp_process_command,
+};
diff --git a/libavfilter/vf_removelogo.c b/libavfilter/vf_removelogo.c
index f2228be..ddaf9ef 100644
--- a/libavfilter/vf_removelogo.c
+++ b/libavfilter/vf_removelogo.c
@@ -72,6 +72,7 @@
 #include "libavutil/imgutils.h"
 #include "avfilter.h"
 #include "formats.h"
+#include "internal.h"
 #include "video.h"
 #include "bbox.h"
 #include "lavfutils.h"
@@ -191,7 +192,7 @@
 
 static int query_formats(AVFilterContext *ctx)
 {
-    enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE };
+    static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE };
     ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
     return 0;
 }
@@ -472,24 +473,24 @@
     }
 }
 
-static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
-{
-    AVFilterLink *outlink = inlink->dst->outputs[0];
-    AVFilterBufferRef *outpicref;
-
-    outpicref = inpicref;
-
-    outlink->out_buf = outpicref;
-    return ff_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0));
-}
-
-static int end_frame(AVFilterLink *inlink)
+static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
 {
     RemovelogoContext *removelogo = inlink->dst->priv;
     AVFilterLink *outlink = inlink->dst->outputs[0];
-    AVFilterBufferRef *inpicref  = inlink ->cur_buf;
-    AVFilterBufferRef *outpicref = outlink->out_buf;
-    int direct = inpicref == outpicref;
+    AVFilterBufferRef *outpicref;
+    int direct = 0;
+
+    if (inpicref->perms & AV_PERM_WRITE) {
+        direct = 1;
+        outpicref = inpicref;
+    } else {
+        outpicref = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
+        if (!outpicref) {
+            avfilter_unref_bufferp(&inpicref);
+            return AVERROR(ENOMEM);
+        }
+        avfilter_copy_buffer_ref_props(outpicref, inpicref);
+    }
 
     blur_image(removelogo->mask,
                inpicref ->data[0], inpicref ->linesize[0],
@@ -507,8 +508,10 @@
                removelogo->half_mask_data, inlink->w/2,
                inlink->w/2, inlink->h/2, direct, &removelogo->half_mask_bbox);
 
-    ff_draw_slice(outlink, 0, inlink->h, 1);
-    return ff_end_frame(outlink);
+    if (!direct)
+        avfilter_unref_bufferp(&inpicref);
+
+    return ff_filter_frame(outlink, outpicref);
 }
 
 static void uninit(AVFilterContext *ctx)
@@ -533,18 +536,14 @@
     }
 }
 
-static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { return 0; }
-
 static const AVFilterPad removelogo_inputs[] = {
     {
         .name             = "default",
         .type             = AVMEDIA_TYPE_VIDEO,
         .get_video_buffer = ff_null_get_video_buffer,
         .config_props     = config_props_input,
-        .draw_slice       = null_draw_slice,
-        .start_frame      = start_frame,
-        .end_frame        = end_frame,
-        .min_perms        = AV_PERM_WRITE | AV_PERM_READ,
+        .filter_frame     = filter_frame,
+        .min_perms        = AV_PERM_READ,
     },
     { NULL }
 };
diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c
index 71f9782..f6e79ff 100644
--- a/libavfilter/vf_scale.c
+++ b/libavfilter/vf_scale.c
@@ -402,7 +402,7 @@
               (int64_t)in->video->sample_aspect_ratio.den * outlink->w * link->h,
               INT_MAX);
 
-    if(scale->interlaced>0 || (scale->interlaced<0 && link->cur_buf->video->interlaced)){
+    if(scale->interlaced>0 || (scale->interlaced<0 && in->video->interlaced)){
         scale_slice(link, out, in, scale->isws[0], 0, (link->h+1)/2, 2, 0);
         scale_slice(link, out, in, scale->isws[1], 0,  link->h   /2, 2, 1);
     }else{
diff --git a/libavfilter/vf_setfield.c b/libavfilter/vf_setfield.c
index c62ee36..43949fa 100644
--- a/libavfilter/vf_setfield.c
+++ b/libavfilter/vf_setfield.c
@@ -23,7 +23,9 @@
  * set field order
  */
 
+#include "libavutil/opt.h"
 #include "avfilter.h"
+#include "internal.h"
 #include "video.h"
 
 enum SetFieldMode {
@@ -34,53 +36,52 @@
 };
 
 typedef struct {
+    const AVClass *class;
     enum SetFieldMode mode;
 } SetFieldContext;
 
+#define OFFSET(x) offsetof(SetFieldContext, x)
+#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
+
+static const AVOption setfield_options[] = {
+    {"mode", "select interlace mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=MODE_AUTO}, -1, MODE_PROG, FLAGS, "mode"},
+    {"auto", "keep the same input field",  0, AV_OPT_TYPE_CONST, {.i64=MODE_AUTO}, INT_MIN, INT_MAX, FLAGS, "mode"},
+    {"bff",  "mark as bottom-field-first", 0, AV_OPT_TYPE_CONST, {.i64=MODE_BFF},  INT_MIN, INT_MAX, FLAGS, "mode"},
+    {"tff",  "mark as top-field-first",    0, AV_OPT_TYPE_CONST, {.i64=MODE_TFF},  INT_MIN, INT_MAX, FLAGS, "mode"},
+    {"prog", "mark as progressive",        0, AV_OPT_TYPE_CONST, {.i64=MODE_PROG}, INT_MIN, INT_MAX, FLAGS, "mode"},
+    {NULL}
+};
+
+AVFILTER_DEFINE_CLASS(setfield);
+
 static av_cold int init(AVFilterContext *ctx, const char *args)
 {
     SetFieldContext *setfield = ctx->priv;
+    static const char *shorthand[] = { "mode", NULL };
 
-    setfield->mode = MODE_AUTO;
+    setfield->class = &setfield_class;
+    av_opt_set_defaults(setfield);
 
-    if (args) {
-        char c;
-        if (sscanf(args, "%d%c", &setfield->mode, &c) != 1) {
-            if      (!strcmp("tff",  args)) setfield->mode = MODE_TFF;
-            else if (!strcmp("bff",  args)) setfield->mode = MODE_BFF;
-            else if (!strcmp("prog", args)) setfield->mode = MODE_PROG;
-            else if (!strcmp("auto", args)) setfield->mode = MODE_AUTO;
-            else {
-                av_log(ctx, AV_LOG_ERROR, "Invalid argument '%s'\n", args);
-                return AVERROR(EINVAL);
-            }
-        } else {
-            if (setfield->mode < -1 || setfield->mode > 1) {
-                av_log(ctx, AV_LOG_ERROR,
-                       "Provided integer value %d must be included between -1 and +1\n",
-                       setfield->mode);
-                return AVERROR(EINVAL);
-            }
-            av_log(ctx, AV_LOG_WARNING,
-                   "Using -1/0/1 is deprecated, use auto/tff/bff/prog\n");
-        }
-    }
-
-    return 0;
+    return av_opt_set_from_string(setfield, args, shorthand, "=", ":");
 }
 
-static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    SetFieldContext *setfield = ctx->priv;
+    av_opt_free(setfield);
+}
+
+static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
 {
     SetFieldContext *setfield = inlink->dst->priv;
-    AVFilterBufferRef *outpicref = avfilter_ref_buffer(inpicref, ~0);
 
     if (setfield->mode == MODE_PROG) {
-        outpicref->video->interlaced = 0;
+        picref->video->interlaced = 0;
     } else if (setfield->mode != MODE_AUTO) {
-        outpicref->video->interlaced = 1;
-        outpicref->video->top_field_first = setfield->mode;
+        picref->video->interlaced = 1;
+        picref->video->top_field_first = setfield->mode;
     }
-    return ff_start_frame(inlink->dst->outputs[0], outpicref);
+    return ff_filter_frame(inlink->dst->outputs[0], picref);
 }
 
 static const AVFilterPad setfield_inputs[] = {
@@ -88,7 +89,7 @@
         .name             = "default",
         .type             = AVMEDIA_TYPE_VIDEO,
         .get_video_buffer = ff_null_get_video_buffer,
-        .start_frame      = start_frame,
+        .filter_frame     = filter_frame,
     },
     { NULL }
 };
@@ -105,8 +106,10 @@
     .name      = "setfield",
     .description = NULL_IF_CONFIG_SMALL("Force field for the output video frame."),
     .init      = init,
+    .uninit    = uninit,
 
     .priv_size = sizeof(SetFieldContext),
     .inputs    = setfield_inputs,
     .outputs   = setfield_outputs,
+    .priv_class = &setfield_class,
 };
diff --git a/libavfilter/vf_showinfo.c b/libavfilter/vf_showinfo.c
index 1cad3c9..f91721d 100644
--- a/libavfilter/vf_showinfo.c
+++ b/libavfilter/vf_showinfo.c
@@ -50,7 +50,7 @@
     uint32_t plane_checksum[4] = {0}, checksum = 0;
     int i, plane, vsub = desc->log2_chroma_h;
 
-    for (plane = 0; frame->data[plane] && plane < 4; plane++) {
+    for (plane = 0; plane < 4 && frame->data[plane]; plane++) {
         int64_t linesize = av_image_get_linesize(frame->format, frame->video->w, plane);
         uint8_t *data = frame->data[plane];
         int h = plane == 1 || plane == 2 ? inlink->h >> vsub : inlink->h;
@@ -80,7 +80,7 @@
            av_get_picture_type_char(frame->video->pict_type),
            checksum, plane_checksum[0]);
 
-    for (plane = 1; frame->data[plane] && plane < 4; plane++)
+    for (plane = 1; plane < 4 && frame->data[plane]; plane++)
         av_log(ctx, AV_LOG_INFO, " %08X", plane_checksum[plane]);
     av_log(ctx, AV_LOG_INFO, "]\n");
 
diff --git a/libavfilter/vf_subtitles.c b/libavfilter/vf_subtitles.c
new file mode 100644
index 0000000..7513e24
--- /dev/null
+++ b/libavfilter/vf_subtitles.c
@@ -0,0 +1,375 @@
+/*
+ * Copyright (c) 2011 Baptiste Coudurier
+ * Copyright (c) 2011 Stefano Sabatini
+ * Copyright (c) 2012 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
+ * Libass subtitles burning filter.
+ *
+ * @see{http://www.matroska.org/technical/specs/subtitles/ssa.html}
+ */
+
+#include <ass/ass.h>
+
+#include "config.h"
+#if CONFIG_SUBTITLES_FILTER
+# include "libavcodec/avcodec.h"
+# include "libavformat/avformat.h"
+#endif
+#include "libavutil/avstring.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/opt.h"
+#include "libavutil/parseutils.h"
+#include "drawutils.h"
+#include "avfilter.h"
+#include "internal.h"
+#include "formats.h"
+#include "video.h"
+
+typedef struct {
+    const AVClass *class;
+    ASS_Library  *library;
+    ASS_Renderer *renderer;
+    ASS_Track    *track;
+    char *filename;
+    char *charenc;
+    uint8_t rgba_map[4];
+    int     pix_step[4];       ///< steps per pixel for each plane of the main output
+    int original_w, original_h;
+    FFDrawContext draw;
+} AssContext;
+
+#define OFFSET(x) offsetof(AssContext, x)
+#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
+
+#define COMMON_OPTIONS \
+    {"filename",       "set the filename of file to read",                         OFFSET(filename),   AV_OPT_TYPE_STRING,     {.str = NULL},  CHAR_MIN, CHAR_MAX, FLAGS }, \
+    {"f",              "set the filename of file to read",                         OFFSET(filename),   AV_OPT_TYPE_STRING,     {.str = NULL},  CHAR_MIN, CHAR_MAX, FLAGS }, \
+    {"original_size",  "set the size of the original video (used to scale fonts)", OFFSET(original_w), AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL},  CHAR_MIN, CHAR_MAX, FLAGS }, \
+
+/* libass supports a log level ranging from 0 to 7 */
+static const int ass_libavfilter_log_level_map[] = {
+    AV_LOG_QUIET,               /* 0 */
+    AV_LOG_PANIC,               /* 1 */
+    AV_LOG_FATAL,               /* 2 */
+    AV_LOG_ERROR,               /* 3 */
+    AV_LOG_WARNING,             /* 4 */
+    AV_LOG_INFO,                /* 5 */
+    AV_LOG_VERBOSE,             /* 6 */
+    AV_LOG_DEBUG,               /* 7 */
+};
+
+static void ass_log(int ass_level, const char *fmt, va_list args, void *ctx)
+{
+    int level = ass_libavfilter_log_level_map[ass_level];
+
+    av_vlog(ctx, level, fmt, args);
+    av_log(ctx, level, "\n");
+}
+
+static av_cold int init(AVFilterContext *ctx, const char *args, const AVClass *class)
+{
+    AssContext *ass = ctx->priv;
+    static const char *shorthand[] = { "filename", NULL };
+    int ret;
+
+    ass->class = class;
+    av_opt_set_defaults(ass);
+
+    if ((ret = av_opt_set_from_string(ass, args, shorthand, "=", ":")) < 0)
+        return ret;
+
+    if (!ass->filename) {
+        av_log(ctx, AV_LOG_ERROR, "No filename provided!\n");
+        return AVERROR(EINVAL);
+    }
+
+    ass->library = ass_library_init();
+    if (!ass->library) {
+        av_log(ctx, AV_LOG_ERROR, "Could not initialize libass.\n");
+        return AVERROR(EINVAL);
+    }
+    ass_set_message_cb(ass->library, ass_log, ctx);
+
+    ass->renderer = ass_renderer_init(ass->library);
+    if (!ass->renderer) {
+        av_log(ctx, AV_LOG_ERROR, "Could not initialize libass renderer.\n");
+        return AVERROR(EINVAL);
+    }
+
+    ass_set_fonts(ass->renderer, NULL, NULL, 1, NULL, 1);
+    return 0;
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    AssContext *ass = ctx->priv;
+
+    av_opt_free(ass);
+    if (ass->track)
+        ass_free_track(ass->track);
+    if (ass->renderer)
+        ass_renderer_done(ass->renderer);
+    if (ass->library)
+        ass_library_done(ass->library);
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    ff_set_common_formats(ctx, ff_draw_supported_pixel_formats(0));
+    return 0;
+}
+
+static int config_input(AVFilterLink *inlink)
+{
+    AssContext *ass = inlink->dst->priv;
+
+    ff_draw_init(&ass->draw, inlink->format, 0);
+
+    ass_set_frame_size  (ass->renderer, inlink->w, inlink->h);
+    if (ass->original_w && ass->original_h)
+        ass_set_aspect_ratio(ass->renderer, (double)inlink->w / inlink->h,
+                             (double)ass->original_w / ass->original_h);
+
+    return 0;
+}
+
+/* libass stores an RGBA color in the format RRGGBBTT, where TT is the transparency level */
+#define AR(c)  ( (c)>>24)
+#define AG(c)  (((c)>>16)&0xFF)
+#define AB(c)  (((c)>>8) &0xFF)
+#define AA(c)  ((0xFF-c) &0xFF)
+
+static void overlay_ass_image(AssContext *ass, AVFilterBufferRef *picref,
+                              const ASS_Image *image)
+{
+    for (; image; image = image->next) {
+        uint8_t rgba_color[] = {AR(image->color), AG(image->color), AB(image->color), AA(image->color)};
+        FFDrawColor color;
+        ff_draw_color(&ass->draw, &color, rgba_color);
+        ff_blend_mask(&ass->draw, &color,
+                      picref->data, picref->linesize,
+                      picref->video->w, picref->video->h,
+                      image->bitmap, image->stride, image->w, image->h,
+                      3, 0, image->dst_x, image->dst_y);
+    }
+}
+
+static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
+{
+    AVFilterContext *ctx = inlink->dst;
+    AVFilterLink *outlink = ctx->outputs[0];
+    AssContext *ass = ctx->priv;
+    int detect_change = 0;
+    double time_ms = picref->pts * av_q2d(inlink->time_base) * 1000;
+    ASS_Image *image = ass_render_frame(ass->renderer, ass->track,
+                                        time_ms, &detect_change);
+
+    if (detect_change)
+        av_log(ctx, AV_LOG_DEBUG, "Change happened at time ms:%f\n", time_ms);
+
+    overlay_ass_image(ass, picref, image);
+
+    return ff_filter_frame(outlink, picref);
+}
+
+static const AVFilterPad ass_inputs[] = {
+    {
+        .name             = "default",
+        .type             = AVMEDIA_TYPE_VIDEO,
+        .filter_frame     = filter_frame,
+        .config_props     = config_input,
+        .min_perms        = AV_PERM_READ | AV_PERM_WRITE,
+    },
+    { NULL }
+};
+
+static const AVFilterPad ass_outputs[] = {
+    {
+        .name = "default",
+        .type = AVMEDIA_TYPE_VIDEO,
+    },
+    { NULL }
+};
+
+#if CONFIG_ASS_FILTER
+
+static const AVOption ass_options[] = {
+    COMMON_OPTIONS
+    {NULL},
+};
+
+AVFILTER_DEFINE_CLASS(ass);
+
+static av_cold int init_ass(AVFilterContext *ctx, const char *args)
+{
+    AssContext *ass = ctx->priv;
+    int ret = init(ctx, args, &ass_class);
+
+    if (ret < 0)
+        return ret;
+
+    ass->track = ass_read_file(ass->library, ass->filename, NULL);
+    if (!ass->track) {
+        av_log(ctx, AV_LOG_ERROR,
+               "Could not create a libass track when reading file '%s'\n",
+               ass->filename);
+        return AVERROR(EINVAL);
+    }
+    return 0;
+}
+
+AVFilter avfilter_vf_ass = {
+    .name          = "ass",
+    .description   = NULL_IF_CONFIG_SMALL("Render ASS subtitles onto input video using the libass library."),
+    .priv_size     = sizeof(AssContext),
+    .init          = init_ass,
+    .uninit        = uninit,
+    .query_formats = query_formats,
+    .inputs        = ass_inputs,
+    .outputs       = ass_outputs,
+    .priv_class    = &ass_class,
+};
+#endif
+
+#if CONFIG_SUBTITLES_FILTER
+
+static const AVOption subtitles_options[] = {
+    COMMON_OPTIONS
+    {"charenc", "set input character encoding", OFFSET(charenc), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX, FLAGS},
+    {NULL},
+};
+
+AVFILTER_DEFINE_CLASS(subtitles);
+
+static av_cold int init_subtitles(AVFilterContext *ctx, const char *args)
+{
+    int ret, sid;
+    AVDictionary *codec_opts = NULL;
+    AVFormatContext *fmt = NULL;
+    AVCodecContext *dec_ctx = NULL;
+    AVCodec *dec = NULL;
+    const AVCodecDescriptor *dec_desc;
+    AVStream *st;
+    AVPacket pkt;
+    AssContext *ass = ctx->priv;
+
+    /* Init libass */
+    ret = init(ctx, args, &subtitles_class);
+    if (ret < 0)
+        return ret;
+    ass->track = ass_new_track(ass->library);
+    if (!ass->track) {
+        av_log(ctx, AV_LOG_ERROR, "Could not create a libass track\n");
+        return AVERROR(EINVAL);
+    }
+
+    /* Open subtitles file */
+    ret = avformat_open_input(&fmt, ass->filename, NULL, NULL);
+    if (ret < 0) {
+        av_log(ctx, AV_LOG_ERROR, "Unable to open %s\n", ass->filename);
+        goto end;
+    }
+    ret = avformat_find_stream_info(fmt, NULL);
+    if (ret < 0)
+        goto end;
+
+    /* Locate subtitles stream */
+    ret = av_find_best_stream(fmt, AVMEDIA_TYPE_SUBTITLE, -1, -1, NULL, 0);
+    if (ret < 0) {
+        av_log(ctx, AV_LOG_ERROR, "Unable to locate subtitle stream in %s\n",
+               ass->filename);
+        goto end;
+    }
+    sid = ret;
+    st = fmt->streams[sid];
+
+    /* Open decoder */
+    dec_ctx = st->codec;
+    dec = avcodec_find_decoder(dec_ctx->codec_id);
+    if (!dec) {
+        av_log(ctx, AV_LOG_ERROR, "Failed to find subtitle codec %s\n",
+               avcodec_get_name(dec_ctx->codec_id));
+        return AVERROR(EINVAL);
+    }
+    dec_desc = avcodec_descriptor_get(dec_ctx->codec_id);
+    if (dec_desc && (dec_desc->props & AV_CODEC_PROP_BITMAP_SUB)) {
+        av_log(ctx, AV_LOG_ERROR,
+               "Only text based subtitles are currently supported\n");
+        return AVERROR_PATCHWELCOME;
+    }
+    if (ass->charenc)
+        av_dict_set(&codec_opts, "sub_charenc", ass->charenc, 0);
+    ret = avcodec_open2(dec_ctx, dec, &codec_opts);
+    if (ret < 0)
+        goto end;
+
+    /* Decode subtitles and push them into the renderer (libass) */
+    if (dec_ctx->subtitle_header)
+        ass_process_codec_private(ass->track,
+                                  dec_ctx->subtitle_header,
+                                  dec_ctx->subtitle_header_size);
+    av_init_packet(&pkt);
+    pkt.data = NULL;
+    pkt.size = 0;
+    while (av_read_frame(fmt, &pkt) >= 0) {
+        int i, got_subtitle;
+        AVSubtitle sub;
+
+        if (pkt.stream_index == sid) {
+            ret = avcodec_decode_subtitle2(dec_ctx, &sub, &got_subtitle, &pkt);
+            if (ret < 0) {
+                av_log(ctx, AV_LOG_WARNING, "Error decoding: %s (ignored)\n",
+                       av_err2str(ret));
+            } else if (got_subtitle) {
+                for (i = 0; i < sub.num_rects; i++) {
+                    char *ass_line = sub.rects[i]->ass;
+                    if (!ass_line)
+                        break;
+                    ass_process_data(ass->track, ass_line, strlen(ass_line));
+                }
+            }
+        }
+        av_free_packet(&pkt);
+        avsubtitle_free(&sub);
+    }
+
+end:
+    av_dict_free(&codec_opts);
+    if (dec_ctx)
+        avcodec_close(dec_ctx);
+    if (fmt)
+        avformat_close_input(&fmt);
+    return ret;
+}
+
+AVFilter avfilter_vf_subtitles = {
+    .name          = "subtitles",
+    .description   = NULL_IF_CONFIG_SMALL("Render text subtitles onto input video using the libass library."),
+    .priv_size     = sizeof(AssContext),
+    .init          = init_subtitles,
+    .uninit        = uninit,
+    .query_formats = query_formats,
+    .inputs        = ass_inputs,
+    .outputs       = ass_outputs,
+    .priv_class    = &subtitles_class,
+};
+#endif
diff --git a/libavfilter/vf_swapuv.c b/libavfilter/vf_swapuv.c
index 6345c0d..82cc07c 100644
--- a/libavfilter/vf_swapuv.c
+++ b/libavfilter/vf_swapuv.c
@@ -23,8 +23,10 @@
  * swap UV filter
  */
 
+#include "libavutil/pixdesc.h"
 #include "avfilter.h"
 #include "formats.h"
+#include "internal.h"
 #include "video.h"
 
 static AVFilterBufferRef *get_video_buffer(AVFilterLink *link, int perms,
@@ -32,45 +34,51 @@
 {
     AVFilterBufferRef *picref =
         ff_default_get_video_buffer(link, perms, w, h);
-    uint8_t *tmp;
-    int tmp2;
 
-    tmp             = picref->data[2];
-    picref->data[2] = picref->data[1];
-    picref->data[1] = tmp;
-
-    tmp2                = picref->linesize[2];
-    picref->linesize[2] = picref->linesize[1];
-    picref->linesize[1] = tmp2;
+    FFSWAP(uint8_t*, picref->data[1], picref->data[2]);
+    FFSWAP(int, picref->linesize[1], picref->linesize[2]);
 
     return picref;
 }
 
-static int start_frame(AVFilterLink *link, AVFilterBufferRef *inpicref)
+static int filter_frame(AVFilterLink *link, AVFilterBufferRef *inpicref)
 {
-    AVFilterBufferRef *outpicref = avfilter_ref_buffer(inpicref, ~0);
+    FFSWAP(uint8_t*, inpicref->data[1], inpicref->data[2]);
+    FFSWAP(int, inpicref->linesize[1], inpicref->linesize[2]);
 
-    outpicref->data[1] = inpicref->data[2];
-    outpicref->data[2] = inpicref->data[1];
+    return ff_filter_frame(link->dst->outputs[0], inpicref);
+}
 
-    outpicref->linesize[1] = inpicref->linesize[2];
-    outpicref->linesize[2] = inpicref->linesize[1];
+static int is_planar_yuv(const AVPixFmtDescriptor *desc)
+{
+    int i;
 
-    return ff_start_frame(link->dst->outputs[0], outpicref);
+    if (desc->flags & ~(PIX_FMT_BE | PIX_FMT_PLANAR | PIX_FMT_ALPHA) ||
+        desc->nb_components < 3 ||
+        (desc->comp[1].depth_minus1 != desc->comp[2].depth_minus1))
+        return 0;
+    for (i = 0; i < desc->nb_components; i++) {
+        if (desc->comp[i].offset_plus1 != 1 ||
+            desc->comp[i].shift != 0 ||
+            desc->comp[i].plane != i)
+            return 0;
+    }
+
+    return 1;
 }
 
 static int query_formats(AVFilterContext *ctx)
 {
-    static const enum AVPixelFormat pix_fmts[] = {
-        AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVA420P,
-        AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVA444P,
-        AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUVJ440P,
-        AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUVJ422P,
-        AV_PIX_FMT_YUV411P,
-        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 (is_planar_yuv(desc))
+            ff_add_format(&formats, fmt);
+    }
+
+    ff_set_common_formats(ctx, formats);
     return 0;
 }
 
@@ -79,7 +87,7 @@
         .name             = "default",
         .type             = AVMEDIA_TYPE_VIDEO,
         .get_video_buffer = get_video_buffer,
-        .start_frame      = start_frame,
+        .filter_frame     = filter_frame,
     },
     { NULL }
 };
diff --git a/libavfilter/vf_tile.c b/libavfilter/vf_tile.c
index 5f5c6d6..e4ced88 100644
--- a/libavfilter/vf_tile.c
+++ b/libavfilter/vf_tile.c
@@ -40,6 +40,7 @@
     unsigned nb_frames;
     FFDrawContext draw;
     FFDrawColor blank;
+    AVFilterBufferRef *out_ref;
 } TileContext;
 
 #define REASONABLE_SIZE 1024
@@ -99,7 +100,7 @@
 static int config_props(AVFilterLink *outlink)
 {
     AVFilterContext *ctx = outlink->src;
-    TileContext *tile   = ctx->priv;
+    TileContext *tile    = ctx->priv;
     AVFilterLink *inlink = ctx->inputs[0];
     const unsigned total_margin_w = (tile->w - 1) * tile->padding + 2*tile->margin;
     const unsigned total_margin_h = (tile->h - 1) * tile->padding + 2*tile->margin;
@@ -140,7 +141,7 @@
 static void draw_blank_frame(AVFilterContext *ctx, AVFilterBufferRef *out_buf)
 {
     TileContext *tile    = ctx->priv;
-    AVFilterLink *inlink  = ctx->inputs[0];
+    AVFilterLink *inlink = ctx->inputs[0];
     unsigned x0, y0;
 
     get_current_tile_pos(ctx, &x0, &y0);
@@ -151,12 +152,11 @@
 }
 static int end_last_frame(AVFilterContext *ctx)
 {
-    TileContext *tile    = ctx->priv;
+    TileContext *tile     = ctx->priv;
     AVFilterLink *outlink = ctx->outputs[0];
-    AVFilterBufferRef *out_buf = outlink->out_buf;
+    AVFilterBufferRef *out_buf = tile->out_ref;
     int ret;
 
-    outlink->out_buf = NULL;
     while (tile->current < tile->nb_frames)
         draw_blank_frame(ctx, out_buf);
     ret = ff_filter_frame(outlink, out_buf);
@@ -171,34 +171,34 @@
 static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
 {
     AVFilterContext *ctx  = inlink->dst;
-    TileContext *tile    = ctx->priv;
+    TileContext *tile     = ctx->priv;
     AVFilterLink *outlink = ctx->outputs[0];
     unsigned x0, y0;
 
     if (!tile->current) {
-        outlink->out_buf = ff_get_video_buffer(outlink, AV_PERM_WRITE,
-                                               outlink->w, outlink->h);
-        if (!outlink->out_buf)
+        tile->out_ref = ff_get_video_buffer(outlink, AV_PERM_WRITE,
+                                            outlink->w, outlink->h);
+        if (!tile->out_ref)
             return AVERROR(ENOMEM);
-        avfilter_copy_buffer_ref_props(outlink->out_buf, picref);
-        outlink->out_buf->video->w = outlink->w;
-        outlink->out_buf->video->h = outlink->h;
+        avfilter_copy_buffer_ref_props(tile->out_ref, picref);
+        tile->out_ref->video->w = outlink->w;
+        tile->out_ref->video->h = outlink->h;
 
         /* fill surface once for margin/padding */
         if (tile->margin || tile->padding)
             ff_fill_rectangle(&tile->draw, &tile->blank,
-                              outlink->out_buf->data,
-                              outlink->out_buf->linesize,
+                              tile->out_ref->data,
+                              tile->out_ref->linesize,
                               0, 0, outlink->w, outlink->h);
     }
 
     get_current_tile_pos(ctx, &x0, &y0);
     ff_copy_rectangle2(&tile->draw,
-                       outlink->out_buf->data, outlink->out_buf->linesize,
-                       inlink ->cur_buf->data, inlink ->cur_buf->linesize,
+                       tile->out_ref->data, tile->out_ref->linesize,
+                       picref->data, picref->linesize,
                        x0, y0, 0, 0, inlink->w, inlink->h);
 
-    avfilter_unref_bufferp(&inlink->cur_buf);
+    avfilter_unref_bufferp(&picref);
     if (++tile->current == tile->nb_frames)
         return end_last_frame(ctx);
 
@@ -208,7 +208,7 @@
 static int request_frame(AVFilterLink *outlink)
 {
     AVFilterContext *ctx = outlink->src;
-    TileContext *tile   = ctx->priv;
+    TileContext *tile    = ctx->priv;
     AVFilterLink *inlink = ctx->inputs[0];
     int r;
 
diff --git a/libavfilter/vf_tinterlace.c b/libavfilter/vf_tinterlace.c
index d24105e..909784e 100644
--- a/libavfilter/vf_tinterlace.c
+++ b/libavfilter/vf_tinterlace.c
@@ -25,6 +25,7 @@
  * temporal field interlace filter, ported from MPlayer/libmpcodecs
  */
 
+#include "libavutil/opt.h"
 #include "libavutil/imgutils.h"
 #include "libavutil/avassert.h"
 #include "avfilter.h"
@@ -38,21 +39,13 @@
     MODE_INTERLEAVE_TOP,
     MODE_INTERLEAVE_BOTTOM,
     MODE_INTERLACEX2,
-};
-
-static const char *tinterlace_mode_str[] = {
-    "merge",
-    "drop_even",
-    "drop_odd",
-    "pad",
-    "interleave_top",
-    "interleave_bottom",
-    "interlacex2",
-    NULL
+    MODE_NB,
 };
 
 typedef struct {
+    const AVClass *class;
     enum TInterlaceMode mode;   ///< interlace mode selected
+    int flags;                  ///< flags affecting interlacing algorithm
     int frame;                  ///< number of the output frame
     int vsub;                   ///< chroma vertical subsampling
     AVFilterBufferRef *cur;
@@ -61,6 +54,29 @@
     int black_linesize[4];
 } TInterlaceContext;
 
+#define OFFSET(x) offsetof(TInterlaceContext, x)
+#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
+#define TINTERLACE_FLAG_VLPF 01
+
+static const AVOption tinterlace_options[] = {
+    {"mode",              "select interlace mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=MODE_MERGE}, 0, MODE_NB-1, FLAGS, "mode"},
+    {"merge",             "merge fields",                                 0, AV_OPT_TYPE_CONST, {.i64=MODE_MERGE},             INT_MIN, INT_MAX, FLAGS, "mode"},
+    {"drop_even",         "drop even fields",                             0, AV_OPT_TYPE_CONST, {.i64=MODE_DROP_EVEN},         INT_MIN, INT_MAX, FLAGS, "mode"},
+    {"drop_odd",          "drop odd fields",                              0, AV_OPT_TYPE_CONST, {.i64=MODE_DROP_ODD},          INT_MIN, INT_MAX, FLAGS, "mode"},
+    {"pad",               "pad alternate lines with black",               0, AV_OPT_TYPE_CONST, {.i64=MODE_PAD},               INT_MIN, INT_MAX, FLAGS, "mode"},
+    {"interleave_top",    "interleave top and bottom fields",             0, AV_OPT_TYPE_CONST, {.i64=MODE_INTERLEAVE_TOP},    INT_MIN, INT_MAX, FLAGS, "mode"},
+    {"interleave_bottom", "interleave bottom and top fields",             0, AV_OPT_TYPE_CONST, {.i64=MODE_INTERLEAVE_BOTTOM}, INT_MIN, INT_MAX, FLAGS, "mode"},
+    {"interlacex2",       "interlace fields from two consecutive frames", 0, AV_OPT_TYPE_CONST, {.i64=MODE_INTERLACEX2},       INT_MIN, INT_MAX, FLAGS, "mode"},
+
+    {"flags",             "set flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, 0, INT_MAX, 0, "flags" },
+    {"low_pass_filter",   "enable vertical low-pass filter",              0, AV_OPT_TYPE_CONST, {.i64 = TINTERLACE_FLAG_VLPF}, INT_MIN, INT_MAX, FLAGS, "flags" },
+    {"vlpf",              "enable vertical low-pass filter",              0, AV_OPT_TYPE_CONST, {.i64 = TINTERLACE_FLAG_VLPF}, INT_MIN, INT_MAX, FLAGS, "flags" },
+
+    {NULL}
+};
+
+AVFILTER_DEFINE_CLASS(tinterlace);
+
 #define FULL_SCALE_YUVJ_FORMATS \
     AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ440P
 
@@ -84,45 +100,22 @@
 static av_cold int init(AVFilterContext *ctx, const char *args)
 {
     TInterlaceContext *tinterlace = ctx->priv;
-    int i;
-    char c;
+    static const char *shorthand[] = { "mode", NULL };
 
-    tinterlace->mode = MODE_MERGE;
+    tinterlace->class = &tinterlace_class;
+    av_opt_set_defaults(tinterlace);
 
-    if (args) {
-        if (sscanf(args, "%d%c", (int *)&tinterlace->mode, &c) == 1) {
-            if (tinterlace->mode > 6) {
-                av_log(ctx, AV_LOG_ERROR,
-                       "Invalid mode '%s', use an integer between 0 and 6\n", args);
-                return AVERROR(EINVAL);
-            }
-
-            av_log(ctx, AV_LOG_WARNING,
-                   "Using numeric constant is deprecated, use symbolic values\n");
-        } else {
-            for (i = 0; tinterlace_mode_str[i]; i++) {
-                if (!strcmp(tinterlace_mode_str[i], args)) {
-                    tinterlace->mode = i;
-                    break;
-                }
-            }
-            if (!tinterlace_mode_str[i]) {
-                av_log(ctx, AV_LOG_ERROR, "Invalid argument '%s'\n", args);
-                return AVERROR(EINVAL);
-            }
-        }
-    }
-
-    return 0;
+    return av_opt_set_from_string(tinterlace, args, shorthand, "=", ":");
 }
 
 static av_cold void uninit(AVFilterContext *ctx)
 {
     TInterlaceContext *tinterlace = ctx->priv;
 
-    if (tinterlace->cur ) avfilter_unref_bufferp(&tinterlace->cur );
-    if (tinterlace->next) avfilter_unref_bufferp(&tinterlace->next);
+    avfilter_unref_bufferp(&tinterlace->cur );
+    avfilter_unref_bufferp(&tinterlace->next);
 
+    av_opt_free(tinterlace);
     av_freep(&tinterlace->black_data[0]);
 }
 
@@ -155,8 +148,16 @@
                    tinterlace->black_linesize[i] * h);
         }
     }
-    av_log(ctx, AV_LOG_VERBOSE, "mode:%s h:%d -> h:%d\n",
-           tinterlace_mode_str[tinterlace->mode], inlink->h, outlink->h);
+    if ((tinterlace->flags & TINTERLACE_FLAG_VLPF)
+            && !(tinterlace->mode == MODE_INTERLEAVE_TOP
+              || tinterlace->mode == MODE_INTERLEAVE_BOTTOM)) {
+        av_log(ctx, AV_LOG_WARNING, "low_pass_filter flag ignored with mode %d\n",
+                tinterlace->mode);
+        tinterlace->flags &= ~TINTERLACE_FLAG_VLPF;
+    }
+    av_log(ctx, AV_LOG_VERBOSE, "mode:%d filter:%s h:%d -> h:%d\n",
+           tinterlace->mode, (tinterlace->flags & TINTERLACE_FLAG_VLPF) ? "on" : "off",
+           inlink->h, outlink->h);
 
     return 0;
 }
@@ -172,16 +173,19 @@
  * @param interleave leave a padding line between each copied line
  * @param dst_field copy to upper or lower field,
  *        only meaningful when interleave is selected
+ * @param flags context flags
  */
 static inline
 void copy_picture_field(uint8_t *dst[4], int dst_linesize[4],
                         const uint8_t *src[4], int src_linesize[4],
                         enum AVPixelFormat format, int w, int src_h,
-                        int src_field, int interleave, int dst_field)
+                        int src_field, int interleave, int dst_field,
+                        int flags)
 {
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(format);
     int plane, vsub = desc->log2_chroma_h;
     int k = src_field == FIELD_UPPER_AND_LOWER ? 1 : 2;
+    int h, i;
 
     for (plane = 0; plane < desc->nb_components; plane++) {
         int lines = plane == 1 || plane == 2 ? src_h >> vsub : src_h;
@@ -197,33 +201,47 @@
             srcp += src_linesize[plane];
         if (interleave && dst_field == FIELD_LOWER)
             dstp += dst_linesize[plane];
-        av_image_copy_plane(dstp, dst_linesize[plane] * (interleave ? 2 : 1),
+        if (flags & TINTERLACE_FLAG_VLPF) {
+            // Low-pass filtering is required when creating an interlaced destination from
+            // a progressive source which contains high-frequency vertical detail.
+            // Filtering will reduce interlace 'twitter' and Moire patterning.
+            int srcp_linesize = src_linesize[plane] * k;
+            int dstp_linesize = dst_linesize[plane] * (interleave ? 2 : 1);
+            for (h = lines; h > 0; h--) {
+                const uint8_t *srcp_above = srcp - src_linesize[plane];
+                const uint8_t *srcp_below = srcp + src_linesize[plane];
+                if (h == lines) srcp_above = srcp; // there is no line above
+                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'
+                    // '1 +' is for rounding. */
+                    dstp[i] = (1 + srcp[i] + srcp[i] + srcp_above[i] + srcp_below[i]) >> 2;
+                }
+                dstp += dstp_linesize;
+                srcp += srcp_linesize;
+            }
+        } else {
+            av_image_copy_plane(dstp, dst_linesize[plane] * (interleave ? 2 : 1),
                             srcp, src_linesize[plane]*k, linesize, lines);
+        }
     }
 }
 
-static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
-{
-    AVFilterContext *ctx = inlink->dst;
-    TInterlaceContext *tinterlace = ctx->priv;
-
-    avfilter_unref_buffer(tinterlace->cur);
-    tinterlace->cur  = tinterlace->next;
-    tinterlace->next = picref;
-    inlink->cur_buf = NULL;
-    return 0;
-}
-
-static int end_frame(AVFilterLink *inlink)
+static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
 {
     AVFilterContext *ctx = inlink->dst;
     AVFilterLink *outlink = ctx->outputs[0];
     TInterlaceContext *tinterlace = ctx->priv;
-    AVFilterBufferRef *cur  = tinterlace->cur;
-    AVFilterBufferRef *next = tinterlace->next;
-    AVFilterBufferRef *out  = NULL;
-    int field, tff;
+    AVFilterBufferRef *cur, *next, *out;
+    int field, tff, ret;
 
+    avfilter_unref_buffer(tinterlace->cur);
+    tinterlace->cur  = tinterlace->next;
+    tinterlace->next = picref;
+
+    cur = tinterlace->cur;
+    next = tinterlace->next;
     /* we need at least two frames */
     if (!tinterlace->cur)
         return 0;
@@ -232,6 +250,8 @@
     case MODE_MERGE: /* move the odd frame into the upper field of the new image, even into
              * the lower field, generating a double-height video at half framerate */
         out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
+        if (!out)
+            return AVERROR(ENOMEM);
         avfilter_copy_buffer_ref_props(out, cur);
         out->video->h = outlink->h;
         out->video->interlaced = 1;
@@ -241,12 +261,12 @@
         copy_picture_field(out->data, out->linesize,
                            (const uint8_t **)cur->data, cur->linesize,
                            inlink->format, inlink->w, inlink->h,
-                           FIELD_UPPER_AND_LOWER, 1, FIELD_UPPER);
+                           FIELD_UPPER_AND_LOWER, 1, FIELD_UPPER, tinterlace->flags);
         /* write even frame lines into the lower field of the new frame */
         copy_picture_field(out->data, out->linesize,
                            (const uint8_t **)next->data, next->linesize,
                            inlink->format, inlink->w, inlink->h,
-                           FIELD_UPPER_AND_LOWER, 1, FIELD_LOWER);
+                           FIELD_UPPER_AND_LOWER, 1, FIELD_LOWER, tinterlace->flags);
         avfilter_unref_bufferp(&tinterlace->next);
         break;
 
@@ -267,12 +287,12 @@
         copy_picture_field(out->data, out->linesize,
                            (const uint8_t **)cur->data, cur->linesize,
                            inlink->format, inlink->w, inlink->h,
-                           FIELD_UPPER_AND_LOWER, 1, field);
+                           FIELD_UPPER_AND_LOWER, 1, field, tinterlace->flags);
         /* pad with black the other field */
         copy_picture_field(out->data, out->linesize,
                            (const uint8_t **)tinterlace->black_data, tinterlace->black_linesize,
                            inlink->format, inlink->w, inlink->h,
-                           FIELD_UPPER_AND_LOWER, 1, !field);
+                           FIELD_UPPER_AND_LOWER, 1, !field, tinterlace->flags);
         break;
 
         /* interleave upper/lower lines from odd frames with lower/upper lines from even frames,
@@ -281,6 +301,8 @@
     case MODE_INTERLEAVE_BOTTOM: /* bottom field first */
         tff = tinterlace->mode == MODE_INTERLEAVE_TOP;
         out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
+        if (!out)
+            return AVERROR(ENOMEM);
         avfilter_copy_buffer_ref_props(out, cur);
         out->video->interlaced = 1;
         out->video->top_field_first = tff;
@@ -289,26 +311,31 @@
         copy_picture_field(out->data, out->linesize,
                            (const uint8_t **)cur->data, cur->linesize,
                            inlink->format, inlink->w, inlink->h,
-                           tff ? FIELD_UPPER : FIELD_LOWER, 1, tff ? FIELD_UPPER : FIELD_LOWER);
+                           tff ? FIELD_UPPER : FIELD_LOWER, 1, tff ? FIELD_UPPER : FIELD_LOWER,
+                           tinterlace->flags);
         /* copy lower/upper field from next */
         copy_picture_field(out->data, out->linesize,
                            (const uint8_t **)next->data, next->linesize,
                            inlink->format, inlink->w, inlink->h,
-                           tff ? FIELD_LOWER : FIELD_UPPER, 1, tff ? FIELD_LOWER : FIELD_UPPER);
+                           tff ? FIELD_LOWER : FIELD_UPPER, 1, tff ? FIELD_LOWER : FIELD_UPPER,
+                           tinterlace->flags);
         avfilter_unref_bufferp(&tinterlace->next);
         break;
     case MODE_INTERLACEX2: /* re-interlace preserving image height, double frame rate */
         /* output current frame first */
         out = avfilter_ref_buffer(cur, ~AV_PERM_WRITE);
+        if (!out)
+            return AVERROR(ENOMEM);
         out->video->interlaced = 1;
 
-        ff_start_frame(outlink, out);
-        ff_draw_slice(outlink, 0, outlink->h, 1);
-        ff_end_frame(outlink);
+        if ((ret = ff_filter_frame(outlink, out)) < 0)
+            return ret;
 
         /* output mix of current and next frame */
         tff = next->video->top_field_first;
         out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
+        if (!out)
+            return AVERROR(ENOMEM);
         avfilter_copy_buffer_ref_props(out, next);
         out->video->interlaced = 1;
 
@@ -316,22 +343,23 @@
         copy_picture_field(out->data, out->linesize,
                            (const uint8_t **)cur->data, cur->linesize,
                            inlink->format, inlink->w, inlink->h,
-                           tff ? FIELD_LOWER : FIELD_UPPER, 1, tff ? FIELD_LOWER : FIELD_UPPER);
+                           tff ? FIELD_LOWER : FIELD_UPPER, 1, tff ? FIELD_LOWER : FIELD_UPPER,
+                           tinterlace->flags);
         /* write next frame first field lines into the first field of the new frame */
         copy_picture_field(out->data, out->linesize,
                            (const uint8_t **)next->data, next->linesize,
                            inlink->format, inlink->w, inlink->h,
-                           tff ? FIELD_UPPER : FIELD_LOWER, 1, tff ? FIELD_UPPER : FIELD_LOWER);
+                           tff ? FIELD_UPPER : FIELD_LOWER, 1, tff ? FIELD_UPPER : FIELD_LOWER,
+                           tinterlace->flags);
         break;
+    default:
+        av_assert0(0);
     }
 
-    ff_start_frame(outlink, out);
-    ff_draw_slice(outlink, 0, outlink->h, 1);
-    ff_end_frame(outlink);
-
+    ret = ff_filter_frame(outlink, out);
     tinterlace->frame++;
 
-    return 0;
+    return ret;
 }
 
 static int request_frame(AVFilterLink *outlink)
@@ -349,15 +377,11 @@
     return 0;
 }
 
-static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { return 0; }
-
 static const AVFilterPad tinterlace_inputs[] = {
     {
         .name         = "default",
         .type         = AVMEDIA_TYPE_VIDEO,
-        .start_frame  = start_frame,
-        .draw_slice   = null_draw_slice,
-        .end_frame    = end_frame,
+        .filter_frame = filter_frame,
     },
     { NULL }
 };
@@ -381,4 +405,5 @@
     .query_formats = query_formats,
     .inputs        = tinterlace_inputs,
     .outputs       = tinterlace_outputs,
+    .priv_class    = &tinterlace_class,
 };
diff --git a/libavfilter/vf_transpose.c b/libavfilter/vf_transpose.c
index 6026caa..270d346 100644
--- a/libavfilter/vf_transpose.c
+++ b/libavfilter/vf_transpose.c
@@ -86,28 +86,20 @@
 
 static int query_formats(AVFilterContext *ctx)
 {
-    enum AVPixelFormat pix_fmts[] = {
-        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_YUV444P16LE,  AV_PIX_FMT_YUV444P16BE,
-        AV_PIX_FMT_NV12,         AV_PIX_FMT_NV21,
-        AV_PIX_FMT_RGB8,         AV_PIX_FMT_BGR8,
-        AV_PIX_FMT_RGB4_BYTE,    AV_PIX_FMT_BGR4_BYTE,
-        AV_PIX_FMT_YUV444P,      AV_PIX_FMT_YUVJ444P,
-        AV_PIX_FMT_YUV420P,      AV_PIX_FMT_YUVJ420P,
-        AV_PIX_FMT_YUV410P,
-        AV_PIX_FMT_YUVA420P,     AV_PIX_FMT_GRAY8,
-        AV_PIX_FMT_NONE
-    };
+    AVFilterFormats *pix_fmts = 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 & PIX_FMT_PAL ||
+              desc->flags & PIX_FMT_HWACCEL ||
+              desc->flags & PIX_FMT_BITSTREAM ||
+              desc->log2_chroma_w != desc->log2_chroma_h))
+            ff_add_format(&pix_fmts, fmt);
+    }
+
+
+    ff_set_common_formats(ctx, pix_fmts);
     return 0;
 }
 
@@ -236,6 +228,16 @@
                 for (x = 0; x < outw; x++)
                     *((uint32_t *)(dst + 4*x)) = *((uint32_t *)(src + x*srclinesize + y*4));
                 break;
+            case 6:
+                for (x = 0; x < outw; x++) {
+                    int64_t v = AV_RB48(src + x*srclinesize + y*6);
+                    AV_WB48(dst + 6*x, v);
+                }
+                break;
+            case 8:
+                for (x = 0; x < outw; x++)
+                    *((uint64_t *)(dst + 8*x)) = *((uint64_t *)(src + x*srclinesize + y*8));
+                break;
             }
             dst += dstlinesize;
         }
diff --git a/libavfilter/vf_unsharp.c b/libavfilter/vf_unsharp.c
index 1e1b009..8c6e18a 100644
--- a/libavfilter/vf_unsharp.c
+++ b/libavfilter/vf_unsharp.c
@@ -36,16 +36,19 @@
  * 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/mem.h"
+#include "libavutil/opt.h"
 #include "libavutil/pixdesc.h"
 
-#define MIN_SIZE 3
-#define MAX_SIZE 13
+#define MIN_MATRIX_SIZE 3
+#define MAX_MATRIX_SIZE 63
 
 /* right-shift and round-up */
 #define SHIFTUP(x,shift) (-((-(x))>>(shift)))
@@ -58,27 +61,57 @@
     int steps_y;                             ///< vertical step count
     int scalebits;                           ///< bits to shift pixel
     int32_t halfscale;                       ///< amount to add to pixel
-    uint32_t *sc[(MAX_SIZE * MAX_SIZE) - 1]; ///< finite state machine storage
+    uint32_t *sc[MAX_MATRIX_SIZE - 1];       ///< finite state machine storage
 } FilterParam;
 
 typedef struct {
+    const AVClass *class;
     FilterParam luma;   ///< luma parameters (width, height, amount)
     FilterParam chroma; ///< chroma parameters (width, height, amount)
     int hsub, vsub;
+    int luma_msize_x, luma_msize_y, chroma_msize_x, chroma_msize_y;
+    double luma_amount, chroma_amount;
 } UnsharpContext;
 
+#define OFFSET(x) offsetof(UnsharpContext, x)
+
+static const AVOption unsharp_options[] = {
+    { "luma_msize_x",    "set luma matrix x size",     OFFSET(luma_msize_x),    AV_OPT_TYPE_INT,    {.i64=5}, 3, 63 },
+    { "lx",              "set luma matrix x size",     OFFSET(luma_msize_x),    AV_OPT_TYPE_INT,    {.i64=5}, 3, 63 },
+    { "luma_msize_y",    "set luma matrix y size",     OFFSET(luma_msize_y),    AV_OPT_TYPE_INT,    {.i64=5}, 3, 63 },
+    { "ly",              "set luma matrix y size",     OFFSET(luma_msize_y),    AV_OPT_TYPE_INT,    {.i64=5}, 3, 63 },
+    { "luma_amount",     "set luma effect amount",     OFFSET(luma_amount),     AV_OPT_TYPE_DOUBLE, {.dbl=1.0}, -DBL_MAX, DBL_MAX },
+    { "la",              "set luma effect amount",     OFFSET(luma_amount),     AV_OPT_TYPE_DOUBLE, {.dbl=1.0}, -DBL_MAX, DBL_MAX },
+
+    { "chroma_msize_x",  "set chroma matrix x size",   OFFSET(chroma_msize_x), AV_OPT_TYPE_INT,    {.i64=5}, 3, 63 },
+    { "cx",              "set chroma matrix x size",   OFFSET(chroma_msize_x), AV_OPT_TYPE_INT,    {.i64=5}, 3, 63 },
+    { "chroma_msize_y",  "set chroma matrix y size",   OFFSET(chroma_msize_y), AV_OPT_TYPE_INT,    {.i64=5}, 3, 63 },
+    { "cy"          ,    "set chroma matrix y size",   OFFSET(chroma_msize_y), AV_OPT_TYPE_INT,    {.i64=5}, 3, 63 },
+    { "chroma_amount",   "set chroma effect strenght", OFFSET(chroma_amount),  AV_OPT_TYPE_DOUBLE, {.dbl=0.0}, -DBL_MAX, DBL_MAX },
+    { "ca",              "set chroma effect strenght", OFFSET(chroma_amount),  AV_OPT_TYPE_DOUBLE, {.dbl=0.0}, -DBL_MAX, DBL_MAX },
+
+    { NULL }
+};
+
+AVFILTER_DEFINE_CLASS(unsharp);
+
 static void apply_unsharp(      uint8_t *dst, int dst_stride,
                           const uint8_t *src, int src_stride,
                           int width, int height, FilterParam *fp)
 {
     uint32_t **sc = fp->sc;
-    uint32_t sr[(MAX_SIZE * MAX_SIZE) - 1], tmp1, tmp2;
+    uint32_t sr[MAX_MATRIX_SIZE - 1], tmp1, tmp2;
 
     int32_t res;
     int x, y, z;
     const uint8_t *src2 = NULL;  //silence a warning
+    const int amount = fp->amount;
+    const int steps_x = fp->steps_x;
+    const int steps_y = fp->steps_y;
+    const int scalebits = fp->scalebits;
+    const int32_t halfscale = fp->halfscale;
 
-    if (!fp->amount) {
+    if (!amount) {
         if (dst_stride == src_stride)
             memcpy(dst, src, src_stride * height);
         else
@@ -87,29 +120,29 @@
         return;
     }
 
-    for (y = 0; y < 2 * fp->steps_y; y++)
-        memset(sc[y], 0, sizeof(sc[y][0]) * (width + 2 * fp->steps_x));
+    for (y = 0; y < 2 * steps_y; y++)
+        memset(sc[y], 0, sizeof(sc[y][0]) * (width + 2 * steps_x));
 
-    for (y = -fp->steps_y; y < height + fp->steps_y; y++) {
+    for (y = -steps_y; y < height + steps_y; y++) {
         if (y < height)
             src2 = src;
 
-        memset(sr, 0, sizeof(sr[0]) * (2 * fp->steps_x - 1));
-        for (x = -fp->steps_x; x < width + fp->steps_x; x++) {
+        memset(sr, 0, sizeof(sr[0]) * (2 * steps_x - 1));
+        for (x = -steps_x; x < width + steps_x; x++) {
             tmp1 = x <= 0 ? src2[0] : x >= width ? src2[width-1] : src2[x];
-            for (z = 0; z < fp->steps_x * 2; z += 2) {
+            for (z = 0; z < steps_x * 2; z += 2) {
                 tmp2 = sr[z + 0] + tmp1; sr[z + 0] = tmp1;
                 tmp1 = sr[z + 1] + tmp2; sr[z + 1] = tmp2;
             }
-            for (z = 0; z < fp->steps_y * 2; z += 2) {
-                tmp2 = sc[z + 0][x + fp->steps_x] + tmp1; sc[z + 0][x + fp->steps_x] = tmp1;
-                tmp1 = sc[z + 1][x + fp->steps_x] + tmp2; sc[z + 1][x + fp->steps_x] = tmp2;
+            for (z = 0; z < steps_y * 2; z += 2) {
+                tmp2 = sc[z + 0][x + steps_x] + tmp1; sc[z + 0][x + steps_x] = tmp1;
+                tmp1 = sc[z + 1][x + steps_x] + tmp2; sc[z + 1][x + steps_x] = tmp2;
             }
-            if (x >= fp->steps_x && y >= fp->steps_y) {
-                const uint8_t *srx = src - fp->steps_y * src_stride + x - fp->steps_x;
-                uint8_t *dsx       = dst - fp->steps_y * dst_stride + x - fp->steps_x;
+            if (x >= steps_x && y >= steps_y) {
+                const uint8_t *srx = src - steps_y * src_stride + x - steps_x;
+                uint8_t *dsx       = dst - steps_y * dst_stride + x - steps_x;
 
-                res = (int32_t)*srx + ((((int32_t) * srx - (int32_t)((tmp1 + fp->halfscale) >> fp->scalebits)) * fp->amount) >> 16);
+                res = (int32_t)*srx + ((((int32_t) * srx - (int32_t)((tmp1 + halfscale) >> scalebits)) * amount) >> 16);
                 *dsx = av_clip_uint8(res);
             }
         }
@@ -135,31 +168,28 @@
 static av_cold int init(AVFilterContext *ctx, const char *args)
 {
     UnsharpContext *unsharp = ctx->priv;
-    int lmsize_x = 5, cmsize_x = 5;
-    int lmsize_y = 5, cmsize_y = 5;
-    double lamount = 1.0f, camount = 0.0f;
+    static const char *shorthand[] = {
+        "luma_msize_x", "luma_msize_y", "luma_amount",
+        "chroma_msize_x", "chroma_msize_y", "chroma_amount",
+        NULL
+    };
+    int ret;
 
-    if (args)
-        sscanf(args, "%d:%d:%lf:%d:%d:%lf", &lmsize_x, &lmsize_y, &lamount,
-                                            &cmsize_x, &cmsize_y, &camount);
+    unsharp->class = &unsharp_class;
+    av_opt_set_defaults(unsharp);
 
-    if ((lamount && (lmsize_x < 2 || lmsize_y < 2)) ||
-        (camount && (cmsize_x < 2 || cmsize_y < 2))) {
-        av_log(ctx, AV_LOG_ERROR,
-               "Invalid value <2 for lmsize_x:%d or lmsize_y:%d or cmsize_x:%d or cmsize_y:%d\n",
-               lmsize_x, lmsize_y, cmsize_x, cmsize_y);
-        return AVERROR(EINVAL);
-    }
+    if ((ret = av_opt_set_from_string(unsharp, args, shorthand, "=", ":")) < 0)
+        return ret;
 
-    set_filter_param(&unsharp->luma,   lmsize_x, lmsize_y, lamount);
-    set_filter_param(&unsharp->chroma, cmsize_x, cmsize_y, camount);
+    set_filter_param(&unsharp->luma,   unsharp->luma_msize_x,   unsharp->luma_msize_y,   unsharp->luma_amount);
+    set_filter_param(&unsharp->chroma, unsharp->chroma_msize_x, unsharp->chroma_msize_y, unsharp->chroma_amount);
 
     return 0;
 }
 
 static int query_formats(AVFilterContext *ctx)
 {
-    enum AVPixelFormat pix_fmts[] = {
+    static const enum AVPixelFormat pix_fmts[] = {
         AV_PIX_FMT_YUV420P,  AV_PIX_FMT_YUV422P,  AV_PIX_FMT_YUV444P,  AV_PIX_FMT_YUV410P,
         AV_PIX_FMT_YUV411P,  AV_PIX_FMT_YUV440P,  AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P,
         AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ440P, AV_PIX_FMT_NONE
@@ -170,30 +200,43 @@
     return 0;
 }
 
-static void init_filter_param(AVFilterContext *ctx, FilterParam *fp, const char *effect_type, int width)
+static int init_filter_param(AVFilterContext *ctx, FilterParam *fp, const char *effect_type, int width)
 {
     int z;
-    const char *effect;
+    const char *effect = fp->amount == 0 ? "none" : fp->amount < 0 ? "blur" : "sharpen";
 
-    effect = fp->amount == 0 ? "none" : fp->amount < 0 ? "blur" : "sharpen";
+    if  (!(fp->msize_x & fp->msize_y & 1)) {
+        av_log(ctx, AV_LOG_ERROR,
+               "Invalid even size for %s matrix size %dx%d\n",
+               effect_type, fp->msize_x, fp->msize_y);
+        return AVERROR(EINVAL);
+    }
 
     av_log(ctx, AV_LOG_VERBOSE, "effect:%s type:%s msize_x:%d msize_y:%d amount:%0.2f\n",
            effect, effect_type, fp->msize_x, fp->msize_y, fp->amount / 65535.0);
 
     for (z = 0; z < 2 * fp->steps_y; z++)
-        fp->sc[z] = av_malloc(sizeof(*(fp->sc[z])) * (width + 2 * fp->steps_x));
+        if (!(fp->sc[z] = av_malloc(sizeof(*(fp->sc[z])) * (width + 2 * fp->steps_x))))
+            return AVERROR(ENOMEM);
+
+    return 0;
 }
 
 static int config_props(AVFilterLink *link)
 {
     UnsharpContext *unsharp = link->dst->priv;
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format);
+    int ret;
 
     unsharp->hsub = desc->log2_chroma_w;
     unsharp->vsub = desc->log2_chroma_h;
 
-    init_filter_param(link->dst, &unsharp->luma,   "luma",   link->w);
-    init_filter_param(link->dst, &unsharp->chroma, "chroma", SHIFTUP(link->w, unsharp->hsub));
+    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));
+    if (ret < 0)
+        return ret;
 
     return 0;
 }
@@ -212,6 +255,7 @@
 
     free_filter_param(&unsharp->luma);
     free_filter_param(&unsharp->chroma);
+    av_opt_free(unsharp);
 }
 
 static int filter_frame(AVFilterLink *link, AVFilterBufferRef *in)
@@ -269,4 +313,6 @@
     .inputs    = avfilter_vf_unsharp_inputs,
 
     .outputs   = avfilter_vf_unsharp_outputs,
+
+    .priv_class = &unsharp_class,
 };
diff --git a/libavfilter/vf_yadif.c b/libavfilter/vf_yadif.c
index b35f98d..b7c2d80 100644
--- a/libavfilter/vf_yadif.c
+++ b/libavfilter/vf_yadif.c
@@ -20,6 +20,7 @@
 #include "libavutil/avassert.h"
 #include "libavutil/cpu.h"
 #include "libavutil/common.h"
+#include "libavutil/opt.h"
 #include "libavutil/pixdesc.h"
 #include "avfilter.h"
 #include "formats.h"
@@ -33,15 +34,15 @@
 #define PERM_RWP AV_PERM_WRITE | AV_PERM_PRESERVE | AV_PERM_REUSE
 
 #define CHECK(j)\
-    {   int score = FFABS(cur[mrefs-1+(j)] - cur[prefs-1-(j)])\
+    {   int score = FFABS(cur[mrefs + off_left + (j)] - cur[prefs + off_left - (j)])\
                   + FFABS(cur[mrefs  +(j)] - cur[prefs  -(j)])\
-                  + FFABS(cur[mrefs+1+(j)] - cur[prefs+1-(j)]);\
+                  + FFABS(cur[mrefs + off_right + (j)] - cur[prefs + off_right - (j)]);\
         if (score < spatial_score) {\
             spatial_score= score;\
             spatial_pred= (cur[mrefs  +(j)] + cur[prefs  -(j)])>>1;\
 
-#define FILTER \
-    for (x = 0;  x < w; x++) { \
+#define FILTER(start, end) \
+    for (x = start;  x < end; x++) { \
         int c = cur[mrefs]; \
         int d = (prev2[0] + next2[0])>>1; \
         int e = cur[prefs]; \
@@ -50,11 +51,15 @@
         int temporal_diff2 =(FFABS(next[mrefs] - c) + FFABS(next[prefs] - e) )>>1; \
         int diff = FFMAX3(temporal_diff0 >> 1, temporal_diff1, temporal_diff2); \
         int spatial_pred = (c+e) >> 1; \
-        int spatial_score = FFABS(cur[mrefs - 1] - cur[prefs - 1]) + FFABS(c-e) \
-                          + FFABS(cur[mrefs + 1] - cur[prefs + 1]) - 1; \
+        int off_right = (x < w - 1) ? 1 : -1;\
+        int off_left  = x ? -1 : 1;\
+        int spatial_score = FFABS(cur[mrefs + off_left]  - cur[prefs + off_left]) + FFABS(c-e) \
+                          + FFABS(cur[mrefs + off_right] - cur[prefs + off_right]) - 1; \
  \
-        CHECK(-1) CHECK(-2) }} }} \
-        CHECK( 1) CHECK( 2) }} }} \
+        if (x > 2 && x < w - 3) {\
+            CHECK(-1) CHECK(-2) }} }} \
+            CHECK( 1) CHECK( 2) }} }} \
+        }\
  \
         if (mode < 2) { \
             int b = (prev2[2 * mrefs] + next2[2 * mrefs])>>1; \
@@ -80,29 +85,86 @@
         next2++; \
     }
 
-static void filter_line_c(uint8_t *dst,
-                          uint8_t *prev, uint8_t *cur, uint8_t *next,
+static void filter_line_c(void *dst1,
+                          void *prev1, void *cur1, void *next1,
                           int w, int prefs, int mrefs, int parity, int mode)
 {
+    uint8_t *dst  = dst1;
+    uint8_t *prev = prev1;
+    uint8_t *cur  = cur1;
+    uint8_t *next = next1;
     int x;
     uint8_t *prev2 = parity ? prev : cur ;
     uint8_t *next2 = parity ? cur  : next;
 
-    FILTER
+    FILTER(0, w)
 }
 
-static void filter_line_c_16bit(uint16_t *dst,
-                                uint16_t *prev, uint16_t *cur, uint16_t *next,
+static void filter_edges(void *dst1, void *prev1, void *cur1, void *next1,
+                         int w, int prefs, int mrefs, int parity, int mode,
+                         int l_edge)
+{
+    uint8_t *dst  = dst1;
+    uint8_t *prev = prev1;
+    uint8_t *cur  = cur1;
+    uint8_t *next = next1;
+    int x;
+    uint8_t *prev2 = parity ? prev : cur ;
+    uint8_t *next2 = parity ? cur  : next;
+
+    FILTER(0, l_edge)
+
+    dst  = (uint8_t*)dst1  + w - 3;
+    prev = (uint8_t*)prev1 + w - 3;
+    cur  = (uint8_t*)cur1  + w - 3;
+    next = (uint8_t*)next1 + w - 3;
+    prev2 = (uint8_t*)(parity ? prev : cur);
+    next2 = (uint8_t*)(parity ? cur  : next);
+
+    FILTER(w - 3, w)
+}
+
+
+static void filter_line_c_16bit(void *dst1,
+                                void *prev1, void *cur1, void *next1,
                                 int w, int prefs, int mrefs, int parity,
                                 int mode)
 {
+    uint16_t *dst  = dst1;
+    uint16_t *prev = prev1;
+    uint16_t *cur  = cur1;
+    uint16_t *next = next1;
     int x;
     uint16_t *prev2 = parity ? prev : cur ;
     uint16_t *next2 = parity ? cur  : next;
     mrefs /= 2;
     prefs /= 2;
 
-    FILTER
+    FILTER(0, w)
+}
+
+static void filter_edges_16bit(void *dst1, void *prev1, void *cur1, void *next1,
+                               int w, int prefs, int mrefs, int parity, int mode,
+                               int l_edge)
+{
+    uint16_t *dst  = dst1;
+    uint16_t *prev = prev1;
+    uint16_t *cur  = cur1;
+    uint16_t *next = next1;
+    int x;
+    uint16_t *prev2 = parity ? prev : cur ;
+    uint16_t *next2 = parity ? cur  : next;
+
+    FILTER(0, l_edge)
+
+    dst   = (uint16_t*)dst1  + w - 3;
+    prev  = (uint16_t*)prev1 + w - 3;
+    cur   = (uint16_t*)cur1  + w - 3;
+    next  = (uint16_t*)next1 + w - 3;
+    prev2 = (uint16_t*)(parity ? prev : cur);
+    next2 = (uint16_t*)(parity ? cur  : next);
+
+    FILTER(w - 3, w)
 }
 
 static void filter(AVFilterContext *ctx, AVFilterBufferRef *dstpic,
@@ -115,8 +177,8 @@
         int w = dstpic->video->w;
         int h = dstpic->video->h;
         int refs = yadif->cur->linesize[i];
-        int absrefs = FFABS(refs);
         int df = (yadif->csp->comp[i].depth_minus1 + 8) / 8;
+        int l_edge, l_edge_pix;
 
         if (i == 1 || i == 2) {
         /* Why is this not part of the per-plane description thing? */
@@ -124,11 +186,11 @@
             h >>= yadif->csp->log2_chroma_h;
         }
 
-        if(yadif->temp_line_size < absrefs) {
-            av_free(yadif->temp_line);
-            yadif->temp_line = av_mallocz(2*64 + 5*absrefs);
-            yadif->temp_line_size = absrefs;
-        }
+        /* 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
+         */
+        l_edge     = yadif->req_align;
+        l_edge_pix = l_edge / df;
 
         for (y = 0; y < h; y++) {
             if ((y ^ parity) & 1) {
@@ -137,26 +199,22 @@
                 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;
-                int     prefs = y+1<h ? refs : -refs;
-                int     mrefs =     y ?-refs :  refs;
-
-                if(y<=1 || y+2>=h) {
-                    uint8_t *tmp = yadif->temp_line + 64 + 2*absrefs;
-                    if(mode<2)
-                        memcpy(tmp+2*mrefs, cur+2*mrefs, w*df);
-                    memcpy(tmp+mrefs, cur+mrefs, w*df);
-                    memcpy(tmp      , cur      , w*df);
-                    if(prefs != mrefs) {
-                        memcpy(tmp+prefs, cur+prefs, w*df);
-                        if(mode<2)
-                            memcpy(tmp+2*prefs, cur+2*prefs, w*df);
-                    }
-                    cur = tmp;
+                if (yadif->req_align) {
+                    yadif->filter_line(dst + l_edge, prev + l_edge, cur + l_edge,
+                                       next + l_edge, w - l_edge_pix - 3,
+                                       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, l_edge_pix);
+                } else {
+                    yadif->filter_line(dst, prev, cur, next + l_edge, w,
+                                       y + 1 < h ? refs : -refs,
+                                       y ? -refs : refs,
+                                       parity ^ tff, mode);
                 }
-
-                yadif->filter_line(dst, prev, cur, next, w,
-                                   prefs, mrefs,
-                                   parity ^ tff, mode);
             } else {
                 memcpy(&dstpic->data[i][y * dstpic->linesize[i]],
                        &yadif->cur->data[i][y * refs], w * df);
@@ -189,11 +247,6 @@
         yadif->out->video->interlaced = 0;
     }
 
-    if (!yadif->csp)
-        yadif->csp = av_pix_fmt_desc_get(link->format);
-    if (yadif->csp->comp[0].depth_minus1 / 8 == 1)
-        yadif->filter_line = (void*)filter_line_c_16bit;
-
     filter(ctx, yadif->out, tff ^ !is_second, tff);
 
     if (is_second) {
@@ -219,11 +272,6 @@
 
     av_assert0(picref);
 
-    if (picref->video->h < 3 || picref->video->w < 3) {
-        av_log(ctx, AV_LOG_ERROR, "Video of less than 3 columns or lines is not supported\n");
-        return AVERROR(EINVAL);
-    }
-
     if (yadif->frame_pending)
         return_frame(ctx, 1);
 
@@ -236,7 +284,7 @@
     if (!yadif->cur)
         return 0;
 
-    if (yadif->auto_enable && !yadif->cur->video->interlaced) {
+    if (yadif->deint && !yadif->cur->video->interlaced) {
         yadif->out  = avfilter_ref_buffer(yadif->cur, ~AV_PERM_WRITE);
         if (!yadif->out)
             return AVERROR(ENOMEM);
@@ -301,42 +349,40 @@
     return 0;
 }
 
-static int poll_frame(AVFilterLink *link)
-{
-    YADIFContext *yadif = link->src->priv;
-    int ret, val;
+#define OFFSET(x) offsetof(YADIFContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
 
-    if (yadif->frame_pending)
-        return 1;
+#define CONST(name, help, val, unit) { name, help, 0, AV_OPT_TYPE_CONST, {.i64=val}, INT_MIN, INT_MAX, FLAGS, unit }
 
-    val = ff_poll_frame(link->src->inputs[0]);
-    if (val <= 0)
-        return val;
+static const AVOption yadif_options[] = {
+    { "mode",   "specify the interlacing mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=YADIF_MODE_SEND_FRAME}, 0, 3, FLAGS, "mode"},
+    CONST("send_frame",           "send one frame for each frame",                                     YADIF_MODE_SEND_FRAME,           "mode"),
+    CONST("send_field",           "send one frame for each field",                                     YADIF_MODE_SEND_FIELD,           "mode"),
+    CONST("send_frame_nospatial", "send one frame for each frame, but skip spatial interlacing check", YADIF_MODE_SEND_FRAME_NOSPATIAL, "mode"),
+    CONST("send_field_nospatial", "send one frame for each field, but skip spatial interlacing check", YADIF_MODE_SEND_FIELD_NOSPATIAL, "mode"),
 
-    //FIXME change API to not requre this red tape
-    if (val >= 1 && !yadif->next) {
-        if ((ret = ff_request_frame(link->src->inputs[0])) < 0)
-            return ret;
-        val = ff_poll_frame(link->src->inputs[0]);
-        if (val <= 0)
-            return val;
-    }
-    assert(yadif->next || !val);
+    { "parity", "specify the assumed picture field parity", OFFSET(parity), AV_OPT_TYPE_INT, {.i64=YADIF_PARITY_AUTO}, -1, 1, FLAGS, "parity" },
+    CONST("tff",  "assume top field first",    YADIF_PARITY_TFF,  "parity"),
+    CONST("bff",  "assume bottom field first", YADIF_PARITY_BFF,  "parity"),
+    CONST("auto", "auto detect parity",        YADIF_PARITY_AUTO, "parity"),
 
-    if (yadif->auto_enable && yadif->next && !yadif->next->video->interlaced)
-        return val;
+    { "deint", "specify which frames to deinterlace", OFFSET(deint), AV_OPT_TYPE_INT, {.i64=YADIF_DEINT_ALL}, 0, 1, FLAGS, "deint" },
+    CONST("all",        "deinterlace all frames",                       YADIF_DEINT_ALL,         "deint"),
+    CONST("interlaced", "only deinterlace frames marked as interlaced", YADIF_DEINT_INTERLACED,  "deint"),
 
-    return val * ((yadif->mode&1)+1);
-}
+    {NULL},
+};
+
+AVFILTER_DEFINE_CLASS(yadif);
 
 static av_cold void uninit(AVFilterContext *ctx)
 {
     YADIFContext *yadif = ctx->priv;
 
-    if (yadif->prev) avfilter_unref_bufferp(&yadif->prev);
-    if (yadif->cur ) avfilter_unref_bufferp(&yadif->cur );
-    if (yadif->next) avfilter_unref_bufferp(&yadif->next);
-    av_freep(&yadif->temp_line); yadif->temp_line_size = 0;
+    avfilter_unref_bufferp(&yadif->prev);
+    avfilter_unref_bufferp(&yadif->cur );
+    avfilter_unref_bufferp(&yadif->next);
+    av_opt_free(yadif);
 }
 
 static int query_formats(AVFilterContext *ctx)
@@ -354,9 +400,18 @@
         AV_NE( AV_PIX_FMT_GRAY16BE, AV_PIX_FMT_GRAY16LE ),
         AV_PIX_FMT_YUV440P,
         AV_PIX_FMT_YUVJ440P,
+        AV_NE( AV_PIX_FMT_YUV420P9BE,  AV_PIX_FMT_YUV420P9LE ),
+        AV_NE( AV_PIX_FMT_YUV422P9BE,  AV_PIX_FMT_YUV422P9LE ),
+        AV_NE( AV_PIX_FMT_YUV444P9BE,  AV_PIX_FMT_YUV444P9LE ),
         AV_NE( AV_PIX_FMT_YUV420P10BE, AV_PIX_FMT_YUV420P10LE ),
         AV_NE( AV_PIX_FMT_YUV422P10BE, AV_PIX_FMT_YUV422P10LE ),
         AV_NE( AV_PIX_FMT_YUV444P10BE, AV_PIX_FMT_YUV444P10LE ),
+        AV_NE( AV_PIX_FMT_YUV420P12BE, AV_PIX_FMT_YUV420P12LE ),
+        AV_NE( AV_PIX_FMT_YUV422P12BE, AV_PIX_FMT_YUV422P12LE ),
+        AV_NE( AV_PIX_FMT_YUV444P12BE, AV_PIX_FMT_YUV444P12LE ),
+        AV_NE( AV_PIX_FMT_YUV420P14BE, AV_PIX_FMT_YUV420P14LE ),
+        AV_NE( AV_PIX_FMT_YUV422P14BE, AV_PIX_FMT_YUV422P14LE ),
+        AV_NE( AV_PIX_FMT_YUV444P14BE, AV_PIX_FMT_YUV444P14LE ),
         AV_NE( AV_PIX_FMT_YUV420P16BE, AV_PIX_FMT_YUV420P16LE ),
         AV_NE( AV_PIX_FMT_YUV422P16BE, AV_PIX_FMT_YUV422P16LE ),
         AV_NE( AV_PIX_FMT_YUV444P16BE, AV_PIX_FMT_YUV444P16LE ),
@@ -374,39 +429,51 @@
 static av_cold int init(AVFilterContext *ctx, const char *args)
 {
     YADIFContext *yadif = ctx->priv;
+    static const char *shorthand[] = { "mode", "parity", "deint", NULL };
+    int ret;
 
-    yadif->mode = 0;
-    yadif->parity = -1;
-    yadif->auto_enable = 0;
-    yadif->csp = NULL;
+    yadif->class = &yadif_class;
+    av_opt_set_defaults(yadif);
 
-    if (args)
-        sscanf(args, "%d:%d:%d",
-               &yadif->mode, &yadif->parity, &yadif->auto_enable);
+    if ((ret = av_opt_set_from_string(yadif, args, shorthand, "=", ":")) < 0)
+        return ret;
 
-    yadif->filter_line = filter_line_c;
-
-    if (ARCH_X86)
-        ff_yadif_init_x86(yadif);
-
-    av_log(ctx, AV_LOG_VERBOSE, "mode:%d parity:%d auto_enable:%d\n",
-           yadif->mode, yadif->parity, yadif->auto_enable);
+    av_log(ctx, AV_LOG_VERBOSE, "mode:%d parity:%d deint:%d\n",
+           yadif->mode, yadif->parity, yadif->deint);
 
     return 0;
 }
 
 static int config_props(AVFilterLink *link)
 {
-    YADIFContext *yadif = link->src->priv;
+    AVFilterContext *ctx = link->src;
+    YADIFContext *s = link->src->priv;
 
     link->time_base.num = link->src->inputs[0]->time_base.num;
     link->time_base.den = link->src->inputs[0]->time_base.den * 2;
     link->w             = link->src->inputs[0]->w;
     link->h             = link->src->inputs[0]->h;
 
-    if(yadif->mode&1)
+    if(s->mode&1)
         link->frame_rate = av_mul_q(link->src->inputs[0]->frame_rate, (AVRational){2,1});
 
+    if (link->w < 3 || link->h < 3) {
+        av_log(ctx, AV_LOG_ERROR, "Video of less than 3 columns or lines is not supported\n");
+        return AVERROR(EINVAL);
+    }
+
+    s->csp = av_pix_fmt_desc_get(link->format);
+    if (s->csp->comp[0].depth_minus1 / 8 == 1) {
+        s->filter_line  = filter_line_c_16bit;
+        s->filter_edges = filter_edges_16bit;
+    } else {
+        s->filter_line  = filter_line_c;
+        s->filter_edges = filter_edges;
+
+        if (ARCH_X86)
+            ff_yadif_init_x86(s);
+    }
+
     return 0;
 }
 
@@ -424,7 +491,6 @@
     {
         .name          = "default",
         .type          = AVMEDIA_TYPE_VIDEO,
-        .poll_frame    = poll_frame,
         .request_frame = request_frame,
         .config_props  = config_props,
     },
@@ -441,6 +507,7 @@
     .query_formats = query_formats,
 
     .inputs    = avfilter_vf_yadif_inputs,
-
     .outputs   = avfilter_vf_yadif_outputs,
+
+    .priv_class = &yadif_class,
 };
diff --git a/libavfilter/video.c b/libavfilter/video.c
index 46c4190..a493204 100644
--- a/libavfilter/video.c
+++ b/libavfilter/video.c
@@ -158,268 +158,3 @@
 
     return ret;
 }
-
-int ff_null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
-{
-    AVFilterBufferRef *buf_out = avfilter_ref_buffer(picref, ~0);
-    if (!buf_out)
-        return AVERROR(ENOMEM);
-    return ff_start_frame(link->dst->outputs[0], buf_out);
-}
-
-// for filters that support (but don't require) outpic==inpic
-int ff_inplace_start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
-{
-    AVFilterLink *outlink = inlink->dst->outputs[0];
-    AVFilterBufferRef *outpicref = NULL, *for_next_filter;
-    int ret = 0;
-
-    if (inpicref->perms & AV_PERM_WRITE) {
-        outpicref = avfilter_ref_buffer(inpicref, ~0);
-        if (!outpicref)
-            return AVERROR(ENOMEM);
-    } else {
-        outpicref = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
-        if (!outpicref)
-            return AVERROR(ENOMEM);
-
-        avfilter_copy_buffer_ref_props(outpicref, inpicref);
-        outpicref->video->w = outlink->w;
-        outpicref->video->h = outlink->h;
-    }
-
-    for_next_filter = avfilter_ref_buffer(outpicref, ~0);
-    if (for_next_filter)
-        ret = ff_start_frame(outlink, for_next_filter);
-    else
-        ret = AVERROR(ENOMEM);
-
-    if (ret < 0) {
-        avfilter_unref_bufferp(&outpicref);
-        return ret;
-    }
-
-    outlink->out_buf = outpicref;
-    return 0;
-}
-
-static int default_start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
-{
-    AVFilterLink *outlink = NULL;
-
-    if (inlink->dst->nb_outputs)
-        outlink = inlink->dst->outputs[0];
-
-    if (outlink && (inlink->dstpad->start_frame || inlink->dstpad->end_frame || inlink->dstpad->draw_slice)) {
-        AVFilterBufferRef *buf_out;
-        outlink->out_buf = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
-        if (!outlink->out_buf)
-            return AVERROR(ENOMEM);
-
-        avfilter_copy_buffer_ref_props(outlink->out_buf, picref);
-        outlink->out_buf->video->w = outlink->w;
-        outlink->out_buf->video->h = outlink->h;
-        buf_out = avfilter_ref_buffer(outlink->out_buf, ~0);
-        if (!buf_out)
-            return AVERROR(ENOMEM);
-
-        return ff_start_frame(outlink, buf_out);
-    }
-    return 0;
-}
-
-static void clear_link(AVFilterLink *link)
-{
-    avfilter_unref_bufferp(&link->cur_buf);
-    avfilter_unref_bufferp(&link->src_buf);
-    avfilter_unref_bufferp(&link->out_buf);
-    link->cur_buf_copy = NULL; /* we do not own the reference */
-}
-
-/* XXX: should we do the duplicating of the picture ref here, instead of
- * forcing the source filter to do it? */
-int ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
-{
-    int (*start_frame)(AVFilterLink *, AVFilterBufferRef *);
-    AVFilterPad *src = link->srcpad;
-    AVFilterPad *dst = link->dstpad;
-    int ret, perms;
-    AVFilterCommand *cmd= link->dst->command_queue;
-    int64_t pts;
-
-    FF_TPRINTF_START(NULL, start_frame); ff_tlog_link(NULL, link, 0); ff_tlog(NULL, " "); ff_tlog_ref(NULL, picref, 1);
-
-    if (strcmp(link->dst->filter->name, "scale")) {
-        av_assert1(picref->format                     == link->format);
-        av_assert1(picref->video->w                   == link->w);
-        av_assert1(picref->video->h                   == link->h);
-    }
-
-    if (link->closed) {
-        avfilter_unref_buffer(picref);
-        return AVERROR_EOF;
-    }
-
-    if (!(start_frame = dst->start_frame))
-        start_frame = default_start_frame;
-
-    av_assert1((picref->perms & src->min_perms) == src->min_perms);
-    picref->perms &= ~ src->rej_perms;
-    perms = picref->perms;
-
-    if (picref->linesize[0] < 0)
-        perms |= AV_PERM_NEG_LINESIZES;
-    /* prepare to copy the picture if it has insufficient permissions */
-    if ((dst->min_perms & perms) != dst->min_perms || dst->rej_perms & perms) {
-        av_log(link->dst, AV_LOG_DEBUG,
-                "frame copy needed (have perms %x, need %x, reject %x)\n",
-                picref->perms,
-                link->dstpad->min_perms, link->dstpad->rej_perms);
-
-        link->cur_buf = ff_get_video_buffer(link, dst->min_perms, link->w, link->h);
-        if (!link->cur_buf) {
-            avfilter_unref_bufferp(&picref);
-            return AVERROR(ENOMEM);
-        }
-
-        link->src_buf = picref;
-        avfilter_copy_buffer_ref_props(link->cur_buf, link->src_buf);
-
-        /* copy palette if required */
-        if (av_pix_fmt_desc_get(link->format)->flags & PIX_FMT_PAL)
-            memcpy(link->cur_buf->data[1], link->src_buf-> data[1], AVPALETTE_SIZE);
-    }
-    else
-        link->cur_buf = picref;
-
-    link->cur_buf_copy = link->cur_buf;
-
-    while(cmd && cmd->time <= picref->pts * av_q2d(link->time_base)){
-        av_log(link->dst, AV_LOG_DEBUG,
-               "Processing command time:%f command:%s arg:%s\n",
-               cmd->time, cmd->command, cmd->arg);
-        avfilter_process_command(link->dst, cmd->command, cmd->arg, 0, 0, cmd->flags);
-        ff_command_queue_pop(link->dst);
-        cmd= link->dst->command_queue;
-    }
-    pts = link->cur_buf->pts;
-    ret = start_frame(link, link->cur_buf);
-    ff_update_link_current_pts(link, pts);
-    if (ret < 0)
-        clear_link(link);
-    else
-        /* incoming buffers must not be freed in start frame,
-           because they can still be in use by the automatic copy mechanism */
-        av_assert1(link->cur_buf_copy->buf->refcount > 0);
-
-    return ret;
-}
-
-int ff_null_end_frame(AVFilterLink *link)
-{
-    return ff_end_frame(link->dst->outputs[0]);
-}
-
-static int default_end_frame(AVFilterLink *inlink)
-{
-    AVFilterLink *outlink = NULL;
-
-    if (inlink->dst->nb_outputs)
-        outlink = inlink->dst->outputs[0];
-
-    if (outlink) {
-        if (inlink->dstpad->filter_frame) {
-            int ret = inlink->dstpad->filter_frame(inlink, inlink->cur_buf);
-            inlink->cur_buf = NULL;
-            return ret;
-        } else if (inlink->dstpad->start_frame || inlink->dstpad->end_frame || inlink->dstpad->draw_slice){
-            return ff_end_frame(outlink);
-        } else {
-            int ret = ff_filter_frame(outlink, inlink->cur_buf);
-            inlink->cur_buf = NULL;
-            return ret;
-        }
-    }
-    return 0;
-}
-
-int ff_end_frame(AVFilterLink *link)
-{
-    int (*end_frame)(AVFilterLink *);
-    int ret;
-
-    if (!(end_frame = link->dstpad->end_frame))
-        end_frame = default_end_frame;
-
-    ret = end_frame(link);
-
-    clear_link(link);
-
-    return ret;
-}
-
-int ff_null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
-{
-    return ff_draw_slice(link->dst->outputs[0], y, h, slice_dir);
-}
-
-static int default_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
-{
-    AVFilterLink *outlink = NULL;
-
-    if (inlink->dst->nb_outputs)
-        outlink = inlink->dst->outputs[0];
-
-    if (outlink && (inlink->dstpad->start_frame || inlink->dstpad->end_frame || inlink->dstpad->draw_slice))
-        return ff_draw_slice(outlink, y, h, slice_dir);
-    return 0;
-}
-
-int ff_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
-{
-    uint8_t *src[4], *dst[4];
-    int i, j, vsub, ret;
-    int (*draw_slice)(AVFilterLink *, int, int, int);
-
-    FF_TPRINTF_START(NULL, draw_slice); ff_tlog_link(NULL, link, 0); ff_tlog(NULL, " y:%d h:%d dir:%d\n", y, h, slice_dir);
-
-    /* copy the slice if needed for permission reasons */
-    if (link->src_buf) {
-        const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format);
-        vsub = desc->log2_chroma_h;
-
-        for (i = 0; i < 4; i++) {
-            if (link->src_buf->data[i]) {
-                src[i] = link->src_buf-> data[i] +
-                    (y >> (i==1 || i==2 ? vsub : 0)) * link->src_buf-> linesize[i];
-                dst[i] = link->cur_buf_copy->data[i] +
-                    (y >> (i==1 || i==2 ? vsub : 0)) * link->cur_buf_copy->linesize[i];
-            } else
-                src[i] = dst[i] = NULL;
-        }
-
-        for (i = 0; i < 4; i++) {
-            int planew =
-                av_image_get_linesize(link->format, link->cur_buf_copy->video->w, i);
-
-            if (!src[i]) continue;
-
-            for (j = 0; j < h >> (i==1 || i==2 ? vsub : 0); j++) {
-                memcpy(dst[i], src[i], planew);
-                src[i] += link->src_buf->linesize[i];
-                dst[i] += link->cur_buf_copy->linesize[i];
-            }
-        }
-    }
-
-    if (!(draw_slice = link->dstpad->draw_slice))
-        draw_slice = default_draw_slice;
-    ret = draw_slice(link, y, h, slice_dir);
-    if (ret < 0)
-        clear_link(link);
-    else
-        /* incoming buffers must not be freed in start frame,
-           because they can still be in use by the automatic copy mechanism */
-        av_assert1(link->cur_buf_copy->buf->refcount > 0);
-    return ret;
-}
diff --git a/libavfilter/video.h b/libavfilter/video.h
index c677f30..a6af163 100644
--- a/libavfilter/video.h
+++ b/libavfilter/video.h
@@ -18,7 +18,6 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-
 #ifndef AVFILTER_VIDEO_H
 #define AVFILTER_VIDEO_H
 
@@ -42,56 +41,4 @@
 AVFilterBufferRef *ff_get_video_buffer(AVFilterLink *link, int perms,
                                        int w, int h);
 
-int ff_inplace_start_frame(AVFilterLink *link, AVFilterBufferRef *picref);
-int ff_null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref);
-int ff_null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir);
-int ff_null_end_frame(AVFilterLink *link);
-
-/**
- * Notify the next filter of the start of a frame.
- *
- * @param link   the output link the frame will be sent over
- * @param picref A reference to the frame about to be sent. The data for this
- *               frame need only be valid once draw_slice() is called for that
- *               portion. The receiving filter will free this reference when
- *               it no longer needs it.
- *
- * @return >= 0 on success, a negative AVERROR on error. This function will
- * unreference picref in case of error.
- */
-int ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref);
-
-/**
- * Pass video frame along and keep an internal reference for later use.
- */
-int ff_null_start_frame_keep_ref(AVFilterLink *inlink, AVFilterBufferRef *picref);
-
-/**
- * Notify the next filter that the current frame has finished.
- *
- * @param link the output link the frame was sent over
- *
- * @return >= 0 on success, a negative AVERROR on error
- */
-int ff_end_frame(AVFilterLink *link);
-
-/**
- * Send a slice to the next filter.
- *
- * Slices have to be provided in sequential order, either in
- * top-bottom or bottom-top order. If slices are provided in
- * non-sequential order the behavior of the function is undefined.
- *
- * @param link the output link over which the frame is being sent
- * @param y    offset in pixels from the top of the image for this slice
- * @param h    height of this slice in pixels
- * @param slice_dir the assumed direction for sending slices,
- *             from the top slice to the bottom slice if the value is 1,
- *             from the bottom slice to the top slice if the value is -1,
- *             for other values the behavior of the function is undefined.
- *
- * @return >= 0 on success, a negative AVERROR on error.
- */
-int ff_draw_slice(AVFilterLink *link, int y, int h, int slice_dir);
-
 #endif /* AVFILTER_VIDEO_H */
diff --git a/libavfilter/vsrc_testsrc.c b/libavfilter/vsrc_testsrc.c
index 185d382..f5e37f8 100644
--- a/libavfilter/vsrc_testsrc.c
+++ b/libavfilter/vsrc_testsrc.c
@@ -248,7 +248,7 @@
     if (av_image_check_size(test->w, test->h, 0, ctx) < 0)
         return AVERROR(EINVAL);
 
-    if (ret = config_props(inlink) < 0)
+    if ((ret = config_props(inlink)) < 0)
         return ret;
 
     av_log(ctx, AV_LOG_VERBOSE, "color:0x%02x%02x%02x%02x\n",
diff --git a/libavfilter/x86/Makefile b/libavfilter/x86/Makefile
index 4289f92..59cefe8 100644
--- a/libavfilter/x86/Makefile
+++ b/libavfilter/x86/Makefile
@@ -1,4 +1,8 @@
-OBJS-$(CONFIG_GRADFUN_FILTER)                += x86/gradfun.o
-OBJS-$(CONFIG_YADIF_FILTER)                  += x86/yadif.o
+OBJS-$(CONFIG_GRADFUN_FILTER)                += x86/vf_gradfun.o
+OBJS-$(CONFIG_HQDN3D_FILTER)                 += x86/vf_hqdn3d_init.o
+OBJS-$(CONFIG_VOLUME_FILTER)                 += x86/af_volume_init.o
+OBJS-$(CONFIG_YADIF_FILTER)                  += x86/vf_yadif_init.o
 
-YASM-OBJS-$(CONFIG_HQDN3D_FILTER)            += x86/hqdn3d.o
+YASM-OBJS-$(CONFIG_HQDN3D_FILTER)            += x86/vf_hqdn3d.o
+YASM-OBJS-$(CONFIG_VOLUME_FILTER)            += x86/af_volume.o
+YASM-OBJS-$(CONFIG_YADIF_FILTER)             += x86/vf_yadif.o
diff --git a/libavfilter/x86/af_volume.asm b/libavfilter/x86/af_volume.asm
new file mode 100644
index 0000000..f4cbcbc
--- /dev/null
+++ b/libavfilter/x86/af_volume.asm
@@ -0,0 +1,140 @@
+;*****************************************************************************
+;* x86-optimized functions for volume filter
+;* Copyright (c) 2012 Justin Ruggles <justin.ruggles@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/x86/x86util.asm"
+
+SECTION_RODATA 32
+
+pd_1_256:     times 4 dq 0x3F70000000000000
+pd_int32_max: times 4 dq 0x41DFFFFFFFC00000
+pw_1:         times 8 dw 1
+pw_128:       times 8 dw 128
+pq_128:       times 2 dq 128
+
+SECTION_TEXT
+
+;------------------------------------------------------------------------------
+; void ff_scale_samples_s16(uint8_t *dst, const uint8_t *src, int len,
+;                           int volume)
+;------------------------------------------------------------------------------
+
+INIT_XMM sse2
+cglobal scale_samples_s16, 4,4,4, dst, src, len, volume
+    movd        m0, volumem
+    pshuflw     m0, m0, 0
+    punpcklwd   m0, [pw_1]
+    mova        m1, [pw_128]
+    lea       lenq, [lend*2-mmsize]
+.loop:
+    ; dst[i] = av_clip_int16((src[i] * volume + 128) >> 8);
+    mova        m2, [srcq+lenq]
+    punpcklwd   m3, m2, m1
+    punpckhwd   m2, m1
+    pmaddwd     m3, m0
+    pmaddwd     m2, m0
+    psrad       m3, 8
+    psrad       m2, 8
+    packssdw    m3, m2
+    mova  [dstq+lenq], m3
+    sub       lenq, mmsize
+    jge .loop
+    REP_RET
+
+;------------------------------------------------------------------------------
+; void ff_scale_samples_s32(uint8_t *dst, const uint8_t *src, int len,
+;                           int volume)
+;------------------------------------------------------------------------------
+
+%macro SCALE_SAMPLES_S32 0
+cglobal scale_samples_s32, 4,4,4, dst, src, len, volume
+%if ARCH_X86_32 && cpuflag(avx)
+    vbroadcastss   xmm2, volumem
+%else
+    movd           xmm2, volumed
+    pshufd         xmm2, xmm2, 0
+%endif
+    CVTDQ2PD         m2, xmm2
+    mulpd            m2, m2, [pd_1_256]
+    mova             m3, [pd_int32_max]
+    lea            lenq, [lend*4-mmsize]
+.loop:
+    CVTDQ2PD         m0, [srcq+lenq         ]
+    CVTDQ2PD         m1, [srcq+lenq+mmsize/2]
+    mulpd            m0, m0, m2
+    mulpd            m1, m1, m2
+    minpd            m0, m0, m3
+    minpd            m1, m1, m3
+    cvtpd2dq       xmm0, m0
+    cvtpd2dq       xmm1, m1
+%if cpuflag(avx)
+    vmovdqa [dstq+lenq         ], xmm0
+    vmovdqa [dstq+lenq+mmsize/2], xmm1
+%else
+    movq    [dstq+lenq         ], xmm0
+    movq    [dstq+lenq+mmsize/2], xmm1
+%endif
+    sub            lenq, mmsize
+    jge .loop
+    REP_RET
+%endmacro
+
+INIT_XMM sse2
+%define CVTDQ2PD cvtdq2pd
+SCALE_SAMPLES_S32
+%if HAVE_AVX_EXTERNAL
+%define CVTDQ2PD vcvtdq2pd
+INIT_YMM avx
+SCALE_SAMPLES_S32
+%endif
+%undef CVTDQ2PD
+
+; NOTE: This is not bit-identical with the C version because it clips to
+;       [-INT_MAX, INT_MAX] instead of [INT_MIN, INT_MAX]
+
+INIT_XMM ssse3, atom
+cglobal scale_samples_s32, 4,4,8, dst, src, len, volume
+    movd        m4, volumem
+    pshufd      m4, m4, 0
+    mova        m5, [pq_128]
+    pxor        m6, m6
+    lea       lenq, [lend*4-mmsize]
+.loop:
+    ; src[i] = av_clipl_int32((src[i] * volume + 128) >> 8);
+    mova        m7, [srcq+lenq]
+    pabsd       m3, m7
+    pshufd      m0, m3, q0100
+    pshufd      m1, m3, q0302
+    pmuludq     m0, m4
+    pmuludq     m1, m4
+    paddq       m0, m5
+    paddq       m1, m5
+    psrlq       m0, 7
+    psrlq       m1, 7
+    shufps      m2, m0, m1, q3131
+    shufps      m0, m0, m1, q2020
+    pcmpgtd     m2, m6
+    por         m0, m2
+    psrld       m0, 1
+    psignd      m0, m7
+    mova  [dstq+lenq], m0
+    sub       lenq, mmsize
+    jge .loop
+    REP_RET
diff --git a/libavfilter/x86/af_volume_init.c b/libavfilter/x86/af_volume_init.c
new file mode 100644
index 0000000..beee8ca
--- /dev/null
+++ b/libavfilter/x86/af_volume_init.c
@@ -0,0 +1,59 @@
+/*
+ * 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/cpu.h"
+#include "libavutil/samplefmt.h"
+#include "libavutil/x86/cpu.h"
+#include "libavfilter/af_volume.h"
+
+void ff_scale_samples_s16_sse2(uint8_t *dst, const uint8_t *src, int len,
+                               int volume);
+
+void ff_scale_samples_s32_sse2(uint8_t *dst, const uint8_t *src, int len,
+                               int volume);
+void ff_scale_samples_s32_ssse3_atom(uint8_t *dst, const uint8_t *src, int len,
+                                     int volume);
+void ff_scale_samples_s32_avx(uint8_t *dst, const uint8_t *src, int len,
+                              int volume);
+
+void ff_volume_init_x86(VolumeContext *vol)
+{
+    int mm_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) {
+            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)) {
+            vol->scale_samples = ff_scale_samples_s32_sse2;
+            vol->samples_align = 4;
+        }
+        if (EXTERNAL_SSSE3(mm_flags) && mm_flags & AV_CPU_FLAG_ATOM) {
+            vol->scale_samples = ff_scale_samples_s32_ssse3_atom;
+            vol->samples_align = 4;
+        }
+        if (EXTERNAL_AVX(mm_flags)) {
+            vol->scale_samples = ff_scale_samples_s32_avx;
+            vol->samples_align = 8;
+        }
+    }
+}
diff --git a/libavfilter/x86/gradfun.c b/libavfilter/x86/vf_gradfun.c
similarity index 84%
rename from libavfilter/x86/gradfun.c
rename to libavfilter/x86/vf_gradfun.c
index 5e71aab..214e764 100644
--- a/libavfilter/x86/gradfun.c
+++ b/libavfilter/x86/vf_gradfun.c
@@ -46,7 +46,9 @@
         "pxor       %%mm7, %%mm7 \n"
         "pshufw $0, %%mm5, %%mm5 \n"
         "movq          %6, %%mm6 \n"
-        "movq          %5, %%mm4 \n"
+        "movq          (%5), %%mm3 \n"
+        "movq         8(%5), %%mm4 \n"
+
         "1: \n"
         "movd     (%2,%0), %%mm0 \n"
         "movd     (%3,%0), %%mm1 \n"
@@ -61,19 +63,44 @@
         "psubw      %%mm6, %%mm2 \n"
         "pminsw     %%mm7, %%mm2 \n" // m = -max(0, 127-m)
         "pmullw     %%mm2, %%mm2 \n"
-        "paddw      %%mm4, %%mm0 \n" // pix += dither
-        "pmulhw     %%mm2, %%mm1 \n"
+        "paddw      %%mm3, %%mm0 \n" // pix += dither
         "psllw         $2, %%mm1 \n" // m = m*m*delta >> 14
+        "pmulhw     %%mm2, %%mm1 \n"
+        "paddw      %%mm1, %%mm0 \n" // pix += m
+        "psraw         $7, %%mm0 \n"
+        "packuswb   %%mm0, %%mm0 \n"
+        "movd       %%mm0, (%1,%0) \n" // dst = clip(pix>>7)
+        "add           $4, %0 \n"
+        "jnl 2f \n"
+
+        "movd     (%2,%0), %%mm0 \n"
+        "movd     (%3,%0), %%mm1 \n"
+        "punpcklbw  %%mm7, %%mm0 \n"
+        "punpcklwd  %%mm1, %%mm1 \n"
+        "psllw         $7, %%mm0 \n"
+        "pxor       %%mm2, %%mm2 \n"
+        "psubw      %%mm0, %%mm1 \n" // delta = dc - pix
+        "psubw      %%mm1, %%mm2 \n"
+        "pmaxsw     %%mm1, %%mm2 \n"
+        "pmulhuw    %%mm5, %%mm2 \n" // m = abs(delta) * thresh >> 16
+        "psubw      %%mm6, %%mm2 \n"
+        "pminsw     %%mm7, %%mm2 \n" // m = -max(0, 127-m)
+        "pmullw     %%mm2, %%mm2 \n"
+        "paddw      %%mm4, %%mm0 \n" // pix += dither
+        "psllw         $2, %%mm1 \n" // m = m*m*delta >> 14
+        "pmulhw     %%mm2, %%mm1 \n"
         "paddw      %%mm1, %%mm0 \n" // pix += m
         "psraw         $7, %%mm0 \n"
         "packuswb   %%mm0, %%mm0 \n"
         "movd       %%mm0, (%1,%0) \n" // dst = clip(pix>>7)
         "add           $4, %0 \n"
         "jl 1b \n"
+
+        "2: \n"
         "emms \n"
         :"+r"(x)
         :"r"(dst+width), "r"(src+width), "r"(dc+width/2),
-         "rm"(thresh), "m"(*dithers), "m"(*pw_7f)
+         "rm"(thresh), "r"(dithers), "m"(*pw_7f)
         :"memory"
     );
 }
@@ -109,9 +136,9 @@
         "psubw      %%xmm6, %%xmm2 \n"
         "pminsw     %%xmm7, %%xmm2 \n" // m = -max(0, 127-m)
         "pmullw     %%xmm2, %%xmm2 \n"
-        "psllw          $1, %%xmm2 \n"
+        "psllw          $2, %%xmm1 \n"
         "paddw      %%xmm4, %%xmm0 \n" // pix += dither
-        "pmulhrsw   %%xmm2, %%xmm1 \n" // m = m*m*delta >> 14
+        "pmulhw     %%xmm2, %%xmm1 \n" // m = m*m*delta >> 14
         "paddw      %%xmm1, %%xmm0 \n" // pix += m
         "psraw          $7, %%xmm0 \n"
         "packuswb   %%xmm0, %%xmm0 \n"
diff --git a/libavfilter/x86/hqdn3d.asm b/libavfilter/x86/vf_hqdn3d.asm
similarity index 100%
rename from libavfilter/x86/hqdn3d.asm
rename to libavfilter/x86/vf_hqdn3d.asm
diff --git a/libavfilter/x86/vf_hqdn3d_init.c b/libavfilter/x86/vf_hqdn3d_init.c
new file mode 100644
index 0000000..4abb878
--- /dev/null
+++ b/libavfilter/x86/vf_hqdn3d_init.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2012 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 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 <stddef.h>
+#include <stdint.h>
+
+#include "libavutil/attributes.h"
+#include "libavfilter/vf_hqdn3d.h"
+#include "config.h"
+
+void ff_hqdn3d_row_8_x86(uint8_t *src, uint8_t *dst, uint16_t *line_ant, uint16_t *frame_ant, ptrdiff_t w, int16_t *spatial, int16_t *temporal);
+void ff_hqdn3d_row_9_x86(uint8_t *src, uint8_t *dst, uint16_t *line_ant, uint16_t *frame_ant, ptrdiff_t w, int16_t *spatial, int16_t *temporal);
+void ff_hqdn3d_row_10_x86(uint8_t *src, uint8_t *dst, uint16_t *line_ant, uint16_t *frame_ant, ptrdiff_t w, int16_t *spatial, int16_t *temporal);
+void ff_hqdn3d_row_16_x86(uint8_t *src, uint8_t *dst, uint16_t *line_ant, uint16_t *frame_ant, ptrdiff_t w, int16_t *spatial, int16_t *temporal);
+
+av_cold void ff_hqdn3d_init_x86(HQDN3DContext *hqdn3d)
+{
+#if HAVE_YASM
+    hqdn3d->denoise_row[ 8] = ff_hqdn3d_row_8_x86;
+    hqdn3d->denoise_row[ 9] = ff_hqdn3d_row_9_x86;
+    hqdn3d->denoise_row[10] = ff_hqdn3d_row_10_x86;
+    hqdn3d->denoise_row[16] = ff_hqdn3d_row_16_x86;
+#endif
+}
diff --git a/libavfilter/x86/vf_yadif.asm b/libavfilter/x86/vf_yadif.asm
new file mode 100644
index 0000000..a8f7987
--- /dev/null
+++ b/libavfilter/x86/vf_yadif.asm
@@ -0,0 +1,254 @@
+;*****************************************************************************
+;* x86-optimized functions for yadif filter
+;*
+;* Copyright (C) 2006 Michael Niedermayer <michaelni@gmx.at>
+;* Copyright (c) 2013 Daniel Kang <daniel.d.kang@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.
+;******************************************************************************
+
+%include "libavutil/x86/x86util.asm"
+
+SECTION_RODATA
+
+pb_1: times 16 db 1
+pw_1: times  8 dw 1
+
+SECTION .text
+
+%macro CHECK 2
+    movu      m2, [curq+t1+%1]
+    movu      m3, [curq+t0+%2]
+    mova      m4, m2
+    mova      m5, m2
+    pxor      m4, m3
+    pavgb     m5, m3
+    pand      m4, [pb_1]
+    psubusb   m5, m4
+%if mmsize == 16
+    psrldq    m5, 1
+%else
+    psrlq     m5, 8
+%endif
+    punpcklbw m5, m7
+    mova      m4, m2
+    psubusb   m2, m3
+    psubusb   m3, m4
+    pmaxub    m2, m3
+    mova      m3, m2
+    mova      m4, m2
+%if mmsize == 16
+    psrldq    m3, 1
+    psrldq    m4, 2
+%else
+    psrlq     m3, 8
+    psrlq     m4, 16
+%endif
+    punpcklbw m2, m7
+    punpcklbw m3, m7
+    punpcklbw m4, m7
+    paddw     m2, m3
+    paddw     m2, m4
+%endmacro
+
+%macro CHECK1 0
+    mova    m3, m0
+    pcmpgtw m3, m2
+    pminsw  m0, m2
+    mova    m6, m3
+    pand    m5, m3
+    pandn   m3, m1
+    por     m3, m5
+    mova    m1, m3
+%endmacro
+
+%macro CHECK2 0
+    paddw   m6, [pw_1]
+    psllw   m6, 14
+    paddsw  m2, m6
+    mova    m3, m0
+    pcmpgtw m3, m2
+    pminsw  m0, m2
+    pand    m5, m3
+    pandn   m3, m1
+    por     m3, m5
+    mova    m1, m3
+%endmacro
+
+%macro LOAD 2
+    movh      m%1, %2
+    punpcklbw m%1, m7
+%endmacro
+
+%macro FILTER 3
+.loop%1:
+    pxor         m7, m7
+    LOAD          0, [curq+t1]
+    LOAD          1, [curq+t0]
+    LOAD          2, [%2]
+    LOAD          3, [%3]
+    mova         m4, m3
+    paddw        m3, m2
+    psraw        m3, 1
+    mova   [rsp+ 0], m0
+    mova   [rsp+16], m3
+    mova   [rsp+32], m1
+    psubw        m2, m4
+    ABS1         m2, m4
+    LOAD          3, [prevq+t1]
+    LOAD          4, [prevq+t0]
+    psubw        m3, m0
+    psubw        m4, m1
+    ABS1         m3, m5
+    ABS1         m4, m5
+    paddw        m3, m4
+    psrlw        m2, 1
+    psrlw        m3, 1
+    pmaxsw       m2, m3
+    LOAD          3, [nextq+t1]
+    LOAD          4, [nextq+t0]
+    psubw        m3, m0
+    psubw        m4, m1
+    ABS1         m3, m5
+    ABS1         m4, m5
+    paddw        m3, m4
+    psrlw        m3, 1
+    pmaxsw       m2, m3
+    mova   [rsp+48], m2
+
+    paddw        m1, m0
+    paddw        m0, m0
+    psubw        m0, m1
+    psrlw        m1, 1
+    ABS1         m0, m2
+
+    movu         m2, [curq+t1-1]
+    movu         m3, [curq+t0-1]
+    mova         m4, m2
+    psubusb      m2, m3
+    psubusb      m3, m4
+    pmaxub       m2, m3
+%if mmsize == 16
+    mova         m3, m2
+    psrldq       m3, 2
+%else
+    pshufw       m3, m2, q0021
+%endif
+    punpcklbw    m2, m7
+    punpcklbw    m3, m7
+    paddw        m0, m2
+    paddw        m0, m3
+    psubw        m0, [pw_1]
+
+    CHECK -2, 0
+    CHECK1
+    CHECK -3, 1
+    CHECK2
+    CHECK 0, -2
+    CHECK1
+    CHECK 1, -3
+    CHECK2
+
+    mova         m6, [rsp+48]
+    cmp   DWORD r8m, 2
+    jge .end%1
+    LOAD          2, [%2+t1*2]
+    LOAD          4, [%3+t1*2]
+    LOAD          3, [%2+t0*2]
+    LOAD          5, [%3+t0*2]
+    paddw        m2, m4
+    paddw        m3, m5
+    psrlw        m2, 1
+    psrlw        m3, 1
+    mova         m4, [rsp+ 0]
+    mova         m5, [rsp+16]
+    mova         m7, [rsp+32]
+    psubw        m2, m4
+    psubw        m3, m7
+    mova         m0, m5
+    psubw        m5, m4
+    psubw        m0, m7
+    mova         m4, m2
+    pminsw       m2, m3
+    pmaxsw       m3, m4
+    pmaxsw       m2, m5
+    pminsw       m3, m5
+    pmaxsw       m2, m0
+    pminsw       m3, m0
+    pxor         m4, m4
+    pmaxsw       m6, m3
+    psubw        m4, m2
+    pmaxsw       m6, m4
+
+.end%1:
+    mova         m2, [rsp+16]
+    mova         m3, m2
+    psubw        m2, m6
+    paddw        m3, m6
+    pmaxsw       m1, m2
+    pminsw       m1, m3
+    packuswb     m1, m1
+
+    movh     [dstq], m1
+    add        dstq, mmsize/2
+    add       prevq, mmsize/2
+    add        curq, mmsize/2
+    add       nextq, mmsize/2
+    sub   DWORD r4m, mmsize/2
+    jg .loop%1
+%endmacro
+
+%macro YADIF 0
+%if ARCH_X86_32
+cglobal yadif_filter_line, 4, 6, 8, 80, dst, prev, cur, next, w, prefs, \
+                                        mrefs, parity, mode
+%else
+cglobal yadif_filter_line, 4, 7, 8, 80, dst, prev, cur, next, w, prefs, \
+                                        mrefs, parity, mode
+%endif
+    cmp      DWORD wm, 0
+    jle .ret
+%if ARCH_X86_32
+    mov            r4, r5mp
+    mov            r5, r6mp
+    DECLARE_REG_TMP 4,5
+%else
+    movsxd         r5, DWORD r5m
+    movsxd         r6, DWORD r6m
+    DECLARE_REG_TMP 5,6
+%endif
+
+    cmp DWORD paritym, 0
+    je .parity0
+    FILTER 1, prevq, curq
+    jmp .ret
+
+.parity0:
+    FILTER 0, curq, nextq
+
+.ret:
+    RET
+%endmacro
+
+INIT_XMM ssse3
+YADIF
+INIT_XMM sse2
+YADIF
+%if ARCH_X86_32
+INIT_MMX mmxext
+YADIF
+%endif
diff --git a/libavfilter/x86/vf_yadif_init.c b/libavfilter/x86/vf_yadif_init.c
new file mode 100644
index 0000000..2873744
--- /dev/null
+++ b/libavfilter/x86/vf_yadif_init.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2006 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 "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,
+                                 void *next, int w, int prefs,
+                                 int mrefs, int parity, int mode);
+void ff_yadif_filter_line_sse2(void *dst, void *prev, void *cur,
+                               void *next, int w, int prefs,
+                               int mrefs, int parity, int mode);
+void ff_yadif_filter_line_ssse3(void *dst, void *prev, void *cur,
+                                void *next, int w, int prefs,
+                                int mrefs, int parity, int mode);
+
+av_cold void ff_yadif_init_x86(YADIFContext *yadif)
+{
+    int cpu_flags = av_get_cpu_flags();
+
+#if HAVE_YASM
+#if ARCH_X86_32
+    if (EXTERNAL_MMXEXT(cpu_flags)) {
+        yadif->filter_line = ff_yadif_filter_line_mmxext;
+        yadif->req_align   = 8;
+    }
+#endif /* ARCH_X86_32 */
+    if (EXTERNAL_SSE2(cpu_flags)) {
+        yadif->filter_line = ff_yadif_filter_line_sse2;
+        yadif->req_align   = 16;
+    }
+    if (EXTERNAL_SSSE3(cpu_flags)) {
+        yadif->filter_line = ff_yadif_filter_line_ssse3;
+        yadif->req_align   = 16;
+    }
+#endif /* HAVE_YASM */
+}
diff --git a/libavfilter/x86/yadif.c b/libavfilter/x86/yadif.c
deleted file mode 100644
index b48a3d6..0000000
--- a/libavfilter/x86/yadif.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2006 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 "libavcodec/x86/dsputil_mmx.h"
-#include "libavfilter/yadif.h"
-
-#if HAVE_INLINE_ASM
-
-DECLARE_ASM_CONST(16, const xmm_reg, pb_1) = {0x0101010101010101ULL, 0x0101010101010101ULL};
-DECLARE_ASM_CONST(16, const xmm_reg, pw_1) = {0x0001000100010001ULL, 0x0001000100010001ULL};
-
-#if HAVE_SSSE3_INLINE
-#define COMPILE_TEMPLATE_SSE2 1
-#define COMPILE_TEMPLATE_SSSE3 1
-#undef RENAME
-#define RENAME(a) a ## _ssse3
-#include "yadif_template.c"
-#undef COMPILE_TEMPLATE_SSSE3
-#endif
-
-#if HAVE_SSE2_INLINE
-#undef RENAME
-#define RENAME(a) a ## _sse2
-#include "yadif_template.c"
-#undef COMPILE_TEMPLATE_SSE2
-#endif
-
-#if HAVE_MMXEXT_INLINE
-#undef RENAME
-#define RENAME(a) a ## _mmxext
-#include "yadif_template.c"
-#endif
-
-#endif /* HAVE_INLINE_ASM */
-
-av_cold void ff_yadif_init_x86(YADIFContext *yadif)
-{
-    int cpu_flags = av_get_cpu_flags();
-
-#if HAVE_MMXEXT_INLINE
-    if (cpu_flags & AV_CPU_FLAG_MMXEXT)
-        yadif->filter_line = yadif_filter_line_mmxext;
-#endif
-#if HAVE_SSE2_INLINE
-    if (cpu_flags & AV_CPU_FLAG_SSE2)
-        yadif->filter_line = yadif_filter_line_sse2;
-#endif
-#if HAVE_SSSE3_INLINE
-    if (cpu_flags & AV_CPU_FLAG_SSSE3)
-        yadif->filter_line = yadif_filter_line_ssse3;
-#endif
-}
diff --git a/libavfilter/x86/yadif_template.c b/libavfilter/x86/yadif_template.c
deleted file mode 100644
index 674c088..0000000
--- a/libavfilter/x86/yadif_template.c
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * Copyright (C) 2006 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.
- */
-
-#ifdef COMPILE_TEMPLATE_SSE2
-#define MM "%%xmm"
-#define MOV  "movq"
-#define MOVQ "movdqa"
-#define MOVQU "movdqu"
-#define STEP 8
-#define LOAD(mem,dst) \
-            MOV"       "mem", "dst" \n\t"\
-            "punpcklbw "MM"7, "dst" \n\t"
-#define PSRL1(reg) "psrldq $1, "reg" \n\t"
-#define PSRL2(reg) "psrldq $2, "reg" \n\t"
-#define PSHUF(src,dst) "movdqa "dst", "src" \n\t"\
-                       "psrldq $2, "src"     \n\t"
-#else
-#define MM "%%mm"
-#define MOV  "movd"
-#define MOVQ "movq"
-#define MOVQU "movq"
-#define STEP 4
-#define LOAD(mem,dst) \
-            MOV"       "mem", "dst" \n\t"\
-            "punpcklbw "MM"7, "dst" \n\t"
-#define PSRL1(reg) "psrlq $8, "reg" \n\t"
-#define PSRL2(reg) "psrlq $16, "reg" \n\t"
-#define PSHUF(src,dst) "pshufw $9, "dst", "src" \n\t"
-#endif
-
-#ifdef COMPILE_TEMPLATE_SSSE3
-#define PABS(tmp,dst) \
-            "pabsw     "dst", "dst" \n\t"
-#else
-#define PABS(tmp,dst) \
-            "pxor     "tmp", "tmp" \n\t"\
-            "psubw    "dst", "tmp" \n\t"\
-            "pmaxsw   "tmp", "dst" \n\t"
-#endif
-
-#define CHECK(pj,mj) \
-            MOVQU" "#pj"(%[cur],%[mrefs]), "MM"2 \n\t" /* cur[x-refs-1+j] */\
-            MOVQU" "#mj"(%[cur],%[prefs]), "MM"3 \n\t" /* cur[x+refs-1-j] */\
-            MOVQ"      "MM"2, "MM"4 \n\t"\
-            MOVQ"      "MM"2, "MM"5 \n\t"\
-            "pxor      "MM"3, "MM"4 \n\t"\
-            "pavgb     "MM"3, "MM"5 \n\t"\
-            "pand     "MANGLE(pb_1)", "MM"4 \n\t"\
-            "psubusb   "MM"4, "MM"5 \n\t"\
-            PSRL1(MM"5")                 \
-            "punpcklbw "MM"7, "MM"5 \n\t" /* (cur[x-refs+j] + cur[x+refs-j])>>1 */\
-            MOVQ"      "MM"2, "MM"4 \n\t"\
-            "psubusb   "MM"3, "MM"2 \n\t"\
-            "psubusb   "MM"4, "MM"3 \n\t"\
-            "pmaxub    "MM"3, "MM"2 \n\t"\
-            MOVQ"      "MM"2, "MM"3 \n\t"\
-            MOVQ"      "MM"2, "MM"4 \n\t" /* ABS(cur[x-refs-1+j] - cur[x+refs-1-j]) */\
-            PSRL1(MM"3")                  /* ABS(cur[x-refs  +j] - cur[x+refs  -j]) */\
-            PSRL2(MM"4")                  /* ABS(cur[x-refs+1+j] - cur[x+refs+1-j]) */\
-            "punpcklbw "MM"7, "MM"2 \n\t"\
-            "punpcklbw "MM"7, "MM"3 \n\t"\
-            "punpcklbw "MM"7, "MM"4 \n\t"\
-            "paddw     "MM"3, "MM"2 \n\t"\
-            "paddw     "MM"4, "MM"2 \n\t" /* score */
-
-#define CHECK1 \
-            MOVQ"      "MM"0, "MM"3 \n\t"\
-            "pcmpgtw   "MM"2, "MM"3 \n\t" /* if(score < spatial_score) */\
-            "pminsw    "MM"2, "MM"0 \n\t" /* spatial_score= score; */\
-            MOVQ"      "MM"3, "MM"6 \n\t"\
-            "pand      "MM"3, "MM"5 \n\t"\
-            "pandn     "MM"1, "MM"3 \n\t"\
-            "por       "MM"5, "MM"3 \n\t"\
-            MOVQ"      "MM"3, "MM"1 \n\t" /* spatial_pred= (cur[x-refs+j] + cur[x+refs-j])>>1; */
-
-#define CHECK2 /* pretend not to have checked dir=2 if dir=1 was bad.\
-                  hurts both quality and speed, but matches the C version. */\
-            "paddw    "MANGLE(pw_1)", "MM"6 \n\t"\
-            "psllw     $14,   "MM"6 \n\t"\
-            "paddsw    "MM"6, "MM"2 \n\t"\
-            MOVQ"      "MM"0, "MM"3 \n\t"\
-            "pcmpgtw   "MM"2, "MM"3 \n\t"\
-            "pminsw    "MM"2, "MM"0 \n\t"\
-            "pand      "MM"3, "MM"5 \n\t"\
-            "pandn     "MM"1, "MM"3 \n\t"\
-            "por       "MM"5, "MM"3 \n\t"\
-            MOVQ"      "MM"3, "MM"1 \n\t"
-
-static void RENAME(yadif_filter_line)(uint8_t *dst, uint8_t *prev, uint8_t *cur,
-                                      uint8_t *next, int w, int prefs,
-                                      int mrefs, int parity, int mode)
-{
-    uint8_t tmpU[5*16];
-    uint8_t *tmp= (uint8_t*)(((uint64_t)(tmpU+15)) & ~15);
-    int x;
-
-#define FILTER\
-    for(x=0; x<w; x+=STEP){\
-        __asm__ volatile(\
-            "pxor      "MM"7, "MM"7 \n\t"\
-            LOAD("(%[cur],%[mrefs])", MM"0") /* c = cur[x-refs] */\
-            LOAD("(%[cur],%[prefs])", MM"1") /* e = cur[x+refs] */\
-            LOAD("(%["prev2"])", MM"2") /* prev2[x] */\
-            LOAD("(%["next2"])", MM"3") /* next2[x] */\
-            MOVQ"      "MM"3, "MM"4 \n\t"\
-            "paddw     "MM"2, "MM"3 \n\t"\
-            "psraw     $1,    "MM"3 \n\t" /* d = (prev2[x] + next2[x])>>1 */\
-            MOVQ"      "MM"0,   (%[tmp]) \n\t" /* c */\
-            MOVQ"      "MM"3, 16(%[tmp]) \n\t" /* d */\
-            MOVQ"      "MM"1, 32(%[tmp]) \n\t" /* e */\
-            "psubw     "MM"4, "MM"2 \n\t"\
-            PABS(      MM"4", MM"2") /* temporal_diff0 */\
-            LOAD("(%[prev],%[mrefs])", MM"3") /* prev[x-refs] */\
-            LOAD("(%[prev],%[prefs])", MM"4") /* prev[x+refs] */\
-            "psubw     "MM"0, "MM"3 \n\t"\
-            "psubw     "MM"1, "MM"4 \n\t"\
-            PABS(      MM"5", MM"3")\
-            PABS(      MM"5", MM"4")\
-            "paddw     "MM"4, "MM"3 \n\t" /* temporal_diff1 */\
-            "psrlw     $1,    "MM"2 \n\t"\
-            "psrlw     $1,    "MM"3 \n\t"\
-            "pmaxsw    "MM"3, "MM"2 \n\t"\
-            LOAD("(%[next],%[mrefs])", MM"3") /* next[x-refs] */\
-            LOAD("(%[next],%[prefs])", MM"4") /* next[x+refs] */\
-            "psubw     "MM"0, "MM"3 \n\t"\
-            "psubw     "MM"1, "MM"4 \n\t"\
-            PABS(      MM"5", MM"3")\
-            PABS(      MM"5", MM"4")\
-            "paddw     "MM"4, "MM"3 \n\t" /* temporal_diff2 */\
-            "psrlw     $1,    "MM"3 \n\t"\
-            "pmaxsw    "MM"3, "MM"2 \n\t"\
-            MOVQ"      "MM"2, 48(%[tmp]) \n\t" /* diff */\
-\
-            "paddw     "MM"0, "MM"1 \n\t"\
-            "paddw     "MM"0, "MM"0 \n\t"\
-            "psubw     "MM"1, "MM"0 \n\t"\
-            "psrlw     $1,    "MM"1 \n\t" /* spatial_pred */\
-            PABS(      MM"2", MM"0")      /* ABS(c-e) */\
-\
-            MOVQU" -1(%[cur],%[mrefs]), "MM"2 \n\t" /* cur[x-refs-1] */\
-            MOVQU" -1(%[cur],%[prefs]), "MM"3 \n\t" /* cur[x+refs-1] */\
-            MOVQ"      "MM"2, "MM"4 \n\t"\
-            "psubusb   "MM"3, "MM"2 \n\t"\
-            "psubusb   "MM"4, "MM"3 \n\t"\
-            "pmaxub    "MM"3, "MM"2 \n\t"\
-            PSHUF(MM"3", MM"2") \
-            "punpcklbw "MM"7, "MM"2 \n\t" /* ABS(cur[x-refs-1] - cur[x+refs-1]) */\
-            "punpcklbw "MM"7, "MM"3 \n\t" /* ABS(cur[x-refs+1] - cur[x+refs+1]) */\
-            "paddw     "MM"2, "MM"0 \n\t"\
-            "paddw     "MM"3, "MM"0 \n\t"\
-            "psubw    "MANGLE(pw_1)", "MM"0 \n\t" /* spatial_score */\
-\
-            CHECK(-2,0)\
-            CHECK1\
-            CHECK(-3,1)\
-            CHECK2\
-            CHECK(0,-2)\
-            CHECK1\
-            CHECK(1,-3)\
-            CHECK2\
-\
-            /* if(p->mode<2) ... */\
-            MOVQ" 48(%[tmp]), "MM"6 \n\t" /* diff */\
-            "cmpl      $2, %[mode] \n\t"\
-            "jge       1f \n\t"\
-            LOAD("(%["prev2"],%[mrefs],2)", MM"2") /* prev2[x-2*refs] */\
-            LOAD("(%["next2"],%[mrefs],2)", MM"4") /* next2[x-2*refs] */\
-            LOAD("(%["prev2"],%[prefs],2)", MM"3") /* prev2[x+2*refs] */\
-            LOAD("(%["next2"],%[prefs],2)", MM"5") /* next2[x+2*refs] */\
-            "paddw     "MM"4, "MM"2 \n\t"\
-            "paddw     "MM"5, "MM"3 \n\t"\
-            "psrlw     $1,    "MM"2 \n\t" /* b */\
-            "psrlw     $1,    "MM"3 \n\t" /* f */\
-            MOVQ"   (%[tmp]), "MM"4 \n\t" /* c */\
-            MOVQ" 16(%[tmp]), "MM"5 \n\t" /* d */\
-            MOVQ" 32(%[tmp]), "MM"7 \n\t" /* e */\
-            "psubw     "MM"4, "MM"2 \n\t" /* b-c */\
-            "psubw     "MM"7, "MM"3 \n\t" /* f-e */\
-            MOVQ"      "MM"5, "MM"0 \n\t"\
-            "psubw     "MM"4, "MM"5 \n\t" /* d-c */\
-            "psubw     "MM"7, "MM"0 \n\t" /* d-e */\
-            MOVQ"      "MM"2, "MM"4 \n\t"\
-            "pminsw    "MM"3, "MM"2 \n\t"\
-            "pmaxsw    "MM"4, "MM"3 \n\t"\
-            "pmaxsw    "MM"5, "MM"2 \n\t"\
-            "pminsw    "MM"5, "MM"3 \n\t"\
-            "pmaxsw    "MM"0, "MM"2 \n\t" /* max */\
-            "pminsw    "MM"0, "MM"3 \n\t" /* min */\
-            "pxor      "MM"4, "MM"4 \n\t"\
-            "pmaxsw    "MM"3, "MM"6 \n\t"\
-            "psubw     "MM"2, "MM"4 \n\t" /* -max */\
-            "pmaxsw    "MM"4, "MM"6 \n\t" /* diff= MAX3(diff, min, -max); */\
-            "1: \n\t"\
-\
-            MOVQ" 16(%[tmp]), "MM"2 \n\t" /* d */\
-            MOVQ"      "MM"2, "MM"3 \n\t"\
-            "psubw     "MM"6, "MM"2 \n\t" /* d-diff */\
-            "paddw     "MM"6, "MM"3 \n\t" /* d+diff */\
-            "pmaxsw    "MM"2, "MM"1 \n\t"\
-            "pminsw    "MM"3, "MM"1 \n\t" /* d = clip(spatial_pred, d-diff, d+diff); */\
-            "packuswb  "MM"1, "MM"1 \n\t"\
-\
-            ::[prev] "r"(prev),\
-             [cur]  "r"(cur),\
-             [next] "r"(next),\
-             [prefs]"r"((x86_reg)prefs),\
-             [mrefs]"r"((x86_reg)mrefs),\
-             [mode] "g"(mode),\
-             [tmp]  "r"(tmp)\
-        );\
-        __asm__ volatile(MOV" "MM"1, %0" :"=m"(*dst));\
-        dst += STEP;\
-        prev+= STEP;\
-        cur += STEP;\
-        next+= STEP;\
-    }
-
-    if (parity) {
-#define prev2 "prev"
-#define next2 "cur"
-        FILTER
-#undef prev2
-#undef next2
-    } else {
-#define prev2 "cur"
-#define next2 "next"
-        FILTER
-#undef prev2
-#undef next2
-    }
-}
-#undef STEP
-#undef MM
-#undef MOV
-#undef MOVQ
-#undef MOVQU
-#undef PSHUF
-#undef PSRL1
-#undef PSRL2
-#undef LOAD
-#undef PABS
-#undef CHECK
-#undef CHECK1
-#undef CHECK2
-#undef FILTER
diff --git a/libavfilter/yadif.h b/libavfilter/yadif.h
index 41691de..50fc856 100644
--- a/libavfilter/yadif.h
+++ b/libavfilter/yadif.h
@@ -22,37 +22,48 @@
 #include "libavutil/pixdesc.h"
 #include "avfilter.h"
 
-typedef struct YADIFContext {
-    /**
-     * 0: send 1 frame for each frame
-     * 1: send 1 frame for each field
-     * 2: like 0 but skips spatial interlacing check
-     * 3: like 1 but skips spatial interlacing check
-     */
-    int mode;
+enum YADIFMode {
+    YADIF_MODE_SEND_FRAME           = 0, ///< send 1 frame for each frame
+    YADIF_MODE_SEND_FIELD           = 1, ///< send 1 frame for each field
+    YADIF_MODE_SEND_FRAME_NOSPATIAL = 2, ///< send 1 frame for each frame but skips spatial interlacing check
+    YADIF_MODE_SEND_FIELD_NOSPATIAL = 3, ///< send 1 frame for each field but skips spatial interlacing check
+};
 
-    /**
-     *  0: top field first
-     *  1: bottom field first
-     * -1: auto-detection
-     */
-    int parity;
+enum YADIFParity {
+    YADIF_PARITY_TFF  =  0, ///< top field first
+    YADIF_PARITY_BFF  =  1, ///< bottom field first
+    YADIF_PARITY_AUTO = -1, ///< auto detection
+};
+
+enum YADIFDeint {
+    YADIF_DEINT_ALL        = 0, ///< deinterlace all frames
+    YADIF_DEINT_INTERLACED = 1, ///< only deinterlace frames marked as interlaced
+};
+
+typedef struct YADIFContext {
+    const AVClass *class;
+
+    enum YADIFMode   mode;
+    enum YADIFParity parity;
+    enum YADIFDeint  deint;
 
     int frame_pending;
 
-    /**
-     *  0: deinterlace all frames
-     *  1: only deinterlace frames marked as interlaced
-     */
-    int auto_enable;
-
     AVFilterBufferRef *cur;
     AVFilterBufferRef *next;
     AVFilterBufferRef *prev;
     AVFilterBufferRef *out;
-    void (*filter_line)(uint8_t *dst,
-                        uint8_t *prev, uint8_t *cur, uint8_t *next,
+
+    /**
+     * Required alignment for filter_line
+     */
+    int req_align;
+    void (*filter_line)(void *dst,
+                        void *prev, void *cur, void *next,
                         int w, int prefs, int mrefs, int parity, int mode);
+    void (*filter_edges)(void *dst, void *prev, void *cur, void *next,
+                         int w, int prefs, int mrefs, int parity, int mode,
+                         int l_edge);
 
     const AVPixFmtDescriptor *csp;
     int eof;
diff --git a/libavformat/Makefile b/libavformat/Makefile
index daa406f..03d7e23 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -25,6 +25,29 @@
        utils.o              \
 
 OBJS-$(CONFIG_NETWORK)                   += network.o
+OBJS-$(CONFIG_RTPDEC)                    += rdt.o                       \
+                                            rtp.o                       \
+                                            rtpdec.o                    \
+                                            rtpdec_amr.o                \
+                                            rtpdec_asf.o                \
+                                            rtpdec_g726.o               \
+                                            rtpdec_h263.o               \
+                                            rtpdec_h263_rfc2190.o       \
+                                            rtpdec_h264.o               \
+                                            rtpdec_ilbc.o               \
+                                            rtpdec_jpeg.o               \
+                                            rtpdec_latm.o               \
+                                            rtpdec_mpeg12.o             \
+                                            rtpdec_mpeg4.o              \
+                                            rtpdec_mpegts.o             \
+                                            rtpdec_qcelp.o              \
+                                            rtpdec_qdm2.o               \
+                                            rtpdec_qt.o                 \
+                                            rtpdec_svq3.o               \
+                                            rtpdec_vp8.o                \
+                                            rtpdec_xiph.o               \
+                                            srtp.o
+OBJS-$(CONFIG_RTPENC_CHAIN)              += rtpenc_chain.o rtp.o
 
 # muxers/demuxers
 OBJS-$(CONFIG_A64_MUXER)                 += a64.o rawenc.o
@@ -40,25 +63,27 @@
 OBJS-$(CONFIG_AFC_DEMUXER)               += afc.o
 OBJS-$(CONFIG_AIFF_DEMUXER)              += aiffdec.o pcm.o isom.o \
                                             mov_chan.o
-OBJS-$(CONFIG_AIFF_MUXER)                += aiffenc.o isom.o
+OBJS-$(CONFIG_AIFF_MUXER)                += aiffenc.o isom.o id3v2enc.o
 OBJS-$(CONFIG_AMR_DEMUXER)               += amr.o
 OBJS-$(CONFIG_AMR_MUXER)                 += amr.o
 OBJS-$(CONFIG_ANM_DEMUXER)               += anm.o
 OBJS-$(CONFIG_APC_DEMUXER)               += apc.o
 OBJS-$(CONFIG_APE_DEMUXER)               += ape.o apetag.o img2.o
+OBJS-$(CONFIG_AQTITLE_DEMUXER)           += aqtitledec.o
 OBJS-$(CONFIG_ASF_DEMUXER)               += asfdec.o asf.o asfcrypt.o \
                                             avlanguage.o
 OBJS-$(CONFIG_ASF_MUXER)                 += asfenc.o asf.o
 OBJS-$(CONFIG_ASS_DEMUXER)               += assdec.o
 OBJS-$(CONFIG_ASS_MUXER)                 += assenc.o
-OBJS-$(CONFIG_AST_DEMUXER)               += ast.o
+OBJS-$(CONFIG_AST_DEMUXER)               += ast.o astdec.o
+OBJS-$(CONFIG_AST_MUXER)                 += ast.o astenc.o
 OBJS-$(CONFIG_AU_DEMUXER)                += au.o pcm.o
-OBJS-$(CONFIG_AU_MUXER)                  += au.o
+OBJS-$(CONFIG_AU_MUXER)                  += au.o rawenc.o
 OBJS-$(CONFIG_AVI_DEMUXER)               += avidec.o
 OBJS-$(CONFIG_AVI_MUXER)                 += avienc.o
 OBJS-$(CONFIG_AVISYNTH)                  += avisynth.o
 OBJS-$(CONFIG_AVM2_MUXER)                += swfenc.o swf.o
-OBJS-$(CONFIG_AVR_DEMUXER)               += avr.o rawdec.o pcm.o
+OBJS-$(CONFIG_AVR_DEMUXER)               += avr.o pcm.o
 OBJS-$(CONFIG_AVS_DEMUXER)               += avs.o vocdec.o voc.o
 OBJS-$(CONFIG_BETHSOFTVID_DEMUXER)       += bethsoftvid.o
 OBJS-$(CONFIG_BFI_DEMUXER)               += bfi.o
@@ -76,6 +101,7 @@
 OBJS-$(CONFIG_CAVSVIDEO_MUXER)           += rawenc.o
 OBJS-$(CONFIG_CDG_DEMUXER)               += cdg.o
 OBJS-$(CONFIG_CDXL_DEMUXER)              += cdxl.o
+OBJS-$(CONFIG_CONCAT_DEMUXER)            += concatdec.o
 OBJS-$(CONFIG_CRC_MUXER)                 += crcenc.o
 OBJS-$(CONFIG_DAUD_DEMUXER)              += daud.o
 OBJS-$(CONFIG_DAUD_MUXER)                += daud.o
@@ -95,6 +121,7 @@
 OBJS-$(CONFIG_EA_DEMUXER)                += electronicarts.o
 OBJS-$(CONFIG_EAC3_DEMUXER)              += ac3dec.o rawdec.o
 OBJS-$(CONFIG_EAC3_MUXER)                += rawenc.o
+OBJS-$(CONFIG_EPAF_DEMUXER)              += epafdec.o pcm.o
 OBJS-$(CONFIG_FFM_DEMUXER)               += ffmdec.o
 OBJS-$(CONFIG_FFM_MUXER)                 += ffmenc.o
 OBJS-$(CONFIG_FFMETADATA_DEMUXER)        += ffmetadec.o
@@ -112,6 +139,7 @@
 OBJS-$(CONFIG_FOURXM_DEMUXER)            += 4xm.o
 OBJS-$(CONFIG_FRAMECRC_MUXER)            += framecrcenc.o framehash.o
 OBJS-$(CONFIG_FRAMEMD5_MUXER)            += md5enc.o framehash.o
+OBJS-$(CONFIG_FRM_DEMUXER)               += frmdec.o
 OBJS-$(CONFIG_GIF_MUXER)                 += gif.o
 OBJS-$(CONFIG_GIF_DEMUXER)               += gifdec.o
 OBJS-$(CONFIG_GSM_DEMUXER)               += gsmdec.o
@@ -133,7 +161,7 @@
 OBJS-$(CONFIG_ICO_DEMUXER)               += icodec.o
 OBJS-$(CONFIG_ICO_MUXER)                 += icoenc.o
 OBJS-$(CONFIG_IDCIN_DEMUXER)             += idcin.o
-OBJS-$(CONFIG_IDF_DEMUXER)               += bintext.o
+OBJS-$(CONFIG_IDF_DEMUXER)               += bintext.o sauce.o
 OBJS-$(CONFIG_IFF_DEMUXER)               += iff.o
 OBJS-$(CONFIG_ILBC_DEMUXER)              += ilbc.o
 OBJS-$(CONFIG_ILBC_MUXER)                += ilbc.o
@@ -143,6 +171,8 @@
 OBJS-$(CONFIG_IMAGE2PIPE_MUXER)          += img2enc.o img2.o
 OBJS-$(CONFIG_INGENIENT_DEMUXER)         += ingenientdec.o rawdec.o
 OBJS-$(CONFIG_IPMOVIE_DEMUXER)           += ipmovie.o
+OBJS-$(CONFIG_IRCAM_DEMUXER)             += ircamdec.o ircam.o pcm.o
+OBJS-$(CONFIG_IRCAM_MUXER)               += ircamenc.o ircam.o rawenc.o
 OBJS-$(CONFIG_ISS_DEMUXER)               += iss.o
 OBJS-$(CONFIG_IV8_DEMUXER)               += iv8.o
 OBJS-$(CONFIG_IVF_DEMUXER)               += ivfdec.o
@@ -153,7 +183,7 @@
 OBJS-$(CONFIG_LATM_DEMUXER)              += rawdec.o
 OBJS-$(CONFIG_LATM_MUXER)                += latmenc.o rawenc.o
 OBJS-$(CONFIG_LMLM4_DEMUXER)             += lmlm4.o
-OBJS-$(CONFIG_LOAS_DEMUXER)              += loasdec.o
+OBJS-$(CONFIG_LOAS_DEMUXER)              += loasdec.o rawdec.o
 OBJS-$(CONFIG_LVF_DEMUXER)               += lvfdec.o
 OBJS-$(CONFIG_LXF_DEMUXER)               += lxfdec.o
 OBJS-$(CONFIG_M4V_DEMUXER)               += m4vdec.o rawdec.o
@@ -166,18 +196,17 @@
 OBJS-$(CONFIG_MD5_MUXER)                 += md5enc.o
 OBJS-$(CONFIG_MGSTS_DEMUXER)             += mgsts.o
 OBJS-$(CONFIG_MICRODVD_DEMUXER)          += microdvddec.o
-OBJS-$(CONFIG_MICRODVD_MUXER)            += microdvdenc.o rawenc.o
+OBJS-$(CONFIG_MICRODVD_MUXER)            += microdvdenc.o
 OBJS-$(CONFIG_MJPEG_DEMUXER)             += rawdec.o
 OBJS-$(CONFIG_MJPEG_MUXER)               += rawenc.o
 OBJS-$(CONFIG_MLP_DEMUXER)               += rawdec.o
 OBJS-$(CONFIG_MLP_MUXER)                 += rawenc.o
 OBJS-$(CONFIG_MM_DEMUXER)                += mm.o
-OBJS-$(CONFIG_MMF_DEMUXER)               += mmf.o pcm.o
-OBJS-$(CONFIG_MMF_MUXER)                 += mmf.o
+OBJS-$(CONFIG_MMF_DEMUXER)               += mmf.o
+OBJS-$(CONFIG_MMF_MUXER)                 += mmf.o rawenc.o
 OBJS-$(CONFIG_MOV_DEMUXER)               += mov.o isom.o mov_chan.o
 OBJS-$(CONFIG_MOV_MUXER)                 += movenc.o isom.o avc.o \
-                                            movenchint.o rtpenc_chain.o \
-                                            mov_chan.o
+                                            movenchint.o mov_chan.o rtp.o
 OBJS-$(CONFIG_MP2_MUXER)                 += mp3enc.o rawenc.o id3v2enc.o
 OBJS-$(CONFIG_MP3_DEMUXER)               += mp3dec.o
 OBJS-$(CONFIG_MP3_MUXER)                 += mp3enc.o rawenc.o id3v2enc.o
@@ -195,13 +224,17 @@
 OBJS-$(CONFIG_MPEGTS_MUXER)              += mpegtsenc.o
 OBJS-$(CONFIG_MPEGVIDEO_DEMUXER)         += mpegvideodec.o rawdec.o
 OBJS-$(CONFIG_MPJPEG_MUXER)              += mpjpeg.o
+OBJS-$(CONFIG_MPL2_DEMUXER)              += mpl2dec.o
+OBJS-$(CONFIG_MPSUB_DEMUXER)             += mpsubdec.o
 OBJS-$(CONFIG_MSNWC_TCP_DEMUXER)         += msnwc_tcp.o
 OBJS-$(CONFIG_MTV_DEMUXER)               += mtv.o
 OBJS-$(CONFIG_MVI_DEMUXER)               += mvi.o
+OBJS-$(CONFIG_MV_DEMUXER)                += mvdec.o
 OBJS-$(CONFIG_MXF_DEMUXER)               += mxfdec.o mxf.o
 OBJS-$(CONFIG_MXF_MUXER)                 += mxfenc.o mxf.o audiointerleave.o
 OBJS-$(CONFIG_MXG_DEMUXER)               += mxg.o
 OBJS-$(CONFIG_NC_DEMUXER)                += ncdec.o
+OBJS-$(CONFIG_NISTSPHERE_DEMUXER)        += nistspheredec.o pcm.o
 OBJS-$(CONFIG_NSV_DEMUXER)               += nsvdec.o
 OBJS-$(CONFIG_NULL_MUXER)                += nullenc.o
 OBJS-$(CONFIG_NUT_DEMUXER)               += nutdec.o nut.o
@@ -263,6 +296,7 @@
 OBJS-$(CONFIG_PCM_U32LE_MUXER)           += pcmenc.o rawenc.o
 OBJS-$(CONFIG_PCM_U8_DEMUXER)            += pcmdec.o pcm.o
 OBJS-$(CONFIG_PCM_U8_MUXER)              += pcmenc.o rawenc.o
+OBJS-$(CONFIG_PJS_DEMUXER)               += pjsdec.o
 OBJS-$(CONFIG_PMP_DEMUXER)               += pmpdec.o
 OBJS-$(CONFIG_PVA_DEMUXER)               += pva.o
 OBJS-$(CONFIG_PVF_DEMUXER)               += pvfdec.o pcm.o
@@ -292,32 +326,13 @@
                                             rtpenc_vp8.o  \
                                             rtpenc_xiph.o \
                                             avc.o
-OBJS-$(CONFIG_RTPDEC)                    += rdt.o         \
-                                            rtp.o         \
-                                            rtpdec.o      \
-                                            rtpdec_amr.o  \
-                                            rtpdec_asf.o  \
-                                            rtpdec_g726.o \
-                                            rtpdec_h263.o \
-                                            rtpdec_h263_rfc2190.o \
-                                            rtpdec_h264.o \
-                                            rtpdec_ilbc.o \
-                                            rtpdec_jpeg.o \
-                                            rtpdec_latm.o \
-                                            rtpdec_mpeg4.o \
-                                            rtpdec_qcelp.o \
-                                            rtpdec_qdm2.o \
-                                            rtpdec_qt.o   \
-                                            rtpdec_svq3.o \
-                                            rtpdec_vp8.o  \
-                                            rtpdec_xiph.o
 OBJS-$(CONFIG_RTSP_DEMUXER)              += rtsp.o rtspdec.o httpauth.o \
                                             urldecode.o
 OBJS-$(CONFIG_RTSP_MUXER)                += rtsp.o rtspenc.o httpauth.o \
-                                            rtpenc_chain.o urldecode.o
+                                            urldecode.o
 OBJS-$(CONFIG_SAMI_DEMUXER)              += samidec.o
 OBJS-$(CONFIG_SAP_DEMUXER)               += sapdec.o
-OBJS-$(CONFIG_SAP_MUXER)                 += sapenc.o rtpenc_chain.o
+OBJS-$(CONFIG_SAP_MUXER)                 += sapenc.o
 OBJS-$(CONFIG_SBG_DEMUXER)               += sbgdec.o
 OBJS-$(CONFIG_SDP_DEMUXER)               += rtsp.o
 OBJS-$(CONFIG_SEGAFILM_DEMUXER)          += segafilm.o
@@ -331,16 +346,19 @@
 OBJS-$(CONFIG_SMUSH_DEMUXER)             += smush.o
 OBJS-$(CONFIG_SOL_DEMUXER)               += sol.o pcm.o
 OBJS-$(CONFIG_SOX_DEMUXER)               += soxdec.o pcm.o
-OBJS-$(CONFIG_SOX_MUXER)                 += soxenc.o
+OBJS-$(CONFIG_SOX_MUXER)                 += soxenc.o rawenc.o
 OBJS-$(CONFIG_SPDIF_DEMUXER)             += spdif.o spdifdec.o
 OBJS-$(CONFIG_SPDIF_MUXER)               += spdif.o spdifenc.o
 OBJS-$(CONFIG_SRT_DEMUXER)               += srtdec.o
 OBJS-$(CONFIG_SRT_MUXER)                 += srtenc.o
 OBJS-$(CONFIG_STR_DEMUXER)               += psxstr.o
+OBJS-$(CONFIG_SUBVIEWER1_DEMUXER)        += subviewer1dec.o
 OBJS-$(CONFIG_SUBVIEWER_DEMUXER)         += subviewerdec.o
 OBJS-$(CONFIG_SWF_DEMUXER)               += swfdec.o swf.o
 OBJS-$(CONFIG_SWF_MUXER)                 += swfenc.o swf.o
 OBJS-$(CONFIG_TAK_DEMUXER)               += takdec.o apetag.o img2.o rawdec.o
+OBJS-$(CONFIG_TEDCAPTIONS_DEMUXER)       += tedcaptionsdec.o
+OBJS-$(CONFIG_TEE_MUXER)                 += tee.o
 OBJS-$(CONFIG_THP_DEMUXER)               += thp.o
 OBJS-$(CONFIG_TIERTEXSEQ_DEMUXER)        += tiertexseq.o
 OBJS-$(CONFIG_MKVTIMESTAMP_V2_MUXER)     += mkvtimestamp_v2.o
@@ -357,8 +375,10 @@
 OBJS-$(CONFIG_VMD_DEMUXER)               += sierravmd.o
 OBJS-$(CONFIG_VOC_DEMUXER)               += vocdec.o voc.o
 OBJS-$(CONFIG_VOC_MUXER)                 += vocenc.o voc.o
+OBJS-$(CONFIG_VPLAYER_DEMUXER)           += vplayerdec.o
 OBJS-$(CONFIG_VQF_DEMUXER)               += vqf.o
-OBJS-$(CONFIG_W64_DEMUXER)               += wavdec.o pcm.o
+OBJS-$(CONFIG_W64_DEMUXER)               += wavdec.o w64.o pcm.o
+OBJS-$(CONFIG_W64_MUXER)                 += wavenc.o w64.o
 OBJS-$(CONFIG_WAV_DEMUXER)               += wavdec.o pcm.o
 OBJS-$(CONFIG_WAV_MUXER)                 += wavenc.o
 OBJS-$(CONFIG_WC3_DEMUXER)               += wc3movie.o
@@ -393,6 +413,7 @@
 OBJS-$(CONFIG_CACHE_PROTOCOL)            += cache.o
 OBJS-$(CONFIG_CONCAT_PROTOCOL)           += concat.o
 OBJS-$(CONFIG_CRYPTO_PROTOCOL)           += crypto.o
+OBJS-$(CONFIG_DATA_PROTOCOL)             += data_uri.o
 OBJS-$(CONFIG_FFRTMPCRYPT_PROTOCOL)      += rtmpcrypt.o rtmpdh.o
 OBJS-$(CONFIG_FFRTMPHTTP_PROTOCOL)       += rtmphttp.o
 OBJS-$(CONFIG_FILE_PROTOCOL)             += file.o
@@ -413,16 +434,20 @@
 OBJS-$(CONFIG_RTMPTS_PROTOCOL)           += rtmpproto.o rtmppkt.o
 OBJS-$(CONFIG_RTP_PROTOCOL)              += rtpproto.o
 OBJS-$(CONFIG_SCTP_PROTOCOL)             += sctp.o
+OBJS-$(CONFIG_SRTP_PROTOCOL)             += srtpproto.o srtp.o
 OBJS-$(CONFIG_TCP_PROTOCOL)              += tcp.o
 OBJS-$(CONFIG_TLS_PROTOCOL)              += tls.o
 OBJS-$(CONFIG_UDP_PROTOCOL)              += udp.o
 
 SKIPHEADERS-$(CONFIG_FFRTMPCRYPT_PROTOCOL) += rtmpdh.h
 SKIPHEADERS-$(CONFIG_NETWORK)            += network.h rtsp.h
-TESTPROGS = seek                                                        \
+TESTPROGS = noproxy                                                     \
+            seek                                                        \
+            srtp                                                        \
             url                                                         \
 
 TOOLS     = aviocat                                                     \
             ismindex                                                    \
             pktdumper                                                   \
             probetest                                                   \
+            seek_print                                                  \
diff --git a/libavformat/aacdec.c b/libavformat/aacdec.c
index e165959..7c17dd0 100644
--- a/libavformat/aacdec.c
+++ b/libavformat/aacdec.c
@@ -31,10 +31,10 @@
 {
     int max_frames = 0, first_frames = 0;
     int fsize, frames;
-    uint8_t *buf0 = p->buf;
-    uint8_t *buf2;
-    uint8_t *buf;
-    uint8_t *end = buf0 + p->buf_size - 7;
+    const uint8_t *buf0 = p->buf;
+    const uint8_t *buf2;
+    const uint8_t *buf;
+    const uint8_t *end = buf0 + p->buf_size - 7;
 
     buf = buf0;
 
diff --git a/libavformat/ac3dec.c b/libavformat/ac3dec.c
index 7a34ea8..c531f8a 100644
--- a/libavformat/ac3dec.c
+++ b/libavformat/ac3dec.c
@@ -27,7 +27,7 @@
 static int ac3_eac3_probe(AVProbeData *p, enum AVCodecID expected_codec_id)
 {
     int max_frames, first_frames = 0, frames;
-    uint8_t *buf, *buf2, *end;
+    const uint8_t *buf, *buf2, *end;
     AC3HeaderInfo hdr;
     GetBitContext gbc;
     enum AVCodecID codec_id = AV_CODEC_ID_AC3;
diff --git a/libavformat/aiff.h b/libavformat/aiff.h
index 5521568..b3ef577 100644
--- a/libavformat/aiff.h
+++ b/libavformat/aiff.h
@@ -40,6 +40,8 @@
     { AV_CODEC_ID_PCM_F64BE,    MKTAG('f','l','6','4') },
     { AV_CODEC_ID_PCM_ALAW,     MKTAG('a','l','a','w') },
     { AV_CODEC_ID_PCM_MULAW,    MKTAG('u','l','a','w') },
+    { AV_CODEC_ID_PCM_S24BE,    MKTAG('i','n','2','4') },
+    { AV_CODEC_ID_PCM_S32BE,    MKTAG('i','n','3','2') },
     { 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',' ') },
diff --git a/libavformat/aiffdec.c b/libavformat/aiffdec.c
index 79b7853..8d466fa 100644
--- a/libavformat/aiffdec.c
+++ b/libavformat/aiffdec.c
@@ -280,8 +280,10 @@
                 return AVERROR(ENOMEM);
             st->codec->extradata_size = size;
             avio_read(pb, st->codec->extradata, size);
-            if (st->codec->codec_id == AV_CODEC_ID_QDM2 && size>=12*4 && !st->codec->block_align)
+            if (st->codec->codec_id == AV_CODEC_ID_QDM2 && size>=12*4 && !st->codec->block_align) {
                 st->codec->block_align = AV_RB32(st->codec->extradata+11*4);
+                aiff->block_duration = AV_RB32(st->codec->extradata+9*4);
+            }
             break;
         case MKTAG('C','H','A','N'):
             if(ff_mov_read_chan(s, pb, st, size) < 0)
diff --git a/libavformat/aiffenc.c b/libavformat/aiffenc.c
index 8cdb261..7c0b4fb 100644
--- a/libavformat/aiffenc.c
+++ b/libavformat/aiffenc.c
@@ -20,25 +20,106 @@
  */
 
 #include "libavutil/intfloat.h"
+#include "libavutil/opt.h"
 #include "avformat.h"
 #include "internal.h"
 #include "aiff.h"
 #include "avio_internal.h"
 #include "isom.h"
+#include "id3v2.h"
 
 typedef struct {
+    const AVClass *class;
     int64_t form;
     int64_t frames;
     int64_t ssnd;
+    int audio_stream_idx;
+    AVPacketList *pict_list;
+    int write_id3v2;
+    int id3v2_version;
 } AIFFOutputContext;
 
+static int put_id3v2_tags(AVFormatContext *s, AIFFOutputContext *aiff)
+{
+    int ret;
+    uint64_t pos, end, size;
+    ID3v2EncContext id3v2 = { 0 };
+    AVIOContext *pb = s->pb;
+    AVPacketList *pict_list = aiff->pict_list;
+
+    if (!pb->seekable)
+        return 0;
+
+    if (!s->metadata && !aiff->pict_list)
+        return 0;
+
+    avio_wl32(pb, MKTAG('I', 'D', '3', ' '));
+    avio_wb32(pb, 0);
+    pos = avio_tell(pb);
+
+    ff_id3v2_start(&id3v2, pb, aiff->id3v2_version, ID3v2_DEFAULT_MAGIC);
+    ff_id3v2_write_metadata(s, &id3v2);
+    while (pict_list) {
+        if ((ret = ff_id3v2_write_apic(s, &id3v2, &pict_list->pkt)) < 0)
+            return ret;
+        pict_list = pict_list->next;
+    }
+    ff_id3v2_finish(&id3v2, pb);
+
+    end = avio_tell(pb);
+    size = end - pos;
+
+    /* Update chunk size */
+    avio_seek(pb, pos - 4, SEEK_SET);
+    avio_wb32(pb, size);
+    avio_seek(pb, end, SEEK_SET);
+
+    if (size & 1)
+        avio_w8(pb, 0);
+
+    return 0;
+}
+
+static void put_meta(AVFormatContext *s, const char *key, uint32_t id)
+{
+    AVDictionaryEntry *tag;
+    AVIOContext *pb = s->pb;
+
+    if (tag = av_dict_get(s->metadata, key, NULL, 0)) {
+        int size = strlen(tag->value);
+
+        avio_wl32(pb, id);
+        avio_wb32(pb, FFALIGN(size, 2));
+        avio_write(pb, tag->value, size);
+        if (size & 1)
+            avio_w8(pb, 0);
+    }
+}
+
 static int aiff_write_header(AVFormatContext *s)
 {
     AIFFOutputContext *aiff = s->priv_data;
     AVIOContext *pb = s->pb;
-    AVCodecContext *enc = s->streams[0]->codec;
+    AVCodecContext *enc;
     uint64_t sample_rate;
-    int aifc = 0;
+    int i, aifc = 0;
+
+    aiff->audio_stream_idx = -1;
+    for (i = 0; i < s->nb_streams; i++) {
+        AVStream *st = s->streams[i];
+        if (aiff->audio_stream_idx < 0 && st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
+            aiff->audio_stream_idx = i;
+        } else if (st->codec->codec_type != AVMEDIA_TYPE_VIDEO) {
+            av_log(s, AV_LOG_ERROR, "Only audio streams and pictures are allowed in AIFF.\n");
+            return AVERROR(EINVAL);
+        }
+    }
+    if (aiff->audio_stream_idx < 0) {
+        av_log(s, AV_LOG_ERROR, "No audio stream present.\n");
+        return AVERROR(EINVAL);
+    }
+
+    enc = s->streams[aiff->audio_stream_idx]->codec;
 
     /* First verify if format is ok */
     if (!enc->codec_tag)
@@ -53,7 +134,6 @@
     ffio_wfourcc(pb, aifc ? "AIFC" : "AIFF");
 
     if (aifc) { // compressed audio
-        enc->bits_per_coded_sample = 16;
         if (!enc->block_align) {
             av_log(s, AV_LOG_ERROR, "block align not set\n");
             return -1;
@@ -70,6 +150,11 @@
         ff_mov_write_chan(pb, enc->channel_layout);
     }
 
+    put_meta(s, "title",     MKTAG('N', 'A', 'M', 'E'));
+    put_meta(s, "author",    MKTAG('A', 'U', 'T', 'H'));
+    put_meta(s, "copyright", MKTAG('(', 'c', ')', ' '));
+    put_meta(s, "comment",   MKTAG('A', 'N', 'N', 'O'));
+
     /* Common chunk */
     ffio_wfourcc(pb, "COMM");
     avio_wb32(pb, aifc ? 24 : 18); /* size */
@@ -111,7 +196,8 @@
     avio_wb32(pb, 0);                    /* Data offset */
     avio_wb32(pb, 0);                    /* Block-size (block align) */
 
-    avpriv_set_pts_info(s->streams[0], 64, 1, s->streams[0]->codec->sample_rate);
+    avpriv_set_pts_info(s->streams[aiff->audio_stream_idx], 64, 1,
+                        s->streams[aiff->audio_stream_idx]->codec->sample_rate);
 
     /* Data is starting here */
     avio_flush(pb);
@@ -121,16 +207,54 @@
 
 static int aiff_write_packet(AVFormatContext *s, AVPacket *pkt)
 {
+    AIFFOutputContext *aiff = s->priv_data;
     AVIOContext *pb = s->pb;
-    avio_write(pb, pkt->data, pkt->size);
+    if (pkt->stream_index == aiff->audio_stream_idx)
+        avio_write(pb, pkt->data, pkt->size);
+    else {
+        int ret;
+        AVPacketList *pict_list, *last;
+
+        if (s->streams[pkt->stream_index]->codec->codec_type != AVMEDIA_TYPE_VIDEO)
+            return 0;
+
+        /* warn only once for each stream */
+        if (s->streams[pkt->stream_index]->nb_frames == 1) {
+            av_log(s, AV_LOG_WARNING, "Got more than one picture in stream %d,"
+                   " ignoring.\n", pkt->stream_index);
+        }
+        if (s->streams[pkt->stream_index]->nb_frames >= 1)
+            return 0;
+
+        pict_list = av_mallocz(sizeof(AVPacketList));
+        if (!pict_list)
+            return AVERROR(ENOMEM);
+
+        if ((ret = av_copy_packet(&pict_list->pkt, pkt)) < 0) {
+            av_freep(&pict_list);
+            return ret;
+        }
+
+        if (!aiff->pict_list)
+            aiff->pict_list = pict_list;
+        else {
+            last = aiff->pict_list;
+            while (last->next)
+                last = last->next;
+            last->next = pict_list;
+        }
+    }
+
     return 0;
 }
 
 static int aiff_write_trailer(AVFormatContext *s)
 {
+    int ret;
     AVIOContext *pb = s->pb;
     AIFFOutputContext *aiff = s->priv_data;
-    AVCodecContext *enc = s->streams[0]->codec;
+    AVPacketList *pict_list = aiff->pict_list;
+    AVCodecContext *enc = s->streams[aiff->audio_stream_idx]->codec;
 
     /* Chunks sizes must be even */
     int64_t file_size, end_size;
@@ -141,10 +265,6 @@
     }
 
     if (s->pb->seekable) {
-        /* File length */
-        avio_seek(pb, aiff->form, SEEK_SET);
-        avio_wb32(pb, file_size - aiff->form - 4);
-
         /* Number of sample frames */
         avio_seek(pb, aiff->frames, SEEK_SET);
         avio_wb32(pb, (file_size-aiff->ssnd-12)/enc->block_align);
@@ -156,12 +276,46 @@
         /* return to the end */
         avio_seek(pb, end_size, SEEK_SET);
 
+        /* Write ID3 tags */
+        if (aiff->write_id3v2)
+            if ((ret = put_id3v2_tags(s, aiff)) < 0)
+                return ret;
+
+        /* File length */
+        file_size = avio_tell(pb);
+        avio_seek(pb, aiff->form, SEEK_SET);
+        avio_wb32(pb, file_size - aiff->form - 4);
+
         avio_flush(pb);
     }
 
+    while (pict_list) {
+        AVPacketList *next = pict_list->next;
+        av_free_packet(&pict_list->pkt);
+        av_freep(&pict_list);
+        pict_list = next;
+    }
+
     return 0;
 }
 
+#define OFFSET(x) offsetof(AIFFOutputContext, x)
+#define ENC AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+    { "write_id3v2", "Enable ID3 tags writing.",
+      OFFSET(write_id3v2), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, ENC },
+    { "id3v2_version", "Select ID3v2 version to write. Currently 3 and 4 are supported.",
+      OFFSET(id3v2_version), AV_OPT_TYPE_INT, {.i64 = 4}, 3, 4, ENC },
+    { NULL },
+};
+
+static const AVClass aiff_muxer_class = {
+    .class_name     = "AIFF muxer",
+    .item_name      = av_default_item_name,
+    .option         = options,
+    .version        = LIBAVUTIL_VERSION_INT,
+};
+
 AVOutputFormat ff_aiff_muxer = {
     .name              = "aiff",
     .long_name         = NULL_IF_CONFIG_SMALL("Audio IFF"),
@@ -169,9 +323,10 @@
     .extensions        = "aif,aiff,afc,aifc",
     .priv_data_size    = sizeof(AIFFOutputContext),
     .audio_codec       = AV_CODEC_ID_PCM_S16BE,
-    .video_codec       = AV_CODEC_ID_NONE,
+    .video_codec       = AV_CODEC_ID_PNG,
     .write_header      = aiff_write_header,
     .write_packet      = aiff_write_packet,
     .write_trailer     = aiff_write_trailer,
     .codec_tag         = (const AVCodecTag* const []){ ff_codec_aiff_tags, 0 },
+    .priv_class        = &aiff_muxer_class,
 };
diff --git a/libavformat/allformats.c b/libavformat/allformats.c
index 2987b8a..ec91b24 100644
--- a/libavformat/allformats.c
+++ b/libavformat/allformats.c
@@ -18,25 +18,36 @@
  * 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 "rtp.h"
 #include "rdt.h"
 #include "url.h"
 #include "version.h"
 
-#define REGISTER_MUXER(X,x) { \
-    extern AVOutputFormat ff_##x##_muxer; \
-    if(CONFIG_##X##_MUXER) av_register_output_format(&ff_##x##_muxer); }
+#define REGISTER_MUXER(X, x)                                            \
+    {                                                                   \
+        extern AVOutputFormat ff_##x##_muxer;                           \
+        if (CONFIG_##X##_MUXER)                                         \
+            av_register_output_format(&ff_##x##_muxer);                 \
+    }
 
-#define REGISTER_DEMUXER(X,x) { \
-    extern AVInputFormat ff_##x##_demuxer; \
-    if(CONFIG_##X##_DEMUXER) av_register_input_format(&ff_##x##_demuxer); }
+#define REGISTER_DEMUXER(X, x)                                          \
+    {                                                                   \
+        extern AVInputFormat ff_##x##_demuxer;                          \
+        if (CONFIG_##X##_DEMUXER)                                       \
+            av_register_input_format(&ff_##x##_demuxer);                \
+    }
 
-#define REGISTER_MUXDEMUX(X,x)  REGISTER_MUXER(X,x); REGISTER_DEMUXER(X,x)
+#define REGISTER_MUXDEMUX(X, x) REGISTER_MUXER(X, x); REGISTER_DEMUXER(X, x)
 
-#define REGISTER_PROTOCOL(X,x) { \
-    extern URLProtocol ff_##x##_protocol; \
-    if(CONFIG_##X##_PROTOCOL) ffurl_register_protocol(&ff_##x##_protocol, sizeof(ff_##x##_protocol)); }
+#define REGISTER_PROTOCOL(X, x)                                         \
+    {                                                                   \
+        extern URLProtocol ff_##x##_protocol;                           \
+        if (CONFIG_##X##_PROTOCOL)                                      \
+            ffurl_register_protocol(&ff_##x##_protocol,                 \
+                                    sizeof(ff_##x##_protocol));         \
+    }
 
 void av_register_all(void)
 {
@@ -49,268 +60,285 @@
     avcodec_register_all();
 
     /* (de)muxers */
-    REGISTER_MUXER    (A64, a64);
-    REGISTER_DEMUXER  (AAC, aac);
-    REGISTER_MUXDEMUX (AC3, ac3);
-    REGISTER_DEMUXER  (ACT, act);
-    REGISTER_DEMUXER  (ADF, adf);
-    REGISTER_MUXER    (ADTS, adts);
-    REGISTER_MUXDEMUX (ADX, adx);
-    REGISTER_DEMUXER  (AEA, aea);
-    REGISTER_DEMUXER  (AFC, afc);
-    REGISTER_MUXDEMUX (AIFF, aiff);
-    REGISTER_MUXDEMUX (AMR, amr);
-    REGISTER_DEMUXER  (ANM, anm);
-    REGISTER_DEMUXER  (APC, apc);
-    REGISTER_DEMUXER  (APE, ape);
-    REGISTER_MUXDEMUX (ASF, asf);
-    REGISTER_MUXDEMUX (ASS, ass);
-    REGISTER_DEMUXER  (AST, ast);
-    REGISTER_MUXER    (ASF_STREAM, asf_stream);
-    REGISTER_MUXDEMUX (AU, au);
-    REGISTER_MUXDEMUX (AVI, avi);
-    REGISTER_DEMUXER  (AVISYNTH, avisynth);
-    REGISTER_MUXER    (AVM2, avm2);
-    REGISTER_DEMUXER  (AVR, avr);
-    REGISTER_DEMUXER  (AVS, avs);
-    REGISTER_DEMUXER  (BETHSOFTVID, bethsoftvid);
-    REGISTER_DEMUXER  (BFI, bfi);
-    REGISTER_DEMUXER  (BINTEXT, bintext);
-    REGISTER_DEMUXER  (BINK, bink);
-    REGISTER_MUXDEMUX (BIT, bit);
-    REGISTER_DEMUXER  (BMV, bmv);
-    REGISTER_DEMUXER  (BRSTM, brstm);
-    REGISTER_DEMUXER  (C93, c93);
-    REGISTER_MUXDEMUX (CAF, caf);
-    REGISTER_MUXDEMUX (CAVSVIDEO, cavsvideo);
-    REGISTER_DEMUXER  (CDG, cdg);
-    REGISTER_DEMUXER  (CDXL, cdxl);
-    REGISTER_MUXER    (CRC, crc);
-    REGISTER_MUXDEMUX (DAUD, daud);
-    REGISTER_DEMUXER  (DFA, dfa);
-    REGISTER_MUXDEMUX (DIRAC, dirac);
-    REGISTER_MUXDEMUX (DNXHD, dnxhd);
-    REGISTER_DEMUXER  (DSICIN, dsicin);
-    REGISTER_MUXDEMUX (DTS, dts);
-    REGISTER_DEMUXER  (DTSHD, dtshd);
-    REGISTER_MUXDEMUX (DV, dv);
-    REGISTER_DEMUXER  (DXA, dxa);
-    REGISTER_DEMUXER  (EA, ea);
-    REGISTER_DEMUXER  (EA_CDATA, ea_cdata);
-    REGISTER_MUXDEMUX (EAC3, eac3);
-    REGISTER_MUXER    (F4V, f4v);
-    REGISTER_MUXDEMUX (FFM, ffm);
-    REGISTER_MUXDEMUX (FFMETADATA, ffmetadata);
-    REGISTER_MUXDEMUX (FILMSTRIP, filmstrip);
-    REGISTER_MUXDEMUX (FLAC, flac);
-    REGISTER_DEMUXER  (FLIC, flic);
-    REGISTER_MUXDEMUX (FLV, flv);
-    REGISTER_DEMUXER  (FOURXM, fourxm);
-    REGISTER_MUXER    (FRAMECRC, framecrc);
-    REGISTER_MUXER    (FRAMEMD5, framemd5);
-    REGISTER_MUXDEMUX (G722, g722);
-    REGISTER_MUXDEMUX (G723_1, g723_1);
-    REGISTER_DEMUXER  (G729, g729);
-    REGISTER_MUXDEMUX (GIF, gif);
-    REGISTER_DEMUXER  (GSM, gsm);
-    REGISTER_MUXDEMUX (GXF, gxf);
-    REGISTER_MUXDEMUX (H261, h261);
-    REGISTER_MUXDEMUX (H263, h263);
-    REGISTER_MUXDEMUX (H264, h264);
-    REGISTER_MUXDEMUX (HLS, hls);
-    REGISTER_MUXDEMUX (ICO, ico);
-    REGISTER_DEMUXER  (IDCIN, idcin);
-    REGISTER_DEMUXER  (IDF, idf);
-    REGISTER_DEMUXER  (IFF, iff);
-    REGISTER_MUXDEMUX (ILBC, ilbc);
-    REGISTER_MUXDEMUX (IMAGE2, image2);
-    REGISTER_MUXDEMUX (IMAGE2PIPE, image2pipe);
-    REGISTER_DEMUXER  (INGENIENT, ingenient);
-    REGISTER_DEMUXER  (IPMOVIE, ipmovie);
-    REGISTER_MUXER    (IPOD, ipod);
-    REGISTER_MUXER    (ISMV, ismv);
-    REGISTER_DEMUXER  (ISS, iss);
-    REGISTER_DEMUXER  (IV8, iv8);
-    REGISTER_MUXDEMUX (IVF, ivf);
-    REGISTER_MUXDEMUX (JACOSUB, jacosub);
-    REGISTER_DEMUXER  (JV, jv);
-    REGISTER_MUXDEMUX (LATM, latm);
-    REGISTER_DEMUXER  (LMLM4, lmlm4);
-    REGISTER_DEMUXER  (LOAS, loas);
-    REGISTER_DEMUXER  (LVF, lvf);
-    REGISTER_DEMUXER  (LXF, lxf);
-    REGISTER_MUXDEMUX (M4V, m4v);
-    REGISTER_MUXER    (MD5, md5);
-    REGISTER_MUXDEMUX (MATROSKA, matroska);
-    REGISTER_MUXER    (MATROSKA_AUDIO, matroska_audio);
-    REGISTER_DEMUXER  (MGSTS, mgsts);
-    REGISTER_MUXDEMUX (MICRODVD, microdvd);
-    REGISTER_MUXDEMUX (MJPEG, mjpeg);
-    REGISTER_MUXDEMUX (MLP, mlp);
-    REGISTER_DEMUXER  (MM, mm);
-    REGISTER_MUXDEMUX (MMF, mmf);
-    REGISTER_MUXDEMUX (MOV, mov);
-    REGISTER_MUXER    (MP2, mp2);
-    REGISTER_MUXDEMUX (MP3, mp3);
-    REGISTER_MUXER    (MP4, mp4);
-    REGISTER_DEMUXER  (MPC, mpc);
-    REGISTER_DEMUXER  (MPC8, mpc8);
-    REGISTER_MUXER    (MPEG1SYSTEM, mpeg1system);
-    REGISTER_MUXER    (MPEG1VCD, mpeg1vcd);
-    REGISTER_MUXER    (MPEG1VIDEO, mpeg1video);
-    REGISTER_MUXER    (MPEG2DVD, mpeg2dvd);
-    REGISTER_MUXER    (MPEG2SVCD, mpeg2svcd);
-    REGISTER_MUXER    (MPEG2VIDEO, mpeg2video);
-    REGISTER_MUXER    (MPEG2VOB, mpeg2vob);
-    REGISTER_DEMUXER  (MPEGPS, mpegps);
-    REGISTER_MUXDEMUX (MPEGTS, mpegts);
-    REGISTER_DEMUXER  (MPEGTSRAW, mpegtsraw);
-    REGISTER_DEMUXER  (MPEGVIDEO, mpegvideo);
-    REGISTER_MUXER    (MPJPEG, mpjpeg);
-    REGISTER_DEMUXER  (MSNWC_TCP, msnwc_tcp);
-    REGISTER_DEMUXER  (MTV, mtv);
-    REGISTER_DEMUXER  (MVI, mvi);
-    REGISTER_MUXDEMUX (MXF, mxf);
-    REGISTER_MUXER    (MXF_D10, mxf_d10);
-    REGISTER_DEMUXER  (MXG, mxg);
-    REGISTER_DEMUXER  (NC, nc);
-    REGISTER_DEMUXER  (NSV, nsv);
-    REGISTER_MUXER    (NULL, null);
-    REGISTER_MUXDEMUX (NUT, nut);
-    REGISTER_DEMUXER  (NUV, nuv);
-    REGISTER_MUXDEMUX (OGG, ogg);
-    REGISTER_MUXDEMUX (OMA, oma);
-    REGISTER_DEMUXER  (PAF, paf);
-    REGISTER_MUXDEMUX (PCM_ALAW,  pcm_alaw);
-    REGISTER_MUXDEMUX (PCM_MULAW, pcm_mulaw);
-    REGISTER_MUXDEMUX (PCM_F64BE, pcm_f64be);
-    REGISTER_MUXDEMUX (PCM_F64LE, pcm_f64le);
-    REGISTER_MUXDEMUX (PCM_F32BE, pcm_f32be);
-    REGISTER_MUXDEMUX (PCM_F32LE, pcm_f32le);
-    REGISTER_MUXDEMUX (PCM_S32BE, pcm_s32be);
-    REGISTER_MUXDEMUX (PCM_S32LE, pcm_s32le);
-    REGISTER_MUXDEMUX (PCM_S24BE, pcm_s24be);
-    REGISTER_MUXDEMUX (PCM_S24LE, pcm_s24le);
-    REGISTER_MUXDEMUX (PCM_S16BE, pcm_s16be);
-    REGISTER_MUXDEMUX (PCM_S16LE, pcm_s16le);
-    REGISTER_MUXDEMUX (PCM_S8,    pcm_s8);
-    REGISTER_MUXDEMUX (PCM_U32BE, pcm_u32be);
-    REGISTER_MUXDEMUX (PCM_U32LE, pcm_u32le);
-    REGISTER_MUXDEMUX (PCM_U24BE, pcm_u24be);
-    REGISTER_MUXDEMUX (PCM_U24LE, pcm_u24le);
-    REGISTER_MUXDEMUX (PCM_U16BE, pcm_u16be);
-    REGISTER_MUXDEMUX (PCM_U16LE, pcm_u16le);
-    REGISTER_MUXDEMUX (PCM_U8,    pcm_u8);
-    REGISTER_DEMUXER  (PMP, pmp);
-    REGISTER_MUXER    (PSP, psp);
-    REGISTER_DEMUXER  (PVA, pva);
-    REGISTER_DEMUXER  (PVF, pvf);
-    REGISTER_DEMUXER  (QCP, qcp);
-    REGISTER_DEMUXER  (R3D, r3d);
-    REGISTER_MUXDEMUX (RAWVIDEO, rawvideo);
-    REGISTER_DEMUXER  (REALTEXT, realtext);
-    REGISTER_DEMUXER  (RL2, rl2);
-    REGISTER_MUXDEMUX (RM, rm);
-    REGISTER_MUXDEMUX (ROQ, roq);
-    REGISTER_DEMUXER  (RPL, rpl);
-    REGISTER_MUXDEMUX (RSO, rso);
-    REGISTER_MUXDEMUX (RTP, rtp);
-    REGISTER_MUXDEMUX (RTSP, rtsp);
-    REGISTER_DEMUXER  (SAMI, sami);
-    REGISTER_MUXDEMUX (SAP, sap);
-    REGISTER_DEMUXER  (SBG, sbg);
-    REGISTER_DEMUXER  (SDP, sdp);
+    REGISTER_MUXER   (A64,              a64);
+    REGISTER_DEMUXER (AAC,              aac);
+    REGISTER_MUXDEMUX(AC3,              ac3);
+    REGISTER_DEMUXER (ACT,              act);
+    REGISTER_DEMUXER (ADF,              adf);
+    REGISTER_MUXER   (ADTS,             adts);
+    REGISTER_MUXDEMUX(ADX,              adx);
+    REGISTER_DEMUXER (AEA,              aea);
+    REGISTER_DEMUXER (AFC,              afc);
+    REGISTER_MUXDEMUX(AIFF,             aiff);
+    REGISTER_MUXDEMUX(AMR,              amr);
+    REGISTER_DEMUXER (ANM,              anm);
+    REGISTER_DEMUXER (APC,              apc);
+    REGISTER_DEMUXER (APE,              ape);
+    REGISTER_DEMUXER (AQTITLE,          aqtitle);
+    REGISTER_MUXDEMUX(ASF,              asf);
+    REGISTER_MUXDEMUX(ASS,              ass);
+    REGISTER_MUXDEMUX(AST,              ast);
+    REGISTER_MUXER   (ASF_STREAM,       asf_stream);
+    REGISTER_MUXDEMUX(AU,               au);
+    REGISTER_MUXDEMUX(AVI,              avi);
+    REGISTER_DEMUXER (AVISYNTH,         avisynth);
+    REGISTER_MUXER   (AVM2,             avm2);
+    REGISTER_DEMUXER (AVR,              avr);
+    REGISTER_DEMUXER (AVS,              avs);
+    REGISTER_DEMUXER (BETHSOFTVID,      bethsoftvid);
+    REGISTER_DEMUXER (BFI,              bfi);
+    REGISTER_DEMUXER (BINTEXT,          bintext);
+    REGISTER_DEMUXER (BINK,             bink);
+    REGISTER_MUXDEMUX(BIT,              bit);
+    REGISTER_DEMUXER (BMV,              bmv);
+    REGISTER_DEMUXER (BRSTM,            brstm);
+    REGISTER_DEMUXER (C93,              c93);
+    REGISTER_MUXDEMUX(CAF,              caf);
+    REGISTER_MUXDEMUX(CAVSVIDEO,        cavsvideo);
+    REGISTER_DEMUXER (CDG,              cdg);
+    REGISTER_DEMUXER (CDXL,             cdxl);
+    REGISTER_DEMUXER (CONCAT,           concat);
+    REGISTER_MUXER   (CRC,              crc);
+    REGISTER_MUXDEMUX(DAUD,             daud);
+    REGISTER_DEMUXER (DFA,              dfa);
+    REGISTER_MUXDEMUX(DIRAC,            dirac);
+    REGISTER_MUXDEMUX(DNXHD,            dnxhd);
+    REGISTER_DEMUXER (DSICIN,           dsicin);
+    REGISTER_MUXDEMUX(DTS,              dts);
+    REGISTER_DEMUXER (DTSHD,            dtshd);
+    REGISTER_MUXDEMUX(DV,               dv);
+    REGISTER_DEMUXER (DXA,              dxa);
+    REGISTER_DEMUXER (EA,               ea);
+    REGISTER_DEMUXER (EA_CDATA,         ea_cdata);
+    REGISTER_MUXDEMUX(EAC3,             eac3);
+    REGISTER_DEMUXER (EPAF,             epaf);
+    REGISTER_MUXER   (F4V,              f4v);
+    REGISTER_MUXDEMUX(FFM,              ffm);
+    REGISTER_MUXDEMUX(FFMETADATA,       ffmetadata);
+    REGISTER_MUXDEMUX(FILMSTRIP,        filmstrip);
+    REGISTER_MUXDEMUX(FLAC,             flac);
+    REGISTER_DEMUXER (FLIC,             flic);
+    REGISTER_MUXDEMUX(FLV,              flv);
+    REGISTER_DEMUXER (FOURXM,           fourxm);
+    REGISTER_MUXER   (FRAMECRC,         framecrc);
+    REGISTER_MUXER   (FRAMEMD5,         framemd5);
+    REGISTER_DEMUXER (FRM,              frm);
+    REGISTER_MUXDEMUX(G722,             g722);
+    REGISTER_MUXDEMUX(G723_1,           g723_1);
+    REGISTER_DEMUXER (G729,             g729);
+    REGISTER_MUXDEMUX(GIF,              gif);
+    REGISTER_DEMUXER (GSM,              gsm);
+    REGISTER_MUXDEMUX(GXF,              gxf);
+    REGISTER_MUXDEMUX(H261,             h261);
+    REGISTER_MUXDEMUX(H263,             h263);
+    REGISTER_MUXDEMUX(H264,             h264);
+    REGISTER_MUXDEMUX(HLS,              hls);
+    REGISTER_MUXDEMUX(ICO,              ico);
+    REGISTER_DEMUXER (IDCIN,            idcin);
+    REGISTER_DEMUXER (IDF,              idf);
+    REGISTER_DEMUXER (IFF,              iff);
+    REGISTER_MUXDEMUX(ILBC,             ilbc);
+    REGISTER_MUXDEMUX(IMAGE2,           image2);
+    REGISTER_MUXDEMUX(IMAGE2PIPE,       image2pipe);
+    REGISTER_DEMUXER (INGENIENT,        ingenient);
+    REGISTER_DEMUXER (IPMOVIE,          ipmovie);
+    REGISTER_MUXER   (IPOD,             ipod);
+    REGISTER_MUXDEMUX(IRCAM,            ircam);
+    REGISTER_MUXER   (ISMV,             ismv);
+    REGISTER_DEMUXER (ISS,              iss);
+    REGISTER_DEMUXER (IV8,              iv8);
+    REGISTER_MUXDEMUX(IVF,              ivf);
+    REGISTER_MUXDEMUX(JACOSUB,          jacosub);
+    REGISTER_DEMUXER (JV,               jv);
+    REGISTER_MUXDEMUX(LATM,             latm);
+    REGISTER_DEMUXER (LMLM4,            lmlm4);
+    REGISTER_DEMUXER (LOAS,             loas);
+    REGISTER_DEMUXER (LVF,              lvf);
+    REGISTER_DEMUXER (LXF,              lxf);
+    REGISTER_MUXDEMUX(M4V,              m4v);
+    REGISTER_MUXER   (MD5,              md5);
+    REGISTER_MUXDEMUX(MATROSKA,         matroska);
+    REGISTER_MUXER   (MATROSKA_AUDIO,   matroska_audio);
+    REGISTER_DEMUXER (MGSTS,            mgsts);
+    REGISTER_MUXDEMUX(MICRODVD,         microdvd);
+    REGISTER_MUXDEMUX(MJPEG,            mjpeg);
+    REGISTER_MUXDEMUX(MLP,              mlp);
+    REGISTER_DEMUXER (MM,               mm);
+    REGISTER_MUXDEMUX(MMF,              mmf);
+    REGISTER_MUXDEMUX(MOV,              mov);
+    REGISTER_MUXER   (MP2,              mp2);
+    REGISTER_MUXDEMUX(MP3,              mp3);
+    REGISTER_MUXER   (MP4,              mp4);
+    REGISTER_DEMUXER (MPC,              mpc);
+    REGISTER_DEMUXER (MPC8,             mpc8);
+    REGISTER_MUXER   (MPEG1SYSTEM,      mpeg1system);
+    REGISTER_MUXER   (MPEG1VCD,         mpeg1vcd);
+    REGISTER_MUXER   (MPEG1VIDEO,       mpeg1video);
+    REGISTER_MUXER   (MPEG2DVD,         mpeg2dvd);
+    REGISTER_MUXER   (MPEG2SVCD,        mpeg2svcd);
+    REGISTER_MUXER   (MPEG2VIDEO,       mpeg2video);
+    REGISTER_MUXER   (MPEG2VOB,         mpeg2vob);
+    REGISTER_DEMUXER (MPEGPS,           mpegps);
+    REGISTER_MUXDEMUX(MPEGTS,           mpegts);
+    REGISTER_DEMUXER (MPEGTSRAW,        mpegtsraw);
+    REGISTER_DEMUXER (MPEGVIDEO,        mpegvideo);
+    REGISTER_MUXER   (MPJPEG,           mpjpeg);
+    REGISTER_DEMUXER (MPL2,             mpl2);
+    REGISTER_DEMUXER (MPSUB,            mpsub);
+    REGISTER_DEMUXER (MSNWC_TCP,        msnwc_tcp);
+    REGISTER_DEMUXER (MTV,              mtv);
+    REGISTER_DEMUXER (MV,               mv);
+    REGISTER_DEMUXER (MVI,              mvi);
+    REGISTER_MUXDEMUX(MXF,              mxf);
+    REGISTER_MUXER   (MXF_D10,          mxf_d10);
+    REGISTER_DEMUXER (MXG,              mxg);
+    REGISTER_DEMUXER (NC,               nc);
+    REGISTER_DEMUXER (NISTSPHERE,       nistsphere);
+    REGISTER_DEMUXER (NSV,              nsv);
+    REGISTER_MUXER   (NULL,             null);
+    REGISTER_MUXDEMUX(NUT,              nut);
+    REGISTER_DEMUXER (NUV,              nuv);
+    REGISTER_MUXDEMUX(OGG,              ogg);
+    REGISTER_MUXDEMUX(OMA,              oma);
+    REGISTER_DEMUXER (PAF,              paf);
+    REGISTER_MUXDEMUX(PCM_ALAW,         pcm_alaw);
+    REGISTER_MUXDEMUX(PCM_MULAW,        pcm_mulaw);
+    REGISTER_MUXDEMUX(PCM_F64BE,        pcm_f64be);
+    REGISTER_MUXDEMUX(PCM_F64LE,        pcm_f64le);
+    REGISTER_MUXDEMUX(PCM_F32BE,        pcm_f32be);
+    REGISTER_MUXDEMUX(PCM_F32LE,        pcm_f32le);
+    REGISTER_MUXDEMUX(PCM_S32BE,        pcm_s32be);
+    REGISTER_MUXDEMUX(PCM_S32LE,        pcm_s32le);
+    REGISTER_MUXDEMUX(PCM_S24BE,        pcm_s24be);
+    REGISTER_MUXDEMUX(PCM_S24LE,        pcm_s24le);
+    REGISTER_MUXDEMUX(PCM_S16BE,        pcm_s16be);
+    REGISTER_MUXDEMUX(PCM_S16LE,        pcm_s16le);
+    REGISTER_MUXDEMUX(PCM_S8,           pcm_s8);
+    REGISTER_MUXDEMUX(PCM_U32BE,        pcm_u32be);
+    REGISTER_MUXDEMUX(PCM_U32LE,        pcm_u32le);
+    REGISTER_MUXDEMUX(PCM_U24BE,        pcm_u24be);
+    REGISTER_MUXDEMUX(PCM_U24LE,        pcm_u24le);
+    REGISTER_MUXDEMUX(PCM_U16BE,        pcm_u16be);
+    REGISTER_MUXDEMUX(PCM_U16LE,        pcm_u16le);
+    REGISTER_MUXDEMUX(PCM_U8,           pcm_u8);
+    REGISTER_DEMUXER (PJS,              pjs);
+    REGISTER_DEMUXER (PMP,              pmp);
+    REGISTER_MUXER   (PSP,              psp);
+    REGISTER_DEMUXER (PVA,              pva);
+    REGISTER_DEMUXER (PVF,              pvf);
+    REGISTER_DEMUXER (QCP,              qcp);
+    REGISTER_DEMUXER (R3D,              r3d);
+    REGISTER_MUXDEMUX(RAWVIDEO,         rawvideo);
+    REGISTER_DEMUXER (REALTEXT,         realtext);
+    REGISTER_DEMUXER (RL2,              rl2);
+    REGISTER_MUXDEMUX(RM,               rm);
+    REGISTER_MUXDEMUX(ROQ,              roq);
+    REGISTER_DEMUXER (RPL,              rpl);
+    REGISTER_MUXDEMUX(RSO,              rso);
+    REGISTER_MUXDEMUX(RTP,              rtp);
+    REGISTER_MUXDEMUX(RTSP,             rtsp);
+    REGISTER_DEMUXER (SAMI,             sami);
+    REGISTER_MUXDEMUX(SAP,              sap);
+    REGISTER_DEMUXER (SBG,              sbg);
+    REGISTER_DEMUXER (SDP,              sdp);
 #if CONFIG_RTPDEC
     av_register_rtp_dynamic_payload_handlers();
     av_register_rdt_dynamic_payload_handlers();
 #endif
-    REGISTER_DEMUXER  (SEGAFILM, segafilm);
-    REGISTER_MUXER    (SEGMENT, segment);
-    REGISTER_MUXER    (SEGMENT, stream_segment);
-    REGISTER_DEMUXER  (SHORTEN, shorten);
-    REGISTER_DEMUXER  (SIFF, siff);
-    REGISTER_DEMUXER  (SMACKER, smacker);
-    REGISTER_MUXDEMUX (SMJPEG, smjpeg);
-    REGISTER_MUXER    (SMOOTHSTREAMING, smoothstreaming);
-    REGISTER_DEMUXER  (SMUSH, smush);
-    REGISTER_DEMUXER  (SOL, sol);
-    REGISTER_MUXDEMUX (SOX, sox);
-    REGISTER_MUXDEMUX (SPDIF, spdif);
-    REGISTER_MUXDEMUX (SRT, srt);
-    REGISTER_DEMUXER  (STR, str);
-    REGISTER_DEMUXER  (SUBVIEWER, subviewer);
-    REGISTER_MUXDEMUX (SWF, swf);
-    REGISTER_DEMUXER  (TAK, tak);
-    REGISTER_MUXER    (TG2, tg2);
-    REGISTER_MUXER    (TGP, tgp);
-    REGISTER_DEMUXER  (THP, thp);
-    REGISTER_DEMUXER  (TIERTEXSEQ, tiertexseq);
-    REGISTER_MUXER    (MKVTIMESTAMP_V2, mkvtimestamp_v2);
-    REGISTER_DEMUXER  (TMV, tmv);
-    REGISTER_MUXDEMUX (TRUEHD, truehd);
-    REGISTER_DEMUXER  (TTA, tta);
-    REGISTER_DEMUXER  (TXD, txd);
-    REGISTER_DEMUXER  (TTY, tty);
-    REGISTER_DEMUXER  (VC1, vc1);
-    REGISTER_MUXDEMUX (VC1T, vc1t);
-    REGISTER_DEMUXER  (VIVO, vivo);
-    REGISTER_DEMUXER  (VMD, vmd);
-    REGISTER_MUXDEMUX (VOC, voc);
-    REGISTER_DEMUXER  (VQF, vqf);
-    REGISTER_DEMUXER  (W64, w64);
-    REGISTER_MUXDEMUX (WAV, wav);
-    REGISTER_DEMUXER  (WC3, wc3);
-    REGISTER_MUXER    (WEBM, webm);
-    REGISTER_DEMUXER  (WEBVTT, webvtt);
-    REGISTER_DEMUXER  (WSAUD, wsaud);
-    REGISTER_DEMUXER  (WSVQA, wsvqa);
-    REGISTER_MUXDEMUX (WTV, wtv);
-    REGISTER_MUXDEMUX (WV, wv);
-    REGISTER_DEMUXER  (XA, xa);
-    REGISTER_DEMUXER  (XBIN, xbin);
-    REGISTER_DEMUXER  (XMV, xmv);
-    REGISTER_DEMUXER  (XWMA, xwma);
-    REGISTER_DEMUXER  (YOP, yop);
-    REGISTER_MUXDEMUX (YUV4MPEGPIPE, yuv4mpegpipe);
+    REGISTER_DEMUXER (SEGAFILM,         segafilm);
+    REGISTER_MUXER   (SEGMENT,          segment);
+    REGISTER_MUXER   (SEGMENT,          stream_segment);
+    REGISTER_DEMUXER (SHORTEN,          shorten);
+    REGISTER_DEMUXER (SIFF,             siff);
+    REGISTER_DEMUXER (SMACKER,          smacker);
+    REGISTER_MUXDEMUX(SMJPEG,           smjpeg);
+    REGISTER_MUXER   (SMOOTHSTREAMING,  smoothstreaming);
+    REGISTER_DEMUXER (SMUSH,            smush);
+    REGISTER_DEMUXER (SOL,              sol);
+    REGISTER_MUXDEMUX(SOX,              sox);
+    REGISTER_MUXDEMUX(SPDIF,            spdif);
+    REGISTER_MUXDEMUX(SRT,              srt);
+    REGISTER_DEMUXER (STR,              str);
+    REGISTER_DEMUXER (SUBVIEWER1,       subviewer1);
+    REGISTER_DEMUXER (SUBVIEWER,        subviewer);
+    REGISTER_MUXDEMUX(SWF,              swf);
+    REGISTER_DEMUXER (TAK,              tak);
+    REGISTER_MUXER   (TEE, tee);
+    REGISTER_DEMUXER (TEDCAPTIONS,      tedcaptions);
+    REGISTER_MUXER   (TG2,              tg2);
+    REGISTER_MUXER   (TGP,              tgp);
+    REGISTER_DEMUXER (THP,              thp);
+    REGISTER_DEMUXER (TIERTEXSEQ,       tiertexseq);
+    REGISTER_MUXER   (MKVTIMESTAMP_V2,  mkvtimestamp_v2);
+    REGISTER_DEMUXER (TMV,              tmv);
+    REGISTER_MUXDEMUX(TRUEHD,           truehd);
+    REGISTER_DEMUXER (TTA,              tta);
+    REGISTER_DEMUXER (TXD,              txd);
+    REGISTER_DEMUXER (TTY,              tty);
+    REGISTER_DEMUXER (VC1,              vc1);
+    REGISTER_MUXDEMUX(VC1T,             vc1t);
+    REGISTER_DEMUXER (VIVO,             vivo);
+    REGISTER_DEMUXER (VMD,              vmd);
+    REGISTER_DEMUXER (VOBSUB,           vobsub);
+    REGISTER_MUXDEMUX(VOC,              voc);
+    REGISTER_DEMUXER (VPLAYER,          vplayer);
+    REGISTER_DEMUXER (VQF,              vqf);
+    REGISTER_MUXDEMUX(W64,              w64);
+    REGISTER_MUXDEMUX(WAV,              wav);
+    REGISTER_DEMUXER (WC3,              wc3);
+    REGISTER_MUXER   (WEBM,             webm);
+    REGISTER_DEMUXER (WEBVTT,           webvtt);
+    REGISTER_DEMUXER (WSAUD,            wsaud);
+    REGISTER_DEMUXER (WSVQA,            wsvqa);
+    REGISTER_MUXDEMUX(WTV,              wtv);
+    REGISTER_MUXDEMUX(WV,               wv);
+    REGISTER_DEMUXER (XA,               xa);
+    REGISTER_DEMUXER (XBIN,             xbin);
+    REGISTER_DEMUXER (XMV,              xmv);
+    REGISTER_DEMUXER (XWMA,             xwma);
+    REGISTER_DEMUXER (YOP,              yop);
+    REGISTER_MUXDEMUX(YUV4MPEGPIPE,     yuv4mpegpipe);
 
     /* protocols */
 #if FF_API_APPLEHTTP_PROTO
-    REGISTER_PROTOCOL (APPLEHTTP, applehttp);
+    REGISTER_PROTOCOL(APPLEHTTP,        applehttp);
 #endif
-    REGISTER_PROTOCOL (BLURAY, bluray);
-    REGISTER_PROTOCOL (CACHE, cache);
-    REGISTER_PROTOCOL (CONCAT, concat);
-    REGISTER_PROTOCOL (CRYPTO, crypto);
-    REGISTER_PROTOCOL (FFRTMPCRYPT, ffrtmpcrypt);
-    REGISTER_PROTOCOL (FFRTMPHTTP, ffrtmphttp);
-    REGISTER_PROTOCOL (FILE, file);
-    REGISTER_PROTOCOL (GOPHER, gopher);
-    REGISTER_PROTOCOL (HLS, hls);
-    REGISTER_PROTOCOL (HTTP, http);
-    REGISTER_PROTOCOL (HTTPPROXY, httpproxy);
-    REGISTER_PROTOCOL (HTTPS, https);
-    REGISTER_PROTOCOL (MMSH, mmsh);
-    REGISTER_PROTOCOL (MMST, mmst);
-    REGISTER_PROTOCOL (MD5,  md5);
-    REGISTER_PROTOCOL (PIPE, pipe);
-    REGISTER_PROTOCOL (RTMP, rtmp);
-    REGISTER_PROTOCOL (RTMPE, rtmpe);
-    REGISTER_PROTOCOL (RTMPS, rtmps);
-    REGISTER_PROTOCOL (RTMPT, rtmpt);
-    REGISTER_PROTOCOL (RTMPTE, rtmpte);
-    REGISTER_PROTOCOL (RTMPTS, rtmpts);
-    REGISTER_PROTOCOL (RTP, rtp);
-    REGISTER_PROTOCOL (SCTP, sctp);
-    REGISTER_PROTOCOL (TCP, tcp);
-    REGISTER_PROTOCOL (TLS, tls);
-    REGISTER_PROTOCOL (UDP, udp);
+    REGISTER_PROTOCOL(BLURAY,           bluray);
+    REGISTER_PROTOCOL(CACHE,            cache);
+    REGISTER_PROTOCOL(CONCAT,           concat);
+    REGISTER_PROTOCOL(CRYPTO,           crypto);
+    REGISTER_PROTOCOL(DATA,             data);
+    REGISTER_PROTOCOL(FFRTMPCRYPT,      ffrtmpcrypt);
+    REGISTER_PROTOCOL(FFRTMPHTTP,       ffrtmphttp);
+    REGISTER_PROTOCOL(FILE,             file);
+    REGISTER_PROTOCOL(GOPHER,           gopher);
+    REGISTER_PROTOCOL(HLS,              hls);
+    REGISTER_PROTOCOL(HTTP,             http);
+    REGISTER_PROTOCOL(HTTPPROXY,        httpproxy);
+    REGISTER_PROTOCOL(HTTPS,            https);
+    REGISTER_PROTOCOL(MMSH,             mmsh);
+    REGISTER_PROTOCOL(MMST,             mmst);
+    REGISTER_PROTOCOL(MD5,              md5);
+    REGISTER_PROTOCOL(PIPE,             pipe);
+    REGISTER_PROTOCOL(RTMP,             rtmp);
+    REGISTER_PROTOCOL(RTMPE,            rtmpe);
+    REGISTER_PROTOCOL(RTMPS,            rtmps);
+    REGISTER_PROTOCOL(RTMPT,            rtmpt);
+    REGISTER_PROTOCOL(RTMPTE,           rtmpte);
+    REGISTER_PROTOCOL(RTMPTS,           rtmpts);
+    REGISTER_PROTOCOL(RTP,              rtp);
+    REGISTER_PROTOCOL(SCTP,             sctp);
+    REGISTER_PROTOCOL(SRTP,             srtp);
+    REGISTER_PROTOCOL(TCP,              tcp);
+    REGISTER_PROTOCOL(TLS,              tls);
+    REGISTER_PROTOCOL(UDP,              udp);
 
     /* external libraries */
-    REGISTER_DEMUXER  (LIBMODPLUG, libmodplug);
-    REGISTER_MUXDEMUX (LIBNUT, libnut);
-    REGISTER_PROTOCOL (LIBRTMP, librtmp);
-    REGISTER_PROTOCOL (LIBRTMPE, librtmpe);
-    REGISTER_PROTOCOL (LIBRTMPS, librtmps);
-    REGISTER_PROTOCOL (LIBRTMPT, librtmpt);
-    REGISTER_PROTOCOL (LIBRTMPTE, librtmpte);
+    REGISTER_DEMUXER (LIBMODPLUG,       libmodplug);
+    REGISTER_MUXDEMUX(LIBNUT,           libnut);
+    REGISTER_PROTOCOL(LIBRTMP,          librtmp);
+    REGISTER_PROTOCOL(LIBRTMPE,         librtmpe);
+    REGISTER_PROTOCOL(LIBRTMPS,         librtmps);
+    REGISTER_PROTOCOL(LIBRTMPT,         librtmpt);
+    REGISTER_PROTOCOL(LIBRTMPTE,        librtmpte);
 }
diff --git a/libavformat/anm.c b/libavformat/anm.c
index 69a5dda..f93c57e 100644
--- a/libavformat/anm.c
+++ b/libavformat/anm.c
@@ -86,7 +86,7 @@
     avio_skip(pb, 4); /* magic number */
     if (avio_rl16(pb) != MAX_PAGES) {
         av_log_ask_for_sample(s, "max_pages != " AV_STRINGIFY(MAX_PAGES) "\n");
-        return AVERROR_INVALIDDATA;
+        return AVERROR_PATCHWELCOME;
     }
 
     anm->nb_pages   = avio_rl16(pb);
@@ -163,7 +163,7 @@
 
 invalid:
     av_log_ask_for_sample(s, NULL);
-    return AVERROR_INVALIDDATA;
+    return AVERROR_PATCHWELCOME;
 }
 
 static int read_packet(AVFormatContext *s,
diff --git a/libavformat/ape.c b/libavformat/ape.c
index c4a390b..551513d 100644
--- a/libavformat/ape.c
+++ b/libavformat/ape.c
@@ -165,14 +165,14 @@
 
     tag = avio_rl32(pb);
     if (tag != MKTAG('M', 'A', 'C', ' '))
-        return -1;
+        return AVERROR_INVALIDDATA;
 
     ape->fileversion = avio_rl16(pb);
 
     if (ape->fileversion < APE_MIN_VERSION || ape->fileversion > APE_MAX_VERSION) {
         av_log(s, AV_LOG_ERROR, "Unsupported file version - %d.%02d\n",
                ape->fileversion / 1000, (ape->fileversion % 1000) / 10);
-        return -1;
+        return AVERROR_PATCHWELCOME;
     }
 
     if (ape->fileversion >= 3980) {
@@ -251,7 +251,7 @@
     if(ape->totalframes > UINT_MAX / sizeof(APEFrame)){
         av_log(s, AV_LOG_ERROR, "Too many frames: %"PRIu32"\n",
                ape->totalframes);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     if (ape->seektablelength && (ape->seektablelength / sizeof(*ape->seektable)) < ape->totalframes) {
         av_log(s, AV_LOG_ERROR,
@@ -278,7 +278,7 @@
             ape->seektable[i] = avio_rl32(pb);
     }else{
         av_log(s, AV_LOG_ERROR, "Missing seektable\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     ape->frames[0].pos     = ape->firstframe;
@@ -320,7 +320,7 @@
     /* now we are ready: build format streams */
     st = avformat_new_stream(s, NULL);
     if (!st)
-        return -1;
+        return AVERROR(ENOMEM);
 
     total_blocks = (ape->totalframes == 0) ? 0 : ((ape->totalframes - 1) * ape->blocksperframe) + ape->finalframeblocks;
 
diff --git a/libavformat/aqtitledec.c b/libavformat/aqtitledec.c
new file mode 100644
index 0000000..325946c
--- /dev/null
+++ b/libavformat/aqtitledec.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2012 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
+ * AQTitle subtitles format demuxer
+ *
+ * @see http://web.archive.org/web/20070210095721/http://www.volny.cz/aberka/czech/aqt.html
+ * @see https://trac.annodex.net/wiki/AQTitle
+ */
+
+#include "avformat.h"
+#include "internal.h"
+#include "subtitles.h"
+#include "libavutil/opt.h"
+
+typedef struct {
+    const AVClass *class;
+    FFDemuxSubtitlesQueue q;
+    AVRational frame_rate;
+} AQTitleContext;
+
+static int aqt_probe(AVProbeData *p)
+{
+    int frame;
+    const char *ptr = p->buf;
+
+    if (sscanf(ptr, "-->> %d", &frame) == 1)
+        return AVPROBE_SCORE_MAX / 2;
+    return 0;
+}
+
+static int aqt_read_header(AVFormatContext *s)
+{
+    AQTitleContext *aqt = s->priv_data;
+    AVStream *st = avformat_new_stream(s, NULL);
+    int new_event = 1;
+    int64_t pos = 0, frame = AV_NOPTS_VALUE;
+    AVPacket *sub = NULL;
+
+    if (!st)
+        return AVERROR(ENOMEM);
+    avpriv_set_pts_info(st, 64, aqt->frame_rate.den, aqt->frame_rate.num);
+    st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
+    st->codec->codec_id   = AV_CODEC_ID_TEXT;
+
+    while (!url_feof(s->pb)) {
+        char line[4096];
+        int len = ff_get_line(s->pb, line, sizeof(line));
+
+        if (!len)
+            break;
+
+        line[strcspn(line, "\r\n")] = 0;
+
+        if (sscanf(line, "-->> %"PRId64, &frame) == 1) {
+            new_event = 1;
+            pos = avio_tell(s->pb);
+            if (sub) {
+                sub->duration = frame - sub->pts;
+                sub = NULL;
+            }
+        } else if (*line) {
+            if (!new_event) {
+                sub = ff_subtitles_queue_insert(&aqt->q, "\n", 1, 1);
+                if (!sub)
+                    return AVERROR(ENOMEM);
+            }
+            sub = ff_subtitles_queue_insert(&aqt->q, line, strlen(line), !new_event);
+            if (!sub)
+                return AVERROR(ENOMEM);
+            if (new_event) {
+                sub->pts = frame;
+                sub->duration = -1;
+                sub->pos = pos;
+            }
+            new_event = 0;
+        }
+    }
+
+    ff_subtitles_queue_finalize(&aqt->q);
+    return 0;
+}
+
+static int aqt_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    AQTitleContext *aqt = s->priv_data;
+    return ff_subtitles_queue_read_packet(&aqt->q, pkt);
+}
+
+static int aqt_read_seek(AVFormatContext *s, int stream_index,
+                         int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
+{
+    AQTitleContext *aqt = s->priv_data;
+    return ff_subtitles_queue_seek(&aqt->q, s, stream_index,
+                                   min_ts, ts, max_ts, flags);
+}
+
+static int aqt_read_close(AVFormatContext *s)
+{
+    AQTitleContext *aqt = s->priv_data;
+    ff_subtitles_queue_clean(&aqt->q);
+    return 0;
+}
+
+#define OFFSET(x) offsetof(AQTitleContext, x)
+#define SD AV_OPT_FLAG_SUBTITLE_PARAM|AV_OPT_FLAG_DECODING_PARAM
+static const AVOption aqt_options[] = {
+    { "subfps", "set the movie frame rate", OFFSET(frame_rate), AV_OPT_TYPE_RATIONAL, {.dbl=25}, 0, INT_MAX, SD },
+    { NULL }
+};
+
+static const AVClass aqt_class = {
+    .class_name = "aqtdec",
+    .item_name  = av_default_item_name,
+    .option     = aqt_options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+AVInputFormat ff_aqtitle_demuxer = {
+    .name           = "aqtitle",
+    .long_name      = NULL_IF_CONFIG_SMALL("AQTitle subtitles"),
+    .priv_data_size = sizeof(AQTitleContext),
+    .read_probe     = aqt_probe,
+    .read_header    = aqt_read_header,
+    .read_packet    = aqt_read_packet,
+    .read_seek2     = aqt_read_seek,
+    .read_close     = aqt_read_close,
+    .extensions     = "aqt",
+    .priv_class     = &aqt_class,
+};
diff --git a/libavformat/asf.c b/libavformat/asf.c
index 8e360d3..dd64a3f 100644
--- a/libavformat/asf.c
+++ b/libavformat/asf.c
@@ -20,7 +20,6 @@
 
 #include "asf.h"
 
-
 const ff_asf_guid ff_asf_header = {
     0x30, 0x26, 0xB2, 0x75, 0x8E, 0x66, 0xCF, 0x11, 0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C
 };
@@ -48,7 +47,7 @@
 };
 
 const ff_asf_guid ff_asf_audio_conceal_spread = {
-     0x50, 0xCD, 0xC3, 0xBF, 0x8F, 0x61, 0xCF, 0x11, 0x8B, 0xB2, 0x00, 0xAA, 0x00, 0xB4, 0xE2, 0x20
+    0x50, 0xCD, 0xC3, 0xBF, 0x8F, 0x61, 0xCF, 0x11, 0x8B, 0xB2, 0x00, 0xAA, 0x00, 0xB4, 0xE2, 0x20
 };
 
 const ff_asf_guid ff_asf_video_stream = {
@@ -91,31 +90,35 @@
 };
 
 const ff_asf_guid ff_asf_extended_content_header = {
-        0x40, 0xA4, 0xD0, 0xD2, 0x07, 0xE3, 0xD2, 0x11, 0x97, 0xF0, 0x00, 0xA0, 0xC9, 0x5E, 0xA8, 0x50
+    0x40, 0xA4, 0xD0, 0xD2, 0x07, 0xE3, 0xD2, 0x11, 0x97, 0xF0, 0x00, 0xA0, 0xC9, 0x5E, 0xA8, 0x50
 };
 
 const ff_asf_guid ff_asf_simple_index_header = {
-        0x90, 0x08, 0x00, 0x33, 0xB1, 0xE5, 0xCF, 0x11, 0x89, 0xF4, 0x00, 0xA0, 0xC9, 0x03, 0x49, 0xCB
+    0x90, 0x08, 0x00, 0x33, 0xB1, 0xE5, 0xCF, 0x11, 0x89, 0xF4, 0x00, 0xA0, 0xC9, 0x03, 0x49, 0xCB
 };
 
 const ff_asf_guid ff_asf_ext_stream_embed_stream_header = {
-        0xe2, 0x65, 0xfb, 0x3a, 0xEF, 0x47, 0xF2, 0x40, 0xac, 0x2c, 0x70, 0xa9, 0x0d, 0x71, 0xd3, 0x43
+    0xe2, 0x65, 0xfb, 0x3a, 0xEF, 0x47, 0xF2, 0x40, 0xac, 0x2c, 0x70, 0xa9, 0x0d, 0x71, 0xd3, 0x43
 };
 
 const ff_asf_guid ff_asf_ext_stream_audio_stream = {
-        0x9d, 0x8c, 0x17, 0x31, 0xE1, 0x03, 0x28, 0x45, 0xb5, 0x82, 0x3d, 0xf9, 0xdb, 0x22, 0xf5, 0x03
+    0x9d, 0x8c, 0x17, 0x31, 0xE1, 0x03, 0x28, 0x45, 0xb5, 0x82, 0x3d, 0xf9, 0xdb, 0x22, 0xf5, 0x03
 };
 
 const ff_asf_guid ff_asf_metadata_header = {
-        0xea, 0xcb, 0xf8, 0xc5, 0xaf, 0x5b, 0x77, 0x48, 0x84, 0x67, 0xaa, 0x8c, 0x44, 0xfa, 0x4c, 0xca
+    0xea, 0xcb, 0xf8, 0xc5, 0xaf, 0x5b, 0x77, 0x48, 0x84, 0x67, 0xaa, 0x8c, 0x44, 0xfa, 0x4c, 0xca
+};
+
+const ff_asf_guid ff_asf_metadata_library_header = {
+    0x94, 0x1c, 0x23, 0x44, 0x98, 0x94, 0xd1, 0x49, 0xa1, 0x41, 0x1d, 0x13, 0x4e, 0x45, 0x70, 0x54
 };
 
 const ff_asf_guid ff_asf_marker_header = {
-        0x01, 0xCD, 0x87, 0xF4, 0x51, 0xA9, 0xCF, 0x11, 0x8E, 0xE6, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65
+    0x01, 0xCD, 0x87, 0xF4, 0x51, 0xA9, 0xCF, 0x11, 0x8E, 0xE6, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65
 };
 
 /* I am not a number !!! This GUID is the one found on the PC used to
-   generate the stream */
+ * generate the stream */
 const ff_asf_guid ff_asf_my_guid = {
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
 };
@@ -138,22 +141,22 @@
 
 /* List of official tags at http://msdn.microsoft.com/en-us/library/dd743066(VS.85).aspx */
 const AVMetadataConv ff_asf_metadata_conv[] = {
-    { "WM/AlbumArtist"     , "album_artist"},
-    { "WM/AlbumTitle"      , "album"       },
-    { "Author"             , "artist"      },
-    { "Description"        , "comment"     },
-    { "WM/Composer"        , "composer"    },
-    { "WM/EncodedBy"       , "encoded_by"  },
-    { "WM/EncodingSettings", "encoder"     },
-    { "WM/Genre"           , "genre"       },
-    { "WM/Language"        , "language"    },
-    { "WM/OriginalFilename", "filename"    },
-    { "WM/PartOfSet"       , "disc"        },
-    { "WM/Publisher"       , "publisher"   },
-    { "WM/Tool"            , "encoder"     },
-    { "WM/TrackNumber"     , "track"       },
+    { "WM/AlbumArtist",          "album_artist"     },
+    { "WM/AlbumTitle",           "album"            },
+    { "Author",                  "artist"           },
+    { "Description",             "comment"          },
+    { "WM/Composer",             "composer"         },
+    { "WM/EncodedBy",            "encoded_by"       },
+    { "WM/EncodingSettings",     "encoder"          },
+    { "WM/Genre",                "genre"            },
+    { "WM/Language",             "language"         },
+    { "WM/OriginalFilename",     "filename"         },
+    { "WM/PartOfSet",            "disc"             },
+    { "WM/Publisher",            "publisher"        },
+    { "WM/Tool",                 "encoder"          },
+    { "WM/TrackNumber",          "track"            },
     { "WM/MediaStationCallSign", "service_provider" },
-    { "WM/MediaStationName", "service_name" },
+    { "WM/MediaStationName",     "service_name"     },
 //  { "Year"               , "date"        }, TODO: conversion year<->date
     { 0 }
 };
diff --git a/libavformat/asf.h b/libavformat/asf.h
index 528d4c1..5ffc746 100644
--- a/libavformat/asf.h
+++ b/libavformat/asf.h
@@ -110,6 +110,7 @@
 extern const ff_asf_guid ff_asf_ext_stream_embed_stream_header;
 extern const ff_asf_guid ff_asf_ext_stream_audio_stream;
 extern const ff_asf_guid ff_asf_metadata_header;
+extern const ff_asf_guid ff_asf_metadata_library_header;
 extern const ff_asf_guid ff_asf_marker_header;
 extern const ff_asf_guid ff_asf_my_guid;
 extern const ff_asf_guid ff_asf_language_guid;
diff --git a/libavformat/asfcrypt.c b/libavformat/asfcrypt.c
index 6a51c04..a402758 100644
--- a/libavformat/asfcrypt.c
+++ b/libavformat/asfcrypt.c
@@ -20,10 +20,10 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavutil/common.h"
-#include "libavutil/intreadwrite.h"
 #include "libavutil/bswap.h"
+#include "libavutil/common.h"
 #include "libavutil/des.h"
+#include "libavutil/intreadwrite.h"
 #include "libavutil/rc4.h"
 #include "asfcrypt.h"
 
@@ -32,7 +32,8 @@
  * @param v number to invert, must be odd!
  * @return number so that result * v = 1 (mod 2^32)
  */
-static uint32_t inverse(uint32_t v) {
+static uint32_t inverse(uint32_t v)
+{
     // v ^ 3 gives the inverse (mod 16), could also be implemented
     // as table etc. (only lowest 4 bits matter!)
     uint32_t inverse = v * v * v;
@@ -50,7 +51,8 @@
  * @param keys output key array containing the keys for encryption in
  *             native endianness
  */
-static void multiswap_init(const uint8_t keybuf[48], uint32_t keys[12]) {
+static void multiswap_init(const uint8_t keybuf[48], uint32_t keys[12])
+{
     int i;
     for (i = 0; i < 12; i++)
         keys[i] = AV_RL32(keybuf + (i << 2)) | 1;
@@ -61,7 +63,8 @@
  *        the other way round.
  * @param keys key array of ints to invert
  */
-static void multiswap_invert_keys(uint32_t keys[12]) {
+static void multiswap_invert_keys(uint32_t keys[12])
+{
     int i;
     for (i = 0; i < 5; i++)
         keys[i] = inverse(keys[i]);
@@ -69,23 +72,25 @@
         keys[i] = inverse(keys[i]);
 }
 
-static uint32_t multiswap_step(const uint32_t keys[12], uint32_t v) {
+static uint32_t multiswap_step(const uint32_t keys[12], uint32_t v)
+{
     int i;
     v *= keys[0];
     for (i = 1; i < 5; i++) {
-        v = (v >> 16) | (v << 16);
+        v  = (v >> 16) | (v << 16);
         v *= keys[i];
     }
     v += keys[5];
     return v;
 }
 
-static uint32_t multiswap_inv_step(const uint32_t keys[12], uint32_t v) {
+static uint32_t multiswap_inv_step(const uint32_t keys[12], uint32_t v)
+{
     int i;
     v -= keys[5];
     for (i = 4; i > 0; i--) {
         v *= keys[i];
-        v = (v >> 16) | (v << 16);
+        v  = (v >> 16) | (v << 16);
     }
     v *= keys[0];
     return v;
@@ -99,17 +104,19 @@
  * @param data data to encrypt
  * @return encrypted data
  */
-static uint64_t multiswap_enc(const uint32_t keys[12], uint64_t key, uint64_t data) {
+static uint64_t multiswap_enc(const uint32_t keys[12],
+                              uint64_t key, uint64_t data)
+{
     uint32_t a = data;
     uint32_t b = data >> 32;
     uint32_t c;
     uint32_t tmp;
-    a += key;
-    tmp = multiswap_step(keys    , a);
-    b += tmp;
-    c = (key >> 32) + tmp;
+    a  += key;
+    tmp = multiswap_step(keys, a);
+    b  += tmp;
+    c   = (key >> 32) + tmp;
     tmp = multiswap_step(keys + 6, b);
-    c += tmp;
+    c  += tmp;
     return ((uint64_t)c << 32) | tmp;
 }
 
@@ -121,25 +128,28 @@
  * @param data data to decrypt
  * @return decrypted data
  */
-static uint64_t multiswap_dec(const uint32_t keys[12], uint64_t key, uint64_t data) {
+static uint64_t multiswap_dec(const uint32_t keys[12],
+                              uint64_t key, uint64_t data)
+{
     uint32_t a;
     uint32_t b;
-    uint32_t c = data >> 32;
+    uint32_t c   = data >> 32;
     uint32_t tmp = data;
-    c -= tmp;
-    b = multiswap_inv_step(keys + 6, tmp);
+    c  -= tmp;
+    b   = multiswap_inv_step(keys + 6, tmp);
     tmp = c - (key >> 32);
-    b -= tmp;
-    a = multiswap_inv_step(keys    , tmp);
-    a -= key;
+    b  -= tmp;
+    a   = multiswap_inv_step(keys, tmp);
+    a  -= key;
     return ((uint64_t)b << 32) | a;
 }
 
-void ff_asfcrypt_dec(const uint8_t key[20], uint8_t *data, int len) {
+void ff_asfcrypt_dec(const uint8_t key[20], uint8_t *data, int len)
+{
     struct AVDES des;
     struct AVRC4 rc4;
-    int num_qwords = len >> 3;
-    uint8_t *qwords = data;
+    int num_qwords      = len >> 3;
+    uint8_t *qwords     = data;
     uint64_t rc4buff[8] = { 0 };
     uint64_t packetkey;
     uint32_t ms_keys[12];
@@ -155,7 +165,7 @@
     av_rc4_crypt(&rc4, (uint8_t *)rc4buff, NULL, sizeof(rc4buff), NULL, 1);
     multiswap_init((uint8_t *)rc4buff, ms_keys);
 
-    packetkey = AV_RN64(&qwords[num_qwords*8 - 8]);
+    packetkey  = AV_RN64(&qwords[num_qwords * 8 - 8]);
     packetkey ^= rc4buff[7];
     av_des_init(&des, key + 12, 64, 1);
     av_des_crypt(&des, (uint8_t *)&packetkey, (uint8_t *)&packetkey, 1, NULL, 1);
diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c
index 2dcdf56..233b6ca 100644
--- a/libavformat/asfdec.c
+++ b/libavformat/asfdec.c
@@ -22,20 +22,21 @@
 //#define DEBUG
 
 #include "libavutil/attributes.h"
+#include "libavutil/avassert.h"
+#include "libavutil/avstring.h"
 #include "libavutil/bswap.h"
 #include "libavutil/common.h"
-#include "libavutil/avstring.h"
 #include "libavutil/dict.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/opt.h"
 #include "avformat.h"
-#include "internal.h"
 #include "avio_internal.h"
+#include "avlanguage.h"
 #include "id3v2.h"
+#include "internal.h"
 #include "riff.h"
 #include "asf.h"
 #include "asfcrypt.h"
-#include "avlanguage.h"
 
 typedef struct {
     const AVClass *class;
@@ -75,13 +76,13 @@
 
     int stream_index;
 
-    ASFStream* asf_st;                   ///< currently decoded stream
+    ASFStream *asf_st;                   ///< currently decoded stream
 
     int no_resync_search;
 } ASFContext;
 
 static const AVOption options[] = {
-    {"no_resync_search", "Don't try to resynchronize by looking for a certain optional start code", offsetof(ASFContext, no_resync_search), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, AV_OPT_FLAG_DECODING_PARAM },
+    { "no_resync_search", "Don't try to resynchronize by looking for a certain optional start code", offsetof(ASFContext, no_resync_search), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, AV_OPT_FLAG_DECODING_PARAM },
     { NULL },
 };
 
@@ -104,11 +105,11 @@
     0xce, 0x75, 0xf8, 0x7b, 0x8d, 0x46, 0xd1, 0x11, 0x8d, 0x82, 0x00, 0x60, 0x97, 0xc9, 0xa2, 0xb2
 };
 
-#define PRINT_IF_GUID(g,cmp) \
-if (!ff_guidcmp(g, &cmp)) \
-    av_dlog(NULL, "(GUID: %s) ", #cmp)
+#define PRINT_IF_GUID(g, cmp) \
+    if (!ff_guidcmp(g, &cmp)) \
+        av_dlog(NULL, "(GUID: %s) ", # cmp)
 
-static void print_guid(const ff_asf_guid *g)
+static void print_guid(ff_asf_guid *g)
 {
     int i;
     PRINT_IF_GUID(g, ff_asf_header);
@@ -132,12 +133,13 @@
     else PRINT_IF_GUID(g, ff_asf_ext_stream_embed_stream_header);
     else PRINT_IF_GUID(g, ff_asf_ext_stream_audio_stream);
     else PRINT_IF_GUID(g, ff_asf_metadata_header);
+    else PRINT_IF_GUID(g, ff_asf_metadata_library_header);
     else PRINT_IF_GUID(g, ff_asf_marker_header);
     else PRINT_IF_GUID(g, stream_bitrate_guid);
     else PRINT_IF_GUID(g, ff_asf_language_guid);
     else
         av_dlog(NULL, "(GUID: unknown) ");
-    for(i=0;i<16;i++)
+    for (i = 0; i < 16; i++)
         av_dlog(NULL, " 0x%02x,", (*g)[i]);
     av_dlog(NULL, "}\n");
 }
@@ -155,13 +157,21 @@
         return 0;
 }
 
-static int get_value(AVIOContext *pb, int type){
-    switch(type){
-        case 2: return avio_rl32(pb);
-        case 3: return avio_rl32(pb);
-        case 4: return avio_rl64(pb);
-        case 5: return avio_rl16(pb);
-        default:return INT_MIN;
+/* size of type 2 (BOOL) is 32bit for "Extended Content Description Object"
+ * but 16 bit for "Metadata Object" and "Metadata Library Object" */
+static int get_value(AVIOContext *pb, int type, int type2_size)
+{
+    switch (type) {
+    case 2:
+        return (type2_size == 32) ? avio_rl32(pb) : avio_rl16(pb);
+    case 3:
+        return avio_rl32(pb);
+    case 4:
+        return avio_rl64(pb);
+    case 5:
+        return avio_rl16(pb);
+    default:
+        return INT_MIN;
     }
 }
 
@@ -169,12 +179,11 @@
  * but in reality this is only loosely similar */
 static int asf_read_picture(AVFormatContext *s, int len)
 {
-    AVPacket pkt = { 0 };
+    AVPacket pkt          = { 0 };
     const CodecMime *mime = ff_id3v2_mime_tags;
-    enum  AVCodecID      id = AV_CODEC_ID_NONE;
+    enum  AVCodecID id    = AV_CODEC_ID_NONE;
     char mimetype[64];
     uint8_t  *desc = NULL;
-    ASFStream *ast = NULL;
     AVStream   *st = NULL;
     int ret, type, picsize, desc_len;
 
@@ -194,7 +203,7 @@
 
     /* picture data size */
     picsize = avio_rl32(s->pb);
-    len -= 4;
+    len    -= 4;
 
     /* picture MIME type */
     len -= avio_get_str16le(s->pb, len, mimetype, sizeof(mimetype));
@@ -228,21 +237,17 @@
     if (ret < 0)
         goto fail;
 
-    st = avformat_new_stream(s, NULL);
-    ast = av_mallocz(sizeof(*ast));
-    if (!st || !ast) {
+    st  = avformat_new_stream(s, NULL);
+    if (!st) {
         ret = AVERROR(ENOMEM);
         goto fail;
     }
-    st->priv_data = ast;
-
-    st->disposition      |= AV_DISPOSITION_ATTACHED_PIC;
-    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
-    st->codec->codec_id   = id;
-
-    st->attached_pic      = pkt;
+    st->disposition              |= AV_DISPOSITION_ATTACHED_PIC;
+    st->codec->codec_type         = AVMEDIA_TYPE_VIDEO;
+    st->codec->codec_id           = id;
+    st->attached_pic              = pkt;
     st->attached_pic.stream_index = st->index;
-    st->attached_pic.flags |= AV_PKT_FLAG_KEY;
+    st->attached_pic.flags       |= AV_PKT_FLAG_KEY;
 
     if (*desc)
         av_dict_set(&st->metadata, "title", desc, AV_DICT_DONT_STRDUP_VAL);
@@ -254,41 +259,61 @@
     return 0;
 
 fail:
-    av_freep(&ast);
     av_freep(&desc);
     av_free_packet(&pkt);
     return ret;
 }
 
-static void get_tag(AVFormatContext *s, const char *key, int type, int len)
+static void get_id3_tag(AVFormatContext *s, int len)
+{
+    ID3v2ExtraMeta *id3v2_extra_meta = NULL;
+
+    ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta);
+    if (id3v2_extra_meta)
+        ff_id3v2_parse_apic(s, &id3v2_extra_meta);
+    ff_id3v2_free_extra_meta(&id3v2_extra_meta);
+}
+
+static void get_tag(AVFormatContext *s, const char *key, int type, int len, int type2_size)
 {
     char *value;
     int64_t off = avio_tell(s->pb);
 
-    if ((unsigned)len >= (UINT_MAX - 1)/2)
+    if ((unsigned)len >= (UINT_MAX - 1) / 2)
         return;
 
-    value = av_malloc(2*len+1);
+    value = av_malloc(2 * len + 1);
     if (!value)
         goto finish;
 
     if (type == 0) {         // UTF16-LE
-        avio_get_str16le(s->pb, len, value, 2*len + 1);
+        avio_get_str16le(s->pb, len, value, 2 * len + 1);
     } else if (type == -1) { // ASCII
         avio_read(s->pb, value, len);
         value[len]=0;
+    } else if (type == 1) {  // byte array
+        if (!strcmp(key, "WM/Picture")) { // handle cover art
+            asf_read_picture(s, len);
+        } else if (!strcmp(key, "ID3")) { // handle ID3 tag
+            get_id3_tag(s, len);
+        } else {
+            av_log(s, AV_LOG_VERBOSE, "Unsupported byte array in tag %s.\n", key);
+        }
+        goto finish;
     } else if (type > 1 && type <= 5) {  // boolean or DWORD or QWORD or WORD
-        uint64_t num = get_value(s->pb, type);
+        uint64_t num = get_value(s->pb, type, type2_size);
         snprintf(value, len, "%"PRIu64, num);
-    } else if (type == 1 && !strcmp(key, "WM/Picture")) { // handle cover art
-        asf_read_picture(s, len);
+    } else if (type == 6) { // (don't) handle GUID
+        av_log(s, AV_LOG_DEBUG, "Unsupported GUID value in tag %s.\n", key);
         goto finish;
     } else {
-        av_log(s, AV_LOG_DEBUG, "Unsupported value type %d in tag %s.\n", type, key);
+        av_log(s, AV_LOG_DEBUG,
+               "Unsupported value type %d in tag %s.\n", type, key);
         goto finish;
     }
     if (*value)
         av_dict_set(&s->metadata, key, value, 0);
+
 finish:
     av_freep(&value);
     avio_seek(s->pb, off + len, SEEK_SET);
@@ -300,20 +325,20 @@
     AVIOContext *pb = s->pb;
 
     ff_get_guid(pb, &asf->hdr.guid);
-    asf->hdr.file_size          = avio_rl64(pb);
-    asf->hdr.create_time        = avio_rl64(pb);
+    asf->hdr.file_size   = avio_rl64(pb);
+    asf->hdr.create_time = avio_rl64(pb);
     avio_rl64(pb);                               /* number of packets */
-    asf->hdr.play_time          = avio_rl64(pb);
-    asf->hdr.send_time          = avio_rl64(pb);
-    asf->hdr.preroll            = avio_rl32(pb);
-    asf->hdr.ignore             = avio_rl32(pb);
-    asf->hdr.flags              = avio_rl32(pb);
-    asf->hdr.min_pktsize        = avio_rl32(pb);
-    asf->hdr.max_pktsize        = avio_rl32(pb);
-    if (asf->hdr.min_pktsize >= (1U<<29))
+    asf->hdr.play_time   = avio_rl64(pb);
+    asf->hdr.send_time   = avio_rl64(pb);
+    asf->hdr.preroll     = avio_rl32(pb);
+    asf->hdr.ignore      = avio_rl32(pb);
+    asf->hdr.flags       = avio_rl32(pb);
+    asf->hdr.min_pktsize = avio_rl32(pb);
+    asf->hdr.max_pktsize = avio_rl32(pb);
+    if (asf->hdr.min_pktsize >= (1U << 29))
         return AVERROR_INVALIDDATA;
-    asf->hdr.max_bitrate        = avio_rl32(pb);
-    s->packet_size = asf->hdr.max_pktsize;
+    asf->hdr.max_bitrate = avio_rl32(pb);
+    s->packet_size       = asf->hdr.max_pktsize;
 
     return 0;
 }
@@ -329,7 +354,7 @@
     int type_specific_size, sizeX;
     unsigned int tag1;
     int64_t pos1, pos2, start_time;
-    int test_for_ext_stream_audio, is_dvr_ms_audio=0;
+    int test_for_ext_stream_audio, is_dvr_ms_audio = 0;
 
     if (s->nb_streams == ASF_MAX_STREAMS) {
         av_log(s, AV_LOG_ERROR, "too many streams\n");
@@ -345,16 +370,16 @@
     asf_st = av_mallocz(sizeof(ASFStream));
     if (!asf_st)
         return AVERROR(ENOMEM);
-    st->priv_data = asf_st;
-    start_time = asf->hdr.preroll;
+    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...
+    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)
             st->duration = asf->hdr.play_time /
-                (10000000 / 1000) - start_time;
+                       (10000000 / 1000) - start_time;
     }
     ff_get_guid(pb, &g);
 
@@ -364,13 +389,13 @@
     } else if (!ff_guidcmp(&g, &ff_asf_video_stream)) {
         type = AVMEDIA_TYPE_VIDEO;
     } else if (!ff_guidcmp(&g, &ff_asf_jfif_media)) {
-        type = AVMEDIA_TYPE_VIDEO;
+        type                = AVMEDIA_TYPE_VIDEO;
         st->codec->codec_id = AV_CODEC_ID_MJPEG;
     } else if (!ff_guidcmp(&g, &ff_asf_command_stream)) {
         type = AVMEDIA_TYPE_DATA;
     } else if (!ff_guidcmp(&g, &ff_asf_ext_stream_embed_stream_header)) {
         test_for_ext_stream_audio = 1;
-        type = AVMEDIA_TYPE_UNKNOWN;
+        type                      = AVMEDIA_TYPE_UNKNOWN;
     } else {
         return -1;
     }
@@ -387,8 +412,8 @@
     if (test_for_ext_stream_audio) {
         ff_get_guid(pb, &g);
         if (!ff_guidcmp(&g, &ff_asf_ext_stream_audio_stream)) {
-            type = AVMEDIA_TYPE_AUDIO;
-            is_dvr_ms_audio=1;
+            type            = AVMEDIA_TYPE_AUDIO;
+            is_dvr_ms_audio = 1;
             ff_get_guid(pb, &g);
             avio_rl32(pb);
             avio_rl32(pb);
@@ -406,46 +431,46 @@
         if (is_dvr_ms_audio) {
             // codec_id and codec_tag are unreliable in dvr_ms
             // files. Set them later by probing stream.
-            st->request_probe= 1;
+            st->request_probe    = 1;
             st->codec->codec_tag = 0;
         }
-        if (st->codec->codec_id == AV_CODEC_ID_AAC) {
+        if (st->codec->codec_id == AV_CODEC_ID_AAC)
             st->need_parsing = AVSTREAM_PARSE_NONE;
-        } else {
+        else
             st->need_parsing = AVSTREAM_PARSE_FULL;
-        }
         /* We have to init the frame size at some point .... */
         pos2 = avio_tell(pb);
         if (size >= (pos2 + 8 - pos1 + 24)) {
-            asf_st->ds_span = avio_r8(pb);
+            asf_st->ds_span        = avio_r8(pb);
             asf_st->ds_packet_size = avio_rl16(pb);
-            asf_st->ds_chunk_size = avio_rl16(pb);
-            avio_rl16(pb); //ds_data_size
-            avio_r8(pb);   //ds_silence_data
+            asf_st->ds_chunk_size  = avio_rl16(pb);
+            avio_rl16(pb);  // ds_data_size
+            avio_r8(pb);    // ds_silence_data
         }
         if (asf_st->ds_span > 1) {
-            if (!asf_st->ds_chunk_size
-                    || (asf_st->ds_packet_size/asf_st->ds_chunk_size <= 1)
-                    || asf_st->ds_packet_size % asf_st->ds_chunk_size)
-                asf_st->ds_span = 0; // disable descrambling
+            if (!asf_st->ds_chunk_size                                ||
+                (asf_st->ds_packet_size / asf_st->ds_chunk_size <= 1) ||
+                asf_st->ds_packet_size % asf_st->ds_chunk_size)
+                asf_st->ds_span = 0;  // disable descrambling
         }
     } else if (type == AVMEDIA_TYPE_VIDEO &&
-            size - (avio_tell(pb) - pos1 + 24) >= 51) {
+               size - (avio_tell(pb) - pos1 + 24) >= 51) {
         avio_rl32(pb);
         avio_rl32(pb);
         avio_r8(pb);
         avio_rl16(pb);        /* size */
-        sizeX= avio_rl32(pb); /* size */
-        st->codec->width = avio_rl32(pb);
+        sizeX             = avio_rl32(pb); /* size */
+        st->codec->width  = avio_rl32(pb);
         st->codec->height = avio_rl32(pb);
         /* not available for asf */
         avio_rl16(pb); /* panes */
         st->codec->bits_per_coded_sample = avio_rl16(pb); /* depth */
-        tag1 = avio_rl32(pb);
+        tag1                             = avio_rl32(pb);
         avio_skip(pb, 20);
         if (sizeX > 40) {
             st->codec->extradata_size = ffio_limit(pb, sizeX - 40);
-            st->codec->extradata = av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
+            st->codec->extradata      = av_mallocz(st->codec->extradata_size +
+                                                   FF_INPUT_BUFFER_PADDING_SIZE);
             avio_read(pb, st->codec->extradata, st->codec->extradata_size);
         }
 
@@ -455,8 +480,8 @@
         if (st->codec->extradata_size && (st->codec->bits_per_coded_sample <= 8)) {
 #if HAVE_BIGENDIAN
             int i;
-            for (i = 0; i < FFMIN(st->codec->extradata_size, AVPALETTE_SIZE)/4; i++)
-                asf_st->palette[i] = av_bswap32(((uint32_t*)st->codec->extradata)[i]);
+            for (i = 0; i < FFMIN(st->codec->extradata_size, AVPALETTE_SIZE) / 4; i++)
+                asf_st->palette[i] = av_bswap32(((uint32_t *)st->codec->extradata)[i]);
 #else
             memcpy(asf_st->palette, st->codec->extradata,
                    FFMIN(st->codec->extradata_size, AVPALETTE_SIZE));
@@ -465,16 +490,18 @@
         }
 
         st->codec->codec_tag = tag1;
-        st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, tag1);
-        if(tag1 == MKTAG('D', 'V', 'R', ' ')){
+        st->codec->codec_id  = ff_codec_get_id(ff_codec_bmp_tags, tag1);
+        if (tag1 == MKTAG('D', 'V', 'R', ' ')) {
             st->need_parsing = AVSTREAM_PARSE_FULL;
-            // issue658 containse wrong w/h and MS even puts a fake seq header with wrong w/h in extradata while a correct one is in te stream. maximum lameness
-            st->codec->width  =
+            /* issue658 contains wrong w/h and MS even puts a fake seq header
+             * with wrong w/h in extradata while a correct one is in the stream.
+             * maximum lameness */
+            st->codec->width      =
                 st->codec->height = 0;
             av_freep(&st->codec->extradata);
-            st->codec->extradata_size=0;
+            st->codec->extradata_size = 0;
         }
-        if(st->codec->codec_id == AV_CODEC_ID_H264)
+        if (st->codec->codec_id == AV_CODEC_ID_H264)
             st->need_parsing = AVSTREAM_PARSE_FULL_ONCE;
     }
     pos2 = avio_tell(pb);
@@ -509,25 +536,25 @@
         asf->streams[stream_num].stream_language_index = stream_languageid_index;
 
     avio_rl64(pb); // avg frametime in 100ns units
-    stream_ct = avio_rl16(pb); //stream-name-count
-    payload_ext_ct = avio_rl16(pb); //payload-extension-system-count
+    stream_ct      = avio_rl16(pb); // stream-name-count
+    payload_ext_ct = avio_rl16(pb); // payload-extension-system-count
 
     if (stream_num < 128) {
         asf->stream_bitrates[stream_num] = leak_rate;
         asf->streams[stream_num].payload_ext_ct = 0;
     }
 
-    for (i=0; i<stream_ct; i++){
+    for (i = 0; i < stream_ct; i++) {
         avio_rl16(pb);
         ext_len = avio_rl16(pb);
         avio_skip(pb, ext_len);
     }
 
-    for (i=0; i<payload_ext_ct; i++){
+    for (i = 0; i < payload_ext_ct; i++) {
         int size;
         ff_get_guid(pb, &g);
         size = avio_rl16(pb);
-        ext_len=avio_rl32(pb);
+        ext_len = avio_rl32(pb);
         avio_skip(pb, ext_len);
         if (stream_num < 128 && i < FF_ARRAY_ELEMS(asf->streams[stream_num].payload)) {
             ASFPayload *p = &asf->streams[stream_num].payload[i];
@@ -551,10 +578,10 @@
     len3 = avio_rl16(pb);
     len4 = avio_rl16(pb);
     len5 = avio_rl16(pb);
-    get_tag(s, "title"    , 0, len1);
-    get_tag(s, "author"   , 0, len2);
-    get_tag(s, "copyright", 0, len3);
-    get_tag(s, "comment"  , 0, len4);
+    get_tag(s, "title", 0, len1, 32);
+    get_tag(s, "author", 0, len2, 32);
+    get_tag(s, "copyright", 0, len3, 32);
+    get_tag(s, "comment", 0, len4, 32);
     avio_skip(pb, len5);
 
     return 0;
@@ -567,29 +594,28 @@
     int desc_count, i, ret;
 
     desc_count = avio_rl16(pb);
-    for(i=0;i<desc_count;i++) {
-        int name_len,value_type,value_len;
+    for (i = 0; i < desc_count; i++) {
+        int name_len, value_type, value_len;
         char name[1024];
 
         name_len = avio_rl16(pb);
-        if (name_len%2)     // must be even, broken lavf versions wrote len-1
+        if (name_len % 2)   // must be even, broken lavf versions wrote len-1
             name_len += 1;
         if ((ret = avio_get_str16le(pb, name_len, name, sizeof(name))) < name_len)
             avio_skip(pb, name_len - ret);
         value_type = avio_rl16(pb);
         value_len  = avio_rl16(pb);
-        if (!value_type && value_len%2)
+        if (!value_type && value_len % 2)
             value_len += 1;
-        /**
-         * My sample has that stream set to 0 maybe that mean the container.
-         * Asf stream count start at 1. I am using 0 to the container value since it's unused
-         */
-        if (!strcmp(name, "AspectRatioX")){
-            asf->dar[0].num= get_value(s->pb, value_type);
-        } else if(!strcmp(name, "AspectRatioY")){
-            asf->dar[0].den= get_value(s->pb, value_type);
-        } else
-            get_tag(s, name, value_type, value_len);
+        /* My sample has that stream set to 0 maybe that mean the container.
+         * ASF stream count starts at 1. I am using 0 to the container value
+         * since it's unused. */
+        if (!strcmp(name, "AspectRatioX"))
+            asf->dar[0].num = get_value(s->pb, value_type, 32);
+        else if (!strcmp(name, "AspectRatioY"))
+            asf->dar[0].den = get_value(s->pb, value_type, 32);
+        else
+            get_tag(s, name, value_type, value_len, 32);
     }
 
     return 0;
@@ -601,13 +627,15 @@
     ASFContext *asf = s->priv_data;
     int j, ret;
     int stream_count = avio_rl16(pb);
-    for(j = 0; j < stream_count; j++) {
+    for (j = 0; j < stream_count; j++) {
         char lang[6];
         unsigned int lang_len = avio_r8(pb);
-        if ((ret = avio_get_str16le(pb, lang_len, lang, sizeof(lang))) < lang_len)
+        if ((ret = avio_get_str16le(pb, lang_len, lang,
+                                    sizeof(lang))) < lang_len)
             avio_skip(pb, lang_len - ret);
         if (j < 128)
-            av_strlcpy(asf->stream_languages[j], lang, sizeof(*asf->stream_languages));
+            av_strlcpy(asf->stream_languages[j], lang,
+                       sizeof(*asf->stream_languages));
     }
 
     return 0;
@@ -617,30 +645,35 @@
 {
     AVIOContext *pb = s->pb;
     ASFContext *asf = s->priv_data;
-    int n, stream_num, name_len, value_len, value_num;
+    int n, stream_num, name_len, value_len;
     int ret, i;
     n = avio_rl16(pb);
 
-    for(i=0;i<n;i++) {
+    for (i = 0; i < n; i++) {
         char name[1024];
-        int av_unused value_type;
+        int value_type;
 
-        avio_rl16(pb); //lang_list_index
-        stream_num= avio_rl16(pb);
-        name_len=   avio_rl16(pb);
+        avio_rl16(pb);  // lang_list_index
+        stream_num = avio_rl16(pb);
+        name_len   = avio_rl16(pb);
         value_type = avio_rl16(pb); /* value_type */
-        value_len=  avio_rl32(pb);
+        value_len  = avio_rl32(pb);
 
         if ((ret = avio_get_str16le(pb, name_len, name, sizeof(name))) < name_len)
             avio_skip(pb, name_len - ret);
-        av_dlog(s, "%d %d %d %d %d <%s>\n",
+        av_dlog(s, "%d stream %d name_len %2d type %d len %4d <%s>\n",
                 i, stream_num, name_len, value_type, value_len, name);
-        value_num= avio_rl16(pb);//we should use get_value() here but it does not work 2 is le16 here but le32 elsewhere
-        avio_skip(pb, value_len - 2);
 
-        if(stream_num<128){
-            if     (!strcmp(name, "AspectRatioX")) asf->dar[stream_num].num= value_num;
-            else if(!strcmp(name, "AspectRatioY")) asf->dar[stream_num].den= value_num;
+        if (!strcmp(name, "AspectRatioX")){
+            int aspect_x = get_value(s->pb, value_type, 16);
+            if(stream_num < 128)
+                asf->dar[stream_num].num = aspect_x;
+        } else if(!strcmp(name, "AspectRatioY")){
+            int aspect_y = get_value(s->pb, value_type, 16);
+            if(stream_num < 128)
+                asf->dar[stream_num].den = aspect_y;
+        } else {
+            get_tag(s, name, value_type, value_len, 16);
         }
     }
 
@@ -658,11 +691,10 @@
     count = avio_rl32(pb);    // markers count
     avio_rl16(pb);            // reserved 2 bytes
     name_len = avio_rl16(pb); // name length
-    for(i=0;i<name_len;i++){
+    for (i = 0; i < name_len; i++)
         avio_r8(pb); // skip the name
-    }
 
-    for(i=0;i<count;i++){
+    for (i = 0; i < count; i++) {
         int64_t pres_time;
         int name_len;
 
@@ -672,9 +704,11 @@
         avio_rl32(pb);             // send time
         avio_rl32(pb);             // flags
         name_len = avio_rl32(pb);  // name length
-        if ((ret = avio_get_str16le(pb, name_len * 2, name, sizeof(name))) < name_len)
+        if ((ret = avio_get_str16le(pb, name_len * 2, name,
+                                    sizeof(name))) < name_len)
             avio_skip(pb, name_len - ret);
-        avpriv_new_chapter(s, i, (AVRational){1, 10000000}, pres_time, AV_NOPTS_VALUE, name );
+        avpriv_new_chapter(s, i, (AVRational) { 1, 10000000 }, pres_time,
+                           AV_NOPTS_VALUE, name);
     }
 
     return 0;
@@ -696,19 +730,19 @@
     avio_r8(pb);
     avio_r8(pb);
     memset(&asf->asfid2avid, -1, sizeof(asf->asfid2avid));
-    for(;;) {
-        uint64_t gpos= avio_tell(pb);
+    for (;;) {
+        uint64_t gpos = avio_tell(pb);
         ff_get_guid(pb, &g);
         gsize = avio_rl64(pb);
         print_guid(&g);
         if (!ff_guidcmp(&g, &ff_asf_data_header)) {
             asf->data_object_offset = avio_tell(pb);
-            // if not streaming, gsize is not unlimited (how?), and there is enough space in the file..
-            if (!(asf->hdr.flags & 0x01) && gsize >= 100) {
+            /* If not streaming, gsize is not unlimited (how?),
+             * and there is enough space in the file.. */
+            if (!(asf->hdr.flags & 0x01) && gsize >= 100)
                 asf->data_object_size = gsize - 24;
-            } else {
+            else
                 asf->data_object_size = (uint64_t)-1;
-            }
             break;
         }
         if (gsize < 24)
@@ -727,6 +761,8 @@
             asf_read_ext_content_desc(s, gsize);
         } else if (!ff_guidcmp(&g, &ff_asf_metadata_header)) {
             asf_read_metadata(s, gsize);
+        } else if (!ff_guidcmp(&g, &ff_asf_metadata_library_header)) {
+            asf_read_metadata(s, gsize);
         } else if (!ff_guidcmp(&g, &ff_asf_ext_stream_header)) {
             asf_read_ext_stream_properties(s, gsize);
 
@@ -746,26 +782,30 @@
                 if (!ff_guidcmp(&g, &ff_asf_content_encryption)) {
                     unsigned int len;
                     AVPacket pkt;
-                    av_log(s, AV_LOG_WARNING, "DRM protected stream detected, decoding will likely fail!\n");
+                    av_log(s, AV_LOG_WARNING,
+                           "DRM protected stream detected, decoding will likely fail!\n");
                     len= avio_rl32(pb);
                     av_log(s, AV_LOG_DEBUG, "Secret data:\n");
                     av_get_packet(pb, &pkt, len); av_hex_dump_log(s, AV_LOG_DEBUG, pkt.data, pkt.size); av_free_packet(&pkt);
                     len= avio_rl32(pb);
-                    get_tag(s, "ASF_Protection_Type", -1, len);
+                    get_tag(s, "ASF_Protection_Type", -1, len, 32);
                     len= avio_rl32(pb);
-                    get_tag(s, "ASF_Key_ID", -1, len);
+                    get_tag(s, "ASF_Key_ID", -1, len, 32);
                     len= avio_rl32(pb);
-                    get_tag(s, "ASF_License_URL", -1, len);
+                    get_tag(s, "ASF_License_URL", -1, len, 32);
                 } else if (!ff_guidcmp(&g, &ff_asf_ext_content_encryption)) {
-                    av_log(s, AV_LOG_WARNING, "Ext DRM protected stream detected, decoding will likely fail!\n");
+                    av_log(s, AV_LOG_WARNING,
+                           "Ext DRM protected stream detected, decoding will likely fail!\n");
                     av_dict_set(&s->metadata, "encryption", "ASF Extended Content Encryption", 0);
                 } else if (!ff_guidcmp(&g, &ff_asf_digital_signature)) {
                     av_log(s, AV_LOG_INFO, "Digital signature detected!\n");
                 }
             }
         }
-        if(avio_tell(pb) != gpos + gsize)
-            av_log(s, AV_LOG_DEBUG, "gpos mismatch our pos=%"PRIu64", end=%"PRIu64"\n", avio_tell(pb)-gpos, gsize);
+        if (avio_tell(pb) != gpos + gsize)
+            av_log(s, AV_LOG_DEBUG,
+                   "gpos mismatch our pos=%"PRIu64", end=%"PRId64"\n",
+                   avio_tell(pb) - gpos, gsize);
         avio_seek(pb, gpos + gsize, SEEK_SET);
     }
     ff_get_guid(pb, &g);
@@ -774,21 +814,22 @@
     avio_r8(pb);
     if (url_feof(pb))
         return AVERROR_EOF;
-    asf->data_offset = avio_tell(pb);
+    asf->data_offset      = avio_tell(pb);
     asf->packet_size_left = 0;
 
-
-    for(i=0; i<128; i++){
-        int stream_num= asf->asfid2avid[i];
-        if(stream_num>=0){
+    for (i = 0; i < 128; i++) {
+        int stream_num = asf->asfid2avid[i];
+        if (stream_num >= 0) {
             AVStream *st = s->streams[stream_num];
             if (!st->codec->bit_rate)
                 st->codec->bit_rate = asf->stream_bitrates[i];
-            if (asf->dar[i].num > 0 && asf->dar[i].den > 0){
+            if (asf->dar[i].num > 0 && asf->dar[i].den > 0) {
                 av_reduce(&st->sample_aspect_ratio.num,
                           &st->sample_aspect_ratio.den,
                           asf->dar[i].num, asf->dar[i].den, INT_MAX);
-            } else if ((asf->dar[0].num > 0) && (asf->dar[0].den > 0) && (st->codec->codec_type==AVMEDIA_TYPE_VIDEO)) // Use ASF container value if the stream doesn't AR set.
+            } else if ((asf->dar[0].num > 0) && (asf->dar[0].den > 0) &&
+                       // Use ASF container value if the stream doesn't set AR.
+                       (st->codec->codec_type == AVMEDIA_TYPE_VIDEO))
                 av_reduce(&st->sample_aspect_ratio.num,
                           &st->sample_aspect_ratio.den,
                           asf->dar[0].num, asf->dar[0].den, INT_MAX);
@@ -802,7 +843,8 @@
                 const char *rfc1766 = asf->stream_languages[asf->streams[i].stream_language_index];
                 if (rfc1766 && strlen(rfc1766) > 1) {
                     const char primary_tag[3] = { rfc1766[0], rfc1766[1], '\0' }; // ignore country code if any
-                    const char *iso6392 = av_convert_lang_to(primary_tag, AV_LANG_ISO639_2_BIBL);
+                    const char *iso6392       = av_convert_lang_to(primary_tag,
+                                                                   AV_LANG_ISO639_2_BIBL);
                     if (iso6392)
                         av_dict_set(&st->metadata, "language", iso6392, 0);
                 }
@@ -815,13 +857,23 @@
     return 0;
 }
 
-#define DO_2BITS(bits, var, defval) \
-    switch (bits & 3) \
-    { \
-    case 3: var = avio_rl32(pb); rsize += 4; break; \
-    case 2: var = avio_rl16(pb); rsize += 2; break; \
-    case 1: var = avio_r8(pb);   rsize++; break; \
-    default: var = defval; break; \
+#define DO_2BITS(bits, var, defval)             \
+    switch (bits & 3) {                         \
+    case 3:                                     \
+        var = avio_rl32(pb);                    \
+        rsize += 4;                             \
+        break;                                  \
+    case 2:                                     \
+        var = avio_rl16(pb);                    \
+        rsize += 2;                             \
+        break;                                  \
+    case 1:                                     \
+        var = avio_r8(pb);                      \
+        rsize++;                                \
+        break;                                  \
+    default:                                    \
+        var = defval;                           \
+        break;                                  \
     }
 
 /**
@@ -838,31 +890,31 @@
     int c, d, e, off;
 
     // if we do not know packet size, allow skipping up to 32 kB
-    off= 32768;
+    off = 32768;
     if (asf->no_resync_search)
         off = 3;
     else if (s->packet_size > 0)
-        off= (avio_tell(pb) - s->data_offset) % s->packet_size + 3;
+        off = (avio_tell(pb) - s->data_offset) % s->packet_size + 3;
 
-    c=d=e=-1;
-    while(off-- > 0){
-        c=d; d=e;
-        e= avio_r8(pb);
-        if(c == 0x82 && !d && !e)
+    c = d = e = -1;
+    while (off-- > 0) {
+        c = d;
+        d = e;
+        e = avio_r8(pb);
+        if (c == 0x82 && !d && !e)
             break;
     }
 
     if (c != 0x82) {
-        /**
-         * This code allows handling of -EAGAIN at packet boundaries (i.e.
+        /* This code allows handling of -EAGAIN at packet boundaries (i.e.
          * if the packet sync code above triggers -EAGAIN). This does not
          * imply complete -EAGAIN handling support at random positions in
-         * the stream.
-         */
+         * the stream. */
         if (pb->error == AVERROR(EAGAIN))
             return AVERROR(EAGAIN);
         if (!url_feof(pb))
-            av_log(s, AV_LOG_ERROR, "ff asf bad header %x  at:%"PRId64"\n", c, avio_tell(pb));
+            av_log(s, AV_LOG_ERROR,
+                   "ff asf bad header %x  at:%"PRId64"\n", c, avio_tell(pb));
     }
     if ((c & 0x8f) == 0x82) {
         if (d || e) {
@@ -870,11 +922,11 @@
                 av_log(s, AV_LOG_ERROR, "ff asf bad non zero\n");
             return AVERROR_INVALIDDATA;
         }
-        c= avio_r8(pb);
-        d= avio_r8(pb);
-        rsize+=3;
-    }else if(!url_feof(pb)){
-        avio_seek(pb, -1, SEEK_CUR); //FIXME
+        c      = avio_r8(pb);
+        d      = avio_r8(pb);
+        rsize += 3;
+    } else if(!url_feof(pb)) {
+        avio_seek(pb, -1, SEEK_CUR); // FIXME
     }
 
     asf->packet_flags    = c;
@@ -884,13 +936,16 @@
     DO_2BITS(asf->packet_flags >> 1, padsize, 0); // sequence ignored
     DO_2BITS(asf->packet_flags >> 3, padsize, 0); // padding length
 
-    //the following checks prevent overflows and infinite loops
-    if(!packet_length || packet_length >= (1U<<29)){
-        av_log(s, AV_LOG_ERROR, "invalid packet_length %d at:%"PRId64"\n", packet_length, avio_tell(pb));
+    // the following checks prevent overflows and infinite loops
+    if (!packet_length || packet_length >= (1U << 29)) {
+        av_log(s, AV_LOG_ERROR,
+               "invalid packet_length %d at:%"PRId64"\n",
+               packet_length, avio_tell(pb));
         return AVERROR_INVALIDDATA;
     }
-    if(padsize >= packet_length){
-        av_log(s, AV_LOG_ERROR, "invalid padsize %d at:%"PRId64"\n", padsize, avio_tell(pb));
+    if (padsize >= packet_length) {
+        av_log(s, AV_LOG_ERROR,
+               "invalid padsize %d at:%"PRId64"\n", padsize, avio_tell(pb));
         return AVERROR_INVALIDDATA;
     }
 
@@ -899,10 +954,11 @@
     // rsize has at least 11 bytes which have to be present
 
     if (asf->packet_flags & 0x01) {
-        asf->packet_segsizetype = avio_r8(pb); rsize++;
+        asf->packet_segsizetype = avio_r8(pb);
+        rsize++;
         asf->packet_segments = asf->packet_segsizetype & 0x3f;
     } else {
-        asf->packet_segments = 1;
+        asf->packet_segments    = 1;
         asf->packet_segsizetype = 0x80;
     }
     if (rsize > packet_length - padsize) {
@@ -916,7 +972,8 @@
     if (packet_length < asf->hdr.min_pktsize)
         padsize += asf->hdr.min_pktsize - packet_length;
     asf->packet_padsize = padsize;
-    av_dlog(s, "packet: size=%d padsize=%d  left=%d\n", s->packet_size, asf->packet_padsize, asf->packet_size_left);
+    av_dlog(s, "packet: size=%d padsize=%d  left=%d\n",
+            s->packet_size, asf->packet_padsize, asf->packet_size_left);
     return 0;
 }
 
@@ -924,18 +981,19 @@
  *
  * @return <0 if error
  */
-static int asf_read_frame_header(AVFormatContext *s, AVIOContext *pb){
+static int asf_read_frame_header(AVFormatContext *s, AVIOContext *pb)
+{
     ASFContext *asf = s->priv_data;
     ASFStream *asfst;
-    int rsize = 1;
-    int num = avio_r8(pb);
+    int rsize       = 1;
+    int num         = avio_r8(pb);
     int i;
     int64_t ts0, ts1 av_unused;
 
     asf->packet_segments--;
     asf->packet_key_frame = num >> 7;
-    asf->stream_index = asf->asfid2avid[num & 0x7f];
-    asfst = &asf->streams[num & 0x7f];
+    asf->stream_index     = asf->asfid2avid[num & 0x7f];
+    asfst                 = &asf->streams[num & 0x7f];
     // sequence should be ignored!
     DO_2BITS(asf->packet_property >> 4, asf->packet_seq, 0);
     DO_2BITS(asf->packet_property >> 2, asf->packet_frag_offset, 0);
@@ -943,7 +1001,7 @@
     av_dlog(asf, "key:%d stream:%d seq:%d offset:%d replic_size:%d\n",
             asf->packet_key_frame, asf->stream_index, asf->packet_seq,
             asf->packet_frag_offset, asf->packet_replic_size);
-    if (rsize+asf->packet_replic_size > asf->packet_size_left) {
+    if (rsize+(int64_t)asf->packet_replic_size > asf->packet_size_left) {
         av_log(s, AV_LOG_ERROR, "packet_replic_size %d is invalid\n", asf->packet_replic_size);
         return AVERROR_INVALIDDATA;
     }
@@ -951,24 +1009,24 @@
         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){
+        if (asf->packet_obj_size >= (1 << 24) || asf->packet_obj_size <= 0) {
             av_log(s, AV_LOG_ERROR, "packet_obj_size invalid\n");
             return AVERROR_INVALIDDATA;
         }
         asf->packet_frag_timestamp = avio_rl32(pb); // timestamp
 
-        for (i=0; i<asfst->payload_ext_ct; i++) {
+        for (i = 0; i < asfst->payload_ext_ct; i++) {
             ASFPayload *p = &asfst->payload[i];
             int size = p->size;
             int64_t payend;
-            if(size == 0xFFFF)
+            if (size == 0xFFFF)
                 size = avio_rl16(pb);
             payend = avio_tell(pb) + size;
             if (payend > end) {
                 av_log(s, AV_LOG_ERROR, "too long payload\n");
                 break;
             }
-            switch(p->type) {
+            switch (p->type) {
             case 0x50:
 //              duration = avio_rl16(pb);
                 break;
@@ -981,10 +1039,10 @@
                 break;
             case 0x2A:
                 avio_skip(pb, 8);
-                ts0= avio_rl64(pb);
-                ts1= avio_rl64(pb);
-                if(ts0!= -1) asf->packet_frag_timestamp= ts0/10000;
-                else         asf->packet_frag_timestamp= AV_NOPTS_VALUE;
+                ts0 = avio_rl64(pb);
+                ts1 = avio_rl64(pb);
+                if (ts0!= -1) asf->packet_frag_timestamp = ts0/10000;
+                else          asf->packet_frag_timestamp = AV_NOPTS_VALUE;
                 break;
             case 0x5B:
             case 0xB7:
@@ -999,16 +1057,17 @@
 
         avio_seek(pb, end, SEEK_SET);
         rsize += asf->packet_replic_size; // FIXME - check validity
-    } else if (asf->packet_replic_size==1){
+    } else if (asf->packet_replic_size == 1) {
         // multipacket - frag_offset is beginning timestamp
-        asf->packet_time_start = asf->packet_frag_offset;
-        asf->packet_frag_offset = 0;
+        asf->packet_time_start     = asf->packet_frag_offset;
+        asf->packet_frag_offset    = 0;
         asf->packet_frag_timestamp = asf->packet_timestamp;
 
         asf->packet_time_delta = avio_r8(pb);
         rsize++;
-    }else if(asf->packet_replic_size!=0){
-        av_log(s, AV_LOG_ERROR, "unexpected packet_replic_size of %d\n", asf->packet_replic_size);
+    } else if (asf->packet_replic_size != 0) {
+        av_log(s, AV_LOG_ERROR, "unexpected packet_replic_size of %d\n",
+               asf->packet_replic_size);
         return AVERROR_INVALIDDATA;
     }
     if (asf->packet_flags & 0x01) {
@@ -1016,9 +1075,10 @@
         if (rsize > asf->packet_size_left) {
             av_log(s, AV_LOG_ERROR, "packet_replic_size is invalid\n");
             return AVERROR_INVALIDDATA;
-        } else if(asf->packet_frag_size > asf->packet_size_left - rsize){
+        } else if (asf->packet_frag_size > asf->packet_size_left - rsize) {
             if (asf->packet_frag_size > asf->packet_size_left - rsize + asf->packet_padsize) {
-                av_log(s, AV_LOG_ERROR, "packet_frag_size is invalid (%d-%d)\n", asf->packet_size_left, rsize);
+                av_log(s, AV_LOG_ERROR, "packet_frag_size is invalid (%d-%d)\n",
+                       asf->packet_size_left, rsize);
                 return AVERROR_INVALIDDATA;
             } else {
                 int diff = asf->packet_frag_size - (asf->packet_size_left - rsize);
@@ -1050,7 +1110,7 @@
  */
 static int ff_asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pkt)
 {
-    ASFContext *asf = s->priv_data;
+    ASFContext *asf   = s->priv_data;
     ASFStream *asf_st = 0;
     for (;;) {
         int ret;
@@ -1065,10 +1125,10 @@
             /* fail safe */
             avio_skip(pb, ret);
 
-            asf->packet_pos= avio_tell(pb);
+            asf->packet_pos = avio_tell(pb);
             if (asf->data_object_size != (uint64_t)-1 &&
                 (asf->packet_pos - asf->data_object_offset >= asf->data_object_size))
-                return AVERROR_EOF; /* Do not exceed the size of the data object */
+                return AVERROR_EOF;  /* Do not exceed the size of the data object */
             return 1;
         }
         if (asf->packet_time_start == 0) {
@@ -1085,12 +1145,14 @@
                 avio_skip(pb, asf->packet_frag_size);
                 asf->packet_size_left -= asf->packet_frag_size;
                 if (asf->stream_index < 0)
-                    av_log(s, AV_LOG_ERROR, "ff asf skip %d (unknown stream)\n", asf->packet_frag_size);
+                    av_log(s, AV_LOG_ERROR, "ff asf skip %d (unknown stream)\n",
+                           asf->packet_frag_size);
                 continue;
             }
             asf->asf_st = s->streams[asf->stream_index]->priv_data;
         }
         asf_st = asf->asf_st;
+        av_assert0(asf_st);
 
         if (asf->packet_replic_size == 1) {
             // frag_offset is here used as the beginning timestamp
@@ -1116,11 +1178,12 @@
         }
 
         if (asf_st->pkt.size != asf->packet_obj_size ||
-            //FIXME is this condition sufficient?
+            // 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);
+                av_log(s, AV_LOG_INFO,
+                       "freeing incomplete packet size %d, new %d\n",
+                       asf_st->pkt.size, asf->packet_obj_size);
                 asf_st->frag_offset = 0;
                 av_free_packet(&asf_st->pkt);
             }
@@ -1163,8 +1226,10 @@
 
         if (asf->packet_frag_offset >= asf_st->pkt.size ||
             asf->packet_frag_size > asf_st->pkt.size - asf->packet_frag_offset) {
-            av_log(s, AV_LOG_ERROR, "packet fragment position invalid %u,%u not in %u\n",
-                   asf->packet_frag_offset, asf->packet_frag_size, asf_st->pkt.size);
+            av_log(s, AV_LOG_ERROR,
+                   "packet fragment position invalid %u,%u not in %u\n",
+                   asf->packet_frag_offset, asf->packet_frag_size,
+                   asf_st->pkt.size);
             continue;
         }
 
@@ -1192,11 +1257,12 @@
         asf_st->frag_offset += ret;
         /* test if whole packet is read */
         if (asf_st->frag_offset == asf_st->pkt.size) {
-            //workaround for macroshit radio DVR-MS files
+            // workaround for macroshit radio DVR-MS files
             if (s->streams[asf->stream_index]->codec->codec_id == AV_CODEC_ID_MPEG2VIDEO &&
                 asf_st->pkt.size > 100) {
                 int i;
-                for (i = 0; i < asf_st->pkt.size && !asf_st->pkt.data[i]; i++);
+                for (i = 0; i < asf_st->pkt.size && !asf_st->pkt.data[i]; i++)
+                    ;
                 if (i == asf_st->pkt.size) {
                     av_log(s, AV_LOG_DEBUG, "discarding ms fart\n");
                     asf_st->frag_offset = 0;
@@ -1207,23 +1273,26 @@
 
             /* return packet */
             if (asf_st->ds_span > 1) {
-                if(asf_st->pkt.size != asf_st->ds_packet_size * asf_st->ds_span) {
-                    av_log(s, AV_LOG_ERROR, "pkt.size != ds_packet_size * "
-                           "ds_span (%d %d %d)\n", asf_st->pkt.size,
-                           asf_st->ds_packet_size, asf_st->ds_span);
+                if (asf_st->pkt.size != asf_st->ds_packet_size * asf_st->ds_span) {
+                    av_log(s, AV_LOG_ERROR,
+                           "pkt.size != ds_packet_size * ds_span (%d %d %d)\n",
+                           asf_st->pkt.size, asf_st->ds_packet_size,
+                           asf_st->ds_span);
                 } else {
                     /* packet descrambling */
-                    uint8_t *newdata = av_malloc(asf_st->pkt.size + FF_INPUT_BUFFER_PADDING_SIZE);
+                    uint8_t *newdata = av_malloc(asf_st->pkt.size +
+                                                 FF_INPUT_BUFFER_PADDING_SIZE);
                     if (newdata) {
                         int offset = 0;
-                        memset(newdata + asf_st->pkt.size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+                        memset(newdata + asf_st->pkt.size, 0,
+                               FF_INPUT_BUFFER_PADDING_SIZE);
                         while (offset < asf_st->pkt.size) {
                             int off = offset / asf_st->ds_chunk_size;
                             int row = off / asf_st->ds_span;
                             int col = off % asf_st->ds_span;
                             int idx = row + col * asf_st->ds_packet_size / asf_st->ds_chunk_size;
                             assert(offset + asf_st->ds_chunk_size <= asf_st->pkt.size);
-                            assert(idx+1 <= asf_st->pkt.size / asf_st->ds_chunk_size);
+                            assert(idx + 1 <= asf_st->pkt.size / asf_st->ds_chunk_size);
                             memcpy(newdata + offset,
                                    asf_st->pkt.data + idx * asf_st->ds_chunk_size,
                                    asf_st->ds_chunk_size);
@@ -1257,7 +1326,8 @@
         if ((ret = ff_asf_parse_packet(s, s->pb, pkt)) <= 0)
             return ret;
         if ((ret = ff_asf_get_packet(s, s->pb)) < 0)
-            assert(asf->packet_size_left < FRAME_HEADER_SIZE || asf->packet_segments < 1);
+            assert(asf->packet_size_left < FRAME_HEADER_SIZE ||
+                   asf->packet_segments < 1);
         asf->packet_time_start = 0;
     }
 }
@@ -1271,32 +1341,34 @@
     ASFStream *asf_st;
     int i;
 
-    asf->packet_size_left = 0;
-    asf->packet_segments = 0;
-    asf->packet_flags = 0;
-    asf->packet_property = 0;
-    asf->packet_timestamp = 0;
-    asf->packet_segsizetype = 0;
-    asf->packet_segments = 0;
-    asf->packet_seq = 0;
-    asf->packet_replic_size = 0;
-    asf->packet_key_frame = 0;
-    asf->packet_padsize = 0;
-    asf->packet_frag_offset = 0;
-    asf->packet_frag_size = 0;
+    asf->packet_size_left      = 0;
+    asf->packet_segments       = 0;
+    asf->packet_flags          = 0;
+    asf->packet_property       = 0;
+    asf->packet_timestamp      = 0;
+    asf->packet_segsizetype    = 0;
+    asf->packet_segments       = 0;
+    asf->packet_seq            = 0;
+    asf->packet_replic_size    = 0;
+    asf->packet_key_frame      = 0;
+    asf->packet_padsize        = 0;
+    asf->packet_frag_offset    = 0;
+    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;
+    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;
+    for (i = 0; i < s->nb_streams; i++) {
+        asf_st = s->streams[i]->priv_data;
+        if (!asf_st)
+            continue;
         av_free_packet(&asf_st->pkt);
-        asf_st->frag_offset=0;
-        asf_st->seq=0;
+        asf_st->frag_offset = 0;
+        asf_st->seq         = 0;
     }
-    asf->asf_st= NULL;
+    asf->asf_st = NULL;
 }
 
 static int asf_read_close(AVFormatContext *s)
@@ -1306,28 +1378,30 @@
     return 0;
 }
 
-static int64_t asf_read_pts(AVFormatContext *s, int stream_index, int64_t *ppos, int64_t pos_limit)
+static int64_t asf_read_pts(AVFormatContext *s, int stream_index,
+                            int64_t *ppos, int64_t pos_limit)
 {
     AVPacket pkt1, *pkt = &pkt1;
     ASFStream *asf_st;
     int64_t pts;
-    int64_t pos= *ppos;
+    int64_t pos = *ppos;
     int i;
     int64_t start_pos[ASF_MAX_STREAMS];
 
-    for(i=0; i<s->nb_streams; i++){
-        start_pos[i]= pos;
-    }
+    for (i = 0; i < s->nb_streams; i++)
+        start_pos[i] = pos;
 
     if (s->packet_size > 0)
-        pos= (pos+s->packet_size-1-s->data_offset)/s->packet_size*s->packet_size+ s->data_offset;
-    *ppos= pos;
+        pos = (pos + s->packet_size - 1 - s->data_offset) /
+              s->packet_size * s->packet_size +
+              s->data_offset;
+    *ppos = pos;
     if (avio_seek(s->pb, pos, SEEK_SET) < 0)
         return AV_NOPTS_VALUE;
 
     asf_reset_header(s);
-    for(;;){
-        if (av_read_frame(s, pkt) < 0){
+    for (;;) {
+        if (av_read_frame(s, pkt) < 0) {
             av_log(s, AV_LOG_INFO, "asf_read_pts failed\n");
             return AV_NOPTS_VALUE;
         }
@@ -1335,31 +1409,33 @@
         pts = pkt->dts;
 
         av_free_packet(pkt);
-        if(pkt->flags&AV_PKT_FLAG_KEY){
-            i= pkt->stream_index;
+        if (pkt->flags & AV_PKT_FLAG_KEY) {
+            i = pkt->stream_index;
 
-            asf_st= s->streams[i]->priv_data;
+            asf_st = s->streams[i]->priv_data;
+            av_assert0(asf_st);
 
 //            assert((asf_st->packet_pos - s->data_offset) % s->packet_size == 0);
-            pos= asf_st->packet_pos;
+            pos = asf_st->packet_pos;
 
-            av_add_index_entry(s->streams[i], pos, pts, pkt->size, pos - start_pos[i] + 1, AVINDEX_KEYFRAME);
-            start_pos[i]= asf_st->packet_pos + 1;
+            av_add_index_entry(s->streams[i], pos, pts, pkt->size,
+                               pos - start_pos[i] + 1, AVINDEX_KEYFRAME);
+            start_pos[i] = asf_st->packet_pos + 1;
 
-            if(pkt->stream_index == stream_index)
-               break;
+            if (pkt->stream_index == stream_index)
+                break;
         }
     }
 
-    *ppos= pos;
+    *ppos = pos;
     return pts;
 }
 
 static void asf_build_simple_index(AVFormatContext *s, int stream_index)
 {
     ff_asf_guid g;
-    ASFContext *asf = s->priv_data;
-    int64_t current_pos= avio_tell(s->pb);
+    ASFContext *asf     = s->priv_data;
+    int64_t current_pos = avio_tell(s->pb);
 
     if(avio_seek(s->pb, asf->data_object_offset + asf->data_object_size, SEEK_SET) < 0) {
         asf->index_read= -1;
@@ -1369,58 +1445,62 @@
     ff_get_guid(s->pb, &g);
 
     /* the data object can be followed by other top-level objects,
-       skip them until the simple index object is reached */
+     * skip them until the simple index object is reached */
     while (ff_guidcmp(&g, &ff_asf_simple_index_header)) {
-        int64_t gsize= avio_rl64(s->pb);
+        int64_t gsize = avio_rl64(s->pb);
         if (gsize < 24 || url_feof(s->pb)) {
             avio_seek(s->pb, current_pos, SEEK_SET);
             asf->index_read= -1;
             return;
         }
-        avio_skip(s->pb, gsize-24);
+        avio_skip(s->pb, gsize - 24);
         ff_get_guid(s->pb, &g);
     }
 
     {
-        int64_t itime, last_pos=-1;
+        int64_t itime, last_pos = -1;
         int pct, ict;
         int i;
-        int64_t av_unused gsize= avio_rl64(s->pb);
+        int64_t av_unused gsize = avio_rl64(s->pb);
         ff_get_guid(s->pb, &g);
-        itime=avio_rl64(s->pb);
-        pct=avio_rl32(s->pb);
-        ict=avio_rl32(s->pb);
-        av_log(s, AV_LOG_DEBUG, "itime:0x%"PRIx64", pct:%d, ict:%d\n",itime,pct,ict);
+        itime = avio_rl64(s->pb);
+        pct   = avio_rl32(s->pb);
+        ict   = avio_rl32(s->pb);
+        av_log(s, AV_LOG_DEBUG,
+               "itime:0x%"PRIx64", pct:%d, ict:%d\n", itime, pct, ict);
 
-        for (i=0;i<ict;i++){
-            int pktnum=avio_rl32(s->pb);
-            int pktct =avio_rl16(s->pb);
-            int64_t pos      = s->data_offset + s->packet_size*(int64_t)pktnum;
-            int64_t index_pts= FFMAX(av_rescale(itime, i, 10000) - asf->hdr.preroll, 0);
+        for (i = 0; i < ict; i++) {
+            int pktnum        = avio_rl32(s->pb);
+            int pktct         = avio_rl16(s->pb);
+            int64_t pos       = s->data_offset + s->packet_size * (int64_t)pktnum;
+            int64_t index_pts = FFMAX(av_rescale(itime, i, 10000) - asf->hdr.preroll, 0);
 
-            if(pos != last_pos){
-            av_log(s, AV_LOG_DEBUG, "pktnum:%d, pktct:%d  pts: %"PRId64"\n", pktnum, pktct, index_pts);
-            av_add_index_entry(s->streams[stream_index], pos, index_pts, s->packet_size, 0, AVINDEX_KEYFRAME);
-            last_pos=pos;
+            if (pos != last_pos) {
+                av_log(s, AV_LOG_DEBUG, "pktnum:%d, pktct:%d  pts: %"PRId64"\n",
+                       pktnum, pktct, index_pts);
+                av_add_index_entry(s->streams[stream_index], pos, index_pts,
+                                   s->packet_size, 0, AVINDEX_KEYFRAME);
+                last_pos = pos;
             }
         }
-        asf->index_read= ict > 1;
+        asf->index_read = ict > 1;
     }
     avio_seek(s->pb, current_pos, SEEK_SET);
 }
 
-static int asf_read_seek(AVFormatContext *s, int stream_index, int64_t pts, int flags)
+static int asf_read_seek(AVFormatContext *s, int stream_index,
+                         int64_t pts, int flags)
 {
     ASFContext *asf = s->priv_data;
-    AVStream *st = s->streams[stream_index];
+    AVStream *st    = s->streams[stream_index];
 
     if (s->packet_size <= 0)
         return -1;
 
     /* Try using the protocol's read_seek if available */
-    if(s->pb) {
+    if (s->pb) {
         int ret = avio_seek_time(s->pb, stream_index, pts, flags);
-        if(ret >= 0)
+        if (ret >= 0)
             asf_reset_header(s);
         if (ret != AVERROR(ENOSYS))
             return ret;
@@ -1429,9 +1509,9 @@
     if (!asf->index_read)
         asf_build_simple_index(s, stream_index);
 
-    if((asf->index_read > 0 && st->index_entries)){
-        int index= av_index_search_timestamp(st, pts, flags);
-        if(index >= 0) {
+    if ((asf->index_read > 0 && st->index_entries)) {
+        int index = av_index_search_timestamp(st, pts, flags);
+        if (index >= 0) {
             /* find the position */
             uint64_t pos = st->index_entries[index].pos;
 
diff --git a/libavformat/asfenc.c b/libavformat/asfenc.c
index 82681d2..f3aec9c 100644
--- a/libavformat/asfenc.c
+++ b/libavformat/asfenc.c
@@ -18,12 +18,13 @@
  * 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 "avformat.h"
+#include "avio_internal.h"
 #include "internal.h"
 #include "riff.h"
 #include "asf.h"
-#include "avio_internal.h"
-#include "libavutil/dict.h"
 
 #undef NDEBUG
 #include <assert.h>
@@ -33,10 +34,9 @@
 #define ASF_INDEX_BLOCK         (1<<9)
 
 #define ASF_PACKET_ERROR_CORRECTION_DATA_SIZE 0x2
-#define ASF_PACKET_ERROR_CORRECTION_FLAGS (\
-                ASF_PACKET_FLAG_ERROR_CORRECTION_PRESENT | \
-                ASF_PACKET_ERROR_CORRECTION_DATA_SIZE\
-                )
+#define ASF_PACKET_ERROR_CORRECTION_FLAGS          \
+    (ASF_PACKET_FLAG_ERROR_CORRECTION_PRESENT |    \
+     ASF_PACKET_ERROR_CORRECTION_DATA_SIZE)
 
 #if (ASF_PACKET_ERROR_CORRECTION_FLAGS != 0)
 #   define ASF_PACKET_ERROR_CORRECTION_FLAGS_FIELD_SIZE 1
@@ -44,12 +44,11 @@
 #   define ASF_PACKET_ERROR_CORRECTION_FLAGS_FIELD_SIZE 0
 #endif
 
-#define ASF_PPI_PROPERTY_FLAGS (\
-                ASF_PL_FLAG_REPLICATED_DATA_LENGTH_FIELD_IS_BYTE | \
-                ASF_PL_FLAG_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_IS_DWORD | \
-                ASF_PL_FLAG_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_IS_BYTE | \
-                ASF_PL_FLAG_STREAM_NUMBER_LENGTH_FIELD_IS_BYTE \
-                )
+#define ASF_PPI_PROPERTY_FLAGS                                       \
+    (ASF_PL_FLAG_REPLICATED_DATA_LENGTH_FIELD_IS_BYTE           |    \
+     ASF_PL_FLAG_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_IS_DWORD |    \
+     ASF_PL_FLAG_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_IS_BYTE       |    \
+     ASF_PL_FLAG_STREAM_NUMBER_LENGTH_FIELD_IS_BYTE)
 
 #define ASF_PPI_LENGTH_TYPE_FLAGS 0
 
@@ -68,7 +67,6 @@
 #   define ASF_PPI_SEQUENCE_FIELD_SIZE 0
 #endif
 
-
 #if (ASF_PPI_FLAG_PACKET_LENGTH_FIELD_IS_BYTE == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_PACKET_LENGTH_FIELD_SIZE))
 #   define ASF_PPI_PACKET_LENGTH_FIELD_SIZE 1
 #endif
@@ -144,51 +142,45 @@
 #   define ASF_PAYLOAD_LENGTH_FIELD_SIZE 0
 #endif
 
-#define PACKET_HEADER_MIN_SIZE (\
-                ASF_PACKET_ERROR_CORRECTION_FLAGS_FIELD_SIZE + \
-                ASF_PACKET_ERROR_CORRECTION_DATA_SIZE + \
-                1 + /*Length Type Flags*/ \
-                1 + /*Property Flags*/ \
-                ASF_PPI_PACKET_LENGTH_FIELD_SIZE + \
-                ASF_PPI_SEQUENCE_FIELD_SIZE + \
-                ASF_PPI_PADDING_LENGTH_FIELD_SIZE + \
-                4 + /*Send Time Field*/ \
-                2   /*Duration Field*/ \
-                )
-
+#define PACKET_HEADER_MIN_SIZE \
+    (ASF_PACKET_ERROR_CORRECTION_FLAGS_FIELD_SIZE +       \
+     ASF_PACKET_ERROR_CORRECTION_DATA_SIZE +              \
+     1 +        /* Length Type Flags */                   \
+     1 +        /* Property Flags */                      \
+     ASF_PPI_PACKET_LENGTH_FIELD_SIZE +                   \
+     ASF_PPI_SEQUENCE_FIELD_SIZE +                        \
+     ASF_PPI_PADDING_LENGTH_FIELD_SIZE +                  \
+     4 +        /* Send Time Field */                     \
+     2)         /* Duration Field */
 
 // Replicated Data shall be at least 8 bytes long.
 #define ASF_PAYLOAD_REPLICATED_DATA_LENGTH 0x08
 
-#define PAYLOAD_HEADER_SIZE_SINGLE_PAYLOAD (\
-                1 + /*Stream Number*/ \
-                ASF_PAYLOAD_MEDIA_OBJECT_NUMBER_FIELD_SIZE + \
-                ASF_PAYLOAD_OFFSET_INTO_MEDIA_OBJECT_FIELD_SIZE + \
-                ASF_PAYLOAD_REPLICATED_DATA_LENGTH_FIELD_SIZE + \
-                ASF_PAYLOAD_REPLICATED_DATA_LENGTH \
-                )
+#define PAYLOAD_HEADER_SIZE_SINGLE_PAYLOAD                \
+    (1 +     /* Stream Number */                          \
+     ASF_PAYLOAD_MEDIA_OBJECT_NUMBER_FIELD_SIZE +         \
+     ASF_PAYLOAD_OFFSET_INTO_MEDIA_OBJECT_FIELD_SIZE +    \
+     ASF_PAYLOAD_REPLICATED_DATA_LENGTH_FIELD_SIZE +      \
+     ASF_PAYLOAD_REPLICATED_DATA_LENGTH)
 
-#define PAYLOAD_HEADER_SIZE_MULTIPLE_PAYLOADS (\
-                1 + /*Stream Number*/ \
-                ASF_PAYLOAD_MEDIA_OBJECT_NUMBER_FIELD_SIZE + \
-                ASF_PAYLOAD_OFFSET_INTO_MEDIA_OBJECT_FIELD_SIZE + \
-                ASF_PAYLOAD_REPLICATED_DATA_LENGTH_FIELD_SIZE + \
-                ASF_PAYLOAD_REPLICATED_DATA_LENGTH + \
-                ASF_PAYLOAD_LENGTH_FIELD_SIZE \
-                )
+#define PAYLOAD_HEADER_SIZE_MULTIPLE_PAYLOADS             \
+    (1 +        /* Stream Number */                       \
+     ASF_PAYLOAD_MEDIA_OBJECT_NUMBER_FIELD_SIZE +         \
+     ASF_PAYLOAD_OFFSET_INTO_MEDIA_OBJECT_FIELD_SIZE +    \
+     ASF_PAYLOAD_REPLICATED_DATA_LENGTH_FIELD_SIZE +      \
+     ASF_PAYLOAD_REPLICATED_DATA_LENGTH +                 \
+     ASF_PAYLOAD_LENGTH_FIELD_SIZE)
 
-#define SINGLE_PAYLOAD_DATA_LENGTH (\
-                PACKET_SIZE - \
-                PACKET_HEADER_MIN_SIZE - \
-                PAYLOAD_HEADER_SIZE_SINGLE_PAYLOAD \
-                )
+#define SINGLE_PAYLOAD_DATA_LENGTH                        \
+    (PACKET_SIZE -                                        \
+     PACKET_HEADER_MIN_SIZE -                             \
+     PAYLOAD_HEADER_SIZE_SINGLE_PAYLOAD)
 
-#define MULTI_PAYLOAD_CONSTANT (\
-                PACKET_SIZE - \
-                PACKET_HEADER_MIN_SIZE - \
-                1 - /*Payload Flags*/ \
-                2*PAYLOAD_HEADER_SIZE_MULTIPLE_PAYLOADS \
-                )
+#define MULTI_PAYLOAD_CONSTANT                            \
+    (PACKET_SIZE -                                        \
+     PACKET_HEADER_MIN_SIZE -                             \
+     1 -         /* Payload Flags */                      \
+     2 * PAYLOAD_HEADER_SIZE_MULTIPLE_PAYLOADS)
 
 typedef struct {
     uint32_t seqno;
@@ -208,7 +200,7 @@
     /* only for reading */
     uint64_t data_offset;                ///< beginning of the first data packet
 
-    ASFIndex* index_ptr;
+    ASFIndex *index_ptr;
     uint32_t nb_index_memory_alloc;
     uint16_t maximum_packet;
     uint32_t next_packet_number;
@@ -218,10 +210,10 @@
 } ASFContext;
 
 static const AVCodecTag codec_asf_bmp_tags[] = {
-    { AV_CODEC_ID_MPEG4, MKTAG('M', '4', 'S', '2') },
-    { AV_CODEC_ID_MPEG4, MKTAG('M', 'P', '4', 'S') },
+    { AV_CODEC_ID_MPEG4,     MKTAG('M', '4', 'S', '2') },
+    { AV_CODEC_ID_MPEG4,     MKTAG('M', 'P', '4', 'S') },
     { AV_CODEC_ID_MSMPEG4V3, MKTAG('M', 'P', '4', '3') },
-    { AV_CODEC_ID_NONE, 0 },
+    { AV_CODEC_ID_NONE,      0 },
 };
 
 #define PREROLL_TIME 3100
@@ -269,7 +261,8 @@
 }
 
 /* write an asf chunk (only used in streaming case) */
-static void put_chunk(AVFormatContext *s, int type, int payload_length, int flags)
+static void put_chunk(AVFormatContext *s, int type,
+                      int payload_length, int flags)
 {
     ASFContext *asf = s->priv_data;
     AVIOContext *pb = s->pb;
@@ -277,10 +270,10 @@
 
     length = payload_length + 8;
     avio_wl16(pb, type);
-    avio_wl16(pb, length);    //size
-    avio_wl32(pb, asf->seqno);//sequence number
-    avio_wl16(pb, flags); /* unknown bytes */
-    avio_wl16(pb, length);    //size_confirm
+    avio_wl16(pb, length);      // size
+    avio_wl32(pb, asf->seqno);  // sequence number
+    avio_wl16(pb, flags);       // unknown bytes
+    avio_wl16(pb, length);      // size_confirm
     asf->seqno++;
 }
 
@@ -289,13 +282,14 @@
 {
     int64_t t;
 
-    t = ti * INT64_C(10000000);
+    t  = ti * INT64_C(10000000);
     t += INT64_C(116444736000000000);
     return t;
 }
 
 /* write the header (used two times if non streamed) */
-static int asf_write_header1(AVFormatContext *s, int64_t file_size, int64_t data_chunk_size)
+static int asf_write_header1(AVFormatContext *s, int64_t file_size,
+                             int64_t data_chunk_size)
 {
     ASFContext *asf = s->priv_data;
     AVIOContext *pb = s->pb;
@@ -310,18 +304,18 @@
 
     ff_metadata_conv(&s->metadata, ff_asf_metadata_conv, NULL);
 
-    tags[0] = av_dict_get(s->metadata, "title"    , NULL, 0);
-    tags[1] = av_dict_get(s->metadata, "author"   , NULL, 0);
+    tags[0] = av_dict_get(s->metadata, "title", NULL, 0);
+    tags[1] = av_dict_get(s->metadata, "author", NULL, 0);
     tags[2] = av_dict_get(s->metadata, "copyright", NULL, 0);
-    tags[3] = av_dict_get(s->metadata, "comment"  , NULL, 0);
-    tags[4] = av_dict_get(s->metadata, "rating"   , NULL, 0);
+    tags[3] = av_dict_get(s->metadata, "comment", NULL, 0);
+    tags[4] = av_dict_get(s->metadata, "rating", NULL, 0);
 
-    duration = asf->duration + PREROLL_TIME * 10000;
-    has_title = tags[0] || tags[1] || tags[2] || tags[3] || tags[4];
+    duration       = asf->duration + PREROLL_TIME * 10000;
+    has_title      = tags[0] || tags[1] || tags[2] || tags[3] || tags[4];
     metadata_count = av_dict_count(s->metadata);
 
     bit_rate = 0;
-    for(n=0;n<s->nb_streams;n++) {
+    for (n = 0; n < s->nb_streams; n++) {
         enc = s->streams[n]->codec;
 
         avpriv_set_pts_info(s->streams[n], 32, 1, 1000); /* 32 bit pts in ms */
@@ -341,7 +335,7 @@
 
     /* file header */
     header_offset = avio_tell(pb);
-    hpos = put_header(pb, &ff_asf_file_header);
+    hpos          = put_header(pb, &ff_asf_file_header);
     ff_put_guid(pb, &ff_asf_my_guid);
     avio_wl64(pb, file_size);
     file_time = 0;
@@ -350,7 +344,7 @@
     avio_wl64(pb, duration); /* end time stamp (in 100ns units) */
     avio_wl64(pb, asf->duration); /* duration (in 100ns units) */
     avio_wl64(pb, PREROLL_TIME); /* start time stamp */
-    avio_wl32(pb, (asf->is_streamed || !pb->seekable ) ? 3 : 2); /* ??? */
+    avio_wl32(pb, (asf->is_streamed || !pb->seekable) ? 3 : 2);  /* ??? */
     avio_wl32(pb, s->packet_size); /* packet size */
     avio_wl32(pb, s->packet_size); /* packet size */
     avio_wl32(pb, bit_rate); /* Nominal data rate in bps */
@@ -396,26 +390,25 @@
     }
 
     /* stream headers */
-    for(n=0;n<s->nb_streams;n++) {
+    for (n = 0; n < s->nb_streams; n++) {
         int64_t es_pos;
         //        ASFStream *stream = &asf->streams[n];
 
-        enc = s->streams[n]->codec;
+        enc                 = s->streams[n]->codec;
         asf->streams[n].num = n + 1;
         asf->streams[n].seq = 1;
 
-
-        switch(enc->codec_type) {
+        switch (enc->codec_type) {
         case AVMEDIA_TYPE_AUDIO:
             wav_extra_size = 0;
-            extra_size = 18 + wav_extra_size;
-            extra_size2 = 8;
+            extra_size     = 18 + wav_extra_size;
+            extra_size2    = 8;
             break;
         default:
         case AVMEDIA_TYPE_VIDEO:
             wav_extra_size = enc->extradata_size;
-            extra_size = 0x33 + wav_extra_size;
-            extra_size2 = 0;
+            extra_size     = 0x33 + wav_extra_size;
+            extra_size2    = 0;
             break;
         }
 
@@ -448,10 +441,10 @@
             }
             /* ERROR Correction */
             avio_w8(pb, 0x01);
-            if(enc->codec_id == AV_CODEC_ID_ADPCM_G726 || !enc->block_align){
+            if (enc->codec_id == AV_CODEC_ID_ADPCM_G726 || !enc->block_align) {
                 avio_wl16(pb, 0x0190);
                 avio_wl16(pb, 0x0190);
-            }else{
+            } else {
                 avio_wl16(pb, enc->block_align);
                 avio_wl16(pb, enc->block_align);
             }
@@ -474,7 +467,7 @@
     hpos = put_header(pb, &ff_asf_codec_comment_header);
     ff_put_guid(pb, &ff_asf_codec_comment1_header);
     avio_wl32(pb, s->nb_streams);
-    for(n=0;n<s->nb_streams;n++) {
+    for (n = 0; n < s->nb_streams; n++) {
         AVCodec *p;
         const char *desc;
         int len;
@@ -482,21 +475,21 @@
         AVIOContext *dyn_buf;
 
         enc = s->streams[n]->codec;
-        p = avcodec_find_encoder(enc->codec_id);
+        p   = avcodec_find_encoder(enc->codec_id);
 
-        if(enc->codec_type == AVMEDIA_TYPE_AUDIO)
+        if (enc->codec_type == AVMEDIA_TYPE_AUDIO)
             avio_wl16(pb, 2);
-        else if(enc->codec_type == AVMEDIA_TYPE_VIDEO)
+        else if (enc->codec_type == AVMEDIA_TYPE_VIDEO)
             avio_wl16(pb, 1);
         else
             avio_wl16(pb, -1);
 
-        if(enc->codec_id == AV_CODEC_ID_WMAV2)
+        if (enc->codec_id == AV_CODEC_ID_WMAV2)
             desc = "Windows Media Audio V8";
         else
             desc = p ? p->name : enc->codec_name;
 
-        if ( avio_open_dyn_buf(&dyn_buf) < 0)
+        if (avio_open_dyn_buf(&dyn_buf) < 0)
             return AVERROR(ENOMEM);
 
         avio_put_str16le(dyn_buf, desc);
@@ -508,7 +501,6 @@
 
         avio_wl16(pb, 0); /* no parameters */
 
-
         /* id */
         if (enc->codec_type == AVMEDIA_TYPE_AUDIO) {
             avio_wl16(pb, 2);
@@ -517,14 +509,14 @@
             avio_wl16(pb, 4);
             avio_wl32(pb, enc->codec_tag);
         }
-        if(!enc->codec_tag)
+        if (!enc->codec_tag)
             return -1;
     }
     end_header(pb, hpos);
 
     /* patch the header size fields */
 
-    cur_pos = avio_tell(pb);
+    cur_pos     = avio_tell(pb);
     header_size = cur_pos - header_offset;
     if (asf->is_streamed) {
         header_size += 8 + 30 + 50;
@@ -559,9 +551,9 @@
     s->packet_size  = PACKET_SIZE;
     asf->nb_packets = 0;
 
-    asf->index_ptr = av_malloc( sizeof(ASFIndex) * ASF_INDEX_BLOCK );
+    asf->index_ptr             = av_malloc(sizeof(ASFIndex) * ASF_INDEX_BLOCK);
     asf->nb_index_memory_alloc = ASF_INDEX_BLOCK;
-    asf->maximum_packet = 0;
+    asf->maximum_packet        = 0;
 
     /* the data-chunk-size has to be 50, which is data_size - asf->data_offset
      *  at the moment this function is done. It is needed to use asf as
@@ -573,11 +565,11 @@
 
     avio_flush(s->pb);
 
-    asf->packet_nb_payloads = 0;
+    asf->packet_nb_payloads     = 0;
     asf->packet_timestamp_start = -1;
-    asf->packet_timestamp_end = -1;
+    asf->packet_timestamp_end   = -1;
     ffio_init_context(&asf->pb, asf->packet_buf, s->packet_size, 1,
-                  NULL, NULL, NULL, NULL);
+                      NULL, NULL, NULL, NULL);
 
     if (s->avoid_negative_ts < 0)
         s->avoid_negative_ts = 1;
@@ -594,30 +586,25 @@
     return asf_write_header(s);
 }
 
-static int put_payload_parsing_info(
-                                AVFormatContext *s,
-                                unsigned int    sendtime,
-                                unsigned int    duration,
-                                int             nb_payloads,
-                                int             padsize
-            )
+static int put_payload_parsing_info(AVFormatContext *s,
+                                    unsigned sendtime, unsigned duration,
+                                    int nb_payloads, int padsize)
 {
     ASFContext *asf = s->priv_data;
     AVIOContext *pb = s->pb;
     int ppi_size, i;
-    int64_t start= avio_tell(pb);
+    int64_t start = avio_tell(pb);
 
     int iLengthTypeFlags = ASF_PPI_LENGTH_TYPE_FLAGS;
 
     padsize -= PACKET_HEADER_MIN_SIZE;
-    if(asf->multi_payloads_present)
+    if (asf->multi_payloads_present)
         padsize--;
-    assert(padsize>=0);
+    assert(padsize >= 0);
 
     avio_w8(pb, ASF_PACKET_ERROR_CORRECTION_FLAGS);
-    for (i = 0; i < ASF_PACKET_ERROR_CORRECTION_DATA_SIZE; i++){
+    for (i = 0; i < ASF_PACKET_ERROR_CORRECTION_DATA_SIZE; i++)
         avio_w8(pb, 0x0);
-    }
 
     if (asf->multi_payloads_present)
         iLengthTypeFlags |= ASF_PPI_FLAG_MULTIPLE_PAYLOADS_PRESENT;
@@ -654,17 +641,14 @@
 
     assert(asf->packet_timestamp_end >= asf->packet_timestamp_start);
 
-    if (asf->is_streamed) {
+    if (asf->is_streamed)
         put_chunk(s, 0x4424, s->packet_size, 0);
-    }
 
-    packet_hdr_size = put_payload_parsing_info(
-                            s,
-                            asf->packet_timestamp_start,
-                            asf->packet_timestamp_end - asf->packet_timestamp_start,
-                            asf->packet_nb_payloads,
-                            asf->packet_size_left
-                        );
+    packet_hdr_size = put_payload_parsing_info(s,
+                                               asf->packet_timestamp_start,
+                                               asf->packet_timestamp_end - asf->packet_timestamp_start,
+                                               asf->packet_nb_payloads,
+                                               asf->packet_size_left);
 
     packet_filled_size = PACKET_SIZE - asf->packet_size_left;
     assert(packet_hdr_size <= asf->packet_size_left);
@@ -674,22 +658,16 @@
 
     avio_flush(s->pb);
     asf->nb_packets++;
-    asf->packet_nb_payloads = 0;
+    asf->packet_nb_payloads     = 0;
     asf->packet_timestamp_start = -1;
-    asf->packet_timestamp_end = -1;
+    asf->packet_timestamp_end   = -1;
     ffio_init_context(&asf->pb, asf->packet_buf, s->packet_size, 1,
-                  NULL, NULL, NULL, NULL);
+                      NULL, NULL, NULL, NULL);
 }
 
-static void put_payload_header(
-                                AVFormatContext *s,
-                                ASFStream       *stream,
-                                int64_t         presentation_time,
-                                int             m_obj_size,
-                                int             m_obj_offset,
-                                int             payload_len,
-                                int             flags
-            )
+static void put_payload_header(AVFormatContext *s, ASFStream *stream,
+                               int64_t presentation_time, int m_obj_size,
+                               int m_obj_offset, int payload_len, int flags)
 {
     ASFContext *asf = s->priv_data;
     AVIOContext *pb = &asf->pb;
@@ -700,8 +678,8 @@
         val |= ASF_PL_FLAG_KEY_FRAME;
     avio_w8(pb, val);
 
-    avio_w8(pb, stream->seq);  //Media object number
-    avio_wl32(pb, m_obj_offset); //Offset Into Media Object
+    avio_w8(pb, stream->seq);     // Media object number
+    avio_wl32(pb, m_obj_offset);  // Offset Into Media Object
 
     // Replicated Data shall be at least 8 bytes long.
     // The first 4 bytes of data shall contain the
@@ -710,23 +688,17 @@
     // Presentation Time for the media object that the payload belongs to.
     avio_w8(pb, ASF_PAYLOAD_REPLICATED_DATA_LENGTH);
 
-    avio_wl32(pb, m_obj_size);       //Replicated Data - Media Object Size
-    avio_wl32(pb, (uint32_t) presentation_time);//Replicated Data - Presentation Time
+    avio_wl32(pb, m_obj_size);        // Replicated Data - Media Object Size
+    avio_wl32(pb, (uint32_t) presentation_time); // Replicated Data - Presentation Time
 
-    if (asf->multi_payloads_present){
-        avio_wl16(pb, payload_len);   //payload length
+    if (asf->multi_payloads_present) {
+        avio_wl16(pb, payload_len);   // payload length
     }
 }
 
-static void put_frame(
-                    AVFormatContext *s,
-                    ASFStream       *stream,
-                    AVStream        *avst,
-                    int64_t         timestamp,
-                    const uint8_t   *buf,
-                    int             m_obj_size,
-                    int             flags
-                )
+static void put_frame(AVFormatContext *s, ASFStream *stream, AVStream *avst,
+                      int64_t timestamp, const uint8_t *buf,
+                      int m_obj_size, int flags)
 {
     ASFContext *asf = s->priv_data;
     int m_obj_offset, payload_len, frag_len1;
@@ -738,19 +710,20 @@
             asf->multi_payloads_present = (payload_len < MULTI_PAYLOAD_CONSTANT);
 
             asf->packet_size_left = PACKET_SIZE;
-            if (asf->multi_payloads_present){
+            if (asf->multi_payloads_present) {
                 frag_len1 = MULTI_PAYLOAD_CONSTANT - 1;
-            }
-            else {
+            } else {
                 frag_len1 = SINGLE_PAYLOAD_DATA_LENGTH;
             }
             asf->packet_timestamp_start = timestamp;
-        }
-        else {
+        } else {
             // multi payloads
-            frag_len1 = asf->packet_size_left - PAYLOAD_HEADER_SIZE_MULTIPLE_PAYLOADS - PACKET_HEADER_MIN_SIZE - 1;
+            frag_len1 = asf->packet_size_left -
+                        PAYLOAD_HEADER_SIZE_MULTIPLE_PAYLOADS -
+                        PACKET_HEADER_MIN_SIZE - 1;
 
-            if(frag_len1 < payload_len && avst->codec->codec_type == AVMEDIA_TYPE_AUDIO){
+            if (frag_len1 < payload_len &&
+                avst->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
                 flush_packet(s);
                 continue;
             }
@@ -759,9 +732,10 @@
             if (payload_len > frag_len1)
                 payload_len = frag_len1;
             else if (payload_len == (frag_len1 - 1))
-                payload_len = frag_len1 - 2;  //additional byte need to put padding length
+                payload_len = frag_len1 - 2;  // additional byte need to put padding length
 
-            put_payload_header(s, stream, timestamp+PREROLL_TIME, m_obj_size, m_obj_offset, payload_len, flags);
+            put_payload_header(s, stream, timestamp + PREROLL_TIME,
+                               m_obj_size, m_obj_offset, payload_len, flags);
             avio_write(&asf->pb, buf, payload_len);
 
             if (asf->multi_payloads_present)
@@ -775,7 +749,7 @@
             payload_len = 0;
         }
         m_obj_offset += payload_len;
-        buf += payload_len;
+        buf          += payload_len;
 
         if (!asf->multi_payloads_present)
             flush_packet(s);
@@ -821,21 +795,22 @@
     uint32_t packet_number;
     int64_t pts;
     int start_sec;
-    int flags= pkt->flags;
+    int flags = pkt->flags;
 
-    codec = s->streams[pkt->stream_index]->codec;
+    codec  = s->streams[pkt->stream_index]->codec;
     stream = &asf->streams[pkt->stream_index];
 
-    if(codec->codec_type == AVMEDIA_TYPE_AUDIO)
+    if (codec->codec_type == AVMEDIA_TYPE_AUDIO)
         flags &= ~AV_PKT_FLAG_KEY;
 
     pts = (pkt->pts != AV_NOPTS_VALUE) ? pkt->pts : pkt->dts;
     assert(pts != AV_NOPTS_VALUE);
     pts *= 10000;
-    asf->duration= FFMAX(asf->duration, pts + pkt->duration * 10000);
+    asf->duration = FFMAX(asf->duration, pts + pkt->duration * 10000);
 
     packet_number = asf->nb_packets;
-    put_frame(s, stream, s->streams[pkt->stream_index], pkt->dts, pkt->data, pkt->size, flags);
+    put_frame(s, stream, s->streams[pkt->stream_index],
+              pkt->dts, pkt->data, pkt->size, flags);
 
     start_sec = (int)((PREROLL_TIME * 10000 + pts + ASF_INDEXED_INTERVAL - 1)
               / ASF_INDEXED_INTERVAL);
@@ -850,19 +825,19 @@
     return 0;
 }
 
-//
-static int asf_write_index(AVFormatContext *s, ASFIndex *index, uint16_t max, uint32_t count)
+static int asf_write_index(AVFormatContext *s, ASFIndex *index,
+                           uint16_t max, uint32_t count)
 {
     AVIOContext *pb = s->pb;
     int i;
 
     ff_put_guid(pb, &ff_asf_simple_index_header);
-    avio_wl64(pb, 24 + 16 + 8 + 4 + 4 + (4 + 2)*count);
+    avio_wl64(pb, 24 + 16 + 8 + 4 + 4 + (4 + 2) * count);
     ff_put_guid(pb, &ff_asf_my_guid);
     avio_wl64(pb, ASF_INDEXED_INTERVAL);
     avio_wl32(pb, max);
     avio_wl32(pb, count);
-    for(i=0; i<count; i++) {
+    for (i = 0; i < count; i++) {
         avio_wl32(pb, index[i].packet_number);
         avio_wl16(pb, index[i].packet_count);
     }
@@ -873,7 +848,7 @@
 static int asf_write_trailer(AVFormatContext *s)
 {
     ASFContext *asf = s->priv_data;
-    int64_t file_size,data_size;
+    int64_t file_size, data_size;
 
     /* flush the current packet */
     if (asf->pb.buf_ptr > asf->pb.buffer)
@@ -913,11 +888,11 @@
     .write_packet   = asf_write_packet,
     .write_trailer  = asf_write_trailer,
     .flags          = AVFMT_GLOBALHEADER,
-    .codec_tag      = (const AVCodecTag* const []){
+    .codec_tag      = (const AVCodecTag * const []) {
         codec_asf_bmp_tags, ff_codec_bmp_tags, ff_codec_wav_tags, 0
     },
 };
-#endif
+#endif /* CONFIG_ASF_MUXER */
 
 #if CONFIG_ASF_STREAM_MUXER
 AVOutputFormat ff_asf_stream_muxer = {
@@ -932,8 +907,8 @@
     .write_packet   = asf_write_packet,
     .write_trailer  = asf_write_trailer,
     .flags          = AVFMT_GLOBALHEADER,
-    .codec_tag      = (const AVCodecTag* const []){
+    .codec_tag      = (const AVCodecTag * const []) {
         codec_asf_bmp_tags, ff_codec_bmp_tags, ff_codec_wav_tags, 0
     },
 };
-#endif //CONFIG_ASF_STREAM_MUXER
+#endif /* CONFIG_ASF_STREAM_MUXER */
diff --git a/libavformat/assdec.c b/libavformat/assdec.c
index 6c4614e..35fcb51 100644
--- a/libavformat/assdec.c
+++ b/libavformat/assdec.c
@@ -22,6 +22,7 @@
 #include "avformat.h"
 #include "internal.h"
 #include "subtitles.h"
+#include "libavcodec/internal.h"
 #include "libavutil/bprint.h"
 
 typedef struct ASSContext{
@@ -132,12 +133,9 @@
 
     av_bprint_finalize(&line, NULL);
 
-    av_bprint_finalize(&header, (char **)&st->codec->extradata);
-    if (!st->codec->extradata) {
-        res = AVERROR(ENOMEM);
+    res = avpriv_bprint_to_extradata(st->codec, &header);
+    if (res < 0)
         goto end;
-    }
-    st->codec->extradata_size = header.len + 1;
 
     ff_subtitles_queue_finalize(&ass->q);
 
diff --git a/libavformat/ast.c b/libavformat/ast.c
index 5f69f47..9de74aa 100644
--- a/libavformat/ast.c
+++ b/libavformat/ast.c
@@ -1,6 +1,6 @@
 /*
- * AST demuxer
- * Copyright (c) 2012 Paul B Mahol
+ * AST common code
+ * Copyright (c) 2012 James Almer
  *
  * This file is part of FFmpeg.
  *
@@ -19,109 +19,11 @@
  * 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 ast_probe(AVProbeData *p)
-{
-    if (AV_RL32(p->buf) == MKTAG('S','T','R','M') &&
-        AV_RB16(p->buf + 10) &&
-        AV_RB16(p->buf + 12) &&
-        AV_RB32(p->buf + 16))
-        return AVPROBE_SCORE_MAX / 3 * 2;
-    return 0;
-}
-
-static int ast_read_header(AVFormatContext *s)
-{
-    int codec, depth;
-    AVStream *st;
-
-    st = avformat_new_stream(s, NULL);
-    if (!st)
-        return AVERROR(ENOMEM);
-
-    avio_skip(s->pb, 8);
-    codec = avio_rb16(s->pb);
-    switch (codec) {
-    case 0:
-        st->codec->codec_id = AV_CODEC_ID_ADPCM_AFC;
-        break;
-    case 1:
-        st->codec->codec_id = AV_CODEC_ID_PCM_S16BE_PLANAR;
-        break;
-    default:
-        av_log(s, AV_LOG_ERROR, "unsupported codec %d\n", codec);
-    }
-
-    depth = avio_rb16(s->pb);
-    if (depth != 16) {
-        av_log_ask_for_sample(s, "unsupported depth %d\n", depth);
-        return AVERROR_INVALIDDATA;
-    }
-
-    st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
-    st->codec->channels = avio_rb16(s->pb);
-    if (!st->codec->channels)
-        return AVERROR_INVALIDDATA;
-
-    if (st->codec->channels == 2)
-        st->codec->channel_layout = AV_CH_LAYOUT_STEREO;
-    else if (st->codec->channels == 4)
-        st->codec->channel_layout = AV_CH_LAYOUT_4POINT0;
-
-    avio_skip(s->pb, 2);
-    st->codec->sample_rate = avio_rb32(s->pb);
-    if (st->codec->sample_rate <= 0)
-        return AVERROR_INVALIDDATA;
-    st->start_time         = 0;
-    st->duration           = avio_rb32(s->pb);
-    avio_skip(s->pb, 40);
-    avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
-
-    return 0;
-}
-
-static int ast_read_packet(AVFormatContext *s, AVPacket *pkt)
-{
-    uint32_t type, size;
-    int64_t pos;
-    int ret;
-
-    if (url_feof(s->pb))
-        return AVERROR_EOF;
-
-    pos  = avio_tell(s->pb);
-    type = avio_rl32(s->pb);
-    size = avio_rb32(s->pb);
-    if (size > INT_MAX / s->streams[0]->codec->channels)
-        return AVERROR_INVALIDDATA;
-
-    size *= s->streams[0]->codec->channels;
-    if ((ret = avio_skip(s->pb, 24)) < 0) // padding
-        return ret;
-
-    if (type == MKTAG('B','L','C','K')) {
-        ret = av_get_packet(s->pb, pkt, size);
-        pkt->stream_index = 0;
-        pkt->pos = pos;
-    } else {
-        av_log(s, AV_LOG_ERROR, "unknown chunk %x\n", type);
-        avio_skip(s->pb, size);
-        ret = AVERROR_INVALIDDATA;
-    }
-
-    return ret;
-}
-
-AVInputFormat ff_ast_demuxer = {
-    .name           = "ast",
-    .long_name      = NULL_IF_CONFIG_SMALL("AST (Audio Stream)"),
-    .read_probe     = ast_probe,
-    .read_header    = ast_read_header,
-    .read_packet    = ast_read_packet,
-    .extensions     = "ast",
-    .flags          = AVFMT_GENERIC_INDEX,
+const AVCodecTag ff_codec_ast_tags[] = {
+    { AV_CODEC_ID_ADPCM_AFC,          0 },
+    { AV_CODEC_ID_PCM_S16BE_PLANAR,   1 },
+    { AV_CODEC_ID_NONE,               0 },
 };
diff --git a/libavcodec/arm/dsputil_init_vfp.c b/libavformat/ast.h
similarity index 66%
copy from libavcodec/arm/dsputil_init_vfp.c
copy to libavformat/ast.h
index 5713c71..4a399ea 100644
--- a/libavcodec/arm/dsputil_init_vfp.c
+++ b/libavformat/ast.h
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2008 Siarhei Siamashka <ssvb@users.sourceforge.net>
+ * AST common code
+ * Copyright (c) 2012 James Almer
  *
  * This file is part of FFmpeg.
  *
@@ -18,13 +19,12 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavcodec/dsputil.h"
-#include "dsputil_arm.h"
+#ifndef AVFORMAT_AST_H
+#define AVFORMAT_AST_H
 
-void ff_vector_fmul_reverse_vfp(float *dst, const float *src0,
-                                const float *src1, int len);
+#include "avformat.h"
+#include "internal.h"
 
-void ff_dsputil_init_vfp(DSPContext* c, AVCodecContext *avctx)
-{
-    c->vector_fmul_reverse = ff_vector_fmul_reverse_vfp;
-}
+extern const AVCodecTag ff_codec_ast_tags[];
+
+#endif /* AVFORMAT_AST_H */
diff --git a/libavformat/astdec.c b/libavformat/astdec.c
new file mode 100644
index 0000000..fb5a34f
--- /dev/null
+++ b/libavformat/astdec.c
@@ -0,0 +1,119 @@
+/*
+ * AST demuxer
+ * 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/channel_layout.h"
+#include "libavutil/intreadwrite.h"
+#include "avformat.h"
+#include "internal.h"
+#include "ast.h"
+
+static int ast_probe(AVProbeData *p)
+{
+    if (AV_RL32(p->buf) == MKTAG('S','T','R','M') &&
+        AV_RB16(p->buf + 10) &&
+        AV_RB16(p->buf + 12) &&
+        AV_RB32(p->buf + 16))
+        return AVPROBE_SCORE_MAX / 3 * 2;
+    return 0;
+}
+
+static int ast_read_header(AVFormatContext *s)
+{
+    int depth;
+    AVStream *st;
+
+    st = avformat_new_stream(s, NULL);
+    if (!st)
+        return AVERROR(ENOMEM);
+
+    avio_skip(s->pb, 8);
+    st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+    st->codec->codec_id   = ff_codec_get_id(ff_codec_ast_tags, avio_rb16(s->pb));
+
+    depth = avio_rb16(s->pb);
+    if (depth != 16) {
+        av_log_ask_for_sample(s, "unsupported depth %d\n", depth);
+        return AVERROR_INVALIDDATA;
+    }
+
+    st->codec->channels = avio_rb16(s->pb);
+    if (!st->codec->channels)
+        return AVERROR_INVALIDDATA;
+
+    if (st->codec->channels == 2)
+        st->codec->channel_layout = AV_CH_LAYOUT_STEREO;
+    else if (st->codec->channels == 4)
+        st->codec->channel_layout = AV_CH_LAYOUT_4POINT0;
+
+    avio_skip(s->pb, 2);
+    st->codec->sample_rate = avio_rb32(s->pb);
+    if (st->codec->sample_rate <= 0)
+        return AVERROR_INVALIDDATA;
+    st->start_time         = 0;
+    st->duration           = avio_rb32(s->pb);
+    avio_skip(s->pb, 40);
+    avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
+
+    return 0;
+}
+
+static int ast_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    uint32_t type, size;
+    int64_t pos;
+    int ret;
+
+    if (url_feof(s->pb))
+        return AVERROR_EOF;
+
+    pos  = avio_tell(s->pb);
+    type = avio_rl32(s->pb);
+    size = avio_rb32(s->pb);
+    if (size > INT_MAX / s->streams[0]->codec->channels)
+        return AVERROR_INVALIDDATA;
+
+    size *= s->streams[0]->codec->channels;
+    if ((ret = avio_skip(s->pb, 24)) < 0) // padding
+        return ret;
+
+    if (type == MKTAG('B','L','C','K')) {
+        ret = av_get_packet(s->pb, pkt, size);
+        pkt->stream_index = 0;
+        pkt->pos = pos;
+    } else {
+        av_log(s, AV_LOG_ERROR, "unknown chunk %x\n", type);
+        avio_skip(s->pb, size);
+        ret = AVERROR_INVALIDDATA;
+    }
+
+    return ret;
+}
+
+AVInputFormat ff_ast_demuxer = {
+    .name           = "ast",
+    .long_name      = NULL_IF_CONFIG_SMALL("AST (Audio Stream)"),
+    .read_probe     = ast_probe,
+    .read_header    = ast_read_header,
+    .read_packet    = ast_read_packet,
+    .extensions     = "ast",
+    .flags          = AVFMT_GENERIC_INDEX,
+    .codec_tag      = (const AVCodecTag* const []){ff_codec_ast_tags, 0},
+};
diff --git a/libavformat/astenc.c b/libavformat/astenc.c
new file mode 100644
index 0000000..edd802c
--- /dev/null
+++ b/libavformat/astenc.c
@@ -0,0 +1,214 @@
+/*
+ * AST muxer
+ * Copyright (c) 2012 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 "avformat.h"
+#include "avio_internal.h"
+#include "internal.h"
+#include "ast.h"
+#include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
+
+typedef struct ASTMuxContext {
+    AVClass *class;
+    int64_t  size;
+    int64_t  samples;
+    int64_t  loopstart;
+    int64_t  loopend;
+    int      fbs;
+} ASTMuxContext;
+
+#define CHECK_LOOP(type) \
+    if (ast->loop ## type > 0) { \
+        ast->loop ## type = av_rescale_rnd(ast->loop ## type, enc->sample_rate, 1000, AV_ROUND_DOWN); \
+        if (ast->loop ## type < 0 || ast->loop ## type > UINT_MAX) { \
+            av_log(s, AV_LOG_ERROR, "Invalid loop" #type " value\n"); \
+            return AVERROR(EINVAL);  \
+        } \
+    }
+
+static int ast_write_header(AVFormatContext *s)
+{
+    ASTMuxContext *ast = s->priv_data;
+    AVIOContext *pb = s->pb;
+    AVCodecContext *enc;
+    unsigned int codec_tag;
+
+    if (s->nb_streams == 1) {
+        enc = s->streams[0]->codec;
+    } else {
+        av_log(s, AV_LOG_ERROR, "only one stream is supported\n");
+        return AVERROR(EINVAL);
+    }
+
+    if (enc->codec_id == AV_CODEC_ID_ADPCM_AFC) {
+        av_log(s, AV_LOG_ERROR, "muxing ADPCM AFC is not implemented\n");
+        return AVERROR_PATCHWELCOME;
+    }
+
+    codec_tag = ff_codec_get_tag(ff_codec_ast_tags, enc->codec_id);
+    if (!codec_tag) {
+        av_log(s, AV_LOG_ERROR, "unsupported codec\n");
+        return AVERROR(EINVAL);
+    }
+
+    if (ast->loopend > 0 && ast->loopstart >= ast->loopend) {
+        av_log(s, AV_LOG_ERROR, "loopend can't be less or equal to loopstart\n");
+        return AVERROR(EINVAL);
+    }
+
+    /* Convert milliseconds to samples */
+    CHECK_LOOP(start)
+    CHECK_LOOP(end)
+
+    ffio_wfourcc(pb, "STRM");
+
+    ast->size = avio_tell(pb);
+    avio_wb32(pb, 0); /* File size minus header */
+    avio_wb16(pb, codec_tag);
+    avio_wb16(pb, 16); /* Bit depth */
+    avio_wb16(pb, enc->channels);
+    avio_wb16(pb, 0); /* Loop flag */
+    avio_wb32(pb, enc->sample_rate);
+
+    ast->samples = avio_tell(pb);
+    avio_wb32(pb, 0); /* Number of samples */
+    avio_wb32(pb, 0); /* Loopstart */
+    avio_wb32(pb, 0); /* Loopend */
+    avio_wb32(pb, 0); /* Size of first block */
+
+    /* Unknown */
+    avio_wb32(pb, 0);
+    avio_wl32(pb, 0x7F);
+    avio_wb64(pb, 0);
+    avio_wb64(pb, 0);
+    avio_wb32(pb, 0);
+
+    avio_flush(pb);
+
+    return 0;
+}
+
+static int ast_write_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    AVIOContext *pb = s->pb;
+    ASTMuxContext *ast = s->priv_data;
+    AVCodecContext *enc = s->streams[0]->codec;
+    int size = pkt->size / enc->channels;
+
+    if (enc->frame_number == 1)
+        ast->fbs = size;
+
+    ffio_wfourcc(pb, "BLCK");
+    avio_wb32(pb, size); /* Block size */
+
+    /* padding */
+    avio_wb64(pb, 0);
+    avio_wb64(pb, 0);
+    avio_wb64(pb, 0);
+
+    avio_write(pb, pkt->data, pkt->size);
+
+    return 0;
+}
+
+static int ast_write_trailer(AVFormatContext *s)
+{
+    AVIOContext *pb = s->pb;
+    ASTMuxContext *ast = s->priv_data;
+    AVCodecContext *enc = s->streams[0]->codec;
+    int64_t file_size = avio_tell(pb);
+    int64_t samples = (file_size - 64 - (32 * enc->frame_number)) / enc->block_align; /* PCM_S16BE_PLANAR */
+
+    av_log(s, AV_LOG_DEBUG, "total samples: %"PRId64"\n", samples);
+
+    if (s->pb->seekable) {
+        /* Number of samples */
+        avio_seek(pb, ast->samples, SEEK_SET);
+        avio_wb32(pb, samples);
+
+        /* Loopstart if provided */
+        if (ast->loopstart > 0) {
+        if (ast->loopstart >= samples) {
+            av_log(s, AV_LOG_WARNING, "Loopstart value is out of range and will be ignored\n");
+            ast->loopstart = -1;
+            avio_skip(pb, 4);
+        } else
+        avio_wb32(pb, ast->loopstart);
+        } else
+            avio_skip(pb, 4);
+
+        /* Loopend if provided. Otherwise number of samples again */
+        if (ast->loopend && ast->loopstart >= 0) {
+            if (ast->loopend > samples) {
+                av_log(s, AV_LOG_WARNING, "Loopend value is out of range and will be ignored\n");
+                ast->loopend = samples;
+            }
+            avio_wb32(pb, ast->loopend);
+        } else {
+            avio_wb32(pb, samples);
+        }
+
+        /* Size of first block */
+        avio_wb32(pb, ast->fbs);
+
+        /* File size minus header */
+        avio_seek(pb, ast->size, SEEK_SET);
+        avio_wb32(pb, file_size - 64);
+
+        /* Loop flag */
+        if (ast->loopstart >= 0) {
+            avio_skip(pb, 6);
+            avio_wb16(pb, 0xFFFF);
+        }
+
+        avio_seek(pb, file_size, SEEK_SET);
+        avio_flush(pb);
+    }
+    return 0;
+}
+
+#define OFFSET(obj) offsetof(ASTMuxContext, obj)
+static const AVOption options[] = {
+  { "loopstart", "Loopstart position in milliseconds.", OFFSET(loopstart), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
+  { "loopend",   "Loopend position in milliseconds.",   OFFSET(loopend),   AV_OPT_TYPE_INT64, { .i64 = 0 }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
+  { NULL },
+};
+
+static const AVClass ast_muxer_class = {
+    .class_name = "AST muxer",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+AVOutputFormat ff_ast_muxer = {
+    .name              = "ast",
+    .long_name         = NULL_IF_CONFIG_SMALL("AST (Audio Stream)"),
+    .extensions        = "ast",
+    .priv_data_size    = sizeof(ASTMuxContext),
+    .audio_codec       = AV_CODEC_ID_PCM_S16BE_PLANAR,
+    .video_codec       = AV_CODEC_ID_NONE,
+    .write_header      = ast_write_header,
+    .write_packet      = ast_write_packet,
+    .write_trailer     = ast_write_trailer,
+    .priv_class        = &ast_muxer_class,
+    .codec_tag         = (const AVCodecTag* const []){ff_codec_ast_tags, 0},
+};
diff --git a/libavformat/au.c b/libavformat/au.c
index 6797c3c..db2ab27 100644
--- a/libavformat/au.c
+++ b/libavformat/au.c
@@ -37,82 +37,23 @@
 /* the specification requires an annotation field of at least eight bytes */
 #define AU_HEADER_SIZE (24+8)
 
-/* The libavcodec codecs we support, and the IDs they have in the file */
 static const AVCodecTag codec_au_tags[] = {
-    { AV_CODEC_ID_PCM_MULAW, 1 },
-    { AV_CODEC_ID_PCM_S8, 2 },
-    { AV_CODEC_ID_PCM_S16BE, 3 },
-    { AV_CODEC_ID_PCM_S24BE, 4 },
-    { AV_CODEC_ID_PCM_S32BE, 5 },
-    { AV_CODEC_ID_PCM_F32BE, 6 },
-    { AV_CODEC_ID_PCM_F64BE, 7 },
-    { AV_CODEC_ID_ADPCM_G722, 24 },
-    { AV_CODEC_ID_PCM_ALAW, 27 },
-    { AV_CODEC_ID_NONE, 0 },
+    { AV_CODEC_ID_PCM_MULAW,  1 },
+    { AV_CODEC_ID_PCM_S8,     2 },
+    { AV_CODEC_ID_PCM_S16BE,  3 },
+    { AV_CODEC_ID_PCM_S24BE,  4 },
+    { AV_CODEC_ID_PCM_S32BE,  5 },
+    { AV_CODEC_ID_PCM_F32BE,  6 },
+    { AV_CODEC_ID_PCM_F64BE,  7 },
+    { AV_CODEC_ID_ADPCM_G722,24 },
+    { AV_CODEC_ID_PCM_ALAW,  27 },
+    { AV_CODEC_ID_NONE,       0 },
 };
 
-#if CONFIG_AU_MUXER
-/* AUDIO_FILE header */
-static int put_au_header(AVIOContext *pb, AVCodecContext *enc)
-{
-    if(!enc->codec_tag)
-        return -1;
-    ffio_wfourcc(pb, ".snd");    /* magic number */
-    avio_wb32(pb, AU_HEADER_SIZE);  /* header size */
-    avio_wb32(pb, AU_UNKNOWN_SIZE); /* data size */
-    avio_wb32(pb, (uint32_t)enc->codec_tag);     /* codec ID */
-    avio_wb32(pb, enc->sample_rate);
-    avio_wb32(pb, (uint32_t)enc->channels);
-    avio_wb64(pb, 0); /* annotation field */
-    return 0;
-}
-
-static int au_write_header(AVFormatContext *s)
-{
-    AVIOContext *pb = s->pb;
-
-    s->priv_data = NULL;
-
-    /* format header */
-    if (put_au_header(pb, s->streams[0]->codec) < 0) {
-        return -1;
-    }
-
-    avio_flush(pb);
-
-    return 0;
-}
-
-static int au_write_packet(AVFormatContext *s, AVPacket *pkt)
-{
-    AVIOContext *pb = s->pb;
-    avio_write(pb, pkt->data, pkt->size);
-    return 0;
-}
-
-static int au_write_trailer(AVFormatContext *s)
-{
-    AVIOContext *pb = s->pb;
-    int64_t file_size;
-
-    if (s->pb->seekable) {
-
-        /* update file size */
-        file_size = avio_tell(pb);
-        avio_seek(pb, 8, SEEK_SET);
-        avio_wb32(pb, (uint32_t)(file_size - AU_HEADER_SIZE));
-        avio_seek(pb, file_size, SEEK_SET);
-
-        avio_flush(pb);
-    }
-
-    return 0;
-}
-#endif /* CONFIG_AU_MUXER */
+#if CONFIG_AU_DEMUXER
 
 static int au_probe(AVProbeData *p)
 {
-    /* check file header */
     if (p->buf[0] == '.' && p->buf[1] == 's' &&
         p->buf[2] == 'n' && p->buf[3] == 'd')
         return AVPROBE_SCORE_MAX;
@@ -120,20 +61,21 @@
         return 0;
 }
 
-/* au input */
+#define BLOCK_SIZE 1024
+
 static int au_read_header(AVFormatContext *s)
 {
-    int size, bps, data_size = 0;
+    int size, data_size = 0;
     unsigned int tag;
     AVIOContext *pb = s->pb;
     unsigned int id, channels, rate;
+    int bps;
     enum AVCodecID codec;
     AVStream *st;
 
-    /* check ".snd" header */
     tag = avio_rl32(pb);
     if (tag != MKTAG('.', 's', 'n', 'd'))
-        return -1;
+        return AVERROR_INVALIDDATA;
     size = avio_rb32(pb); /* header size */
     data_size = avio_rb32(pb); /* data size in bytes */
 
@@ -142,85 +84,128 @@
         return AVERROR_INVALIDDATA;
     }
 
-    id = avio_rb32(pb);
-    rate = avio_rb32(pb);
+    id       = avio_rb32(pb);
+    rate     = avio_rb32(pb);
     channels = avio_rb32(pb);
 
-    codec = ff_codec_get_id(codec_au_tags, id);
-
-    if (!(bps = av_get_bits_per_sample(codec))) {
-        av_log_ask_for_sample(s, "could not determine bits per sample\n");
-        return AVERROR_INVALIDDATA;
-    }
-
-    if (channels == 0 || channels > 64) {
-        av_log(s, AV_LOG_ERROR, "Invalid number of channels %d\n", channels);
-        return AVERROR_INVALIDDATA;
-    }
-
-    if (size >= 24) {
+    if (size > 24) {
         /* skip unused data */
         avio_skip(pb, size - 24);
     }
 
-    /* now we are ready: build format streams */
+    codec = ff_codec_get_id(codec_au_tags, id);
+
+    if (codec == AV_CODEC_ID_NONE) {
+        av_log_ask_for_sample(s, "unknown or unsupported codec tag: %u\n", id);
+        return AVERROR_PATCHWELCOME;
+    }
+
+    bps = av_get_bits_per_sample(codec);
+    if (!bps) {
+        av_log_ask_for_sample(s, "could not determine bits per sample\n");
+        return AVERROR_PATCHWELCOME;
+    }
+
+    if (channels == 0 || channels >= INT_MAX / (BLOCK_SIZE * bps >> 3)) {
+        av_log(s, AV_LOG_ERROR, "Invalid number of channels %u\n", channels);
+        return AVERROR_INVALIDDATA;
+    }
+
+    if (rate == 0 || rate > INT_MAX) {
+        av_log(s, AV_LOG_ERROR, "Invalid sample rate: %u\n", rate);
+        return AVERROR_INVALIDDATA;
+    }
+
     st = avformat_new_stream(s, NULL);
     if (!st)
-        return -1;
-    st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
-    st->codec->codec_tag = id;
-    st->codec->codec_id = codec;
-    st->codec->channels = channels;
+        return AVERROR(ENOMEM);
+    st->codec->codec_type  = AVMEDIA_TYPE_AUDIO;
+    st->codec->codec_tag   = id;
+    st->codec->codec_id    = codec;
+    st->codec->channels    = channels;
     st->codec->sample_rate = rate;
+    st->codec->bit_rate    = channels * rate * bps;
+    st->codec->block_align = FFMAX(bps * st->codec->channels / 8, 1);
     if (data_size != AU_UNKNOWN_SIZE)
     st->duration = (((int64_t)data_size)<<3) / (st->codec->channels * (int64_t)bps);
+
+    st->start_time = 0;
     avpriv_set_pts_info(st, 64, 1, rate);
+
     return 0;
 }
 
-#define BLOCK_SIZE 1024
-
-static int au_read_packet(AVFormatContext *s,
-                          AVPacket *pkt)
-{
-    int ret;
-    int bpcs = av_get_bits_per_sample(s->streams[0]->codec->codec_id);
-
-    if (!bpcs)
-        return AVERROR(EINVAL);
-    ret= av_get_packet(s->pb, pkt, BLOCK_SIZE *
-                       s->streams[0]->codec->channels *
-                       bpcs >> 3);
-    if (ret < 0)
-        return ret;
-    pkt->flags &= ~AV_PKT_FLAG_CORRUPT;
-    pkt->stream_index = 0;
-    return 0;
-}
-
-#if CONFIG_AU_DEMUXER
 AVInputFormat ff_au_demuxer = {
-    .name           = "au",
-    .long_name      = NULL_IF_CONFIG_SMALL("Sun AU"),
-    .read_probe     = au_probe,
-    .read_header    = au_read_header,
-    .read_packet    = au_read_packet,
-    .read_seek      = ff_pcm_read_seek,
-    .codec_tag      = (const AVCodecTag* const []){ codec_au_tags, 0 },
+    .name        = "au",
+    .long_name   = NULL_IF_CONFIG_SMALL("Sun AU"),
+    .read_probe  = au_probe,
+    .read_header = au_read_header,
+    .read_packet = ff_pcm_read_packet,
+    .read_seek   = ff_pcm_read_seek,
+    .codec_tag   = (const AVCodecTag* const []) { codec_au_tags, 0 },
 };
-#endif
+
+#endif /* CONFIG_AU_DEMUXER */
 
 #if CONFIG_AU_MUXER
+
+#include "rawenc.h"
+
+static int au_write_header(AVFormatContext *s)
+{
+    AVIOContext *pb = s->pb;
+    AVCodecContext *enc = s->streams[0]->codec;
+
+    if (s->nb_streams != 1) {
+        av_log(s, AV_LOG_ERROR, "only one stream is supported\n");
+        return AVERROR(EINVAL);
+    }
+
+    enc->codec_tag = ff_codec_get_tag(codec_au_tags, enc->codec_id);
+    if (!enc->codec_tag) {
+        av_log(s, AV_LOG_ERROR, "unsupported codec\n");
+        return AVERROR(EINVAL);
+    }
+
+    ffio_wfourcc(pb, ".snd");                   /* magic number */
+    avio_wb32(pb, AU_HEADER_SIZE);              /* header size */
+    avio_wb32(pb, AU_UNKNOWN_SIZE);             /* data size */
+    avio_wb32(pb, enc->codec_tag);              /* codec ID */
+    avio_wb32(pb, enc->sample_rate);
+    avio_wb32(pb, enc->channels);
+    avio_wb64(pb, 0); /* annotation field */
+    avio_flush(pb);
+
+    return 0;
+}
+
+static int au_write_trailer(AVFormatContext *s)
+{
+    AVIOContext *pb = s->pb;
+    int64_t file_size = avio_tell(pb);
+
+    if (s->pb->seekable && file_size < INT32_MAX) {
+        /* update file size */
+        avio_seek(pb, 8, SEEK_SET);
+        avio_wb32(pb, (uint32_t)(file_size - AU_HEADER_SIZE));
+        avio_seek(pb, file_size, SEEK_SET);
+        avio_flush(pb);
+    }
+
+    return 0;
+}
+
 AVOutputFormat ff_au_muxer = {
-    .name              = "au",
-    .long_name         = NULL_IF_CONFIG_SMALL("Sun AU"),
-    .mime_type         = "audio/basic",
-    .extensions        = "au",
-    .audio_codec       = AV_CODEC_ID_PCM_S16BE,
-    .video_codec       = AV_CODEC_ID_NONE,
-    .write_header      = au_write_header,
-    .write_packet      = au_write_packet,
-    .write_trailer     = au_write_trailer,
-    .codec_tag         = (const AVCodecTag* const []){ codec_au_tags, 0 },
+    .name          = "au",
+    .long_name     = NULL_IF_CONFIG_SMALL("Sun AU"),
+    .mime_type     = "audio/basic",
+    .extensions    = "au",
+    .audio_codec   = AV_CODEC_ID_PCM_S16BE,
+    .video_codec   = AV_CODEC_ID_NONE,
+    .write_header  = au_write_header,
+    .write_packet  = ff_raw_write_packet,
+    .write_trailer = au_write_trailer,
+    .codec_tag     = (const AVCodecTag* const []) { codec_au_tags, 0 },
 };
-#endif //CONFIG_AU_MUXER
+
+#endif /* CONFIG_AU_MUXER */
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 4b916cc..9b72279 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -630,6 +630,13 @@
 #define AV_DISPOSITION_ATTACHED_PIC      0x0400
 
 /**
+ * Options for behavior on timestamp wrap detection.
+ */
+#define AV_PTS_WRAP_IGNORE      0   ///< ignore the wrap
+#define AV_PTS_WRAP_ADD_OFFSET  1   ///< add the format specific offset on wrap detection
+#define AV_PTS_WRAP_SUB_OFFSET  -1  ///< subtract the format specific offset on wrap detection
+
+/**
  * Stream structure.
  * New fields can be added to the end with minor version bumps.
  * Removal, reordering and changes to existing fields require a major
@@ -747,7 +754,7 @@
         int64_t last_dts;
         int64_t duration_gcd;
         int duration_count;
-        double duration_error[2][2][MAX_STD_TIMEBASES];
+        double (*duration_error)[2][MAX_STD_TIMEBASES];
         int64_t codec_info_duration;
         int64_t codec_info_duration_fields;
         int found_decoder;
@@ -837,7 +844,7 @@
 
     /**
      * Number of internally decoded frames, used internally in libavformat, do not access
-     * its lifetime differs from info which is why its not in that structure.
+     * its lifetime differs from info which is why it is not in that structure.
      */
     int nb_decoded_frames;
 
@@ -847,6 +854,23 @@
      */
     int64_t mux_ts_offset;
 
+    /**
+     * Internal data to check for wrapping of the time stamp
+     */
+    int64_t pts_wrap_reference;
+
+    /**
+     * Options for behavior, when a wrap is detected.
+     *
+     * Defined by AV_PTS_WRAP_ values.
+     *
+     * If correction is enabled, there are two possibilities:
+     * If the first time stamp is near the wrap point, the wrap offset
+     * will be subtracted, which will create negative time stamps.
+     * Otherwise the offset will be added.
+     */
+    int pts_wrap_behavior;
+
 } AVStream;
 
 #define AV_PROGRAM_RUNNING 1
@@ -878,6 +902,9 @@
      */
     int64_t start_time;
     int64_t end_time;
+
+    int64_t pts_wrap_reference;    ///< reference dts for wrap detection
+    int pts_wrap_behavior;         ///< behavior on wrap detection
 } AVProgram;
 
 #define AVFMTCTX_NOHEADER      0x0001 /**< signal that no header is present
@@ -1169,6 +1196,20 @@
      */
     unsigned int skip_initial_bytes;
 
+    /**
+     * Correct single timestamp overflows
+     * - encoding: unused
+     * - decoding: Set by user via AVOPtions (NO direct access)
+     */
+    unsigned int correct_ts_overflow;
+
+    /**
+     * Force seeking to any (also non key) frames.
+     * - encoding: unused
+     * - decoding: Set by user via AVOPtions (NO direct access)
+     */
+    int seek2any;
+
     /*****************************************************************
      * 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
@@ -1252,7 +1293,6 @@
  *
  * @see av_register_input_format()
  * @see av_register_output_format()
- * @see av_register_protocol()
  */
 void av_register_all(void);
 
@@ -1897,6 +1937,18 @@
  */
 unsigned int av_codec_get_tag(const struct AVCodecTag * const *tags, enum AVCodecID id);
 
+/**
+ * Get the codec tag for the given codec id.
+ *
+ * @param tags list of supported codec_id - codec_tag pairs, as stored
+ * in AVInputFormat.codec_tag and AVOutputFormat.codec_tag
+ * @param id codec id that should be searched for in the list
+ * @param tag A pointer to the found tag
+ * @return 0 if id was not found in tags, > 0 if it was found
+ */
+int av_codec_get_tag2(const struct AVCodecTag * const *tags, enum AVCodecID id,
+                      unsigned int *tag);
+
 int av_find_default_stream_index(AVFormatContext *s);
 
 /**
diff --git a/libavformat/avidec.c b/libavformat/avidec.c
index 974071c..00ac3de 100644
--- a/libavformat/avidec.c
+++ b/libavformat/avidec.c
@@ -140,7 +140,7 @@
         if(!memcmp(header, avi_headers[i], 8))
             break;
     if(!avi_headers[i][0])
-        return -1;
+        return AVERROR_INVALIDDATA;
 
     if(header[7] == 0x19)
         av_log(s, AV_LOG_INFO, "This file has been generated by a totally broken muxer.\n");
@@ -168,26 +168,26 @@
             longs_pre_entry,index_type, entries_in_use, chunk_id, base);
 
     if(stream_id >= s->nb_streams || stream_id < 0)
-        return -1;
+        return AVERROR_INVALIDDATA;
     st= s->streams[stream_id];
     ast = st->priv_data;
 
     if(index_sub_type)
-        return -1;
+        return AVERROR_INVALIDDATA;
 
     avio_rl32(pb);
 
     if(index_type && longs_pre_entry != 2)
-        return -1;
+        return AVERROR_INVALIDDATA;
     if(index_type>1)
-        return -1;
+        return AVERROR_INVALIDDATA;
 
     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)
             base &= 0xFFFFFFFF;
         else
-            return -1;
+            return AVERROR_INVALIDDATA;
     }
 
     for(i=0; i<entries_in_use; i++){
@@ -201,7 +201,7 @@
             av_log(s, AV_LOG_ERROR, "pos:%"PRId64", len:%X\n", pos, len);
 #endif
             if(url_feof(pb))
-                return -1;
+                return AVERROR_INVALIDDATA;
 
             if(last_pos == pos || pos == base - 8)
                 avi->non_interleaved= 1;
@@ -218,13 +218,13 @@
             duration = avio_rl32(pb);
 
             if(url_feof(pb))
-                return -1;
+                return AVERROR_INVALIDDATA;
 
             pos = avio_tell(pb);
 
             if(avi->odml_depth > MAX_ODML_DEPTH){
                 av_log(s, AV_LOG_ERROR, "Too deeply nested ODML indexes\n");
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
 
             if(avio_seek(pb, offset+8, SEEK_SET) < 0)
@@ -279,10 +279,10 @@
     size += (size & 1);
 
     if (size == UINT_MAX)
-        return -1;
+        return AVERROR(EINVAL);
     value = av_malloc(size+1);
     if (!value)
-        return -1;
+        return AVERROR(ENOMEM);
     avio_read(pb, value, size);
     value[size]=0;
 
@@ -367,8 +367,9 @@
 
     avi->stream_index= -1;
 
-    if (get_riff(s, pb) < 0)
-        return -1;
+    ret = get_riff(s, pb);
+    if (ret < 0)
+        return ret;
 
     av_log(avi, AV_LOG_DEBUG, "use odml:%d\n", avi->use_odml);
 
@@ -483,6 +484,8 @@
                 ast = s->streams[0]->priv_data;
                 av_freep(&s->streams[0]->codec->extradata);
                 av_freep(&s->streams[0]->codec);
+                if (s->streams[0]->info)
+                    av_freep(&s->streams[0]->info->duration_error);
                 av_freep(&s->streams[0]->info);
                 av_freep(&s->streams[0]);
                 s->nb_streams = 0;
@@ -761,7 +764,9 @@
             break;
         case MKTAG('s', 't', 'r', 'n'):
             if(s->nb_streams){
-                avi_read_tag(s, s->streams[s->nb_streams-1], tag, size);
+                ret = avi_read_tag(s, s->streams[s->nb_streams-1], tag, size);
+                if (ret < 0)
+                    return ret;
                 break;
             }
         default:
@@ -784,7 +789,7 @@
     /* check stream number */
     if (stream_index != s->nb_streams - 1) {
     fail:
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     if(!avi->index_loaded && pb->seekable)
@@ -817,7 +822,7 @@
 }
 
 static int read_gab2_sub(AVStream *st, AVPacket *pkt) {
-    if (!strcmp(pkt->data, "GAB2") && AV_RL16(pkt->data+5) == 2) {
+    if (pkt->data && !strcmp(pkt->data, "GAB2") && AV_RL16(pkt->data+5) == 2) {
         uint8_t desc[256];
         int score = AVPROBE_SCORE_MAX / 2, ret;
         AVIStream *ast = st->priv_data;
@@ -1262,7 +1267,7 @@
 
     nb_index_entries = size / 16;
     if (nb_index_entries <= 0)
-        return -1;
+        return AVERROR_INVALIDDATA;
 
     idx1_pos = avio_tell(pb);
     avio_seek(pb, avi->movi_list+4, SEEK_SET);
@@ -1304,7 +1309,6 @@
 
         av_dlog(s, "%d cum_len=%"PRId64"\n", len, ast->cum_len);
 
-
         // even if we have only a single stream, we should
         // switch to non-interleaved to get correct timestamps
         if(last_pos == pos)
@@ -1465,7 +1469,7 @@
                    timestamp * FFMAX(ast->sample_size, 1),
                    st->index_entries[0].timestamp,
                    st->index_entries[st->nb_index_entries - 1].timestamp);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     /* find the position */
diff --git a/libavformat/avio.c b/libavformat/avio.c
index 6d8a8bb..f6af0cb 100644
--- a/libavformat/avio.c
+++ b/libavformat/avio.c
@@ -119,6 +119,16 @@
     if (up->flags & URL_PROTOCOL_FLAG_NETWORK && !ff_network_init())
         return AVERROR(EIO);
 #endif
+    if ((flags & AVIO_FLAG_READ) && !up->url_read) {
+        av_log(NULL, AV_LOG_ERROR,
+               "Impossible to open the '%s' protocol for reading\n", up->name);
+        return AVERROR(EIO);
+    }
+    if ((flags & AVIO_FLAG_WRITE) && !up->url_write) {
+        av_log(NULL, AV_LOG_ERROR,
+               "Impossible to open the '%s' protocol for writing\n", up->name);
+        return AVERROR(EIO);
+    }
     uc = av_mallocz(sizeof(URLContext) + strlen(filename) + 1);
     if (!uc) {
         err = AVERROR(ENOMEM);
@@ -210,7 +220,9 @@
                                      "Missing call to av_register_all()?\n");
     }
 
-    if (filename[proto_len] != ':' &&  filename[proto_len] != ',' || is_dos_path(filename))
+    if (filename[proto_len] != ':' &&
+        (filename[proto_len] != ',' || !strchr(filename + proto_len + 1, ':')) ||
+        is_dos_path(filename))
         strcpy(proto_str, "file");
     else
         av_strlcpy(proto_str, filename, FFMIN(proto_len+1, sizeof(proto_str)));
diff --git a/libavformat/avio_internal.h b/libavformat/avio_internal.h
index 3c0fc93..cf36764 100644
--- a/libavformat/avio_internal.h
+++ b/libavformat/avio_internal.h
@@ -83,7 +83,7 @@
 /**
  * Open a write only packetized memory stream with a maximum packet
  * size of 'max_packet_size'.  The stream is stored in a memory buffer
- * with a big endian 4 byte header giving the packet size in bytes.
+ * with a big-endian 4 byte header giving the packet size in bytes.
  *
  * @param s new IO context
  * @param max_packet_size maximum packet size (must be > 0)
diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c
index 906415d..7a73a17 100644
--- a/libavformat/aviobuf.c
+++ b/libavformat/aviobuf.c
@@ -77,28 +77,32 @@
                   int (*write_packet)(void *opaque, uint8_t *buf, int buf_size),
                   int64_t (*seek)(void *opaque, int64_t offset, int whence))
 {
-    s->buffer = buffer;
+    s->buffer      = buffer;
     s->buffer_size = buffer_size;
-    s->buf_ptr = buffer;
-    s->opaque = opaque;
-    s->direct = 0;
+    s->buf_ptr     = buffer;
+    s->opaque      = opaque;
+    s->direct      = 0;
+
     url_resetbuf(s, write_flag ? AVIO_FLAG_WRITE : AVIO_FLAG_READ);
-    s->write_packet = write_packet;
-    s->read_packet = read_packet;
-    s->seek = seek;
-    s->pos = 0;
-    s->must_flush = 0;
-    s->eof_reached = 0;
-    s->error = 0;
-    s->seekable = AVIO_SEEKABLE_NORMAL;
+
+    s->write_packet    = write_packet;
+    s->read_packet     = read_packet;
+    s->seek            = seek;
+    s->pos             = 0;
+    s->must_flush      = 0;
+    s->eof_reached     = 0;
+    s->error           = 0;
+    s->seekable        = AVIO_SEEKABLE_NORMAL;
     s->max_packet_size = 0;
-    s->update_checksum= NULL;
-    if(!read_packet && !write_flag){
-        s->pos = buffer_size;
+    s->update_checksum = NULL;
+
+    if (!read_packet && !write_flag) {
+        s->pos     = buffer_size;
         s->buf_end = s->buffer + buffer_size;
     }
     s->read_pause = NULL;
     s->read_seek  = NULL;
+
     return 0;
 }
 
@@ -121,9 +125,9 @@
 
 static void writeout(AVIOContext *s, const uint8_t *data, int len)
 {
-    if (s->write_packet && !s->error){
-        int ret= s->write_packet(s->opaque, (uint8_t *)data, len);
-        if(ret < 0){
+    if (s->write_packet && !s->error) {
+        int ret = s->write_packet(s->opaque, (uint8_t *)data, len);
+        if (ret < 0) {
             s->error = ret;
         }
     }
@@ -134,9 +138,10 @@
 {
     if (s->buf_ptr > s->buffer) {
         writeout(s, s->buffer, s->buf_ptr - s->buffer);
-        if(s->update_checksum){
-            s->checksum= s->update_checksum(s->checksum, s->checksum_ptr, s->buf_ptr - s->checksum_ptr);
-            s->checksum_ptr= s->buffer;
+        if (s->update_checksum) {
+            s->checksum     = s->update_checksum(s->checksum, s->checksum_ptr,
+                                                 s->buf_ptr - s->checksum_ptr);
+            s->checksum_ptr = s->buffer;
         }
     }
     s->buf_ptr = s->buffer;
@@ -256,13 +261,13 @@
 {
     int64_t size;
 
-    if(!s)
+    if (!s)
         return AVERROR(EINVAL);
 
     if (!s->seek)
         return AVERROR(ENOSYS);
     size = s->seek(s->opaque, 0, AVSEEK_SIZE);
-    if(size<0){
+    if (size < 0) {
         if ((size = s->seek(s->opaque, -1, SEEK_END)) < 0)
             return size;
         size++;
@@ -319,29 +324,31 @@
         uint16_t tmp;
 
         GET_UTF8(ch, *q++, break;)
-        PUT_UTF16(ch, tmp, avio_wl16(s, tmp);ret += 2;)
+        PUT_UTF16(ch, tmp, avio_wl16(s, tmp); ret += 2;)
     }
     avio_wl16(s, 0);
     ret += 2;
     return ret;
 }
 
-int ff_get_v_length(uint64_t val){
-    int i=1;
+int ff_get_v_length(uint64_t val)
+{
+    int i = 1;
 
-    while(val>>=7)
+    while (val >>= 7)
         i++;
 
     return i;
 }
 
-void ff_put_v(AVIOContext *bc, uint64_t val){
-    int i= ff_get_v_length(val);
+void ff_put_v(AVIOContext *bc, uint64_t val)
+{
+    int i = ff_get_v_length(val);
 
-    while(--i>0)
-        avio_w8(bc, 128 | (uint8_t)(val>>(7*i)));
+    while (--i > 0)
+        avio_w8(bc, 128 | (uint8_t)(val >> (7*i)));
 
-    avio_w8(bc, val&127);
+    avio_w8(bc, val & 127);
 }
 
 void avio_wl64(AVIOContext *s, uint64_t val)
@@ -384,9 +391,12 @@
 
 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->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;
 
     /* can't fill the buffer without read_packet, just set EOF if appropriate */
     if (!s->read_packet && s->buf_ptr >= s->buf_end)
@@ -396,10 +406,11 @@
     if (s->eof_reached)
         return;
 
-    if(s->update_checksum && dst == s->buffer){
-        if(s->buf_end > s->checksum_ptr)
-            s->checksum= s->update_checksum(s->checksum, s->checksum_ptr, s->buf_end - s->checksum_ptr);
-        s->checksum_ptr= s->buffer;
+    if (s->update_checksum && dst == s->buffer) {
+        if (s->buf_end > s->checksum_ptr)
+            s->checksum = s->update_checksum(s->checksum, s->checksum_ptr,
+                                             s->buf_end - s->checksum_ptr);
+        s->checksum_ptr = s->buffer;
     }
 
     /* make buffer smaller in case it ended up large after probing */
@@ -410,7 +421,7 @@
         len = s->buffer_size;
     }
 
-    if(s->read_packet)
+    if (s->read_packet)
         len = s->read_packet(s->opaque, dst, len);
     else
         len = 0;
@@ -418,8 +429,8 @@
         /* do not modify buffer if EOF reached so that a seek back can
            be done without rereading data */
         s->eof_reached = 1;
-        if(len<0)
-            s->error= len;
+        if (len < 0)
+            s->error = len;
     } else {
         s->pos += len;
         s->buf_ptr = dst;
@@ -436,8 +447,9 @@
 
 unsigned long ffio_get_checksum(AVIOContext *s)
 {
-    s->checksum= s->update_checksum(s->checksum, s->checksum_ptr, s->buf_ptr - s->checksum_ptr);
-    s->update_checksum= NULL;
+    s->checksum = s->update_checksum(s->checksum, s->checksum_ptr,
+                                     s->buf_ptr - s->checksum_ptr);
+    s->update_checksum = NULL;
     return s->checksum;
 }
 
@@ -445,10 +457,10 @@
                    unsigned long (*update_checksum)(unsigned long c, const uint8_t *p, unsigned int len),
                    unsigned long checksum)
 {
-    s->update_checksum= update_checksum;
-    if(s->update_checksum){
-        s->checksum= checksum;
-        s->checksum_ptr= s->buf_ptr;
+    s->update_checksum = update_checksum;
+    if (s->update_checksum) {
+        s->checksum     = checksum;
+        s->checksum_ptr = s->buf_ptr;
     }
 }
 
@@ -471,7 +483,7 @@
         len = s->buf_end - s->buf_ptr;
         if (len > size)
             len = size;
-        if (len == 0) {
+        if (len == 0 || s->write_flag) {
             if((s->direct || size > s->buffer_size) && !s->update_checksum){
                 if(s->read_packet)
                     len = s->read_packet(s->opaque, buf, size);
@@ -490,7 +502,7 @@
                     s->buf_ptr = s->buffer;
                     s->buf_end = s->buffer/* + len*/;
                 }
-            }else{
+            } else {
                 fill_buffer(s);
                 len = s->buf_end - s->buf_ptr;
                 if (len == 0)
@@ -514,11 +526,25 @@
 {
     int len;
 
-    if(size<0)
+    if (size < 0)
         return -1;
 
+    if (s->read_packet && s->write_flag) {
+        len = s->read_packet(s->opaque, buf, size);
+        if (len > 0)
+            s->pos += len;
+        return len;
+    }
+
     len = s->buf_end - s->buf_ptr;
     if (len == 0) {
+        /* Reset the buf_end pointer to the start of the buffer, to make sure
+         * the fill_buffer call tries to read as much data as fits into the
+         * full buffer, instead of just what space is left after buf_end.
+         * This avoids returning partial packets at the end of the buffer,
+         * for packet based inputs.
+         */
+        s->buf_end = s->buf_ptr = s->buffer;
         fill_buffer(s);
         len = s->buf_end - s->buf_ptr;
     }
@@ -842,7 +868,7 @@
     if (!s->read_seek)
         return AVERROR(ENOSYS);
     ret = s->read_seek(h, stream_index, timestamp, flags);
-    if(ret >= 0) {
+    if (ret >= 0) {
         int64_t pos;
         s->buf_ptr = s->buf_end; // Flush buffer
         pos = s->seek(h, 0, SEEK_CUR);
@@ -871,7 +897,7 @@
     /* reallocate buffer if needed */
     new_size = d->pos + buf_size;
     new_allocated_size = d->allocated_size;
-    if(new_size < d->pos || new_size > INT_MAX/2)
+    if (new_size < d->pos || new_size > INT_MAX/2)
         return -1;
     while (new_size > new_allocated_size) {
         if (!new_allocated_size)
@@ -900,8 +926,8 @@
 
     /* packetized write: output the header */
     AV_WB32(buf1, buf_size);
-    ret= dyn_buf_write(opaque, buf1, 4);
-    if(ret < 0)
+    ret = dyn_buf_write(opaque, buf1, 4);
+    if (ret < 0)
         return ret;
 
     /* then the data */
@@ -927,7 +953,7 @@
     DynBuffer *d;
     unsigned io_buffer_size = max_packet_size ? max_packet_size : 1024;
 
-    if(sizeof(DynBuffer) + io_buffer_size < io_buffer_size)
+    if (sizeof(DynBuffer) + io_buffer_size < io_buffer_size)
         return -1;
     d = av_mallocz(sizeof(DynBuffer) + io_buffer_size);
     if (!d)
diff --git a/libavformat/avisynth.c b/libavformat/avisynth.c
index e5d9b76..1e4dee1 100644
--- a/libavformat/avisynth.c
+++ b/libavformat/avisynth.c
@@ -226,7 +226,7 @@
 }
 
 AVInputFormat ff_avisynth_demuxer = {
-    .name           = "avs",
+    .name           = "avisynth",
     .long_name      = NULL_IF_CONFIG_SMALL("AVISynth"),
     .priv_data_size = sizeof(AVISynthContext),
     .read_header    = avisynth_read_header,
diff --git a/libavformat/avr.c b/libavformat/avr.c
index d3b23db..71a107c 100644
--- a/libavformat/avr.c
+++ b/libavformat/avr.c
@@ -22,7 +22,6 @@
 #include "libavutil/intreadwrite.h"
 #include "avformat.h"
 #include "internal.h"
-#include "rawdec.h"
 #include "pcm.h"
 
 static int avr_probe(AVProbeData *p)
@@ -83,6 +82,8 @@
         return AVERROR_PATCHWELCOME;
     }
 
+    st->codec->block_align = bps * st->codec->channels / 8;
+
     avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
     return 0;
 }
@@ -92,7 +93,7 @@
     .long_name      = NULL_IF_CONFIG_SMALL("AVR (Audio Visual Research)"),
     .read_probe     = avr_probe,
     .read_header    = avr_read_header,
-    .read_packet    = ff_raw_read_partial_packet,
+    .read_packet    = ff_pcm_read_packet,
     .read_seek      = ff_pcm_read_seek,
     .extensions     = "avr",
     .flags          = AVFMT_GENERIC_INDEX,
diff --git a/libavformat/bethsoftvid.c b/libavformat/bethsoftvid.c
index 831bdd2..caff7ab 100644
--- a/libavformat/bethsoftvid.c
+++ b/libavformat/bethsoftvid.c
@@ -57,7 +57,7 @@
 
 static int vid_probe(AVProbeData *p)
 {
-    // little endian VID tag, file starts with "VID\0"
+    // little-endian VID tag, file starts with "VID\0"
     if (AV_RL32(p->buf) != MKTAG('V', 'I', 'D', 0))
         return 0;
 
diff --git a/libavformat/bfi.c b/libavformat/bfi.c
index d26d848..a28e09a 100644
--- a/libavformat/bfi.c
+++ b/libavformat/bfi.c
@@ -92,6 +92,8 @@
     vstream->codec->codec_type = AVMEDIA_TYPE_VIDEO;
     vstream->codec->codec_id   = AV_CODEC_ID_BFI;
     vstream->codec->pix_fmt    = AV_PIX_FMT_PAL8;
+    vstream->nb_frames         =
+    vstream->duration          = bfi->nframes;
 
     /* Set up the audio codec now... */
     astream->codec->codec_type      = AVMEDIA_TYPE_AUDIO;
@@ -150,7 +152,7 @@
             return ret;
 
         pkt->pts          = bfi->video_frame;
-        bfi->video_frame += ret / bfi->video_size;
+        bfi->video_frame += bfi->video_size ? ret / bfi->video_size : 1;
 
         /* One less frame to read. A cursory decrement. */
         bfi->nframes--;
diff --git a/libavformat/bink.c b/libavformat/bink.c
index c77a8f8..887f70a 100644
--- a/libavformat/bink.c
+++ b/libavformat/bink.c
@@ -112,6 +112,7 @@
         return AVERROR(EIO);
     }
     avpriv_set_pts_info(vst, 64, fps_den, fps_num);
+    vst->avg_frame_rate = av_inv_q(vst->time_base);
 
     vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
     vst->codec->codec_id   = AV_CODEC_ID_BINKVIDEO;
diff --git a/libavformat/brstm.c b/libavformat/brstm.c
index a4db35a..82f3027 100644
--- a/libavformat/brstm.c
+++ b/libavformat/brstm.c
@@ -75,7 +75,7 @@
         return AVERROR_INVALIDDATA;
     }
     if (bom == 0xFFFE) {
-        av_log_ask_for_sample(s, "unsupported byte order");
+        av_log_ask_for_sample(s, "unsupported byte order\n");
         return AVERROR_PATCHWELCOME;
     }
 
@@ -110,7 +110,7 @@
     case 1: codec = AV_CODEC_ID_PCM_S16BE_PLANAR; break;
     case 2: codec = AV_CODEC_ID_ADPCM_THP;        break;
     default:
-        av_log_ask_for_sample(s, "unsupported codec: %d", codec);
+        av_log_ask_for_sample(s, "unsupported codec: %d\n", codec);
         return AVERROR_PATCHWELCOME;
     }
 
@@ -219,6 +219,10 @@
                 goto fail;
             }
             avio_skip(s->pb, start - avio_tell(s->pb));
+
+            if (major!=1 || minor)
+                av_log_ask_for_sample(s, "Version %d.%d\n", major, minor);
+
             return 0;
         default:
             av_log(s, AV_LOG_WARNING, "skipping unknown chunk: %X\n", chunk);
@@ -245,7 +249,7 @@
     b->current_block++;
     if (b->current_block == b->block_count) {
         size    = b->last_block_used_bytes;
-        samples = size / 16 * 14;
+        samples = size / (8 * codec->channels) * 14;
     } else if (b->current_block < b->block_count) {
         size    = b->block_size;
         samples = b->samples_per_block;
@@ -266,19 +270,18 @@
                                     (b->current_block - 1), 4 * codec->channels);
 
         ret = avio_read(s->pb, dst, size);
-        if (ret < 0) {
+        if (ret != size)
             av_free_packet(pkt);
-            return ret;
-        }
         pkt->duration = samples;
     } else {
         ret = av_get_packet(s->pb, pkt, size);
-        if (ret < 0)
-            return ret;
     }
 
     pkt->stream_index = 0;
 
+    if (ret != size)
+        ret = AVERROR(EIO);
+
     return ret;
 }
 
diff --git a/libavformat/cafdec.c b/libavformat/cafdec.c
index 718942b..337758e 100644
--- a/libavformat/cafdec.c
+++ b/libavformat/cafdec.c
@@ -300,7 +300,7 @@
         }
 
         if (size > 0) {
-            if (pos + size < pos)
+            if (pos > INT64_MAX - size)
                 return AVERROR_INVALIDDATA;
             avio_skip(pb, FFMAX(0, pos + size - avio_tell(pb)));
         }
@@ -312,7 +312,7 @@
     if (caf->bytes_per_packet > 0 && caf->frames_per_packet > 0) {
         if (caf->data_size > 0)
             st->nb_frames = (caf->data_size / caf->bytes_per_packet) * caf->frames_per_packet;
-    } else if (st->nb_index_entries) {
+    } else if (st->nb_index_entries && st->duration > 0) {
         st->codec->bit_rate = st->codec->sample_rate * caf->data_size * 8 /
                               st->duration;
     } else {
diff --git a/libavformat/cafenc.c b/libavformat/cafenc.c
index 92b61c9..11bb055 100644
--- a/libavformat/cafenc.c
+++ b/libavformat/cafenc.c
@@ -21,7 +21,6 @@
 
 #include "avformat.h"
 #include "caf.h"
-#include "riff.h"
 #include "isom.h"
 #include "avio_internal.h"
 #include "libavutil/intfloat.h"
@@ -239,11 +238,11 @@
 
 static int caf_write_trailer(AVFormatContext *s)
 {
+    CAFContext *caf = s->priv_data;
     AVIOContext *pb = s->pb;
     AVCodecContext *enc = s->streams[0]->codec;
 
     if (pb->seekable) {
-        CAFContext *caf = s->priv_data;
         int64_t file_size = avio_tell(pb);
 
         avio_seek(pb, caf->data, SEEK_SET);
@@ -257,11 +256,11 @@
             avio_wb32(pb, 0); ///< mPrimingFrames
             avio_wb32(pb, 0); ///< mRemainderFrames
             avio_write(pb, caf->pkt_sizes, caf->size_entries_used);
-            av_freep(&caf->pkt_sizes);
             caf->size_buffer_size = 0;
         }
         avio_flush(pb);
     }
+    av_freep(&caf->pkt_sizes);
     return 0;
 }
 
diff --git a/libavformat/concatdec.c b/libavformat/concatdec.c
new file mode 100644
index 0000000..052b4eb
--- /dev/null
+++ b/libavformat/concatdec.c
@@ -0,0 +1,293 @@
+/*
+ * Copyright (c) 2012 Nicolas George
+ *
+ * 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/parseutils.h"
+#include "avformat.h"
+#include "internal.h"
+
+typedef struct {
+    char *url;
+    int64_t start_time;
+    int64_t duration;
+} ConcatFile;
+
+typedef struct {
+    AVClass *class;
+    ConcatFile *files;
+    ConcatFile *cur_file;
+    unsigned nb_files;
+    AVFormatContext *avf;
+    int safe;
+} ConcatContext;
+
+static int concat_probe(AVProbeData *probe)
+{
+    return memcmp(probe->buf, "ffconcat version 1.0", 20) ?
+           0 : AVPROBE_SCORE_MAX;
+}
+
+static char *get_keyword(uint8_t **cursor)
+{
+    char *ret = *cursor += strspn(*cursor, SPACE_CHARS);
+    *cursor += strcspn(*cursor, SPACE_CHARS);
+    if (**cursor) {
+        *((*cursor)++) = 0;
+        *cursor += strspn(*cursor, SPACE_CHARS);
+    }
+    return ret;
+}
+
+static int safe_filename(const char *f)
+{
+    const char *start = f;
+
+    for (; *f; f++) {
+        /* A-Za-z0-9_- */
+        if (!((unsigned)((*f | 32) - 'a') < 26 ||
+              (unsigned)(*f - '0') < 10 || *f == '_' || *f == '-')) {
+            if (f == start)
+                return 0;
+            else if (*f == '/')
+                start = f + 1;
+            else if (*f != '.')
+                return 0;
+        }
+    }
+    return 1;
+}
+
+#define FAIL(retcode) do { ret = (retcode); goto fail; } while(0)
+
+static int add_file(AVFormatContext *avf, char *filename, ConcatFile **rfile,
+                    unsigned *nb_files_alloc)
+{
+    ConcatContext *cat = avf->priv_data;
+    ConcatFile *file;
+    char *url;
+    size_t url_len;
+
+    if (cat->safe > 0 && !safe_filename(filename)) {
+        av_log(avf, AV_LOG_ERROR, "Unsafe file name '%s'\n", filename);
+        return AVERROR(EPERM);
+    }
+    url_len = strlen(avf->filename) + strlen(filename) + 16;
+    if (!(url = av_malloc(url_len)))
+        return AVERROR(ENOMEM);
+    ff_make_absolute_url(url, url_len, avf->filename, filename);
+    av_free(filename);
+
+    if (cat->nb_files >= *nb_files_alloc) {
+        size_t n = FFMAX(*nb_files_alloc * 2, 16);
+        ConcatFile *new_files;
+        if (n <= cat->nb_files || n > SIZE_MAX / sizeof(*cat->files) ||
+            !(new_files = av_realloc(cat->files, n * sizeof(*cat->files))))
+            return AVERROR(ENOMEM);
+        cat->files = new_files;
+        *nb_files_alloc = n;
+    }
+
+    file = &cat->files[cat->nb_files++];
+    memset(file, 0, sizeof(*file));
+    *rfile = file;
+
+    file->url        = url;
+    file->start_time = AV_NOPTS_VALUE;
+    file->duration   = AV_NOPTS_VALUE;
+
+    return 0;
+}
+
+static int open_file(AVFormatContext *avf, unsigned fileno)
+{
+    ConcatContext *cat = avf->priv_data;
+    ConcatFile *file = &cat->files[fileno];
+    int ret;
+
+    if ((ret = avformat_open_input(&cat->avf, file->url, NULL, NULL)) < 0 ||
+        (ret = avformat_find_stream_info(cat->avf, NULL)) < 0) {
+        av_log(avf, AV_LOG_ERROR, "Impossible to open '%s'\n", file->url);
+        return ret;
+    }
+    cat->cur_file = file;
+    if (file->start_time == AV_NOPTS_VALUE)
+        file->start_time = !fileno ? 0 :
+                           cat->files[fileno - 1].start_time +
+                           cat->files[fileno - 1].duration;
+    return 0;
+}
+
+static int concat_read_close(AVFormatContext *avf)
+{
+    ConcatContext *cat = avf->priv_data;
+    unsigned i;
+
+    if (cat->avf)
+        avformat_close_input(&cat->avf);
+    for (i = 0; i < cat->nb_files; i++)
+        av_freep(&cat->files[i].url);
+    av_freep(&cat->files);
+    return 0;
+}
+
+static int concat_read_header(AVFormatContext *avf)
+{
+    ConcatContext *cat = avf->priv_data;
+    uint8_t buf[4096];
+    uint8_t *cursor, *keyword;
+    int ret, line = 0, i;
+    unsigned nb_files_alloc = 0;
+    ConcatFile *file = NULL;
+    AVStream *st, *source_st;
+
+    while (1) {
+        if ((ret = ff_get_line(avf->pb, buf, sizeof(buf))) <= 0)
+            break;
+        line++;
+        cursor = buf;
+        keyword = get_keyword(&cursor);
+        if (!*keyword || *keyword == '#')
+            continue;
+
+        if (!strcmp(keyword, "file")) {
+            char *filename = av_get_token((const char **)&cursor, SPACE_CHARS);
+            if (!filename) {
+                av_log(avf, AV_LOG_ERROR, "Line %d: filename required\n", line);
+                FAIL(AVERROR_INVALIDDATA);
+            }
+            if ((ret = add_file(avf, filename, &file, &nb_files_alloc)) < 0)
+                FAIL(ret);
+        } else if (!strcmp(keyword, "duration")) {
+            char *dur_str = get_keyword(&cursor);
+            int64_t dur;
+            if (!file) {
+                av_log(avf, AV_LOG_ERROR, "Line %d: duration without file\n",
+                       line);
+                FAIL(AVERROR_INVALIDDATA);
+            }
+            if ((ret = av_parse_time(&dur, dur_str, 1)) < 0) {
+                av_log(avf, AV_LOG_ERROR, "Line %d: invalid duration '%s'\n",
+                       line, dur_str);
+                FAIL(ret);
+            }
+            file->duration = dur;
+        } else if (!strcmp(keyword, "ffconcat")) {
+            char *ver_kw  = get_keyword(&cursor);
+            char *ver_val = get_keyword(&cursor);
+            if (strcmp(ver_kw, "version") || strcmp(ver_val, "1.0")) {
+                av_log(avf, AV_LOG_ERROR, "Line %d: invalid version\n", line);
+                FAIL(AVERROR_INVALIDDATA);
+            }
+            if (cat->safe < 0)
+                cat->safe = 1;
+        } else {
+            av_log(avf, AV_LOG_ERROR, "Line %d: unknown keyword '%s'\n",
+                   line, keyword);
+            FAIL(AVERROR_INVALIDDATA);
+        }
+    }
+    if (ret < 0)
+        FAIL(ret);
+
+    if ((ret = open_file(avf, 0)) < 0)
+        FAIL(ret);
+    for (i = 0; i < cat->avf->nb_streams; i++) {
+        if (!(st = avformat_new_stream(avf, NULL)))
+            FAIL(AVERROR(ENOMEM));
+        source_st = cat->avf->streams[i];
+        if ((ret = avcodec_copy_context(st->codec, source_st->codec)) < 0)
+            FAIL(ret);
+        st->r_frame_rate        = source_st->r_frame_rate;
+        st->avg_frame_rate      = source_st->avg_frame_rate;
+        st->time_base           = source_st->time_base;
+        st->sample_aspect_ratio = source_st->sample_aspect_ratio;
+    }
+
+    return 0;
+
+fail:
+    concat_read_close(avf);
+    return ret;
+}
+
+static int open_next_file(AVFormatContext *avf)
+{
+    ConcatContext *cat = avf->priv_data;
+    unsigned fileno = cat->cur_file - cat->files;
+
+    if (cat->cur_file->duration == AV_NOPTS_VALUE)
+        cat->cur_file->duration = cat->avf->duration;
+
+    if (++fileno >= cat->nb_files)
+        return AVERROR_EOF;
+    avformat_close_input(&cat->avf);
+    return open_file(avf, fileno);
+}
+
+static int concat_read_packet(AVFormatContext *avf, AVPacket *pkt)
+{
+    ConcatContext *cat = avf->priv_data;
+    int ret;
+    int64_t delta;
+
+    while (1) {
+        if ((ret = av_read_frame(cat->avf, pkt)) != AVERROR_EOF ||
+            (ret = open_next_file(avf)) < 0)
+            break;
+    }
+    delta = av_rescale_q(cat->cur_file->start_time - cat->avf->start_time,
+                         AV_TIME_BASE_Q,
+                         cat->avf->streams[pkt->stream_index]->time_base);
+    if (pkt->pts != AV_NOPTS_VALUE)
+        pkt->pts += delta;
+    if (pkt->dts != AV_NOPTS_VALUE)
+        pkt->dts += delta;
+    return ret;
+}
+
+#define OFFSET(x) offsetof(ConcatContext, x)
+#define DEC AV_OPT_FLAG_DECODING_PARAM
+
+static const AVOption options[] = {
+    { "safe", "enable safe mode",
+      OFFSET(safe), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, DEC },
+    { NULL }
+};
+
+static const AVClass concat_class = {
+    .class_name = "concat demuxer",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+
+AVInputFormat ff_concat_demuxer = {
+    .name           = "concat",
+    .long_name      = NULL_IF_CONFIG_SMALL("Virtual concatenation script"),
+    .priv_data_size = sizeof(ConcatContext),
+    .read_probe     = concat_probe,
+    .read_header    = concat_read_header,
+    .read_packet    = concat_read_packet,
+    .read_close     = concat_read_close,
+    .priv_class     = &concat_class,
+    .extensions     = "ffconcat,ffcat",
+};
diff --git a/libavformat/data_uri.c b/libavformat/data_uri.c
new file mode 100644
index 0000000..1598b99
--- /dev/null
+++ b/libavformat/data_uri.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2012 Nicolas George
+ *
+ * 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 "libavutil/avstring.h"
+#include "libavutil/base64.h"
+#include "url.h"
+
+typedef struct {
+    const uint8_t *data;
+    void *tofree;
+    size_t size;
+    size_t pos;
+} DataContext;
+
+static av_cold int data_open(URLContext *h, const char *uri, int flags)
+{
+    DataContext *dc = h->priv_data;
+    const char *data, *opt, *next;
+    char *ddata;
+    int ret, base64 = 0;
+    size_t in_size;
+
+    /* data:content/type[;base64],payload */
+
+    av_strstart(uri, "data:", &uri);
+    data = strchr(uri, ',');
+    if (!data) {
+        av_log(h, AV_LOG_ERROR, "No ',' delimiter in URI\n");
+        return AVERROR(EINVAL);
+    }
+    opt = uri;
+    while (opt < data) {
+        next = av_x_if_null(memchr(opt, ';', data - opt), data);
+        if (opt == uri) {
+            if (!memchr(opt, '/', next - opt)) { /* basic validity check */
+                av_log(h, AV_LOG_ERROR, "Invalid content-type '%.*s'\n",
+                       (int)(next - opt), opt);
+                return AVERROR(EINVAL);
+            }
+            av_log(h, AV_LOG_VERBOSE, "Content-type: %.*s\n",
+                   (int)(next - opt), opt);
+        } else {
+            if (!av_strncasecmp(opt, "base64", next - opt)) {
+                base64 = 1;
+            } else {
+                av_log(h, AV_LOG_VERBOSE, "Ignoring option '%.*s'\n",
+                       (int)(next - opt), opt);
+            }
+        }
+        opt = next + 1;
+    }
+
+    data++;
+    in_size = strlen(data);
+    if (base64) {
+        size_t out_size = 3 * (in_size / 4) + 1;
+
+        if (out_size > INT_MAX || !(ddata = av_malloc(out_size)))
+            return AVERROR(ENOMEM);
+        if ((ret = av_base64_decode(ddata, data, out_size)) < 0) {
+            av_free(ddata);
+            av_log(h, AV_LOG_ERROR, "Invalid base64 in URI\n");
+            return ret;
+        }
+        dc->data = dc->tofree = ddata;
+        dc->size = ret;
+    } else {
+        dc->data = data;
+        dc->size = in_size;
+    }
+    return 0;
+}
+
+static av_cold int data_close(URLContext *h)
+{
+    DataContext *dc = h->priv_data;
+
+    av_freep(&dc->tofree);
+    return 0;
+}
+
+static int data_read(URLContext *h, unsigned char *buf, int size)
+{
+    DataContext *dc = h->priv_data;
+
+    if (dc->pos >= dc->size)
+        return AVERROR_EOF;
+    size = FFMIN(size, dc->size - dc->pos);
+    memcpy(buf, dc->data + dc->pos, size);
+    dc->pos += size;
+    return size;
+}
+
+URLProtocol ff_data_protocol = {
+    .name           = "data",
+    .url_open       = data_open,
+    .url_close      = data_close,
+    .url_read       = data_read,
+    .priv_data_size = sizeof(DataContext),
+};
diff --git a/libavformat/dvenc.c b/libavformat/dvenc.c
index a132edb..0b3811e 100644
--- a/libavformat/dvenc.c
+++ b/libavformat/dvenc.c
@@ -51,9 +51,9 @@
     AVFifoBuffer     *audio_data[2]; /* FIFO for storing excessive amounts of PCM */
     int               frames;        /* current frame number */
     int64_t           start_time;    /* recording start time */
-    int               has_audio;     /* frame under contruction has audio */
-    int               has_video;     /* frame under contruction has video */
-    uint8_t           frame_buf[DV_MAX_FRAME_SIZE]; /* frame under contruction */
+    int               has_audio;     /* frame under construction has audio */
+    int               has_video;     /* frame under construction has video */
+    uint8_t           frame_buf[DV_MAX_FRAME_SIZE]; /* frame under construction */
     AVTimecode        tc;            /* timecode context */
 };
 
@@ -376,8 +376,8 @@
                 break;
         }
     }
-    if (tcr)
-        return av_timecode_init_from_string(&dvc->tc, rate, tcr->value, s);
+    if (tcr && av_timecode_init_from_string(&dvc->tc, rate, tcr->value, s) >= 0)
+        return 0;
     return av_timecode_init(&dvc->tc, rate, 0, 0, s);
 }
 
diff --git a/libavformat/dxa.c b/libavformat/dxa.c
index 30d1e02..22ee2a9 100644
--- a/libavformat/dxa.c
+++ b/libavformat/dxa.c
@@ -65,12 +65,12 @@
 
     tag = avio_rl32(pb);
     if (tag != MKTAG('D', 'E', 'X', 'A'))
-        return -1;
+        return AVERROR_INVALIDDATA;
     flags = avio_r8(pb);
     c->frames = avio_rb16(pb);
     if(!c->frames){
         av_log(s, AV_LOG_ERROR, "File contains no frames ???\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     fps = avio_rb32(pb);
@@ -90,7 +90,7 @@
 
     st = avformat_new_stream(s, NULL);
     if (!st)
-        return -1;
+        return AVERROR(ENOMEM);
 
     // Parse WAV data header
     if(avio_rl32(pb) == MKTAG('W', 'A', 'V', 'E')){
@@ -103,7 +103,7 @@
 
         ast = avformat_new_stream(s, NULL);
         if (!ast)
-            return -1;
+            return AVERROR(ENOMEM);
         ret = ff_get_wav_header(pb, ast->codec, fsize);
         if (ret < 0)
             return ret;
@@ -191,7 +191,7 @@
             size = AV_RB32(buf + 5);
             if(size > 0xFFFFFF){
                 av_log(s, AV_LOG_ERROR, "Frame size is too big: %d\n", size);
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
             if(av_new_packet(pkt, size + DXA_EXTRA_SIZE + pal_size) < 0)
                 return AVERROR(ENOMEM);
@@ -209,10 +209,10 @@
             return 0;
         default:
             av_log(s, AV_LOG_ERROR, "Unknown tag %c%c%c%c\n", buf[0], buf[1], buf[2], buf[3]);
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
     }
-    return AVERROR(EIO);
+    return AVERROR_EOF;
 }
 
 AVInputFormat ff_dxa_demuxer = {
diff --git a/libavformat/eacdata.c b/libavformat/eacdata.c
index be31d00..57e5145 100644
--- a/libavformat/eacdata.c
+++ b/libavformat/eacdata.c
@@ -76,7 +76,6 @@
     st->codec->channels = cdata->channels;
     st->codec->channel_layout = channel_layout;
     st->codec->sample_rate = sample_rate;
-    st->codec->sample_fmt = AV_SAMPLE_FMT_S16;
     avpriv_set_pts_info(st, 64, 1, sample_rate);
 
     cdata->audio_pts = 0;
diff --git a/libavformat/epafdec.c b/libavformat/epafdec.c
new file mode 100644
index 0000000..ffb8b95
--- /dev/null
+++ b/libavformat/epafdec.c
@@ -0,0 +1,104 @@
+/*
+ * Ensoniq Paris Audio File demuxer
+ * 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/intreadwrite.h"
+#include "avformat.h"
+#include "internal.h"
+#include "pcm.h"
+
+static int epaf_probe(AVProbeData *p)
+{
+    if (((AV_RL32(p->buf) == MKTAG('f','a','p',' ') &&
+          AV_RL32(p->buf + 8) == 1) ||
+         (AV_RL32(p->buf) == MKTAG(' ','p','a','f') &&
+          AV_RN32(p->buf + 8) == 0)) &&
+       !AV_RN32(p->buf +  4) && AV_RN32(p->buf + 12) &&
+        AV_RN32(p->buf + 20))
+        return AVPROBE_SCORE_MAX / 4 * 3;
+    return 0;
+}
+
+static int epaf_read_header(AVFormatContext *s)
+{
+    int le, sample_rate, codec, channels;
+    AVStream *st;
+
+    avio_skip(s->pb, 4);
+    if (avio_rl32(s->pb))
+        return AVERROR_INVALIDDATA;
+
+    le = avio_rl32(s->pb);
+    if (le && le != 1)
+        return AVERROR_INVALIDDATA;
+
+    if (le) {
+        sample_rate = avio_rl32(s->pb);
+        codec       = avio_rl32(s->pb);
+        channels    = avio_rl32(s->pb);
+    } else {
+        sample_rate = avio_rb32(s->pb);
+        codec       = avio_rb32(s->pb);
+        channels    = avio_rb32(s->pb);
+    }
+
+    if (!channels || !sample_rate)
+        return AVERROR_INVALIDDATA;
+
+    st = avformat_new_stream(s, NULL);
+    if (!st)
+        return AVERROR(ENOMEM);
+
+    st->codec->codec_type  = AVMEDIA_TYPE_AUDIO;
+    st->codec->channels    = channels;
+    st->codec->sample_rate = sample_rate;
+    switch (codec) {
+    case 0:
+        st->codec->codec_id = le ? AV_CODEC_ID_PCM_S16LE : AV_CODEC_ID_PCM_S16BE;
+        break;
+    case 2:
+        st->codec->codec_id = AV_CODEC_ID_PCM_S8;
+        break;
+    case 1:
+        av_log_missing_feature(s, "24-bit Paris PCM format", 1);
+    default:
+        return AVERROR_INVALIDDATA;
+    }
+
+    st->codec->bits_per_coded_sample = av_get_bits_per_sample(st->codec->codec_id);
+    st->codec->block_align = st->codec->bits_per_coded_sample * st->codec->channels / 8;
+
+    avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
+
+    if (avio_skip(s->pb, 2024) < 0)
+        return AVERROR_INVALIDDATA;
+    return 0;
+}
+
+AVInputFormat ff_epaf_demuxer = {
+    .name           = "epaf",
+    .long_name      = NULL_IF_CONFIG_SMALL("Ensoniq Paris Audio File"),
+    .read_probe     = epaf_probe,
+    .read_header    = epaf_read_header,
+    .read_packet    = ff_pcm_read_packet,
+    .read_seek      = ff_pcm_read_seek,
+    .extensions     = "paf,fap",
+    .flags          = AVFMT_GENERIC_INDEX,
+};
diff --git a/libavformat/filmstripdec.c b/libavformat/filmstripdec.c
index b41fdb7..aa41fa4 100644
--- a/libavformat/filmstripdec.c
+++ b/libavformat/filmstripdec.c
@@ -56,7 +56,7 @@
     st->nb_frames = avio_rb32(pb);
     if (avio_rb16(pb) != 0) {
         av_log_ask_for_sample(s, "unsupported packing method\n");
-        return AVERROR_INVALIDDATA;
+        return AVERROR_PATCHWELCOME;
     }
 
     avio_skip(pb, 2);
diff --git a/libavformat/flacdec.c b/libavformat/flacdec.c
index bbb28f4..ecc47e6 100644
--- a/libavformat/flacdec.c
+++ b/libavformat/flacdec.c
@@ -277,8 +277,8 @@
 
 static int flac_probe(AVProbeData *p)
 {
-    uint8_t *bufptr = p->buf;
-    uint8_t *end    = p->buf + p->buf_size;
+    const uint8_t *bufptr = p->buf;
+    const uint8_t *end    = p->buf + p->buf_size;
 
     if(bufptr > end-4 || memcmp(bufptr, "fLaC", 4)) return 0;
     else                                            return AVPROBE_SCORE_MAX/2;
diff --git a/libavformat/flic.c b/libavformat/flic.c
index 2b9ee67..8d49116 100644
--- a/libavformat/flic.c
+++ b/libavformat/flic.c
@@ -158,7 +158,6 @@
         ast->codec->codec_tag = 0;
         ast->codec->sample_rate = FLIC_TFTD_SAMPLE_RATE;
         ast->codec->channels = 1;
-        ast->codec->sample_fmt = AV_SAMPLE_FMT_U8;
         ast->codec->bit_rate = st->codec->sample_rate * 8;
         ast->codec->bits_per_coded_sample = 8;
         ast->codec->channel_layout = AV_CH_LAYOUT_MONO;
diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
index 09a77c4..b57929e 100644
--- a/libavformat/flvdec.c
+++ b/libavformat/flvdec.c
@@ -713,13 +713,13 @@
         st = s->streams[i];
         if (stream_type == FLV_STREAM_TYPE_AUDIO) {
             if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
-                flv_same_audio_codec(st->codec, flags)) {
+                (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 &&
-                flv_same_video_codec(st->codec, flags)) {
+                (s->video_codec_id || flv_same_video_codec(st->codec, flags))) {
                 break;
             }
         } else if (stream_type == FLV_STREAM_TYPE_DATA) {
diff --git a/libavformat/flvenc.c b/libavformat/flvenc.c
index c528bf5..502da0f 100644
--- a/libavformat/flvenc.c
+++ b/libavformat/flvenc.c
@@ -426,10 +426,14 @@
     file_size = avio_tell(pb);
 
     /* update information */
-    avio_seek(pb, flv->duration_offset, SEEK_SET);
-    put_amf_double(pb, flv->duration / (double)1000);
-    avio_seek(pb, flv->filesize_offset, SEEK_SET);
-    put_amf_double(pb, file_size);
+    if (avio_seek(pb, flv->duration_offset, SEEK_SET) < 0)
+        av_log(s, AV_LOG_WARNING, "Failed to update header with correct duration.\n");
+    else
+        put_amf_double(pb, flv->duration / (double)1000);
+    if (avio_seek(pb, flv->filesize_offset, SEEK_SET) < 0)
+        av_log(s, AV_LOG_WARNING, "Failed to update header with correct filesize.\n");
+    else
+        put_amf_double(pb, file_size);
 
     avio_seek(pb, file_size, SEEK_SET);
     return 0;
@@ -490,7 +494,7 @@
     } else if (enc->codec_id == AV_CODEC_ID_AAC && pkt->size > 2 &&
                (AV_RB16(pkt->data) & 0xfff0) == 0xfff0) {
         av_log(s, AV_LOG_ERROR, "Malformed AAC bitstream detected: "
-               "use audio bistream filter 'aac_adtstoasc' to fix it "
+               "use audio bitstream filter 'aac_adtstoasc' to fix it "
                "('-bsf:a aac_adtstoasc' option with ffmpeg)\n");
         return AVERROR_INVALIDDATA;
     }
diff --git a/libavformat/framecrcenc.c b/libavformat/framecrcenc.c
index 8a69748..92f2e91 100644
--- a/libavformat/framecrcenc.c
+++ b/libavformat/framecrcenc.c
@@ -33,8 +33,17 @@
              pkt->stream_index, pkt->dts, pkt->pts, pkt->duration, pkt->size, crc);
     if (pkt->flags != AV_PKT_FLAG_KEY)
         av_strlcatf(buf, sizeof(buf), ", F=0x%0X", pkt->flags);
-    if (pkt->side_data_elems)
+    if (pkt->side_data_elems) {
+        int i;
         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);
+            av_strlcatf(buf, sizeof(buf), ", %8d, 0x%08x", pkt->side_data[i].size, side_data_crc);
+        }
+    }
     av_strlcatf(buf, sizeof(buf), "\n");
     avio_write(s->pb, buf, strlen(buf));
     avio_flush(s->pb);
diff --git a/libavformat/frmdec.c b/libavformat/frmdec.c
new file mode 100644
index 0000000..a6f19af
--- /dev/null
+++ b/libavformat/frmdec.c
@@ -0,0 +1,110 @@
+/*
+ * Megalux Frame demuxer
+ * Copyright (c) 2010 Peter Ross <pross@xvid.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
+ */
+
+/**
+ * @file
+ * Megalux Frame demuxer
+ */
+
+#include "libavcodec/raw.h"
+#include "libavutil/intreadwrite.h"
+#include "avformat.h"
+
+static const PixelFormatTag frm_pix_fmt_tags[] = {
+    { AV_PIX_FMT_RGB555, 1 },
+    { AV_PIX_FMT_RGB0,   2 },
+    { AV_PIX_FMT_RGB24,  3 },
+    { AV_PIX_FMT_BGR0,   4 },
+    { AV_PIX_FMT_BGRA,   5 },
+    { AV_PIX_FMT_NONE,   0 },
+};
+
+typedef struct {
+    int count;
+} FrmContext;
+
+static int frm_read_probe(AVProbeData *p)
+{
+    if (p->buf_size > 8 &&
+        p->buf[0] == 'F' && p->buf[1] == 'R' && p->buf[2] == 'M' &&
+        AV_RL16(&p->buf[4]) && AV_RL16(&p->buf[6]))
+        return AVPROBE_SCORE_MAX / 4;
+    return 0;
+}
+
+static int frm_read_header(AVFormatContext *avctx)
+{
+    AVIOContext *pb = avctx->pb;
+    AVStream *st = avformat_new_stream(avctx, 0);
+    if (!st)
+        return AVERROR(ENOMEM);
+
+    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+    st->codec->codec_id   = AV_CODEC_ID_RAWVIDEO;
+    avio_skip(pb, 3);
+
+    st->codec->pix_fmt    = avpriv_find_pix_fmt(frm_pix_fmt_tags, avio_r8(pb));
+    if (!st->codec->pix_fmt)
+        return AVERROR_INVALIDDATA;
+
+    st->codec->codec_tag  = 0;
+    st->codec->width      = avio_rl16(pb);
+    st->codec->height     = avio_rl16(pb);
+    return 0;
+}
+
+static int frm_read_packet(AVFormatContext *avctx, AVPacket *pkt)
+{
+    FrmContext *s = avctx->priv_data;
+    AVCodecContext *stc = avctx->streams[0]->codec;
+    int packet_size, ret;
+
+    if (s->count)
+        return AVERROR_EOF;
+
+    packet_size = avpicture_get_size(stc->pix_fmt, stc->width, stc->height);
+    if (packet_size < 0)
+        return AVERROR_INVALIDDATA;
+
+    ret = av_get_packet(avctx->pb, pkt, packet_size);
+    if (ret < 0)
+        return ret;
+
+    if (stc->pix_fmt == AV_PIX_FMT_BGRA) {
+        int i;
+        for (i = 3; i + 1 <= pkt->size; i += 4)
+            pkt->data[i] = 0xFF - pkt->data[i];
+    }
+
+    pkt->stream_index = 0;
+    s->count++;
+
+    return 0;
+}
+
+AVInputFormat ff_frm_demuxer = {
+    .name           = "frm",
+    .priv_data_size = sizeof(FrmContext),
+    .long_name      = NULL_IF_CONFIG_SMALL("Megalux Frame"),
+    .read_probe     = frm_read_probe,
+    .read_header    = frm_read_header,
+    .read_packet    = frm_read_packet,
+};
diff --git a/libavformat/gifdec.c b/libavformat/gifdec.c
index 46eef7c..1122849 100644
--- a/libavformat/gifdec.c
+++ b/libavformat/gifdec.c
@@ -44,8 +44,6 @@
      */
     int min_delay;
     int default_delay;
-    int total_duration; ///< In hundredths of second.
-    int frame_idx;
 } GIFDemuxContext;
 
 /**
@@ -72,6 +70,19 @@
     return AVPROBE_SCORE_MAX;
 }
 
+static int resync(AVIOContext *pb)
+{
+    int i;
+    for (i = 0; i < 6; i++) {
+        int b = avio_r8(pb);
+        if (b != gif87a_sig[i] && b != gif89a_sig[i])
+            i = -(b != 'G');
+        if (url_feof(pb))
+            return AVERROR_EOF;
+    }
+    return 0;
+}
+
 static int gif_read_header(AVFormatContext *s)
 {
     GIFDemuxContext *gdc = s->priv_data;
@@ -79,8 +90,7 @@
     AVStream        *st;
     int width, height, ret;
 
-    /* skip 6-byte magick */
-    if ((ret = avio_skip(pb, 6)) < 0)
+    if ((ret = resync(pb)) < 0)
         return ret;
 
     gdc->delay  = gdc->default_delay;
@@ -173,6 +183,7 @@
     }
 
     if (keyframe) {
+parse_keyframe:
         /* skip 2 bytes of width and 2 of height */
         if ((ret = avio_skip(pb, 4)) < 0)
             return ret;
@@ -183,16 +194,13 @@
         if ((ret = avio_skip(pb, 2)) < 0)
             return ret;
 
-        /* glogal color table presence */
+        /* global color table presence */
         if (packed_fields & 0x80) {
             ct_size = 3 * (1 << ((packed_fields & 0x07) + 1));
 
             if ((ret = avio_skip(pb, ct_size)) < 0)
                 return ret;
         }
-
-        gdc->total_duration = 0;
-        gdc->frame_idx      = 0;
     } else {
         avio_seek(pb, -ret, SEEK_CUR);
         ret = AVERROR_EOF;
@@ -201,7 +209,7 @@
     while (GIF_TRAILER != (block_label = avio_r8(pb)) && !url_feof(pb)) {
         if (block_label == GIF_EXTENSION_INTRODUCER) {
             if ((ret = gif_read_ext (s)) < 0 )
-                return ret;
+                goto resync;
         } else if (block_label == GIF_IMAGE_SEPARATOR) {
             /* skip to last byte of Image Descriptor header */
             if ((ret = avio_skip(pb, 8)) < 0)
@@ -220,11 +228,11 @@
             /* read LZW Minimum Code Size */
             if (avio_r8(pb) < 1) {
                 av_log(s, AV_LOG_ERROR, "lzw minimum code size must be >= 1\n");
-                return AVERROR_INVALIDDATA;
+                goto resync;
             }
 
             if ((ret = gif_skip_subblocks(pb)) < 0)
-                return ret;
+                goto resync;
 
             frame_end = avio_tell(pb);
 
@@ -239,28 +247,31 @@
                 pkt->flags |= AV_PKT_FLAG_KEY;
 
             pkt->stream_index = 0;
-            pkt->pts = gdc->total_duration;
-            gdc->total_duration += gdc->delay;
             pkt->duration = gdc->delay;
-            pkt->dts = gdc->frame_idx;
 
             /* Graphic Control Extension's scope is single frame.
              * Remove its influence. */
             gdc->delay = gdc->default_delay;
-            gdc->frame_idx++;
             frame_parsed = 1;
 
             break;
         } else {
             av_log(s, AV_LOG_ERROR, "invalid block label\n");
-            return AVERROR_INVALIDDATA;
+resync:
+            if (!keyframe)
+                avio_seek(pb, frame_start, SEEK_SET);
+            if ((ret = resync(pb)) < 0)
+                return ret;
+            frame_start = avio_tell(pb) - 6;
+            keyframe = 1;
+            goto parse_keyframe;
         }
     }
 
     if (ret >= 0 && !frame_parsed) {
         /* This might happen when there is no image block
          * between extension blocks and GIF_TRAILER or EOF */
-        return  AVERROR_EOF;
+        return AVERROR_EOF;
     } else
         return ret;
 }
diff --git a/libavformat/hls.c b/libavformat/hls.c
index f515dfb..0b7d050 100644
--- a/libavformat/hls.c
+++ b/libavformat/hls.c
@@ -103,6 +103,8 @@
     int64_t seek_timestamp;
     int seek_flags;
     AVIOInterruptCB *interrupt_callback;
+    char *user_agent;                    ///< holds HTTP user agent set as an AVOption to the HTTP protocol context
+    char *cookies;                       ///< holds HTTP cookie values set in either the initial response or as an AVOption to the HTTP protocol context
 } HLSContext;
 
 static int read_chomp_line(AVIOContext *s, char *buf, int maxlen)
@@ -139,6 +141,8 @@
         av_free(var);
     }
     av_freep(&c->variants);
+    av_freep(&c->cookies);
+    av_freep(&c->user_agent);
     c->n_variants = 0;
 }
 
@@ -216,6 +220,11 @@
         close_in = 1;
         /* Some HLS servers dont like being sent the range header */
         av_dict_set(&opts, "seekable", "0", 0);
+
+        // broker prior HTTP options that should be consistent across requests
+        av_dict_set(&opts, "user-agent", c->user_agent, 0);
+        av_dict_set(&opts, "cookies", c->cookies, 0);
+
         ret = avio_open2(&in, url, AVIO_FLAG_READ,
                          c->interrupt_callback, &opts);
         av_dict_free(&opts);
@@ -328,12 +337,17 @@
     return ret;
 }
 
-static int open_input(struct variant *var)
+static int open_input(HLSContext *c, struct variant *var)
 {
     AVDictionary *opts = NULL;
     int ret;
     struct segment *seg = var->segments[var->cur_seq_no - var->start_seq_no];
+
+    // broker prior HTTP options that should be consistent across requests
+    av_dict_set(&opts, "user-agent", c->user_agent, 0);
+    av_dict_set(&opts, "cookies", c->cookies, 0);
     av_dict_set(&opts, "seekable", "0", 0);
+
     if (seg->key_type == KEY_NONE) {
         ret = ffurl_open(&var->input, seg->url, AVIO_FLAG_READ,
                           &var->parent->interrupt_callback, &opts);
@@ -429,7 +443,7 @@
             goto reload;
         }
 
-        ret = open_input(v);
+        ret = open_input(c, v);
         if (ret < 0)
             return ret;
     }
@@ -461,11 +475,27 @@
 
 static int hls_read_header(AVFormatContext *s)
 {
+    URLContext *u = (s->flags & AVFMT_FLAG_CUSTOM_IO) ? NULL : s->pb->opaque;
     HLSContext *c = s->priv_data;
     int ret = 0, i, j, stream_offset = 0;
 
     c->interrupt_callback = &s->interrupt_callback;
 
+    // if the URL context is good, read important options we must broker later
+    if (u && u->prot->priv_data_class) {
+        // get the previous user agent & set back to null if string size is zero
+        av_freep(&c->user_agent);
+        av_opt_get(u->priv_data, "user-agent", 0, (uint8_t**)&(c->user_agent));
+        if (c->user_agent && !strlen(c->user_agent))
+            av_freep(&c->user_agent);
+
+        // get the previous cookies & set back to null if string size is zero
+        av_freep(&c->cookies);
+        av_opt_get(u->priv_data, "cookies", 0, (uint8_t**)&(c->cookies));
+        if (c->cookies && !strlen(c->cookies))
+            av_freep(&c->cookies);
+    }
+
     if ((ret = parse_playlist(c, s->filename, NULL, s->pb)) < 0)
         goto fail;
 
diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index ecf07ef..18914c0 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -38,7 +38,8 @@
 
 typedef struct HLSContext {
     const AVClass *class;  // Class for private options.
-    int number;
+    unsigned number;
+    int64_t sequence;
     AVOutputFormat *oformat;
     AVFormatContext *avf;
     float time;            // Set by a private option.
@@ -48,6 +49,8 @@
     int has_video;
     int64_t start_pts;
     int64_t end_pts;
+    int64_t duration;      ///< last segment duration computed so far, in seconds
+    int nb_entries;
     ListEntry *list;
     ListEntry *end_list;
     char *basename;
@@ -85,8 +88,7 @@
     if (!en)
         return AVERROR(ENOMEM);
 
-    av_get_frame_filename(en->name, sizeof(en->name), hls->basename,
-                          hls->number -1);
+    av_strlcpy(en->name, av_basename(hls->avf->filename), sizeof(en->name));
 
     en->duration = duration;
     en->next     = NULL;
@@ -98,11 +100,14 @@
 
     hls->end_list = en;
 
-    if (hls->number >= hls->size) {
+    if (hls->nb_entries >= hls->size) {
         en = hls->list;
         hls->list = en->next;
         av_free(en);
-    }
+    } else
+        hls->nb_entries++;
+
+    hls->sequence++;
 
     return 0;
 }
@@ -122,17 +127,23 @@
 {
     HLSContext *hls = s->priv_data;
     ListEntry *en;
+    int target_duration = 0;
     int ret = 0;
 
     if ((ret = avio_open2(&hls->pb, s->filename, AVIO_FLAG_WRITE,
                           &s->interrupt_callback, NULL)) < 0)
         goto fail;
 
+    for (en = hls->list; en; en = en->next) {
+        if (target_duration < en->duration)
+            target_duration = en->duration;
+    }
+
     avio_printf(hls->pb, "#EXTM3U\n");
     avio_printf(hls->pb, "#EXT-X-VERSION:3\n");
-    avio_printf(hls->pb, "#EXT-X-TARGETDURATION:%d\n", (int)hls->time);
-    avio_printf(hls->pb, "#EXT-X-MEDIA-SEQUENCE:%d\n",
-                FFMAX(0, hls->number - hls->size));
+    avio_printf(hls->pb, "#EXT-X-TARGETDURATION:%d\n", target_duration);
+    avio_printf(hls->pb, "#EXT-X-MEDIA-SEQUENCE:%"PRId64"\n",
+                FFMAX(0, hls->sequence - hls->size));
 
     for (en = hls->list; en; en = en->next) {
         avio_printf(hls->pb, "#EXTINF:%d,\n", en->duration);
@@ -157,8 +168,10 @@
         c->number %= c->wrap;
 
     if (av_get_frame_filename(oc->filename, sizeof(oc->filename),
-                              c->basename, c->number++) < 0)
+                              c->basename, c->number++) < 0) {
+        av_log(oc, AV_LOG_ERROR, "Invalid segment filename template '%s'\n", c->basename);
         return AVERROR(EINVAL);
+    }
 
     if ((err = avio_open2(&oc->pb, oc->filename, AVIO_FLAG_WRITE,
                           &s->interrupt_callback, NULL)) < 0)
@@ -176,11 +189,11 @@
     int ret, i;
     char *p;
     const char *pattern = "%d.ts";
-    int basename_size = strlen(s->filename) + strlen(pattern);
+    int basename_size = strlen(s->filename) + strlen(pattern) + 1;
 
     hls->number      = 0;
 
-    hls->recording_time = hls->time * 1000000;
+    hls->recording_time = hls->time * AV_TIME_BASE;
     hls->start_pts      = AV_NOPTS_VALUE;
 
     for (i = 0; i < s->nb_streams; i++)
@@ -213,7 +226,7 @@
     if (p)
         *p = '\0';
 
-    av_strlcat(hls->basename, "%d.ts", basename_size);
+    av_strlcat(hls->basename, pattern, basename_size);
 
     if ((ret = hls_mux_init(s)) < 0)
         goto fail;
@@ -240,22 +253,31 @@
     AVFormatContext *oc = hls->avf;
     AVStream *st = s->streams[pkt->stream_index];
     int64_t end_pts = hls->recording_time * hls->number;
-    int ret;
+    int ret, is_ref_pkt = 0;
 
     if (hls->start_pts == AV_NOPTS_VALUE) {
         hls->start_pts = pkt->pts;
         hls->end_pts   = pkt->pts;
     }
-    end_pts += hls->start_pts;
 
     if ((hls->has_video && st->codec->codec_type == AVMEDIA_TYPE_VIDEO)      &&
-        av_compare_ts(pkt->pts, st->time_base, end_pts, AV_TIME_BASE_Q) >= 0 &&
+        pkt->pts != AV_NOPTS_VALUE) {
+        is_ref_pkt = 1;
+        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) {
 
-        append_entry(hls, av_rescale(pkt->pts - hls->end_pts,
-                                     st->time_base.num,
-                                     st->time_base.den));
+        ret = append_entry(hls, hls->duration);
+        if (ret)
+            return ret;
+
         hls->end_pts = pkt->pts;
+        hls->duration = 0;
 
         av_write_frame(oc, NULL); /* Flush any buffered data */
         avio_close(oc->pb);
@@ -285,6 +307,7 @@
     avio_closep(&oc->pb);
     avformat_free_context(oc);
     av_free(hls->basename);
+    append_entry(hls, hls->duration);
     hls_window(s, 1);
 
     free_entries(hls);
@@ -295,9 +318,10 @@
 #define OFFSET(x) offsetof(HLSContext, x)
 #define E AV_OPT_FLAG_ENCODING_PARAM
 static const AVOption options[] = {
-    {"hls_time",      "segment length in seconds",               OFFSET(time),    AV_OPT_TYPE_FLOAT,  {.dbl = 2},     0, FLT_MAX, E},
-    {"hls_list_size", "maximum number of playlist entries",      OFFSET(size),    AV_OPT_TYPE_INT,    {.i64 = 5},     0, INT_MAX, E},
-    {"hls_wrap",      "number after which the index wraps",      OFFSET(wrap),    AV_OPT_TYPE_INT,    {.i64 = 0},     0, INT_MAX, E},
+    {"start_number",  "set first number in the sequence",        OFFSET(sequence),AV_OPT_TYPE_INT64,  {.i64 = 0},     0, INT64_MAX, E},
+    {"hls_time",      "set segment length in seconds",           OFFSET(time),    AV_OPT_TYPE_FLOAT,  {.dbl = 2},     0, FLT_MAX, E},
+    {"hls_list_size", "set maximum number of playlist entries",  OFFSET(size),    AV_OPT_TYPE_INT,    {.i64 = 5},     0, INT_MAX, E},
+    {"hls_wrap",      "set number after which the index wraps",  OFFSET(wrap),    AV_OPT_TYPE_INT,    {.i64 = 0},     0, INT_MAX, E},
     { NULL },
 };
 
@@ -311,7 +335,7 @@
 
 AVOutputFormat ff_hls_muxer = {
     .name           = "hls",
-    .long_name      = NULL_IF_CONFIG_SMALL("hls"),
+    .long_name      = NULL_IF_CONFIG_SMALL("Apple HTTP Live Streaming"),
     .extensions     = "m3u8",
     .priv_data_size = sizeof(HLSContext),
     .audio_codec    = AV_CODEC_ID_MP2,
diff --git a/libavformat/http.c b/libavformat/http.c
index 308c22d..5946000 100644
--- a/libavformat/http.c
+++ b/libavformat/http.c
@@ -63,6 +63,8 @@
     int post_datalen;
     int is_akamai;
     int rw_timeout;
+    char *mime_type;
+    char *cookies;          ///< holds newline (\n) delimited Set-Cookie header field values (without the "Set-Cookie: " field name)
 } HTTPContext;
 
 #define OFFSET(x) offsetof(HTTPContext, x)
@@ -70,14 +72,16 @@
 #define E AV_OPT_FLAG_ENCODING_PARAM
 #define DEC AV_OPT_FLAG_DECODING_PARAM
 static const AVOption options[] = {
-{"seekable", "Control seekability of connection", OFFSET(seekable), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, D },
+{"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 },
-{"headers", "custom HTTP headers, can override built in default headers", OFFSET(headers), AV_OPT_TYPE_STRING, { 0 }, 0, 0, D|E },
+{"headers", "set custom HTTP headers, can override built in default headers", OFFSET(headers), AV_OPT_TYPE_STRING, { 0 }, 0, 0, D|E },
 {"content_type", "force a content type", OFFSET(content_type), AV_OPT_TYPE_STRING, { 0 }, 0, 0, D|E },
 {"user-agent", "override User-Agent header", OFFSET(user_agent), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC},
 {"multiple_requests", "use persistent connections", OFFSET(multiple_requests), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, D|E },
-{"post_data", "custom HTTP post data", OFFSET(post_data), AV_OPT_TYPE_BINARY, .flags = D|E },
-{"timeout", "timeout of socket i/o operations", OFFSET(rw_timeout), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, D|E },
+{"post_data", "set custom HTTP post data", OFFSET(post_data), AV_OPT_TYPE_BINARY, .flags = D|E },
+{"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 },
 {NULL}
 };
 #define HTTP_CLASS(flavor)\
@@ -116,10 +120,6 @@
     HTTPAuthType cur_auth_type, cur_proxy_auth_type;
     HTTPContext *s = h->priv_data;
 
-    proxy_path = getenv("http_proxy");
-    use_proxy = (proxy_path != NULL) && !getenv("no_proxy") &&
-        av_strstart(proxy_path, "http://", NULL);
-
     /* fill the dest addr */
  redo:
     /* needed in any case to build the host string */
@@ -128,6 +128,10 @@
                  path1, sizeof(path1), s->location);
     ff_url_join(hoststr, sizeof(hoststr), NULL, NULL, hostname, port, NULL);
 
+    proxy_path = getenv("http_proxy");
+    use_proxy = !ff_http_match_no_proxy(getenv("no_proxy"), hostname) &&
+                proxy_path != NULL && av_strstart(proxy_path, "http://", NULL);
+
     if (!strcmp(proto, "https")) {
         lower_proto = "tls";
         use_proxy = 0;
@@ -355,11 +359,122 @@
                 s->willclose = 1;
         } else if (!av_strcasecmp (tag, "Server") && !av_strcasecmp (p, "AkamaiGHost")) {
             s->is_akamai = 1;
+        } else if (!av_strcasecmp (tag, "Content-Type")) {
+            av_free(s->mime_type); s->mime_type = av_strdup(p);
+        } else if (!av_strcasecmp (tag, "Set-Cookie")) {
+            if (!s->cookies) {
+                if (!(s->cookies = av_strdup(p)))
+                    return AVERROR(ENOMEM);
+            } else {
+                char *tmp = s->cookies;
+                size_t str_size = strlen(tmp) + strlen(p) + 2;
+                if (!(s->cookies = av_malloc(str_size))) {
+                    s->cookies = tmp;
+                    return AVERROR(ENOMEM);
+                }
+                snprintf(s->cookies, str_size, "%s\n%s", tmp, p);
+                av_free(tmp);
+            }
         }
     }
     return 1;
 }
 
+/**
+ * Create a string containing cookie values for use as a HTTP cookie header
+ * field value for a particular path and domain from the cookie values stored in
+ * the HTTP protocol context. The cookie string is stored in *cookies.
+ *
+ * @return a negative value if an error condition occurred, 0 otherwise
+ */
+static int get_cookies(HTTPContext *s, char **cookies, const char *path,
+                       const char *domain)
+{
+    // cookie strings will look like Set-Cookie header field values.  Multiple
+    // Set-Cookie fields will result in multiple values delimited by a newline
+    int ret = 0;
+    char *next, *cookie, *set_cookies = av_strdup(s->cookies), *cset_cookies = set_cookies;
+
+    if (!set_cookies) return AVERROR(EINVAL);
+
+    *cookies = NULL;
+    while ((cookie = av_strtok(set_cookies, "\n", &next))) {
+        int domain_offset = 0;
+        char *param, *next_param, *cdomain = NULL, *cpath = NULL, *cvalue = NULL;
+        set_cookies = NULL;
+
+        while ((param = av_strtok(cookie, "; ", &next_param))) {
+            cookie = NULL;
+            if        (!av_strncasecmp("path=",   param, 5)) {
+                av_free(cpath);
+                cpath = av_strdup(&param[5]);
+            } else if (!av_strncasecmp("domain=", param, 7)) {
+                av_free(cdomain);
+                cdomain = av_strdup(&param[7]);
+            } else if (!av_strncasecmp("secure",  param, 6) ||
+                       !av_strncasecmp("comment", param, 7) ||
+                       !av_strncasecmp("max-age", param, 7) ||
+                       !av_strncasecmp("version", param, 7)) {
+                // ignore Comment, Max-Age, Secure and Version
+            } else {
+                av_free(cvalue);
+                cvalue = av_strdup(param);
+            }
+        }
+
+        // ensure all of the necessary values are valid
+        if (!cdomain || !cpath || !cvalue) {
+            av_log(s, AV_LOG_WARNING,
+                   "Invalid cookie found, no value, path or domain specified\n");
+            goto done_cookie;
+        }
+
+        // check if the request path matches the cookie path
+        if (av_strncasecmp(path, cpath, strlen(cpath)))
+            goto done_cookie;
+
+        // the domain should be at least the size of our cookie domain
+        domain_offset = strlen(domain) - strlen(cdomain);
+        if (domain_offset < 0)
+            goto done_cookie;
+
+        // match the cookie domain
+        if (av_strcasecmp(&domain[domain_offset], cdomain))
+            goto done_cookie;
+
+        // cookie parameters match, so copy the value
+        if (!*cookies) {
+            if (!(*cookies = av_strdup(cvalue))) {
+                ret = AVERROR(ENOMEM);
+                goto done_cookie;
+            }
+        } else {
+            char *tmp = *cookies;
+            size_t str_size = strlen(cvalue) + strlen(*cookies) + 3;
+            if (!(*cookies = av_malloc(str_size))) {
+                ret = AVERROR(ENOMEM);
+                goto done_cookie;
+            }
+            snprintf(*cookies, str_size, "%s; %s", tmp, cvalue);
+            av_free(tmp);
+        }
+
+        done_cookie:
+        av_free(cdomain);
+        av_free(cpath);
+        av_free(cvalue);
+        if (ret < 0) {
+            if (*cookies) av_freep(cookies);
+            av_free(cset_cookies);
+            return ret;
+        }
+    }
+
+    av_free(cset_cookies);
+
+    return 0;
+}
+
 static inline int has_header(const char *str, const char *header)
 {
     /* header + 2 to skip over CRLF prefix. (make sure you have one!) */
@@ -456,6 +571,14 @@
     if (!has_header(s->headers, "\r\nContent-Type: ") && s->content_type)
         len += av_strlcatf(headers + len, sizeof(headers) - len,
                            "Content-Type: %s\r\n", s->content_type);
+    if (!has_header(s->headers, "\r\nCookie: ") && s->cookies) {
+        char *cookies = NULL;
+        if (!get_cookies(s, &cookies, path, hoststr)) {
+            len += av_strlcatf(headers + len, sizeof(headers) - len,
+                               "Cookie: %s\r\n", cookies);
+            av_free(cookies);
+        }
+    }
 
     /* now add in custom headers */
     if (s->headers)
diff --git a/libavformat/icoenc.c b/libavformat/icoenc.c
index cbf8bd9..3e6a1ea 100644
--- a/libavformat/icoenc.c
+++ b/libavformat/icoenc.c
@@ -44,7 +44,7 @@
 
 static int ico_check_attributes(AVFormatContext *s, const AVCodecContext *c)
 {
-    if (c->codec_id == CODEC_ID_BMP) {
+    if (c->codec_id == AV_CODEC_ID_BMP) {
         if (c->pix_fmt == AV_PIX_FMT_PAL8 && AV_PIX_FMT_RGB32 != AV_PIX_FMT_BGRA) {
             av_log(s, AV_LOG_ERROR, "Wrong endianness for bmp pixel format\n");
             return AVERROR(EINVAL);
@@ -55,7 +55,7 @@
             av_log(s, AV_LOG_ERROR, "BMP must be 1bit, 4bit, 8bit, 16bit, 24bit, or 32bit\n");
             return AVERROR(EINVAL);
         }
-    } else if (c->codec_id == CODEC_ID_PNG) {
+    } else if (c->codec_id == AV_CODEC_ID_PNG) {
         if (c->pix_fmt != AV_PIX_FMT_RGBA) {
             av_log(s, AV_LOG_ERROR, "PNG in ico requires pixel format to be rgba\n");
             return AVERROR(EINVAL);
@@ -129,7 +129,7 @@
     image->width = (c->width == 256) ? 0 : c->width;
     image->height = (c->height == 256) ? 0 : c->height;
 
-    if (c->codec_id == CODEC_ID_PNG) {
+    if (c->codec_id == AV_CODEC_ID_PNG) {
         image->bits = c->bits_per_coded_sample;
         image->size = pkt->size;
 
@@ -170,7 +170,7 @@
         avio_w8(pb, ico->images[i].width);
         avio_w8(pb, ico->images[i].height);
 
-        if (s->streams[i]->codec->codec_id == CODEC_ID_BMP &&
+        if (s->streams[i]->codec->codec_id == AV_CODEC_ID_BMP &&
             s->streams[i]->codec->pix_fmt == AV_PIX_FMT_PAL8) {
             avio_w8(pb, (ico->images[i].bits >= 8) ? 0 : 1 << ico->images[i].bits);
         } else {
@@ -195,8 +195,8 @@
     .priv_data_size = sizeof(IcoMuxContext),
     .mime_type      = "image/vnd.microsoft.icon",
     .extensions     = "ico",
-    .audio_codec    = CODEC_ID_NONE,
-    .video_codec    = CODEC_ID_BMP,
+    .audio_codec    = AV_CODEC_ID_NONE,
+    .video_codec    = AV_CODEC_ID_BMP,
     .write_header   = ico_write_header,
     .write_packet   = ico_write_packet,
     .write_trailer  = ico_write_trailer,
diff --git a/libavformat/id3v1.c b/libavformat/id3v1.c
index 2d1e806..d73adc7 100644
--- a/libavformat/id3v1.c
+++ b/libavformat/id3v1.c
@@ -23,6 +23,7 @@
 #include "libavcodec/avcodec.h"
 #include "libavutil/dict.h"
 
+/* See Genre List at http://id3.org/id3v2.3.0 */
 const char * const ff_id3v1_genre_str[ID3v1_GENRE_MAX + 1] = {
       [0] = "Blues",
       [1] = "Classic Rock",
@@ -91,7 +92,7 @@
      [64] = "Native American",
      [65] = "Cabaret",
      [66] = "New Wave",
-     [67] = "Psychadelic",
+     [67] = "Psychadelic", /* sic, the misspelling is used in the specification */
      [68] = "Rave",
      [69] = "Showtunes",
      [70] = "Trailer",
diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c
index f805f5b..2cab5ac 100644
--- a/libavformat/id3v2.c
+++ b/libavformat/id3v2.c
@@ -788,10 +788,12 @@
         /* save the current offset in case there's nothing to read/skip */
         off = avio_tell(s->pb);
         ret = avio_read(s->pb, buf, ID3v2_HEADER_SIZE);
-        if (ret != ID3v2_HEADER_SIZE)
+        if (ret != ID3v2_HEADER_SIZE) {
+            avio_seek(s->pb, off, SEEK_SET);
             break;
-            found_header = ff_id3v2_match(buf, magic);
-            if (found_header) {
+        }
+        found_header = ff_id3v2_match(buf, magic);
+        if (found_header) {
             /* parse ID3v2 header */
             len = ((buf[6] & 0x7f) << 21) |
                   ((buf[7] & 0x7f) << 14) |
diff --git a/libavformat/idcin.c b/libavformat/idcin.c
index bede040..c32607d 100644
--- a/libavformat/idcin.c
+++ b/libavformat/idcin.c
@@ -68,6 +68,8 @@
  *       transmitting them to the video decoder
  */
 
+#include "libavutil/audioconvert.h"
+#include "libavutil/imgutils.h"
 #include "libavutil/intreadwrite.h"
 #include "avformat.h"
 #include "internal.h"
@@ -80,13 +82,13 @@
     int audio_stream_index;
     int audio_chunk_size1;
     int audio_chunk_size2;
+    int block_align;
 
     /* demux state variables */
     int current_audio_chunk;
     int next_chunk_is_video;
     int audio_present;
-
-    int64_t pts;
+    int64_t first_pkt_pos;
 } IdcinDemuxContext;
 
 static int idcin_probe(AVProbeData *p)
@@ -145,6 +147,7 @@
     AVStream *st;
     unsigned int width, height;
     unsigned int sample_rate, bytes_per_sample, channels;
+    int ret;
 
     /* get the 5 header parameters */
     width = avio_rl32(pb);
@@ -153,10 +156,38 @@
     bytes_per_sample = avio_rl32(pb);
     channels = avio_rl32(pb);
 
+    if (s->pb->eof_reached) {
+        av_log(s, AV_LOG_ERROR, "incomplete header\n");
+        return s->pb->error ? s->pb->error : AVERROR_EOF;
+    }
+
+    if (av_image_check_size(width, height, 0, s) < 0)
+        return AVERROR_INVALIDDATA;
+    if (sample_rate > 0) {
+        if (sample_rate < 14 || sample_rate > INT_MAX) {
+            av_log(s, AV_LOG_ERROR, "invalid sample rate: %u\n", sample_rate);
+            return AVERROR_INVALIDDATA;
+        }
+        if (bytes_per_sample < 1 || bytes_per_sample > 2) {
+            av_log(s, AV_LOG_ERROR, "invalid bytes per sample: %u\n",
+                   bytes_per_sample);
+            return AVERROR_INVALIDDATA;
+        }
+        if (channels < 1 || channels > 2) {
+            av_log(s, AV_LOG_ERROR, "invalid channels: %u\n", channels);
+            return AVERROR_INVALIDDATA;
+        }
+        idcin->audio_present = 1;
+    } else {
+        /* if sample rate is 0, assume no audio */
+        idcin->audio_present = 0;
+    }
+
     st = avformat_new_stream(s, NULL);
     if (!st)
         return AVERROR(ENOMEM);
     avpriv_set_pts_info(st, 33, 1, IDCIN_FPS);
+    st->start_time = 0;
     idcin->video_stream_index = st->index;
     st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
     st->codec->codec_id = AV_CODEC_ID_IDCIN;
@@ -167,25 +198,31 @@
     /* load up the Huffman tables into extradata */
     st->codec->extradata_size = HUFFMAN_TABLE_SIZE;
     st->codec->extradata = av_malloc(HUFFMAN_TABLE_SIZE);
-    if (avio_read(pb, st->codec->extradata, HUFFMAN_TABLE_SIZE) !=
-        HUFFMAN_TABLE_SIZE)
+    ret = avio_read(pb, st->codec->extradata, HUFFMAN_TABLE_SIZE);
+    if (ret < 0) {
+        return ret;
+    } else if (ret != HUFFMAN_TABLE_SIZE) {
+        av_log(s, AV_LOG_ERROR, "incomplete header\n");
         return AVERROR(EIO);
+    }
 
-    /* if sample rate is 0, assume no audio */
-    if (sample_rate) {
+    if (idcin->audio_present) {
         idcin->audio_present = 1;
         st = avformat_new_stream(s, NULL);
         if (!st)
             return AVERROR(ENOMEM);
-        avpriv_set_pts_info(st, 33, 1, IDCIN_FPS);
+        avpriv_set_pts_info(st, 63, 1, sample_rate);
+        st->start_time = 0;
         idcin->audio_stream_index = st->index;
         st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
         st->codec->codec_tag = 1;
         st->codec->channels = channels;
+        st->codec->channel_layout = channels > 1 ? AV_CH_LAYOUT_STEREO :
+                                                   AV_CH_LAYOUT_MONO;
         st->codec->sample_rate = sample_rate;
         st->codec->bits_per_coded_sample = bytes_per_sample * 8;
         st->codec->bit_rate = sample_rate * bytes_per_sample * 8 * channels;
-        st->codec->block_align = bytes_per_sample * channels;
+        st->codec->block_align = idcin->block_align = bytes_per_sample * channels;
         if (bytes_per_sample == 1)
             st->codec->codec_id = AV_CODEC_ID_PCM_U8;
         else
@@ -201,11 +238,10 @@
                 (sample_rate / 14) * bytes_per_sample * channels;
         }
         idcin->current_audio_chunk = 0;
-    } else
-        idcin->audio_present = 1;
+    }
 
     idcin->next_chunk_is_video = 1;
-    idcin->pts = 0;
+    idcin->first_pkt_pos = avio_tell(s->pb);
 
     return 0;
 }
@@ -225,7 +261,7 @@
     uint32_t palette[256];
 
     if (url_feof(s->pb))
-        return AVERROR(EIO);
+        return s->pb->error ? s->pb->error : AVERROR_EOF;
 
     if (idcin->next_chunk_is_video) {
         command = avio_rl32(pb);
@@ -233,8 +269,13 @@
             return AVERROR(EIO);
         } else if (command == 1) {
             /* trigger a palette change */
-            if (avio_read(pb, palette_buffer, 768) != 768)
+            ret = avio_read(pb, palette_buffer, 768);
+            if (ret < 0) {
+                return ret;
+            } else if (ret != 768) {
+                av_log(s, AV_LOG_ERROR, "incomplete packet\n");
                 return AVERROR(EIO);
+            }
             /* scale the palette as necessary */
             palette_scale = 2;
             for (i = 0; i < 768; i++)
@@ -253,7 +294,15 @@
             }
         }
 
+        if (s->pb->eof_reached) {
+            av_log(s, AV_LOG_ERROR, "incomplete packet\n");
+            return s->pb->error ? s->pb->error : AVERROR_EOF;
+        }
         chunk_size = avio_rl32(pb);
+        if (chunk_size < 4 || chunk_size > INT_MAX - 4) {
+            av_log(s, AV_LOG_ERROR, "invalid chunk size: %u\n", chunk_size);
+            return AVERROR_INVALIDDATA;
+        }
         /* skip the number of decoded bytes (always equal to width * height) */
         avio_skip(pb, 4);
         if (chunk_size < 4)
@@ -262,17 +311,25 @@
         ret= av_get_packet(pb, pkt, chunk_size);
         if (ret < 0)
             return ret;
+        else if (ret != chunk_size) {
+            av_log(s, AV_LOG_ERROR, "incomplete packet\n");
+            av_free_packet(pkt);
+            return AVERROR(EIO);
+        }
         if (command == 1) {
             uint8_t *pal;
 
             pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE,
                                           AVPALETTE_SIZE);
-            if (!pal)
+            if (!pal) {
+                av_free_packet(pkt);
                 return AVERROR(ENOMEM);
+            }
             memcpy(pal, palette, AVPALETTE_SIZE);
+            pkt->flags |= AV_PKT_FLAG_KEY;
         }
         pkt->stream_index = idcin->video_stream_index;
-        pkt->pts = idcin->pts;
+        pkt->duration     = 1;
     } else {
         /* send out the audio chunk */
         if (idcin->current_audio_chunk)
@@ -283,16 +340,32 @@
         if (ret < 0)
             return ret;
         pkt->stream_index = idcin->audio_stream_index;
-        pkt->pts = idcin->pts;
+        pkt->duration     = chunk_size / idcin->block_align;
 
         idcin->current_audio_chunk ^= 1;
-        idcin->pts++;
     }
 
     if (idcin->audio_present)
         idcin->next_chunk_is_video ^= 1;
 
-    return ret;
+    return 0;
+}
+
+static int idcin_read_seek(AVFormatContext *s, int stream_index,
+                           int64_t timestamp, int flags)
+{
+    IdcinDemuxContext *idcin = s->priv_data;
+
+    if (idcin->first_pkt_pos > 0) {
+        int ret = avio_seek(s->pb, idcin->first_pkt_pos, SEEK_SET);
+        if (ret < 0)
+            return ret;
+        ff_update_cur_dts(s, s->streams[idcin->video_stream_index], 0);
+        idcin->next_chunk_is_video = 1;
+        idcin->current_audio_chunk = 0;
+        return 0;
+    }
+    return -1;
 }
 
 AVInputFormat ff_idcin_demuxer = {
@@ -302,4 +375,6 @@
     .read_probe     = idcin_probe,
     .read_header    = idcin_read_header,
     .read_packet    = idcin_read_packet,
+    .read_seek      = idcin_read_seek,
+    .flags          = AVFMT_NO_BYTE_SEEK,
 };
diff --git a/libavformat/iff.c b/libavformat/iff.c
index e59d49b..348026a 100644
--- a/libavformat/iff.c
+++ b/libavformat/iff.c
@@ -53,6 +53,8 @@
 #define ID_CMAP       MKTAG('C','M','A','P')
 #define ID_ACBM       MKTAG('A','C','B','M')
 #define ID_DEEP       MKTAG('D','E','E','P')
+#define ID_RGB8       MKTAG('R','G','B','8')
+#define ID_RGBN       MKTAG('R','G','B','N')
 
 #define ID_FORM       MKTAG('F','O','R','M')
 #define ID_ANNO       MKTAG('A','N','N','O')
@@ -68,6 +70,7 @@
 #define ID_DBOD       MKTAG('D','B','O','D')
 #define ID_DPEL       MKTAG('D','P','E','L')
 #define ID_DLOC       MKTAG('D','L','O','C')
+#define ID_TVDC       MKTAG('T','V','D','C')
 
 #define LEFT    2
 #define RIGHT   4
@@ -81,7 +84,7 @@
  * set it to smallest possible size of 2 to indicate that there's
  * no extradata changing in this frame.
  */
-#define IFF_EXTRA_VIDEO_SIZE 9
+#define IFF_EXTRA_VIDEO_SIZE 41
 
 typedef enum {
     COMP_NONE,
@@ -90,9 +93,9 @@
 } svx8_compression_type;
 
 typedef struct {
-    uint64_t  body_pos;
+    int64_t  body_pos;
+    int64_t  body_end;
     uint32_t  body_size;
-    uint32_t  sent_bytes;
     svx8_compression_type   svx8_compression;
     unsigned  maud_bits;
     unsigned  maud_compression;
@@ -102,6 +105,7 @@
     unsigned  flags;        ///< 1 for EHB, 0 is no extra half darkening
     unsigned  transparency; ///< transparency color index in palette
     unsigned  masking;      ///< masking method used
+    uint8_t   tvdc[32];     ///< TVDC lookup table
 } IffDemuxContext;
 
 /* Metadata string read */
@@ -134,7 +138,9 @@
           AV_RL32(d+8) == ID_PBM  ||
           AV_RL32(d+8) == ID_ACBM ||
           AV_RL32(d+8) == ID_DEEP ||
-          AV_RL32(d+8) == ID_ILBM) )
+          AV_RL32(d+8) == ID_ILBM ||
+          AV_RL32(d+8) == ID_RGB8 ||
+          AV_RL32(d+8) == ID_RGBN) )
         return AVPROBE_SCORE_MAX;
     return 0;
 }
@@ -221,6 +227,7 @@
         case ID_DBOD:
         case ID_MDAT:
             iff->body_pos = avio_tell(pb);
+            iff->body_end = iff->body_pos + data_size;
             iff->body_size = data_size;
             break;
 
@@ -313,6 +320,14 @@
             st->codec->height = avio_rb16(pb);
             break;
 
+        case ID_TVDC:
+            if (data_size < sizeof(iff->tvdc))
+                return AVERROR_INVALIDDATA;
+            res = avio_read(pb, iff->tvdc, sizeof(iff->tvdc));
+            if (res < 0)
+                return res;
+            break;
+
         case ID_ANNO:
         case ID_TEXT:      metadata_tag = "comment";   break;
         case ID_AUTH:      metadata_tag = "artist";    break;
@@ -403,6 +418,7 @@
         bytestream_put_byte(&buf, iff->flags);
         bytestream_put_be16(&buf, iff->transparency);
         bytestream_put_byte(&buf, iff->masking);
+        bytestream_put_buffer(&buf, iff->tvdc, sizeof(iff->tvdc));
         st->codec->codec_id = AV_CODEC_ID_IFF_ILBM;
         break;
     default:
@@ -419,14 +435,14 @@
     AVIOContext *pb = s->pb;
     AVStream *st = s->streams[0];
     int ret;
+    int64_t pos = avio_tell(pb);
 
-    if(iff->sent_bytes >= iff->body_size)
+    if (pos >= iff->body_end)
         return AVERROR_EOF;
 
     if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
         if (st->codec->codec_tag == ID_MAUD) {
-            ret = av_get_packet(pb, pkt,
-                                FFMIN(iff->body_size - iff->sent_bytes, 1024 * st->codec->block_align));
+            ret = av_get_packet(pb, pkt, FFMIN(iff->body_end - pos, 1024 * st->codec->block_align));
         } else {
             ret = av_get_packet(pb, pkt, iff->body_size);
         }
@@ -444,11 +460,10 @@
         av_assert0(0);
     }
 
-    if(iff->sent_bytes == 0)
+    if (pos == iff->body_pos)
         pkt->flags |= AV_PKT_FLAG_KEY;
     if (ret < 0)
         return ret;
-    iff->sent_bytes += ret;
     pkt->stream_index = 0;
     return ret;
 }
@@ -460,4 +475,5 @@
     .read_probe     = iff_probe,
     .read_header    = iff_read_header,
     .read_packet    = iff_read_packet,
+    .flags          = AVFMT_GENERIC_INDEX,
 };
diff --git a/libavformat/img2dec.c b/libavformat/img2dec.c
index f492bba..882abb9 100644
--- a/libavformat/img2dec.c
+++ b/libavformat/img2dec.c
@@ -46,6 +46,7 @@
     int img_first;
     int img_last;
     int img_number;
+    int64_t pts;
     int img_count;
     int is_pipe;
     int split_planes;       /**< use independent file for each Y, U, V plane */
@@ -393,6 +394,8 @@
         return AVERROR(ENOMEM);
     pkt->stream_index = 0;
     pkt->flags       |= AV_PKT_FLAG_KEY;
+    if (!s->is_pipe)
+        pkt->pts      = s->pts;
 
     pkt->size = 0;
     for (i = 0; i < 3; i++) {
@@ -411,6 +414,7 @@
     } else {
         s->img_count++;
         s->img_number++;
+        s->pts++;
         return 0;
     }
 }
@@ -426,6 +430,17 @@
     return 0;
 }
 
+static int img_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
+{
+    VideoDemuxData *s1 = s->priv_data;
+
+    if (timestamp < 0 || !s1->loop && timestamp > s1->img_last - s1->img_first)
+        return -1;
+    s1->img_number = timestamp%(s1->img_last - s1->img_first + 1) + s1->img_first;
+    s1->pts = timestamp;
+    return 0;
+}
+
 #define OFFSET(x) offsetof(VideoDemuxData, x)
 #define DEC AV_OPT_FLAG_DECODING_PARAM
 static const AVOption options[] = {
@@ -433,9 +448,9 @@
     { "loop",         "force loop over input file sequence", OFFSET(loop),         AV_OPT_TYPE_INT,    {.i64 = 0   }, 0, 1,       DEC },
 
     { "pattern_type", "set pattern type",                    OFFSET(pattern_type), AV_OPT_TYPE_INT,    {.i64=PT_GLOB_SEQUENCE}, 0,       INT_MAX, DEC, "pattern_type"},
-    { "glob_sequence","glob/sequence pattern type",          0,                    AV_OPT_TYPE_CONST,  {.i64=PT_GLOB_SEQUENCE}, INT_MIN, INT_MAX, DEC, "pattern_type" },
-    { "glob",         "glob pattern type",                   0,                    AV_OPT_TYPE_CONST,  {.i64=PT_GLOB         }, INT_MIN, INT_MAX, DEC, "pattern_type" },
-    { "sequence",     "glob pattern type",                   0,                    AV_OPT_TYPE_CONST,  {.i64=PT_SEQUENCE     }, INT_MIN, INT_MAX, DEC, "pattern_type" },
+    { "glob_sequence","select glob/sequence pattern type",   0, AV_OPT_TYPE_CONST,  {.i64=PT_GLOB_SEQUENCE}, INT_MIN, INT_MAX, DEC, "pattern_type" },
+    { "glob",         "select glob pattern type",            0, AV_OPT_TYPE_CONST,  {.i64=PT_GLOB         }, INT_MIN, INT_MAX, DEC, "pattern_type" },
+    { "sequence",     "select sequence pattern type",        0, AV_OPT_TYPE_CONST,  {.i64=PT_SEQUENCE     }, INT_MIN, INT_MAX, DEC, "pattern_type" },
 
     { "pixel_format", "set video pixel format",              OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0,       DEC },
     { "start_number", "set first number in the sequence",    OFFSET(start_number), AV_OPT_TYPE_INT,    {.i64 = 0   }, 0, INT_MAX, DEC },
@@ -460,6 +475,7 @@
     .read_header    = img_read_header,
     .read_packet    = img_read_packet,
     .read_close     = img_read_close,
+    .read_seek      = img_read_seek,
     .flags          = AVFMT_NOFILE,
     .priv_class     = &img2_class,
 };
diff --git a/libavformat/img2enc.c b/libavformat/img2enc.c
index 9621d3c..67b5819 100644
--- a/libavformat/img2enc.c
+++ b/libavformat/img2enc.c
@@ -78,7 +78,7 @@
         if (av_get_frame_filename(filename, sizeof(filename),
                                   img->path, img->img_number) < 0 && img->img_number > 1 && !img->updatefirst) {
             av_log(s, AV_LOG_ERROR,
-                   "Could not get frame filename number %d from pattern '%s'\n",
+                   "Could not get frame filename number %d from pattern '%s' (either set updatefirst or use a pattern like %%03d within the filename pattern)\n",
                    img->img_number, img->path);
             return AVERROR(EINVAL);
         }
@@ -128,8 +128,8 @@
 #define OFFSET(x) offsetof(VideoMuxData, x)
 #define ENC AV_OPT_FLAG_ENCODING_PARAM
 static const AVOption muxoptions[] = {
-    { "updatefirst",  "",                            OFFSET(updatefirst), AV_OPT_TYPE_INT, { .i64 = 0 }, 0,       1, ENC },
-    { "start_number", "first number in the sequence", OFFSET(img_number), AV_OPT_TYPE_INT, { .i64 = 1 }, 1, INT_MAX, ENC },
+    { "updatefirst",  "update the first image file",      OFFSET(updatefirst), 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 },
     { NULL },
 };
 
diff --git a/libavformat/internal.h b/libavformat/internal.h
index 14f4cdb..4d56388 100644
--- a/libavformat/internal.h
+++ b/libavformat/internal.h
@@ -292,14 +292,16 @@
                       int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t ));
 
 /**
- * Set the pts for a given stream. If the new values would be invalid
- * (<= 0), it leaves the AVStream unchanged.
+ * Set the time base and wrapping info for a given stream. This will be used
+ * to interpret the stream's timestamps. If the new time base is invalid
+ * (numerator or denominator are non-positive), it leaves the stream
+ * unchanged.
  *
  * @param s stream
  * @param pts_wrap_bits number of bits effectively used by the pts
- *        (used for wrap control, 33 is the value for MPEG)
- * @param pts_num numerator to convert to seconds (MPEG: 1)
- * @param pts_den denominator to convert to seconds (MPEG: 90000)
+ *        (used for wrap control)
+ * @param pts_num time base numerator
+ * @param pts_den time base denominator
  */
 void avpriv_set_pts_info(AVStream *s, int pts_wrap_bits,
                          unsigned int pts_num, unsigned int pts_den);
@@ -383,4 +385,11 @@
  */
 AVRational ff_choose_timebase(AVFormatContext *s, AVStream *st, int min_precission);
 
+/**
+ * Generate standard extradata for AVC-Intra based on width/height and field order.
+ */
+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/ipmovie.c b/libavformat/ipmovie.c
index 17ef7bb..676363b 100644
--- a/libavformat/ipmovie.c
+++ b/libavformat/ipmovie.c
@@ -527,8 +527,8 @@
 
 static int ipmovie_probe(AVProbeData *p)
 {
-    uint8_t *b = p->buf;
-    uint8_t *b_end = p->buf + p->buf_size - sizeof(signature);
+    const uint8_t *b = p->buf;
+    const uint8_t *b_end = p->buf + p->buf_size - sizeof(signature);
     do {
         if (b[0] == signature[0] && memcmp(b, signature, sizeof(signature)) == 0)
             return AVPROBE_SCORE_MAX;
diff --git a/libavformat/ircam.c b/libavformat/ircam.c
new file mode 100644
index 0000000..a267c18
--- /dev/null
+++ b/libavformat/ircam.c
@@ -0,0 +1,47 @@
+/*
+ * IRCAM common code
+ * 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 "avformat.h"
+#include "internal.h"
+
+const AVCodecTag ff_codec_ircam_le_tags[] = {
+    { AV_CODEC_ID_PCM_ALAW,  0x10001 },
+    { AV_CODEC_ID_PCM_F32LE, 0x00004 },
+    { AV_CODEC_ID_PCM_F64LE, 0x00008 },
+    { AV_CODEC_ID_PCM_MULAW, 0x20001 },
+    { AV_CODEC_ID_PCM_S16LE, 0x00002 },
+    { AV_CODEC_ID_PCM_S24LE, 0x00003 },
+    { AV_CODEC_ID_PCM_S32LE, 0x40004 },
+    { AV_CODEC_ID_PCM_S8,    0x00001 },
+    { AV_CODEC_ID_NONE,      0       },
+};
+
+const AVCodecTag ff_codec_ircam_be_tags[] = {
+    { AV_CODEC_ID_PCM_ALAW,  0x10001 },
+    { AV_CODEC_ID_PCM_F32BE, 0x00004 },
+    { AV_CODEC_ID_PCM_F64BE, 0x00008 },
+    { AV_CODEC_ID_PCM_MULAW, 0x20001 },
+    { AV_CODEC_ID_PCM_S16BE, 0x00002 },
+    { AV_CODEC_ID_PCM_S24BE, 0x00003 },
+    { AV_CODEC_ID_PCM_S32BE, 0x40004 },
+    { AV_CODEC_ID_PCM_S8,    0x00001 },
+    { AV_CODEC_ID_NONE,      0       },
+};
diff --git a/libavcodec/arm/dsputil_init_vfp.c b/libavformat/ircam.h
similarity index 66%
copy from libavcodec/arm/dsputil_init_vfp.c
copy to libavformat/ircam.h
index 5713c71..f7f9c84 100644
--- a/libavcodec/arm/dsputil_init_vfp.c
+++ b/libavformat/ircam.h
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2008 Siarhei Siamashka <ssvb@users.sourceforge.net>
+ * IRCAM common code
+ * Copyright (c) 2012 Paul B Mahol
  *
  * This file is part of FFmpeg.
  *
@@ -18,13 +19,12 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavcodec/dsputil.h"
-#include "dsputil_arm.h"
+#ifndef AVFORMAT_IRCAM_H
+#define AVFORMAT_IRCAM_H
 
-void ff_vector_fmul_reverse_vfp(float *dst, const float *src0,
-                                const float *src1, int len);
+#include "internal.h"
 
-void ff_dsputil_init_vfp(DSPContext* c, AVCodecContext *avctx)
-{
-    c->vector_fmul_reverse = ff_vector_fmul_reverse_vfp;
-}
+extern const AVCodecTag ff_codec_ircam_be_tags[];
+extern const AVCodecTag ff_codec_ircam_le_tags[];
+
+#endif /* AVFORMAT_IRCAM_H */
diff --git a/libavformat/ircamdec.c b/libavformat/ircamdec.c
new file mode 100644
index 0000000..f9533ec
--- /dev/null
+++ b/libavformat/ircamdec.c
@@ -0,0 +1,115 @@
+/*
+ * IRCAM demuxer
+ * 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/intreadwrite.h"
+#include "avformat.h"
+#include "internal.h"
+#include "pcm.h"
+#include "ircam.h"
+
+static int ircam_probe(AVProbeData *p)
+{
+    if ((p->buf[0] == 0x64 && p->buf[1] == 0xA3 && p->buf[3] == 0x00 &&
+         p->buf[2] >=    1 && p->buf[2] <= 4) ||
+        (p->buf[3] == 0x64 && p->buf[2] == 0xA3 && p->buf[0] == 0x00 &&
+         p->buf[1] >=    1 && p->buf[1] <= 3) &&
+        AV_RN32(p->buf + 4) && AV_RN32(p->buf + 8))
+        return AVPROBE_SCORE_MAX / 4 * 3;
+    return 0;
+}
+
+static const struct endianess {
+    uint32_t magic;
+    int      is_le;
+} table[] = {
+  { 0x64A30100, 0 },
+  { 0x64A30200, 1 },
+  { 0x64A30300, 0 },
+  { 0x64A30400, 1 },
+  { 0x0001A364, 1 },
+  { 0x0002A364, 0 },
+  { 0x0003A364, 1 },
+};
+
+static int ircam_read_header(AVFormatContext *s)
+{
+    uint32_t magic, sample_rate, channels, tag;
+    const AVCodecTag *tags;
+    int le = -1, i;
+    AVStream *st;
+
+    magic = avio_rl32(s->pb);
+    for (i = 0; i < 7; i++) {
+        if (magic == table[i].magic) {
+            le = table[i].is_le;
+            break;
+        }
+    }
+
+    if (le == 1) {
+        sample_rate = av_int2float(avio_rl32(s->pb));
+        channels    = avio_rl32(s->pb);
+        tag         = avio_rl32(s->pb);
+        tags        = ff_codec_ircam_le_tags;
+    } else if (le == 0) {
+        sample_rate = av_int2float(avio_rb32(s->pb));
+        channels    = avio_rb32(s->pb);
+        tag         = avio_rb32(s->pb);
+        tags        = ff_codec_ircam_be_tags;
+    } else {
+        return AVERROR_INVALIDDATA;
+    }
+
+    if (!channels || !sample_rate)
+        return AVERROR_INVALIDDATA;
+
+    st = avformat_new_stream(s, NULL);
+    if (!st)
+        return AVERROR(ENOMEM);
+
+    st->codec->codec_type  = AVMEDIA_TYPE_AUDIO;
+    st->codec->channels    = channels;
+    st->codec->sample_rate = sample_rate;
+
+    st->codec->codec_id = ff_codec_get_id(tags, tag);
+    if (st->codec->codec_id == AV_CODEC_ID_NONE) {
+        av_log(s, AV_LOG_ERROR, "unknown tag %X\n", tag);
+        return AVERROR_INVALIDDATA;
+    }
+
+    st->codec->bits_per_coded_sample = av_get_bits_per_sample(st->codec->codec_id);
+    st->codec->block_align = st->codec->bits_per_coded_sample * st->codec->channels / 8;
+    avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
+    avio_skip(s->pb, 1008);
+
+    return 0;
+}
+
+AVInputFormat ff_ircam_demuxer = {
+    .name           = "ircam",
+    .long_name      = NULL_IF_CONFIG_SMALL("Berkeley/IRCAM/CARL Sound Format"),
+    .read_probe     = ircam_probe,
+    .read_header    = ircam_read_header,
+    .read_packet    = ff_pcm_read_packet,
+    .read_seek      = ff_pcm_read_seek,
+    .extensions     = "sf,ircam",
+    .flags          = AVFMT_GENERIC_INDEX,
+};
diff --git a/libavformat/ircamenc.c b/libavformat/ircamenc.c
new file mode 100644
index 0000000..38f15fb
--- /dev/null
+++ b/libavformat/ircamenc.c
@@ -0,0 +1,62 @@
+/*
+ * IRCAM muxer
+ * 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/intreadwrite.h"
+#include "avformat.h"
+#include "avio_internal.h"
+#include "internal.h"
+#include "rawenc.h"
+#include "ircam.h"
+
+static int ircam_write_header(AVFormatContext *s)
+{
+    AVCodecContext *codec = s->streams[0]->codec;
+    uint32_t tag;
+
+    if (s->nb_streams != 1) {
+        av_log(s, AV_LOG_ERROR, "only one stream is supported\n");
+        return AVERROR(EINVAL);
+    }
+
+    tag = ff_codec_get_tag(ff_codec_ircam_le_tags, codec->codec_id);
+    if (!tag) {
+        av_log(s, AV_LOG_ERROR, "unsupported codec\n");
+        return AVERROR(EINVAL);
+    }
+
+    avio_wl32(s->pb, 0x0001A364);
+    avio_wl32(s->pb, av_float2int(codec->sample_rate));
+    avio_wl32(s->pb, codec->channels);
+    avio_wl32(s->pb, tag);
+    ffio_fill(s->pb, 0, 1008);
+    return 0;
+}
+
+AVOutputFormat ff_ircam_muxer = {
+    .name           = "ircam",
+    .extensions     = "sf,ircam",
+    .long_name      = NULL_IF_CONFIG_SMALL("Berkeley/IRCAM/CARL Sound Format"),
+    .audio_codec    = AV_CODEC_ID_PCM_S16LE,
+    .video_codec    = AV_CODEC_ID_NONE,
+    .write_header   = ircam_write_header,
+    .write_packet   = ff_raw_write_packet,
+    .codec_tag      = (const AVCodecTag *const []){ ff_codec_ircam_le_tags, 0 },
+};
diff --git a/libavformat/isom.c b/libavformat/isom.c
index 811184b..3f419a8 100644
--- a/libavformat/isom.c
+++ b/libavformat/isom.c
@@ -147,6 +147,7 @@
     { AV_CODEC_ID_8BPS,    MKTAG('8', 'B', 'P', 'S') }, /* Planar RGB (8BPS) */
     { AV_CODEC_ID_SMC,     MKTAG('s', 'm', 'c', ' ') }, /* Apple Graphics (SMC) */
     { AV_CODEC_ID_QTRLE,   MKTAG('r', 'l', 'e', ' ') }, /* Apple Animation (RLE) */
+    { AV_CODEC_ID_SGIRLE,  MKTAG('r', 'l', 'e', '1') }, /* SGI RLE 8-bit */
     { AV_CODEC_ID_MSRLE,   MKTAG('W', 'R', 'L', 'E') },
     { AV_CODEC_ID_QDRAW,   MKTAG('q', 'd', 'r', 'w') }, /* QuickDraw */
 
@@ -165,6 +166,7 @@
     { AV_CODEC_ID_H264, MKTAG('a', 'i', '1', '3') }, /* AVC-Intra 100M 1080p24/30/60 */
     { AV_CODEC_ID_H264, MKTAG('a', 'i', '1', '5') }, /* AVC-Intra 100M 1080i50 */
     { AV_CODEC_ID_H264, MKTAG('a', 'i', '1', '6') }, /* AVC-Intra 100M 1080i60 */
+    { AV_CODEC_ID_H264, MKTAG('A', 'V', 'i', 'n') }, /* AVC-Intra with implicit SPS/PPS */
 
     { AV_CODEC_ID_MPEG1VIDEO, MKTAG('m', '1', 'v', '1') }, /* Apple MPEG-1 Camcorder */
     { AV_CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', 'e', 'g') }, /* MPEG */
@@ -227,7 +229,7 @@
 
     { AV_CODEC_ID_DIRAC,     MKTAG('d', 'r', 'a', 'c') },
     { AV_CODEC_ID_DNXHD,     MKTAG('A', 'V', 'd', 'n') }, /* AVID DNxHD */
-//  { AV_CODEC_ID_FLV1,      MKTAG('H', '2', '6', '3') }, /* Flash Media Server, forced in demuxer */
+    { AV_CODEC_ID_H263,      MKTAG('H', '2', '6', '3') },
     { AV_CODEC_ID_MSMPEG4V3, MKTAG('3', 'I', 'V', 'D') }, /* 3ivx DivX Doctor */
     { AV_CODEC_ID_RAWVIDEO,  MKTAG('A', 'V', '1', 'x') }, /* AVID 1:1x */
     { AV_CODEC_ID_RAWVIDEO,  MKTAG('A', 'V', 'u', 'p') },
@@ -292,6 +294,8 @@
     { AV_CODEC_ID_QDMC,            MKTAG('Q', 'D', 'M', 'C') },
     { AV_CODEC_ID_SPEEX,           MKTAG('s', 'p', 'e', 'x') }, /* Flash Media Server */
     { AV_CODEC_ID_WMAV2,           MKTAG('W', 'M', 'A', '2') },
+    { AV_CODEC_ID_EVRC,            MKTAG('s', 'e', 'v', 'c') }, /* 3GPP2 */
+    { AV_CODEC_ID_SMV,             MKTAG('s', 's', 'm', 'v') }, /* 3GPP2 */
     { AV_CODEC_ID_NONE, 0 },
 };
 
diff --git a/libavformat/isom.h b/libavformat/isom.h
index f6eba56..4154baf 100644
--- a/libavformat/isom.h
+++ b/libavformat/isom.h
@@ -94,6 +94,7 @@
 
 typedef struct MOVStreamContext {
     AVIOContext *pb;
+    int pb_is_copied;
     int ffindex;          ///< AVStream index
     int next_chunk;
     unsigned int chunk_count;
@@ -128,9 +129,7 @@
     unsigned drefs_count;
     MOVDref *drefs;
     int dref_id;
-    unsigned tref_type;
-    unsigned trefs_count;
-    uint32_t *trefs;
+    int timecode_track;
     int wrong_dts;        ///< dts are wrong due to huge ctts offset (iMovie files)
     int width;            ///< tkhd width
     int height;           ///< tkhd height
diff --git a/libavformat/jacosubdec.c b/libavformat/jacosubdec.c
index 1c58e3b..89e7e1bf 100644
--- a/libavformat/jacosubdec.c
+++ b/libavformat/jacosubdec.c
@@ -28,6 +28,7 @@
 #include "avformat.h"
 #include "internal.h"
 #include "subtitles.h"
+#include "libavcodec/internal.h"
 #include "libavcodec/jacosub.h"
 #include "libavutil/avstring.h"
 #include "libavutil/bprint.h"
@@ -159,7 +160,7 @@
     JACOsubContext *jacosub = s->priv_data;
     int shift_set = 0; // only the first shift matters
     int merge_line = 0;
-    int i;
+    int i, ret;
 
     AVStream *st = avformat_new_stream(s, NULL);
     if (!st)
@@ -228,8 +229,9 @@
     }
 
     /* general/essential directives in the extradata */
-    av_bprint_finalize(&header, (char **)&st->codec->extradata);
-    st->codec->extradata_size = header.len + 1;
+    ret = avpriv_bprint_to_extradata(st->codec, &header);
+    if (ret < 0)
+        return ret;
 
     /* SHIFT and TIMERES affect the whole script so packet timing can only be
      * done in a second pass */
@@ -265,5 +267,4 @@
     .read_packet    = jacosub_read_packet,
     .read_seek2     = jacosub_read_seek,
     .read_close     = jacosub_read_close,
-    .flags          = AVFMT_GENERIC_INDEX,
 };
diff --git a/libavformat/latmenc.c b/libavformat/latmenc.c
index 233eab8..9dfb4e4 100644
--- a/libavformat/latmenc.c
+++ b/libavformat/latmenc.c
@@ -156,6 +156,15 @@
         av_log(s, AV_LOG_ERROR, "ADTS header detected - ADTS will not be incorrectly muxed into LATM\n");
         return AVERROR_INVALIDDATA;
     }
+
+    if (!s->streams[0]->codec->extradata) {
+        if(pkt->size > 2 && pkt->data[0] == 0x56 && (pkt->data[1] >> 4) == 0xe &&
+            (AV_RB16(pkt->data + 1) & 0x1FFF) + 3 == pkt->size)
+            return ff_raw_write_packet(s, pkt);
+        else
+            return AVERROR_INVALIDDATA;
+    }
+
     if (pkt->size > 0x1fff)
         goto too_large;
 
diff --git a/libavformat/libavformat.v b/libavformat/libavformat.v
index 5f86d62..0b47668 100644
--- a/libavformat/libavformat.v
+++ b/libavformat/libavformat.v
@@ -24,11 +24,7 @@
                 url_open;
                 url_close;
                 url_write;
-                url_get_max_packet_size;
                 #those are deprecated, remove on next bump
-                find_info_tag;
-                parse_date;
-                dump_format;
                 url_*;
                 ff_timefilter_destroy;
                 ff_timefilter_new;
@@ -36,9 +32,6 @@
                 ff_timefilter_reset;
                 get_*;
                 put_*;
-                udp_set_remote_url;
-                udp_get_local_port;
-                init_checksum;
-                init_put_byte;
+                ff_codec_get_id;
         local: *;
 };
diff --git a/libavformat/lmlm4.c b/libavformat/lmlm4.c
index c3eec02..29ee2a3 100644
--- a/libavformat/lmlm4.c
+++ b/libavformat/lmlm4.c
@@ -35,7 +35,7 @@
 #define LMLM4_MAX_PACKET_SIZE   1024 * 1024
 
 static int lmlm4_probe(AVProbeData * pd) {
-    unsigned char *buf = pd->buf;
+    const unsigned char *buf = pd->buf;
     unsigned int frame_type, packet_size;
 
     frame_type  = AV_RB16(buf+2);
diff --git a/libavformat/loasdec.c b/libavformat/loasdec.c
index ccb9464..d3a8dbd 100644
--- a/libavformat/loasdec.c
+++ b/libavformat/loasdec.c
@@ -29,10 +29,10 @@
 {
     int max_frames = 0, first_frames = 0;
     int fsize, frames;
-    uint8_t *buf0 = p->buf;
-    uint8_t *buf2;
-    uint8_t *buf;
-    uint8_t *end = buf0 + p->buf_size - 3;
+    const uint8_t *buf0 = p->buf;
+    const uint8_t *buf2;
+    const uint8_t *buf;
+    const uint8_t *end = buf0 + p->buf_size - 3;
     buf = buf0;
 
     for(; buf < end; buf= buf2+1) {
@@ -55,7 +55,6 @@
     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;
-    else if(max_frames>=1) return 1;
     else                   return 0;
 }
 
diff --git a/libavformat/matroska.c b/libavformat/matroska.c
index 930c609..09eecf2 100644
--- a/libavformat/matroska.c
+++ b/libavformat/matroska.c
@@ -21,6 +21,9 @@
 
 #include "matroska.h"
 
+/* If you add a tag here that is not in ff_codec_bmp_tags[]
+   or ff_codec_wav_tags[], add it also to additional_audio_tags[]
+   or additional_video_tags[] in matroskaenc.c */
 const CodecTags ff_mkv_codec_tags[]={
     {"A_AAC"            , AV_CODEC_ID_AAC},
     {"A_AC3"            , AV_CODEC_ID_AC3},
@@ -32,6 +35,7 @@
     {"A_MPEG/L2"        , AV_CODEC_ID_MP2},
     {"A_MPEG/L1"        , AV_CODEC_ID_MP2},
     {"A_MPEG/L3"        , AV_CODEC_ID_MP3},
+    {"A_OPUS/EXPERIMENTAL",AV_CODEC_ID_OPUS},
     {"A_OPUS",            AV_CODEC_ID_OPUS},
     {"A_PCM/FLOAT/IEEE" , AV_CODEC_ID_PCM_F32LE},
     {"A_PCM/FLOAT/IEEE" , AV_CODEC_ID_PCM_F64LE},
@@ -62,6 +66,7 @@
     {"S_ASS"            , AV_CODEC_ID_SSA},
     {"S_SSA"            , AV_CODEC_ID_SSA},
     {"S_VOBSUB"         , AV_CODEC_ID_DVD_SUBTITLE},
+    {"S_DVBSUB"         , AV_CODEC_ID_DVB_SUBTITLE},
     {"S_HDMV/PGS"       , AV_CODEC_ID_HDMV_PGS_SUBTITLE},
 
     {"V_DIRAC"          , AV_CODEC_ID_DIRAC},
@@ -112,7 +117,7 @@
     "bottom_top",
     "top_bottom",
     "checkerboard_rl",
-    "checkerboard_lr"
+    "checkerboard_lr",
     "row_interleaved_rl",
     "row_interleaved_lr",
     "col_interleaved_rl",
diff --git a/libavformat/matroska.h b/libavformat/matroska.h
index 8411633..8e6f8cc 100644
--- a/libavformat/matroska.h
+++ b/libavformat/matroska.h
@@ -118,6 +118,7 @@
 #define MATROSKA_ID_VIDEODISPLAYUNIT 0x54B2
 #define MATROSKA_ID_VIDEOFLAGINTERLACED 0x9A
 #define MATROSKA_ID_VIDEOSTEREOMODE 0x53B8
+#define MATROSKA_ID_VIDEOALPHAMODE 0x53C0
 #define MATROSKA_ID_VIDEOASPECTRATIO 0x54B3
 #define MATROSKA_ID_VIDEOCOLORSPACE 0x2EB524
 
@@ -175,6 +176,10 @@
 #define MATROSKA_ID_CLUSTERPOSITION 0xA7
 #define MATROSKA_ID_CLUSTERPREVSIZE 0xAB
 #define MATROSKA_ID_BLOCKGROUP 0xA0
+#define MATROSKA_ID_BLOCKADDITIONS 0x75A1
+#define MATROSKA_ID_BLOCKMORE 0xA6
+#define MATROSKA_ID_BLOCKADDID 0xEE
+#define MATROSKA_ID_BLOCKADDITIONAL 0xA5
 #define MATROSKA_ID_SIMPLEBLOCK 0xA3
 
 /* IDs in the blockgroup master */
diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index b3ce5be..ab675ae 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -55,6 +55,8 @@
 #include <bzlib.h>
 #endif
 
+static int matroska_read_close(AVFormatContext *s);
+
 typedef enum {
     EBML_NONE,
     EBML_UINT,
@@ -119,6 +121,7 @@
     uint64_t pixel_height;
     EbmlBin color_space;
     uint64_t stereo_mode;
+    uint64_t alpha_mode;
 } MatroskaTrackVideo;
 
 typedef struct {
@@ -167,6 +170,7 @@
     AVStream *stream;
     int64_t end_timecode;
     int ms_compat;
+    uint64_t max_block_additional_id;
 } MatroskaTrack;
 
 typedef struct {
@@ -283,6 +287,8 @@
     int64_t  reference;
     uint64_t non_simple;
     EbmlBin  bin;
+    uint64_t additional_id;
+    EbmlBin  additional;
 } MatroskaBlock;
 
 static EbmlSyntax ebml_header[] = {
@@ -320,6 +326,7 @@
     { MATROSKA_ID_VIDEOPIXELHEIGHT,   EBML_UINT, 0, offsetof(MatroskaTrackVideo,pixel_height) },
     { MATROSKA_ID_VIDEOCOLORSPACE,    EBML_BIN,  0, offsetof(MatroskaTrackVideo,color_space) },
     { MATROSKA_ID_VIDEOSTEREOMODE,    EBML_UINT, 0, offsetof(MatroskaTrackVideo,stereo_mode) },
+    { MATROSKA_ID_VIDEOALPHAMODE,     EBML_UINT, 0, offsetof(MatroskaTrackVideo,alpha_mode) },
     { MATROSKA_ID_VIDEOPIXELCROPB,    EBML_NONE },
     { MATROSKA_ID_VIDEOPIXELCROPT,    EBML_NONE },
     { MATROSKA_ID_VIDEOPIXELCROPL,    EBML_NONE },
@@ -389,6 +396,7 @@
     { MATROSKA_ID_TRACKAUDIO,           EBML_NEST, 0, offsetof(MatroskaTrack,audio), {.n=matroska_track_audio} },
     { MATROSKA_ID_TRACKOPERATION,       EBML_NEST, 0, offsetof(MatroskaTrack,operation), {.n=matroska_track_operation} },
     { MATROSKA_ID_TRACKCONTENTENCODINGS,EBML_NEST, 0, 0, {.n=matroska_track_encodings} },
+    { MATROSKA_ID_TRACKMAXBLKADDID,     EBML_UINT, 0, offsetof(MatroskaTrack,max_block_additional_id) },
     { MATROSKA_ID_TRACKFLAGENABLED,     EBML_NONE },
     { MATROSKA_ID_TRACKFLAGLACING,      EBML_NONE },
     { MATROSKA_ID_CODECNAME,            EBML_NONE },
@@ -397,7 +405,6 @@
     { MATROSKA_ID_CODECDOWNLOADURL,     EBML_NONE },
     { MATROSKA_ID_TRACKMINCACHE,        EBML_NONE },
     { MATROSKA_ID_TRACKMAXCACHE,        EBML_NONE },
-    { MATROSKA_ID_TRACKMAXBLKADDID,     EBML_NONE },
     { 0 }
 };
 
@@ -528,8 +535,20 @@
     { 0 }
 };
 
+static EbmlSyntax matroska_blockmore[] = {
+    { MATROSKA_ID_BLOCKADDID,      EBML_UINT, 0, offsetof(MatroskaBlock,additional_id) },
+    { MATROSKA_ID_BLOCKADDITIONAL, EBML_BIN,  0, offsetof(MatroskaBlock,additional) },
+    { 0 }
+};
+
+static EbmlSyntax matroska_blockadditions[] = {
+    { MATROSKA_ID_BLOCKMORE, EBML_NEST, 0, 0, {.n=matroska_blockmore} },
+    { 0 }
+};
+
 static EbmlSyntax matroska_blockgroup[] = {
     { MATROSKA_ID_BLOCK,          EBML_BIN,  0, offsetof(MatroskaBlock,bin) },
+    { MATROSKA_ID_BLOCKADDITIONS, EBML_NEST, 0, 0, {.n=matroska_blockadditions} },
     { 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) },
@@ -774,6 +793,7 @@
     bin->pos  = avio_tell(pb);
     if (avio_read(pb, bin->data, length) != length) {
         av_freep(&bin->data);
+        bin->size = 0;
         return AVERROR(EIO);
     }
 
@@ -1611,7 +1631,7 @@
                    && track->codec_priv.data != NULL) {
             int ret;
             ffio_init_context(&b, track->codec_priv.data, track->codec_priv.size,
-                          AVIO_FLAG_READ, NULL, NULL, NULL, NULL);
+                              0, NULL, NULL, NULL, NULL);
             ret = ff_get_wav_header(&b, st->codec, track->codec_priv.size);
             if (ret < 0)
                 return ret;
@@ -1712,6 +1732,8 @@
                 extradata_offset = 78;
             }
 #else
+            /* Returning without closing would cause leaks with some files */
+            matroska_read_close(s);
             return AVERROR_INVALIDDATA;
 #endif
         }
@@ -1777,6 +1799,10 @@
             if (track->video.stereo_mode && track->video.stereo_mode < MATROSKA_VIDEO_STEREO_MODE_COUNT)
                 av_dict_set(&st->metadata, "stereo_mode", ff_matroska_video_stereo_mode[track->video.stereo_mode], 0);
 
+            /* export alpha mode flag as metadata tag  */
+            if (track->video.alpha_mode)
+                av_dict_set(&st->metadata, "alpha_mode", "1", 0);
+
             /* if we have virtual track, mark the real tracks */
             for (j=0; j < track->operation.combine_planes.nb_elem; j++) {
                 char buf[32];
@@ -1795,6 +1821,7 @@
             st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
             st->codec->sample_rate = track->audio.out_samplerate;
             st->codec->channels = track->audio.channels;
+            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 (track->type == MATROSKA_TRACK_TYPE_SUBTITLE) {
@@ -2086,7 +2113,8 @@
                                 AVStream *st,
                                 uint8_t *data, int pkt_size,
                                 uint64_t timecode, uint64_t lace_duration,
-                                int64_t pos, int is_keyframe)
+                                int64_t pos, int is_keyframe,
+                                uint8_t *additional, uint64_t additional_id, int additional_size)
 {
     MatroskaTrackEncoding *encodings = track->encodings.elem;
     uint8_t *pkt_data = data;
@@ -2123,6 +2151,17 @@
     pkt->flags = is_keyframe;
     pkt->stream_index = st->index;
 
+    if (additional_size > 0) {
+        uint8_t *side_data = av_packet_new_side_data(pkt,
+                                                     AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL,
+                                                     additional_size + 8);
+        if(side_data == NULL) {
+            return AVERROR(ENOMEM);
+        }
+        AV_WB64(side_data, additional_id);
+        memcpy(side_data + 8, additional, additional_size);
+    }
+
     if (track->ms_compat)
         pkt->dts = timecode;
     else
@@ -2172,6 +2211,7 @@
 static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
                                 int size, int64_t pos, uint64_t cluster_time,
                                 uint64_t block_duration, int is_keyframe,
+                                uint8_t *additional, uint64_t additional_id, int additional_size,
                                 int64_t cluster_pos)
 {
     uint64_t timecode = AV_NOPTS_VALUE;
@@ -2269,7 +2309,8 @@
         } else {
             res = matroska_parse_frame(matroska, track, st, data, lace_size[n],
                                       timecode, lace_duration,
-                                      pos, !n? is_keyframe : 0);
+                                      pos, !n? is_keyframe : 0,
+                                      additional, additional_id, additional_size);
             if (res)
                 goto end;
         }
@@ -2325,6 +2366,8 @@
         i = blocks_list->nb_elem - 1;
         if (blocks[i].bin.size > 0 && blocks[i].bin.data) {
             int is_keyframe = blocks[i].non_simple ? !blocks[i].reference : -1;
+            uint8_t* additional = blocks[i].additional.size > 0 ?
+                                    blocks[i].additional.data : NULL;
             if (!blocks[i].non_simple)
                 blocks[i].duration = 0;
             res = matroska_parse_block(matroska,
@@ -2332,6 +2375,8 @@
                                        blocks[i].bin.pos,
                                        matroska->current_cluster.timecode,
                                        blocks[i].duration, is_keyframe,
+                                       additional, blocks[i].additional_id,
+                                       blocks[i].additional.size,
                                        matroska->current_cluster_pos);
         }
     }
@@ -2362,7 +2407,7 @@
             res=matroska_parse_block(matroska,
                                      blocks[i].bin.data, blocks[i].bin.size,
                                      blocks[i].bin.pos,  cluster.timecode,
-                                     blocks[i].duration, is_keyframe,
+                                     blocks[i].duration, is_keyframe, NULL, 0, 0,
                                      pos);
         }
     ebml_free(matroska_cluster, &cluster);
@@ -2434,9 +2479,14 @@
 
     avio_seek(s->pb, st->index_entries[index_min].pos, SEEK_SET);
     matroska->current_id = 0;
-    st->skip_to_keyframe =
-    matroska->skip_to_keyframe = !(flags & AVSEEK_FLAG_ANY);
-    matroska->skip_to_timecode = st->index_entries[index].timestamp;
+    if (flags & AVSEEK_FLAG_ANY) {
+        st->skip_to_keyframe = 0;
+        matroska->skip_to_timecode = timestamp;
+    } else {
+        st->skip_to_keyframe = 1;
+        matroska->skip_to_timecode = st->index_entries[index].timestamp;
+    }
+    matroska->skip_to_keyframe = 1;
     matroska->done = 0;
     matroska->num_levels = 0;
     ff_update_cur_dts(s, st, st->index_entries[index].timestamp);
diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
index 2a8a2ea..4544f8e 100644
--- a/libavformat/matroskaenc.c
+++ b/libavformat/matroskaenc.c
@@ -28,6 +28,7 @@
 #include "flacenc.h"
 #include "avlanguage.h"
 #include "libavutil/samplefmt.h"
+#include "libavutil/sha.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/intfloat.h"
 #include "libavutil/mathematics.h"
@@ -71,6 +72,7 @@
 
 typedef struct {
     int             write_dts;
+    int             has_cue;
 } mkv_track;
 
 #define MODE_MATROSKAv2 0x01
@@ -383,7 +385,7 @@
     return 0;
 }
 
-static int64_t mkv_write_cues(AVIOContext *pb, mkv_cues *cues, int num_tracks)
+static int64_t mkv_write_cues(AVIOContext *pb, mkv_cues *cues, mkv_track *tracks, int num_tracks)
 {
     ebml_master cues_element;
     int64_t currentpos;
@@ -402,7 +404,14 @@
 
         // put all the entries from different tracks that have the exact same
         // timestamp into the same CuePoint
+        for (j = 0; j < num_tracks; j++)
+            tracks[j].has_cue = 0;
         for (j = 0; j < cues->num_entries - i && entry[j].pts == pts; j++) {
+            int tracknum = entry[j].tracknum - 1;
+            av_assert0(tracknum>=0 && tracknum<num_tracks);
+            if (tracks[tracknum].has_cue)
+                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);
@@ -485,7 +494,7 @@
                 avio_write(dyn_cp, codec->extradata + 12,
                                    codec->extradata_size - 12);
         }
-        else if (codec->extradata_size)
+        else if (codec->extradata_size && codec->codec_id != AV_CODEC_ID_TTA)
             avio_write(dyn_cp, codec->extradata, codec->extradata_size);
     } else if (codec->codec_type == AVMEDIA_TYPE_VIDEO) {
         if (qt_id) {
@@ -497,8 +506,9 @@
             if (!codec->codec_tag)
                 codec->codec_tag = ff_codec_get_tag(ff_codec_bmp_tags, codec->codec_id);
             if (!codec->codec_tag) {
-                av_log(s, AV_LOG_ERROR, "No bmp codec ID found.\n");
-                ret = -1;
+                av_log(s, AV_LOG_ERROR, "No bmp codec tag found for codec %s\n",
+                       avcodec_get_name(codec->codec_id));
+                ret = AVERROR(EINVAL);
             }
 
             ff_put_bmp_header(dyn_cp, codec, ff_codec_bmp_tags, 0);
@@ -508,8 +518,9 @@
         unsigned int tag;
         tag = ff_codec_get_tag(ff_codec_wav_tags, codec->codec_id);
         if (!tag) {
-            av_log(s, AV_LOG_ERROR, "No wav codec ID found.\n");
-            ret = -1;
+            av_log(s, AV_LOG_ERROR, "No wav codec tag found for codec %s\n",
+                   avcodec_get_name(codec->codec_id));
+            ret = AVERROR(EINVAL);
         }
         if (!codec->codec_tag)
             codec->codec_tag = tag;
@@ -529,7 +540,7 @@
     MatroskaMuxContext *mkv = s->priv_data;
     AVIOContext *pb = s->pb;
     ebml_master tracks;
-    int i, j, ret;
+    int i, j, ret, default_stream_exists = 0;
 
     ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_TRACKS, avio_tell(pb));
     if (ret < 0) return ret;
@@ -537,6 +548,10 @@
     tracks = start_ebml_master(pb, MATROSKA_ID_TRACKS, 0);
     for (i = 0; i < s->nb_streams; i++) {
         AVStream *st = s->streams[i];
+        default_stream_exists |= st->disposition & AV_DISPOSITION_DEFAULT;
+    }
+    for (i = 0; i < s->nb_streams; i++) {
+        AVStream *st = s->streams[i];
         AVCodecContext *codec = st->codec;
         ebml_master subinfo, track;
         int native_id = 0;
@@ -553,6 +568,8 @@
 
         if (!bit_depth)
             bit_depth = av_get_bytes_per_sample(codec->sample_fmt) << 3;
+        if (!bit_depth)
+            bit_depth = codec->bits_per_coded_sample;
 
         if (codec->codec_id == AV_CODEC_ID_AAC)
             get_aac_sample_rates(s, codec, &sample_rate, &output_sample_rate);
@@ -567,8 +584,11 @@
         tag = av_dict_get(st->metadata, "language", NULL, 0);
         put_ebml_string(pb, MATROSKA_ID_TRACKLANGUAGE, tag ? tag->value:"und");
 
-        if (st->disposition)
+        if (default_stream_exists) {
             put_ebml_uint(pb, MATROSKA_ID_TRACKFLAGDEFAULT, !!(st->disposition & AV_DISPOSITION_DEFAULT));
+        }
+        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
@@ -637,7 +657,11 @@
                 }
 
                 if (st->sample_aspect_ratio.num) {
-                    int d_width = codec->width*av_q2d(st->sample_aspect_ratio);
+                    int64_t d_width = av_rescale(codec->width, st->sample_aspect_ratio.num, st->sample_aspect_ratio.den);
+                    if (d_width > INT_MAX) {
+                        av_log(s, AV_LOG_ERROR, "Overflow in display width\n");
+                        return AVERROR(EINVAL);
+                    }
                     put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYWIDTH , d_width);
                     put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYHEIGHT, codec->height);
                 }
@@ -852,6 +876,7 @@
         ebml_master attached_file;
         AVDictionaryEntry *t;
         const char *mimetype = NULL;
+        uint64_t fileuid;
 
         if (st->codec->codec_type != AVMEDIA_TYPE_ATTACHMENT)
             continue;
@@ -881,9 +906,25 @@
             return AVERROR(EINVAL);
         }
 
+        if (st->codec->flags & CODEC_FLAG_BITEXACT) {
+            struct AVSHA *sha = av_sha_alloc();
+            uint8_t digest[20];
+            if (!sha)
+                return AVERROR(ENOMEM);
+            av_sha_init(sha, 160);
+            av_sha_update(sha, st->codec->extradata, st->codec->extradata_size);
+            av_sha_final(sha, digest);
+            av_free(sha);
+            fileuid = AV_RL64(digest);
+        } else {
+            fileuid = av_lfg_get(&c);
+        }
+        av_log(s, AV_LOG_VERBOSE, "Using %.16"PRIx64" for attachment %d\n",
+               fileuid, i);
+
         put_ebml_string(pb, MATROSKA_ID_FILEMIMETYPE, mimetype);
         put_ebml_binary(pb, MATROSKA_ID_FILEDATA, st->codec->extradata, st->codec->extradata_size);
-        put_ebml_uint(pb, MATROSKA_ID_FILEUID, av_lfg_get(&c));
+        put_ebml_uint(pb, MATROSKA_ID_FILEUID, fileuid);
         end_ebml_master(pb, attached_file);
     }
     end_ebml_master(pb, attachments);
@@ -905,6 +946,19 @@
     if (s->avoid_negative_ts < 0)
         s->avoid_negative_ts = 1;
 
+    for (i = 0; i < s->nb_streams; i++)
+        if (s->streams[i]->codec->codec_id == AV_CODEC_ID_ATRAC3 ||
+            s->streams[i]->codec->codec_id == AV_CODEC_ID_COOK ||
+            s->streams[i]->codec->codec_id == AV_CODEC_ID_RA_288 ||
+            s->streams[i]->codec->codec_id == AV_CODEC_ID_SIPR ||
+            s->streams[i]->codec->codec_id == AV_CODEC_ID_RV10 ||
+            s->streams[i]->codec->codec_id == AV_CODEC_ID_RV20) {
+            av_log(s, AV_LOG_ERROR,
+                   "The Matroska muxer does not yet support muxing %s\n",
+                   avcodec_get_name(s->streams[i]->codec->codec_id));
+            return AVERROR_PATCHWELCOME;
+        }
+
     mkv->tracks = av_mallocz(s->nb_streams * sizeof(*mkv->tracks));
     if (!mkv->tracks)
         return AVERROR(ENOMEM);
@@ -1289,7 +1343,7 @@
 
     if (pb->seekable) {
         if (mkv->cues->num_entries) {
-            cuespos = mkv_write_cues(pb, mkv->cues, s->nb_streams);
+            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;
@@ -1331,6 +1385,33 @@
     return 0;
 }
 
+const AVCodecTag additional_audio_tags[] = {
+    { AV_CODEC_ID_ALAC,      0XFFFFFFFF },
+    { AV_CODEC_ID_EAC3,      0XFFFFFFFF },
+    { AV_CODEC_ID_MLP,       0xFFFFFFFF },
+    { AV_CODEC_ID_OPUS,      0xFFFFFFFF },
+    { AV_CODEC_ID_PCM_S16BE, 0xFFFFFFFF },
+    { AV_CODEC_ID_PCM_S24BE, 0xFFFFFFFF },
+    { AV_CODEC_ID_PCM_S32BE, 0xFFFFFFFF },
+    { AV_CODEC_ID_QDM2,      0xFFFFFFFF },
+    { AV_CODEC_ID_RA_144,    0xFFFFFFFF },
+    { 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[] = {
+    { AV_CODEC_ID_PRORES,    0xFFFFFFFF },
+    { AV_CODEC_ID_RV10,      0xFFFFFFFF },
+    { AV_CODEC_ID_RV20,      0xFFFFFFFF },
+    { AV_CODEC_ID_RV30,      0xFFFFFFFF },
+    { AV_CODEC_ID_RV40,      0xFFFFFFFF },
+    { AV_CODEC_ID_VP9,       0xFFFFFFFF },
+    { AV_CODEC_ID_NONE,      0xFFFFFFFF }
+};
+
 #if CONFIG_MATROSKA_MUXER
 AVOutputFormat ff_matroska_muxer = {
     .name              = "matroska",
@@ -1347,6 +1428,10 @@
     .write_trailer     = mkv_write_trailer,
     .flags             = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS |
                          AVFMT_TS_NONSTRICT,
+    .codec_tag         = (const AVCodecTag* const []){
+         ff_codec_bmp_tags, ff_codec_wav_tags,
+         additional_audio_tags, additional_video_tags, 0
+    },
     .subtitle_codec    = AV_CODEC_ID_SSA,
     .query_codec       = mkv_query_codec,
 };
@@ -1383,5 +1468,8 @@
     .write_packet      = mkv_write_packet,
     .write_trailer     = mkv_write_trailer,
     .flags             = AVFMT_GLOBALHEADER | AVFMT_TS_NONSTRICT,
+    .codec_tag         = (const AVCodecTag* const []){
+        ff_codec_wav_tags, additional_audio_tags, 0
+    },
 };
 #endif
diff --git a/libavformat/microdvddec.c b/libavformat/microdvddec.c
index 68a5d87..4b42846 100644
--- a/libavformat/microdvddec.c
+++ b/libavformat/microdvddec.c
@@ -35,7 +35,8 @@
 
 static int microdvd_probe(AVProbeData *p)
 {
-    unsigned char c, *ptr = p->buf;
+    unsigned char c;
+    const uint8_t *ptr = p->buf;
     int i;
 
     if (AV_RB24(ptr) == 0xEFBBBF)
@@ -82,18 +83,19 @@
         return AVERROR(ENOMEM);
 
     while (!url_feof(s->pb)) {
+        char *p = line;
         AVPacket *sub;
         int64_t pos = avio_tell(s->pb);
         int len = ff_get_line(s->pb, line, sizeof(line));
 
         if (!len)
             break;
-        if (i < 3) {
+        line[strcspn(line, "\r\n")] = 0;
+        if (i++ < 3) {
             int frame;
             double fps;
             char c;
 
-            i++;
             if ((sscanf(line, "{%d}{}%6lf",    &frame, &fps) == 2 ||
                  sscanf(line, "{%d}{%*d}%6lf", &frame, &fps) == 2)
                 && frame <= 1 && fps > 3 && fps < 100)
@@ -106,12 +108,24 @@
                 continue;
             }
         }
-        sub = ff_subtitles_queue_insert(&microdvd->q, line, len, 0);
+#define SKIP_FRAME_ID                                       \
+    p = strchr(p, '}');                                     \
+    if (!p) {                                               \
+        av_log(s, AV_LOG_WARNING, "Invalid event \"%s\""    \
+               " at line %d\n", line, i);                   \
+        continue;                                           \
+    }                                                       \
+    p++
+        SKIP_FRAME_ID;
+        SKIP_FRAME_ID;
+        if (!*p)
+            continue;
+        sub = ff_subtitles_queue_insert(&microdvd->q, p, strlen(p), 0);
         if (!sub)
             return AVERROR(ENOMEM);
         sub->pos = pos;
-        sub->pts = get_pts(sub->data);
-        sub->duration = get_duration(sub->data);
+        sub->pts = get_pts(line);
+        sub->duration = get_duration(line);
     }
     ff_subtitles_queue_finalize(&microdvd->q);
     avpriv_set_pts_info(st, 64, pts_info.den, pts_info.num);
@@ -150,5 +164,4 @@
     .read_packet    = microdvd_read_packet,
     .read_seek2     = microdvd_read_seek,
     .read_close     = microdvd_read_close,
-    .flags          = AVFMT_GENERIC_INDEX,
 };
diff --git a/libavformat/microdvdenc.c b/libavformat/microdvdenc.c
index ba97444..30fd0ea 100644
--- a/libavformat/microdvdenc.c
+++ b/libavformat/microdvdenc.c
@@ -19,12 +19,14 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <inttypes.h>
 #include "avformat.h"
-#include "rawenc.h"
+#include "internal.h"
 
 static int microdvd_write_header(struct AVFormatContext *s)
 {
     AVCodecContext *avctx = s->streams[0]->codec;
+    AVRational tb = avctx->time_base;
 
     if (s->nb_streams != 1 || avctx->codec_id != AV_CODEC_ID_MICRODVD) {
         av_log(s, AV_LOG_ERROR, "Exactly one MicroDVD stream is needed.\n");
@@ -36,6 +38,21 @@
         avio_write(s->pb, avctx->extradata, avctx->extradata_size);
         avio_flush(s->pb);
     }
+
+    avpriv_set_pts_info(s->streams[0], 64, tb.num, tb.den);
+    return 0;
+}
+
+static int microdvd_write_packet(AVFormatContext *avf, AVPacket *pkt)
+{
+    avio_printf(avf->pb, "{%"PRId64"}", pkt->pts);
+    if (pkt->duration < 0)
+        avio_write(avf->pb, "{}", 2);
+    else
+        avio_printf(avf->pb, "{%"PRId64"}", pkt->pts + pkt->duration);
+    avio_write(avf->pb, pkt->data, pkt->size);
+    avio_write(avf->pb, "\n", 1);
+    avio_flush(avf->pb);
     return 0;
 }
 
@@ -45,7 +62,7 @@
     .mime_type      = "text/x-microdvd",
     .extensions     = "sub",
     .write_header   = microdvd_write_header,
-    .write_packet   = ff_raw_write_packet,
+    .write_packet   = microdvd_write_packet,
     .flags          = AVFMT_NOTIMESTAMPS,
     .subtitle_codec = AV_CODEC_ID_MICRODVD,
 };
diff --git a/libavformat/mmf.c b/libavformat/mmf.c
index 38c6970..d074d7c 100644
--- a/libavformat/mmf.c
+++ b/libavformat/mmf.c
@@ -24,11 +24,13 @@
 #include "internal.h"
 #include "avio_internal.h"
 #include "pcm.h"
+#include "rawenc.h"
 #include "riff.h"
 
 typedef struct {
     int64_t atrpos, atsqpos, awapos;
-    int64_t data_size;
+    int64_t data_end;
+    int stereo;
 } MMFContext;
 
 static const int mmf_rates[] = { 4000, 8000, 11025, 22050, 44100 };
@@ -67,11 +69,23 @@
     AVIOContext *pb = s->pb;
     int64_t pos;
     int rate;
+    const char *version = s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT ?
+                          "VN:Lavf," :
+                          "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);
-        return -1;
+        return AVERROR(EINVAL);
+    }
+
+    mmf->stereo = s->streams[0]->codec->channels > 1;
+    if (mmf->stereo &&
+        s->streams[0]->codec->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
+        av_log(s, AV_LOG_ERROR, "Yamaha SMAF stereo is experimental, "
+               "add '-strict %d' if you want to use it.\n",
+               FF_COMPLIANCE_EXPERIMENTAL);
+        return AVERROR(EINVAL);
     }
 
     ffio_wfourcc(pb, "MMMD");
@@ -82,7 +96,9 @@
     avio_w8(pb, 1); /* code type */
     avio_w8(pb, 0); /* status */
     avio_w8(pb, 0); /* counts */
-    avio_write(pb, "VN:libavcodec,", sizeof("VN:libavcodec,") -1); /* metadata ("ST:songtitle,VN:version,...") */
+    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);
 
     avio_write(pb, "ATR\x00", 4);
@@ -90,7 +106,7 @@
     mmf->atrpos = avio_tell(pb);
     avio_w8(pb, 0); /* format type */
     avio_w8(pb, 0); /* sequence type */
-    avio_w8(pb, (0 << 7) | (1 << 4) | rate); /* (channel << 7) | (format << 4) | rate */
+    avio_w8(pb, (mmf->stereo << 7) | (1 << 4) | rate); /* (channel << 7) | (format << 4) | rate */
     avio_w8(pb, 0); /* wave base bit */
     avio_w8(pb, 2); /* time base d */
     avio_w8(pb, 2); /* time base g */
@@ -110,13 +126,6 @@
     return 0;
 }
 
-static int mmf_write_packet(AVFormatContext *s, AVPacket *pkt)
-{
-    AVIOContext *pb = s->pb;
-    avio_write(pb, pkt->data, pkt->size);
-    return 0;
-}
-
 /* Write a variable-length symbol */
 static void put_varlength(AVIOContext *pb, int val)
 {
@@ -150,7 +159,7 @@
 
         /* "play wav" */
         avio_w8(pb, 0); /* start time */
-        avio_w8(pb, 1); /* (channel << 6) | wavenum */
+        avio_w8(pb, (mmf->stereo << 6) | 1); /* (channel << 6) | wavenum */
         gatetime = size * 500 / s->streams[0]->codec->sample_rate;
         put_varlength(pb, gatetime); /* duration */
 
@@ -193,7 +202,7 @@
 
     tag = avio_rl32(pb);
     if (tag != MKTAG('M', 'M', 'M', 'D'))
-        return -1;
+        return AVERROR_INVALIDDATA;
     avio_skip(pb, 4); /* file_size */
 
     /* Skip some unused chunks that may or may not be present */
@@ -208,11 +217,11 @@
     /* Tag = "ATRx", where "x" = track number */
     if ((tag & 0xffffff) == MKTAG('M', 'T', 'R', 0)) {
         av_log(s, AV_LOG_ERROR, "MIDI like format found, unsupported\n");
-        return -1;
+        return AVERROR_PATCHWELCOME;
     }
     if ((tag & 0xffffff) != MKTAG('A', 'T', 'R', 0)) {
         av_log(s, AV_LOG_ERROR, "Unsupported SMAF chunk %08x\n", tag);
-        return -1;
+        return AVERROR_PATCHWELCOME;
     }
 
     avio_r8(pb); /* format type */
@@ -221,7 +230,7 @@
     rate = mmf_rate(params & 0x0f);
     if(rate  < 0) {
         av_log(s, AV_LOG_ERROR, "Invalid sample rate\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     avio_r8(pb); /* wave base bit */
     avio_r8(pb); /* time base d */
@@ -239,9 +248,9 @@
     /* Make sure it's followed by an Awa chunk, aka wave data */
     if ((tag & 0xffffff) != MKTAG('A', 'w', 'a', 0)) {
         av_log(s, AV_LOG_ERROR, "Unexpected SMAF chunk %08x\n", tag);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
-    mmf->data_size = size;
+    mmf->data_end = avio_tell(pb) + size;
 
     st = avformat_new_stream(s, NULL);
     if (!st)
@@ -250,8 +259,8 @@
     st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
     st->codec->codec_id = AV_CODEC_ID_ADPCM_YAMAHA;
     st->codec->sample_rate = rate;
-    st->codec->channels = 1;
-    st->codec->channel_layout = AV_CH_LAYOUT_MONO;
+    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;
 
@@ -266,19 +275,19 @@
                            AVPacket *pkt)
 {
     MMFContext *mmf = s->priv_data;
-    int ret, size;
+    int64_t left, size;
+    int ret;
 
-    if (url_feof(s->pb) || !mmf->data_size)
+    left = mmf->data_end - avio_tell(s->pb);
+    size = FFMIN(left, MAX_SIZE);
+    if (url_feof(s->pb) || size <= 0)
         return AVERROR_EOF;
 
-    size = FFMIN(MAX_SIZE, mmf->data_size);
-
     ret = av_get_packet(s->pb, pkt, size);
     if (ret < 0)
         return ret;
 
     pkt->stream_index = 0;
-    mmf->data_size -= ret;
 
     return ret;
 }
@@ -291,7 +300,7 @@
     .read_probe     = mmf_probe,
     .read_header    = mmf_read_header,
     .read_packet    = mmf_read_packet,
-    .read_seek      = ff_pcm_read_seek,
+    .flags          = AVFMT_GENERIC_INDEX,
 };
 #endif
 #if CONFIG_MMF_MUXER
@@ -304,7 +313,7 @@
     .audio_codec       = AV_CODEC_ID_ADPCM_YAMAHA,
     .video_codec       = AV_CODEC_ID_NONE,
     .write_header      = mmf_write_header,
-    .write_packet      = mmf_write_packet,
+    .write_packet      = ff_raw_write_packet,
     .write_trailer     = mmf_write_trailer,
 };
 #endif
diff --git a/libavformat/mov.c b/libavformat/mov.c
index f380b39..137f79b 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -278,6 +278,17 @@
     return 0;
 }
 
+static int mov_metadata_raw(MOVContext *c, AVIOContext *pb,
+                            unsigned len, const char *key)
+{
+    char *value = av_malloc(len + 1);
+    if (!value)
+        return AVERROR(ENOMEM);
+    avio_read(pb, value, len);
+    value[len] = 0;
+    return av_dict_set(&c->fc->metadata, key, value, AV_DICT_DONT_STRDUP_VAL);
+}
+
 static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 {
 #ifdef MOV_EXPORT_ALL_METADATA
@@ -334,6 +345,10 @@
         parse = mov_metadata_int8_no_padding; break;
     case MKTAG( 'p','g','a','p'): key = "gapless_playback";
         parse = mov_metadata_int8_no_padding; break;
+    case MKTAG( '@','P','R','M'):
+        return mov_metadata_raw(c, pb, atom.size, "premiere_version");
+    case MKTAG( '@','P','R','Q'):
+        return mov_metadata_raw(c, pb, atom.size, "quicktime_version");
     }
 
     if (c->itunes_metadata && atom.size > 8) {
@@ -429,6 +444,7 @@
     return 0;
 }
 
+#define MIN_DATA_ENTRY_BOX_SIZE 12
 static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 {
     AVStream *st;
@@ -442,7 +458,8 @@
 
     avio_rb32(pb); // version + flags
     entries = avio_rb32(pb);
-    if (entries >= UINT_MAX / sizeof(*sc->drefs))
+    if (entries >  (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
+        entries >= UINT_MAX / sizeof(*sc->drefs))
         return AVERROR_INVALIDDATA;
     av_free(sc->drefs);
     sc->drefs_count = 0;
@@ -679,6 +696,9 @@
     if (atom.size < 16)
         return 0;
 
+    /* skip version and flags */
+    avio_skip(pb, 4);
+
     ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
 
     return 0;
@@ -815,7 +835,7 @@
 
     version = avio_r8(pb);
     if (version > 1) {
-        av_log_ask_for_sample(c, "unsupported version %d\n", version);
+        av_log_ask_for_sample(c->fc, "unsupported version %d\n", version);
         return AVERROR_PATCHWELCOME;
     }
     avio_rb24(pb); /* flags */
@@ -1259,6 +1279,7 @@
             int color_greyscale;
             int color_table_id;
 
+            st->codec->codec_id = id;
             avio_rb16(pb); /* version */
             avio_rb16(pb); /* revision level */
             avio_rb32(pb); /* vendor */
@@ -1280,13 +1301,15 @@
             if (len < 31)
                 avio_skip(pb, 31 - len);
             /* codec_tag YV12 triggers an UV swap in rawdec.c */
-            if (!memcmp(st->codec->codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25))
+            if (!memcmp(st->codec->codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)){
                 st->codec->codec_tag=MKTAG('I', '4', '2', '0');
-            /* Flash Media Server streams files with Sorenson Spark and tag H263 */
-            if (!memcmp(st->codec->codec_name, "Sorenson H263", 13)
-                && format == MKTAG('H','2','6','3'))
-                id = AV_CODEC_ID_FLV1;
-            st->codec->codec_id = id;
+                st->codec->width &= ~1;
+                st->codec->height &= ~1;
+            }
+            /* Flash Media Server uses tag H263 with Sorenson Spark */
+            if (format == MKTAG('H','2','6','3') &&
+                !memcmp(st->codec->codec_name, "Sorenson H263", 13))
+                st->codec->codec_id = AV_CODEC_ID_FLV1;
 
             st->codec->bits_per_coded_sample = avio_rb16(pb); /* depth */
             color_table_id = avio_rb16(pb); /* colortable id */
@@ -2210,8 +2233,10 @@
                    "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
                    st->index, dref->path, dref->dir, dref->filename,
                    dref->volume, dref->nlvl_from, dref->nlvl_to);
-    } else
+    } else {
         sc->pb = c->fc->pb;
+        sc->pb_is_copied = 1;
+    }
 
     if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
         if (!st->sample_aspect_ratio.num &&
@@ -2222,7 +2247,7 @@
 
         if (st->duration > 0)
             av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
-                    sc->time_scale*st->nb_frames, st->duration, INT_MAX);
+                      sc->time_scale*st->nb_frames, st->duration, INT_MAX);
 
 #if FF_API_R_FRAME_RATE
         if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
@@ -2231,6 +2256,12 @@
 #endif
     }
 
+    // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
+    if (!st->codec->extradata_size && st->codec->codec_id == AV_CODEC_ID_H264 &&
+        st->codec->codec_tag != MKTAG('a', 'v', 'c', '1')) {
+        ff_generate_avci_extradata(st);
+    }
+
     switch (st->codec->codec_id) {
 #if CONFIG_H261_DECODER
     case AV_CODEC_ID_H261:
@@ -2667,36 +2698,14 @@
     return 0;
 }
 
-static int mov_read_chan2(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 {
-    if (atom.size < 16)
-        return 0;
-    avio_skip(pb, 4);
-    ff_mov_read_chan(c->fc, pb, c->fc->streams[0],  atom.size - 4);
-    return 0;
-}
-
-static int mov_read_tref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
-{
-    uint32_t i, size;
     MOVStreamContext *sc;
 
     if (c->fc->nb_streams < 1)
         return AVERROR_INVALIDDATA;
     sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
-
-    size = avio_rb32(pb);
-    if (size < 12)
-        return 0;
-
-    sc->trefs_count = (size - 4) / 8;
-    sc->trefs = av_malloc(sc->trefs_count * sizeof(*sc->trefs));
-    if (!sc->trefs)
-        return AVERROR(ENOMEM);
-
-    sc->tref_type = avio_rl32(pb);
-    for (i = 0; i < sc->trefs_count; i++)
-        sc->trefs[i] = avio_rb32(pb);
+    sc->timecode_track = avio_rb32(pb);
     return 0;
 }
 
@@ -2747,7 +2756,8 @@
 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
 { MKTAG('t','r','a','k'), mov_read_trak },
 { MKTAG('t','r','a','f'), mov_read_default },
-{ MKTAG('t','r','e','f'), mov_read_tref },
+{ MKTAG('t','r','e','f'), mov_read_default },
+{ MKTAG('t','m','c','d'), mov_read_tmcd },
 { MKTAG('c','h','a','p'), mov_read_chap },
 { MKTAG('t','r','e','x'), mov_read_trex },
 { MKTAG('t','r','u','n'), mov_read_trun },
@@ -3057,8 +3067,7 @@
             av_freep(&sc->drefs[j].dir);
         }
         av_freep(&sc->drefs);
-        av_freep(&sc->trefs);
-        if (sc->pb && sc->pb != s->pb)
+        if (!sc->pb_is_copied)
             avio_close(sc->pb);
         sc->pb = NULL;
         av_freep(&sc->chunk_offsets);
@@ -3085,17 +3094,15 @@
 
 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
 {
-    int i, j;
+    int i;
 
     for (i = 0; i < s->nb_streams; i++) {
         AVStream *st = s->streams[i];
         MOVStreamContext *sc = st->priv_data;
 
-        if (s->streams[i]->codec->codec_type != AVMEDIA_TYPE_VIDEO)
-            continue;
-        for (j = 0; j < sc->trefs_count; j++)
-            if (tmcd_id == sc->trefs[j])
-                return 1;
+        if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
+            sc->timecode_track == tmcd_id)
+            return 1;
     }
     return 0;
 }
@@ -3123,7 +3130,7 @@
 {
     MOVContext *mov = s->priv_data;
     AVIOContext *pb = s->pb;
-    int i, err;
+    int i, j, err;
     MOVAtom atom = { AV_RL32("root") };
 
     mov->fc = s;
@@ -3158,11 +3165,15 @@
     for (i = 0; i < s->nb_streams; i++) {
         AVStream *st = s->streams[i];
         MOVStreamContext *sc = st->priv_data;
-        if (sc->tref_type == AV_RL32("tmcd") && sc->trefs_count) {
+        if (sc->timecode_track > 0) {
             AVDictionaryEntry *tcr;
-            int tmcd_st_id = sc->trefs[0] - 1;
+            int tmcd_st_id = -1;
 
-            if (tmcd_st_id < 0 || tmcd_st_id >= s->nb_streams)
+            for (j = 0; j < s->nb_streams; j++)
+                if (s->streams[j]->id == sc->timecode_track)
+                    tmcd_st_id = j;
+
+            if (tmcd_st_id < 0 || tmcd_st_id == i)
                 continue;
             tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
             if (tcr)
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index f08aa7e..510cef5 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -356,8 +356,7 @@
     else
         avio_w8(pb, 0x11); // flags (= Visualstream)
 
-    avio_w8(pb,  track->enc->rc_buffer_size>>(3+16));      // Buffersize DB (24 bits)
-    avio_wb16(pb, (track->enc->rc_buffer_size>>3)&0xFFFF); // Buffersize DB
+    avio_wb24(pb, track->enc->rc_buffer_size >> 3); // Buffersize DB
 
     avg_bitrate = compute_avg_bitrate(track);
     // maxbitrate (FIXME should be max rate in any 1 sec window)
@@ -1128,13 +1127,17 @@
         mov_write_avcc_tag(pb, track);
         if(track->mode == MODE_IPOD)
             mov_write_uuid_tag_ipod(pb);
-    } else if (track->enc->field_order != AV_FIELD_UNKNOWN)
-        mov_write_fiel_tag(pb, track);
-    else if (track->enc->codec_id == AV_CODEC_ID_VC1 && track->vos_len > 0)
+    } else if (track->enc->codec_id == AV_CODEC_ID_VC1 && track->vos_len > 0)
         mov_write_dvc1_tag(pb, track);
     else if (track->vos_len > 0)
         mov_write_glbl_tag(pb, track);
 
+    if (track->enc->codec_id != AV_CODEC_ID_H264 &&
+        track->enc->codec_id != AV_CODEC_ID_MPEG4 &&
+        track->enc->codec_id != AV_CODEC_ID_DNXHD)
+        if (track->enc->field_order != AV_FIELD_UNKNOWN)
+            mov_write_fiel_tag(pb, track);
+
     if (track->enc->sample_aspect_ratio.den && track->enc->sample_aspect_ratio.num &&
         track->enc->sample_aspect_ratio.den != track->enc->sample_aspect_ratio.num) {
         mov_write_pasp_tag(pb, track);
@@ -1147,7 +1150,12 @@
 {
     int64_t pos = avio_tell(pb);
     int frame_duration = av_rescale(track->timescale, track->enc->time_base.num, track->enc->time_base.den);
-    int nb_frames = (track->timescale + frame_duration/2) / frame_duration;
+    int nb_frames = 1.0/av_q2d(track->enc->time_base) + 0.5;
+
+    if (nb_frames > 255) {
+        av_log(NULL, AV_LOG_ERROR, "fps %d is too large\n", nb_frames);
+        return AVERROR(EINVAL);
+    }
 
     avio_wb32(pb, 0); /* size */
     ffio_wfourcc(pb, "tmcd");               /* Data format */
diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c
index d11dceb..c6d6987 100644
--- a/libavformat/mp3dec.c
+++ b/libavformat/mp3dec.c
@@ -49,7 +49,7 @@
     int max_frames, first_frames = 0;
     int fsize, frames, sample_rate;
     uint32_t header;
-    uint8_t *buf, *buf0, *buf2, *end;
+    const uint8_t *buf, *buf0, *buf2, *end;
     AVCodecContext avctx;
 
     buf0 = p->buf;
diff --git a/libavformat/mpc8.c b/libavformat/mpc8.c
index 191f696..73f8057 100644
--- a/libavformat/mpc8.c
+++ b/libavformat/mpc8.c
@@ -55,7 +55,7 @@
     int64_t apetag_start;
 } MPCContext;
 
-static inline int64_t bs_get_v(uint8_t **bs)
+static inline int64_t bs_get_v(const uint8_t **bs)
 {
     int64_t v = 0;
     int br = 0;
@@ -75,8 +75,8 @@
 
 static int mpc8_probe(AVProbeData *p)
 {
-    uint8_t *bs = p->buf + 4;
-    uint8_t *bs_end = bs + p->buf_size;
+    const uint8_t *bs = p->buf + 4;
+    const uint8_t *bs_end = bs + p->buf_size;
     int64_t size;
 
     if (p->buf_size < 16)
@@ -139,6 +139,11 @@
     int i, t, seekd;
     GetBitContext gb;
 
+    if (s->nb_streams<=0) {
+        av_log(s, AV_LOG_ERROR, "cannot parse stream table before stream header\n");
+        return;
+    }
+
     avio_seek(s->pb, off, SEEK_SET);
     mpc8_get_chunk_header(s->pb, &tag, &size);
     if(tag != TAG_SEEKTABLE){
diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c
index 22e7869..4eaffd8 100644
--- a/libavformat/mpeg.c
+++ b/libavformat/mpeg.c
@@ -23,6 +23,11 @@
 #include "internal.h"
 #include "mpeg.h"
 
+#if CONFIG_VOBSUB_DEMUXER
+# include "subtitles.h"
+# include "libavutil/bprint.h"
+#endif
+
 #undef NDEBUG
 #include <assert.h>
 
@@ -31,7 +36,7 @@
 
 #define MAX_SYNC_SIZE 100000
 
-static int check_pes(uint8_t *p, uint8_t *end){
+static int check_pes(const uint8_t *p, const uint8_t *end){
     int pes1;
     int pes2=      (p[3] & 0xC0) == 0x80
                 && (p[4] & 0xC0) != 0x40
@@ -103,6 +108,10 @@
     int32_t header_state;
     unsigned char psm_es_type[256];
     int sofdec;
+#if CONFIG_VOBSUB_DEMUXER
+    AVFormatContext *sub_ctx;
+    FFDemuxSubtitlesQueue q;
+#endif
 } MpegDemuxContext;
 
 static int mpegps_read_header(AVFormatContext *s)
@@ -373,7 +382,7 @@
     MpegDemuxContext *m = s->priv_data;
     AVStream *st;
     int len, startcode, i, es_type, ret;
-    int lpcm_header_len;
+    int lpcm_header_len = -1; //Init to supress warning
     int request_probe= 0;
     enum AVCodecID codec_id = AV_CODEC_ID_NONE;
     enum AVMediaType type;
@@ -407,7 +416,6 @@
     }
 
     es_type = m->psm_es_type[startcode & 0xff];
-    if(es_type > 0 && es_type != STREAM_TYPE_PRIVATE_DATA){
         if(es_type == STREAM_TYPE_VIDEO_MPEG1){
             codec_id = AV_CODEC_ID_MPEG2VIDEO;
             type = AVMEDIA_TYPE_VIDEO;
@@ -430,9 +438,6 @@
         } else if(es_type == STREAM_TYPE_AUDIO_AC3){
             codec_id = AV_CODEC_ID_AC3;
             type = AVMEDIA_TYPE_AUDIO;
-        } else {
-            goto skip;
-        }
     } else if (startcode >= 0x1e0 && startcode <= 0x1ef) {
         static const unsigned char avs_seqh[4] = { 0, 0, 1, 0xb0 };
         unsigned char buf[8];
@@ -495,7 +500,7 @@
     if(st->discard >= AVDISCARD_ALL)
         goto skip;
     if (startcode >= 0xa0 && startcode <= 0xaf) {
-      if (lpcm_header_len == 6) {
+      if (lpcm_header_len == 6 && st->codec->codec_id == AV_CODEC_ID_MLP) {
             if (len < 6)
                 goto skip;
             avio_skip(s->pb, 6);
@@ -574,3 +579,256 @@
     .read_timestamp = mpegps_read_dts,
     .flags          = AVFMT_SHOW_IDS | AVFMT_TS_DISCONT,
 };
+
+#if CONFIG_VOBSUB_DEMUXER
+
+#define REF_STRING "# VobSub index file,"
+
+static int vobsub_probe(AVProbeData *p)
+{
+    if (!strncmp(p->buf, REF_STRING, sizeof(REF_STRING) - 1))
+        return AVPROBE_SCORE_MAX;
+    return 0;
+}
+
+static int vobsub_read_header(AVFormatContext *s)
+{
+    int i, ret = 0, header_parsed = 0, langidx = 0;
+    MpegDemuxContext *vobsub = s->priv_data;
+    char *sub_name = NULL;
+    size_t fname_len;
+    char *ext, *header_str;
+    AVBPrint header;
+    int64_t delay = 0;
+    AVStream *st = NULL;
+
+    sub_name = av_strdup(s->filename);
+    fname_len = strlen(sub_name);
+    ext = sub_name - 3 + fname_len;
+    if (fname_len < 4 || *(ext - 1) != '.') {
+        av_log(s, AV_LOG_ERROR, "The input index filename is too short "
+               "to guess the associated .SUB file\n");
+        ret = AVERROR_INVALIDDATA;
+        goto end;
+    }
+    memcpy(ext, !strncmp(ext, "IDX", 3) ? "SUB" : "sub", 3);
+    av_log(s, AV_LOG_VERBOSE, "IDX/SUB: %s -> %s\n", s->filename, sub_name);
+    ret = avformat_open_input(&vobsub->sub_ctx, sub_name, &ff_mpegps_demuxer, NULL);
+    if (ret < 0) {
+        av_log(s, AV_LOG_ERROR, "Unable to open %s as MPEG subtitles\n", sub_name);
+        goto end;
+    }
+
+    av_bprint_init(&header, 0, AV_BPRINT_SIZE_UNLIMITED);
+    while (!url_feof(s->pb)) {
+        char line[2048];
+        int len = ff_get_line(s->pb, line, sizeof(line));
+
+        if (!len)
+            break;
+
+        line[strcspn(line, "\r\n")] = 0;
+
+        if (!strncmp(line, "id:", 3)) {
+            int n, stream_id = 0;
+            char id[64] = {0};
+
+            n = sscanf(line, "id: %63[^,], index: %u", id, &stream_id);
+            if (n != 2) {
+                av_log(s, AV_LOG_WARNING, "Unable to parse index line '%s', "
+                       "assuming 'id: und, index: 0'\n", line);
+                strcpy(id, "und");
+                stream_id = 0;
+            }
+
+            st = avformat_new_stream(s, NULL);
+            if (!st) {
+                ret = AVERROR(ENOMEM);
+                goto end;
+            }
+            st->id = stream_id;
+            st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
+            st->codec->codec_id   = AV_CODEC_ID_DVD_SUBTITLE;
+            av_dict_set(&st->metadata, "language", id, 0);
+            av_log(s, AV_LOG_DEBUG, "IDX stream[%d] id=%s\n", stream_id, id);
+            header_parsed = 1;
+
+        } else if (st && !strncmp(line, "timestamp:", 10)) {
+            AVPacket *sub;
+            int hh, mm, ss, ms;
+            int64_t pos, timestamp;
+            const char *p = line + 10;
+
+            if (sscanf(p, "%02d:%02d:%02d:%03d, filepos: %"PRIx64,
+                       &hh, &mm, &ss, &ms, &pos) != 5) {
+                av_log(s, AV_LOG_ERROR, "Unable to parse timestamp line '%s', "
+                       "abort parsing\n", line);
+                break;
+            }
+            timestamp = (hh*3600LL + mm*60LL + ss) * 1000LL + ms + delay;
+            timestamp = av_rescale_q(timestamp, (AVRational){1,1000}, st->time_base);
+
+            sub = ff_subtitles_queue_insert(&vobsub->q, "", 0, 0);
+            if (!sub) {
+                ret = AVERROR(ENOMEM);
+                goto end;
+            }
+            sub->pos = pos;
+            sub->pts = timestamp;
+            sub->stream_index = s->nb_streams - 1;
+
+        } else if (st && !strncmp(line, "alt:", 4)) {
+            const char *p = line + 4;
+
+            while (*p == ' ')
+                p++;
+            av_dict_set(&st->metadata, "title", p, 0);
+            av_log(s, AV_LOG_DEBUG, "IDX stream[%d] name=%s\n", st->id, p);
+            header_parsed = 1;
+
+        } else if (!strncmp(line, "delay:", 6)) {
+            int sign = 1, hh = 0, mm = 0, ss = 0, ms = 0;
+            const char *p = line + 6;
+
+            while (*p == ' ')
+                p++;
+            if (*p == '-' || *p == '+') {
+                sign = *p == '-' ? -1 : 1;
+                p++;
+            }
+            sscanf(p, "%d:%d:%d:%d", &hh, &mm, &ss, &ms);
+            delay = ((hh*3600LL + mm*60LL + ss) * 1000LL + ms) * sign;
+
+        } else if (!strncmp(line, "langidx:", 8)) {
+            const char *p = line + 8;
+
+            if (sscanf(p, "%d", &langidx) != 1)
+                av_log(s, AV_LOG_ERROR, "Invalid langidx specified\n");
+
+        } else if (!header_parsed) {
+            if (line[0] && line[0] != '#')
+                av_bprintf(&header, "%s\n", line);
+        }
+    }
+
+    if (langidx < s->nb_streams)
+        s->streams[langidx]->disposition |= AV_DISPOSITION_DEFAULT;
+
+    ff_subtitles_queue_finalize(&vobsub->q);
+
+    if (!av_bprint_is_complete(&header)) {
+        av_bprint_finalize(&header, NULL);
+        ret = AVERROR(ENOMEM);
+        goto end;
+    }
+    av_bprint_finalize(&header, &header_str);
+    for (i = 0; i < s->nb_streams; i++) {
+        AVStream *sub_st = s->streams[i];
+        sub_st->codec->extradata      = av_strdup(header_str);
+        sub_st->codec->extradata_size = header.len;
+    }
+    av_free(header_str);
+
+end:
+    av_free(sub_name);
+    return ret;
+}
+
+static int vobsub_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    MpegDemuxContext *vobsub = s->priv_data;
+    FFDemuxSubtitlesQueue *q = &vobsub->q;
+    AVIOContext *pb = vobsub->sub_ctx->pb;
+    int ret, psize, len16 = -1;
+    AVPacket idx_pkt;
+
+    ret = ff_subtitles_queue_read_packet(q, &idx_pkt);
+    if (ret < 0)
+        return ret;
+
+    /* compute maximum packet size using the next packet position. This is
+     * useful when the len in the header is non-sense */
+    if (q->current_sub_idx < q->nb_subs) {
+        psize = q->subs[q->current_sub_idx].pos - idx_pkt.pos;
+    } else {
+        int64_t fsize = avio_size(pb);
+        psize = fsize < 0 ? 0xffff : fsize - idx_pkt.pos;
+    }
+
+    avio_seek(pb, idx_pkt.pos, SEEK_SET);
+
+    av_init_packet(pkt);
+    pkt->size = 0;
+    pkt->data = NULL;
+
+    do {
+        int n, to_read, startcode;
+        int64_t pts, dts;
+
+        ret = mpegps_read_pes_header(vobsub->sub_ctx, NULL, &startcode, &pts, &dts);
+        if (ret < 0)
+            return ret;
+        to_read = ret & 0xffff;
+
+        /* this prevents reads above the current packet */
+        if (pkt->size + to_read > psize)
+            break;
+
+        /* if the len is computed, we check for overread */
+        if (len16 != -1 && pkt->size + to_read > len16)
+            break;
+
+        /* the current chunk doesn't match the stream index (unlikely) */
+        if ((startcode & 0x1f) != idx_pkt.stream_index)
+            break;
+
+        ret = av_grow_packet(pkt, to_read);
+        if (ret < 0)
+            return ret;
+
+        n = avio_read(pb, pkt->data + (pkt->size - to_read), to_read);
+        if (n < to_read)
+            pkt->size -= to_read - n;
+
+        /* first chunk contains the total len of the packet to raise */
+        if (len16 == -1 && n > 2)
+            len16 = AV_RB16(pkt->data);
+    } while (len16 != -1 && pkt->size != len16);
+
+    pkt->pts = pkt->dts = idx_pkt.pts;
+    pkt->pos = idx_pkt.pos;
+    pkt->stream_index = idx_pkt.stream_index;
+
+    return 0;
+}
+
+static int vobsub_read_seek(AVFormatContext *s, int stream_index,
+                            int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
+{
+    MpegDemuxContext *vobsub = s->priv_data;
+    return ff_subtitles_queue_seek(&vobsub->q, s, stream_index,
+                                   min_ts, ts, max_ts, flags);
+}
+
+static int vobsub_read_close(AVFormatContext *s)
+{
+    MpegDemuxContext *vobsub = s->priv_data;
+    ff_subtitles_queue_clean(&vobsub->q);
+    if (vobsub->sub_ctx)
+        avformat_close_input(&vobsub->sub_ctx);
+    return 0;
+}
+
+AVInputFormat ff_vobsub_demuxer = {
+    .name           = "vobsub",
+    .long_name      = NULL_IF_CONFIG_SMALL("VobSub subtitle format"),
+    .priv_data_size = sizeof(MpegDemuxContext),
+    .read_probe     = vobsub_probe,
+    .read_header    = vobsub_read_header,
+    .read_packet    = vobsub_read_packet,
+    .read_seek2     = vobsub_read_seek,
+    .read_close     = vobsub_read_close,
+    .flags          = AVFMT_SHOW_IDS,
+    .extensions     = "idx",
+};
+#endif
diff --git a/libavformat/mpegenc.c b/libavformat/mpegenc.c
index e2a96bc..b467bb5 100644
--- a/libavformat/mpegenc.c
+++ b/libavformat/mpegenc.c
@@ -482,7 +482,7 @@
         stream->packet_number = 0;
     }
     s->system_header_size = get_system_header_size(ctx);
-    s->last_scr = 0;
+    s->last_scr = AV_NOPTS_VALUE;
     return 0;
  fail:
     for(i=0;i<ctx->nb_streams;i++) {
@@ -1061,13 +1061,22 @@
     pts= pkt->pts;
     dts= pkt->dts;
 
-    if(pts != AV_NOPTS_VALUE) pts += 2*preload;
-    if(dts != AV_NOPTS_VALUE){
-        if(!s->last_scr)
-            s->last_scr= dts + preload;
-        dts += 2*preload;
+    if (s->last_scr == AV_NOPTS_VALUE) {
+        if (dts == AV_NOPTS_VALUE || (dts < preload && ctx->avoid_negative_ts) || s->is_dvd) {
+            if (dts != AV_NOPTS_VALUE)
+                s->preload += av_rescale(-dts, AV_TIME_BASE, 90000);
+            s->last_scr = 0;
+        } else {
+            s->last_scr = dts - preload;
+            s->preload = 0;
+        }
+        preload = av_rescale(s->preload, 90000, AV_TIME_BASE);
+        av_log(ctx, AV_LOG_DEBUG, "First SCR: %"PRId64" First DTS: %"PRId64"\n", s->last_scr, dts + preload);
     }
 
+    if (dts != AV_NOPTS_VALUE) dts += preload;
+    if (pts != AV_NOPTS_VALUE) pts += preload;
+
     av_dlog(ctx, "dts:%f pts:%f flags:%d stream:%d nopts:%d\n",
             dts / 90000.0, pts / 90000.0, pkt->flags,
             pkt->stream_index, pts != AV_NOPTS_VALUE);
diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index aa7bde5..8b92bc4 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -182,10 +182,25 @@
 
 extern AVInputFormat ff_mpegts_demuxer;
 
+static void clear_avprogram(MpegTSContext *ts, unsigned int programid)
+{
+    AVProgram *prg = NULL;
+    int i;
+    for(i=0; i<ts->stream->nb_programs; i++)
+        if(ts->stream->programs[i]->id == programid){
+            prg = ts->stream->programs[i];
+            break;
+        }
+    if (!prg)
+        return;
+    prg->nb_stream_indexes = 0;
+}
+
 static void clear_program(MpegTSContext *ts, unsigned int programid)
 {
     int i;
 
+    clear_avprogram(ts, programid);
     for(i=0; i<ts->nb_prg; i++)
         if(ts->prg[i].id == programid)
             ts->prg[i].nb_pids = 0;
@@ -193,6 +208,9 @@
 
 static void clear_programs(MpegTSContext *ts)
 {
+    int i;
+    for(i=0; i<ts->nb_prg; i++)
+        clear_avprogram(ts, ts->prg[i].id);
     av_freep(&ts->prg);
     ts->nb_prg=0;
 }
@@ -546,7 +564,9 @@
     { 0x10, AVMEDIA_TYPE_VIDEO,      AV_CODEC_ID_MPEG4 },
     /* Makito encoder sets stream type 0x11 for AAC,
      * so auto-detect LOAS/LATM instead of hardcoding it. */
-//  { 0x11, AVMEDIA_TYPE_AUDIO,   AV_CODEC_ID_AAC_LATM }, /* LATM syntax */
+#if !CONFIG_LOAS_DEMUXER
+    { 0x11, AVMEDIA_TYPE_AUDIO,   AV_CODEC_ID_AAC_LATM }, /* LATM syntax */
+#endif
     { 0x1b, AVMEDIA_TYPE_VIDEO,       AV_CODEC_ID_H264 },
     { 0xd1, AVMEDIA_TYPE_VIDEO,      AV_CODEC_ID_DIRAC },
     { 0xea, AVMEDIA_TYPE_VIDEO,        AV_CODEC_ID_VC1 },
@@ -581,6 +601,7 @@
     { MKTAG('D','T','S','1'), AVMEDIA_TYPE_AUDIO,   AV_CODEC_ID_DTS },
     { MKTAG('D','T','S','2'), AVMEDIA_TYPE_AUDIO,   AV_CODEC_ID_DTS },
     { MKTAG('D','T','S','3'), AVMEDIA_TYPE_AUDIO,   AV_CODEC_ID_DTS },
+    { MKTAG('K','L','V','A'), AVMEDIA_TYPE_DATA,    AV_CODEC_ID_SMPTE_KLV },
     { MKTAG('V','C','-','1'), AVMEDIA_TYPE_VIDEO,   AV_CODEC_ID_VC1 },
     { 0 },
 };
@@ -712,20 +733,11 @@
     pes->flags = 0;
 }
 
-static uint64_t get_bits64(GetBitContext *gb, int bits)
+static uint64_t get_ts64(GetBitContext *gb, int bits)
 {
-    uint64_t ret = 0;
-
     if (get_bits_left(gb) < bits)
         return AV_NOPTS_VALUE;
-    while (bits > 17) {
-        ret <<= 17;
-        ret |= get_bits(gb, 17);
-        bits -= 17;
-    }
-    ret <<= bits;
-    ret |= get_bits(gb, bits);
-    return ret;
+    return get_bits64(gb, bits);
 }
 
 static int read_sl_header(PESContext *pes, SLConfigDescr *sl, const uint8_t *buf, int buf_size)
@@ -774,9 +786,9 @@
         if (sl->inst_bitrate_len)
             inst_bitrate_flag = get_bits1(&gb);
         if (dts_flag == 1)
-            dts = get_bits64(&gb, sl->timestamp_len);
+            dts = get_ts64(&gb, sl->timestamp_len);
         if (cts_flag == 1)
-            cts = get_bits64(&gb, sl->timestamp_len);
+            cts = get_ts64(&gb, sl->timestamp_len);
         if (sl->au_len > 0)
             skip_bits_long(&gb, sl->au_len);
         if (inst_bitrate_flag)
@@ -1513,6 +1525,8 @@
             pes = ts->pids[pid]->u.pes_filter.opaque;
             if (!pes->st) {
                 pes->st = avformat_new_stream(pes->stream, NULL);
+                if (!pes->st)
+                    goto out;
                 pes->st->id = pes->pid;
             }
             st = pes->st;
@@ -1521,6 +1535,8 @@
             pes = add_pes_stream(ts, pid, pcr_pid);
             if (pes) {
                 st = avformat_new_stream(pes->stream, NULL);
+                if (!st)
+                    goto out;
                 st->id = pes->pid;
             }
         } else {
@@ -1529,6 +1545,8 @@
                 st = ts->stream->streams[idx];
             } else {
                 st = avformat_new_stream(ts->stream, NULL);
+                if (!st)
+                    goto out;
                 st->id = pid;
                 st->codec->codec_type = AVMEDIA_TYPE_DATA;
             }
@@ -2128,16 +2146,20 @@
     return ret;
 }
 
-static int mpegts_read_close(AVFormatContext *s)
+static void mpegts_free(MpegTSContext *ts)
 {
-    MpegTSContext *ts = s->priv_data;
     int i;
 
     clear_programs(ts);
 
     for(i=0;i<NB_PID_MAX;i++)
         if (ts->pids[i]) mpegts_close_filter(ts, ts->pids[i]);
+}
 
+static int mpegts_read_close(AVFormatContext *s)
+{
+    MpegTSContext *ts = s->priv_data;
+    mpegts_free(ts);
     return 0;
 }
 
@@ -2251,10 +2273,7 @@
 
 void ff_mpegts_parse_close(MpegTSContext *ts)
 {
-    int i;
-
-    for(i=0;i<NB_PID_MAX;i++)
-        av_free(ts->pids[i]);
+    mpegts_free(ts);
     av_free(ts);
 }
 
diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c
index 1b66bab..56b9d85 100644
--- a/libavformat/mpegtsenc.c
+++ b/libavformat/mpegtsenc.c
@@ -1081,7 +1081,7 @@
     }
 
     if (ts_st->first_pts_check && pts == AV_NOPTS_VALUE) {
-        av_log(s, AV_LOG_ERROR, "first pts value must set\n");
+        av_log(s, AV_LOG_ERROR, "first pts value must be set\n");
         return AVERROR_INVALIDDATA;
     }
     ts_st->first_pts_check = 0;
diff --git a/libavformat/mpl2dec.c b/libavformat/mpl2dec.c
new file mode 100644
index 0000000..ce2061b
--- /dev/null
+++ b/libavformat/mpl2dec.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2012 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
+ * MPL2 subtitles format demuxer
+ */
+
+#include "avformat.h"
+#include "internal.h"
+#include "subtitles.h"
+
+typedef struct {
+    FFDemuxSubtitlesQueue q;
+} MPL2Context;
+
+static int mpl2_probe(AVProbeData *p)
+{
+    int i;
+    char c;
+    int64_t start, end;
+    const unsigned char *ptr = p->buf;
+    const unsigned char *ptr_end = ptr + p->buf_size;
+
+    for (i = 0; i < 2; i++) {
+        if (sscanf(ptr, "[%"PRId64"][%"PRId64"]%c", &start, &end, &c) != 3 &&
+            sscanf(ptr, "[%"PRId64"][]%c",          &start,       &c) != 2)
+            return 0;
+        ptr += strcspn(ptr, "\r\n") + 1;
+        if (ptr >= ptr_end)
+            return 0;
+    }
+    return AVPROBE_SCORE_MAX;
+}
+
+static int read_ts(char **line, int64_t *pts_start, int *duration)
+{
+    char c;
+    int len;
+    int64_t end;
+
+    if (sscanf(*line, "[%"PRId64"][]%c%n",
+               pts_start, &c, &len) >= 2) {
+        *duration = -1;
+        *line += len - 1;
+        return 0;
+    }
+    if (sscanf(*line, "[%"PRId64"][%"PRId64"]%c%n",
+               pts_start, &end, &c, &len) >= 3) {
+        *duration = end - *pts_start;
+        *line += len - 1;
+        return 0;
+    }
+    return -1;
+}
+
+static int mpl2_read_header(AVFormatContext *s)
+{
+    MPL2Context *mpl2 = s->priv_data;
+    AVStream *st = avformat_new_stream(s, NULL);
+    int res = 0;
+
+    if (!st)
+        return AVERROR(ENOMEM);
+    avpriv_set_pts_info(st, 64, 1, 10);
+    st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
+    st->codec->codec_id   = AV_CODEC_ID_MPL2;
+
+    while (!url_feof(s->pb)) {
+        char line[4096];
+        char *p = line;
+        const int64_t pos = avio_tell(s->pb);
+        int len = ff_get_line(s->pb, line, sizeof(line));
+        int64_t pts_start;
+        int duration;
+
+        if (!len)
+            break;
+
+        line[strcspn(line, "\r\n")] = 0;
+
+        if (!read_ts(&p, &pts_start, &duration)) {
+            AVPacket *sub;
+
+            sub = ff_subtitles_queue_insert(&mpl2->q, p, strlen(p), 0);
+            if (!sub)
+                return AVERROR(ENOMEM);
+            sub->pos = pos;
+            sub->pts = pts_start;
+            sub->duration = duration;
+        }
+    }
+
+    ff_subtitles_queue_finalize(&mpl2->q);
+    return res;
+}
+
+static int mpl2_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    MPL2Context *mpl2 = s->priv_data;
+    return ff_subtitles_queue_read_packet(&mpl2->q, pkt);
+}
+
+static int mpl2_read_seek(AVFormatContext *s, int stream_index,
+                          int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
+{
+    MPL2Context *mpl2 = s->priv_data;
+    return ff_subtitles_queue_seek(&mpl2->q, s, stream_index,
+                                   min_ts, ts, max_ts, flags);
+}
+
+static int mpl2_read_close(AVFormatContext *s)
+{
+    MPL2Context *mpl2 = s->priv_data;
+    ff_subtitles_queue_clean(&mpl2->q);
+    return 0;
+}
+
+AVInputFormat ff_mpl2_demuxer = {
+    .name           = "mpl2",
+    .long_name      = NULL_IF_CONFIG_SMALL("MPL2 subtitles"),
+    .priv_data_size = sizeof(MPL2Context),
+    .read_probe     = mpl2_probe,
+    .read_header    = mpl2_read_header,
+    .read_packet    = mpl2_read_packet,
+    .read_seek2     = mpl2_read_seek,
+    .read_close     = mpl2_read_close,
+    .extensions     = "txt,mpl2",
+};
diff --git a/libavformat/mpsubdec.c b/libavformat/mpsubdec.c
new file mode 100644
index 0000000..2acafaa
--- /dev/null
+++ b/libavformat/mpsubdec.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2012 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
+ * MPlayer subtitles format demuxer
+ */
+
+#include "avformat.h"
+#include "internal.h"
+#include "subtitles.h"
+
+typedef struct {
+    FFDemuxSubtitlesQueue q;
+} MPSubContext;
+
+static int mpsub_probe(AVProbeData *p)
+{
+    const char *ptr     = p->buf;
+    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;
+        ptr += strcspn(ptr, "\n") + 1;
+    }
+    return 0;
+}
+
+static int mpsub_read_header(AVFormatContext *s)
+{
+    MPSubContext *mpsub = s->priv_data;
+    AVStream *st;
+    AVBPrint buf;
+    AVRational pts_info = (AVRational){ 100, 1 }; // ts based by default
+    int res = 0;
+    float multiplier = 100.0;
+    float current_pts = 0;
+
+    av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
+
+    while (!url_feof(s->pb)) {
+        char line[1024];
+        float start, duration;
+        int fps, len = ff_get_line(s->pb, line, sizeof(line));
+
+        if (!len)
+            break;
+
+        line[strcspn(line, "\r\n")] = 0;
+
+        if (sscanf(line, "FORMAT=%d", &fps) == 1 && fps > 3 && fps < 100) {
+            /* frame based timing */
+            pts_info = (AVRational){ fps, 1 };
+            multiplier = 1.0;
+        } else if (sscanf(line, "%f %f", &start, &duration) == 2) {
+            AVPacket *sub;
+            const int64_t pos = avio_tell(s->pb);
+
+            ff_subtitles_read_chunk(s->pb, &buf);
+            if (buf.len) {
+                sub = ff_subtitles_queue_insert(&mpsub->q, buf.str, buf.len, 0);
+                if (!sub) {
+                    res = AVERROR(ENOMEM);
+                    goto end;
+                }
+                sub->pts = (int64_t)(current_pts + start*multiplier);
+                sub->duration = (int)(duration * multiplier);
+                current_pts += (start + duration) * multiplier;
+                sub->pos = pos;
+            }
+        }
+    }
+
+    st = avformat_new_stream(s, NULL);
+    if (!st)
+        return AVERROR(ENOMEM);
+    avpriv_set_pts_info(st, 64, pts_info.den, pts_info.num);
+    st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
+    st->codec->codec_id   = AV_CODEC_ID_TEXT;
+
+    ff_subtitles_queue_finalize(&mpsub->q);
+
+end:
+    av_bprint_finalize(&buf, NULL);
+    return res;
+}
+
+static int mpsub_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    MPSubContext *mpsub = s->priv_data;
+    return ff_subtitles_queue_read_packet(&mpsub->q, pkt);
+}
+
+static int mpsub_read_seek(AVFormatContext *s, int stream_index,
+                           int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
+{
+    MPSubContext *mpsub = s->priv_data;
+    return ff_subtitles_queue_seek(&mpsub->q, s, stream_index,
+                                   min_ts, ts, max_ts, flags);
+}
+
+static int mpsub_read_close(AVFormatContext *s)
+{
+    MPSubContext *mpsub = s->priv_data;
+    ff_subtitles_queue_clean(&mpsub->q);
+    return 0;
+}
+
+AVInputFormat ff_mpsub_demuxer = {
+    .name           = "mpsub",
+    .long_name      = NULL_IF_CONFIG_SMALL("MPlayer subtitles"),
+    .priv_data_size = sizeof(MPSubContext),
+    .read_probe     = mpsub_probe,
+    .read_header    = mpsub_read_header,
+    .read_packet    = mpsub_read_packet,
+    .read_seek2     = mpsub_read_seek,
+    .read_close     = mpsub_read_close,
+    .extensions     = "sub",
+};
diff --git a/libavformat/mtv.c b/libavformat/mtv.c
index 622a9b8..5f39ec5 100644
--- a/libavformat/mtv.c
+++ b/libavformat/mtv.c
@@ -115,7 +115,7 @@
 
     if (audio_subsegments == 0) {
         av_log_ask_for_sample(s, "MTV files without audio are not supported\n");
-        return AVERROR_INVALIDDATA;
+        return AVERROR_PATCHWELCOME;
     }
 
     mtv->full_segment_size =
diff --git a/libavformat/mux.c b/libavformat/mux.c
index 9bcee99..98ec7a4 100644
--- a/libavformat/mux.c
+++ b/libavformat/mux.c
@@ -395,7 +395,7 @@
             return ret;
     }
 
-    if ((ret = init_pts(s) < 0))
+    if ((ret = init_pts(s)) < 0)
         return ret;
 
     return 0;
@@ -484,13 +484,28 @@
     return 0;
 }
 
+/**
+ * Move side data from payload to internal struct, call muxer, and restore
+ * original packet.
+ */
+static inline int split_write_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    int ret, did_split;
+
+    did_split = av_packet_split_side_data(pkt);
+    ret = s->oformat->write_packet(s, pkt);
+    if (did_split)
+        av_packet_merge_side_data(pkt);
+    return ret;
+}
+
 int av_write_frame(AVFormatContext *s, AVPacket *pkt)
 {
     int ret;
 
     if (!pkt) {
         if (s->oformat->flags & AVFMT_ALLOW_FLUSH) {
-            ret = s->oformat->write_packet(s, pkt);
+            ret = s->oformat->write_packet(s, NULL);
             if (ret >= 0 && s->pb && s->pb->error < 0)
                 ret = s->pb->error;
             return ret;
@@ -503,7 +518,7 @@
     if (ret < 0 && !(s->oformat->flags & AVFMT_NOTIMESTAMPS))
         return ret;
 
-    ret = s->oformat->write_packet(s, pkt);
+    ret = split_write_packet(s, pkt);
     if (ret >= 0 && s->pb && s->pb->error < 0)
         ret = s->pb->error;
 
@@ -534,20 +549,26 @@
         next_point = &s->packet_buffer;
     }
 
-    if (*next_point) {
-        if (chunked) {
-            uint64_t max= av_rescale_q(s->max_chunk_duration, AV_TIME_BASE_Q, st->time_base);
-            if (   st->interleaver_chunk_size     + pkt->size     <= s->max_chunk_size-1U
-                && st->interleaver_chunk_duration + pkt->duration <= max-1U) {
-                st->interleaver_chunk_size     += pkt->size;
-                st->interleaver_chunk_duration += pkt->duration;
-                goto next_non_null;
-            } else {
-                st->interleaver_chunk_size     =
+    if (chunked) {
+        uint64_t max= av_rescale_q_rnd(s->max_chunk_duration, AV_TIME_BASE_Q, st->time_base, AV_ROUND_UP);
+        st->interleaver_chunk_size     += pkt->size;
+        st->interleaver_chunk_duration += pkt->duration;
+        if (   (s->max_chunk_size && st->interleaver_chunk_size > s->max_chunk_size)
+            || (max && st->interleaver_chunk_duration           > max)) {
+            st->interleaver_chunk_size      = 0;
+            this_pktl->pkt.flags |= CHUNK_START;
+            if (max && st->interleaver_chunk_duration > max) {
+                int64_t syncoffset = (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)*max/2;
+                int64_t syncto = av_rescale(pkt->dts + syncoffset, 1, max)*max - syncoffset;
+
+                st->interleaver_chunk_duration += (pkt->dts - syncto)/8 - max;
+            } else
                 st->interleaver_chunk_duration = 0;
-                this_pktl->pkt.flags |= CHUNK_START;
-            }
         }
+    }
+    if (*next_point) {
+        if (chunked && !(this_pktl->pkt.flags & CHUNK_START))
+            goto next_non_null;
 
         if (compare(s, &s->packet_buffer_end->pkt, pkt)) {
             while (   *next_point
@@ -733,7 +754,7 @@
         if (ret <= 0) //FIXME cleanup needed for ret<0 ?
             return ret;
 
-        ret = s->oformat->write_packet(s, &opkt);
+        ret = split_write_packet(s, &opkt);
         if (ret >= 0)
             s->streams[opkt.stream_index]->nb_frames++;
 
@@ -759,7 +780,7 @@
         if (!ret)
             break;
 
-        ret = s->oformat->write_packet(s, &pkt);
+        ret = split_write_packet(s, &pkt);
         if (ret >= 0)
             s->streams[pkt.stream_index]->nb_frames++;
 
diff --git a/libavformat/mvdec.c b/libavformat/mvdec.c
new file mode 100644
index 0000000..103a40a
--- /dev/null
+++ b/libavformat/mvdec.c
@@ -0,0 +1,441 @@
+/*
+ * Silicon Graphics Movie demuxer
+ * Copyright (c) 2012 Peter Ross
+ *
+ * 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
+ * Silicon Graphics Movie demuxer
+ */
+
+#include "libavutil/eval.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/rational.h"
+#include "avformat.h"
+#include "internal.h"
+
+typedef struct {
+    int nb_video_tracks;
+    int nb_audio_tracks;
+
+    int eof_count;        /**< number of streams that have finished */
+    int stream_index;     /**< current stream index */
+    int frame[2];         /**< frame nb for current stream */
+} MvContext;
+
+#define AUDIO_FORMAT_SIGNED 401
+
+static int mv_probe(AVProbeData *p)
+{
+    if (AV_RB32(p->buf) == MKBETAG('M','O','V','I') && AV_RB16(p->buf + 4) < 3)
+        return AVPROBE_SCORE_MAX;
+    return 0;
+}
+
+static char * var_read_string(AVIOContext *pb, int size)
+{
+    char *str = av_malloc(size + 1);
+    int n;
+    if (!str)
+        return NULL;
+    n = avio_get_str(pb, size, str, size + 1);
+    if (n < size)
+         avio_skip(pb, size - n);
+    return str;
+}
+
+static int var_read_int(AVIOContext *pb, int size)
+{
+    int v;
+    char * s = var_read_string(pb, size);
+    if (!s || sscanf(s, "%d", &v) != 1)
+        v = 0;
+    av_free(s);
+    return v;
+}
+
+static AVRational var_read_float(AVIOContext *pb, int size)
+{
+    AVRational v;
+    char * s = var_read_string(pb, size);
+    if (!s)
+        return (AVRational){0, 0};
+    v = av_d2q(av_strtod(s, NULL), INT_MAX);
+    av_free(s);
+    return v;
+}
+
+static void var_read_metadata(AVFormatContext *avctx, const char *tag, int size)
+{
+    char *value = var_read_string(avctx->pb, size);
+    if (value)
+        av_dict_set(&avctx->metadata, tag, value, AV_DICT_DONT_STRDUP_VAL);
+}
+
+static int set_channels(AVFormatContext *avctx, AVStream *st, int channels) {
+    if (channels <= 0) {
+        av_log(avctx, AV_LOG_ERROR, "Channel count %d invalid\n", channels);
+        return AVERROR_INVALIDDATA;
+    }
+    st->codec->channels = channels;
+    st->codec->channel_layout = (st->codec->channels == 1) ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO;
+    return 0;
+}
+
+/**
+ * Parse global variable
+ * @return < 0 if unknown
+ */
+static int parse_global_var(AVFormatContext *avctx, AVStream *st, const char *name, int size)
+{
+    MvContext *mv = avctx->priv_data;
+    AVIOContext *pb = avctx->pb;
+    if (!strcmp(name, "__NUM_I_TRACKS")) {
+        mv->nb_video_tracks = var_read_int(pb, size);
+    } else if (!strcmp(name, "__NUM_A_TRACKS")) {
+        mv->nb_audio_tracks = var_read_int(pb, size);
+    } else if (!strcmp(name, "COMMENT") || !strcmp(name, "TITLE")) {
+        var_read_metadata(avctx, name, size);
+    } else if (!strcmp(name, "LOOP_MODE") || !strcmp(name, "NUM_LOOPS") || !strcmp(name, "OPTIMIZED")) {
+        avio_skip(pb, size); // ignore
+    } else
+        return -1;
+
+    return 0;
+}
+
+/**
+ * Parse audio variable
+ * @return < 0 if unknown
+ */
+static int parse_audio_var(AVFormatContext *avctx, AVStream *st, const char *name, int size)
+{
+    AVIOContext *pb = avctx->pb;
+    if (!strcmp(name, "__DIR_COUNT")) {
+        st->nb_frames = var_read_int(pb, size);
+    } else if (!strcmp(name, "AUDIO_FORMAT")) {
+        st->codec->codec_id = var_read_int(pb, size);
+    } else if (!strcmp(name, "COMPRESSION")) {
+        st->codec->codec_tag = var_read_int(pb, size);
+    } else if (!strcmp(name, "DEFAULT_VOL")) {
+        var_read_metadata(avctx, name, size);
+    } else if (!strcmp(name, "NUM_CHANNELS")) {
+        return set_channels(avctx, st, var_read_int(pb, size));
+    } else if (!strcmp(name, "SAMPLE_RATE")) {
+        st->codec->sample_rate = var_read_int(pb, size);
+        avpriv_set_pts_info(st, 33, 1, st->codec->sample_rate);
+    } else if (!strcmp(name, "SAMPLE_WIDTH")) {
+        st->codec->bits_per_coded_sample = var_read_int(pb, size) * 8;
+    } else
+        return -1;
+    return 0;
+}
+
+/**
+ * Parse video variable
+ * @return < 0 if unknown
+ */
+static int parse_video_var(AVFormatContext *avctx, AVStream *st, const char *name, int size)
+{
+    AVIOContext *pb = avctx->pb;
+    if (!strcmp(name, "__DIR_COUNT")) {
+        st->nb_frames = st->duration = var_read_int(pb, size);
+    } else if (!strcmp(name, "COMPRESSION")) {
+        char * str = var_read_string(pb, size);
+        if (!str)
+            return AVERROR_INVALIDDATA;
+        if (!strcmp(str, "1")) {
+            st->codec->codec_id = AV_CODEC_ID_MVC1;
+        } else if (!strcmp(str, "2")) {
+            st->codec->pix_fmt  = AV_PIX_FMT_ABGR;
+            st->codec->codec_id = AV_CODEC_ID_RAWVIDEO;
+        } else if (!strcmp(str, "3")) {
+            st->codec->codec_id = AV_CODEC_ID_SGIRLE;
+        } else if (!strcmp(str, "10")) {
+            st->codec->codec_id = AV_CODEC_ID_MJPEG;
+        } else if (!strcmp(str, "MVC2")) {
+            st->codec->codec_id = AV_CODEC_ID_MVC2;
+        } else {
+            av_log_ask_for_sample(avctx, "unknown video compression %s\n", str);
+        }
+        av_free(str);
+    } else if (!strcmp(name, "FPS")) {
+        AVRational fps = var_read_float(pb, size);
+        avpriv_set_pts_info(st, 64, fps.den, fps.num);
+    } else if (!strcmp(name, "HEIGHT")) {
+        st->codec->height = var_read_int(pb, size);
+    } else if (!strcmp(name, "PIXEL_ASPECT")) {
+        st->sample_aspect_ratio = var_read_float(pb, size);
+        av_reduce(&st->sample_aspect_ratio.num, &st->sample_aspect_ratio.den,
+                  st->sample_aspect_ratio.num, st->sample_aspect_ratio.den, INT_MAX);
+    } else if (!strcmp(name, "WIDTH")) {
+        st->codec->width = var_read_int(pb, size);
+    } else if (!strcmp(name, "ORIENTATION")) {
+        if (var_read_int(pb, size) == 1101) {
+            st->codec->extradata       = av_strdup("BottomUp");
+            st->codec->extradata_size  = 9;
+        }
+    } else if (!strcmp(name, "Q_SPATIAL") || !strcmp(name, "Q_TEMPORAL")) {
+        var_read_metadata(avctx, name, size);
+    } else if (!strcmp(name, "INTERLACING") || !strcmp(name, "PACKING")) {
+        avio_skip(pb, size); // ignore
+    } else
+        return -1;
+    return 0;
+}
+
+static void read_table(AVFormatContext *avctx, AVStream *st, int (*parse)(AVFormatContext *avctx, AVStream *st, const char *name, int size))
+{
+    int count, i;
+    AVIOContext *pb = avctx->pb;
+    avio_skip(pb, 4);
+    count = avio_rb32(pb);
+    avio_skip(pb, 4);
+    for (i = 0; i < count; i++) {
+        char name[17];
+        int size;
+        avio_read(pb, name, 16);
+        name[sizeof(name) - 1] = 0;
+        size = avio_rb32(pb);
+        if (parse(avctx, st, name, size) < 0) {
+            av_log_ask_for_sample(avctx, "unknown variable %s\n", name);
+            avio_skip(pb, size);
+        }
+    }
+}
+
+static void read_index(AVIOContext *pb, AVStream *st)
+{
+    uint64_t timestamp = 0;
+    int i;
+    for (i = 0; i < st->nb_frames; i++) {
+        uint32_t pos  = avio_rb32(pb);
+        uint32_t size = avio_rb32(pb);
+        avio_skip(pb, 8);
+        av_add_index_entry(st, pos, timestamp, size, 0, AVINDEX_KEYFRAME);
+        if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
+            timestamp += size / (st->codec->channels * 2);
+        } else {
+            timestamp++;
+        }
+    }
+}
+
+static int mv_read_header(AVFormatContext *avctx)
+{
+    MvContext *mv = avctx->priv_data;
+    AVIOContext *pb = avctx->pb;
+    AVStream *ast = NULL, *vst = NULL; //initialization to suppress warning
+    int version, i;
+
+    avio_skip(pb, 4);
+
+    version = avio_rb16(pb);
+    if (version == 2) {
+        uint64_t timestamp;
+        int v;
+        avio_skip(pb, 22);
+
+        /* allocate audio track first to prevent unnecessary seeking
+           (audio packet always precede video packet for a given frame) */
+        ast = avformat_new_stream(avctx, NULL);
+        if (!ast)
+            return AVERROR(ENOMEM);
+
+        vst = avformat_new_stream(avctx, NULL);
+        if (!vst)
+            return AVERROR(ENOMEM);
+        vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+        avpriv_set_pts_info(vst, 64, 1, 15);
+        vst->nb_frames = avio_rb32(pb);
+        v = avio_rb32(pb);
+        switch (v) {
+        case 1:
+            vst->codec->codec_id = AV_CODEC_ID_MVC1;
+            break;
+        case 2:
+            vst->codec->pix_fmt  = AV_PIX_FMT_ARGB;
+            vst->codec->codec_id = AV_CODEC_ID_RAWVIDEO;
+            break;
+        default:
+            av_log_ask_for_sample(avctx, "unknown video compression %i\n", v);
+            break;
+        }
+        vst->codec->codec_tag = 0;
+        vst->codec->width     = avio_rb32(pb);
+        vst->codec->height    = avio_rb32(pb);
+        avio_skip(pb, 12);
+
+        ast->codec->codec_type     = AVMEDIA_TYPE_AUDIO;
+        ast->nb_frames             = vst->nb_frames;
+        ast->codec->sample_rate    = avio_rb32(pb);
+        avpriv_set_pts_info(ast, 33, 1, ast->codec->sample_rate);
+        if (set_channels(avctx, ast, avio_rb32(pb)) < 0)
+            return AVERROR_INVALIDDATA;
+
+        v = avio_rb32(pb);
+        if (v == AUDIO_FORMAT_SIGNED) {
+            ast->codec->codec_id = AV_CODEC_ID_PCM_S16BE;
+        } else {
+            av_log_ask_for_sample(avctx, "unknown audio compression (format %i)\n", v);
+        }
+
+        avio_skip(pb, 12);
+        var_read_metadata(avctx, "title", 0x80);
+        var_read_metadata(avctx, "comment", 0x100);
+        avio_skip(pb, 0x80);
+
+        timestamp = 0;
+        for (i = 0; i < vst->nb_frames; i++) {
+            uint32_t pos   = avio_rb32(pb);
+            uint32_t asize = avio_rb32(pb);
+            uint32_t vsize = avio_rb32(pb);
+            avio_skip(pb, 8);
+            av_add_index_entry(ast, pos,         timestamp, asize, 0, AVINDEX_KEYFRAME);
+            av_add_index_entry(vst, pos + asize, i,         vsize, 0, AVINDEX_KEYFRAME);
+            timestamp += asize / (ast->codec->channels * 2);
+        }
+    } else if (!version && avio_rb16(pb) == 3) {
+        avio_skip(pb, 4);
+
+        read_table(avctx, NULL, parse_global_var);
+
+        if (mv->nb_audio_tracks > 1) {
+            av_log_ask_for_sample(avctx, "multiple audio streams\n");
+            return AVERROR_PATCHWELCOME;
+        } else if (mv->nb_audio_tracks) {
+            ast = avformat_new_stream(avctx, NULL);
+            if (!ast)
+                return AVERROR(ENOMEM);
+            ast->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+            /* temporarily store compression value in codec_tag; format value in codec_id */
+            read_table(avctx, ast, parse_audio_var);
+            if (ast->codec->codec_tag == 100 && ast->codec->codec_id == AUDIO_FORMAT_SIGNED && ast->codec->bits_per_coded_sample == 16) {
+                ast->codec->codec_id = AV_CODEC_ID_PCM_S16BE;
+            } else {
+                av_log_ask_for_sample(avctx, "unknown audio compression %i (format %i, width %i)\n",
+                    ast->codec->codec_tag, ast->codec->codec_id, ast->codec->bits_per_coded_sample);
+                ast->codec->codec_id = AV_CODEC_ID_NONE;
+            }
+            ast->codec->codec_tag = 0;
+            if (ast->codec->channels <= 0) {
+                av_log(avctx, AV_LOG_ERROR, "No valid channel count found\n");
+                return AVERROR_INVALIDDATA;
+            }
+        }
+
+        if (mv->nb_video_tracks > 1) {
+            av_log_ask_for_sample(avctx, "multiple video streams\n");
+            return AVERROR_PATCHWELCOME;
+        } else if (mv->nb_video_tracks) {
+            vst = avformat_new_stream(avctx, NULL);
+            if (!vst)
+                return AVERROR(ENOMEM);
+            vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+            read_table(avctx, vst, parse_video_var);
+        }
+
+        if (mv->nb_audio_tracks)
+            read_index(pb, ast);
+
+        if (mv->nb_video_tracks)
+            read_index(pb, vst);
+    } else {
+        av_log_ask_for_sample(avctx, "unknown version %i\n", version);
+        return AVERROR_PATCHWELCOME;
+    }
+
+    return 0;
+}
+
+static int mv_read_packet(AVFormatContext *avctx, AVPacket *pkt)
+{
+    MvContext *mv = avctx->priv_data;
+    AVIOContext *pb = avctx->pb;
+    AVStream *st = avctx->streams[mv->stream_index];
+    const AVIndexEntry *index;
+    int frame = mv->frame[mv->stream_index];
+    int ret;
+    uint64_t pos;
+
+    if (frame  < st->nb_index_entries) {
+        index = &st->index_entries[frame];
+        pos = avio_tell(pb);
+        if (index->pos > pos)
+            avio_skip(pb, index->pos - pos);
+        else if (index->pos < pos) {
+            if (!pb->seekable)
+                return AVERROR(EIO);
+            ret = avio_seek(pb, index->pos, SEEK_SET);
+            if (ret < 0)
+                return ret;
+        }
+        ret = av_get_packet(pb, pkt, index->size);
+        if (ret < 0)
+            return ret;
+
+        pkt->stream_index = mv->stream_index;
+        pkt->pts = index->timestamp;
+        pkt->flags |= AV_PKT_FLAG_KEY;
+
+        mv->frame[mv->stream_index]++;
+        mv->eof_count = 0;
+    } else {
+        mv->eof_count++;
+        if (mv->eof_count >= avctx->nb_streams)
+            return AVERROR_EOF;
+    }
+
+    mv->stream_index++;
+    if (mv->stream_index >= avctx->nb_streams)
+        mv->stream_index = 0;
+
+    return 0;
+}
+
+static int mv_read_seek(AVFormatContext *avctx, int stream_index, int64_t timestamp, int flags)
+{
+    MvContext *mv = avctx->priv_data;
+    AVStream *st = avctx->streams[stream_index];
+    int frame, i;
+
+    if ((flags & AVSEEK_FLAG_FRAME) || (flags & AVSEEK_FLAG_BYTE))
+        return AVERROR(ENOSYS);
+
+    if (!avctx->pb->seekable)
+        return AVERROR(EIO);
+
+    frame = av_index_search_timestamp(st, timestamp, flags);
+    if (frame < 0)
+        return -1;
+
+    for (i = 0; i < avctx->nb_streams; i++)
+        mv->frame[i] = frame;
+    return 0;
+}
+
+AVInputFormat ff_mv_demuxer = {
+    .name           = "mv",
+    .long_name      = NULL_IF_CONFIG_SMALL("Silicon Graphics Movie"),
+    .priv_data_size = sizeof(MvContext),
+    .read_probe     = mv_probe,
+    .read_header    = mv_read_header,
+    .read_packet    = mv_read_packet,
+    .read_seek      = mv_read_seek,
+};
diff --git a/libavformat/mvi.c b/libavformat/mvi.c
index 9184927..953c182 100644
--- a/libavformat/mvi.c
+++ b/libavformat/mvi.c
@@ -89,12 +89,17 @@
     ast->codec->bit_rate        = ast->codec->sample_rate * 8;
 
     avpriv_set_pts_info(vst, 64, msecs_per_frame, 1000000);
+    vst->avg_frame_rate    = av_inv_q(vst->time_base);
     vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
     vst->codec->codec_id   = AV_CODEC_ID_MOTIONPIXELS;
 
     mvi->get_int = (vst->codec->width * vst->codec->height < (1 << 16)) ? avio_rl16 : avio_rl24;
 
     mvi->audio_frame_size   = ((uint64_t)mvi->audio_data_size << MVI_FRAC_BITS) / frames_count;
+    if (!mvi->audio_frame_size) {
+        av_log(s, AV_LOG_ERROR, "audio_frame_size is 0\n");
+        return AVERROR_INVALIDDATA;
+    }
     mvi->audio_size_counter = (ast->codec->sample_rate * 830 / mvi->audio_frame_size - 1) * mvi->audio_frame_size;
     mvi->audio_size_left    = mvi->audio_data_size;
 
diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c
index 921dc42..f7aaa5a 100644
--- a/libavformat/mxfdec.c
+++ b/libavformat/mxfdec.c
@@ -134,6 +134,7 @@
     AVRational edit_rate;
     int intra_only;
     uint64_t sample_count;
+    int64_t original_duration;  ///< duration before multiplying st->duration by SampleRate/EditRate
 } MXFTrack;
 
 typedef struct {
@@ -866,7 +867,11 @@
     default:
         /* Private uid used by SONY C0023S01.mxf */
         if (IS_KLV_KEY(uid, mxf_sony_mpeg4_extradata)) {
-            descriptor->extradata = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
+            if (descriptor->extradata)
+                av_log(NULL, AV_LOG_WARNING, "Duplicate sony_mpeg4_extradata\n");
+            av_free(descriptor->extradata);
+            descriptor->extradata_size = 0;
+            descriptor->extradata = av_malloc(size);
             if (!descriptor->extradata)
                 return AVERROR(ENOMEM);
             descriptor->extradata_size = size;
@@ -1441,7 +1446,7 @@
         }
         st->id = source_track->track_id;
         st->priv_data = source_track;
-        st->duration = component->duration;
+        source_track->original_duration = st->duration = component->duration;
         if (st->duration == -1)
             st->duration = AV_NOPTS_VALUE;
         st->start_time = component->start_position;
@@ -1453,6 +1458,9 @@
         }
         avpriv_set_pts_info(st, 64, material_track->edit_rate.den, material_track->edit_rate.num);
 
+        /* ensure SourceTrack EditRate == MaterialTrack EditRate since only the former is accessible via st->priv_data */
+        source_track->edit_rate = material_track->edit_rate;
+
         PRINT_KEY(mxf->fc, "data definition   ul", source_track->sequence->data_definition_ul);
         codec_ul = mxf_get_codec_ul(ff_mxf_data_definition_uls, &source_track->sequence->data_definition_ul);
         st->codec->codec_type = codec_ul->id;
@@ -1498,10 +1506,15 @@
         /* TODO: drop PictureEssenceCoding and SoundEssenceCompression, only check EssenceContainer */
         codec_ul = mxf_get_codec_ul(ff_mxf_codec_uls, &descriptor->essence_codec_ul);
         st->codec->codec_id = (enum AVCodecID)codec_ul->id;
-        if (descriptor->extradata) {
-            st->codec->extradata = descriptor->extradata;
-            st->codec->extradata_size = descriptor->extradata_size;
+        av_log(mxf->fc, AV_LOG_VERBOSE, "%s: Universal Label: ",
+               avcodec_get_name(st->codec->codec_id));
+        for (k = 0; k < 16; k++) {
+            av_log(mxf->fc, AV_LOG_VERBOSE, "%.2x",
+                   descriptor->essence_codec_ul[k]);
+            if (!(k+1 & 19) || k == 5)
+                av_log(mxf->fc, AV_LOG_VERBOSE, ".");
         }
+        av_log(mxf->fc, AV_LOG_VERBOSE, "\n");
         if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
             source_track->intra_only = mxf_is_intra_only(descriptor);
             container_ul = mxf_get_codec_ul(mxf_picture_essence_container_uls, essence_container_ul);
@@ -1515,6 +1528,7 @@
                     av_log(mxf->fc, AV_LOG_INFO, "SegmentedFrame layout isn't currently supported\n");
                     break;
                 case FullFrame:
+                    st->codec->field_order = AV_FIELD_PROGRESSIVE;
                     break;
                 case OneField:
                     /* Every other line is stored and needs to be duplicated. */
@@ -1565,6 +1579,10 @@
                 avpriv_set_pts_info(st, 64, 1, 48000);
             }
 
+            /* if duration is set, rescale it from EditRate to SampleRate */
+            if (st->duration != AV_NOPTS_VALUE)
+                st->duration = av_rescale_q(st->duration, av_inv_q(material_track->edit_rate), st->time_base);
+
             /* TODO: implement AV_CODEC_ID_RAWAUDIO */
             if (st->codec->codec_id == AV_CODEC_ID_PCM_S16LE) {
                 if (descriptor->bits_per_sample > 16 && descriptor->bits_per_sample <= 24)
@@ -1580,6 +1598,13 @@
                 st->need_parsing = AVSTREAM_PARSE_FULL;
             }
         }
+        if (descriptor->extradata) {
+            st->codec->extradata = av_mallocz(descriptor->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
+            if (st->codec->extradata)
+                memcpy(st->codec->extradata, descriptor->extradata, descriptor->extradata_size);
+        } else if(st->codec->codec_id == CODEC_ID_H264) {
+            ff_generate_avci_extradata(st);
+        }
         if (st->codec->codec_type != AVMEDIA_TYPE_DATA && (*essence_container_ul)[15] > 0x01) {
             /* TODO: decode timestamps */
             st->need_parsing = AVSTREAM_PARSE_TIMESTAMPS;
@@ -2052,7 +2077,9 @@
 {
     MXFTrack *track = mxf->fc->streams[pkt->stream_index]->priv_data;
     pkt->pts = track->sample_count;
-    track->sample_count += pkt->size / (codec->channels * av_get_bits_per_sample(codec->codec_id) / 8);
+    if (codec->channels <= 0 || av_get_bits_per_sample(codec->codec_id) <= 0)
+        return AVERROR(EINVAL);
+    track->sample_count += pkt->size / (codec->channels * (int64_t)av_get_bits_per_sample(codec->codec_id) / 8);
     return 0;
 }
 
@@ -2224,6 +2251,9 @@
 
     for (i = 0; i < mxf->metadata_sets_count; i++) {
         switch (mxf->metadata_sets[i]->type) {
+        case Descriptor:
+            av_freep(&((MXFDescriptor *)mxf->metadata_sets[i])->extradata);
+            break;
         case MultipleDescriptor:
             av_freep(&((MXFDescriptor *)mxf->metadata_sets[i])->sub_descriptors_refs);
             break;
@@ -2263,8 +2293,8 @@
 }
 
 static int mxf_probe(AVProbeData *p) {
-    uint8_t *bufp = p->buf;
-    uint8_t *end = p->buf + p->buf_size;
+    const uint8_t *bufp = p->buf;
+    const uint8_t *end = p->buf + p->buf_size;
 
     if (p->buf_size < sizeof(mxf_header_partition_pack_key))
         return 0;
@@ -2288,6 +2318,11 @@
     int64_t seekpos;
     int i, ret;
     MXFIndexTable *t;
+    MXFTrack *source_track = st->priv_data;
+
+    /* if audio then truncate sample_time to EditRate */
+    if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO)
+        sample_time = av_rescale_q(sample_time, st->time_base, av_inv_q(source_track->edit_rate));
 
     if (mxf->nb_index_tables <= 0) {
     if (!s->bit_rate)
@@ -2313,7 +2348,7 @@
         } else {
             /* no IndexEntryArray (one or more CBR segments)
              * make sure we don't seek past the end */
-            sample_time = FFMIN(sample_time, st->duration - 1);
+            sample_time = FFMIN(sample_time, source_track->original_duration - 1);
         }
 
         if ((ret = mxf_edit_unit_absolute_offset(mxf, t, sample_time, &sample_time, &seekpos, 1)) << 0)
diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c
index c583197..cf9b77d 100644
--- a/libavformat/mxfenc.c
+++ b/libavformat/mxfenc.c
@@ -170,7 +170,7 @@
       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 },
       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
       mxf_write_generic_sound_desc },
-    // DV Unknwon
+    // DV Unknown
     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x7F,0x01 },
       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 },
       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x00,0x00,0x00 },
@@ -1401,7 +1401,7 @@
     MXFStreamContext *sc = st->priv_data;
     int i, cid;
     uint8_t* header_cid;
-    unsigned int frame_size = 0;
+    int frame_size = 0;
 
     if (mxf->header_written)
         return 1;
@@ -1412,7 +1412,7 @@
     header_cid = pkt->data + 0x28;
     cid = header_cid[0] << 24 | header_cid[1] << 16 | header_cid[2] << 8 | header_cid[3];
 
-    if ((i = ff_dnxhd_get_cid_table(cid)) < 0)
+    if ((frame_size = avpriv_dnxhd_get_frame_size(cid)) < 0)
         return -1;
 
     switch (cid) {
@@ -1453,7 +1453,6 @@
         return -1;
     }
 
-    frame_size = ff_dnxhd_cid_table[i].frame_size;
     sc->codec_ul = &mxf_essence_container_uls[sc->index].codec_ul;
     sc->aspect_ratio = (AVRational){ 16, 9 };
 
diff --git a/libavformat/mxg.c b/libavformat/mxg.c
index d911a33..e9a6f22 100644
--- a/libavformat/mxg.c
+++ b/libavformat/mxg.c
@@ -101,17 +101,19 @@
     MXGContext *mxg = s->priv_data;
     unsigned int current_pos = mxg->buffer_ptr - mxg->buffer;
     unsigned int soi_pos;
+    uint8_t *buffer;
     int ret;
 
     /* reallocate internal buffer */
     if (current_pos > current_pos + cache_size)
         return AVERROR(ENOMEM);
     soi_pos = mxg->soi_ptr - mxg->buffer;
-    mxg->buffer = av_fast_realloc(mxg->buffer, &mxg->buffer_size,
-                                  current_pos + cache_size +
-                                  FF_INPUT_BUFFER_PADDING_SIZE);
-    if (!mxg->buffer)
+    buffer = av_fast_realloc(mxg->buffer, &mxg->buffer_size,
+                             current_pos + cache_size +
+                             FF_INPUT_BUFFER_PADDING_SIZE);
+    if (!buffer)
         return AVERROR(ENOMEM);
+    mxg->buffer = buffer;
     mxg->buffer_ptr = mxg->buffer + current_pos;
     if (mxg->soi_ptr) mxg->soi_ptr = mxg->buffer + soi_pos;
 
diff --git a/libavformat/network.c b/libavformat/network.c
index 6e924be..ceed719 100644
--- a/libavformat/network.c
+++ b/libavformat/network.c
@@ -28,6 +28,8 @@
 #if HAVE_THREADS
 #if HAVE_PTHREADS
 #include <pthread.h>
+#elif HAVE_OS2THREADS
+#include "libavcodec/os2threads.h"
 #else
 #include "libavcodec/w32pthreads.h"
 #endif
@@ -60,8 +62,6 @@
 #if HAVE_THREADS && GNUTLS_VERSION_NUMBER <= 0x020b00
 #include <gcrypt.h>
 #include <errno.h>
-#undef malloc
-#undef free
 GCRY_THREAD_OPTION_PTHREAD_IMPL;
 #endif
 #endif
diff --git a/libavformat/nistspheredec.c b/libavformat/nistspheredec.c
new file mode 100644
index 0000000..59c2020
--- /dev/null
+++ b/libavformat/nistspheredec.c
@@ -0,0 +1,128 @@
+/*
+ * NIST Sphere demuxer
+ * 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/avstring.h"
+#include "libavutil/intreadwrite.h"
+#include "avformat.h"
+#include "internal.h"
+#include "pcm.h"
+
+static int nist_probe(AVProbeData *p)
+{
+    if (AV_RL64(p->buf) == AV_RL64("NIST_1A\x0a"))
+        return AVPROBE_SCORE_MAX;
+    return 0;
+}
+
+static int nist_read_header(AVFormatContext *s)
+{
+    char buffer[32], coding[32] = "pcm", format[32] = "01";
+    int bps = 0, be = 0;
+    int32_t header_size;
+    AVStream *st;
+
+    st = avformat_new_stream(s, NULL);
+    if (!st)
+        return AVERROR(ENOMEM);
+
+    st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+
+    ff_get_line(s->pb, buffer, sizeof(buffer));
+    ff_get_line(s->pb, buffer, sizeof(buffer));
+    sscanf(buffer, "%"SCNd32, &header_size);
+    if (header_size <= 0)
+        return AVERROR_INVALIDDATA;
+
+    while (!url_feof(s->pb)) {
+        ff_get_line(s->pb, buffer, sizeof(buffer));
+
+        if (avio_tell(s->pb) >= header_size)
+            return AVERROR_INVALIDDATA;
+
+        if (!memcmp(buffer, "end_head", 8)) {
+            if (!st->codec->bits_per_coded_sample)
+                st->codec->bits_per_coded_sample = bps << 3;
+
+            if (!av_strcasecmp(coding, "pcm")) {
+                st->codec->codec_id = ff_get_pcm_codec_id(st->codec->bits_per_coded_sample,
+                                                          0, be, 0xFFFF);
+            } else if (!av_strcasecmp(coding, "alaw")) {
+                st->codec->codec_id = AV_CODEC_ID_PCM_ALAW;
+            } else if (!av_strcasecmp(coding, "ulaw") ||
+                       !av_strcasecmp(coding, "mu-law")) {
+                st->codec->codec_id = AV_CODEC_ID_PCM_MULAW;
+            } else {
+                av_log_ask_for_sample(s, "unsupported coding: %s\n", coding);
+            }
+
+            avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
+
+            st->codec->block_align = st->codec->bits_per_coded_sample * st->codec->channels / 8;
+
+            if (avio_tell(s->pb) > header_size)
+                return AVERROR_INVALIDDATA;
+
+            avio_skip(s->pb, header_size - avio_tell(s->pb));
+
+            return 0;
+        } else if (!memcmp(buffer, "channel_count", 13)) {
+            sscanf(buffer, "%*s %*s %"SCNd32, &st->codec->channels);
+        } else if (!memcmp(buffer, "sample_byte_format", 18)) {
+            sscanf(buffer, "%*s %*s %31s", format);
+
+            if (!av_strcasecmp(format, "01")) {
+                be = 0;
+            } else if (!av_strcasecmp(format, "10")) {
+                be = 1;
+            } else if (av_strcasecmp(format, "1")) {
+                av_log_ask_for_sample(s, "unsupported sample byte format: %s\n", format);
+                return AVERROR_PATCHWELCOME;
+            }
+        } else if (!memcmp(buffer, "sample_coding", 13)) {
+            sscanf(buffer, "%*s %*s %31s", coding);
+        } else if (!memcmp(buffer, "sample_count", 12)) {
+            sscanf(buffer, "%*s %*s %"SCNd64, &st->duration);
+        } else if (!memcmp(buffer, "sample_n_bytes", 14)) {
+            sscanf(buffer, "%*s %*s %"SCNd32, &bps);
+        } else if (!memcmp(buffer, "sample_rate", 11)) {
+            sscanf(buffer, "%*s %*s %"SCNd32, &st->codec->sample_rate);
+        } else if (!memcmp(buffer, "sample_sig_bits", 15)) {
+            sscanf(buffer, "%*s %*s %"SCNd32, &st->codec->bits_per_coded_sample);
+        } else {
+            char key[32], value[32];
+            sscanf(buffer, "%31s %*s %31s", key, value);
+            av_dict_set(&s->metadata, key, value, AV_DICT_APPEND);
+        }
+    }
+
+    return AVERROR_EOF;
+}
+
+AVInputFormat ff_nistsphere_demuxer = {
+    .name           = "nistsphere",
+    .long_name      = NULL_IF_CONFIG_SMALL("NIST SPeech HEader REsources"),
+    .read_probe     = nist_probe,
+    .read_header    = nist_read_header,
+    .read_packet    = ff_pcm_read_packet,
+    .read_seek      = ff_pcm_read_seek,
+    .extensions     = "nist,sph",
+    .flags          = AVFMT_GENERIC_INDEX,
+};
diff --git a/libavformat/noproxy-test.c b/libavformat/noproxy-test.c
new file mode 100644
index 0000000..a156620
--- /dev/null
+++ b/libavformat/noproxy-test.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2013 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 "internal.h"
+
+static void test(const char *pattern, const char *host)
+{
+    int res = ff_http_match_no_proxy(pattern, host);
+    printf("The pattern \"%s\" %s the hostname %s\n",
+           pattern ? pattern : "(null)", res ? "matches" : "does not match",
+           host);
+}
+
+int main(void)
+{
+    test(NULL, "domain.com");
+    test("example.com domain.com", "domain.com");
+    test("example.com other.com", "domain.com");
+    test("example.com,domain.com", "domain.com");
+    test("example.com,domain.com", "otherdomain.com");
+    test("example.com, *.domain.com", "sub.domain.com");
+    test("example.com, *.domain.com", "domain.com");
+    test("example.com, .domain.com", "domain.com");
+    test("*", "domain.com");
+    return 0;
+}
diff --git a/libavformat/nsvdec.c b/libavformat/nsvdec.c
index b6984a6..bcc2180 100644
--- a/libavformat/nsvdec.c
+++ b/libavformat/nsvdec.c
@@ -251,7 +251,7 @@
             nsv->state = NSV_FOUND_BEEF;
             return 0;
         }
-        /* we read as big endian, thus the MK*BE* */
+        /* we read as big-endian, thus the MK*BE* */
         if (v == TB_NSVF) { /* NSVf */
             av_dlog(s, "NSV resynced on NSVf after %d bytes\n", i+1);
             nsv->state = NSV_FOUND_NSVF;
diff --git a/libavformat/nut.c b/libavformat/nut.c
index 62a650d..2abe969 100644
--- a/libavformat/nut.c
+++ b/libavformat/nut.c
@@ -40,6 +40,7 @@
 };
 
 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 ) },
diff --git a/libavformat/nutdec.c b/libavformat/nutdec.c
index ac3ef7d..f260a3e 100644
--- a/libavformat/nutdec.c
+++ b/libavformat/nutdec.c
@@ -522,6 +522,8 @@
 
             if (stream_id_plus1 && !strcmp(name, "r_frame_rate")) {
                 sscanf(str_value, "%d/%d", &st->r_frame_rate.num, &st->r_frame_rate.den);
+                if (st->r_frame_rate.num >= 1000LL*st->r_frame_rate.den)
+                    st->r_frame_rate.num = st->r_frame_rate.den = 0;
                 continue;
             }
 
diff --git a/libavformat/nutenc.c b/libavformat/nutenc.c
index 4671152..2d8d265 100644
--- a/libavformat/nutenc.c
+++ b/libavformat/nutenc.c
@@ -990,7 +990,7 @@
         write_headers(s, bc);
 
     ret = avio_open_dyn_buf(&dyn_bc);
-    if (ret >= 0) {
+    if (ret >= 0 && nut->sp_count) {
         write_index(nut, dyn_bc);
         put_packet(nut, bc, dyn_bc, 1, INDEX_STARTCODE);
     }
diff --git a/libavformat/oggdec.c b/libavformat/oggdec.c
index 3ca33dc..5cb03fe 100644
--- a/libavformat/oggdec.c
+++ b/libavformat/oggdec.c
@@ -57,25 +57,25 @@
 };
 
 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts);
-static int ogg_read_close(AVFormatContext *s);
+static int ogg_new_stream(AVFormatContext *s, uint32_t serial);
 
 //FIXME We could avoid some structure duplication
 static int ogg_save(AVFormatContext *s)
 {
     struct ogg *ogg = s->priv_data;
     struct ogg_state *ost =
-        av_malloc(sizeof (*ost) + (ogg->nstreams-1) * sizeof (*ogg->streams));
+        av_malloc(sizeof(*ost) + (ogg->nstreams - 1) * sizeof(*ogg->streams));
     int i;
-    ost->pos = avio_tell (s->pb);
-    ost->curidx = ogg->curidx;
-    ost->next = ogg->state;
+    ost->pos      = avio_tell(s->pb);
+    ost->curidx   = ogg->curidx;
+    ost->next     = ogg->state;
     ost->nstreams = ogg->nstreams;
     memcpy(ost->streams, ogg->streams, ogg->nstreams * sizeof(*ogg->streams));
 
-    for (i = 0; i < ogg->nstreams; i++){
+    for (i = 0; i < ogg->nstreams; i++) {
         struct ogg_stream *os = ogg->streams + i;
-        os->buf = av_mallocz (os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
-        memcpy (os->buf, ost->streams[i].buf, os->bufpos);
+        os->buf = av_mallocz(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
+        memcpy(os->buf, ost->streams[i].buf, os->bufpos);
     }
 
     ogg->state = ost;
@@ -95,17 +95,18 @@
 
     ogg->state = ost->next;
 
-    if (!discard){
+    if (!discard) {
         struct ogg_stream *old_streams = ogg->streams;
 
         for (i = 0; i < ogg->nstreams; i++)
-            av_free (ogg->streams[i].buf);
+            av_free(ogg->streams[i].buf);
 
-        avio_seek (bc, ost->pos, SEEK_SET);
-        ogg->curidx = ost->curidx;
+        avio_seek(bc, ost->pos, SEEK_SET);
+        ogg->page_pos = -1;
+        ogg->curidx   = ost->curidx;
         ogg->nstreams = ost->nstreams;
-        ogg->streams = av_realloc (ogg->streams,
-                                   ogg->nstreams * sizeof (*ogg->streams));
+        ogg->streams  = av_realloc(ogg->streams,
+                                   ogg->nstreams * sizeof(*ogg->streams));
 
         if (ogg->streams) {
             memcpy(ogg->streams, ost->streams,
@@ -116,7 +117,7 @@
         }
     }
 
-    av_free (ost);
+    av_free(ost);
 
     return 0;
 }
@@ -127,18 +128,18 @@
     int i;
     int64_t start_pos = avio_tell(s->pb);
 
-    for (i = 0; i < ogg->nstreams; i++){
+    for (i = 0; i < ogg->nstreams; i++) {
         struct ogg_stream *os = ogg->streams + i;
-        os->bufpos = 0;
-        os->pstart = 0;
-        os->psize = 0;
-        os->granule = -1;
-        os->lastpts = AV_NOPTS_VALUE;
-        os->lastdts = AV_NOPTS_VALUE;
-        os->sync_pos = -1;
-        os->page_pos = 0;
-        os->nsegs = 0;
-        os->segp = 0;
+        os->bufpos     = 0;
+        os->pstart     = 0;
+        os->psize      = 0;
+        os->granule    = -1;
+        os->lastpts    = AV_NOPTS_VALUE;
+        os->lastdts    = AV_NOPTS_VALUE;
+        os->sync_pos   = -1;
+        os->page_pos   = 0;
+        os->nsegs      = 0;
+        os->segp       = 0;
         os->incomplete = 0;
         os->got_data = 0;
         if (start_pos <= s->data_offset) {
@@ -146,6 +147,7 @@
         }
     }
 
+    ogg->page_pos = -1;
     ogg->curidx = -1;
 
     return 0;
@@ -157,7 +159,7 @@
 
     for (i = 0; ogg_codecs[i]; i++)
         if (size >= ogg_codecs[i]->magicsize &&
-            !memcmp (buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
+            !memcmp(buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
             return ogg_codecs[i];
 
     return NULL;
@@ -168,41 +170,65 @@
  * situation where a new audio stream spawn (identified with a new serial) and
  * must replace the previous one (track switch).
  */
-static int ogg_replace_stream(AVFormatContext *s, uint32_t serial)
+static int ogg_replace_stream(AVFormatContext *s, uint32_t serial, int nsegs)
 {
     struct ogg *ogg = s->priv_data;
     struct ogg_stream *os;
-    unsigned bufsize;
-    uint8_t *buf;
+    const struct ogg_codec *codec;
+    int i = 0;
 
-    if (ogg->nstreams != 1) {
+    if (s->pb->seekable) {
+        uint8_t magic[8];
+        int64_t pos = avio_tell(s->pb);
+        avio_skip(s->pb, nsegs);
+        avio_read(s->pb, magic, sizeof(magic));
+        avio_seek(s->pb, pos, SEEK_SET);
+        codec = ogg_find_codec(magic, sizeof(magic));
+        if (!codec) {
+            av_log(s, AV_LOG_ERROR, "Cannot identify new stream\n");
+            return AVERROR_INVALIDDATA;
+        }
+        for (i = 0; i < ogg->nstreams; i++) {
+            if (ogg->streams[i].codec == codec)
+                break;
+        }
+        if (i >= ogg->nstreams)
+            return ogg_new_stream(s, serial);
+    } else if (ogg->nstreams != 1) {
         av_log_missing_feature(s, "Changing stream parameters in multistream ogg", 0);
         return AVERROR_PATCHWELCOME;
     }
 
-    os = &ogg->streams[0];
+    os = &ogg->streams[i];
 
-    buf = os->buf;
+    os->serial  = serial;
+    return i;
+
+#if 0
+    buf     = os->buf;
     bufsize = os->bufsize;
+    codec   = os->codec;
 
-    if (!ogg->state || ogg->state->streams[0].private != os->private)
-        av_freep(&ogg->streams[0].private);
+    if (!ogg->state || ogg->state->streams[i].private != os->private)
+        av_freep(&ogg->streams[i].private);
 
     /* Set Ogg stream settings similar to what is done in ogg_new_stream(). We
      * also re-use the ogg_stream allocated buffer */
     memset(os, 0, sizeof(*os));
-    os->serial = serial;
+    os->serial  = serial;
     os->bufsize = bufsize;
-    os->buf = buf;
-    os->header = -1;
+    os->buf     = buf;
+    os->header  = -1;
+    os->codec   = codec;
 
-    return 0;
+    return i;
+#endif
 }
 
 static int ogg_new_stream(AVFormatContext *s, uint32_t serial)
 {
     struct ogg *ogg = s->priv_data;
-    int idx = ogg->nstreams;
+    int idx         = ogg->nstreams;
     AVStream *st;
     struct ogg_stream *os;
     size_t size;
@@ -218,12 +244,12 @@
         !(os = av_realloc(ogg->streams, size)))
         return AVERROR(ENOMEM);
     ogg->streams = os;
-    os = ogg->streams + idx;
+    os           = ogg->streams + idx;
     memset(os, 0, sizeof(*os));
-    os->serial = serial;
-    os->bufsize = DECODER_BUFFER_SIZE;
-    os->buf = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
-    os->header = -1;
+    os->serial        = serial;
+    os->bufsize       = DECODER_BUFFER_SIZE;
+    os->buf           = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
+    os->header        = -1;
     os->start_granule = OGG_NOGRANULE_VALUE;
     if (!os->buf)
         return AVERROR(ENOMEM);
@@ -246,11 +272,13 @@
     struct ogg_stream *os = ogg->streams + idx;
     uint8_t *nb = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
     int size = os->bufpos - os->pstart;
-    if(os->buf){
+
+    if (os->buf) {
         memcpy(nb, os->buf + os->pstart, size);
         av_free(os->buf);
     }
-    os->buf = nb;
+
+    os->buf    = nb;
     os->bufpos = size;
     os->pstart = 0;
 
@@ -284,7 +312,7 @@
     if (ret < 4)
         return ret < 0 ? ret : AVERROR_EOF;
 
-    do{
+    do {
         int c;
 
         if (sync[sp & 3] == 'O' &&
@@ -292,32 +320,40 @@
             sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
             break;
 
+        if(!i && bc->seekable && ogg->page_pos > 0) {
+            memset(sync, 0, 4);
+            avio_seek(bc, ogg->page_pos+4, SEEK_SET);
+            ogg->page_pos = -1;
+        }
+
         c = avio_r8(bc);
+
         if (url_feof(bc))
             return AVERROR_EOF;
-        sync[sp++ & 3] = c;
-    }while (i++ < MAX_PAGE_SIZE);
 
-    if (i >= MAX_PAGE_SIZE){
-        av_log (s, AV_LOG_INFO, "ogg, can't find sync word\n");
+        sync[sp++ & 3] = c;
+    } while (i++ < MAX_PAGE_SIZE);
+
+    if (i >= MAX_PAGE_SIZE) {
+        av_log(s, AV_LOG_INFO, "cannot find sync word\n");
         return AVERROR_INVALIDDATA;
     }
 
-    if (avio_r8(bc) != 0){      /* version */
+    if (avio_r8(bc) != 0) {      /* version */
         av_log (s, AV_LOG_ERROR, "ogg page, unsupported version\n");
         return AVERROR_INVALIDDATA;
     }
 
-    flags = avio_r8(bc);
-    gp = avio_rl64 (bc);
-    serial = avio_rl32 (bc);
+    flags  = avio_r8(bc);
+    gp     = avio_rl64(bc);
+    serial = avio_rl32(bc);
     avio_skip(bc, 8); /* seq, crc */
-    nsegs = avio_r8(bc);
+    nsegs  = avio_r8(bc);
 
-    idx = ogg_find_stream (ogg, serial);
-    if (idx < 0){
+    idx = ogg_find_stream(ogg, serial);
+    if (idx < 0) {
         if (data_packets_seen(ogg))
-            idx = ogg_replace_stream(s, serial);
+            idx = ogg_replace_stream(s, serial, nsegs);
         else
             idx = ogg_new_stream(s, serial);
 
@@ -328,9 +364,10 @@
     }
 
     os = ogg->streams + idx;
+    ogg->page_pos =
     os->page_pos = avio_tell(bc) - 27;
 
-    if(os->psize > 0)
+    if (os->psize > 0)
         ogg_new_buf(ogg, idx);
 
     ret = avio_read(bc, os->segments, nsegs);
@@ -338,7 +375,7 @@
         return ret < 0 ? ret : AVERROR_EOF;
 
     os->nsegs = nsegs;
-    os->segp = 0;
+    os->segp  = 0;
 
     size = 0;
     for (i = 0; i < nsegs; i++)
@@ -347,12 +384,12 @@
     if (!(flags & OGG_FLAG_BOS))
         os->got_data = 1;
 
-    if (flags & OGG_FLAG_CONT || os->incomplete){
-        if (!os->psize){
+    if (flags & OGG_FLAG_CONT || os->incomplete) {
+        if (!os->psize) {
             // If this is the very first segment we started
             // playback in the middle of a continuation packet.
             // Discard it since we missed the start of it.
-            while (os->segp < os->nsegs){
+            while (os->segp < os->nsegs) {
                 int seg = os->segments[os->segp++];
                 os->pstart += seg;
                 if (seg < 255)
@@ -360,15 +397,17 @@
             }
             os->sync_pos = os->page_pos;
         }
-    }else{
-        os->psize = 0;
+    } else {
+        os->psize    = 0;
         os->sync_pos = os->page_pos;
     }
 
-    if (os->bufsize - os->bufpos < size){
-        uint8_t *nb = av_malloc ((os->bufsize *= 2) + FF_INPUT_BUFFER_PADDING_SIZE);
-        memcpy (nb, os->buf, os->bufpos);
-        av_free (os->buf);
+    if (os->bufsize - os->bufpos < size) {
+        uint8_t *nb = av_malloc((os->bufsize *= 2) + FF_INPUT_BUFFER_PADDING_SIZE);
+        if (!nb)
+            return AVERROR(ENOMEM);
+        memcpy(nb, os->buf, os->bufpos);
+        av_free(os->buf);
         os->buf = nb;
     }
 
@@ -378,7 +417,7 @@
 
     os->bufpos += size;
     os->granule = gp;
-    os->flags = flags;
+    os->flags   = flags;
 
     memset(os->buf + os->bufpos, 0, FF_INPUT_BUFFER_PADDING_SIZE);
     if (sid)
@@ -401,16 +440,16 @@
     int idx, i, ret;
     struct ogg_stream *os;
     int complete = 0;
-    int segp = 0, psize = 0;
+    int segp     = 0, psize = 0;
 
     av_dlog(s, "ogg_packet: curidx=%i\n", ogg->curidx);
     if (sid)
         *sid = -1;
 
-    do{
+    do {
         idx = ogg->curidx;
 
-        while (idx < 0){
+        while (idx < 0) {
             ret = ogg_read_page(s, &idx);
             if (ret < 0)
                 return ret;
@@ -421,52 +460,54 @@
         av_dlog(s, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
                 idx, os->pstart, os->psize, os->segp, os->nsegs);
 
-        if (!os->codec){
-            if (os->header < 0){
-                os->codec = ogg_find_codec (os->buf, os->bufpos);
-                if (!os->codec){
+        if (!os->codec) {
+            if (os->header < 0) {
+                os->codec = ogg_find_codec(os->buf, os->bufpos);
+                if (!os->codec) {
                     av_log(s, AV_LOG_WARNING, "Codec not found\n");
                     os->header = 0;
                     return 0;
                 }
-            }else{
+            } else {
                 return 0;
             }
         }
 
-        segp = os->segp;
+        segp  = os->segp;
         psize = os->psize;
 
-        while (os->segp < os->nsegs){
+        while (os->segp < os->nsegs) {
             int ss = os->segments[os->segp++];
             os->psize += ss;
-            if (ss < 255){
+            if (ss < 255) {
                 complete = 1;
                 break;
             }
         }
 
-        if (!complete && os->segp == os->nsegs){
-            ogg->curidx = -1;
+        if (!complete && os->segp == os->nsegs) {
+            ogg->curidx    = -1;
             // Do not set incomplete for empty packets.
             // Together with the code in ogg_read_page
             // that discards all continuation of empty packets
             // we would get an infinite loop.
             os->incomplete = !!os->psize;
         }
-    }while (!complete);
+    } while (!complete);
 
 
     if (os->granule == -1)
-        av_log(s, AV_LOG_WARNING, "Page at %"PRId64" is missing granule\n", os->page_pos);
+        av_log(s, AV_LOG_WARNING,
+               "Page at %"PRId64" is missing granule\n",
+               os->page_pos);
 
-    ogg->curidx = idx;
+    ogg->curidx    = idx;
     os->incomplete = 0;
 
     if (os->header) {
-        os->header = os->codec->header (s, idx);
-        if (!os->header){
-            os->segp = segp;
+        os->header = os->codec->header(s, idx);
+        if (!os->header) {
+            os->segp  = segp;
             os->psize = psize;
 
             // We have reached the first non-header packet in this stream.
@@ -478,6 +519,7 @@
             // compute the data_offset.
             if (!s->data_offset)
                 s->data_offset = os->sync_pos;
+
             for (i = 0; i < ogg->nstreams; i++) {
                 struct ogg_stream *cur_os = ogg->streams + i;
 
@@ -486,16 +528,16 @@
                 if (cur_os->incomplete)
                     s->data_offset = FFMIN(s->data_offset, cur_os->sync_pos);
             }
-        }else{
+        } else {
             os->nb_header++;
             os->pstart += os->psize;
-            os->psize = 0;
+            os->psize   = 0;
         }
     } else {
-        os->pflags = 0;
+        os->pflags    = 0;
         os->pduration = 0;
         if (os->codec && os->codec->packet)
-            os->codec->packet (s, idx);
+            os->codec->packet(s, idx);
         if (sid)
             *sid = idx;
         if (dstart)
@@ -504,8 +546,8 @@
             *dsize = os->psize;
         if (fpos)
             *fpos = os->sync_pos;
-        os->pstart += os->psize;
-        os->psize = 0;
+        os->pstart  += os->psize;
+        os->psize    = 0;
         if(os->pstart == os->bufpos)
             os->bufpos = os->pstart = 0;
         os->sync_pos = os->page_pos;
@@ -533,7 +575,7 @@
     int64_t size, end;
     int streams_left=0;
 
-    if(!s->pb->seekable)
+    if (!s->pb->seekable)
         return 0;
 
 // already set
@@ -541,30 +583,31 @@
         return 0;
 
     size = avio_size(s->pb);
-    if(size < 0)
+    if (size < 0)
         return 0;
-    end = size > MAX_PAGE_SIZE? size - MAX_PAGE_SIZE: 0;
+    end = size > MAX_PAGE_SIZE ? size - MAX_PAGE_SIZE : 0;
 
-    ogg_save (s);
-    avio_seek (s->pb, end, SEEK_SET);
+    ogg_save(s);
+    avio_seek(s->pb, end, SEEK_SET);
+    ogg->page_pos = -1;
 
-    while (!ogg_read_page (s, &i)){
+    while (!ogg_read_page(s, &i)) {
         if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
             ogg->streams[i].codec) {
             s->streams[i]->duration =
-                ogg_gptopts (s, i, ogg->streams[i].granule, NULL);
-            if (s->streams[i]->start_time != AV_NOPTS_VALUE){
+                ogg_gptopts(s, i, ogg->streams[i].granule, NULL);
+            if (s->streams[i]->start_time != AV_NOPTS_VALUE) {
                 s->streams[i]->duration -= s->streams[i]->start_time;
                 streams_left-= (ogg->streams[i].got_start==-1);
                 ogg->streams[i].got_start= 1;
-            }else if(!ogg->streams[i].got_start){
+            } else if(!ogg->streams[i].got_start) {
                 ogg->streams[i].got_start= -1;
                 streams_left++;
             }
         }
     }
 
-    ogg_restore (s, 0);
+    ogg_restore(s, 0);
 
     ogg_save (s);
     avio_seek (s->pb, s->data_offset, SEEK_SET);
@@ -573,11 +616,11 @@
         int64_t pts;
         if (i < 0) continue;
         pts = ogg_calc_pts(s, i, NULL);
-        if (pts != AV_NOPTS_VALUE && s->streams[i]->start_time == AV_NOPTS_VALUE && !ogg->streams[i].got_start){
+        if (pts != AV_NOPTS_VALUE && s->streams[i]->start_time == AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
             s->streams[i]->duration -= pts;
             ogg->streams[i].got_start= 1;
             streams_left--;
-        }else if(s->streams[i]->start_time != AV_NOPTS_VALUE && !ogg->streams[i].got_start){
+        }else if(s->streams[i]->start_time != AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
             ogg->streams[i].got_start= 1;
             streams_left--;
         }
@@ -587,6 +630,23 @@
     return 0;
 }
 
+static int ogg_read_close(AVFormatContext *s)
+{
+    struct ogg *ogg = s->priv_data;
+    int i;
+
+    for (i = 0; i < ogg->nstreams; i++) {
+        av_free(ogg->streams[i].buf);
+        if (ogg->streams[i].codec &&
+            ogg->streams[i].codec->cleanup) {
+            ogg->streams[i].codec->cleanup(s, i);
+        }
+        av_free(ogg->streams[i].private);
+    }
+    av_free(ogg->streams);
+    return 0;
+}
+
 static int ogg_read_header(AVFormatContext *s)
 {
     struct ogg *ogg = s->priv_data;
@@ -619,22 +679,22 @@
     }
 
     //linear granulepos seek from end
-    ogg_get_length (s);
+    ogg_get_length(s);
 
     return 0;
 }
 
 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
 {
-    struct ogg *ogg = s->priv_data;
+    struct ogg *ogg       = s->priv_data;
     struct ogg_stream *os = ogg->streams + idx;
-    int64_t pts = AV_NOPTS_VALUE;
+    int64_t pts           = AV_NOPTS_VALUE;
 
     if (dts)
         *dts = AV_NOPTS_VALUE;
 
     if (os->lastpts != AV_NOPTS_VALUE) {
-        pts = os->lastpts;
+        pts         = os->lastpts;
         os->lastpts = AV_NOPTS_VALUE;
     }
     if (os->lastdts != AV_NOPTS_VALUE) {
@@ -677,14 +737,14 @@
 
     //Get an ogg packet
 retry:
-    do{
+    do {
         ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
         if (ret < 0)
             return ret;
-    }while (idx < 0 || !s->streams[idx]);
+    } while (idx < 0 || !s->streams[idx]);
 
     ogg = s->priv_data;
-    os = ogg->streams + idx;
+    os  = ogg->streams + idx;
 
     // pflags might not be set until after this
     pts = ogg_calc_pts(s, idx, &dts);
@@ -699,43 +759,31 @@
     if (ret < 0)
         return ret;
     pkt->stream_index = idx;
-    memcpy (pkt->data, os->buf + pstart, psize);
+    memcpy(pkt->data, os->buf + pstart, psize);
 
-    pkt->pts = pts;
-    pkt->dts = dts;
-    pkt->flags = os->pflags;
+    pkt->pts      = pts;
+    pkt->dts      = dts;
+    pkt->flags    = os->pflags;
     pkt->duration = os->pduration;
-    pkt->pos = fpos;
+    pkt->pos      = fpos;
 
     return psize;
 }
 
-static int ogg_read_close(AVFormatContext *s)
-{
-    struct ogg *ogg = s->priv_data;
-    int i;
-
-    for (i = 0; i < ogg->nstreams; i++){
-        av_free (ogg->streams[i].buf);
-        av_free (ogg->streams[i].private);
-    }
-    av_free (ogg->streams);
-    return 0;
-}
-
 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
                                   int64_t *pos_arg, int64_t pos_limit)
 {
     struct ogg *ogg = s->priv_data;
     AVIOContext *bc = s->pb;
-    int64_t pts = AV_NOPTS_VALUE;
-    int64_t keypos = -1;
+    int64_t pts     = AV_NOPTS_VALUE;
+    int64_t keypos  = -1;
     int i;
     int pstart, psize;
     avio_seek(bc, *pos_arg, SEEK_SET);
     ogg_reset(s);
 
-    while (avio_tell(bc) <= pos_limit && !ogg_packet(s, &i, &pstart, &psize, pos_arg)) {
+    while (   avio_tell(bc) <= pos_limit
+           && !ogg_packet(s, &i, &pstart, &psize, pos_arg)) {
         if (i == stream_index) {
             struct ogg_stream *os = ogg->streams + stream_index;
             pts = ogg_calc_pts(s, i, NULL);
@@ -761,7 +809,7 @@
 static int ogg_read_seek(AVFormatContext *s, int stream_index,
                          int64_t timestamp, int flags)
 {
-    struct ogg *ogg = s->priv_data;
+    struct ogg *ogg       = s->priv_data;
     struct ogg_stream *os = ogg->streams + stream_index;
     int ret;
 
@@ -777,7 +825,7 @@
         os->keyframe_seek = 1;
 
     ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
-    os = ogg->streams + stream_index;
+    os  = ogg->streams + stream_index;
     if (ret < 0)
         os->keyframe_seek = 0;
     return ret;
@@ -801,5 +849,5 @@
     .read_seek      = ogg_read_seek,
     .read_timestamp = ogg_read_timestamp,
     .extensions     = "ogg",
-    .flags          = AVFMT_GENERIC_INDEX,
+    .flags          = AVFMT_GENERIC_INDEX | AVFMT_TS_DISCONT,
 };
diff --git a/libavformat/oggdec.h b/libavformat/oggdec.h
index febf8cb..e9a300d 100644
--- a/libavformat/oggdec.h
+++ b/libavformat/oggdec.h
@@ -55,6 +55,7 @@
      * Number of expected headers
      */
     int nb_header;
+    void (*cleanup)(AVFormatContext *s, int idx);
 };
 
 struct ogg_stream {
@@ -99,6 +100,7 @@
     int nstreams;
     int headers;
     int curidx;
+    int64_t page_pos;                   ///< file offset of the current page
     struct ogg_state *state;
 };
 
diff --git a/libavformat/oggenc.c b/libavformat/oggenc.c
index 2ff6704..3d4519c 100644
--- a/libavformat/oggenc.c
+++ b/libavformat/oggenc.c
@@ -35,6 +35,7 @@
 #define MAX_PAGE_SIZE 65025
 
 typedef struct {
+    int64_t start_granule;
     int64_t granule;
     int stream_index;
     uint8_t flags;
@@ -68,6 +69,7 @@
     const AVClass *class;
     OGGPageList *page_list;
     int pref_size; ///< preferred page size (0 => fill all segments)
+    int64_t pref_duration;      ///< preferred page duration (0 => fill all segments)
 } OGGContext;
 
 #define OFFSET(x) offsetof(OGGContext, x)
@@ -76,8 +78,10 @@
 static const AVOption options[] = {
     { "oggpagesize", "Set preferred Ogg page size.",
       offsetof(OGGContext, pref_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, MAX_PAGE_SIZE, AV_OPT_FLAG_ENCODING_PARAM},
-    { "pagesize", "preferred page size in bytes",
+    { "pagesize", "preferred page size in bytes (deprecated)",
         OFFSET(pref_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, MAX_PAGE_SIZE, PARAM },
+    { "page_duration", "preferred page duration, in microseconds",
+        OFFSET(pref_duration), AV_OPT_TYPE_INT, { .i64 = 1000000 }, 0, INT64_MAX, PARAM },
     { NULL },
 };
 
@@ -185,6 +189,7 @@
         return AVERROR(ENOMEM);
     l->page = oggstream->page;
 
+    oggstream->page.start_granule = oggstream->page.granule;
     oggstream->page_count++;
     ogg_reset_cur_page(oggstream);
 
@@ -223,6 +228,12 @@
         flush = 1;
     }
 
+    // avoid a continued page
+    if (!header && oggstream->page.size > 0 &&
+        MAX_PAGE_SIZE - oggstream->page.size < size) {
+        ogg_buffer_page(s, oggstream);
+    }
+
     for (i = 0; i < total_segments; ) {
         OGGPage *page = &oggstream->page;
 
@@ -245,9 +256,19 @@
         if (i == total_segments)
             page->granule = granule;
 
-        if (!header && (page->segments_count == 255 ||
-            (ogg->pref_size > 0 && page->size >= ogg->pref_size))) {
-           ogg_buffer_page(s, oggstream);
+        if (!header) {
+            AVStream *st = s->streams[page->stream_index];
+
+            int64_t start = av_rescale_q(page->start_granule, st->time_base,
+                                         AV_TIME_BASE_Q);
+            int64_t next  = av_rescale_q(page->granule, st->time_base,
+                                         AV_TIME_BASE_Q);
+
+            if (page->segments_count == 255 ||
+                (ogg->pref_size     > 0 && page->size   >= ogg->pref_size) ||
+                (ogg->pref_duration > 0 && next - start >= ogg->pref_duration)) {
+                ogg_buffer_page(s, oggstream);
+            }
         }
     }
 
@@ -380,9 +401,13 @@
 
 static int ogg_write_header(AVFormatContext *s)
 {
-    OGGStreamContext *oggstream;
+    OGGContext *ogg = s->priv_data;
+    OGGStreamContext *oggstream = NULL;
     int i, j;
 
+    if (ogg->pref_size)
+        av_log(s, AV_LOG_WARNING, "The pagesize option is deprecated\n");
+
     for (i = 0; i < s->nb_streams; i++) {
         AVStream *st = s->streams[i];
         unsigned serial_num = i;
@@ -502,6 +527,9 @@
         }
         ogg_buffer_page(s, oggstream);
     }
+
+    oggstream->page.start_granule = AV_NOPTS_VALUE;
+
     return 0;
 }
 
@@ -551,6 +579,9 @@
     else
         granule = pkt->pts + pkt->duration;
 
+    if (oggstream->page.start_granule == AV_NOPTS_VALUE)
+        oggstream->page.start_granule = pkt->pts;
+
     ret = ogg_buffer_data(s, st, pkt->data, pkt->size, granule, 0);
     if (ret < 0)
         return ret;
@@ -566,9 +597,13 @@
 {
     int i;
 
-    /* flush current page */
-    for (i = 0; i < s->nb_streams; i++)
-        ogg_buffer_page(s, s->streams[i]->priv_data);
+    /* flush current page if needed */
+    for (i = 0; i < s->nb_streams; i++) {
+        OGGStreamContext *oggstream = s->streams[i]->priv_data;
+
+        if (oggstream->page.size > 0)
+            ogg_buffer_page(s, oggstream);
+    }
 
     ogg_write_pages(s, 1);
 
diff --git a/libavformat/oggparseskeleton.c b/libavformat/oggparseskeleton.c
index f9ad701..b6959a6 100644
--- a/libavformat/oggparseskeleton.c
+++ b/libavformat/oggparseskeleton.c
@@ -61,7 +61,7 @@
         start_num = AV_RL64(buf+12);
         start_den = AV_RL64(buf+20);
 
-        if (start_den) {
+        if (start_den > 0 && start_num > 0) {
             int base_den;
             av_reduce(&start_time, &base_den, start_num, start_den, INT_MAX);
             avpriv_set_pts_info(st, 64, 1, base_den);
diff --git a/libavformat/oggparsespeex.c b/libavformat/oggparsespeex.c
index 42480a3..63e6370 100644
--- a/libavformat/oggparsespeex.c
+++ b/libavformat/oggparsespeex.c
@@ -58,6 +58,11 @@
         st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
         st->codec->codec_id = AV_CODEC_ID_SPEEX;
 
+        if (os->psize < 68) {
+            av_log(s, AV_LOG_ERROR, "speex packet too small\n");
+            return AVERROR_INVALIDDATA;
+        }
+
         st->codec->sample_rate = AV_RL32(p + 36);
         st->codec->channels = AV_RL32(p + 48);
         if (st->codec->channels < 1 || st->codec->channels > 2) {
diff --git a/libavformat/oggparsevorbis.c b/libavformat/oggparsevorbis.c
index 3c91080..0b52bc7 100644
--- a/libavformat/oggparsevorbis.c
+++ b/libavformat/oggparsevorbis.c
@@ -179,6 +179,8 @@
     len = priv->len[0] + priv->len[1] + priv->len[2];
     buf_len = len + len/255 + 64;
     ptr = *buf = av_realloc(NULL, buf_len);
+    if (!*buf)
+        return 0;
     memset(*buf, '\0', buf_len);
 
     ptr[0] = 2;
@@ -194,6 +196,16 @@
     return offset;
 }
 
+static void vorbis_cleanup(AVFormatContext *s, int idx)
+{
+    struct ogg *ogg = s->priv_data;
+    struct ogg_stream *os = ogg->streams + idx;
+    struct oggvorbis_private *priv = os->private;
+    int i;
+    if (os->private)
+        for (i = 0; i < 3; i++)
+            av_freep(&priv->packet[i]);
+}
 
 static int
 vorbis_header (AVFormatContext * s, int idx)
@@ -232,6 +244,7 @@
         const uint8_t *p = os->buf + os->pstart + 7; /* skip "\001vorbis" tag */
         unsigned blocksize, bs0, bs1;
         int srate;
+        int channels;
 
         if (os->psize != 30)
             return -1;
@@ -239,7 +252,12 @@
         if (bytestream_get_le32(&p) != 0) /* vorbis_version */
             return -1;
 
-        st->codec->channels = bytestream_get_byte(&p);
+        channels= bytestream_get_byte(&p);
+        if (st->codec->channels && channels != st->codec->channels) {
+            av_log(s, AV_LOG_ERROR, "Channel change is not supported\n");
+            return AVERROR_PATCHWELCOME;
+        }
+        st->codec->channels = channels;
         srate = bytestream_get_le32(&p);
         p += 4; // skip maximum bitrate
         st->codec->bit_rate = bytestream_get_le32(&p); // nominal bitrate
@@ -369,5 +387,6 @@
     .magicsize = 7,
     .header = vorbis_header,
     .packet = vorbis_packet,
+    .cleanup= vorbis_cleanup,
     .nb_header = 3,
 };
diff --git a/libavformat/options_table.h b/libavformat/options_table.h
index 3394706..6750050 100644
--- a/libavformat/options_table.h
+++ b/libavformat/options_table.h
@@ -18,8 +18,8 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#ifndef AVFORMAT_OPTIONS_TABLE
-#define AVFORMAT_OPTIONS_TABLE
+#ifndef AVFORMAT_OPTIONS_TABLE_H
+#define AVFORMAT_OPTIONS_TABLE_H
 
 #include <limits.h>
 
@@ -48,7 +48,8 @@
 {"keepside", "dont 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"},
-{"analyzeduration", "how many microseconds are analyzed to estimate duration", OFFSET(max_analyze_duration), AV_OPT_TYPE_INT, {.i64 = 5*AV_TIME_BASE }, 0, INT_MAX, D},
+{"seek2any", "forces seeking to enable seek to any mode", OFFSET(seek2any), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 1, D},
+{"analyzeduration", "specify how many microseconds are analyzed to probe the input", OFFSET(max_analyze_duration), AV_OPT_TYPE_INT, {.i64 = 5*AV_TIME_BASE }, 0, INT_MAX, D},
 {"cryptokey", "decryption key", OFFSET(key), AV_OPT_TYPE_BINARY, {.dbl = 0}, 0, 0, D},
 {"indexmem", "max memory used for timestamp index (per stream)", OFFSET(max_index_size), AV_OPT_TYPE_INT, {.i64 = 1<<20 }, 0, INT_MAX, D},
 {"rtbufsize", "max memory used for buffering real-time frames", OFFSET(max_picture_buffer), AV_OPT_TYPE_INT, {.i64 = 3041280 }, 0, INT_MAX, D}, /* defaults to 1s of 15fps 352x288 YUYV422 video */
@@ -71,8 +72,9 @@
 {"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"},
 {"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", "avoid negative timestamps", OFFSET(avoid_negative_ts), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, E},
+{"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},
 {"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},
 {NULL},
 };
 
@@ -81,4 +83,4 @@
 #undef DEFAULT
 #undef OFFSET
 
-#endif // AVFORMAT_OPTIONS_TABLE
+#endif /* AVFORMAT_OPTIONS_TABLE_H */
diff --git a/libavformat/pcm.c b/libavformat/pcm.c
index bba741d..2fe44dc 100644
--- a/libavformat/pcm.c
+++ b/libavformat/pcm.c
@@ -23,6 +23,26 @@
 #include "avformat.h"
 #include "pcm.h"
 
+#define RAW_SAMPLES     1024
+
+int ff_pcm_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    int ret, size;
+
+    size= RAW_SAMPLES*s->streams[0]->codec->block_align;
+    if (size <= 0)
+        return AVERROR(EINVAL);
+
+    ret= av_get_packet(s->pb, pkt, size);
+
+    pkt->flags &= ~AV_PKT_FLAG_CORRUPT;
+    pkt->stream_index = 0;
+    if (ret < 0)
+        return ret;
+
+    return ret;
+}
+
 int ff_pcm_read_seek(AVFormatContext *s,
                      int stream_index, int64_t timestamp, int flags)
 {
diff --git a/libavformat/pcm.h b/libavformat/pcm.h
index 60d8eb3..9af36d5 100644
--- a/libavformat/pcm.h
+++ b/libavformat/pcm.h
@@ -24,6 +24,7 @@
 
 #include "avformat.h"
 
+int ff_pcm_read_packet(AVFormatContext *s, AVPacket *pkt);
 int ff_pcm_read_seek(AVFormatContext *s,
                      int stream_index, int64_t timestamp, int flags);
 
diff --git a/libavformat/pcmdec.c b/libavformat/pcmdec.c
index 30f69d3..f4264d9 100644
--- a/libavformat/pcmdec.c
+++ b/libavformat/pcmdec.c
@@ -26,8 +26,6 @@
 #include "libavutil/opt.h"
 #include "libavutil/avassert.h"
 
-#define RAW_SAMPLES     1024
-
 typedef struct PCMAudioDemuxerContext {
     AVClass *class;
     int sample_rate;
@@ -61,28 +59,6 @@
     return 0;
 }
 
-static int pcm_read_packet(AVFormatContext *s, AVPacket *pkt)
-{
-    int ret, size, bps;
-    //    AVStream *st = s->streams[0];
-
-    size= RAW_SAMPLES*s->streams[0]->codec->block_align;
-
-    ret= av_get_packet(s->pb, pkt, size);
-
-    pkt->flags &= ~AV_PKT_FLAG_CORRUPT;
-    pkt->stream_index = 0;
-    if (ret < 0)
-        return ret;
-
-    bps= av_get_bits_per_sample(s->streams[0]->codec->codec_id);
-    av_assert1(bps); // if false there IS a bug elsewhere (NOT in this function)
-    pkt->dts=
-    pkt->pts= pkt->pos*8 / (bps * s->streams[0]->codec->channels);
-
-    return ret;
-}
-
 static const AVOption pcm_options[] = {
     { "sample_rate", "", offsetof(PCMAudioDemuxerContext, sample_rate), AV_OPT_TYPE_INT, {.i64 = 44100}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
     { "channels",    "", offsetof(PCMAudioDemuxerContext, channels),    AV_OPT_TYPE_INT, {.i64 = 1}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
@@ -101,7 +77,7 @@
     .long_name      = NULL_IF_CONFIG_SMALL(long_name_),     \
     .priv_data_size = sizeof(PCMAudioDemuxerContext),       \
     .read_header    = pcm_read_header,                      \
-    .read_packet    = pcm_read_packet,                      \
+    .read_packet    = ff_pcm_read_packet,                   \
     .read_seek      = ff_pcm_read_seek,                     \
     .flags          = AVFMT_GENERIC_INDEX,                  \
     .extensions     = ext,                                  \
diff --git a/libavformat/pjsdec.c b/libavformat/pjsdec.c
new file mode 100644
index 0000000..ef2b626
--- /dev/null
+++ b/libavformat/pjsdec.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2012 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
+ * PJS (Phoenix Japanimation Society) subtitles format demuxer
+ *
+ * @see http://subs.com.ru/page.php?al=pjs
+ */
+
+#include "avformat.h"
+#include "internal.h"
+#include "subtitles.h"
+
+typedef struct {
+    FFDemuxSubtitlesQueue q;
+} PJSContext;
+
+static int pjs_probe(AVProbeData *p)
+{
+    char c;
+    int64_t start, end;
+    const unsigned char *ptr = p->buf;
+
+    if (sscanf(ptr, "%"PRId64",%"PRId64",%c", &start, &end, &c) == 3) {
+        size_t q1pos = strcspn(ptr, "\"");
+        size_t q2pos = q1pos + strcspn(ptr + q1pos + 1, "\"") + 1;
+        if (strcspn(ptr, "\r\n") > q2pos)
+            return AVPROBE_SCORE_MAX;
+    }
+    return 0;
+}
+
+static int64_t read_ts(char **line, int *duration)
+{
+    int64_t start, end;
+
+    if (sscanf(*line, "%"PRId64",%"PRId64, &start, &end) == 2) {
+        *line += strcspn(*line, "\"") + 1;
+        *duration = end - start;
+        return start;
+    }
+    return AV_NOPTS_VALUE;
+}
+
+static int pjs_read_header(AVFormatContext *s)
+{
+    PJSContext *pjs = s->priv_data;
+    AVStream *st = avformat_new_stream(s, NULL);
+    int res = 0;
+
+    if (!st)
+        return AVERROR(ENOMEM);
+    avpriv_set_pts_info(st, 64, 1, 10);
+    st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
+    st->codec->codec_id   = AV_CODEC_ID_PJS;
+
+    while (!url_feof(s->pb)) {
+        char line[4096];
+        char *p = line;
+        const int64_t pos = avio_tell(s->pb);
+        int len = ff_get_line(s->pb, line, sizeof(line));
+        int64_t pts_start;
+        int duration;
+
+        if (!len)
+            break;
+
+        line[strcspn(line, "\r\n")] = 0;
+
+        pts_start = read_ts(&p, &duration);
+        if (pts_start != AV_NOPTS_VALUE) {
+            AVPacket *sub;
+
+            p[strcspn(p, "\"")] = 0;
+            sub = ff_subtitles_queue_insert(&pjs->q, p, strlen(p), 0);
+            if (!sub)
+                return AVERROR(ENOMEM);
+            sub->pos = pos;
+            sub->pts = pts_start;
+            sub->duration = duration;
+        }
+    }
+
+    ff_subtitles_queue_finalize(&pjs->q);
+    return res;
+}
+
+static int pjs_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    PJSContext *pjs = s->priv_data;
+    return ff_subtitles_queue_read_packet(&pjs->q, pkt);
+}
+
+static int pjs_read_seek(AVFormatContext *s, int stream_index,
+                         int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
+{
+    PJSContext *pjs = s->priv_data;
+    return ff_subtitles_queue_seek(&pjs->q, s, stream_index,
+                                   min_ts, ts, max_ts, flags);
+}
+
+static int pjs_read_close(AVFormatContext *s)
+{
+    PJSContext *pjs = s->priv_data;
+    ff_subtitles_queue_clean(&pjs->q);
+    return 0;
+}
+
+AVInputFormat ff_pjs_demuxer = {
+    .name           = "pjs",
+    .long_name      = NULL_IF_CONFIG_SMALL("PJS (Phoenix Japanimation Society) subtitles"),
+    .priv_data_size = sizeof(PJSContext),
+    .read_probe     = pjs_probe,
+    .read_header    = pjs_read_header,
+    .read_packet    = pjs_read_packet,
+    .read_seek2     = pjs_read_seek,
+    .read_close     = pjs_read_close,
+    .extensions     = "pjs",
+};
diff --git a/libavformat/pmpdec.c b/libavformat/pmpdec.c
index 2ea37ef..e0394a9 100644
--- a/libavformat/pmpdec.c
+++ b/libavformat/pmpdec.c
@@ -44,11 +44,13 @@
     PMPContext *pmp = s->priv_data;
     AVIOContext *pb = s->pb;
     int tb_num, tb_den;
-    int index_cnt;
+    uint32_t index_cnt;
     int audio_codec_id = AV_CODEC_ID_NONE;
     int srate, channels;
-    int i;
+    unsigned i;
     uint64_t pos;
+    int64_t fsize = avio_size(pb);
+
     AVStream *vst = avformat_new_stream(s, NULL);
     if (!vst)
         return AVERROR(ENOMEM);
@@ -91,6 +93,26 @@
     avio_skip(pb, 10);
     srate = avio_rl32(pb);
     channels = avio_rl32(pb) + 1;
+    pos = avio_tell(pb) + 4LL*index_cnt;
+    for (i = 0; i < index_cnt; i++) {
+        uint32_t size = avio_rl32(pb);
+        int flags = size & 1 ? AVINDEX_KEYFRAME : 0;
+        if (url_feof(pb)) {
+            av_log(s, AV_LOG_FATAL, "Encountered EOF while reading index.\n");
+            return AVERROR_INVALIDDATA;
+        }
+        size >>= 1;
+        if (size < 9 + 4*pmp->num_streams) {
+            av_log(s, AV_LOG_ERROR, "Packet too small\n");
+            return AVERROR_INVALIDDATA;
+        }
+        av_add_index_entry(vst, pos, i, size, 0, flags);
+        pos += size;
+        if (fsize > 0 && i == 0 && pos > fsize) {
+            av_log(s, AV_LOG_ERROR, "File ends before first packet\n");
+            return AVERROR_INVALIDDATA;
+        }
+    }
     for (i = 1; i < pmp->num_streams; i++) {
         AVStream *ast = avformat_new_stream(s, NULL);
         if (!ast)
@@ -101,14 +123,6 @@
         ast->codec->sample_rate = srate;
         avpriv_set_pts_info(ast, 32, 1, srate);
     }
-    pos = avio_tell(pb) + 4*index_cnt;
-    for (i = 0; i < index_cnt; i++) {
-        int size = avio_rl32(pb);
-        int flags = size & 1 ? AVINDEX_KEYFRAME : 0;
-        size >>= 1;
-        av_add_index_entry(vst, pos, i, size, 0, flags);
-        pos += size;
-    }
     return 0;
 }
 
diff --git a/libavformat/psxstr.c b/libavformat/psxstr.c
index 35a6d71..a2a629f 100644
--- a/libavformat/psxstr.c
+++ b/libavformat/psxstr.c
@@ -69,8 +69,8 @@
 
 static int str_probe(AVProbeData *p)
 {
-    uint8_t *sector= p->buf;
-    uint8_t *end= sector + p->buf_size;
+    const uint8_t *sector= p->buf;
+    const uint8_t *end= sector + p->buf_size;
     int aud=0, vid=0;
 
     if (p->buf_size < RAW_CD_SECTOR_SIZE)
diff --git a/libavformat/pva.c b/libavformat/pva.c
index ff8ccee..ae42c83 100644
--- a/libavformat/pva.c
+++ b/libavformat/pva.c
@@ -32,7 +32,7 @@
     int continue_pes;
 } PVAContext;
 
-static int pva_check(uint8_t *p) {
+static int pva_check(const uint8_t *p) {
     int length = AV_RB16(p + 6);
     if (AV_RB16(p) != PVA_MAGIC || !p[2] || p[2] > 2 || p[4] != 0x55 ||
         (p[5] & 0xe0) || length > PVA_MAX_PAYLOAD_LENGTH)
@@ -41,7 +41,7 @@
 }
 
 static int pva_probe(AVProbeData * pd) {
-    unsigned char *buf = pd->buf;
+    const unsigned char *buf = pd->buf;
     int len = pva_check(buf);
 
     if (len < 0)
diff --git a/libavformat/pvfdec.c b/libavformat/pvfdec.c
index 9d18256..c678046 100644
--- a/libavformat/pvfdec.c
+++ b/libavformat/pvfdec.c
@@ -37,7 +37,7 @@
     int bps, channels, sample_rate;
 
     avio_skip(s->pb, 5);
-    ff_get_line(s->pb, (char *)&buffer, 32);
+    ff_get_line(s->pb, buffer, sizeof(buffer));
     if (sscanf(buffer, "%d %d %d",
                &channels,
                &sample_rate,
@@ -63,23 +63,12 @@
     return 0;
 }
 
-static int pvf_read_packet(AVFormatContext *s, AVPacket *pkt)
-{
-    int ret;
-
-    ret = av_get_packet(s->pb, pkt, 1024 * s->streams[0]->codec->block_align);
-    pkt->flags &= ~AV_PKT_FLAG_CORRUPT;
-    pkt->stream_index = 0;
-
-    return ret;
-}
-
 AVInputFormat ff_pvf_demuxer = {
     .name           = "pvf",
     .long_name      = NULL_IF_CONFIG_SMALL("PVF (Portable Voice Format)"),
     .read_probe     = pvf_probe,
     .read_header    = pvf_read_header,
-    .read_packet    = pvf_read_packet,
+    .read_packet    = ff_pcm_read_packet,
     .read_seek      = ff_pcm_read_seek,
     .extensions     = "pvf",
     .flags          = AVFMT_GENERIC_INDEX,
diff --git a/libavformat/qcp.c b/libavformat/qcp.c
index 3cb85fb..1ef86fe 100644
--- a/libavformat/qcp.c
+++ b/libavformat/qcp.c
@@ -102,11 +102,9 @@
     if (is_qcelp_13k_guid(buf)) {
         st->codec->codec_id = AV_CODEC_ID_QCELP;
     } else if (!memcmp(buf, guid_evrc, 16)) {
-        av_log(s, AV_LOG_ERROR, "EVRC codec is not supported.\n");
-        return AVERROR_PATCHWELCOME;
+        st->codec->codec_id = AV_CODEC_ID_EVRC;
     } else if (!memcmp(buf, guid_smv, 16)) {
-        av_log(s, AV_LOG_ERROR, "SMV codec is not supported.\n");
-        return AVERROR_PATCHWELCOME;
+        st->codec->codec_id = AV_CODEC_ID_SMV;
     } else {
         av_log(s, AV_LOG_ERROR, "Unknown codec GUID.\n");
         return AVERROR_INVALIDDATA;
diff --git a/libavformat/r3d.c b/libavformat/r3d.c
index 35da81e..3b3ecce 100644
--- a/libavformat/r3d.c
+++ b/libavformat/r3d.c
@@ -285,6 +285,10 @@
     dts = avio_rb32(s->pb);
 
     st->codec->sample_rate = avio_rb32(s->pb);
+    if (st->codec->sample_rate < 0) {
+        av_log(s, AV_LOG_ERROR, "negative sample rate\n");
+        return AVERROR_INVALIDDATA;
+    }
 
     samples = avio_rb32(s->pb);
 
@@ -312,7 +316,8 @@
 
     pkt->stream_index = 1;
     pkt->dts = dts;
-    pkt->duration = av_rescale(samples, st->time_base.den, st->codec->sample_rate);
+    if (st->codec->sample_rate)
+        pkt->duration = av_rescale(samples, st->time_base.den, st->codec->sample_rate);
     av_dlog(s, "pkt dts %"PRId64" duration %d samples %d sample rate %d\n",
             pkt->dts, pkt->duration, samples, st->codec->sample_rate);
 
diff --git a/libavformat/rawvideodec.c b/libavformat/rawvideodec.c
index b2ca663..8460781 100644
--- a/libavformat/rawvideodec.c
+++ b/libavformat/rawvideodec.c
@@ -72,6 +72,8 @@
     st->codec->width  = width;
     st->codec->height = height;
     st->codec->pix_fmt = pix_fmt;
+    st->codec->bit_rate = av_rescale_q(avpicture_get_size(st->codec->pix_fmt, width, height),
+                                       (AVRational){8,1}, st->time_base);
 
     return 0;
 }
@@ -101,9 +103,9 @@
 #define OFFSET(x) offsetof(RawVideoDemuxerContext, x)
 #define DEC AV_OPT_FLAG_DECODING_PARAM
 static const AVOption rawvideo_options[] = {
-    { "video_size", "A string describing frame size, such as 640x480 or hd720.", OFFSET(video_size), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
-    { "pixel_format", "", OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = "yuv420p"}, 0, 0, DEC },
-    { "framerate", "", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = "25"}, 0, 0, DEC },
+    { "video_size", "set frame size", OFFSET(video_size), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
+    { "pixel_format", "set pixel format", OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = "yuv420p"}, 0, 0, DEC },
+    { "framerate", "set frame rate", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = "25"}, 0, 0, DEC },
     { NULL },
 };
 
diff --git a/libavformat/rdt.c b/libavformat/rdt.c
index 6404a5d..695323a 100644
--- a/libavformat/rdt.c
+++ b/libavformat/rdt.c
@@ -293,7 +293,7 @@
 static int
 rdt_parse_packet (AVFormatContext *ctx, PayloadContext *rdt, AVStream *st,
                   AVPacket *pkt, uint32_t *timestamp,
-                  const uint8_t *buf, int len, int flags)
+                  const uint8_t *buf, int len, uint16_t rtp_seq, int flags)
 {
     int seq = 1, res;
     AVIOContext pb;
@@ -348,7 +348,7 @@
         timestamp= 0; ///< Should not be used if buf is NULL, but should be set to the timestamp of the packet returned....
         rv= s->parse_packet(s->ic, s->dynamic_protocol_context,
                             s->streams[s->prev_stream_id],
-                            pkt, &timestamp, NULL, 0, flags);
+                            pkt, &timestamp, NULL, 0, 0, flags);
         return rv;
     }
 
@@ -375,7 +375,7 @@
 
     rv = s->parse_packet(s->ic, s->dynamic_protocol_context,
                          s->streams[s->prev_stream_id],
-                         pkt, &timestamp, buf, len, flags);
+                         pkt, &timestamp, buf, len, 0, flags);
 
     return rv;
 }
diff --git a/libavformat/realtextdec.c b/libavformat/realtextdec.c
index 6a6a844..67bc339 100644
--- a/libavformat/realtextdec.c
+++ b/libavformat/realtextdec.c
@@ -149,6 +149,5 @@
     .read_packet    = realtext_read_packet,
     .read_seek2     = realtext_read_seek,
     .read_close     = realtext_read_close,
-    .flags          = AVFMT_GENERIC_INDEX,
     .extensions     = "rt",
 };
diff --git a/libavformat/riff.c b/libavformat/riff.c
index af48947..ac1a4ff 100644
--- a/libavformat/riff.c
+++ b/libavformat/riff.c
@@ -62,6 +62,7 @@
     { AV_CODEC_ID_MPEG4,        MKTAG('M', 'P', '4', 'S') },
     { AV_CODEC_ID_MPEG4,        MKTAG('M', '4', 'S', '2') },
     { AV_CODEC_ID_MPEG4,        MKTAG( 4 ,  0 ,  0 ,  0 ) }, /* some broken avi use this */
+    { AV_CODEC_ID_MPEG4,        MKTAG('Z', 'M', 'P', '4') }, /* some broken avi use this */
     { AV_CODEC_ID_MPEG4,        MKTAG('D', 'I', 'V', '1') },
     { AV_CODEC_ID_MPEG4,        MKTAG('B', 'L', 'Z', '0') },
     { AV_CODEC_ID_MPEG4,        MKTAG('m', 'p', '4', 'v') },
@@ -325,6 +326,8 @@
     { AV_CODEC_ID_CLLC,         MKTAG('C', 'L', 'L', 'C') },
     { AV_CODEC_ID_MSS2,         MKTAG('M', 'S', 'S', '2') },
     { 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_NONE,         0 }
 };
 
@@ -424,10 +427,14 @@
 {
     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, pos, SEEK_SET);
+    avio_seek(pb, FFALIGN(pos, 2), SEEK_SET);
 }
 
 /* WAVEFORMATEX header */
@@ -462,11 +469,11 @@
     }
     avio_wl16(pb, enc->channels);
     avio_wl32(pb, enc->sample_rate);
-    if (enc->codec_id == CODEC_ID_ATRAC3 ||
-        enc->codec_id == CODEC_ID_G723_1 ||
-        enc->codec_id == CODEC_ID_GSM_MS ||
-        enc->codec_id == CODEC_ID_MP2    ||
-        enc->codec_id == CODEC_ID_MP3) {
+    if (enc->codec_id == AV_CODEC_ID_ATRAC3 ||
+        enc->codec_id == AV_CODEC_ID_G723_1 ||
+        enc->codec_id == AV_CODEC_ID_GSM_MS ||
+        enc->codec_id == AV_CODEC_ID_MP2    ||
+        enc->codec_id == AV_CODEC_ID_MP3) {
         bps = 0;
     } else {
         if (!(bps = av_get_bits_per_sample(enc->codec_id))) {
@@ -815,7 +822,13 @@
 
         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;
+            }
+            break;
+        }
         if (chunk_size > end || end - chunk_size < cur || chunk_size == UINT_MAX) {
             avio_seek(pb, -9, SEEK_CUR);
             chunk_code = avio_rl32(pb);
diff --git a/libavformat/riff.h b/libavformat/riff.h
index 8579a95..70b2f76 100644
--- a/libavformat/riff.h
+++ b/libavformat/riff.h
@@ -51,7 +51,7 @@
 enum AVCodecID ff_wav_codec_get_id(unsigned int tag, int bps);
 int ff_get_wav_header(AVIOContext *pb, AVCodecContext *codec, int size);
 
-extern const AVCodecTag ff_codec_bmp_tags[];
+extern const AVCodecTag ff_codec_bmp_tags[]; // exposed through avformat_get_riff_video_tags()
 extern const AVCodecTag ff_codec_wav_tags[];
 
 void ff_parse_specific_params(AVCodecContext *stream, int *au_rate, int *au_ssize, int *au_scale);
diff --git a/libavformat/rl2.c b/libavformat/rl2.c
index 73d6b27..800e12e 100644
--- a/libavformat/rl2.c
+++ b/libavformat/rl2.c
@@ -232,7 +232,7 @@
     }
 
     if(stream_id == -1)
-        return AVERROR(EIO);
+        return AVERROR_EOF;
 
     ++rl2->index_pos[stream_id];
 
diff --git a/libavformat/rmdec.c b/libavformat/rmdec.c
index 2bfa5ce..ee1e0ff 100644
--- a/libavformat/rmdec.c
+++ b/libavformat/rmdec.c
@@ -25,6 +25,7 @@
 #include "libavutil/intreadwrite.h"
 #include "libavutil/dict.h"
 #include "avformat.h"
+#include "avio_internal.h"
 #include "internal.h"
 #include "rmsipr.h"
 #include "rm.h"
@@ -127,9 +128,12 @@
     /* ra type header */
     version = avio_rb16(pb); /* version */
     if (version == 3) {
+        unsigned bytes_per_minute;
         int header_size = avio_rb16(pb);
         int64_t startpos = avio_tell(pb);
-        avio_skip(pb, 14);
+        avio_skip(pb, 8);
+        bytes_per_minute = avio_rb16(pb);
+        avio_skip(pb, 4);
         rm_read_metadata(s, 0);
         if ((startpos + header_size) >= avio_tell(pb) + 2) {
             // fourcc (should always be "lpcJ")
@@ -139,6 +143,8 @@
         // Skip extra header crap (this should never happen)
         if ((startpos + header_size) > avio_tell(pb))
             avio_skip(pb, header_size + startpos - avio_tell(pb));
+        if (bytes_per_minute)
+            st->codec->bit_rate = 8LL * bytes_per_minute / 60;
         st->codec->sample_rate = 8000;
         st->codec->channels = 1;
         st->codec->channel_layout = AV_CH_LAYOUT_MONO;
@@ -148,6 +154,7 @@
     } else {
         int flavor, sub_packet_h, coded_framesize, sub_packet_size;
         int codecdata_length;
+        unsigned bytes_per_minute;
         /* old version (4) */
         avio_skip(pb, 2); /* unused */
         avio_rb32(pb); /* .ra4 */
@@ -157,7 +164,11 @@
         flavor= avio_rb16(pb); /* add codec info / flavor */
         ast->coded_framesize = coded_framesize = avio_rb32(pb); /* coded frame size */
         avio_rb32(pb); /* ??? */
-        avio_rb32(pb); /* ??? */
+        bytes_per_minute = avio_rb32(pb);
+        if (version == 4) {
+            if (bytes_per_minute)
+                st->codec->bit_rate = 8LL * bytes_per_minute / 60;
+        }
         avio_rb32(pb); /* ??? */
         ast->sub_packet_h = sub_packet_h = avio_rb16(pb); /* 1 */
         st->codec->block_align= avio_rb16(pb); /* frame size */
@@ -196,13 +207,17 @@
             st->need_parsing = AVSTREAM_PARSE_HEADERS;
         case AV_CODEC_ID_ATRAC3:
         case AV_CODEC_ID_SIPR:
-            avio_rb16(pb); avio_r8(pb);
-            if (version == 5)
-                avio_r8(pb);
-            codecdata_length = avio_rb32(pb);
-            if(codecdata_length + FF_INPUT_BUFFER_PADDING_SIZE <= (unsigned)codecdata_length){
-                av_log(s, AV_LOG_ERROR, "codecdata_length too large\n");
-                return -1;
+            if (read_all) {
+                codecdata_length = 0;
+            } else {
+                avio_rb16(pb); avio_r8(pb);
+                if (version == 5)
+                    avio_r8(pb);
+                codecdata_length = avio_rb32(pb);
+                if(codecdata_length + FF_INPUT_BUFFER_PADDING_SIZE <= (unsigned)codecdata_length){
+                    av_log(s, AV_LOG_ERROR, "codecdata_length too large\n");
+                    return -1;
+                }
             }
 
             ast->audio_framesize = st->codec->block_align;
@@ -644,7 +659,8 @@
                                    AVPacket *pkt, int len, int *pseq,
                                    int64_t *timestamp)
 {
-    int hdr, seq, pic_num, len2, pos;
+    int hdr;
+    int seq = 0, pic_num = 0, len2 = 0, pos = 0; //init to silcense compiler warning
     int type;
 
     hdr = avio_r8(pb); len--;
@@ -681,6 +697,10 @@
 
     *pseq = seq;
     if((seq & 0x7F) == 1 || vst->curpic_num != pic_num){
+        if (len2 > ffio_limit(pb, len2)) {
+            av_log(s, AV_LOG_ERROR, "Impossibly sized packet\n");
+            return AVERROR_INVALIDDATA;
+        }
         vst->slices = ((hdr & 0x3F) << 1) + 1;
         vst->videobufsize = len2 + 8*vst->slices + 1;
         av_free_packet(&vst->pkt); //FIXME this should be output.
@@ -860,7 +880,7 @@
 static int rm_read_packet(AVFormatContext *s, AVPacket *pkt)
 {
     RMDemuxContext *rm = s->priv_data;
-    AVStream *st;
+    AVStream *st = NULL; // init to silence compiler warning
     int i, len, res, seq = 1;
     int64_t timestamp, pos;
     int flags;
diff --git a/libavformat/rmenc.c b/libavformat/rmenc.c
index 6c05657..a96c429 100644
--- a/libavformat/rmenc.c
+++ b/libavformat/rmenc.c
@@ -217,8 +217,8 @@
                 coded_frame_size--;
             avio_wb32(s, coded_frame_size); /* frame length */
             avio_wb32(s, 0x51540); /* unknown */
-            avio_wb32(s, 0x249f0); /* unknown */
-            avio_wb32(s, 0x249f0); /* unknown */
+            avio_wb32(s, stream->enc->bit_rate / 8 * 60); /* bytes per minute */
+            avio_wb32(s, stream->enc->bit_rate / 8 * 60); /* bytes per minute */
             avio_wb16(s, 0x01);
             /* frame length : seems to be very important */
             avio_wb16(s, coded_frame_size);
diff --git a/libavformat/rsodec.c b/libavformat/rsodec.c
index 19c21e0..aae80a8 100644
--- a/libavformat/rsodec.c
+++ b/libavformat/rsodec.c
@@ -50,7 +50,7 @@
     bps = av_get_bits_per_sample(codec);
     if (!bps) {
         av_log_ask_for_sample(s, "could not determine bits per sample\n");
-        return AVERROR_INVALIDDATA;
+        return AVERROR_PATCHWELCOME;
     }
 
     /* now we are ready: build format streams */
@@ -65,34 +65,19 @@
     st->codec->channels     = 1;
     st->codec->channel_layout = AV_CH_LAYOUT_MONO;
     st->codec->sample_rate  = rate;
+    st->codec->block_align  = 1;
 
     avpriv_set_pts_info(st, 64, 1, rate);
 
     return 0;
 }
 
-#define BLOCK_SIZE 1024 /* in samples */
-
-static int rso_read_packet(AVFormatContext *s, AVPacket *pkt)
-{
-    int bps = av_get_bits_per_sample(s->streams[0]->codec->codec_id);
-    int ret = av_get_packet(s->pb, pkt, BLOCK_SIZE * bps >> 3);
-
-    if (ret < 0)
-        return ret;
-
-    pkt->flags &= ~AV_PKT_FLAG_CORRUPT;
-    pkt->stream_index = 0;
-
-    return 0;
-}
-
 AVInputFormat ff_rso_demuxer = {
     .name           =   "rso",
     .long_name      =   NULL_IF_CONFIG_SMALL("Lego Mindstorms RSO"),
     .extensions     =   "rso",
     .read_header    =   rso_read_header,
-    .read_packet    =   rso_read_packet,
+    .read_packet    =   ff_pcm_read_packet,
     .read_seek      =   ff_pcm_read_seek,
     .codec_tag      =   (const AVCodecTag* const []){ff_codec_rso_tags, 0},
 };
diff --git a/libavformat/rtmppkt.c b/libavformat/rtmppkt.c
index b607d5b..3bd28eb 100644
--- a/libavformat/rtmppkt.c
+++ b/libavformat/rtmppkt.c
@@ -47,6 +47,19 @@
     bytestream_put_buffer(dst, str, strlen(str));
 }
 
+void ff_amf_write_string2(uint8_t **dst, const char *str1, const char *str2)
+{
+    int len1 = 0, len2 = 0;
+    if (str1)
+        len1 = strlen(str1);
+    if (str2)
+        len2 = strlen(str2);
+    bytestream_put_byte(dst, AMF_DATA_TYPE_STRING);
+    bytestream_put_be16(dst, len1 + len2);
+    bytestream_put_buffer(dst, str1, len1);
+    bytestream_put_buffer(dst, str2, len2);
+}
+
 void ff_amf_write_null(uint8_t **dst)
 {
     bytestream_put_byte(dst, AMF_DATA_TYPE_NULL);
@@ -343,11 +356,11 @@
                 data++;
                 break;
             }
-            if (data + size >= data_end || data + size < data)
+            if (size < 0 || size >= data_end - data)
                 return -1;
             data += size;
             t = ff_amf_tag_size(data, data_end);
-            if (t < 0 || data + t >= data_end)
+            if (t < 0 || t >= data_end - data)
                 return -1;
             data += t;
         }
@@ -376,7 +389,7 @@
         int size = bytestream_get_be16(&data);
         if (!size)
             break;
-        if (data + size >= data_end || data + size < data)
+        if (size < 0 || size >= data_end - data)
             return -1;
         data += size;
         if (size == namelen && !memcmp(data-size, name, namelen)) {
@@ -397,7 +410,7 @@
             return 0;
         }
         len = ff_amf_tag_size(data, data_end);
-        if (len < 0 || data + len >= data_end || data + len < data)
+        if (len < 0 || len >= data_end - data)
             return -1;
         data += len;
     }
@@ -427,7 +440,7 @@
 
 static void ff_amf_tag_contents(void *ctx, const uint8_t *data, const uint8_t *data_end)
 {
-    int size;
+    unsigned int size;
     char buf[1024];
 
     if (data >= data_end)
@@ -446,7 +459,7 @@
         } else {
             size = bytestream_get_be32(&data);
         }
-        size = FFMIN(size, 1023);
+        size = FFMIN(size, sizeof(buf) - 1);
         memcpy(buf, data, size);
         buf[size] = 0;
         av_log(ctx, AV_LOG_DEBUG, " string '%s'\n", buf);
@@ -459,22 +472,21 @@
     case AMF_DATA_TYPE_OBJECT:
         av_log(ctx, AV_LOG_DEBUG, " {\n");
         for (;;) {
-            int size = bytestream_get_be16(&data);
             int t;
-            memcpy(buf, data, size);
-            buf[size] = 0;
+            size = bytestream_get_be16(&data);
+            av_strlcpy(buf, data, FFMIN(sizeof(buf), size + 1));
             if (!size) {
                 av_log(ctx, AV_LOG_DEBUG, " }\n");
                 data++;
                 break;
             }
-            if (data + size >= data_end || data + size < data)
+            if (size >= data_end - data)
                 return;
             data += size;
             av_log(ctx, AV_LOG_DEBUG, "  %s: ", buf);
             ff_amf_tag_contents(ctx, data, data_end);
             t = ff_amf_tag_size(data, data_end);
-            if (t < 0 || data + t >= data_end)
+            if (t < 0 || t >= data_end - data)
                 return;
             data += t;
         }
diff --git a/libavformat/rtmppkt.h b/libavformat/rtmppkt.h
index 9b58803..a942295 100644
--- a/libavformat/rtmppkt.h
+++ b/libavformat/rtmppkt.h
@@ -204,6 +204,15 @@
 void ff_amf_write_string(uint8_t **dst, const char *str);
 
 /**
+ * Write a string consisting of two parts in AMF format to a buffer.
+ *
+ * @param dst pointer to the input buffer (will be modified)
+ * @param str1 first string to write, may be null
+ * @param str2 second string to write, may be null
+ */
+void ff_amf_write_string2(uint8_t **dst, const char *str1, const char *str2);
+
+/**
  * Write AMF NULL value to buffer.
  *
  * @param dst pointer to the input buffer (will be modified)
diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c
index 72462cf..598122a 100644
--- a/libavformat/rtmpproto.c
+++ b/libavformat/rtmpproto.c
@@ -26,8 +26,10 @@
 
 #include "libavcodec/bytestream.h"
 #include "libavutil/avstring.h"
+#include "libavutil/base64.h"
 #include "libavutil/intfloat.h"
 #include "libavutil/lfg.h"
+#include "libavutil/md5.h"
 #include "libavutil/opt.h"
 #include "libavutil/random_seed.h"
 #include "libavutil/sha.h"
@@ -48,7 +50,7 @@
 
 //#define DEBUG
 
-#define APP_MAX_LENGTH 128
+#define APP_MAX_LENGTH 1024
 #define PLAYPATH_MAX_LENGTH 256
 #define TCURL_MAX_LENGTH 512
 #define FLASHVER_MAX_LENGTH 64
@@ -116,6 +118,11 @@
     int           listen;                     ///< listen mode flag
     int           listen_timeout;             ///< listen timeout to wait for new connections
     int           nb_streamid;                ///< The next stream id to return on createStream calls
+    char          username[50];
+    char          password[50];
+    char          auth_params[500];
+    int           do_reconnect;
+    int           auth_tried;
 } RTMPContext;
 
 #define PLAYER_KEY_OPEN_PART_LEN 30   ///< length of partial key used for first client digest signing
@@ -202,6 +209,9 @@
     for (i = 0; i < rt->nb_tracked_methods; i ++)
         av_free(rt->tracked_methods[i].name);
     av_free(rt->tracked_methods);
+    rt->tracked_methods      = NULL;
+    rt->tracked_methods_size = 0;
+    rt->nb_tracked_methods   = 0;
 }
 
 static int rtmp_send_packet(RTMPContext *rt, RTMPPacket *pkt, int track)
@@ -302,7 +312,7 @@
     int ret;
 
     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
-                                     0, 4096)) < 0)
+                                     0, 4096 + APP_MAX_LENGTH)) < 0)
         return ret;
 
     p = pkt.data;
@@ -311,7 +321,7 @@
     ff_amf_write_number(&p, ++rt->nb_invokes);
     ff_amf_write_object_start(&p);
     ff_amf_write_field_name(&p, "app");
-    ff_amf_write_string(&p, rt->app);
+    ff_amf_write_string2(&p, rt->app, rt->auth_params);
 
     if (!rt->is_input) {
         ff_amf_write_field_name(&p, "type");
@@ -326,7 +336,7 @@
     }
 
     ff_amf_write_field_name(&p, "tcUrl");
-    ff_amf_write_string(&p, rt->tcurl);
+    ff_amf_write_string2(&p, rt->tcurl, rt->auth_params);
     if (rt->is_input) {
         ff_amf_write_field_name(&p, "fpad");
         ff_amf_write_bool(&p, 0);
@@ -1509,8 +1519,191 @@
     return 0;
 }
 
+static int do_adobe_auth(RTMPContext *rt, const char *user, const char *salt,
+                         const char *opaque, const char *challenge)
+{
+    uint8_t hash[16];
+    char hashstr[AV_BASE64_SIZE(sizeof(hash))], challenge2[10];
+    struct AVMD5 *md5 = av_md5_alloc();
+    if (!md5)
+        return AVERROR(ENOMEM);
+
+    snprintf(challenge2, sizeof(challenge2), "%08x", av_get_random_seed());
+
+    av_md5_init(md5);
+    av_md5_update(md5, user, strlen(user));
+    av_md5_update(md5, salt, strlen(salt));
+    av_md5_update(md5, rt->password, strlen(rt->password));
+    av_md5_final(md5, hash);
+    av_base64_encode(hashstr, sizeof(hashstr), hash,
+                     sizeof(hash));
+    av_md5_init(md5);
+    av_md5_update(md5, hashstr, strlen(hashstr));
+    if (opaque)
+        av_md5_update(md5, opaque, strlen(opaque));
+    else if (challenge)
+        av_md5_update(md5, challenge, strlen(challenge));
+    av_md5_update(md5, challenge2, strlen(challenge2));
+    av_md5_final(md5, hash);
+    av_base64_encode(hashstr, sizeof(hashstr), hash,
+                     sizeof(hash));
+    snprintf(rt->auth_params, sizeof(rt->auth_params),
+             "?authmod=%s&user=%s&challenge=%s&response=%s",
+             "adobe", user, challenge2, hashstr);
+    if (opaque)
+        av_strlcatf(rt->auth_params, sizeof(rt->auth_params),
+                    "&opaque=%s", opaque);
+
+    av_free(md5);
+    return 0;
+}
+
+static int do_llnw_auth(RTMPContext *rt, const char *user, const char *nonce)
+{
+    uint8_t hash[16];
+    char hashstr1[33], hashstr2[33];
+    const char *realm = "live";
+    const char *method = "publish";
+    const char *qop = "auth";
+    const char *nc = "00000001";
+    char cnonce[10];
+    struct AVMD5 *md5 = av_md5_alloc();
+    if (!md5)
+        return AVERROR(ENOMEM);
+
+    snprintf(cnonce, sizeof(cnonce), "%08x", av_get_random_seed());
+
+    av_md5_init(md5);
+    av_md5_update(md5, user, strlen(user));
+    av_md5_update(md5, ":", 1);
+    av_md5_update(md5, realm, strlen(realm));
+    av_md5_update(md5, ":", 1);
+    av_md5_update(md5, rt->password, strlen(rt->password));
+    av_md5_final(md5, hash);
+    ff_data_to_hex(hashstr1, hash, 16, 1);
+    hashstr1[32] = '\0';
+
+    av_md5_init(md5);
+    av_md5_update(md5, method, strlen(method));
+    av_md5_update(md5, ":/", 2);
+    av_md5_update(md5, rt->app, strlen(rt->app));
+    av_md5_final(md5, hash);
+    ff_data_to_hex(hashstr2, hash, 16, 1);
+    hashstr2[32] = '\0';
+
+    av_md5_init(md5);
+    av_md5_update(md5, hashstr1, strlen(hashstr1));
+    av_md5_update(md5, ":", 1);
+    if (nonce)
+        av_md5_update(md5, nonce, strlen(nonce));
+    av_md5_update(md5, ":", 1);
+    av_md5_update(md5, nc, strlen(nc));
+    av_md5_update(md5, ":", 1);
+    av_md5_update(md5, cnonce, strlen(cnonce));
+    av_md5_update(md5, ":", 1);
+    av_md5_update(md5, qop, strlen(qop));
+    av_md5_update(md5, ":", 1);
+    av_md5_update(md5, hashstr2, strlen(hashstr2));
+    av_md5_final(md5, hash);
+    ff_data_to_hex(hashstr1, hash, 16, 1);
+
+    snprintf(rt->auth_params, sizeof(rt->auth_params),
+             "?authmod=%s&user=%s&nonce=%s&cnonce=%s&nc=%s&response=%s",
+             "llnw", user, nonce, cnonce, nc, hashstr1);
+
+    av_free(md5);
+    return 0;
+}
+
+static int handle_connect_error(URLContext *s, const char *desc)
+{
+    RTMPContext *rt = s->priv_data;
+    char buf[300], *ptr, authmod[15];
+    int i = 0, ret = 0;
+    const char *user = "", *salt = "", *opaque = NULL,
+               *challenge = NULL, *cptr = NULL, *nonce = NULL;
+
+    if (!(cptr = strstr(desc, "authmod=adobe")) &&
+        !(cptr = strstr(desc, "authmod=llnw"))) {
+        av_log(s, AV_LOG_ERROR,
+               "Unknown connect error (unsupported authentication method?)\n");
+        return AVERROR_UNKNOWN;
+    }
+    cptr += strlen("authmod=");
+    while (*cptr && *cptr != ' ' && i < sizeof(authmod) - 1)
+        authmod[i++] = *cptr++;
+    authmod[i] = '\0';
+
+    if (!rt->username[0] || !rt->password[0]) {
+        av_log(s, AV_LOG_ERROR, "No credentials set\n");
+        return AVERROR_UNKNOWN;
+    }
+
+    if (strstr(desc, "?reason=authfailed")) {
+        av_log(s, AV_LOG_ERROR, "Incorrect username/password\n");
+        return AVERROR_UNKNOWN;
+    } else if (strstr(desc, "?reason=nosuchuser")) {
+        av_log(s, AV_LOG_ERROR, "Incorrect username\n");
+        return AVERROR_UNKNOWN;
+    }
+
+    if (rt->auth_tried) {
+        av_log(s, AV_LOG_ERROR, "Authentication failed\n");
+        return AVERROR_UNKNOWN;
+    }
+
+    rt->auth_params[0] = '\0';
+
+    if (strstr(desc, "code=403 need auth")) {
+        snprintf(rt->auth_params, sizeof(rt->auth_params),
+                 "?authmod=%s&user=%s", authmod, rt->username);
+        return 0;
+    }
+
+    if (!(cptr = strstr(desc, "?reason=needauth"))) {
+        av_log(s, AV_LOG_ERROR, "No auth parameters found\n");
+        return AVERROR_UNKNOWN;
+    }
+
+    av_strlcpy(buf, cptr + 1, sizeof(buf));
+    ptr = buf;
+
+    while (ptr) {
+        char *next  = strchr(ptr, '&');
+        char *value = strchr(ptr, '=');
+        if (next)
+            *next++ = '\0';
+        if (value)
+            *value++ = '\0';
+        if (!strcmp(ptr, "user")) {
+            user = value;
+        } else if (!strcmp(ptr, "salt")) {
+            salt = value;
+        } else if (!strcmp(ptr, "opaque")) {
+            opaque = value;
+        } else if (!strcmp(ptr, "challenge")) {
+            challenge = value;
+        } else if (!strcmp(ptr, "nonce")) {
+            nonce = value;
+        }
+        ptr = next;
+    }
+
+    if (!strcmp(authmod, "adobe")) {
+        if ((ret = do_adobe_auth(rt, user, salt, challenge, opaque)) < 0)
+            return ret;
+    } else {
+        if ((ret = do_llnw_auth(rt, user, nonce)) < 0)
+            return ret;
+    }
+
+    rt->auth_tried = 1;
+    return 0;
+}
+
 static int handle_invoke_error(URLContext *s, RTMPPacket *pkt)
 {
+    RTMPContext *rt = s->priv_data;
     const uint8_t *data_end = pkt->data + pkt->data_size;
     char *tracked_method = NULL;
     int level = AV_LOG_ERROR;
@@ -1529,8 +1722,14 @@
             /* Gracefully ignore Adobe-specific historical artifact errors. */
             level = AV_LOG_WARNING;
             ret = 0;
+        } else if (tracked_method && !strcmp(tracked_method, "connect")) {
+            ret = handle_connect_error(s, tmpstr);
+            if (!ret) {
+                rt->do_reconnect = 1;
+                level = AV_LOG_VERBOSE;
+            }
         } else
-            ret = -1;
+            ret = AVERROR_UNKNOWN;
         av_log(s, level, "Server error: %s\n", tmpstr);
     }
 
@@ -1790,7 +1989,7 @@
                !memcmp(pkt->data, "\002\000\007publish", 10)       ||
                !memcmp(pkt->data, "\002\000\010_checkbw", 11)      ||
                !memcmp(pkt->data, "\002\000\014createStream", 15)) {
-        if (ret = send_invoke_response(s, pkt) < 0)
+        if ((ret = send_invoke_response(s, pkt)) < 0)
             return ret;
     }
 
@@ -1955,6 +2154,10 @@
             ff_rtmp_packet_destroy(&rpkt);
             return ret;
         }
+        if (rt->do_reconnect && for_header) {
+            ff_rtmp_packet_destroy(&rpkt);
+            return 0;
+        }
         if (rt->state == STATE_STOPPED) {
             ff_rtmp_packet_destroy(&rpkt);
             return AVERROR_EOF;
@@ -2057,7 +2260,7 @@
 static int rtmp_open(URLContext *s, const char *uri, int flags)
 {
     RTMPContext *rt = s->priv_data;
-    char proto[8], hostname[256], path[1024], *fname;
+    char proto[8], hostname[256], path[1024], auth[100], *fname;
     char *old_app;
     uint8_t buf[2048];
     int port;
@@ -2069,9 +2272,19 @@
 
     rt->is_input = !(flags & AVIO_FLAG_WRITE);
 
-    av_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname), &port,
+    av_url_split(proto, sizeof(proto), auth, sizeof(auth),
+                 hostname, sizeof(hostname), &port,
                  path, sizeof(path), s->filename);
 
+    if (auth[0]) {
+        char *ptr = strchr(auth, ':');
+        if (ptr) {
+            *ptr = '\0';
+            av_strlcpy(rt->username, auth, sizeof(rt->username));
+            av_strlcpy(rt->password, ptr + 1, sizeof(rt->password));
+        }
+    }
+
     if (rt->listen && strcmp(proto, "rtmp")) {
         av_log(s, AV_LOG_ERROR, "rtmp_listen not available for %s\n",
                proto);
@@ -2107,6 +2320,7 @@
             ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL);
     }
 
+reconnect:
     if ((ret = ffurl_open(&rt->stream, buf, AVIO_FLAG_READ_WRITE,
                           &s->interrupt_callback, &opts)) < 0) {
         av_log(s , AV_LOG_ERROR, "Cannot open connection %s\n", buf);
@@ -2153,16 +2367,20 @@
             fname = strchr(p + 1, '/');
             if (!fname || (c && c < fname)) {
                 fname = p + 1;
-                av_strlcpy(rt->app, path + 1, p - path);
+                av_strlcpy(rt->app, path + 1, FFMIN(p - path, APP_MAX_LENGTH));
             } else {
                 fname++;
-                av_strlcpy(rt->app, path + 1, fname - path - 1);
+                av_strlcpy(rt->app, path + 1, FFMIN(fname - path - 1, APP_MAX_LENGTH));
             }
         }
     }
 
     if (old_app) {
         // The name of application has been defined by the user, override it.
+        if (strlen(old_app) >= APP_MAX_LENGTH) {
+            ret = AVERROR(EINVAL);
+            goto fail;
+        }
         av_free(rt->app);
         rt->app = old_app;
     }
@@ -2236,6 +2454,16 @@
     if (ret < 0)
         goto fail;
 
+    if (rt->do_reconnect) {
+        ffurl_close(rt->stream);
+        rt->stream       = NULL;
+        rt->do_reconnect = 0;
+        rt->nb_invokes   = 0;
+        memset(rt->prev_pkt, 0, sizeof(rt->prev_pkt));
+        free_tracked_methods(rt);
+        goto reconnect;
+    }
+
     if (rt->is_input) {
         // generate FLV header for demuxer
         rt->flv_size = 13;
diff --git a/libavformat/rtp.c b/libavformat/rtp.c
index ae0fd58..c4dcf6a 100644
--- a/libavformat/rtp.c
+++ b/libavformat/rtp.c
@@ -19,29 +19,25 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include <libavutil/opt.h>
+#include "libavutil/opt.h"
 #include "avformat.h"
 
 #include "rtp.h"
 
-//#define DEBUG
-
 /* from http://www.iana.org/assignments/rtp-parameters last updated 05 January 2005 */
 /* payload types >= 96 are dynamic;
  * payload types between 72 and 76 are reserved for RTCP conflict avoidance;
  * all the other payload types not present in the table are unassigned or
  * reserved
  */
-static const struct
-{
+static const struct {
     int pt;
     const char enc_name[6];
     enum AVMediaType codec_type;
     enum AVCodecID codec_id;
     int clock_rate;
     int audio_channels;
-} AVRtpPayloadTypes[]=
-{
+} rtp_payload_types[] = {
   {0, "PCMU",        AVMEDIA_TYPE_AUDIO,   AV_CODEC_ID_PCM_MULAW, 8000, 1},
   {3, "GSM",         AVMEDIA_TYPE_AUDIO,   AV_CODEC_ID_NONE, 8000, 1},
   {4, "G723",        AVMEDIA_TYPE_AUDIO,   AV_CODEC_ID_G723_1, 8000, 1},
@@ -75,15 +71,15 @@
 {
     int i = 0;
 
-    for (i = 0; AVRtpPayloadTypes[i].pt >= 0; i++)
-        if (AVRtpPayloadTypes[i].pt == payload_type) {
-            if (AVRtpPayloadTypes[i].codec_id != AV_CODEC_ID_NONE) {
-                codec->codec_type = AVRtpPayloadTypes[i].codec_type;
-                codec->codec_id = AVRtpPayloadTypes[i].codec_id;
-                if (AVRtpPayloadTypes[i].audio_channels > 0)
-                    codec->channels = AVRtpPayloadTypes[i].audio_channels;
-                if (AVRtpPayloadTypes[i].clock_rate > 0)
-                    codec->sample_rate = AVRtpPayloadTypes[i].clock_rate;
+    for (i = 0; rtp_payload_types[i].pt >= 0; i++)
+        if (rtp_payload_types[i].pt == payload_type) {
+            if (rtp_payload_types[i].codec_id != AV_CODEC_ID_NONE) {
+                codec->codec_type = rtp_payload_types[i].codec_type;
+                codec->codec_id = rtp_payload_types[i].codec_id;
+                if (rtp_payload_types[i].audio_channels > 0)
+                    codec->channels = rtp_payload_types[i].audio_channels;
+                if (rtp_payload_types[i].clock_rate > 0)
+                    codec->sample_rate = rtp_payload_types[i].clock_rate;
                 return 0;
             }
         }
@@ -97,7 +93,7 @@
     AVOutputFormat *ofmt = fmt ? fmt->oformat : NULL;
 
     /* Was the payload type already specified for the RTP muxer? */
-    if (ofmt && ofmt->priv_class) {
+    if (ofmt && ofmt->priv_class && fmt->priv_data) {
         int64_t payload_type;
         if (av_opt_get_int(fmt->priv_data, "payload_type", 0, &payload_type) >= 0 &&
             payload_type >= 0)
@@ -105,24 +101,24 @@
     }
 
     /* static payload type */
-    for (i = 0; AVRtpPayloadTypes[i].pt >= 0; ++i)
-        if (AVRtpPayloadTypes[i].codec_id == codec->codec_id) {
-            if (codec->codec_id == AV_CODEC_ID_H263 && (!fmt ||
-                !fmt->oformat->priv_class ||
+    for (i = 0; rtp_payload_types[i].pt >= 0; ++i)
+        if (rtp_payload_types[i].codec_id == codec->codec_id) {
+            if (codec->codec_id == AV_CODEC_ID_H263 && (!fmt || !fmt->oformat ||
+                !fmt->oformat->priv_class || !fmt->priv_data ||
                 !av_opt_flag_is_set(fmt->priv_data, "rtpflags", "rfc2190")))
                 continue;
             /* G722 has 8000 as nominal rate even if the sample rate is 16000,
              * see section 4.5.2 in RFC 3551. */
             if (codec->codec_id == AV_CODEC_ID_ADPCM_G722 &&
                 codec->sample_rate == 16000 && codec->channels == 1)
-                return AVRtpPayloadTypes[i].pt;
+                return rtp_payload_types[i].pt;
             if (codec->codec_type == AVMEDIA_TYPE_AUDIO &&
-                ((AVRtpPayloadTypes[i].clock_rate > 0 &&
-                  codec->sample_rate != AVRtpPayloadTypes[i].clock_rate) ||
-                 (AVRtpPayloadTypes[i].audio_channels > 0 &&
-                  codec->channels != AVRtpPayloadTypes[i].audio_channels)))
+                ((rtp_payload_types[i].clock_rate > 0 &&
+                  codec->sample_rate != rtp_payload_types[i].clock_rate) ||
+                 (rtp_payload_types[i].audio_channels > 0 &&
+                  codec->channels != rtp_payload_types[i].audio_channels)))
                 continue;
-            return AVRtpPayloadTypes[i].pt;
+            return rtp_payload_types[i].pt;
         }
 
     if (idx < 0)
@@ -136,10 +132,9 @@
 {
     int i;
 
-    for (i = 0; AVRtpPayloadTypes[i].pt >= 0; i++)
-        if (AVRtpPayloadTypes[i].pt == payload_type) {
-            return AVRtpPayloadTypes[i].enc_name;
-        }
+    for (i = 0; rtp_payload_types[i].pt >= 0; i++)
+        if (rtp_payload_types[i].pt == payload_type)
+            return rtp_payload_types[i].enc_name;
 
     return "";
 }
@@ -148,10 +143,9 @@
 {
     int i;
 
-    for (i = 0; AVRtpPayloadTypes[i].pt >= 0; i++)
-        if (!strcmp(buf, AVRtpPayloadTypes[i].enc_name) && (codec_type == AVRtpPayloadTypes[i].codec_type)){
-            return AVRtpPayloadTypes[i].codec_id;
-        }
+    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))
+            return rtp_payload_types[i].codec_id;
 
     return AV_CODEC_ID_NONE;
 }
diff --git a/libavformat/rtpdec.c b/libavformat/rtpdec.c
index e92419d..a1f1701 100644
--- a/libavformat/rtpdec.c
+++ b/libavformat/rtpdec.c
@@ -24,94 +24,82 @@
 #include "libavutil/time.h"
 #include "libavcodec/get_bits.h"
 #include "avformat.h"
-#include "mpegts.h"
-#include "url.h"
-
 #include "network.h"
-
+#include "srtp.h"
+#include "url.h"
 #include "rtpdec.h"
 #include "rtpdec_formats.h"
 
-//#define DEBUG
-
-/* TODO: - add RTCP statistics reporting (should be optional).
-
-         - add support for h263/mpeg4 packetized output : IDEA: send a
-         buffer to 'rtp_write_packet' contains all the packets for ONE
-         frame. Each packet should have a four byte header containing
-         the length in big endian format (same trick as
-         'ffio_open_dyn_packet_buf')
-*/
+#define MIN_FEEDBACK_INTERVAL 200000 /* 200 ms in us */
 
 static RTPDynamicProtocolHandler realmedia_mp3_dynamic_handler = {
-    .enc_name           = "X-MP3-draft-00",
-    .codec_type         = AVMEDIA_TYPE_AUDIO,
-    .codec_id           = AV_CODEC_ID_MP3ADU,
+    .enc_name   = "X-MP3-draft-00",
+    .codec_type = AVMEDIA_TYPE_AUDIO,
+    .codec_id   = AV_CODEC_ID_MP3ADU,
 };
 
 static RTPDynamicProtocolHandler speex_dynamic_handler = {
-    .enc_name         = "speex",
-    .codec_type       = AVMEDIA_TYPE_AUDIO,
-    .codec_id         = AV_CODEC_ID_SPEEX,
+    .enc_name   = "speex",
+    .codec_type = AVMEDIA_TYPE_AUDIO,
+    .codec_id   = AV_CODEC_ID_SPEEX,
 };
 
 static RTPDynamicProtocolHandler opus_dynamic_handler = {
-    .enc_name         = "opus",
-    .codec_type       = AVMEDIA_TYPE_AUDIO,
-    .codec_id         = AV_CODEC_ID_OPUS,
+    .enc_name   = "opus",
+    .codec_type = AVMEDIA_TYPE_AUDIO,
+    .codec_id   = AV_CODEC_ID_OPUS,
 };
 
-/* statistics functions */
-static RTPDynamicProtocolHandler *RTPFirstDynamicPayloadHandler= NULL;
+static RTPDynamicProtocolHandler *rtp_first_dynamic_payload_handler = NULL;
 
 void ff_register_dynamic_payload_handler(RTPDynamicProtocolHandler *handler)
 {
-    handler->next= RTPFirstDynamicPayloadHandler;
-    RTPFirstDynamicPayloadHandler= handler;
+    handler->next = rtp_first_dynamic_payload_handler;
+    rtp_first_dynamic_payload_handler = handler;
 }
 
 void av_register_rtp_dynamic_payload_handlers(void)
 {
-    ff_register_dynamic_payload_handler(&ff_mp4v_es_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_mpeg4_generic_dynamic_handler);
     ff_register_dynamic_payload_handler(&ff_amr_nb_dynamic_handler);
     ff_register_dynamic_payload_handler(&ff_amr_wb_dynamic_handler);
+    ff_register_dynamic_payload_handler(&ff_g726_16_dynamic_handler);
+    ff_register_dynamic_payload_handler(&ff_g726_24_dynamic_handler);
+    ff_register_dynamic_payload_handler(&ff_g726_32_dynamic_handler);
+    ff_register_dynamic_payload_handler(&ff_g726_40_dynamic_handler);
     ff_register_dynamic_payload_handler(&ff_h263_1998_dynamic_handler);
     ff_register_dynamic_payload_handler(&ff_h263_2000_dynamic_handler);
     ff_register_dynamic_payload_handler(&ff_h263_rfc2190_dynamic_handler);
     ff_register_dynamic_payload_handler(&ff_h264_dynamic_handler);
     ff_register_dynamic_payload_handler(&ff_ilbc_dynamic_handler);
     ff_register_dynamic_payload_handler(&ff_jpeg_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_vorbis_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_theora_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_qdm2_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_svq3_dynamic_handler);
     ff_register_dynamic_payload_handler(&ff_mp4a_latm_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_vp8_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_qcelp_dynamic_handler);
-    ff_register_dynamic_payload_handler(&realmedia_mp3_dynamic_handler);
-    ff_register_dynamic_payload_handler(&speex_dynamic_handler);
-    ff_register_dynamic_payload_handler(&opus_dynamic_handler);
-
+    ff_register_dynamic_payload_handler(&ff_mp4v_es_dynamic_handler);
+    ff_register_dynamic_payload_handler(&ff_mpeg_audio_dynamic_handler);
+    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_qcelp_dynamic_handler);
+    ff_register_dynamic_payload_handler(&ff_qdm2_dynamic_handler);
     ff_register_dynamic_payload_handler(&ff_qt_rtp_aud_handler);
     ff_register_dynamic_payload_handler(&ff_qt_rtp_vid_handler);
     ff_register_dynamic_payload_handler(&ff_quicktime_rtp_aud_handler);
     ff_register_dynamic_payload_handler(&ff_quicktime_rtp_vid_handler);
-
-    ff_register_dynamic_payload_handler(&ff_g726_16_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_g726_24_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_g726_32_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_g726_40_dynamic_handler);
+    ff_register_dynamic_payload_handler(&ff_svq3_dynamic_handler);
+    ff_register_dynamic_payload_handler(&ff_theora_dynamic_handler);
+    ff_register_dynamic_payload_handler(&ff_vorbis_dynamic_handler);
+    ff_register_dynamic_payload_handler(&ff_vp8_dynamic_handler);
+    ff_register_dynamic_payload_handler(&opus_dynamic_handler);
+    ff_register_dynamic_payload_handler(&realmedia_mp3_dynamic_handler);
+    ff_register_dynamic_payload_handler(&speex_dynamic_handler);
 }
 
 RTPDynamicProtocolHandler *ff_rtp_handler_find_by_name(const char *name,
-                                                  enum AVMediaType codec_type)
+                                                       enum AVMediaType codec_type)
 {
     RTPDynamicProtocolHandler *handler;
-    for (handler = RTPFirstDynamicPayloadHandler;
+    for (handler = rtp_first_dynamic_payload_handler;
          handler; handler = handler->next)
         if (!av_strcasecmp(name, handler->enc_name) &&
             codec_type == handler->codec_type)
@@ -120,10 +108,10 @@
 }
 
 RTPDynamicProtocolHandler *ff_rtp_handler_find_by_id(int id,
-                                                enum AVMediaType codec_type)
+                                                     enum AVMediaType codec_type)
 {
     RTPDynamicProtocolHandler *handler;
-    for (handler = RTPFirstDynamicPayloadHandler;
+    for (handler = rtp_first_dynamic_payload_handler;
          handler; handler = handler->next)
         if (handler->static_payload_id && handler->static_payload_id == id &&
             codec_type == handler->codec_type)
@@ -131,7 +119,8 @@
     return NULL;
 }
 
-static int rtcp_parse_packet(RTPDemuxContext *s, const unsigned char *buf, int len)
+static int rtcp_parse_packet(RTPDemuxContext *s, const unsigned char *buf,
+                             int len)
 {
     int payload_len;
     while (len >= 4) {
@@ -140,11 +129,13 @@
         switch (buf[1]) {
         case RTCP_SR:
             if (payload_len < 20) {
-                av_log(NULL, AV_LOG_ERROR, "Invalid length for RTCP SR packet\n");
+                av_log(NULL, AV_LOG_ERROR,
+                       "Invalid length for RTCP SR packet\n");
                 return AVERROR_INVALIDDATA;
             }
 
-            s->last_rtcp_ntp_time = AV_RB64(buf + 8);
+            s->last_rtcp_reception_time = av_gettime();
+            s->last_rtcp_ntp_time  = AV_RB64(buf + 8);
             s->last_rtcp_timestamp = AV_RB32(buf + 16);
             if (s->first_rtcp_ntp_time == AV_NOPTS_VALUE) {
                 s->first_rtcp_ntp_time = s->last_rtcp_ntp_time;
@@ -164,7 +155,7 @@
     return -1;
 }
 
-#define RTP_SEQ_MOD (1<<16)
+#define RTP_SEQ_MOD (1 << 16)
 
 static void rtp_init_statistics(RTPStatistics *s, uint16_t base_sequence)
 {
@@ -174,8 +165,9 @@
 }
 
 /*
-* called whenever there is a large jump in sequence numbers, or when they get out of probation...
-*/
+ * Called whenever there is a large jump in sequence numbers,
+ * or when they get out of probation...
+ */
 static void rtp_init_sequence(RTPStatistics *s, uint16_t seq)
 {
     s->max_seq        = seq;
@@ -189,9 +181,7 @@
     s->transit        = 0;
 }
 
-/*
-* returns 1 if we should handle this packet.
-*/
+/* Returns 1 if we should handle this packet. */
 static int rtp_valid_packet_in_sequence(RTPStatistics *s, uint16_t seq)
 {
     uint16_t udelta = seq - s->max_seq;
@@ -199,7 +189,8 @@
     const int MAX_MISORDER   = 100;
     const int MIN_SEQUENTIAL = 2;
 
-    /* source not valid until MIN_SEQUENTIAL packets with sequence seq. numbers have been received */
+    /* source not valid until MIN_SEQUENTIAL packets with sequence
+     * seq. numbers have been received */
     if (s->probation) {
         if (seq == s->max_seq + 1) {
             s->probation--;
@@ -211,7 +202,7 @@
             }
         } else {
             s->probation = MIN_SEQUENTIAL - 1;
-            s->max_seq = seq;
+            s->max_seq   = seq;
         }
     } else if (udelta < MAX_DROPOUT) {
         // in order, with permissible gap
@@ -223,7 +214,8 @@
     } else if (udelta <= RTP_SEQ_MOD - MAX_MISORDER) {
         // sequence made a large jump...
         if (seq == s->bad_seq) {
-            // two sequential packets-- assume that the other side restarted without telling us; just resync.
+            /* two sequential packets -- assume that the other side
+             * restarted without telling us; just resync. */
             rtp_init_sequence(s, seq);
         } else {
             s->bad_seq = (seq + 1) & (RTP_SEQ_MOD - 1);
@@ -236,7 +228,26 @@
     return 1;
 }
 
-int ff_rtp_check_and_send_back_rr(RTPDemuxContext *s, int count)
+static void rtcp_update_jitter(RTPStatistics *s, uint32_t sent_timestamp,
+                               uint32_t arrival_timestamp)
+{
+    // Most of this is pretty straight from RFC 3550 appendix A.8
+    uint32_t transit = arrival_timestamp - sent_timestamp;
+    uint32_t prev_transit = s->transit;
+    int32_t d = transit - prev_transit;
+    // Doing the FFABS() call directly on the "transit - prev_transit"
+    // expression doesn't work, since it's an unsigned expression. Doing the
+    // transit calculation in unsigned is desired though, since it most
+    // probably will need to wrap around.
+    d = FFABS(d);
+    s->transit = transit;
+    if (!prev_transit)
+        return;
+    s->jitter += d - (int32_t) ((s->jitter + 8) >> 4);
+}
+
+int ff_rtp_check_and_send_back_rr(RTPDemuxContext *s, URLContext *fd,
+                                  AVIOContext *avio, int count)
 {
     AVIOContext *pb;
     uint8_t *buf;
@@ -247,16 +258,15 @@
     uint32_t extended_max;
     uint32_t expected_interval;
     uint32_t received_interval;
-    uint32_t lost_interval;
+    int32_t  lost_interval;
     uint32_t expected;
     uint32_t fraction;
-    uint64_t ntp_time = s->last_rtcp_ntp_time; // TODO: Get local ntp time?
 
-    if (!s->rtp_ctx || (count < 1))
+    if ((!fd && !avio) || (count < 1))
         return -1;
 
     /* TODO: I think this is way too often; RFC 1889 has algorithm for this */
-    /* XXX: mpeg pts hardcoded. RTCP send every 0.5 seconds */
+    /* XXX: MPEG pts hardcoded. RTCP send every 0.5 seconds */
     s->octet_count += count;
     rtcp_bytes = ((s->octet_count - s->last_octet_count) * RTCP_TX_RATIO_NUM) /
         RTCP_TX_RATIO_DEN;
@@ -265,7 +275,9 @@
         return -1;
     s->last_octet_count = s->octet_count;
 
-    if (avio_open_dyn_buf(&pb) < 0)
+    if (!fd)
+        pb = avio;
+    else if (avio_open_dyn_buf(&pb) < 0)
         return -1;
 
     // Receiver Report
@@ -277,15 +289,15 @@
     avio_wb32(pb, s->ssrc); // server SSRC
     // some placeholders we should really fill...
     // RFC 1889/p64
-    extended_max = stats->cycles + stats->max_seq;
-    expected = extended_max - stats->base_seq + 1;
-    lost = expected - stats->received;
-    lost = FFMIN(lost, 0xffffff); // clamp it since it's only 24 bits...
-    expected_interval = expected - stats->expected_prior;
+    extended_max          = stats->cycles + stats->max_seq;
+    expected              = extended_max - stats->base_seq;
+    lost                  = expected - stats->received;
+    lost                  = FFMIN(lost, 0xffffff); // clamp it since it's only 24 bits...
+    expected_interval     = expected - stats->expected_prior;
     stats->expected_prior = expected;
-    received_interval = stats->received - stats->received_prior;
+    received_interval     = stats->received - stats->received_prior;
     stats->received_prior = stats->received;
-    lost_interval = expected_interval - received_interval;
+    lost_interval         = expected_interval - received_interval;
     if (expected_interval == 0 || lost_interval <= 0)
         fraction = 0;
     else
@@ -301,8 +313,9 @@
         avio_wb32(pb, 0); /* last SR timestamp */
         avio_wb32(pb, 0); /* delay since last SR */
     } else {
-        uint32_t middle_32_bits = s->last_rtcp_ntp_time >> 16; // this is valid, right? do we need to handle 64 bit values special?
-        uint32_t delay_since_last = ntp_time - s->last_rtcp_ntp_time;
+        uint32_t middle_32_bits   = s->last_rtcp_ntp_time >> 16; // this is valid, right? do we need to handle 64 bit values special?
+        uint32_t delay_since_last = av_rescale(av_gettime() - s->last_rtcp_reception_time,
+                                               65536, AV_TIME_BASE);
 
         avio_wb32(pb, middle_32_bits); /* last SR timestamp */
         avio_wb32(pb, delay_since_last); /* delay since last SR */
@@ -312,29 +325,31 @@
     avio_w8(pb, (RTP_VERSION << 6) + 1); /* 1 report block */
     avio_w8(pb, RTCP_SDES);
     len = strlen(s->hostname);
-    avio_wb16(pb, (6 + len + 3) / 4); /* length in words - 1 */
+    avio_wb16(pb, (7 + len + 3) / 4); /* length in words - 1 */
     avio_wb32(pb, s->ssrc + 1);
     avio_w8(pb, 0x01);
     avio_w8(pb, len);
     avio_write(pb, s->hostname, len);
+    avio_w8(pb, 0); /* END */
     // padding
-    for (len = (6 + len) % 4; len % 4; len++) {
+    for (len = (7 + len) % 4; len % 4; len++)
         avio_w8(pb, 0);
-    }
 
     avio_flush(pb);
+    if (!fd)
+        return 0;
     len = avio_close_dyn_buf(pb, &buf);
     if ((len > 0) && buf) {
         int av_unused result;
         av_dlog(s->ic, "sending %d bytes of RR\n", len);
-        result= ffurl_write(s->rtp_ctx, buf, len);
+        result = ffurl_write(fd, buf, len);
         av_dlog(s->ic, "result from ffurl_write: %d\n", result);
         av_free(buf);
     }
     return 0;
 }
 
-void ff_rtp_send_punch_packets(URLContext* rtp_handle)
+void ff_rtp_send_punch_packets(URLContext *rtp_handle)
 {
     AVIOContext *pb;
     uint8_t *buf;
@@ -372,46 +387,121 @@
     av_free(buf);
 }
 
+static int find_missing_packets(RTPDemuxContext *s, uint16_t *first_missing,
+                                uint16_t *missing_mask)
+{
+    int i;
+    uint16_t next_seq = s->seq + 1;
+    RTPPacket *pkt = s->queue;
+
+    if (!pkt || pkt->seq == next_seq)
+        return 0;
+
+    *missing_mask = 0;
+    for (i = 1; i <= 16; i++) {
+        uint16_t missing_seq = next_seq + i;
+        while (pkt) {
+            int16_t diff = pkt->seq - missing_seq;
+            if (diff >= 0)
+                break;
+            pkt = pkt->next;
+        }
+        if (!pkt)
+            break;
+        if (pkt->seq == missing_seq)
+            continue;
+        *missing_mask |= 1 << (i - 1);
+    }
+
+    *first_missing = next_seq;
+    return 1;
+}
+
+int ff_rtp_send_rtcp_feedback(RTPDemuxContext *s, URLContext *fd,
+                              AVIOContext *avio)
+{
+    int len, need_keyframe, missing_packets;
+    AVIOContext *pb;
+    uint8_t *buf;
+    int64_t now;
+    uint16_t first_missing, missing_mask;
+
+    if (!fd && !avio)
+        return -1;
+
+    need_keyframe = s->handler && s->handler->need_keyframe &&
+                    s->handler->need_keyframe(s->dynamic_protocol_context);
+    missing_packets = find_missing_packets(s, &first_missing, &missing_mask);
+
+    if (!need_keyframe && !missing_packets)
+        return 0;
+
+    /* Send new feedback if enough time has elapsed since the last
+     * feedback packet. */
+
+    now = av_gettime();
+    if (s->last_feedback_time &&
+        (now - s->last_feedback_time) < MIN_FEEDBACK_INTERVAL)
+        return 0;
+    s->last_feedback_time = now;
+
+    if (!fd)
+        pb = avio;
+    else if (avio_open_dyn_buf(&pb) < 0)
+        return -1;
+
+    if (need_keyframe) {
+        avio_w8(pb, (RTP_VERSION << 6) | 1); /* PLI */
+        avio_w8(pb, RTCP_PSFB);
+        avio_wb16(pb, 2); /* length in words - 1 */
+        // our own SSRC: we use the server's SSRC + 1 to avoid conflicts
+        avio_wb32(pb, s->ssrc + 1);
+        avio_wb32(pb, s->ssrc); // server SSRC
+    }
+
+    if (missing_packets) {
+        avio_w8(pb, (RTP_VERSION << 6) | 1); /* NACK */
+        avio_w8(pb, RTCP_RTPFB);
+        avio_wb16(pb, 3); /* length in words - 1 */
+        avio_wb32(pb, s->ssrc + 1);
+        avio_wb32(pb, s->ssrc); // server SSRC
+
+        avio_wb16(pb, first_missing);
+        avio_wb16(pb, missing_mask);
+    }
+
+    avio_flush(pb);
+    if (!fd)
+        return 0;
+    len = avio_close_dyn_buf(pb, &buf);
+    if (len > 0 && buf) {
+        ffurl_write(fd, buf, len);
+        av_free(buf);
+    }
+    return 0;
+}
 
 /**
  * open a new RTP parse context for stream 'st'. 'st' can be NULL for
- * MPEG2TS streams to indicate that they should be demuxed inside the
- * rtp demux (otherwise AV_CODEC_ID_MPEG2TS packets are returned)
+ * MPEG2-TS streams.
  */
-RTPDemuxContext *ff_rtp_parse_open(AVFormatContext *s1, AVStream *st, URLContext *rtpc, int payload_type, int queue_size)
+RTPDemuxContext *ff_rtp_parse_open(AVFormatContext *s1, AVStream *st,
+                                   int payload_type, int queue_size)
 {
     RTPDemuxContext *s;
 
     s = av_mallocz(sizeof(RTPDemuxContext));
     if (!s)
         return NULL;
-    s->payload_type = payload_type;
-    s->last_rtcp_ntp_time = AV_NOPTS_VALUE;
+    s->payload_type        = payload_type;
+    s->last_rtcp_ntp_time  = AV_NOPTS_VALUE;
     s->first_rtcp_ntp_time = AV_NOPTS_VALUE;
-    s->ic = s1;
-    s->st = st;
-    s->queue_size = queue_size;
-    rtp_init_statistics(&s->statistics, 0); // do we know the initial sequence from sdp?
-    if (!strcmp(ff_rtp_enc_name(payload_type), "MP2T")) {
-        s->ts = ff_mpegts_parse_open(s->ic);
-        if (s->ts == NULL) {
-            av_free(s);
-            return NULL;
-        }
-    } else if (st) {
-        switch(st->codec->codec_id) {
-        case AV_CODEC_ID_MPEG1VIDEO:
-        case AV_CODEC_ID_MPEG2VIDEO:
-        case AV_CODEC_ID_MP2:
-        case AV_CODEC_ID_MP3:
-        case AV_CODEC_ID_MPEG4:
-        case AV_CODEC_ID_H263:
-        case AV_CODEC_ID_H264:
-            st->need_parsing = AVSTREAM_PARSE_FULL;
-            break;
-        case AV_CODEC_ID_VORBIS:
-            st->need_parsing = AVSTREAM_PARSE_HEADERS;
-            break;
+    s->ic                  = s1;
+    s->st                  = st;
+    s->queue_size          = queue_size;
+    rtp_init_statistics(&s->statistics, 0);
+    if (st) {
+        switch (st->codec->codec_id) {
         case AV_CODEC_ID_ADPCM_G722:
             /* According to RFC 3551, the stream clock rate is 8000
              * even if the sample rate is 16000. */
@@ -423,7 +513,6 @@
         }
     }
     // needed to send back RTCP RR in RTSP sessions
-    s->rtp_ctx = rtpc;
     gethostname(s->hostname, sizeof(s->hostname));
     return s;
 }
@@ -432,11 +521,19 @@
                                        RTPDynamicProtocolHandler *handler)
 {
     s->dynamic_protocol_context = ctx;
-    s->parse_packet = handler->parse_packet;
+    s->handler                  = handler;
+}
+
+void ff_rtp_parse_set_crypto(RTPDemuxContext *s, const char *suite,
+                             const char *params)
+{
+    if (!ff_srtp_set_crypto(&s->srtp, suite, params))
+        s->srtp_enabled = 1;
 }
 
 /**
- * This was the second switch in rtp_parse packet.  Normalizes time, if required, sets stream_index, etc.
+ * This was the second switch in rtp_parse packet.
+ * Normalizes time, if required, sets stream_index, etc.
  */
 static void finalize_packet(RTPDemuxContext *s, AVPacket *pkt, uint32_t timestamp)
 {
@@ -452,7 +549,9 @@
         /* compute pts from timestamp with received ntp_time */
         delta_timestamp = timestamp - s->last_rtcp_timestamp;
         /* convert to the PTS timebase */
-        addend = av_rescale(s->last_rtcp_ntp_time - s->first_rtcp_ntp_time, s->st->time_base.den, (uint64_t)s->st->time_base.num << 32);
+        addend = av_rescale(s->last_rtcp_ntp_time - s->first_rtcp_ntp_time,
+                            s->st->time_base.den,
+                            (uint64_t) s->st->time_base.num << 32);
         pkt->pts = s->range_start_offset + s->rtcp_ts_offset + addend +
                    delta_timestamp;
         return;
@@ -460,32 +559,35 @@
 
     if (!s->base_timestamp)
         s->base_timestamp = timestamp;
-    /* assume that the difference is INT32_MIN < x < INT32_MAX, but allow the first timestamp to exceed INT32_MAX */
+    /* assume that the difference is INT32_MIN < x < INT32_MAX,
+     * but allow the first timestamp to exceed INT32_MAX */
     if (!s->timestamp)
         s->unwrapped_timestamp += timestamp;
     else
         s->unwrapped_timestamp += (int32_t)(timestamp - s->timestamp);
     s->timestamp = timestamp;
-    pkt->pts = s->unwrapped_timestamp + s->range_start_offset - s->base_timestamp;
+    pkt->pts     = s->unwrapped_timestamp + s->range_start_offset -
+                   s->base_timestamp;
 }
 
 static int rtp_parse_packet_internal(RTPDemuxContext *s, AVPacket *pkt,
                                      const uint8_t *buf, int len)
 {
-    unsigned int ssrc, h;
-    int payload_type, seq, ret, flags = 0;
-    int ext;
+    unsigned int ssrc;
+    int payload_type, seq, flags = 0;
+    int ext, csrc;
     AVStream *st;
     uint32_t timestamp;
-    int rv= 0;
+    int rv = 0;
 
-    ext = buf[0] & 0x10;
+    csrc         = buf[0] & 0x0f;
+    ext          = buf[0] & 0x10;
     payload_type = buf[1] & 0x7f;
     if (buf[1] & 0x80)
         flags |= RTP_FLAG_MARKER;
-    seq  = AV_RB16(buf + 2);
+    seq       = AV_RB16(buf + 2);
     timestamp = AV_RB32(buf + 4);
-    ssrc = AV_RB32(buf + 8);
+    ssrc      = AV_RB32(buf + 8);
     /* store the ssrc in the RTPDemuxContext */
     s->ssrc = ssrc;
 
@@ -495,9 +597,9 @@
 
     st = s->st;
     // only do something with this if all the rtp checks pass...
-    if(!rtp_valid_packet_in_sequence(&s->statistics, seq))
-    {
-        av_log(st?st->codec:NULL, AV_LOG_ERROR, "RTP: PT=%02x: bad cseq %04x expected=%04x\n",
+    if (!rtp_valid_packet_in_sequence(&s->statistics, seq)) {
+        av_log(st ? st->codec : NULL, AV_LOG_ERROR,
+               "RTP: PT=%02x: bad cseq %04x expected=%04x\n",
                payload_type, seq, ((s->seq + 1) & 0xffff));
         return -1;
     }
@@ -509,8 +611,13 @@
     }
 
     s->seq = seq;
-    len -= 12;
-    buf += 12;
+    len   -= 12;
+    buf   += 12;
+
+    len   -= 4 * csrc;
+    buf   += 4 * csrc;
+    if (len < 0)
+        return AVERROR_INVALIDDATA;
 
     /* RFC 3550 Section 5.3.1 RTP Header Extension handling */
     if (ext) {
@@ -527,66 +634,17 @@
         buf += ext;
     }
 
-    if (!st) {
-        /* specific MPEG2TS demux support */
-        ret = ff_mpegts_parse_packet(s->ts, pkt, buf, len);
-        /* The only error that can be returned from ff_mpegts_parse_packet
-         * is "no more data to return from the provided buffer", so return
-         * AVERROR(EAGAIN) for all errors */
-        if (ret < 0)
-            return AVERROR(EAGAIN);
-        if (ret < len) {
-            s->read_buf_size = len - ret;
-            memcpy(s->buf, buf + ret, s->read_buf_size);
-            s->read_buf_index = 0;
-            return 1;
-        }
-        return 0;
-    } else if (s->parse_packet) {
-        rv = s->parse_packet(s->ic, s->dynamic_protocol_context,
-                             s->st, pkt, &timestamp, buf, len, flags);
-    } else {
-        // at this point, the RTP header has been stripped;  This is ASSUMING that there is only 1 CSRC, which in't wise.
-        switch(st->codec->codec_id) {
-        case AV_CODEC_ID_MP2:
-        case AV_CODEC_ID_MP3:
-            /* better than nothing: skip mpeg audio RTP header */
-            if (len <= 4)
-                return -1;
-            h = AV_RB32(buf);
-            len -= 4;
-            buf += 4;
-            if (av_new_packet(pkt, len) < 0)
-                return AVERROR(ENOMEM);
-            memcpy(pkt->data, buf, len);
-            break;
-        case AV_CODEC_ID_MPEG1VIDEO:
-        case AV_CODEC_ID_MPEG2VIDEO:
-            /* better than nothing: skip mpeg video RTP header */
-            if (len <= 4)
-                return -1;
-            h = AV_RB32(buf);
-            buf += 4;
-            len -= 4;
-            if (h & (1 << 26)) {
-                /* mpeg2 */
-                if (len <= 4)
-                    return -1;
-                buf += 4;
-                len -= 4;
-            }
-            if (av_new_packet(pkt, len) < 0)
-                return AVERROR(ENOMEM);
-            memcpy(pkt->data, buf, len);
-            break;
-        default:
-            if (av_new_packet(pkt, len) < 0)
-                return AVERROR(ENOMEM);
-            memcpy(pkt->data, buf, len);
-            break;
-        }
-
+    if (s->handler && s->handler->parse_packet) {
+        rv = s->handler->parse_packet(s->ic, s->dynamic_protocol_context,
+                                      s->st, pkt, &timestamp, buf, len, seq,
+                                      flags);
+    } else if (st) {
+        if ((rv = av_new_packet(pkt, len)) < 0)
+            return rv;
+        memcpy(pkt->data, buf, len);
         pkt->stream_index = st->index;
+    } else {
+        return AVERROR(EINVAL);
     }
 
     // now perform timestamp things....
@@ -610,30 +668,26 @@
 
 static void enqueue_packet(RTPDemuxContext *s, uint8_t *buf, int len)
 {
-    uint16_t seq = AV_RB16(buf + 2);
-    RTPPacket *cur = s->queue, *prev = NULL, *packet;
+    uint16_t seq   = AV_RB16(buf + 2);
+    RTPPacket **cur = &s->queue, *packet;
 
     /* Find the correct place in the queue to insert the packet */
-    while (cur) {
-        int16_t diff = seq - cur->seq;
+    while (*cur) {
+        int16_t diff = seq - (*cur)->seq;
         if (diff < 0)
             break;
-        prev = cur;
-        cur = cur->next;
+        cur = &(*cur)->next;
     }
 
     packet = av_mallocz(sizeof(*packet));
     if (!packet)
         return;
     packet->recvtime = av_gettime();
-    packet->seq = seq;
-    packet->len = len;
-    packet->buf = buf;
-    packet->next = cur;
-    if (prev)
-        prev->next = packet;
-    else
-        s->queue = packet;
+    packet->seq      = seq;
+    packet->len      = len;
+    packet->buf      = buf;
+    packet->next     = *cur;
+    *cur = packet;
     s->queue_len++;
 }
 
@@ -660,7 +714,7 @@
                "RTP: missed %d packets\n", s->queue->seq - s->seq - 1);
 
     /* Parse the first packet in the queue, and dequeue it */
-    rv = rtp_parse_packet_internal(s, pkt, s->queue->buf, s->queue->len);
+    rv   = rtp_parse_packet_internal(s, pkt, s->queue->buf, s->queue->len);
     next = s->queue->next;
     av_free(s->queue->buf);
     av_free(s->queue);
@@ -672,10 +726,10 @@
 static int rtp_parse_one_packet(RTPDemuxContext *s, AVPacket *pkt,
                                 uint8_t **bufptr, int len)
 {
-    uint8_t* buf = bufptr ? *bufptr : NULL;
-    int ret, flags = 0;
+    uint8_t *buf = bufptr ? *bufptr : NULL;
+    int flags = 0;
     uint32_t timestamp;
-    int rv= 0;
+    int rv = 0;
 
     if (!buf) {
         /* If parsing of the previous packet actually returned 0 or an error,
@@ -684,27 +738,15 @@
         if (s->prev_ret <= 0)
             return rtp_parse_queued_packet(s, pkt);
         /* return the next packets, if any */
-        if(s->st && s->parse_packet) {
+        if (s->handler && s->handler->parse_packet) {
             /* timestamp should be overwritten by parse_packet, if not,
              * the packet is left with pts == AV_NOPTS_VALUE */
             timestamp = RTP_NOTS_VALUE;
-            rv= s->parse_packet(s->ic, s->dynamic_protocol_context,
-                                s->st, pkt, &timestamp, NULL, 0, flags);
+            rv        = s->handler->parse_packet(s->ic, s->dynamic_protocol_context,
+                                                 s->st, pkt, &timestamp, NULL, 0, 0,
+                                                 flags);
             finalize_packet(s, pkt, timestamp);
             return rv;
-        } else {
-            // TODO: Move to a dynamic packet handler (like above)
-            if (s->read_buf_index >= s->read_buf_size)
-                return AVERROR(EAGAIN);
-            ret = ff_mpegts_parse_packet(s->ts, pkt, s->buf + s->read_buf_index,
-                                      s->read_buf_size - s->read_buf_index);
-            if (ret < 0)
-                return AVERROR(EAGAIN);
-            s->read_buf_index += ret;
-            if (s->read_buf_index < s->read_buf_size)
-                return 1;
-            else
-                return 0;
         }
     }
 
@@ -717,6 +759,16 @@
         return rtcp_parse_packet(s, buf, len);
     }
 
+    if (s->st) {
+        int64_t received = av_gettime();
+        uint32_t arrival_ts = av_rescale_q(received, AV_TIME_BASE_Q,
+                                           s->st->time_base);
+        timestamp = AV_RB32(buf + 4);
+        // Calculate the jitter immediately, before queueing the packet
+        // into the reordering queue.
+        rtcp_update_jitter(&s->statistics, timestamp, arrival_ts);
+    }
+
     if ((s->seq == 0 && !s->queue) || s->queue_size <= 1) {
         /* First packet, or no reordering */
         return rtp_parse_packet_internal(s, pkt, buf, len);
@@ -757,7 +809,10 @@
 int ff_rtp_parse_packet(RTPDemuxContext *s, AVPacket *pkt,
                         uint8_t **bufptr, int len)
 {
-    int rv = rtp_parse_one_packet(s, pkt, bufptr, len);
+    int rv;
+    if (s->srtp_enabled && bufptr && ff_srtp_decrypt(&s->srtp, *bufptr, &len) < 0)
+        return -1;
+    rv = rtp_parse_one_packet(s, pkt, bufptr, len);
     s->prev_ret = rv;
     while (rv == AVERROR(EAGAIN) && has_next_packet(s))
         rv = rtp_parse_queued_packet(s, pkt);
@@ -767,9 +822,7 @@
 void ff_rtp_parse_close(RTPDemuxContext *s)
 {
     ff_rtp_reset_packet_queue(s);
-    if (!strcmp(ff_rtp_enc_name(s->payload_type), "MP2T")) {
-        ff_mpegts_parse_close(s->ts);
-    }
+    ff_srtp_free(&s->srtp);
     av_free(s);
 }
 
@@ -789,14 +842,16 @@
     }
 
     // remove protocol identifier
-    while (*p && *p == ' ') p++; // strip spaces
-    while (*p && *p != ' ') p++; // eat protocol identifier
-    while (*p && *p == ' ') p++; // strip trailing spaces
+    while (*p && *p == ' ')
+        p++;                     // strip spaces
+    while (*p && *p != ' ')
+        p++;                     // eat protocol identifier
+    while (*p && *p == ' ')
+        p++;                     // strip trailing spaces
 
     while (ff_rtsp_next_attr_and_value(&p,
                                        attr, sizeof(attr),
                                        value, value_size)) {
-
         res = parse_fmtp(stream, data, attr, value);
         if (res < 0 && res != AVERROR_PATCHWELCOME) {
             av_free(value);
@@ -811,9 +866,9 @@
 {
     av_init_packet(pkt);
 
-    pkt->size = avio_close_dyn_buf(*dyn_buf, &pkt->data);
+    pkt->size         = avio_close_dyn_buf(*dyn_buf, &pkt->data);
     pkt->stream_index = stream_idx;
     pkt->destruct     = av_destruct_packet;
-    *dyn_buf = NULL;
+    *dyn_buf          = NULL;
     return pkt->size;
 }
diff --git a/libavformat/rtpdec.h b/libavformat/rtpdec.h
index 15d472a..e469c0f 100644
--- a/libavformat/rtpdec.h
+++ b/libavformat/rtpdec.h
@@ -19,6 +19,7 @@
  * 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_RTPDEC_H
 #define AVFORMAT_RTPDEC_H
 
@@ -26,21 +27,25 @@
 #include "avformat.h"
 #include "rtp.h"
 #include "url.h"
+#include "srtp.h"
 
 typedef struct PayloadContext PayloadContext;
-typedef struct RTPDynamicProtocolHandler_s RTPDynamicProtocolHandler;
+typedef struct RTPDynamicProtocolHandler RTPDynamicProtocolHandler;
 
 #define RTP_MIN_PACKET_LENGTH 12
-#define RTP_MAX_PACKET_LENGTH 1500 /* XXX: suppress this define */
+#define RTP_MAX_PACKET_LENGTH 1500
 
 #define RTP_REORDER_QUEUE_DEFAULT_SIZE 10
 
 #define RTP_NOTS_VALUE ((uint32_t)-1)
 
 typedef struct RTPDemuxContext RTPDemuxContext;
-RTPDemuxContext *ff_rtp_parse_open(AVFormatContext *s1, AVStream *st, URLContext *rtpc, int payload_type, int queue_size);
+RTPDemuxContext *ff_rtp_parse_open(AVFormatContext *s1, AVStream *st,
+                                   int payload_type, int queue_size);
 void ff_rtp_parse_set_dynamic_protocol(RTPDemuxContext *s, PayloadContext *ctx,
                                        RTPDynamicProtocolHandler *handler);
+void ff_rtp_parse_set_crypto(RTPDemuxContext *s, const char *suite,
+                             const char *params);
 int ff_rtp_parse_packet(RTPDemuxContext *s, AVPacket *pkt,
                         uint8_t **buf, int len);
 void ff_rtp_parse_close(RTPDemuxContext *s);
@@ -66,10 +71,13 @@
 
 /**
  * some rtp servers assume client is dead if they don't hear from them...
- * so we send a Receiver Report to the provided ByteIO context
+ * so we send a Receiver Report to the provided URLContext or AVIOContext
  * (we don't have access to the rtcp handle from here)
  */
-int ff_rtp_check_and_send_back_rr(RTPDemuxContext *s, int count);
+int ff_rtp_check_and_send_back_rr(RTPDemuxContext *s, URLContext *fd,
+                                  AVIOContext *avio, int count);
+int ff_rtp_send_rtcp_feedback(RTPDemuxContext *s, URLContext *fd,
+                              AVIOContext *avio);
 
 // these statistics are used for rtcp receiver reports...
 typedef struct RTPStatistics {
@@ -78,9 +86,9 @@
     uint32_t base_seq;          ///< base sequence number
     uint32_t bad_seq;           ///< last bad sequence number + 1
     int probation;              ///< sequence packets till source is valid
-    int received;               ///< packets received
-    int expected_prior;         ///< packets expected in last interval
-    int received_prior;         ///< packets received in last interval
+    uint32_t received;          ///< packets received
+    uint32_t expected_prior;    ///< packets expected in last interval
+    uint32_t received_prior;    ///< packets received in last interval
     uint32_t transit;           ///< relative transit time for previous packet
     uint32_t jitter;            ///< estimated jitter.
 } RTPStatistics;
@@ -94,39 +102,42 @@
  * @param s stream context
  * @param st stream that this packet belongs to
  * @param pkt packet in which to write the parsed data
- * @param timestamp pointer in which to write the timestamp of this RTP packet
+ * @param timestamp pointer to the RTP timestamp of the input data, can be
+ *                  updated by the function if returning older, buffered data
  * @param buf pointer to raw RTP packet data
  * @param len length of buf
+ * @param seq RTP sequence number of the packet
  * @param flags flags from the RTP packet header (RTP_FLAG_*)
  */
-typedef int (*DynamicPayloadPacketHandlerProc) (AVFormatContext *ctx,
-                                                PayloadContext *s,
-                                                AVStream *st,
-                                                AVPacket * pkt,
-                                                uint32_t *timestamp,
-                                                const uint8_t * buf,
-                                                int len, int flags);
+typedef int (*DynamicPayloadPacketHandlerProc)(AVFormatContext *ctx,
+                                               PayloadContext *s,
+                                               AVStream *st, AVPacket *pkt,
+                                               uint32_t *timestamp,
+                                               const uint8_t * buf,
+                                               int len, uint16_t seq, int flags);
 
-struct RTPDynamicProtocolHandler_s {
-    // fields from AVRtpDynamicPayloadType_s
-    const char enc_name[50];    /* XXX: still why 50 ? ;-) */
+struct RTPDynamicProtocolHandler {
+    const char enc_name[50];
     enum AVMediaType codec_type;
     enum AVCodecID codec_id;
     int static_payload_id; /* 0 means no payload id is set. 0 is a valid
                             * payload ID (PCMU), too, but that format doesn't
                             * require any custom depacketization code. */
 
-    // may be null
-    int (*init)(AVFormatContext *s, int st_index, PayloadContext *priv_data); ///< Initialize dynamic protocol handler, called after the full rtpmap line is parsed
-    int (*parse_sdp_a_line) (AVFormatContext *s,
-                             int st_index,
-                             PayloadContext *priv_data,
-                             const char *line); ///< Parse the a= line from the sdp field
-    PayloadContext *(*alloc) (void); ///< allocate any data needed by the rtp parsing for this dynamic data.
-    void (*free)(PayloadContext *protocol_data); ///< free any data needed by the rtp parsing for this dynamic data.
-    DynamicPayloadPacketHandlerProc parse_packet; ///< parse handler for this dynamic packet.
+    /** Initialize dynamic protocol handler, called after the full rtpmap line is parsed, may be null */
+    int (*init)(AVFormatContext *s, int st_index, PayloadContext *priv_data);
+    /** Parse the a= line from the sdp field */
+    int (*parse_sdp_a_line)(AVFormatContext *s, int st_index,
+                            PayloadContext *priv_data, const char *line);
+    /** Allocate any data needed by the rtp parsing for this dynamic data. */
+    PayloadContext *(*alloc)(void);
+    /** Free any data needed by the rtp parsing for this dynamic data. */
+    void (*free)(PayloadContext *protocol_data);
+    /** Parse handler for this dynamic packet */
+    DynamicPayloadPacketHandlerProc parse_packet;
+    int (*need_keyframe)(PayloadContext *context);
 
-    struct RTPDynamicProtocolHandler_s *next;
+    struct RTPDynamicProtocolHandler *next;
 };
 
 typedef struct RTPPacket {
@@ -137,7 +148,6 @@
     struct RTPPacket *next;
 } RTPPacket;
 
-// moved out of rtp.c, because the h264 decoder needs to know about this structure..
 struct RTPDemuxContext {
     AVFormatContext *ic;
     AVStream *st;
@@ -150,14 +160,14 @@
     int64_t  unwrapped_timestamp;
     int64_t  range_start_offset;
     int max_payload_size;
-    struct MpegTSContext *ts;   /* only used for MP2T payloads */
-    int read_buf_index;
-    int read_buf_size;
     /* used to send back RTCP RR */
-    URLContext *rtp_ctx;
     char hostname[256];
 
-    RTPStatistics statistics; ///< Statistics for this stream (used by RTCP receiver reports)
+    int srtp_enabled;
+    struct SRTPContext srtp;
+
+    /** Statistics for this stream (used by RTCP receiver reports) */
+    RTPStatistics statistics;
 
     /** Fields for packet reordering @{ */
     int prev_ret;     ///< The return value of the actual parsing of the previous packet
@@ -167,24 +177,21 @@
     /*@}*/
 
     /* rtcp sender statistics receive */
-    int64_t last_rtcp_ntp_time;    // TODO: move into statistics
-    int64_t first_rtcp_ntp_time;   // TODO: move into statistics
-    uint32_t last_rtcp_timestamp;  // TODO: move into statistics
+    int64_t last_rtcp_ntp_time;
+    int64_t last_rtcp_reception_time;
+    int64_t first_rtcp_ntp_time;
+    uint32_t last_rtcp_timestamp;
     int64_t rtcp_ts_offset;
 
     /* rtcp sender statistics */
-    unsigned int packet_count;     // TODO: move into statistics (outgoing)
-    unsigned int octet_count;      // TODO: move into statistics (outgoing)
-    unsigned int last_octet_count; // TODO: move into statistics (outgoing)
-    int first_packet;
-    /* buffer for output */
-    uint8_t buf[RTP_MAX_PACKET_LENGTH];
-    uint8_t *buf_ptr;
+    unsigned int packet_count;
+    unsigned int octet_count;
+    unsigned int last_octet_count;
+    int64_t last_feedback_time;
 
     /* dynamic payload stuff */
-    DynamicPayloadPacketHandlerProc parse_packet;     ///< This is also copied from the dynamic protocol handler structure
-    PayloadContext *dynamic_protocol_context;        ///< This is a copy from the values setup from the sdp parsing, in rtsp.c don't free me.
-    int max_frames_per_packet;
+    const RTPDynamicProtocolHandler *handler;
+    PayloadContext *dynamic_protocol_context;
 };
 
 void ff_register_dynamic_payload_handler(RTPDynamicProtocolHandler *handler);
@@ -193,7 +200,9 @@
 RTPDynamicProtocolHandler *ff_rtp_handler_find_by_id(int id,
                                                 enum AVMediaType codec_type);
 
-int ff_rtsp_next_attr_and_value(const char **p, char *attr, int attr_size, char *value, int value_size); ///< from rtsp.c, but used by rtp dynamic protocol handlers.
+/* from rtsp.c, but used by rtp dynamic protocol handlers. */
+int ff_rtsp_next_attr_and_value(const char **p, char *attr, int attr_size,
+                                char *value, int value_size);
 
 int ff_parse_fmtp(AVStream *stream, PayloadContext *data, const char *p,
                   int (*parse_fmtp)(AVStream *stream,
diff --git a/libavformat/rtpdec_amr.c b/libavformat/rtpdec_amr.c
index 3f5e775..211cf17 100644
--- a/libavformat/rtpdec_amr.c
+++ b/libavformat/rtpdec_amr.c
@@ -51,13 +51,10 @@
     av_free(data);
 }
 
-static int amr_handle_packet(AVFormatContext *ctx,
-                             PayloadContext *data,
-                             AVStream *st,
-                             AVPacket * pkt,
-                             uint32_t * timestamp,
-                             const uint8_t * buf,
-                             int len, int flags)
+static int amr_handle_packet(AVFormatContext *ctx, PayloadContext *data,
+                             AVStream *st, AVPacket *pkt, uint32_t *timestamp,
+                             const uint8_t *buf, int len, uint16_t seq,
+                             int flags)
 {
     const uint8_t *frame_sizes = NULL;
     int frames;
diff --git a/libavformat/rtpdec_asf.c b/libavformat/rtpdec_asf.c
index e37fde7..35603f2 100644
--- a/libavformat/rtpdec_asf.c
+++ b/libavformat/rtpdec_asf.c
@@ -168,7 +168,8 @@
 static int asfrtp_parse_packet(AVFormatContext *s, PayloadContext *asf,
                                AVStream *st, AVPacket *pkt,
                                uint32_t *timestamp,
-                               const uint8_t *buf, int len, int flags)
+                               const uint8_t *buf, int len, uint16_t seq,
+                               int flags)
 {
     AVIOContext *pb = &asf->pb;
     int res, mflags, len_off;
diff --git a/libavformat/rtpdec_formats.h b/libavformat/rtpdec_formats.h
index 471888b..9caeb5c 100644
--- a/libavformat/rtpdec_formats.h
+++ b/libavformat/rtpdec_formats.h
@@ -33,7 +33,7 @@
 
 int ff_h263_handle_packet(AVFormatContext *ctx, PayloadContext *data,
                           AVStream *st, AVPacket *pkt, uint32_t *timestamp,
-                          const uint8_t *buf, int len, int flags);
+                          const uint8_t *buf, int len, uint16_t seq, int flags);
 
 extern RTPDynamicProtocolHandler ff_amr_nb_dynamic_handler;
 extern RTPDynamicProtocolHandler ff_amr_wb_dynamic_handler;
@@ -49,7 +49,10 @@
 extern RTPDynamicProtocolHandler ff_jpeg_dynamic_handler;
 extern RTPDynamicProtocolHandler ff_mp4a_latm_dynamic_handler;
 extern RTPDynamicProtocolHandler ff_mp4v_es_dynamic_handler;
+extern RTPDynamicProtocolHandler ff_mpeg_audio_dynamic_handler;
+extern RTPDynamicProtocolHandler ff_mpeg_video_dynamic_handler;
 extern RTPDynamicProtocolHandler ff_mpeg4_generic_dynamic_handler;
+extern RTPDynamicProtocolHandler ff_mpegts_dynamic_handler;
 extern RTPDynamicProtocolHandler ff_ms_rtp_asf_pfa_handler;
 extern RTPDynamicProtocolHandler ff_ms_rtp_asf_pfv_handler;
 extern RTPDynamicProtocolHandler ff_qcelp_dynamic_handler;
diff --git a/libavformat/rtpdec_h263.c b/libavformat/rtpdec_h263.c
index e604dc1..dd7aa60 100644
--- a/libavformat/rtpdec_h263.c
+++ b/libavformat/rtpdec_h263.c
@@ -23,9 +23,17 @@
 #include "rtpdec_formats.h"
 #include "libavutil/intreadwrite.h"
 
+static int h263_init(AVFormatContext *ctx, int st_index, PayloadContext *data)
+{
+    if (st_index < 0)
+        return 0;
+    ctx->streams[st_index]->need_parsing = AVSTREAM_PARSE_FULL;
+    return 0;
+}
+
 int ff_h263_handle_packet(AVFormatContext *ctx, PayloadContext *data,
                           AVStream *st, AVPacket *pkt, uint32_t *timestamp,
-                          const uint8_t *buf, int len, int flags)
+                          const uint8_t *buf, int len, uint16_t seq, int flags)
 {
     uint8_t *ptr;
     uint16_t header;
@@ -92,6 +100,7 @@
     .enc_name         = "H263-1998",
     .codec_type       = AVMEDIA_TYPE_VIDEO,
     .codec_id         = AV_CODEC_ID_H263,
+    .init             = h263_init,
     .parse_packet     = ff_h263_handle_packet,
 };
 
@@ -99,5 +108,6 @@
     .enc_name         = "H263-2000",
     .codec_type       = AVMEDIA_TYPE_VIDEO,
     .codec_id         = AV_CODEC_ID_H263,
+    .init             = h263_init,
     .parse_packet     = ff_h263_handle_packet,
 };
diff --git a/libavformat/rtpdec_h263_rfc2190.c b/libavformat/rtpdec_h263_rfc2190.c
index 4957b33..4b6e996 100644
--- a/libavformat/rtpdec_h263_rfc2190.c
+++ b/libavformat/rtpdec_h263_rfc2190.c
@@ -55,9 +55,18 @@
     av_free(data);
 }
 
+static int h263_init(AVFormatContext *ctx, int st_index, PayloadContext *data)
+{
+    if (st_index < 0)
+        return 0;
+    ctx->streams[st_index]->need_parsing = AVSTREAM_PARSE_FULL;
+    return 0;
+}
+
 static int h263_handle_packet(AVFormatContext *ctx, PayloadContext *data,
                               AVStream *st, AVPacket *pkt, uint32_t *timestamp,
-                              const uint8_t *buf, int len, int flags)
+                              const uint8_t *buf, int len, uint16_t seq,
+                              int flags)
 {
     /* Corresponding to header fields in the RFC */
     int f, p, i, sbit, ebit, src, r;
@@ -65,7 +74,7 @@
 
     if (data->newformat)
         return ff_h263_handle_packet(ctx, data, st, pkt, timestamp, buf, len,
-                                     flags);
+                                     seq, flags);
 
     if (data->buf && data->timestamp != *timestamp) {
         /* Dropping old buffered, unfinished data */
@@ -122,7 +131,7 @@
                    "signalled with a static payload type.\n");
             data->newformat = 1;
             return ff_h263_handle_packet(ctx, data, st, pkt, timestamp, buf,
-                                         len, flags);
+                                         len, seq, flags);
         }
     }
 
@@ -197,6 +206,7 @@
 RTPDynamicProtocolHandler ff_h263_rfc2190_dynamic_handler = {
     .codec_type        = AVMEDIA_TYPE_VIDEO,
     .codec_id          = AV_CODEC_ID_H263,
+    .init              = h263_init,
     .parse_packet      = h263_handle_packet,
     .alloc             = h263_new_context,
     .free              = h263_free_context,
diff --git a/libavformat/rtpdec_h264.c b/libavformat/rtpdec_h264.c
index 083f8e8..d1133b7 100644
--- a/libavformat/rtpdec_h264.c
+++ b/libavformat/rtpdec_h264.c
@@ -165,7 +165,8 @@
 // return 0 on packet, no more left, 1 on packet, 1 on partial packet
 static int h264_handle_packet(AVFormatContext *ctx, PayloadContext *data,
                               AVStream *st, AVPacket *pkt, uint32_t *timestamp,
-                              const uint8_t *buf, int len, int flags)
+                              const uint8_t *buf, int len, uint16_t seq,
+                              int flags)
 {
     uint8_t nal;
     uint8_t type;
@@ -337,6 +338,14 @@
     av_free(data);
 }
 
+static int h264_init(AVFormatContext *s, int st_index, PayloadContext *data)
+{
+    if (st_index < 0)
+        return 0;
+    s->streams[st_index]->need_parsing = AVSTREAM_PARSE_FULL;
+    return 0;
+}
+
 static int parse_h264_sdp_line(AVFormatContext *s, int st_index,
                                PayloadContext *h264_data, const char *line)
 {
@@ -382,6 +391,7 @@
     .enc_name         = "H264",
     .codec_type       = AVMEDIA_TYPE_VIDEO,
     .codec_id         = AV_CODEC_ID_H264,
+    .init             = h264_init,
     .parse_sdp_a_line = parse_h264_sdp_line,
     .alloc            = h264_new_context,
     .free             = h264_free_context,
diff --git a/libavformat/rtpdec_jpeg.c b/libavformat/rtpdec_jpeg.c
index 447dd36..80fe295 100644
--- a/libavformat/rtpdec_jpeg.c
+++ b/libavformat/rtpdec_jpeg.c
@@ -219,7 +219,8 @@
 
 static int jpeg_parse_packet(AVFormatContext *ctx, PayloadContext *jpeg,
                              AVStream *st, AVPacket *pkt, uint32_t *timestamp,
-                             const uint8_t *buf, int len, int flags)
+                             const uint8_t *buf, int len, uint16_t seq,
+                             int flags)
 {
     uint8_t type, q, width, height;
     const uint8_t *qtables = NULL;
@@ -370,7 +371,7 @@
         /* Prepare the JPEG packet. */
         if ((ret = ff_rtp_finalize_packet(pkt, &jpeg->frame, st->index)) < 0) {
             av_log(ctx, AV_LOG_ERROR,
-                   "Error occured when getting frame buffer.\n");
+                   "Error occurred when getting frame buffer.\n");
             return ret;
         }
 
diff --git a/libavformat/rtpdec_latm.c b/libavformat/rtpdec_latm.c
index 2ea141b..bacc186 100644
--- a/libavformat/rtpdec_latm.c
+++ b/libavformat/rtpdec_latm.c
@@ -51,7 +51,8 @@
 
 static int latm_parse_packet(AVFormatContext *ctx, PayloadContext *data,
                              AVStream *st, AVPacket *pkt, uint32_t *timestamp,
-                             const uint8_t *buf, int len, int flags)
+                             const uint8_t *buf, int len, uint16_t seq,
+                             int flags)
 {
     int ret, cur_len;
 
diff --git a/libavformat/rtpdec_mpeg12.c b/libavformat/rtpdec_mpeg12.c
new file mode 100644
index 0000000..82e58a0
--- /dev/null
+++ b/libavformat/rtpdec_mpeg12.c
@@ -0,0 +1,72 @@
+/*
+ * Common code for the RTP depacketization of MPEG-1/2 formats.
+ * Copyright (c) 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 "rtpdec_formats.h"
+#include "libavutil/intreadwrite.h"
+
+static int mpeg_init(AVFormatContext *ctx, int st_index, PayloadContext *data)
+{
+    if (st_index < 0)
+        return 0;
+    ctx->streams[st_index]->need_parsing = AVSTREAM_PARSE_FULL;
+    return 0;
+}
+
+static int mpeg_parse_packet(AVFormatContext *ctx, PayloadContext *data,
+                             AVStream *st, AVPacket *pkt, uint32_t *timestamp,
+                             const uint8_t *buf, int len, uint16_t seq,
+                             int flags)
+{
+    unsigned int h;
+    if (len <= 4)
+        return AVERROR_INVALIDDATA;
+    h    = AV_RB32(buf);
+    buf += 4;
+    len -= 4;
+    if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && h & (1 << 26)) {
+        /* MPEG-2 */
+        if (len <= 4)
+            return AVERROR_INVALIDDATA;
+        buf += 4;
+        len -= 4;
+    }
+    if (av_new_packet(pkt, len) < 0)
+        return AVERROR(ENOMEM);
+    memcpy(pkt->data, buf, len);
+    pkt->stream_index = st->index;
+    return 0;
+}
+
+RTPDynamicProtocolHandler ff_mpeg_audio_dynamic_handler = {
+    .codec_type        = AVMEDIA_TYPE_AUDIO,
+    .codec_id          = AV_CODEC_ID_MP3,
+    .init              = mpeg_init,
+    .parse_packet      = mpeg_parse_packet,
+    .static_payload_id = 14,
+};
+
+RTPDynamicProtocolHandler ff_mpeg_video_dynamic_handler = {
+    .codec_type        = AVMEDIA_TYPE_VIDEO,
+    .codec_id          = AV_CODEC_ID_MPEG2VIDEO,
+    .init              = mpeg_init,
+    .parse_packet      = mpeg_parse_packet,
+    .static_payload_id = 32,
+};
diff --git a/libavformat/rtpdec_mpeg4.c b/libavformat/rtpdec_mpeg4.c
index a647169..3f1f244 100644
--- a/libavformat/rtpdec_mpeg4.c
+++ b/libavformat/rtpdec_mpeg4.c
@@ -32,9 +32,8 @@
 #include "libavutil/avstring.h"
 #include "libavcodec/get_bits.h"
 
-/** Structure listing useful vars to parse RTP packet payload*/
-struct PayloadContext
-{
+/** Structure listing useful vars to parse RTP packet payload */
+struct PayloadContext {
     int sizelength;
     int indexlength;
     int indexdeltalength;
@@ -58,6 +57,9 @@
     int nb_au_headers;
     int au_headers_length_bytes;
     int cur_au_index;
+
+    uint8_t buf[RTP_MAX_PACKET_LENGTH];
+    int buf_pos, buf_size;
 };
 
 typedef struct {
@@ -69,8 +71,7 @@
 /* All known fmtp parameters and the corresponding RTPAttrTypeEnum */
 #define ATTR_NAME_TYPE_INT 0
 #define ATTR_NAME_TYPE_STR 1
-static const AttrNameMap attr_names[]=
-{
+static const AttrNameMap attr_names[] = {
     { "SizeLength",       ATTR_NAME_TYPE_INT,
       offsetof(PayloadContext, sizelength) },
     { "IndexLength",      ATTR_NAME_TYPE_INT,
@@ -91,14 +92,14 @@
     return av_mallocz(sizeof(PayloadContext));
 }
 
-static void free_context(PayloadContext * data)
+static void free_context(PayloadContext *data)
 {
     av_free(data->au_headers);
     av_free(data->mode);
     av_free(data);
 }
 
-static int parse_fmtp_config(AVCodecContext * codec, char *value)
+static int parse_fmtp_config(AVCodecContext *codec, char *value)
 {
     /* decode the hexa encoded parameter */
     int len = ff_hex_to_data(NULL, value);
@@ -111,11 +112,14 @@
     return 0;
 }
 
-static int rtp_parse_mp4_au(PayloadContext *data, const uint8_t *buf)
+static int rtp_parse_mp4_au(PayloadContext *data, const uint8_t *buf, int len)
 {
     int au_headers_length, au_header_size, i;
     GetBitContext getbitcontext;
 
+    if (len < 2)
+        return AVERROR_INVALIDDATA;
+
     /* decode the first 2 bytes where the AUHeader sections are stored
        length in bits */
     au_headers_length = AV_RB16(buf);
@@ -127,6 +131,10 @@
 
     /* skip AU headers length section (2 bytes) */
     buf += 2;
+    len -= 2;
+
+    if (len < data->au_headers_length_bytes)
+        return AVERROR_INVALIDDATA;
 
     init_get_bits(&getbitcontext, buf, data->au_headers_length_bytes * 8);
 
@@ -139,45 +147,65 @@
     if (!data->au_headers || data->au_headers_allocated < data->nb_au_headers) {
         av_free(data->au_headers);
         data->au_headers = av_malloc(sizeof(struct AUHeaders) * data->nb_au_headers);
+        if (!data->au_headers)
+            return AVERROR(ENOMEM);
         data->au_headers_allocated = data->nb_au_headers;
     }
 
-    /* XXX: We handle multiple AU Section as only one (need to fix this for interleaving)
-       In my test, the FAAD decoder does not behave correctly when sending each AU one by one
-       but does when sending the whole as one big packet...  */
-    data->au_headers[0].size = 0;
-    data->au_headers[0].index = 0;
     for (i = 0; i < data->nb_au_headers; ++i) {
-        data->au_headers[0].size += get_bits_long(&getbitcontext, data->sizelength);
-        data->au_headers[0].index = get_bits_long(&getbitcontext, data->indexlength);
+        data->au_headers[i].size  = get_bits_long(&getbitcontext, data->sizelength);
+        data->au_headers[i].index = get_bits_long(&getbitcontext, data->indexlength);
     }
 
-    data->nb_au_headers = 1;
-
     return 0;
 }
 
 
 /* Follows RFC 3640 */
-static int aac_parse_packet(AVFormatContext *ctx,
-                            PayloadContext *data,
-                            AVStream *st,
-                            AVPacket *pkt,
-                            uint32_t *timestamp,
-                            const uint8_t *buf, int len, int flags)
+static int aac_parse_packet(AVFormatContext *ctx, PayloadContext *data,
+                            AVStream *st, AVPacket *pkt, uint32_t *timestamp,
+                            const uint8_t *buf, int len, uint16_t seq,
+                            int flags)
 {
-    if (rtp_parse_mp4_au(data, buf))
+    int ret;
+
+    if (!buf) {
+        if (data->cur_au_index > data->nb_au_headers)
+            return AVERROR_INVALIDDATA;
+        if (data->buf_size - data->buf_pos < data->au_headers[data->cur_au_index].size)
+            return AVERROR_INVALIDDATA;
+        if ((ret = av_new_packet(pkt, data->au_headers[data->cur_au_index].size)) < 0)
+            return ret;
+        memcpy(pkt->data, &data->buf[data->buf_pos], data->au_headers[data->cur_au_index].size);
+        data->buf_pos += data->au_headers[data->cur_au_index].size;
+        pkt->stream_index = st->index;
+        data->cur_au_index++;
+        return data->cur_au_index < data->nb_au_headers;
+    }
+
+    if (rtp_parse_mp4_au(data, buf, len))
         return -1;
 
     buf += data->au_headers_length_bytes + 2;
     len -= data->au_headers_length_bytes + 2;
 
-    /* XXX: Fixme we only handle the case where rtp_parse_mp4_au define
-                    one au_header */
-    av_new_packet(pkt, data->au_headers[0].size);
+    if (len < data->au_headers[0].size)
+        return AVERROR_INVALIDDATA;
+    if ((ret = av_new_packet(pkt, data->au_headers[0].size)) < 0)
+        return ret;
     memcpy(pkt->data, buf, data->au_headers[0].size);
-
+    len -= data->au_headers[0].size;
+    buf += data->au_headers[0].size;
     pkt->stream_index = st->index;
+
+    if (len > 0 && data->nb_au_headers > 1) {
+        data->buf_size = FFMIN(len, sizeof(data->buf));
+        memcpy(data->buf, buf, data->buf_size);
+        data->cur_au_index = 1;
+        data->buf_pos = 0;
+        return 1;
+    }
+
     return 0;
 }
 
@@ -224,10 +252,19 @@
     return 0;
 }
 
+static int init_video(AVFormatContext *s, int st_index, PayloadContext *data)
+{
+    if (st_index < 0)
+        return 0;
+    s->streams[st_index]->need_parsing = AVSTREAM_PARSE_FULL;
+    return 0;
+}
+
 RTPDynamicProtocolHandler ff_mp4v_es_dynamic_handler = {
     .enc_name           = "MP4V-ES",
     .codec_type         = AVMEDIA_TYPE_VIDEO,
     .codec_id           = AV_CODEC_ID_MPEG4,
+    .init               = init_video,
     .parse_sdp_a_line   = parse_sdp_line,
 };
 
diff --git a/libavformat/rtpdec_mpegts.c b/libavformat/rtpdec_mpegts.c
new file mode 100644
index 0000000..cbb8eb4
--- /dev/null
+++ b/libavformat/rtpdec_mpegts.c
@@ -0,0 +1,106 @@
+/*
+ * RTP MPEG2TS depacketizer
+ * Copyright (c) 2003 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 "mpegts.h"
+#include "rtpdec_formats.h"
+
+struct PayloadContext {
+    struct MpegTSContext *ts;
+    int read_buf_index;
+    int read_buf_size;
+    uint8_t buf[RTP_MAX_PACKET_LENGTH];
+};
+
+static PayloadContext *mpegts_new_context(void)
+{
+    return av_mallocz(sizeof(PayloadContext));
+}
+
+static void mpegts_free_context(PayloadContext *data)
+{
+    if (!data)
+        return;
+    if (data->ts)
+        ff_mpegts_parse_close(data->ts);
+    av_free(data);
+}
+
+static int mpegts_init(AVFormatContext *ctx, int st_index, PayloadContext *data)
+{
+    data->ts = ff_mpegts_parse_open(ctx);
+    if (!data->ts)
+        return AVERROR(ENOMEM);
+    return 0;
+}
+
+static int mpegts_handle_packet(AVFormatContext *ctx, PayloadContext *data,
+                                AVStream *st, AVPacket *pkt, uint32_t *timestamp,
+                                const uint8_t *buf, int len, uint16_t seq,
+                                int flags)
+{
+    int ret;
+
+    // We don't want to use the RTP timestamps at all. If the mpegts demuxer
+    // doesn't set any pts/dts, the generic rtpdec code shouldn't try to
+    // fill it in either, since the mpegts and RTP timestamps are in totally
+    // different ranges.
+    *timestamp = RTP_NOTS_VALUE;
+
+    if (!data->ts)
+        return AVERROR(EINVAL);
+
+    if (!buf) {
+        if (data->read_buf_index >= data->read_buf_size)
+            return AVERROR(EAGAIN);
+        ret = ff_mpegts_parse_packet(data->ts, pkt, data->buf + data->read_buf_index,
+                                     data->read_buf_size - data->read_buf_index);
+        if (ret < 0)
+            return AVERROR(EAGAIN);
+        data->read_buf_index += ret;
+        if (data->read_buf_index < data->read_buf_size)
+            return 1;
+        else
+            return 0;
+    }
+
+    ret = ff_mpegts_parse_packet(data->ts, pkt, buf, len);
+    /* The only error that can be returned from ff_mpegts_parse_packet
+     * is "no more data to return from the provided buffer", so return
+     * AVERROR(EAGAIN) for all errors */
+    if (ret < 0)
+        return AVERROR(EAGAIN);
+    if (ret < len) {
+        data->read_buf_size = FFMIN(len - ret, sizeof(data->buf));
+        memcpy(data->buf, buf + ret, data->read_buf_size);
+        data->read_buf_index = 0;
+        return 1;
+    }
+    return 0;
+}
+
+RTPDynamicProtocolHandler ff_mpegts_dynamic_handler = {
+    .codec_type        = AVMEDIA_TYPE_DATA,
+    .parse_packet      = mpegts_handle_packet,
+    .alloc             = mpegts_new_context,
+    .init              = mpegts_init,
+    .free              = mpegts_free_context,
+    .static_payload_id = 33,
+};
diff --git a/libavformat/rtpdec_qcelp.c b/libavformat/rtpdec_qcelp.c
index 7e1d0b7..eebcdd0 100644
--- a/libavformat/rtpdec_qcelp.c
+++ b/libavformat/rtpdec_qcelp.c
@@ -210,7 +210,8 @@
 
 static int qcelp_parse_packet(AVFormatContext *ctx, PayloadContext *data,
                               AVStream *st, AVPacket *pkt, uint32_t *timestamp,
-                              const uint8_t *buf, int len, int flags)
+                              const uint8_t *buf, int len, uint16_t seq,
+                              int flags)
 {
     if (buf)
         return store_packet(ctx, data, st, pkt, timestamp, buf, len);
diff --git a/libavformat/rtpdec_qdm2.c b/libavformat/rtpdec_qdm2.c
index 3a8ffd5..6ce776d 100644
--- a/libavformat/rtpdec_qdm2.c
+++ b/libavformat/rtpdec_qdm2.c
@@ -238,7 +238,8 @@
 static int qdm2_parse_packet(AVFormatContext *s, PayloadContext *qdm,
                              AVStream *st, AVPacket *pkt,
                              uint32_t *timestamp,
-                             const uint8_t *buf, int len, int flags)
+                             const uint8_t *buf, int len, uint16_t seq,
+                             int flags)
 {
     int res = AVERROR_INVALIDDATA, n;
     const uint8_t *end = buf + len, *p = buf;
diff --git a/libavformat/rtpdec_qt.c b/libavformat/rtpdec_qt.c
index f0f01d9..9631b0a 100644
--- a/libavformat/rtpdec_qt.c
+++ b/libavformat/rtpdec_qt.c
@@ -42,7 +42,7 @@
 static int qt_rtp_parse_packet(AVFormatContext *s, PayloadContext *qt,
                                AVStream *st, AVPacket *pkt,
                                uint32_t *timestamp, const uint8_t *buf,
-                               int len, int flags)
+                               int len, uint16_t seq, int flags)
 {
     AVIOContext pb;
     GetBitContext gb;
diff --git a/libavformat/rtpdec_svq3.c b/libavformat/rtpdec_svq3.c
index 779ad8a..106b785 100644
--- a/libavformat/rtpdec_svq3.c
+++ b/libavformat/rtpdec_svq3.c
@@ -41,7 +41,8 @@
 static int svq3_parse_packet (AVFormatContext *s, PayloadContext *sv,
                               AVStream *st, AVPacket *pkt,
                               uint32_t *timestamp,
-                              const uint8_t *buf, int len, int flags)
+                              const uint8_t *buf, int len, uint16_t seq,
+                              int flags)
 {
     int config_packet, start_packet, end_packet;
 
diff --git a/libavformat/rtpdec_vp8.c b/libavformat/rtpdec_vp8.c
index 1edc152..623d359 100644
--- a/libavformat/rtpdec_vp8.c
+++ b/libavformat/rtpdec_vp8.c
@@ -33,21 +33,69 @@
 
 struct PayloadContext {
     AVIOContext *data;
-    uint32_t       timestamp;
+    uint32_t     timestamp;
+    int          is_keyframe;
+    /* If sequence_ok is set, we keep returning data (even if we might have
+     * lost some data, but we haven't lost any too critical data that would
+     * cause the decoder to desynchronize and output random garbage).
+     */
+    int          sequence_ok;
+    int          first_part_size;
+    uint16_t     prev_seq;
+    int          prev_pictureid;
+    int          broken_frame;
+    /* If sequence_dirty is set, we have lost some data (critical or
+     * non-critical) and decoding will have some sort of artefacts, and
+     * we thus should request a new keyframe.
+     */
+    int          sequence_dirty;
+    int          got_keyframe;
 };
 
-static int vp8_handle_packet(AVFormatContext *ctx,
-                             PayloadContext *vp8,
-                             AVStream *st,
-                             AVPacket *pkt,
-                             uint32_t *timestamp,
-                             const uint8_t *buf,
-                             int len, int flags)
+static void vp8_free_buffer(PayloadContext *vp8)
+{
+    uint8_t *tmp;
+    if (!vp8->data)
+        return;
+    avio_close_dyn_buf(vp8->data, &tmp);
+    av_free(tmp);
+    vp8->data = NULL;
+}
+
+static int vp8_broken_sequence(AVFormatContext *ctx, PayloadContext *vp8,
+                               const char *msg)
+{
+    vp8->sequence_ok = 0;
+    av_log(ctx, AV_LOG_WARNING, "%s", msg);
+    vp8_free_buffer(vp8);
+    return AVERROR(EAGAIN);
+}
+
+static int vp8_handle_packet(AVFormatContext *ctx, PayloadContext *vp8,
+                             AVStream *st, AVPacket *pkt, uint32_t *timestamp,
+                             const uint8_t *buf, int len, uint16_t seq,
+                             int flags)
 {
     int start_partition, end_packet;
     int extended_bits, part_id;
     int pictureid_present = 0, tl0picidx_present = 0, tid_present = 0,
         keyidx_present = 0;
+    int pictureid = -1, pictureid_mask = 0;
+    int returned_old_frame = 0;
+    uint32_t old_timestamp;
+
+    if (!buf) {
+        if (vp8->data) {
+            int ret = ff_rtp_finalize_packet(pkt, &vp8->data, st->index);
+            if (ret < 0)
+                return ret;
+            *timestamp = vp8->timestamp;
+            if (vp8->sequence_dirty)
+                pkt->flags |= AV_PKT_FLAG_CORRUPT;
+            return 0;
+        }
+        return AVERROR(EAGAIN);
+    }
 
     if (len < 1)
         return AVERROR_INVALIDDATA;
@@ -69,12 +117,21 @@
         len--;
     }
     if (pictureid_present) {
-        int size;
         if (len < 1)
             return AVERROR_INVALIDDATA;
-        size = buf[0] & 0x80 ? 2 : 1;
-        buf += size;
-        len -= size;
+        if (buf[0] & 0x80) {
+            if (len < 2)
+                return AVERROR_INVALIDDATA;
+            pictureid = AV_RB16(buf) & 0x7fff;
+            pictureid_mask = 0x7fff;
+            buf += 2;
+            len -= 2;
+        } else {
+            pictureid = buf[0] & 0x7f;
+            pictureid_mask = 0x7f;
+            buf++;
+            len--;
+        }
     }
     if (tl0picidx_present) {
         // Ignoring temporal level zero index
@@ -89,31 +146,121 @@
     if (len < 1)
         return AVERROR_INVALIDDATA;
 
-    if (start_partition && part_id == 0) {
+    if (start_partition && part_id == 0 && len >= 3) {
         int res;
-        if (vp8->data) {
-            uint8_t *tmp;
-            avio_close_dyn_buf(vp8->data, &tmp);
-            av_free(tmp);
-            vp8->data = NULL;
+        int non_key = buf[0] & 0x01;
+        if (!non_key) {
+            vp8_free_buffer(vp8);
+            // Keyframe, decoding ok again
+            vp8->sequence_ok = 1;
+            vp8->sequence_dirty = 0;
+            vp8->got_keyframe = 1;
+        } else {
+            int can_continue = vp8->data && !vp8->is_keyframe &&
+                               avio_tell(vp8->data) >= vp8->first_part_size;
+            if (!vp8->sequence_ok)
+                return AVERROR(EAGAIN);
+            if (!vp8->got_keyframe)
+                return vp8_broken_sequence(ctx, vp8, "Keyframe missing\n");
+            if (pictureid >= 0) {
+                if (pictureid != ((vp8->prev_pictureid + 1) & pictureid_mask)) {
+                    return vp8_broken_sequence(ctx, vp8,
+                                               "Missed a picture, sequence broken\n");
+                } else {
+                    if (vp8->data && !can_continue)
+                        return vp8_broken_sequence(ctx, vp8,
+                                                   "Missed a picture, sequence broken\n");
+                }
+            } else {
+                uint16_t expected_seq = vp8->prev_seq + 1;
+                int16_t diff = seq - expected_seq;
+                if (vp8->data) {
+                    // No picture id, so we can't know if missed packets
+                    // contained any new frames. If diff == 0, we did get
+                    // later packets from the same frame (matching timestamp),
+                    // so we know we didn't miss any frame. If diff == 1 and
+                    // we still have data (not flushed by the end of frame
+                    // marker), the single missed packet must have been part
+                    // of the same frame.
+                    if ((diff == 0 || diff == 1) && can_continue) {
+                        // Proceed with what we have
+                    } else {
+                        return vp8_broken_sequence(ctx, vp8,
+                                                   "Missed too much, sequence broken\n");
+                    }
+                } else {
+                    if (diff != 0)
+                        return vp8_broken_sequence(ctx, vp8,
+                                                   "Missed unknown data, sequence broken\n");
+                }
+            }
+            if (vp8->data) {
+                vp8->sequence_dirty = 1;
+                if (avio_tell(vp8->data) >= vp8->first_part_size) {
+                    int ret = ff_rtp_finalize_packet(pkt, &vp8->data, st->index);
+                    if (ret < 0)
+                        return ret;
+                    pkt->flags |= AV_PKT_FLAG_CORRUPT;
+                    returned_old_frame = 1;
+                    old_timestamp = vp8->timestamp;
+                } else {
+                    // Shouldn't happen
+                    vp8_free_buffer(vp8);
+                }
+            }
         }
+        vp8->first_part_size = (AV_RL16(&buf[1]) << 3 | buf[0] >> 5) + 3;
         if ((res = avio_open_dyn_buf(&vp8->data)) < 0)
             return res;
         vp8->timestamp = *timestamp;
-     }
+        vp8->broken_frame = 0;
+        vp8->prev_pictureid = pictureid;
+        vp8->is_keyframe = !non_key;
+    } else {
+        uint16_t expected_seq = vp8->prev_seq + 1;
 
-    if (!vp8->data || vp8->timestamp != *timestamp) {
-        av_log(ctx, AV_LOG_WARNING,
-               "Received no start marker; dropping frame\n");
-        return AVERROR(EAGAIN);
+        if (!vp8->sequence_ok)
+            return AVERROR(EAGAIN);
+
+        if (vp8->timestamp != *timestamp) {
+            // Missed the start of the new frame, sequence broken
+            return vp8_broken_sequence(ctx, vp8,
+                                       "Received no start marker; dropping frame\n");
+        }
+
+        if (seq != expected_seq) {
+            if (vp8->is_keyframe) {
+                return vp8_broken_sequence(ctx, vp8,
+                                           "Missed part of a keyframe, sequence broken\n");
+            } else if (vp8->data && avio_tell(vp8->data) >= vp8->first_part_size) {
+                vp8->broken_frame = 1;
+                vp8->sequence_dirty = 1;
+            } else {
+                return vp8_broken_sequence(ctx, vp8,
+                                           "Missed part of the first partition, sequence broken\n");
+            }
+        }
     }
 
-    avio_write(vp8->data, buf, len);
+    if (!vp8->data)
+        return vp8_broken_sequence(ctx, vp8, "Received no start marker\n");
+
+    vp8->prev_seq = seq;
+    if (!vp8->broken_frame)
+        avio_write(vp8->data, buf, len);
+
+    if (returned_old_frame) {
+        *timestamp = old_timestamp;
+        return end_packet ? 1 : 0;
+    }
 
     if (end_packet) {
-        int ret = ff_rtp_finalize_packet(pkt, &vp8->data, st->index);
+        int ret;
+        ret = ff_rtp_finalize_packet(pkt, &vp8->data, st->index);
         if (ret < 0)
             return ret;
+        if (vp8->sequence_dirty)
+            pkt->flags |= AV_PKT_FLAG_CORRUPT;
         return 0;
     }
 
@@ -122,19 +269,24 @@
 
 static PayloadContext *vp8_new_context(void)
 {
-    return av_mallocz(sizeof(PayloadContext));
+    PayloadContext *vp8 = av_mallocz(sizeof(PayloadContext));
+    if (!vp8)
+        return NULL;
+    vp8->sequence_ok = 1;
+    return vp8;
 }
 
 static void vp8_free_context(PayloadContext *vp8)
 {
-    if (vp8->data) {
-        uint8_t *tmp;
-        avio_close_dyn_buf(vp8->data, &tmp);
-        av_free(tmp);
-    }
+    vp8_free_buffer(vp8);
     av_free(vp8);
 }
 
+static int vp8_need_keyframe(PayloadContext *vp8)
+{
+    return vp8->sequence_dirty || !vp8->sequence_ok;
+}
+
 RTPDynamicProtocolHandler ff_vp8_dynamic_handler = {
     .enc_name       = "VP8",
     .codec_type     = AVMEDIA_TYPE_VIDEO,
@@ -142,4 +294,5 @@
     .alloc          = vp8_new_context,
     .free           = vp8_free_context,
     .parse_packet   = vp8_handle_packet,
+    .need_keyframe  = vp8_need_keyframe,
 };
diff --git a/libavformat/rtpdec_xiph.c b/libavformat/rtpdec_xiph.c
index ad24c26..eddb781 100644
--- a/libavformat/rtpdec_xiph.c
+++ b/libavformat/rtpdec_xiph.c
@@ -69,12 +69,20 @@
     av_free(data);
 }
 
-static int xiph_handle_packet(AVFormatContext * ctx,
-                              PayloadContext * data,
-                              AVStream * st,
-                              AVPacket * pkt,
-                              uint32_t * timestamp,
-                              const uint8_t * buf, int len, int flags)
+static int xiph_vorbis_init(AVFormatContext *ctx, int st_index,
+                            PayloadContext *data)
+{
+    if (st_index < 0)
+        return 0;
+    ctx->streams[st_index]->need_parsing = AVSTREAM_PARSE_HEADERS;
+    return 0;
+}
+
+
+static int xiph_handle_packet(AVFormatContext *ctx, PayloadContext *data,
+                              AVStream *st, AVPacket *pkt, uint32_t *timestamp,
+                              const uint8_t *buf, int len, uint16_t seq,
+                              int flags)
 {
 
     int ident, fragmented, tdt, num_pkts, pkt_len;
@@ -393,6 +401,7 @@
     .enc_name         = "vorbis",
     .codec_type       = AVMEDIA_TYPE_AUDIO,
     .codec_id         = AV_CODEC_ID_VORBIS,
+    .init             = xiph_vorbis_init,
     .parse_sdp_a_line = xiph_parse_sdp_line,
     .alloc            = xiph_new_context,
     .free             = xiph_free_context,
diff --git a/libavformat/rtpenc.c b/libavformat/rtpenc.c
index 0010a92..7adf687 100644
--- a/libavformat/rtpenc.c
+++ b/libavformat/rtpenc.c
@@ -34,6 +34,8 @@
     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 },
     { "ssrc", "Stream identifier", offsetof(RTPMuxContext, ssrc), AV_OPT_TYPE_INT, { .i64 = 0 }, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
+    { "cname", "CNAME to include in RTCP SR packets", offsetof(RTPMuxContext, cname), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, AV_OPT_FLAG_ENCODING_PARAM },
+    { "seq", "Starting sequence number", offsetof(RTPMuxContext, seq), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 65535, AV_OPT_FLAG_ENCODING_PARAM },
     { NULL },
 };
 
@@ -123,6 +125,16 @@
         /* Round the NTP time to whole milliseconds. */
         s->first_rtcp_ntp_time = (s1->start_time_realtime / 1000) * 1000 +
                                  NTP_OFFSET_US;
+    // Pick a random sequence start number, but in the lower end of the
+    // available range, so that any wraparound doesn't happen immediately.
+    // (Immediate wraparound would be an issue for SRTP.)
+    if (s->seq < 0) {
+        if (st->codec->flags & CODEC_FLAG_BITEXACT) {
+            s->seq = 0;
+        } else
+            s->seq = av_get_random_seed() & 0x0fff;
+    } else
+        s->seq &= 0xffff; // Use the given parameter, wrapped to the right interval
 
     if (s1->packet_size) {
         if (s1->pb->max_packet_size)
@@ -271,6 +283,22 @@
     avio_wb32(s1->pb, rtp_ts);
     avio_wb32(s1->pb, s->packet_count);
     avio_wb32(s1->pb, s->octet_count);
+
+    if (s->cname) {
+        int len = FFMIN(strlen(s->cname), 255);
+        avio_w8(s1->pb, (RTP_VERSION << 6) + 1);
+        avio_w8(s1->pb, RTCP_SDES);
+        avio_wb16(s1->pb, (7 + len + 3) / 4); /* length in words - 1 */
+
+        avio_wb32(s1->pb, s->ssrc);
+        avio_w8(s1->pb, 0x01); /* CNAME */
+        avio_w8(s1->pb, len);
+        avio_write(s1->pb, s->cname, len);
+        avio_w8(s1->pb, 0); /* END */
+        for (len = (7 + len) % 4; len % 4; len++)
+            avio_w8(s1->pb, 0);
+    }
+
     avio_flush(s1->pb);
 }
 
@@ -292,7 +320,7 @@
     avio_write(s1->pb, buf1, len);
     avio_flush(s1->pb);
 
-    s->seq++;
+    s->seq = (s->seq + 1) & 0xffff;
     s->octet_count += len;
     s->packet_count++;
 }
diff --git a/libavformat/rtpenc.h b/libavformat/rtpenc.h
index bc523b4..72a5fa4 100644
--- a/libavformat/rtpenc.h
+++ b/libavformat/rtpenc.h
@@ -30,7 +30,8 @@
     AVStream *st;
     int payload_type;
     uint32_t ssrc;
-    uint16_t seq;
+    const char *cname;
+    int seq;
     uint32_t timestamp;
     uint32_t base_timestamp;
     uint32_t cur_timestamp;
@@ -38,13 +39,13 @@
     int num_frames;
 
     /* rtcp sender statistics receive */
-    int64_t last_rtcp_ntp_time;    // TODO: move into statistics
-    int64_t first_rtcp_ntp_time;   // TODO: move into statistics
+    int64_t last_rtcp_ntp_time;
+    int64_t first_rtcp_ntp_time;
 
     /* rtcp sender statistics */
-    unsigned int packet_count;     // TODO: move into statistics (outgoing)
-    unsigned int octet_count;      // TODO: move into statistics (outgoing)
-    unsigned int last_octet_count; // TODO: move into statistics (outgoing)
+    unsigned int packet_count;
+    unsigned int octet_count;
+    unsigned int last_octet_count;
     int first_packet;
     /* buffer for output */
     uint8_t *buf;
@@ -59,6 +60,8 @@
     int nal_length_size;
 
     int flags;
+
+    unsigned int frame_count;
 };
 
 typedef struct RTPMuxContext RTPMuxContext;
diff --git a/libavformat/rtpenc_chain.c b/libavformat/rtpenc_chain.c
index df7410d..70d68ce 100644
--- a/libavformat/rtpenc_chain.c
+++ b/libavformat/rtpenc_chain.c
@@ -64,7 +64,7 @@
     /* Get the payload type from the codec */
     if (st->id < RTP_PT_PRIVATE)
         rtpctx->streams[0]->id =
-            ff_rtp_get_payload_type(rtpctx, st->codec, idx);
+            ff_rtp_get_payload_type(s, st->codec, idx);
     else
         rtpctx->streams[0]->id = st->id;
 
diff --git a/libavformat/rtpenc_h264.c b/libavformat/rtpenc_h264.c
index 68f4975..b6c16e1 100644
--- a/libavformat/rtpenc_h264.c
+++ b/libavformat/rtpenc_h264.c
@@ -31,14 +31,14 @@
 
 static const uint8_t *avc_mp4_find_startcode(const uint8_t *start, const uint8_t *end, int nal_length_size)
 {
-    int res = 0;
+    unsigned int res = 0;
 
     if (end - start < nal_length_size)
         return NULL;
     while (nal_length_size--)
         res = (res << 8) | *start++;
 
-    if (start + res > end || res < 0 || start + res < start)
+    if (res > end - start)
         return NULL;
 
     return start + res;
diff --git a/libavformat/rtpenc_vp8.c b/libavformat/rtpenc_vp8.c
index d16e676..671d245 100644
--- a/libavformat/rtpenc_vp8.c
+++ b/libavformat/rtpenc_vp8.c
@@ -26,24 +26,30 @@
 void ff_rtp_send_vp8(AVFormatContext *s1, const uint8_t *buf, int size)
 {
     RTPMuxContext *s = s1->priv_data;
-    int len, max_packet_size;
+    int len, max_packet_size, header_size;
 
     s->buf_ptr      = s->buf;
     s->timestamp    = s->cur_timestamp;
-    max_packet_size = s->max_payload_size - 1; // minus one for header byte
 
-    // no extended control bits, reference frame, start of partition,
+    // extended control bit set, reference frame, start of partition,
     // partition id 0
-    *s->buf_ptr++ = 0x10;
+    *s->buf_ptr++ = 0x90;
+    *s->buf_ptr++ = 0x80; // Picture id present
+    *s->buf_ptr++ = s->frame_count++ & 0x7f;
+    // Calculate the number of remaining bytes
+    header_size     = s->buf_ptr - s->buf;
+    max_packet_size = s->max_payload_size - header_size;
+
     while (size > 0) {
         len = FFMIN(size, max_packet_size);
 
         memcpy(s->buf_ptr, buf, len);
-        ff_rtp_send_data(s1, s->buf, len+1, size == len); // marker bit is last packet in frame
+        // marker bit is last packet in frame
+        ff_rtp_send_data(s1, s->buf, len + header_size, size == len);
 
         size         -= len;
         buf          += len;
-        s->buf_ptr    = s->buf;
-        *s->buf_ptr++ = 0; // payload descriptor
+        // Clear the partition start bit, keep the rest of the header untouched
+        s->buf[0]    &= ~0x10;
     }
 }
diff --git a/libavformat/rtpproto.c b/libavformat/rtpproto.c
index 17b0f64..62ec4c9 100644
--- a/libavformat/rtpproto.c
+++ b/libavformat/rtpproto.c
@@ -40,9 +40,6 @@
 #include <sys/poll.h>
 #endif
 
-#define RTP_TX_BUF_SIZE  (64 * 1024)
-#define RTP_RX_BUF_SIZE  (128 * 1024)
-
 typedef struct RTPContext {
     URLContext *rtp_hd, *rtcp_hd;
     int rtp_fd, rtcp_fd;
diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index 04ea47c..317893c 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -97,6 +97,7 @@
 
 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" },
     RTSP_MEDIATYPE_OPTS("allowed_media_types", "Media types to accept from the server"),
     RTSP_REORDERING_OPTS(),
     { NULL },
@@ -180,7 +181,8 @@
 {
     if (!handler)
         return;
-    codec->codec_id          = handler->codec_id;
+    if (codec)
+        codec->codec_id          = handler->codec_id;
     rtsp_st->dynamic_handler = handler;
     if (handler->alloc) {
         rtsp_st->dynamic_protocol_context = handler->alloc();
@@ -200,8 +202,7 @@
     AVCodec *c;
     const char *c_name;
 
-    /* Loop into AVRtpDynamicPayloadTypes[] and AVRtpPayloadTypes[] and
-     * see if we can handle this kind of payload.
+    /* See if we can handle this kind of payload.
      * The space should normally not be there but some Real streams or
      * particular servers ("RealServer Version 6.1.3.970", see issue 1658)
      * have a trailing space. */
@@ -209,7 +210,6 @@
     if (payload_type < RTP_PT_PRIVATE) {
         /* We are in a standard case
          * (from http://www.iana.org/assignments/rtp-parameters). */
-        /* search into AVRtpPayloadTypes[] */
         codec->codec_id = ff_rtp_codec_id(buf, codec->codec_type);
     }
 
@@ -245,10 +245,6 @@
             i = atoi(buf);
             if (i > 0)
                 codec->channels = i;
-            // TODO: there is a bug here; if it is a mono stream, and
-            // less than 22000Hz, faad upconverts to stereo and twice
-            // the frequency.  No problem, but the sample rate is being
-            // set here by the sdp line. Patch on its way. (rdm)
         }
         av_log(s, AV_LOG_DEBUG, "audio samplerate set to: %i\n",
                codec->sample_rate);
@@ -379,6 +375,8 @@
         get_word(buf1, sizeof(buf1), &p); /* protocol */
         if (!strcmp(buf1, "udp"))
             rt->transport = RTSP_TRANSPORT_RAW;
+        else if (strstr(buf1, "/AVPF") || strstr(buf1, "/SAVPF"))
+            rtsp_st->feedback = 1;
 
         /* XXX: handle list of formats */
         get_word(buf1, sizeof(buf1), &p); /* format list */
@@ -386,8 +384,17 @@
 
         if (!strcmp(ff_rtp_enc_name(rtsp_st->sdp_payload_type), "MP2T")) {
             /* no corresponding stream */
-            if (rt->transport == RTSP_TRANSPORT_RAW && !rt->ts && CONFIG_RTPDEC)
-                rt->ts = ff_mpegts_parse_open(s);
+            if (rt->transport == RTSP_TRANSPORT_RAW) {
+                if (!rt->ts && CONFIG_RTPDEC)
+                    rt->ts = ff_mpegts_parse_open(s);
+            } else {
+                RTPDynamicProtocolHandler *handler;
+                handler = ff_rtp_handler_find_by_id(
+                              rtsp_st->sdp_payload_type, AVMEDIA_TYPE_DATA);
+                init_rtp_handler(handler, rtsp_st, NULL);
+                if (handler && handler->init)
+                    handler->init(s, -1, rtsp_st->dynamic_protocol_context);
+            }
         } else if (rt->server_type == RTSP_SERVER_WMS &&
                    codec_type == AVMEDIA_TYPE_DATA) {
             /* RTX stream, a stream that carries all the other actual
@@ -483,6 +490,14 @@
                    s->nb_streams > 0) {
             st = s->streams[s->nb_streams - 1];
             st->codec->sample_rate = atoi(p);
+        } else if (av_strstart(p, "crypto:", &p) && s->nb_streams > 0) {
+            // RFC 4568
+            rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
+            get_word(buf1, sizeof(buf1), &p); // ignore tag
+            get_word(rtsp_st->crypto_suite, sizeof(rtsp_st->crypto_suite), &p);
+            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 (rt->server_type == RTSP_SERVER_WMS)
                 ff_wms_parse_sdp_a_line(s, p);
@@ -644,7 +659,7 @@
                                             rtsp_st->dynamic_protocol_context,
                                             rtsp_st->dynamic_handler);
     else if (CONFIG_RTPDEC)
-        rtsp_st->transport_priv = ff_rtp_parse_open(s, st, rtsp_st->rtp_handle,
+        rtsp_st->transport_priv = ff_rtp_parse_open(s, st,
                                          rtsp_st->sdp_payload_type,
                                          reordering_queue_size);
 
@@ -656,6 +671,10 @@
                                               rtsp_st->dynamic_protocol_context,
                                               rtsp_st->dynamic_handler);
         }
+        if (rtsp_st->crypto_suite[0])
+            ff_rtp_parse_set_crypto(rtsp_st->transport_priv,
+                                    rtsp_st->crypto_suite,
+                                    rtsp_st->crypto_params);
     }
 
     return 0;
@@ -1785,6 +1804,50 @@
     }
 }
 
+static int pick_stream(AVFormatContext *s, RTSPStream **rtsp_st,
+                       const uint8_t *buf, int len)
+{
+    RTSPState *rt = s->priv_data;
+    int i;
+    if (len < 0)
+        return len;
+    if (rt->nb_rtsp_streams == 1) {
+        *rtsp_st = rt->rtsp_streams[0];
+        return len;
+    }
+    if (len >= 8 && rt->transport == RTSP_TRANSPORT_RTP) {
+        if (RTP_PT_IS_RTCP(rt->recvbuf[1])) {
+            int no_ssrc = 0;
+            for (i = 0; i < rt->nb_rtsp_streams; i++) {
+                RTPDemuxContext *rtpctx = rt->rtsp_streams[i]->transport_priv;
+                if (!rtpctx)
+                    continue;
+                if (rtpctx->ssrc == AV_RB32(&buf[4])) {
+                    *rtsp_st = rt->rtsp_streams[i];
+                    return len;
+                }
+                if (!rtpctx->ssrc)
+                    no_ssrc = 1;
+            }
+            if (no_ssrc) {
+                av_log(s, AV_LOG_WARNING,
+                       "Unable to pick stream for packet - SSRC not known for "
+                       "all streams\n");
+                return AVERROR(EAGAIN);
+            }
+        } else {
+            for (i = 0; i < rt->nb_rtsp_streams; i++) {
+                if ((buf[1] & 0x7f) == rt->rtsp_streams[i]->sdp_payload_type) {
+                    *rtsp_st = rt->rtsp_streams[i];
+                    return len;
+                }
+            }
+        }
+    }
+    av_log(s, AV_LOG_WARNING, "Unable to pick stream for packet\n");
+    return AVERROR(EAGAIN);
+}
+
 int ff_rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt)
 {
     RTSPState *rt = s->priv_data;
@@ -1818,6 +1881,7 @@
             rt->cur_transport_priv = NULL;
     }
 
+redo:
     if (rt->transport == RTSP_TRANSPORT_RTP) {
         int i;
         int64_t first_queue_time = 0;
@@ -1833,12 +1897,15 @@
                 first_queue_st   = rt->rtsp_streams[i];
             }
         }
-        if (first_queue_time)
+        if (first_queue_time) {
             wait_end = first_queue_time + s->max_delay;
+        } else {
+            wait_end = 0;
+            first_queue_st = NULL;
+        }
     }
 
     /* read next RTP packet */
- redo:
     if (!rt->recvbuf) {
         rt->recvbuf = av_malloc(RECVBUF_SIZE);
         if (!rt->recvbuf)
@@ -1856,7 +1923,17 @@
     case RTSP_LOWER_TRANSPORT_UDP_MULTICAST:
         len = udp_read_packet(s, &rtsp_st, rt->recvbuf, RECVBUF_SIZE, wait_end);
         if (len > 0 && rtsp_st->transport_priv && rt->transport == RTSP_TRANSPORT_RTP)
-            ff_rtp_check_and_send_back_rr(rtsp_st->transport_priv, len);
+            ff_rtp_check_and_send_back_rr(rtsp_st->transport_priv, rtsp_st->rtp_handle, NULL, len);
+        break;
+    case RTSP_LOWER_TRANSPORT_CUSTOM:
+        if (first_queue_st && rt->transport == RTSP_TRANSPORT_RTP &&
+            wait_end && wait_end < av_gettime())
+            len = AVERROR(EAGAIN);
+        else
+            len = ffio_read_partial(s->pb, rt->recvbuf, RECVBUF_SIZE);
+        len = pick_stream(s, &rtsp_st, rt->recvbuf, len);
+        if (len > 0 && rtsp_st->transport_priv && rt->transport == RTSP_TRANSPORT_RTP)
+            ff_rtp_check_and_send_back_rr(rtsp_st->transport_priv, NULL, s->pb, len);
         break;
     }
     if (len == AVERROR(EAGAIN) && first_queue_st &&
@@ -1873,6 +1950,12 @@
         ret = ff_rdt_parse_packet(rtsp_st->transport_priv, pkt, &rt->recvbuf, len);
     } else if (rt->transport == RTSP_TRANSPORT_RTP) {
         ret = ff_rtp_parse_packet(rtsp_st->transport_priv, pkt, &rt->recvbuf, len);
+        if (rtsp_st->feedback) {
+            AVIOContext *pb = NULL;
+            if (rt->lower_transport == RTSP_LOWER_TRANSPORT_CUSTOM)
+                pb = s->pb;
+            ff_rtp_send_rtcp_feedback(rtsp_st->transport_priv, rtsp_st->rtp_handle, pb);
+        }
         if (ret < 0) {
             /* Either bad packet, or a RTCP packet. Check if the
              * first_rtcp_ntp_time field was initialized. */
@@ -1969,6 +2052,8 @@
 
     if (s->max_delay < 0) /* Not set by the caller */
         s->max_delay = DEFAULT_REORDERING_DELAY;
+    if (rt->rtsp_flags & RTSP_FLAG_CUSTOM_IO)
+        rt->lower_transport = RTSP_LOWER_TRANSPORT_CUSTOM;
 
     /* read the whole sdp file */
     /* XXX: better loading */
@@ -1989,17 +2074,19 @@
         char namebuf[50];
         rtsp_st = rt->rtsp_streams[i];
 
-        getnameinfo((struct sockaddr*) &rtsp_st->sdp_ip, sizeof(rtsp_st->sdp_ip),
-                    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);
-        if (ffurl_open(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE,
-                       &s->interrupt_callback, NULL) < 0) {
-            err = AVERROR_INVALIDDATA;
-            goto fail;
+        if (!(rt->rtsp_flags & RTSP_FLAG_CUSTOM_IO)) {
+            getnameinfo((struct sockaddr*) &rtsp_st->sdp_ip, sizeof(rtsp_st->sdp_ip),
+                        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);
+            if (ffurl_open(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE,
+                           &s->interrupt_callback, NULL) < 0) {
+                err = AVERROR_INVALIDDATA;
+                goto fail;
+            }
         }
         if ((err = ff_rtsp_open_transport_ctx(s, rtsp_st)))
             goto fail;
diff --git a/libavformat/rtsp.h b/libavformat/rtsp.h
index 3a5ad71..321cd7a 100644
--- a/libavformat/rtsp.h
+++ b/libavformat/rtsp.h
@@ -42,6 +42,10 @@
     RTSP_LOWER_TRANSPORT_HTTP = 8,          /**< HTTP tunneled - not a proper
                                                  transport mode as such,
                                                  only for use via AVOptions */
+    RTSP_LOWER_TRANSPORT_CUSTOM = 16,       /**< Custom IO - not a public
+                                                 option for lower_transport_mask,
+                                                 but set in the SDP demuxer based
+                                                 on a flag. */
 };
 
 /**
@@ -396,6 +400,7 @@
                                           receive packets only from the right
                                           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. */
 
 /**
  * Describe a single stream, as identified by a single m= line block in the
@@ -432,6 +437,12 @@
     /** private data associated with the dynamic protocol */
     PayloadContext *dynamic_protocol_context;
     //@}
+
+    /** Enable sending RTCP feedback messages according to RFC 4585 */
+    int feedback;
+
+    char crypto_suite[40];
+    char crypto_params[100];
 } RTSPStream;
 
 void ff_rtsp_parse_line(RTSPMessageHeader *reply, const char *buf,
diff --git a/libavformat/samidec.c b/libavformat/samidec.c
index 85fd220..2eaee6f 100644
--- a/libavformat/samidec.c
+++ b/libavformat/samidec.c
@@ -27,6 +27,7 @@
 #include "avformat.h"
 #include "internal.h"
 #include "subtitles.h"
+#include "libavcodec/internal.h"
 #include "libavutil/avstring.h"
 #include "libavutil/bprint.h"
 #include "libavutil/intreadwrite.h"
@@ -91,13 +92,9 @@
         av_bprint_clear(&buf);
     }
 
-    st->codec->extradata_size = hdr_buf.len + 1;
-    av_bprint_finalize(&hdr_buf, (char **)&st->codec->extradata);
-    if (!st->codec->extradata) {
-        st->codec->extradata_size = 0;
-        res = AVERROR(ENOMEM);
+    res = avpriv_bprint_to_extradata(st->codec, &hdr_buf);
+    if (res < 0)
         goto end;
-    }
 
     ff_subtitles_queue_finalize(&sami->q);
 
@@ -136,6 +133,5 @@
     .read_packet    = sami_read_packet,
     .read_seek2     = sami_read_seek,
     .read_close     = sami_read_close,
-    .flags          = AVFMT_GENERIC_INDEX,
     .extensions     = "smi,sami",
 };
diff --git a/libavformat/sapenc.c b/libavformat/sapenc.c
index 7abfd50..6b1cd18 100644
--- a/libavformat/sapenc.c
+++ b/libavformat/sapenc.c
@@ -23,8 +23,10 @@
 #include "libavutil/parseutils.h"
 #include "libavutil/random_seed.h"
 #include "libavutil/avstring.h"
+#include "libavutil/dict.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/time.h"
+#include "libavutil/dict.h"
 #include "internal.h"
 #include "network.h"
 #include "os_support.h"
@@ -76,6 +78,7 @@
     struct sockaddr_storage localaddr;
     socklen_t addrlen = sizeof(localaddr);
     int udp_fd;
+    AVDictionaryEntry* title = av_dict_get(s->metadata, "title", NULL, 0);
 
     if (!ff_network_init())
         return AVERROR(EIO);
@@ -158,6 +161,9 @@
         av_strlcpy(contexts[i]->filename, url, sizeof(contexts[i]->filename));
     }
 
+    if (s->nb_streams > 0 && title)
+        av_dict_set(&contexts[0]->metadata, "title", title->value, 0);
+
     ff_url_join(url, sizeof(url), "udp", NULL, announce_addr, port,
                 "?ttl=%d&connect=1", ttl);
     ret = ffurl_open(&sap->ann_fd, url, AVIO_FLAG_WRITE,
diff --git a/libavformat/sauce.c b/libavformat/sauce.c
index 21cc95b..a2347b0 100644
--- a/libavformat/sauce.c
+++ b/libavformat/sauce.c
@@ -71,7 +71,7 @@
             if (get_height && t2)
                 avctx->streams[0]->codec->height = t2<<4;
         } else if (datatype == 5) {
-            if (filetype > 1) {
+            if (filetype) {
                 avctx->streams[0]->codec->width = (filetype == 1 ? t1 : filetype) << 4;
                 *got_width = 1;
             }
diff --git a/libavformat/sctp.c b/libavformat/sctp.c
index 7fbc11f..2fd5400 100644
--- a/libavformat/sctp.c
+++ b/libavformat/sctp.c
@@ -296,8 +296,10 @@
         /*StreamId is introduced as a 2byte code into the stream*/
         struct sctp_sndrcvinfo info = { 0 };
         info.sinfo_stream           = AV_RB16(buf);
-        if (info.sinfo_stream > s->max_streams)
-            abort();
+        if (info.sinfo_stream > s->max_streams) {
+            av_log(h, AV_LOG_ERROR, "bad input data\n");
+            return AVERROR(EINVAL);
+        }
         ret = ff_sctp_send(s->fd, buf + 2, size - 2, &info, MSG_EOR);
     } else
         ret = send(s->fd, buf, size, 0);
diff --git a/libavformat/sdp.c b/libavformat/sdp.c
index cdc3e21..0124218 100644
--- a/libavformat/sdp.c
+++ b/libavformat/sdp.c
@@ -128,7 +128,7 @@
 
     *ttl = 0;
 
-    if (strcmp(proto, "rtp")) {
+    if (strcmp(proto, "rtp") && strcmp(proto, "srtp")) {
         /* The url isn't for the actual rtp sessions,
          * don't parse out anything else than the destination.
          */
@@ -681,6 +681,19 @@
                 av_strlcatf(buf, size,
                                    "a=control:streamid=%d\r\n", i + j);
             }
+            if (ac[i]->pb && ac[i]->pb->av_class) {
+                uint8_t *crypto_suite = NULL, *crypto_params = NULL;
+                av_opt_get(ac[i]->pb, "srtp_out_suite",  AV_OPT_SEARCH_CHILDREN,
+                           &crypto_suite);
+                av_opt_get(ac[i]->pb, "srtp_out_params", AV_OPT_SEARCH_CHILDREN,
+                           &crypto_params);
+                if (crypto_suite && crypto_suite[0])
+                    av_strlcatf(buf, size,
+                                "a=crypto:1 %s inline:%s\r\n",
+                                crypto_suite, crypto_params);
+                av_free(crypto_suite);
+                av_free(crypto_params);
+            }
         }
     }
 
diff --git a/libavformat/seek-test.c b/libavformat/seek-test.c
index 49ac3ac..34ac4de 100644
--- a/libavformat/seek-test.c
+++ b/libavformat/seek-test.c
@@ -28,9 +28,6 @@
 #include "libavutil/mathematics.h"
 #include "libavformat/avformat.h"
 
-#undef printf
-#undef fprintf
-
 static char buffer[20];
 
 static const char *ret_str(int v)
diff --git a/libavformat/segment.c b/libavformat/segment.c
index 1ad410e..13d8c43 100644
--- a/libavformat/segment.c
+++ b/libavformat/segment.c
@@ -21,9 +21,11 @@
 /**
  * @file generic segmenter
  * M3U8 specification can be find here:
- * @url{http://tools.ietf.org/id/draft-pantos-http-live-streaming-08.txt}
+ * @url{http://tools.ietf.org/id/draft-pantos-http-live-streaming}
  */
 
+/* #define DEBUG */
+
 #include <float.h>
 
 #include "avformat.h"
@@ -35,6 +37,15 @@
 #include "libavutil/avstring.h"
 #include "libavutil/parseutils.h"
 #include "libavutil/mathematics.h"
+#include "libavutil/timestamp.h"
+
+typedef struct SegmentListEntry {
+    int index;
+    double start_time, end_time;
+    int64_t start_pts;
+    char filename[1024];
+    struct SegmentListEntry *next;
+} SegmentListEntry;
 
 typedef enum {
     LIST_TYPE_UNDEFINED = -1,
@@ -45,7 +56,6 @@
     LIST_TYPE_NB,
 } ListType;
 
-
 #define SEGMENT_LIST_FLAG_CACHE 1
 #define SEGMENT_LIST_FLAG_LIVE  2
 
@@ -60,20 +70,34 @@
     char *list;            ///< filename for the segment list file
     int   list_flags;      ///< flags affecting list generation
     int   list_size;       ///< number of entries for the segment list file
-    double list_max_segment_time; ///< max segment time in the current list
     ListType list_type;    ///< set the list type
     AVIOContext *list_pb;  ///< list file put-byte context
     char *time_str;        ///< segment duration specification string
     int64_t time;          ///< segment duration
+
     char *times_str;       ///< segment times specification string
     int64_t *times;        ///< list of segment interval specification
     int nb_times;          ///< number of elments in the times array
+
+    char *frames_str;      ///< segment frame numbers specification string
+    int *frames;           ///< list of frame number specification
+    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 has_video;
-    double start_time, end_time;
+
+    int reset_timestamps;  ///< reset timestamps at the begin of each segment
+    char *reference_stream_specifier; ///< reference stream specifier
+    int   reference_stream_index;
+
+    SegmentListEntry cur_entry;
+    SegmentListEntry *segment_list_entries;
+    SegmentListEntry *segment_list_entries_end;
+
+    int is_first_pkt;      ///< tells if it is the first packet in the segment
 } SegmentContext;
 
 static void print_csv_escaped_str(AVIOContext *ctx, const char *str)
@@ -127,6 +151,22 @@
     return 0;
 }
 
+static int set_segment_filename(AVFormatContext *s)
+{
+    SegmentContext *seg = s->priv_data;
+    AVFormatContext *oc = seg->avf;
+
+    if (seg->segment_idx_wrap)
+        seg->segment_idx %= seg->segment_idx_wrap;
+    if (av_get_frame_filename(oc->filename, sizeof(oc->filename),
+                              s->filename, seg->segment_idx) < 0) {
+        av_log(oc, AV_LOG_ERROR, "Invalid segment filename template '%s'\n", s->filename);
+        return AVERROR(EINVAL);
+    }
+    av_strlcpy(seg->cur_entry.filename, oc->filename, sizeof(seg->cur_entry.filename));
+    return 0;
+}
+
 static int segment_start(AVFormatContext *s, int write_header)
 {
     SegmentContext *seg = s->priv_data;
@@ -142,14 +182,8 @@
     }
 
     seg->segment_idx++;
-    if (seg->segment_idx_wrap)
-        seg->segment_idx %= seg->segment_idx_wrap;
-
-    if (av_get_frame_filename(oc->filename, sizeof(oc->filename),
-                              s->filename, seg->segment_idx) < 0) {
-        av_log(oc, AV_LOG_ERROR, "Invalid segment filename template '%s'\n", s->filename);
-        return AVERROR(EINVAL);
-    }
+    if ((err = set_segment_filename(s)) < 0)
+        return err;
     seg->segment_count++;
 
     if ((err = avio_open2(&oc->pb, oc->filename, AVIO_FLAG_WRITE,
@@ -164,6 +198,7 @@
             return err;
     }
 
+    seg->is_first_pkt = 1;
     return 0;
 }
 
@@ -176,37 +211,48 @@
                      &s->interrupt_callback, NULL);
     if (ret < 0)
         return ret;
-    seg->list_max_segment_time = 0;
 
-    if (seg->list_type == LIST_TYPE_M3U8) {
+    if (seg->list_type == LIST_TYPE_M3U8 && seg->segment_list_entries) {
+        SegmentListEntry *entry;
+        double max_duration = 0;
+
         avio_printf(seg->list_pb, "#EXTM3U\n");
         avio_printf(seg->list_pb, "#EXT-X-VERSION:3\n");
-        avio_printf(seg->list_pb, "#EXT-X-MEDIA-SEQUENCE:%d\n", seg->segment_idx);
-        avio_printf(seg->list_pb, "#EXT-X-ALLOWCACHE:%d\n",
-                    !!(seg->list_flags & SEGMENT_LIST_FLAG_CACHE));
-        if (seg->list_flags & SEGMENT_LIST_FLAG_LIVE)
-            avio_printf(seg->list_pb,
-                        "#EXT-X-TARGETDURATION:%"PRId64"\n", seg->time / 1000000);
+        avio_printf(seg->list_pb, "#EXT-X-MEDIA-SEQUENCE:%d\n", seg->segment_list_entries->index);
+        avio_printf(seg->list_pb, "#EXT-X-ALLOW-CACHE:%s\n",
+                    seg->list_flags & SEGMENT_LIST_FLAG_CACHE ? "YES" : "NO");
+
+        for (entry = seg->segment_list_entries; entry; entry = entry->next)
+            max_duration = FFMAX(max_duration, entry->end_time - entry->start_time);
+        avio_printf(seg->list_pb, "#EXT-X-TARGETDURATION:%"PRId64"\n", (int64_t)ceil(max_duration));
     }
 
     return ret;
 }
 
-static void segment_list_close(AVFormatContext *s)
+static void segment_list_print_entry(AVIOContext      *list_ioctx,
+                                     ListType          list_type,
+                                     const SegmentListEntry *list_entry)
 {
-    SegmentContext *seg = s->priv_data;
-
-    if (seg->list_type == LIST_TYPE_M3U8) {
-        if (!(seg->list_flags & SEGMENT_LIST_FLAG_LIVE))
-            avio_printf(seg->list_pb, "#EXT-X-TARGETDURATION:%d\n",
-                        (int)ceil(seg->list_max_segment_time));
-        avio_printf(seg->list_pb, "#EXT-X-ENDLIST\n");
+    switch (list_type) {
+    case LIST_TYPE_FLAT:
+        avio_printf(list_ioctx, "%s\n", list_entry->filename);
+        break;
+    case LIST_TYPE_CSV:
+    case LIST_TYPE_EXT:
+        print_csv_escaped_str(list_ioctx, list_entry->filename);
+        avio_printf(list_ioctx, ",%f,%f\n", list_entry->start_time, list_entry->end_time);
+        break;
+    case LIST_TYPE_M3U8:
+        avio_printf(list_ioctx, "#EXTINF:%f,\n%s\n",
+                    list_entry->end_time - list_entry->start_time, list_entry->filename);
+        break;
+    default:
+        av_assert0(!"Invalid list type");
     }
-
-    avio_close(seg->list_pb);
 }
 
-static int segment_end(AVFormatContext *s, int write_trailer)
+static int segment_end(AVFormatContext *s, int write_trailer, int is_last)
 {
     SegmentContext *seg = s->priv_data;
     AVFormatContext *oc = seg->avf;
@@ -221,22 +267,38 @@
                oc->filename);
 
     if (seg->list) {
-        if (seg->list_size && !(seg->segment_count % seg->list_size)) {
-            segment_list_close(s);
+        if (seg->list_size || seg->list_type == LIST_TYPE_M3U8) {
+            SegmentListEntry *entry = av_mallocz(sizeof(*entry));
+            if (!entry) {
+                ret = AVERROR(ENOMEM);
+                goto end;
+            }
+
+            /* append new element */
+            memcpy(entry, &seg->cur_entry, sizeof(*entry));
+            if (!seg->segment_list_entries)
+                seg->segment_list_entries = seg->segment_list_entries_end = entry;
+            else
+                seg->segment_list_entries_end->next = entry;
+            seg->segment_list_entries_end = entry;
+
+            /* drop first item */
+            if (seg->list_size && seg->segment_count > seg->list_size) {
+                entry = seg->segment_list_entries;
+                seg->segment_list_entries = seg->segment_list_entries->next;
+                av_freep(&entry);
+            }
+
+            avio_close(seg->list_pb);
             if ((ret = segment_list_open(s)) < 0)
                 goto end;
+            for (entry = seg->segment_list_entries; entry; entry = entry->next)
+                segment_list_print_entry(seg->list_pb, seg->list_type, entry);
+            if (seg->list_type == LIST_TYPE_M3U8 && is_last)
+                avio_printf(seg->list_pb, "#EXT-X-ENDLIST\n");
+        } else {
+            segment_list_print_entry(seg->list_pb, seg->list_type, &seg->cur_entry);
         }
-
-        if (seg->list_type == LIST_TYPE_FLAT) {
-            avio_printf(seg->list_pb, "%s\n", oc->filename);
-        } else if (seg->list_type == LIST_TYPE_CSV || seg->list_type == LIST_TYPE_EXT) {
-            print_csv_escaped_str(seg->list_pb, oc->filename);
-            avio_printf(seg->list_pb, ",%f,%f\n", seg->start_time, seg->end_time);
-        } else if (seg->list_type == LIST_TYPE_M3U8) {
-            avio_printf(seg->list_pb, "#EXTINF:%f,\n%s\n",
-                        seg->end_time - seg->start_time, oc->filename);
-        }
-        seg->list_max_segment_time = FFMAX(seg->end_time - seg->start_time, seg->list_max_segment_time);
         avio_flush(seg->list_pb);
     }
 
@@ -274,13 +336,18 @@
     for (i = 0; i < *nb_times; i++) {
         int64_t t;
         char *tstr = av_strtok(p, ",", &saveptr);
-        av_assert0(tstr);
         p = NULL;
 
+        if (!tstr || !tstr[0]) {
+            av_log(log_ctx, AV_LOG_ERROR, "Empty time specification in times list %s\n",
+                   times_str);
+            FAIL(AVERROR(EINVAL));
+        }
+
         ret = av_parse_time(&t, tstr, 1);
         if (ret < 0) {
             av_log(log_ctx, AV_LOG_ERROR,
-                   "Invalid time duration specification in %s\n", p);
+                   "Invalid time duration specification '%s' in times list %s\n", tstr, times_str);
             FAIL(AVERROR(EINVAL));
         }
         (*times)[i] = t;
@@ -299,6 +366,65 @@
     return ret;
 }
 
+static int parse_frames(void *log_ctx, int **frames, int *nb_frames,
+                        const char *frames_str)
+{
+    char *p;
+    int i, ret = 0;
+    char *frames_str1 = av_strdup(frames_str);
+    char *saveptr = NULL;
+
+    if (!frames_str1)
+        return AVERROR(ENOMEM);
+
+#define FAIL(err) ret = err; goto end
+
+    *nb_frames = 1;
+    for (p = frames_str1; *p; p++)
+        if (*p == ',')
+            (*nb_frames)++;
+
+    *frames = av_malloc(sizeof(**frames) * *nb_frames);
+    if (!*frames) {
+        av_log(log_ctx, AV_LOG_ERROR, "Could not allocate forced frames array\n");
+        FAIL(AVERROR(ENOMEM));
+    }
+
+    p = frames_str1;
+    for (i = 0; i < *nb_frames; i++) {
+        long int f;
+        char *tailptr;
+        char *fstr = av_strtok(p, ",", &saveptr);
+
+        p = NULL;
+        if (!fstr) {
+            av_log(log_ctx, AV_LOG_ERROR, "Empty frame specification in frame list %s\n",
+                   frames_str);
+            FAIL(AVERROR(EINVAL));
+        }
+        f = strtol(fstr, &tailptr, 10);
+        if (*tailptr || f <= 0 || f >= INT_MAX) {
+            av_log(log_ctx, AV_LOG_ERROR,
+                   "Invalid argument '%s', must be a positive integer <= INT64_MAX\n",
+                   fstr);
+            FAIL(AVERROR(EINVAL));
+        }
+        (*frames)[i] = f;
+
+        /* check on monotonicity */
+        if (i && (*frames)[i-1] > (*frames)[i]) {
+            av_log(log_ctx, AV_LOG_ERROR,
+                   "Specified frame %d is greater than the following frame %d\n",
+                   (*frames)[i], (*frames)[i-1]);
+            FAIL(AVERROR(EINVAL));
+        }
+    }
+
+end:
+    av_free(frames_str1);
+    return ret;
+}
+
 static int open_null_ctx(AVIOContext **ctx)
 {
     int buf_size = 32768;
@@ -319,32 +445,86 @@
     av_free(pb);
 }
 
+static int select_reference_stream(AVFormatContext *s)
+{
+    SegmentContext *seg = s->priv_data;
+    int ret, i;
+
+    seg->reference_stream_index = -1;
+    if (!strcmp(seg->reference_stream_specifier, "auto")) {
+        /* select first index of type with highest priority */
+        int type_index_map[AVMEDIA_TYPE_NB];
+        static const enum AVMediaType type_priority_list[] = {
+            AVMEDIA_TYPE_VIDEO,
+            AVMEDIA_TYPE_AUDIO,
+            AVMEDIA_TYPE_SUBTITLE,
+            AVMEDIA_TYPE_DATA,
+            AVMEDIA_TYPE_ATTACHMENT
+        };
+        enum AVMediaType type;
+
+        for (i = 0; i < AVMEDIA_TYPE_NB; i++)
+            type_index_map[i] = -1;
+
+        /* select first index for each type */
+        for (i = 0; i < s->nb_streams; i++) {
+            type = s->streams[i]->codec->codec_type;
+            if ((unsigned)type < AVMEDIA_TYPE_NB && type_index_map[type] == -1
+                /* ignore attached pictures/cover art streams */
+                && !(s->streams[i]->disposition & AV_DISPOSITION_ATTACHED_PIC))
+                type_index_map[type] = i;
+        }
+
+        for (i = 0; i < FF_ARRAY_ELEMS(type_priority_list); i++) {
+            type = type_priority_list[i];
+            if ((seg->reference_stream_index = type_index_map[type]) >= 0)
+                break;
+        }
+    } else {
+        for (i = 0; i < s->nb_streams; i++) {
+            ret = avformat_match_stream_specifier(s, s->streams[i],
+                                                  seg->reference_stream_specifier);
+            if (ret < 0)
+                return ret;
+            if (ret > 0) {
+                seg->reference_stream_index = i;
+                break;
+            }
+        }
+    }
+
+    if (seg->reference_stream_index < 0) {
+        av_log(s, AV_LOG_ERROR, "Could not select stream matching identifier '%s'\n",
+               seg->reference_stream_specifier);
+        return AVERROR(EINVAL);
+    }
+
+    return 0;
+}
+
 static int seg_write_header(AVFormatContext *s)
 {
     SegmentContext *seg = s->priv_data;
     AVFormatContext *oc = NULL;
-    int ret, i;
+    int ret;
 
     seg->segment_count = 0;
     if (!seg->write_header_trailer)
         seg->individual_header_trailer = 0;
 
-    if (seg->time_str && seg->times_str) {
+    if (!!seg->time_str + !!seg->times_str + !!seg->frames_str > 1) {
         av_log(s, AV_LOG_ERROR,
-               "segment_time and segment_times options are mutually exclusive, select just one of them\n");
-        return AVERROR(EINVAL);
-    }
-
-    if ((seg->list_flags & SEGMENT_LIST_FLAG_LIVE) && seg->times_str) {
-        av_log(s, AV_LOG_ERROR,
-               "segment_flags +live and segment_times options are mutually exclusive:"
-               "specify -segment_time if you want a live-friendly list\n");
+               "segment_time, segment_times, and segment_frames options "
+               "are mutually exclusive, select just one of them\n");
         return AVERROR(EINVAL);
     }
 
     if (seg->times_str) {
         if ((ret = parse_times(s, &seg->times, &seg->nb_times, seg->times_str)) < 0)
             return ret;
+    } else if (seg->frames_str) {
+        if ((ret = parse_frames(s, &seg->frames, &seg->nb_frames, seg->frames_str)) < 0)
+            return ret;
     } else {
         /* set default value if not specified */
         if (!seg->time_str)
@@ -379,14 +559,11 @@
     if (seg->list_type == LIST_TYPE_EXT)
         av_log(s, AV_LOG_WARNING, "'ext' list type option is deprecated in favor of 'csv'\n");
 
-    for (i = 0; i < s->nb_streams; i++)
-        seg->has_video +=
-            (s->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO);
-
-    if (seg->has_video > 1)
-        av_log(s, AV_LOG_WARNING,
-               "More than a single video stream present, "
-               "expect issues decoding it.\n");
+    if ((ret = select_reference_stream(s)) < 0)
+        goto fail;
+    av_log(s, AV_LOG_VERBOSE, "Selected stream id:%d type:%s\n",
+           seg->reference_stream_index,
+           av_get_media_type_string(s->streams[seg->reference_stream_index]->codec->codec_type));
 
     seg->oformat = av_guess_format(seg->format, s->filename, NULL);
 
@@ -405,11 +582,8 @@
         goto fail;
     oc = seg->avf;
 
-    if (av_get_frame_filename(oc->filename, sizeof(oc->filename),
-                              s->filename, seg->segment_idx) < 0) {
-        ret = AVERROR(EINVAL);
+    if ((ret = set_segment_filename(s)) < 0)
         goto fail;
-    }
     seg->segment_count++;
 
     if (seg->write_header_trailer) {
@@ -425,6 +599,7 @@
         avio_close(oc->pb);
         goto fail;
     }
+    seg->is_first_pkt = 1;
 
     if (oc->avoid_negative_ts > 0 && s->avoid_negative_ts < 0)
         s->avoid_negative_ts = 1;
@@ -439,7 +614,7 @@
 fail:
     if (ret) {
         if (seg->list)
-            segment_list_close(s);
+            avio_close(seg->list_pb);
         if (seg->avf)
             avformat_free_context(seg->avf);
     }
@@ -451,26 +626,32 @@
     SegmentContext *seg = s->priv_data;
     AVFormatContext *oc = seg->avf;
     AVStream *st = s->streams[pkt->stream_index];
-    int64_t end_pts;
+    int64_t end_pts = INT64_MAX;
+    int start_frame = INT_MAX;
     int ret;
 
     if (seg->times) {
         end_pts = seg->segment_count <= seg->nb_times ?
             seg->times[seg->segment_count-1] : INT64_MAX;
+    } else if (seg->frames) {
+        start_frame = seg->segment_count <= seg->nb_frames ?
+            seg->frames[seg->segment_count-1] : INT_MAX;
     } else {
         end_pts = seg->time * seg->segment_count;
     }
 
-    /* if the segment has video, start a new segment *only* with a key video frame */
-    if ((st->codec->codec_type == AVMEDIA_TYPE_VIDEO || !seg->has_video) &&
-        av_compare_ts(pkt->pts, st->time_base,
-                      end_pts-seg->time_delta, AV_TIME_BASE_Q) >= 0 &&
-        pkt->flags & AV_PKT_FLAG_KEY) {
+    av_dlog(s, "packet stream:%d pts:%s pts_time:%s is_key:%d frame:%d\n",
+           pkt->stream_index, av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &st->time_base),
+           pkt->flags & AV_PKT_FLAG_KEY,
+           pkt->stream_index == seg->reference_stream_index ? seg->frame_count : -1);
 
-        av_log(s, AV_LOG_DEBUG, "Next segment starts with packet stream:%d pts:%"PRId64" pts_time:%f\n",
-               pkt->stream_index, pkt->pts, pkt->pts * av_q2d(st->time_base));
-
-        ret = segment_end(s, seg->individual_header_trailer);
+    if (pkt->stream_index == seg->reference_stream_index &&
+        pkt->flags & AV_PKT_FLAG_KEY &&
+        (seg->frame_count >= start_frame ||
+         (pkt->pts != AV_NOPTS_VALUE &&
+          av_compare_ts(pkt->pts, st->time_base,
+                        end_pts-seg->time_delta, AV_TIME_BASE_Q) >= 0))) {
+        ret = segment_end(s, seg->individual_header_trailer, 0);
 
         if (!ret)
             ret = segment_start(s, seg->individual_header_trailer);
@@ -480,15 +661,45 @@
 
         oc = seg->avf;
 
-        seg->start_time = (double)pkt->pts * av_q2d(st->time_base);
+        seg->cur_entry.index = seg->segment_idx;
+        seg->cur_entry.start_time = (double)pkt->pts * av_q2d(st->time_base);
+        seg->cur_entry.start_pts = av_rescale_q(pkt->pts, st->time_base, AV_TIME_BASE_Q);
     } else if (pkt->pts != AV_NOPTS_VALUE) {
-        seg->end_time = FFMAX(seg->end_time,
-                              (double)(pkt->pts + pkt->duration) * av_q2d(st->time_base));
+        seg->cur_entry.end_time =
+            FFMAX(seg->cur_entry.end_time, (double)(pkt->pts + pkt->duration) * av_q2d(st->time_base));
+    }
+
+    if (seg->is_first_pkt) {
+        av_log(s, AV_LOG_DEBUG, "segment:'%s' starts with packet stream:%d pts:%s pts_time:%s frame:%d\n",
+               seg->avf->filename, pkt->stream_index,
+               av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &st->time_base), seg->frame_count);
+        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));
+
+        /* 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);
+
+        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);
 
 fail:
+    if (pkt->stream_index == seg->reference_stream_index)
+        seg->frame_count++;
+
     if (ret < 0) {
         if (seg->list)
             avio_close(seg->list_pb);
@@ -502,22 +713,32 @@
 {
     SegmentContext *seg = s->priv_data;
     AVFormatContext *oc = seg->avf;
+    SegmentListEntry *cur, *next;
+
     int ret;
     if (!seg->write_header_trailer) {
-        if ((ret = segment_end(s, 0)) < 0)
+        if ((ret = segment_end(s, 0, 1)) < 0)
             goto fail;
         open_null_ctx(&oc->pb);
         ret = av_write_trailer(oc);
         close_null_ctx(oc->pb);
     } else {
-        ret = segment_end(s, 1);
+        ret = segment_end(s, 1, 1);
     }
 fail:
     if (seg->list)
-        segment_list_close(s);
+        avio_close(seg->list_pb);
 
     av_opt_free(seg);
     av_freep(&seg->times);
+    av_freep(&seg->frames);
+
+    cur = seg->segment_list_entries;
+    while (cur) {
+        next = cur->next;
+        av_free(cur);
+        cur = next;
+    }
 
     avformat_free_context(oc);
     return ret;
@@ -526,6 +747,7 @@
 #define OFFSET(x) offsetof(SegmentContext, x)
 #define E AV_OPT_FLAG_ENCODING_PARAM
 static const AVOption options[] = {
+    { "reference_stream",  "set reference stream", OFFSET(reference_stream_specifier), AV_OPT_TYPE_STRING, {.str = "auto"}, CHAR_MIN, CHAR_MAX, E },
     { "segment_format",    "set container format used for the segments", OFFSET(format),  AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,       E },
     { "segment_list",      "set the segment list filename",              OFFSET(list),    AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,       E },
 
@@ -534,18 +756,24 @@
     { "live",              "enable live-friendly list generation (useful for HLS)", 0, AV_OPT_TYPE_CONST, {.i64 = SEGMENT_LIST_FLAG_LIVE }, INT_MIN, INT_MAX,    E, "list_flags"},
 
     { "segment_list_size", "set the maximum number of playlist entries", OFFSET(list_size), AV_OPT_TYPE_INT,  {.i64 = 0},     0, INT_MAX, E },
+
     { "segment_list_type", "set the segment list type",                  OFFSET(list_type), AV_OPT_TYPE_INT,  {.i64 = LIST_TYPE_UNDEFINED}, -1, LIST_TYPE_NB-1, E, "list_type" },
-    { "flat", "flat format",     0, AV_OPT_TYPE_CONST, {.i64=LIST_TYPE_FLAT }, INT_MIN, INT_MAX, 0, "list_type" },
-    { "csv",  "csv format",      0, AV_OPT_TYPE_CONST, {.i64=LIST_TYPE_CSV  }, INT_MIN, INT_MAX, 0, "list_type" },
-    { "ext",  "extended format", 0, AV_OPT_TYPE_CONST, {.i64=LIST_TYPE_EXT  }, INT_MIN, INT_MAX, 0, "list_type" },
-    { "m3u8", "M3U8 format",     0, AV_OPT_TYPE_CONST, {.i64=LIST_TYPE_M3U8 }, INT_MIN, INT_MAX, 0, "list_type" },
-    { "hls", "Apple HTTP Live Streaming compatible",     0, AV_OPT_TYPE_CONST, {.i64=LIST_TYPE_M3U8 }, INT_MIN, INT_MAX, 0, "list_type" },
+    { "flat", "flat format",     0, AV_OPT_TYPE_CONST, {.i64=LIST_TYPE_FLAT }, INT_MIN, INT_MAX, E, "list_type" },
+    { "csv",  "csv format",      0, AV_OPT_TYPE_CONST, {.i64=LIST_TYPE_CSV  }, INT_MIN, INT_MAX, E, "list_type" },
+    { "ext",  "extended format", 0, AV_OPT_TYPE_CONST, {.i64=LIST_TYPE_EXT  }, INT_MIN, INT_MAX, E, "list_type" },
+    { "m3u8", "M3U8 format",     0, AV_OPT_TYPE_CONST, {.i64=LIST_TYPE_M3U8 }, INT_MIN, INT_MAX, E, "list_type" },
+    { "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_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 },
+    { "segment_start_number", "set the sequence number of the first segment", OFFSET(segment_idx), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E },
+
     { "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 },
     { NULL },
 };
 
diff --git a/libavformat/siff.c b/libavformat/siff.c
index a834d4d..c8b68ab 100644
--- a/libavformat/siff.c
+++ b/libavformat/siff.c
@@ -76,7 +76,7 @@
     AVStream *ast;
     ast = avformat_new_stream(s, NULL);
     if (!ast)
-        return -1;
+        return AVERROR(ENOMEM);
     ast->codec->codec_type      = AVMEDIA_TYPE_AUDIO;
     ast->codec->codec_id        = AV_CODEC_ID_PCM_U8;
     ast->codec->channels        = 1;
@@ -95,15 +95,15 @@
 
     if (avio_rl32(pb) != TAG_VBHD){
         av_log(s, AV_LOG_ERROR, "Header chunk is missing\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     if(avio_rb32(pb) != 32){
         av_log(s, AV_LOG_ERROR, "Header chunk size is incorrect\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     if(avio_rl16(pb) != 1){
         av_log(s, AV_LOG_ERROR, "Incorrect header version\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     width = avio_rl16(pb);
     height = avio_rl16(pb);
@@ -111,7 +111,7 @@
     c->frames = avio_rl16(pb);
     if(!c->frames){
         av_log(s, AV_LOG_ERROR, "File contains no frames ???\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     c->bits = avio_rl16(pb);
     c->rate = avio_rl16(pb);
@@ -121,13 +121,15 @@
 
     st = avformat_new_stream(s, NULL);
     if (!st)
-        return -1;
+        return AVERROR(ENOMEM);
     st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
     st->codec->codec_id   = AV_CODEC_ID_VB;
     st->codec->codec_tag  = MKTAG('V', 'B', 'V', '1');
     st->codec->width      = width;
     st->codec->height     = height;
     st->codec->pix_fmt    = AV_PIX_FMT_PAL8;
+    st->nb_frames         =
+    st->duration          = c->frames;
     avpriv_set_pts_info(st, 16, 1, 12);
 
     c->cur_frame = 0;
@@ -135,7 +137,7 @@
     c->has_audio = !!c->rate;
     c->curstrm = -1;
     if (c->has_audio && create_audio_stream(s, c) < 0)
-        return -1;
+        return AVERROR(ENOMEM);
     return 0;
 }
 
@@ -143,11 +145,11 @@
 {
     if (avio_rl32(pb) != TAG_SHDR){
         av_log(s, AV_LOG_ERROR, "Header chunk is missing\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     if(avio_rb32(pb) != 8){
         av_log(s, AV_LOG_ERROR, "Header chunk size is incorrect\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     avio_skip(pb, 4); //unknown value
     c->rate = avio_rl16(pb);
@@ -161,24 +163,25 @@
     AVIOContext *pb = s->pb;
     SIFFContext *c = s->priv_data;
     uint32_t tag;
+    int ret;
 
     if (avio_rl32(pb) != TAG_SIFF)
-        return -1;
+        return AVERROR_INVALIDDATA;
     avio_skip(pb, 4); //ignore size
     tag = avio_rl32(pb);
 
     if (tag != TAG_VBV1 && tag != TAG_SOUN){
         av_log(s, AV_LOG_ERROR, "Not a VBV file\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
-    if (tag == TAG_VBV1 && siff_parse_vbv1(s, c, pb) < 0)
-        return -1;
-    if (tag == TAG_SOUN && siff_parse_soun(s, c, pb) < 0)
-        return -1;
+    if (tag == TAG_VBV1 && (ret = siff_parse_vbv1(s, c, pb)) < 0)
+        return ret;
+    if (tag == TAG_SOUN && (ret = siff_parse_soun(s, c, pb)) < 0)
+        return ret;
     if (avio_rl32(pb) != MKTAG('B', 'O', 'D', 'Y')){
         av_log(s, AV_LOG_ERROR, "'BODY' chunk is missing\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     avio_skip(pb, 4); //ignore size
 
diff --git a/libavformat/smacker.c b/libavformat/smacker.c
index be22bec..883a2b7 100644
--- a/libavformat/smacker.c
+++ b/libavformat/smacker.c
@@ -110,7 +110,7 @@
     /* read and check header */
     smk->magic = avio_rl32(pb);
     if (smk->magic != MKTAG('S', 'M', 'K', '2') && smk->magic != MKTAG('S', 'M', 'K', '4'))
-        return -1;
+        return AVERROR_INVALIDDATA;
     smk->width = avio_rl32(pb);
     smk->height = avio_rl32(pb);
     smk->frames = avio_rl32(pb);
@@ -124,7 +124,7 @@
 
     if(smk->treesize >= UINT_MAX/4){ // smk->treesize + 16 must not overflow (this check is probably redundant)
         av_log(s, AV_LOG_ERROR, "treesize too large\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
 //FIXME remove extradata "rebuilding"
@@ -140,7 +140,7 @@
     /* setup data */
     if(smk->frames > 0xFFFFFF) {
         av_log(s, AV_LOG_ERROR, "Too many frames: %i\n", smk->frames);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     smk->frm_size = av_malloc(smk->frames * 4);
     smk->frm_flags = av_malloc(smk->frames);
@@ -158,7 +158,7 @@
     /* init video codec */
     st = avformat_new_stream(s, NULL);
     if (!st)
-        return -1;
+        return AVERROR(ENOMEM);
     smk->videoindex = st->index;
     st->codec->width = smk->width;
     st->codec->height = smk->height;
@@ -216,7 +216,7 @@
         av_log(s, AV_LOG_ERROR, "Cannot allocate %i bytes of extradata\n", smk->treesize + 16);
         av_free(smk->frm_size);
         av_free(smk->frm_flags);
-        return -1;
+        return AVERROR(ENOMEM);
     }
     ret = avio_read(pb, st->codec->extradata + 16, st->codec->extradata_size - 16);
     if(ret != st->codec->extradata_size - 16){
diff --git a/libavformat/smjpegdec.c b/libavformat/smjpegdec.c
index ceb29c9..f32f635 100644
--- a/libavformat/smjpegdec.c
+++ b/libavformat/smjpegdec.c
@@ -78,7 +78,7 @@
         case SMJPEG_SND:
             if (ast) {
                 av_log_ask_for_sample(s, "multiple audio streams not supported\n");
-                return AVERROR_INVALIDDATA;
+                return AVERROR_PATCHWELCOME;
             }
             hlength = avio_rb32(pb);
             if (hlength < 8)
diff --git a/libavformat/smoothstreamingenc.c b/libavformat/smoothstreamingenc.c
index e51d088..096bf79 100644
--- a/libavformat/smoothstreamingenc.c
+++ b/libavformat/smoothstreamingenc.c
@@ -51,7 +51,7 @@
     char dirname[1024];
     uint8_t iobuf[32768];
     URLContext *out;  // Current output stream where all output is written
-    URLContext *out2; // Auxillary output stream where all output also is written
+    URLContext *out2; // Auxiliary output stream where all output is also written
     URLContext *tail_out; // The actual main output stream, if we're currently seeked back to write elsewhere
     int64_t tail_pos, cur_pos, cur_start_pos;
     int packets_written;
diff --git a/libavformat/soxdec.c b/libavformat/soxdec.c
index 4c951bb..aec4284 100644
--- a/libavformat/soxdec.c
+++ b/libavformat/soxdec.c
@@ -75,12 +75,12 @@
 
     if (comment_size > 0xFFFFFFFFU - SOX_FIXED_HDR - 4U) {
         av_log(s, AV_LOG_ERROR, "invalid comment size (%u)\n", comment_size);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     if (sample_rate <= 0 || sample_rate > INT_MAX) {
         av_log(s, AV_LOG_ERROR, "invalid sample rate (%f)\n", sample_rate);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     sample_rate_frac = sample_rate - floor(sample_rate);
@@ -92,7 +92,7 @@
     if ((header_size + 4) & 7 || header_size < SOX_FIXED_HDR + comment_size
         || st->codec->channels > 65535) /* Reserve top 16 bits */ {
         av_log(s, AV_LOG_ERROR, "invalid header\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     if (comment_size && comment_size < UINT_MAX) {
@@ -124,31 +124,11 @@
     return 0;
 }
 
-#define SOX_SAMPLES 1024
-
-static int sox_read_packet(AVFormatContext *s,
-                           AVPacket *pkt)
-{
-    int ret, size;
-
-    if (url_feof(s->pb))
-        return AVERROR_EOF;
-
-    size = SOX_SAMPLES*s->streams[0]->codec->block_align;
-    ret = av_get_packet(s->pb, pkt, size);
-    if (ret < 0)
-        return AVERROR(EIO);
-    pkt->flags &= ~AV_PKT_FLAG_CORRUPT;
-    pkt->stream_index = 0;
-
-    return 0;
-}
-
 AVInputFormat ff_sox_demuxer = {
     .name           = "sox",
     .long_name      = NULL_IF_CONFIG_SMALL("SoX native"),
     .read_probe     = sox_probe,
     .read_header    = sox_read_header,
-    .read_packet    = sox_read_packet,
+    .read_packet    = ff_pcm_read_packet,
     .read_seek      = ff_pcm_read_seek,
 };
diff --git a/libavformat/soxenc.c b/libavformat/soxenc.c
index 6b4412d..e219d75 100644
--- a/libavformat/soxenc.c
+++ b/libavformat/soxenc.c
@@ -34,6 +34,7 @@
 #include "libavutil/dict.h"
 #include "avformat.h"
 #include "avio_internal.h"
+#include "rawenc.h"
 #include "sox.h"
 
 typedef struct {
@@ -51,7 +52,7 @@
     comment = av_dict_get(s->metadata, "comment", NULL, 0);
     if (comment)
         comment_len = strlen(comment->value);
-    comment_size = (comment_len + 7) & ~7;
+    comment_size = FFALIGN(comment_len, 8);
 
     sox->header_size = SOX_FIXED_HDR + comment_size;
 
@@ -77,21 +78,13 @@
     if (comment_len)
         avio_write(pb, comment->value, comment_len);
 
-    for ( ; comment_size > comment_len; comment_len++)
-        avio_w8(pb, 0);
+    ffio_fill(pb, 0, comment_size - comment_len);
 
     avio_flush(pb);
 
     return 0;
 }
 
-static int sox_write_packet(AVFormatContext *s, AVPacket *pkt)
-{
-    AVIOContext *pb = s->pb;
-    avio_write(pb, pkt->data, pkt->size);
-    return 0;
-}
-
 static int sox_write_trailer(AVFormatContext *s)
 {
     SoXContext *sox = s->priv_data;
@@ -123,6 +116,6 @@
     .audio_codec       = AV_CODEC_ID_PCM_S32LE,
     .video_codec       = AV_CODEC_ID_NONE,
     .write_header      = sox_write_header,
-    .write_packet      = sox_write_packet,
+    .write_packet      = ff_raw_write_packet,
     .write_trailer     = sox_write_trailer,
 };
diff --git a/libavformat/spdif.h b/libavformat/spdif.h
index 4b11de2..0a0d962 100644
--- a/libavformat/spdif.h
+++ b/libavformat/spdif.h
@@ -23,6 +23,7 @@
 #define AVFORMAT_SPDIF_H
 
 #include <stdint.h>
+#include "avformat.h"
 
 #define SYNCWORD1 0xF872
 #define SYNCWORD2 0x4E1F
@@ -58,5 +59,7 @@
 };
 
 void ff_spdif_bswap_buf16(uint16_t *dst, const uint16_t *src, int w);
+int ff_spdif_read_packet(AVFormatContext *s, AVPacket *pkt);
+int ff_spdif_probe(const uint8_t *p_buf, int buf_size, enum AVCodecID *codec);
 
 #endif /* AVFORMAT_SPDIF_H */
diff --git a/libavformat/spdifdec.c b/libavformat/spdifdec.c
index 94cfe84..e1329cc 100644
--- a/libavformat/spdifdec.c
+++ b/libavformat/spdifdec.c
@@ -105,14 +105,19 @@
 
 static int spdif_probe(AVProbeData *p)
 {
-    const uint8_t *buf = p->buf;
-    const uint8_t *probe_end = p->buf + FFMIN(2 * SPDIF_MAX_OFFSET, p->buf_size - 1);
+    enum AVCodecID codec;
+    return ff_spdif_probe (p->buf, p->buf_size, &codec);
+}
+
+int ff_spdif_probe(const uint8_t *p_buf, int buf_size, enum AVCodecID *codec)
+{
+    const uint8_t *buf = p_buf;
+    const uint8_t *probe_end = p_buf + FFMIN(2 * SPDIF_MAX_OFFSET, buf_size - 1);
     const uint8_t *expected_code = buf + 7;
     uint32_t state = 0;
     int sync_codes = 0;
     int consecutive_codes = 0;
     int offset;
-    enum AVCodecID codec;
 
     for (; buf < probe_end; buf++) {
         state = (state << 8) | *buf;
@@ -127,16 +132,16 @@
             } else
                 consecutive_codes = 0;
 
-            if (buf + 4 + AAC_ADTS_HEADER_SIZE > p->buf + p->buf_size)
+            if (buf + 4 + AAC_ADTS_HEADER_SIZE > p_buf + buf_size)
                 break;
 
             /* continue probing to find more sync codes */
-            probe_end = FFMIN(buf + SPDIF_MAX_OFFSET, p->buf + p->buf_size - 1);
+            probe_end = FFMIN(buf + SPDIF_MAX_OFFSET, p_buf + buf_size - 1);
 
             /* skip directly to the next sync code */
             if (!spdif_get_offset_and_codec(NULL, (buf[2] << 8) | buf[1],
-                                            &buf[5], &offset, &codec)) {
-                if (buf + offset >= p->buf + p->buf_size)
+                                            &buf[5], &offset, codec)) {
+                if (buf + offset >= p_buf + buf_size)
                     break;
                 expected_code = buf + offset;
                 buf = expected_code - 7;
@@ -161,7 +166,7 @@
     return 0;
 }
 
-static int spdif_read_packet(AVFormatContext *s, AVPacket *pkt)
+int ff_spdif_read_packet(AVFormatContext *s, AVPacket *pkt)
 {
     AVIOContext *pb = s->pb;
     enum IEC61937DataType data_type;
@@ -230,6 +235,6 @@
     .long_name      = NULL_IF_CONFIG_SMALL("IEC 61937 (compressed data in S/PDIF)"),
     .read_probe     = spdif_probe,
     .read_header    = spdif_read_header,
-    .read_packet    = spdif_read_packet,
+    .read_packet    = ff_spdif_read_packet,
     .flags          = AVFMT_GENERIC_INDEX,
 };
diff --git a/libavformat/spdifenc.c b/libavformat/spdifenc.c
index bb0c363..aaf0568 100644
--- a/libavformat/spdifenc.c
+++ b/libavformat/spdifenc.c
@@ -339,7 +339,7 @@
         ctx->data_type  = mpeg_data_type [version & 1][layer];
         ctx->pkt_offset = spdif_mpeg_pkt_offset[version & 1][layer];
     }
-    // TODO Data type dependant info (normal/karaoke, dynamic range control)
+    // TODO Data type dependent info (normal/karaoke, dynamic range control)
     return 0;
 }
 
@@ -414,7 +414,7 @@
          * distribute the TrueHD frames in the MAT frame */
         av_log(s, AV_LOG_ERROR, "TrueHD frame too big, %d bytes\n", pkt->size);
         av_log_ask_for_sample(s, NULL);
-        return AVERROR_INVALIDDATA;
+        return AVERROR_PATCHWELCOME;
     }
 
     memcpy(&ctx->hd_buf[ctx->hd_buf_count * TRUEHD_FRAME_OFFSET - BURST_HEADER_SIZE + mat_code_length],
diff --git a/libavformat/srtdec.c b/libavformat/srtdec.c
index f55fb11..76e06e4 100644
--- a/libavformat/srtdec.c
+++ b/libavformat/srtdec.c
@@ -21,12 +21,17 @@
 
 #include "avformat.h"
 #include "internal.h"
+#include "subtitles.h"
 #include "libavutil/bprint.h"
 #include "libavutil/intreadwrite.h"
 
+typedef struct {
+    FFDemuxSubtitlesQueue q;
+} SRTContext;
+
 static int srt_probe(AVProbeData *p)
 {
-    unsigned char *ptr = p->buf;
+    const unsigned char *ptr = p->buf;
     int i, v, num = 0;
 
     if (AV_RB24(ptr) == 0xEFBBBF)
@@ -42,17 +47,6 @@
     return 0;
 }
 
-static int srt_read_header(AVFormatContext *s)
-{
-    AVStream *st = avformat_new_stream(s, NULL);
-    if (!st)
-        return AVERROR(ENOMEM);
-    avpriv_set_pts_info(st, 64, 1, 1000);
-    st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
-    st->codec->codec_id   = AV_CODEC_ID_SUBRIP;
-    return 0;
-}
-
 static int64_t get_pts(const char **buf, int *duration,
                        int32_t *x1, int32_t *y1, int32_t *x2, int32_t *y2)
 {
@@ -77,99 +71,93 @@
     return AV_NOPTS_VALUE;
 }
 
-static inline int is_eol(char c)
+static int srt_read_header(AVFormatContext *s)
 {
-    return c == '\r' || c == '\n';
-}
-
-static void read_chunk(AVIOContext *pb, AVBPrint *buf)
-{
-    char eol_buf[5];
-    int n = 0, i = 0, nb_eol = 0;
-
-    for (;;) {
-        char c = avio_r8(pb);
-
-        if (!c)
-            break;
-
-        /* ignore all initial line breaks */
-        if (n == 0 && is_eol(c))
-            continue;
-
-        /* line break buffering: we don't want to add the trailing \r\n */
-        if (is_eol(c)) {
-            nb_eol += c == '\n';
-            if (nb_eol == 2)
-                break;
-            eol_buf[i++] = c;
-            if (i == sizeof(eol_buf) - 1)
-                break;
-            continue;
-        }
-
-        /* only one line break followed by data: we flush the line breaks
-         * buffer */
-        if (i) {
-            eol_buf[i] = 0;
-            av_bprintf(buf, "%s", eol_buf);
-            i = nb_eol = 0;
-        }
-
-        av_bprint_chars(buf, c, 1);
-        n++;
-    }
-
-    /* FIXME: remove the following when the lavc SubRip decoder is fixed
-     * (trailing tags are not correctly flushed, see what happens to FATE when
-     * you disable this code) */
-    if (buf->len)
-        av_bprintf(buf, "\n");
-}
-
-static int srt_read_packet(AVFormatContext *s, AVPacket *pkt)
-{
+    SRTContext *srt = s->priv_data;
     AVBPrint buf;
-    int64_t pos = avio_tell(s->pb);
-    int res = AVERROR_EOF;
+    AVStream *st = avformat_new_stream(s, NULL);
+    int res = 0;
+
+    if (!st)
+        return AVERROR(ENOMEM);
+    avpriv_set_pts_info(st, 64, 1, 1000);
+    st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
+    st->codec->codec_id   = AV_CODEC_ID_SUBRIP;
 
     av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
-    read_chunk(s->pb, &buf);
 
-    if (buf.len) {
-        int64_t pts;
-        int duration, pkt_size;
-        const char *ptr = buf.str;
-        int32_t x1 = -1, y1 = -1, x2 = -1, y2 = -1;
+    while (!url_feof(s->pb)) {
+        ff_subtitles_read_chunk(s->pb, &buf);
 
-        pts = get_pts(&ptr, &duration, &x1, &y1, &x2, &y2);
-        pkt_size = buf.len - (ptr - buf.str);
-        if (pts != AV_NOPTS_VALUE && !(res = av_new_packet(pkt, pkt_size))) {
-            memcpy(pkt->data, ptr, pkt->size);
-            pkt->flags |= AV_PKT_FLAG_KEY;
-            pkt->pos = pos;
-            pkt->pts = pkt->dts = pts;
-            pkt->duration = duration;
-            if (x1 != -1) {
-                uint8_t *p = av_packet_new_side_data(pkt, AV_PKT_DATA_SUBTITLE_POSITION, 16);
-                if (p) {
-                    AV_WL32(p,      x1);
-                    AV_WL32(p +  4, y1);
-                    AV_WL32(p +  8, x2);
-                    AV_WL32(p + 12, y2);
+        if (buf.len) {
+            int64_t pos = avio_tell(s->pb);
+            int64_t pts;
+            int duration;
+            const char *ptr = buf.str;
+            int32_t x1 = -1, y1 = -1, x2 = -1, y2 = -1;
+            AVPacket *sub;
+
+            pts = get_pts(&ptr, &duration, &x1, &y1, &x2, &y2);
+            if (pts != AV_NOPTS_VALUE) {
+                int len = buf.len - (ptr - buf.str);
+                if (len <= 0)
+                    continue;
+                sub = ff_subtitles_queue_insert(&srt->q, ptr, len, 0);
+                if (!sub) {
+                    res = AVERROR(ENOMEM);
+                    goto end;
+                }
+                sub->pos = pos;
+                sub->pts = pts;
+                sub->duration = duration;
+                if (x1 != -1) {
+                    uint8_t *p = av_packet_new_side_data(sub, AV_PKT_DATA_SUBTITLE_POSITION, 16);
+                    if (p) {
+                        AV_WL32(p,      x1);
+                        AV_WL32(p +  4, y1);
+                        AV_WL32(p +  8, x2);
+                        AV_WL32(p + 12, y2);
+                    }
                 }
             }
         }
     }
+
+    ff_subtitles_queue_finalize(&srt->q);
+
+end:
     av_bprint_finalize(&buf, NULL);
     return res;
 }
 
+static int srt_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    SRTContext *srt = s->priv_data;
+    return ff_subtitles_queue_read_packet(&srt->q, pkt);
+}
+
+static int srt_read_seek(AVFormatContext *s, int stream_index,
+                         int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
+{
+    SRTContext *srt = s->priv_data;
+    return ff_subtitles_queue_seek(&srt->q, s, stream_index,
+                                   min_ts, ts, max_ts, flags);
+}
+
+static int srt_read_close(AVFormatContext *s)
+{
+    SRTContext *srt = s->priv_data;
+    ff_subtitles_queue_clean(&srt->q);
+    return 0;
+}
+
 AVInputFormat ff_srt_demuxer = {
     .name        = "srt",
     .long_name   = NULL_IF_CONFIG_SMALL("SubRip subtitle"),
+    .priv_data_size = sizeof(SRTContext),
     .read_probe  = srt_probe,
     .read_header = srt_read_header,
     .read_packet = srt_read_packet,
-    .flags       = AVFMT_GENERIC_INDEX,
+    .read_seek2  = srt_read_seek,
+    .read_close  = srt_read_close,
 };
diff --git a/libavformat/srtenc.c b/libavformat/srtenc.c
index 97b297e..e02c4ef 100644
--- a/libavformat/srtenc.c
+++ b/libavformat/srtenc.c
@@ -22,6 +22,7 @@
 #include "avformat.h"
 #include "internal.h"
 #include "libavutil/log.h"
+#include "libavutil/intreadwrite.h"
 
 /* TODO: add options for:
    - character encoding;
@@ -63,6 +64,16 @@
 
     if (write_ts) {
         int64_t s = pkt->pts, e, d = pkt->duration;
+        int size, x1 = -1, y1 = -1, x2 = -1, y2 = -1;
+        const uint8_t *p;
+
+        p = av_packet_get_side_data(pkt, AV_PKT_DATA_SUBTITLE_POSITION, &size);
+        if (p && size == 16) {
+            x1 = AV_RL32(p     );
+            y1 = AV_RL32(p +  4);
+            x2 = AV_RL32(p +  8);
+            y2 = AV_RL32(p + 12);
+        }
 
         if (d <= 0)
             /* For backward compatibility, fallback to convergence_duration. */
@@ -73,12 +84,16 @@
             return 0;
         }
         e = s + d;
-        avio_printf(avf->pb, "%d\n%02d:%02d:%02d,%03d --> %02d:%02d:%02d,%03d\n",
+        avio_printf(avf->pb, "%d\n%02d:%02d:%02d,%03d --> %02d:%02d:%02d,%03d",
                        srt->index,
                        (int)(s / 3600000),      (int)(s / 60000) % 60,
                        (int)(s /    1000) % 60, (int)(s %  1000),
                        (int)(e / 3600000),      (int)(e / 60000) % 60,
                        (int)(e /    1000) % 60, (int)(e %  1000));
+        if (p)
+            avio_printf(avf->pb, "  X1:%03d X2:%03d Y1:%03d Y2:%03d",
+                        x1, x2, y1, y2);
+        avio_printf(avf->pb, "\n");
     }
     avio_write(avf->pb, pkt->data, pkt->size);
     if (write_ts)
diff --git a/libavformat/srtp.c b/libavformat/srtp.c
new file mode 100644
index 0000000..65309d0
--- /dev/null
+++ b/libavformat/srtp.c
@@ -0,0 +1,471 @@
+/*
+ * SRTP encryption/decryption
+ * 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 "libavutil/base64.h"
+#include "libavutil/aes.h"
+#include "libavutil/hmac.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/log.h"
+#include "rtp.h"
+#include "srtp.h"
+
+void ff_srtp_free(struct SRTPContext *s)
+{
+    if (!s)
+        return;
+    av_freep(&s->aes);
+    if (s->hmac)
+        av_hmac_free(s->hmac);
+    s->hmac = NULL;
+}
+
+static void encrypt_counter(struct AVAES *aes, uint8_t *iv, uint8_t *outbuf,
+                            int outlen)
+{
+    int i, j, outpos;
+    for (i = 0, outpos = 0; outpos < outlen; i++) {
+        uint8_t keystream[16];
+        AV_WB16(&iv[14], i);
+        av_aes_crypt(aes, keystream, iv, 1, NULL, 0);
+        for (j = 0; j < 16 && outpos < outlen; j++, outpos++)
+            outbuf[outpos] ^= keystream[j];
+    }
+}
+
+static void derive_key(struct AVAES *aes, const uint8_t *salt, int label,
+                       uint8_t *out, int outlen)
+{
+    uint8_t input[16] = { 0 };
+    memcpy(input, salt, 14);
+    // Key derivation rate assumed to be zero
+    input[14 - 7] ^= label;
+    memset(out, 0, outlen);
+    encrypt_counter(aes, input, out, outlen);
+}
+
+int ff_srtp_set_crypto(struct SRTPContext *s, const char *suite,
+                       const char *params)
+{
+    uint8_t buf[30];
+
+    ff_srtp_free(s);
+
+    // RFC 4568
+    if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_80") ||
+        !strcmp(suite, "SRTP_AES128_CM_HMAC_SHA1_80")) {
+        s->rtp_hmac_size = s->rtcp_hmac_size = 10;
+    } else if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_32")) {
+        s->rtp_hmac_size = s->rtcp_hmac_size = 4;
+    } else if (!strcmp(suite, "SRTP_AES128_CM_HMAC_SHA1_32")) {
+        // RFC 5764 section 4.1.2
+        s->rtp_hmac_size  = 4;
+        s->rtcp_hmac_size = 10;
+    } else {
+        av_log(NULL, AV_LOG_WARNING, "SRTP Crypto suite %s not supported\n",
+                                     suite);
+        return AVERROR(EINVAL);
+    }
+    if (av_base64_decode(buf, params, sizeof(buf)) != sizeof(buf)) {
+        av_log(NULL, AV_LOG_WARNING, "Incorrect amount of SRTP params\n");
+        return AVERROR(EINVAL);
+    }
+    // MKI and lifetime not handled yet
+    s->aes  = av_aes_alloc();
+    s->hmac = av_hmac_alloc(AV_HMAC_SHA1);
+    if (!s->aes || !s->hmac)
+        return AVERROR(ENOMEM);
+    memcpy(s->master_key, buf, 16);
+    memcpy(s->master_salt, buf + 16, 14);
+
+    // RFC 3711
+    av_aes_init(s->aes, s->master_key, 128, 0);
+
+    derive_key(s->aes, s->master_salt, 0x00, s->rtp_key, sizeof(s->rtp_key));
+    derive_key(s->aes, s->master_salt, 0x02, s->rtp_salt, sizeof(s->rtp_salt));
+    derive_key(s->aes, s->master_salt, 0x01, s->rtp_auth, sizeof(s->rtp_auth));
+
+    derive_key(s->aes, s->master_salt, 0x03, s->rtcp_key, sizeof(s->rtcp_key));
+    derive_key(s->aes, s->master_salt, 0x05, s->rtcp_salt, sizeof(s->rtcp_salt));
+    derive_key(s->aes, s->master_salt, 0x04, s->rtcp_auth, sizeof(s->rtcp_auth));
+    return 0;
+}
+
+static void create_iv(uint8_t *iv, const uint8_t *salt, uint64_t index,
+                      uint32_t ssrc)
+{
+    uint8_t indexbuf[8];
+    int i;
+    memset(iv, 0, 16);
+    AV_WB32(&iv[4], ssrc);
+    AV_WB64(indexbuf, index);
+    for (i = 0; i < 8; i++) // index << 16
+        iv[6 + i] ^= indexbuf[i];
+    for (i = 0; i < 14; i++)
+        iv[i] ^= salt[i];
+}
+
+int ff_srtp_decrypt(struct SRTPContext *s, uint8_t *buf, int *lenptr)
+{
+    uint8_t iv[16] = { 0 }, hmac[20];
+    int len = *lenptr;
+    int av_uninit(seq_largest);
+    uint32_t ssrc, av_uninit(roc);
+    uint64_t index;
+    int rtcp, hmac_size;
+
+    // TODO: Missing replay protection
+
+    if (len < 2)
+        return AVERROR_INVALIDDATA;
+
+    rtcp = RTP_PT_IS_RTCP(buf[1]);
+    hmac_size = rtcp ? s->rtcp_hmac_size : s->rtp_hmac_size;
+
+    if (len < hmac_size)
+        return AVERROR_INVALIDDATA;
+
+    // Authentication HMAC
+    av_hmac_init(s->hmac, rtcp ? s->rtcp_auth : s->rtp_auth, sizeof(s->rtp_auth));
+    // If MKI is used, this should exclude the MKI as well
+    av_hmac_update(s->hmac, buf, len - hmac_size);
+
+    if (!rtcp) {
+        int seq = AV_RB16(buf + 2);
+        uint32_t v;
+        uint8_t rocbuf[4];
+
+        // RFC 3711 section 3.3.1, appendix A
+        seq_largest = s->seq_initialized ? s->seq_largest : seq;
+        v = roc = s->roc;
+        if (seq_largest < 32768) {
+            if (seq - seq_largest > 32768)
+                v = roc - 1;
+        } else {
+            if (seq_largest - 32768 > seq)
+                v = roc + 1;
+        }
+        if (v == roc) {
+            seq_largest = FFMAX(seq_largest, seq);
+        } else if (v == roc + 1) {
+            seq_largest = seq;
+            roc = v;
+        }
+        index = seq + (((uint64_t)v) << 16);
+
+        AV_WB32(rocbuf, roc);
+        av_hmac_update(s->hmac, rocbuf, 4);
+    }
+
+    av_hmac_final(s->hmac, hmac, sizeof(hmac));
+    if (memcmp(hmac, buf + len - hmac_size, hmac_size)) {
+        av_log(NULL, AV_LOG_WARNING, "HMAC mismatch\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    len -= hmac_size;
+    *lenptr = len;
+
+    if (len < 12)
+        return AVERROR_INVALIDDATA;
+
+    if (rtcp) {
+        uint32_t srtcp_index = AV_RB32(buf + len - 4);
+        len -= 4;
+        *lenptr = len;
+
+        ssrc = AV_RB32(buf + 4);
+        index = srtcp_index & 0x7fffffff;
+
+        buf += 8;
+        len -= 8;
+        if (!(srtcp_index & 0x80000000))
+            return 0;
+    } else {
+        int ext, csrc;
+        s->seq_initialized = 1;
+        s->seq_largest     = seq_largest;
+        s->roc             = roc;
+
+        csrc = buf[0] & 0x0f;
+        ext  = buf[0] & 0x10;
+        ssrc = AV_RB32(buf + 8);
+
+        buf += 12;
+        len -= 12;
+
+        buf += 4 * csrc;
+        len -= 4 * csrc;
+        if (len < 0)
+            return AVERROR_INVALIDDATA;
+
+        if (ext) {
+            if (len < 4)
+                return AVERROR_INVALIDDATA;
+            ext = (AV_RB16(buf + 2) + 1) * 4;
+            if (len < ext)
+                return AVERROR_INVALIDDATA;
+            len -= ext;
+            buf += ext;
+        }
+    }
+
+    create_iv(iv, rtcp ? s->rtcp_salt : s->rtp_salt, index, ssrc);
+    av_aes_init(s->aes, rtcp ? s->rtcp_key : s->rtp_key, 128, 0);
+    encrypt_counter(s->aes, iv, buf, len);
+
+    return 0;
+}
+
+int ff_srtp_encrypt(struct SRTPContext *s, const uint8_t *in, int len,
+                    uint8_t *out, int outlen)
+{
+    uint8_t iv[16] = { 0 }, hmac[20];
+    uint64_t index;
+    uint32_t ssrc;
+    int rtcp, hmac_size, padding;
+    uint8_t *buf;
+
+    if (len < 8)
+        return AVERROR_INVALIDDATA;
+
+    rtcp = RTP_PT_IS_RTCP(in[1]);
+    hmac_size = rtcp ? s->rtcp_hmac_size : s->rtp_hmac_size;
+    padding = hmac_size;
+    if (rtcp)
+        padding += 4; // For the RTCP index
+
+    if (len + padding > outlen)
+        return 0;
+
+    memcpy(out, in, len);
+    buf = out;
+
+    if (rtcp) {
+        ssrc = AV_RB32(buf + 4);
+        index = s->rtcp_index++;
+
+        buf += 8;
+        len -= 8;
+    } else {
+        int ext, csrc;
+        int seq = AV_RB16(buf + 2);
+
+        if (len < 12)
+            return AVERROR_INVALIDDATA;
+
+        ssrc = AV_RB32(buf + 8);
+
+        if (seq < s->seq_largest)
+            s->roc++;
+        s->seq_largest = seq;
+        index = seq + (((uint64_t)s->roc) << 16);
+
+        csrc = buf[0] & 0x0f;
+        ext = buf[0] & 0x10;
+
+        buf += 12;
+        len -= 12;
+
+        buf += 4 * csrc;
+        len -= 4 * csrc;
+        if (len < 0)
+            return AVERROR_INVALIDDATA;
+
+        if (ext) {
+            if (len < 4)
+                return AVERROR_INVALIDDATA;
+            ext = (AV_RB16(buf + 2) + 1) * 4;
+            if (len < ext)
+                return AVERROR_INVALIDDATA;
+            len -= ext;
+            buf += ext;
+        }
+    }
+
+    create_iv(iv, rtcp ? s->rtcp_salt : s->rtp_salt, index, ssrc);
+    av_aes_init(s->aes, rtcp ? s->rtcp_key : s->rtp_key, 128, 0);
+    encrypt_counter(s->aes, iv, buf, len);
+
+    if (rtcp) {
+        AV_WB32(buf + len, 0x80000000 | index);
+        len += 4;
+    }
+
+    av_hmac_init(s->hmac, rtcp ? s->rtcp_auth : s->rtp_auth, sizeof(s->rtp_auth));
+    av_hmac_update(s->hmac, out, buf + len - out);
+    if (!rtcp) {
+        uint8_t rocbuf[4];
+        AV_WB32(rocbuf, s->roc);
+        av_hmac_update(s->hmac, rocbuf, 4);
+    }
+    av_hmac_final(s->hmac, hmac, sizeof(hmac));
+
+    memcpy(buf + len, hmac, hmac_size);
+    len += hmac_size;
+    return buf + len - out;
+}
+
+#ifdef TEST
+#include <stdio.h>
+
+static const char *aes128_80_key = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmn";
+
+static const uint8_t rtp_aes128_80[] = {
+    // RTP header
+    0x80, 0xe0, 0x12, 0x34, 0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78,
+    // encrypted payload
+    0x62, 0x69, 0x76, 0xca, 0xc5,
+    // HMAC
+    0xa1, 0xac, 0x1b, 0xb4, 0xa0, 0x1c, 0xd5, 0x49, 0x28, 0x99,
+};
+
+static const uint8_t rtcp_aes128_80[] = {
+    // RTCP header
+    0x81, 0xc9, 0x00, 0x07, 0x12, 0x34, 0x56, 0x78,
+    // encrypted payload
+    0x8a, 0xac, 0xdc, 0xa5, 0x4c, 0xf6, 0x78, 0xa6, 0x62, 0x8f, 0x24, 0xda,
+    0x6c, 0x09, 0x3f, 0xa9, 0x28, 0x7a, 0xb5, 0x7f, 0x1f, 0x0f, 0xc9, 0x35,
+    // RTCP index
+    0x80, 0x00, 0x00, 0x03,
+    // HMAC
+    0xe9, 0x3b, 0xc0, 0x5c, 0x0c, 0x06, 0x9f, 0xab, 0xc0, 0xde,
+};
+
+static const char *aes128_32_key = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmn";
+
+static const uint8_t rtp_aes128_32[] = {
+    // RTP header
+    0x80, 0xe0, 0x12, 0x34, 0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78,
+    // encrypted payload
+    0x62, 0x69, 0x76, 0xca, 0xc5,
+    // HMAC
+    0xa1, 0xac, 0x1b, 0xb4,
+};
+
+static const uint8_t rtcp_aes128_32[] = {
+    // RTCP header
+    0x81, 0xc9, 0x00, 0x07, 0x12, 0x34, 0x56, 0x78,
+    // encrypted payload
+    0x35, 0xe9, 0xb5, 0xff, 0x0d, 0xd1, 0xde, 0x70, 0x74, 0x10, 0xaa, 0x1b,
+    0xb2, 0x8d, 0xf0, 0x20, 0x02, 0x99, 0x6b, 0x1b, 0x0b, 0xd0, 0x47, 0x34,
+    // RTCP index
+    0x80, 0x00, 0x00, 0x04,
+    // HMAC
+    0x5b, 0xd2, 0xa9, 0x9d,
+};
+
+static const char *aes128_80_32_key = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmn";
+
+static const uint8_t rtp_aes128_80_32[] = {
+    // RTP header
+    0x80, 0xe0, 0x12, 0x34, 0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78,
+    // encrypted payload
+    0x62, 0x69, 0x76, 0xca, 0xc5,
+    // HMAC
+    0xa1, 0xac, 0x1b, 0xb4,
+};
+
+static const uint8_t rtcp_aes128_80_32[] = {
+    // RTCP header
+    0x81, 0xc9, 0x00, 0x07, 0x12, 0x34, 0x56, 0x78,
+    // encrypted payload
+    0xd6, 0xae, 0xc1, 0x58, 0x63, 0x70, 0xc9, 0x88, 0x66, 0x26, 0x1c, 0x53,
+    0xff, 0x5d, 0x5d, 0x2b, 0x0f, 0x8c, 0x72, 0x3e, 0xc9, 0x1d, 0x43, 0xf9,
+    // RTCP index
+    0x80, 0x00, 0x00, 0x05,
+    // HMAC
+    0x09, 0x16, 0xb4, 0x27, 0x9a, 0xe9, 0x92, 0x26, 0x4e, 0x10,
+};
+
+static void print_data(const uint8_t *buf, int len)
+{
+    int i;
+    for (i = 0; i < len; i++)
+        printf("%02x", buf[i]);
+    printf("\n");
+}
+
+static int test_decrypt(struct SRTPContext *srtp, const uint8_t *in, int len,
+                        uint8_t *out)
+{
+    memcpy(out, in, len);
+    if (!ff_srtp_decrypt(srtp, out, &len)) {
+        print_data(out, len);
+        return len;
+    } else
+        return -1;
+}
+
+static void test_encrypt(const uint8_t *data, int in_len, const char *suite,
+                         const char *key)
+{
+    struct SRTPContext enc = { 0 }, dec = { 0 };
+    int len;
+    char buf[1500];
+    ff_srtp_set_crypto(&enc, suite, key);
+    ff_srtp_set_crypto(&dec, suite, key);
+    len = ff_srtp_encrypt(&enc, data, in_len, buf, sizeof(buf));
+    if (!ff_srtp_decrypt(&dec, buf, &len)) {
+        if (len == in_len && !memcmp(buf, data, len))
+            printf("Decrypted content matches input\n");
+        else
+            printf("Decrypted content doesn't match input\n");
+    } else {
+        printf("Decryption failed\n");
+    }
+    ff_srtp_free(&enc);
+    ff_srtp_free(&dec);
+}
+
+int main(void)
+{
+    static const char *aes128_80_suite = "AES_CM_128_HMAC_SHA1_80";
+    static const char *aes128_32_suite = "AES_CM_128_HMAC_SHA1_32";
+    static const char *aes128_80_32_suite = "SRTP_AES128_CM_HMAC_SHA1_32";
+    static const char *test_key = "abcdefghijklmnopqrstuvwxyz1234567890ABCD";
+    uint8_t buf[1500];
+    struct SRTPContext srtp = { 0 };
+    int len;
+    ff_srtp_set_crypto(&srtp, aes128_80_suite, aes128_80_key);
+    len = test_decrypt(&srtp, rtp_aes128_80, sizeof(rtp_aes128_80), buf);
+    test_encrypt(buf, len, aes128_80_suite, test_key);
+    test_encrypt(buf, len, aes128_32_suite, test_key);
+    test_encrypt(buf, len, aes128_80_32_suite, test_key);
+    test_decrypt(&srtp, rtcp_aes128_80, sizeof(rtcp_aes128_80), buf);
+    test_encrypt(buf, len, aes128_80_suite, test_key);
+    test_encrypt(buf, len, aes128_32_suite, test_key);
+    test_encrypt(buf, len, aes128_80_32_suite, test_key);
+    ff_srtp_free(&srtp);
+
+    memset(&srtp, 0, sizeof(srtp)); // Clear the context
+    ff_srtp_set_crypto(&srtp, aes128_32_suite, aes128_32_key);
+    test_decrypt(&srtp, rtp_aes128_32, sizeof(rtp_aes128_32), buf);
+    test_decrypt(&srtp, rtcp_aes128_32, sizeof(rtcp_aes128_32), buf);
+    ff_srtp_free(&srtp);
+
+    memset(&srtp, 0, sizeof(srtp)); // Clear the context
+    ff_srtp_set_crypto(&srtp, aes128_80_32_suite, aes128_80_32_key);
+    test_decrypt(&srtp, rtp_aes128_80_32, sizeof(rtp_aes128_80_32), buf);
+    test_decrypt(&srtp, rtcp_aes128_80_32, sizeof(rtcp_aes128_80_32), buf);
+    ff_srtp_free(&srtp);
+    return 0;
+}
+#endif /* TEST */
diff --git a/libavformat/srtp.h b/libavformat/srtp.h
new file mode 100644
index 0000000..3189f8f
--- /dev/null
+++ b/libavformat/srtp.h
@@ -0,0 +1,52 @@
+/*
+ * SRTP encryption/decryption
+ * 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
+ */
+
+#ifndef AVFORMAT_SRTP_H
+#define AVFORMAT_SRTP_H
+
+#include <stdint.h>
+
+struct AVAES;
+struct AVHMAC;
+
+struct SRTPContext {
+    struct AVAES *aes;
+    struct AVHMAC *hmac;
+    int rtp_hmac_size, rtcp_hmac_size;
+    uint8_t master_key[16];
+    uint8_t master_salt[14];
+    uint8_t rtp_key[16],  rtcp_key[16];
+    uint8_t rtp_salt[14], rtcp_salt[14];
+    uint8_t rtp_auth[20], rtcp_auth[20];
+    int seq_largest, seq_initialized;
+    uint32_t roc;
+
+    uint32_t rtcp_index;
+};
+
+int ff_srtp_set_crypto(struct SRTPContext *s, const char *suite,
+                       const char *params);
+void ff_srtp_free(struct SRTPContext *s);
+int ff_srtp_decrypt(struct SRTPContext *s, uint8_t *buf, int *lenptr);
+int ff_srtp_encrypt(struct SRTPContext *s, const uint8_t *in, int len,
+                    uint8_t *out, int outlen);
+
+#endif /* AVFORMAT_SRTP_H */
diff --git a/libavformat/srtpproto.c b/libavformat/srtpproto.c
new file mode 100644
index 0000000..f5e3d14
--- /dev/null
+++ b/libavformat/srtpproto.c
@@ -0,0 +1,144 @@
+/*
+ * SRTP network protocol
+ * 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 "libavutil/opt.h"
+#include "avformat.h"
+#include "avio_internal.h"
+#include "url.h"
+
+#include "internal.h"
+#include "srtp.h"
+
+typedef struct SRTPProtoContext {
+    const AVClass *class;
+    URLContext *rtp_hd;
+    const char *out_suite, *out_params;
+    const char *in_suite, *in_params;
+    struct SRTPContext srtp_out, srtp_in;
+    uint8_t encryptbuf[1500];
+} SRTPProtoContext;
+
+#define D AV_OPT_FLAG_DECODING_PARAM
+#define E AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+    { "srtp_out_suite", "", offsetof(SRTPProtoContext, out_suite), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E },
+    { "srtp_out_params", "", offsetof(SRTPProtoContext, out_params), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E },
+    { "srtp_in_suite", "", offsetof(SRTPProtoContext, in_suite), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E },
+    { "srtp_in_params", "", offsetof(SRTPProtoContext, in_params), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E },
+    { NULL }
+};
+
+static const AVClass srtp_context_class = {
+    .class_name     = "srtp",
+    .item_name      = av_default_item_name,
+    .option         = options,
+    .version        = LIBAVUTIL_VERSION_INT,
+};
+
+static int srtp_close(URLContext *h)
+{
+    SRTPProtoContext *s = h->priv_data;
+    ff_srtp_free(&s->srtp_out);
+    ff_srtp_free(&s->srtp_in);
+    ffurl_close(s->rtp_hd);
+    s->rtp_hd = NULL;
+    return 0;
+}
+
+static int srtp_open(URLContext *h, const char *uri, int flags)
+{
+    SRTPProtoContext *s = h->priv_data;
+    char hostname[256], buf[1024], path[1024];
+    int rtp_port, ret;
+
+    if (s->out_suite && s->out_params)
+        if ((ret = ff_srtp_set_crypto(&s->srtp_out, s->out_suite, s->out_params)) < 0)
+            goto fail;
+    if (s->in_suite && s->in_params)
+        if ((ret = ff_srtp_set_crypto(&s->srtp_in, s->in_suite, s->in_params)) < 0)
+            goto fail;
+
+    av_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &rtp_port,
+                 path, sizeof(path), uri);
+    ff_url_join(buf, sizeof(buf), "rtp", NULL, hostname, rtp_port, "%s", path);
+    if ((ret = ffurl_open(&s->rtp_hd, buf, flags, &h->interrupt_callback, NULL)) < 0)
+        goto fail;
+
+    h->max_packet_size = FFMIN(s->rtp_hd->max_packet_size,
+                               sizeof(s->encryptbuf)) - 14;
+    h->is_streamed = 1;
+    return 0;
+
+fail:
+    srtp_close(h);
+    return ret;
+}
+
+static int srtp_read(URLContext *h, uint8_t *buf, int size)
+{
+    SRTPProtoContext *s = h->priv_data;
+    int ret;
+start:
+    ret = ffurl_read(s->rtp_hd, buf, size);
+    if (ret > 0 && s->srtp_in.aes) {
+        if (ff_srtp_decrypt(&s->srtp_in, buf, &ret) < 0)
+            goto start;
+    }
+    return ret;
+}
+
+static int srtp_write(URLContext *h, const uint8_t *buf, int size)
+{
+    SRTPProtoContext *s = h->priv_data;
+    if (!s->srtp_out.aes)
+        return ffurl_write(s->rtp_hd, buf, size);
+    size = ff_srtp_encrypt(&s->srtp_out, buf, size, s->encryptbuf,
+                           sizeof(s->encryptbuf));
+    if (size < 0)
+        return size;
+    return ffurl_write(s->rtp_hd, s->encryptbuf, size);
+}
+
+static int srtp_get_file_handle(URLContext *h)
+{
+    SRTPProtoContext *s = h->priv_data;
+    return ffurl_get_file_handle(s->rtp_hd);
+}
+
+static int srtp_get_multi_file_handle(URLContext *h, int **handles,
+                                      int *numhandles)
+{
+    SRTPProtoContext *s = h->priv_data;
+    return ffurl_get_multi_file_handle(s->rtp_hd, handles, numhandles);
+}
+
+URLProtocol ff_srtp_protocol = {
+    .name                      = "srtp",
+    .url_open                  = srtp_open,
+    .url_read                  = srtp_read,
+    .url_write                 = srtp_write,
+    .url_close                 = srtp_close,
+    .url_get_file_handle       = srtp_get_file_handle,
+    .url_get_multi_file_handle = srtp_get_multi_file_handle,
+    .priv_data_size            = sizeof(SRTPProtoContext),
+    .priv_data_class           = &srtp_context_class,
+    .flags                     = URL_PROTOCOL_FLAG_NETWORK,
+};
diff --git a/libavformat/subtitles.c b/libavformat/subtitles.c
index b264ec5..5462616 100644
--- a/libavformat/subtitles.c
+++ b/libavformat/subtitles.c
@@ -104,16 +104,6 @@
         int i, idx = -1;
         int64_t min_ts_diff = INT64_MAX;
         int64_t ts_selected;
-        if (stream_index == -1) {
-            AVRational time_base = s->streams[0]->time_base;
-            ts = av_rescale_q(ts, AV_TIME_BASE_Q, time_base);
-            min_ts = av_rescale_rnd(min_ts, time_base.den,
-                                    time_base.num * (int64_t)AV_TIME_BASE,
-                                    AV_ROUND_UP);
-            max_ts = av_rescale_rnd(max_ts, time_base.den,
-                                    time_base.num * (int64_t)AV_TIME_BASE,
-                                    AV_ROUND_DOWN);
-        }
         /* TODO: q->subs[] is sorted by pts so we could do a binary search */
         for (i = 0; i < q->nb_subs; i++) {
             int64_t pts = q->subs[i].pts;
@@ -192,3 +182,49 @@
     }
     return NULL;
 }
+
+static inline int is_eol(char c)
+{
+    return c == '\r' || c == '\n';
+}
+
+void ff_subtitles_read_chunk(AVIOContext *pb, AVBPrint *buf)
+{
+    char eol_buf[5];
+    int n = 0, i = 0, nb_eol = 0;
+
+    av_bprint_clear(buf);
+
+    for (;;) {
+        char c = avio_r8(pb);
+
+        if (!c)
+            break;
+
+        /* ignore all initial line breaks */
+        if (n == 0 && is_eol(c))
+            continue;
+
+        /* line break buffering: we don't want to add the trailing \r\n */
+        if (is_eol(c)) {
+            nb_eol += c == '\n';
+            if (nb_eol == 2)
+                break;
+            eol_buf[i++] = c;
+            if (i == sizeof(eol_buf) - 1)
+                break;
+            continue;
+        }
+
+        /* only one line break followed by data: we flush the line breaks
+         * buffer */
+        if (i) {
+            eol_buf[i] = 0;
+            av_bprintf(buf, "%s", eol_buf);
+            i = nb_eol = 0;
+        }
+
+        av_bprint_chars(buf, c, 1);
+        n++;
+    }
+}
diff --git a/libavformat/subtitles.h b/libavformat/subtitles.h
index 55e6182..455b374 100644
--- a/libavformat/subtitles.h
+++ b/libavformat/subtitles.h
@@ -81,4 +81,19 @@
  */
 const char *ff_smil_get_attr_ptr(const char *s, const char *attr);
 
+/**
+ * @brief Read a subtitles chunk.
+ *
+ * A chunk is defined by a multiline "event", ending with a second line break.
+ * The trailing line breaks are trimmed. CRLF are supported.
+ * Example: "foo\r\nbar\r\n\r\nnext" will print "foo\r\nbar" into buf, and pb
+ * will focus on the 'n' of the "next" string.
+ *
+ * @param pb  I/O context
+ * @param buf an initialized buf where the chunk is written
+ *
+ * @note buf is cleared before writing into it.
+ */
+void ff_subtitles_read_chunk(AVIOContext *pb, AVBPrint *buf);
+
 #endif /* AVFORMAT_SUBTITLES_H */
diff --git a/libavformat/subviewer1dec.c b/libavformat/subviewer1dec.c
new file mode 100644
index 0000000..0dc1942
--- /dev/null
+++ b/libavformat/subviewer1dec.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2012 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
+ * SubViewer v1 subtitle demuxer
+ */
+
+#include "avformat.h"
+#include "internal.h"
+#include "subtitles.h"
+
+typedef struct {
+    FFDemuxSubtitlesQueue q;
+} SubViewer1Context;
+
+static int subviewer1_probe(AVProbeData *p)
+{
+    const unsigned char *ptr = p->buf;
+
+    if (strstr(ptr, "******** START SCRIPT ********"))
+        return AVPROBE_SCORE_MAX / 2;
+    return 0;
+}
+
+static int subviewer1_read_header(AVFormatContext *s)
+{
+    int delay = 0;
+    AVPacket *sub = NULL;
+    SubViewer1Context *subviewer1 = s->priv_data;
+    AVStream *st = avformat_new_stream(s, NULL);
+
+    if (!st)
+        return AVERROR(ENOMEM);
+    avpriv_set_pts_info(st, 64, 1, 1);
+    st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
+    st->codec->codec_id   = AV_CODEC_ID_SUBVIEWER1;
+
+    while (!url_feof(s->pb)) {
+        char line[4096];
+        int len = ff_get_line(s->pb, line, sizeof(line));
+        int hh, mm, ss;
+
+        if (!len)
+            break;
+
+        if (!strncmp(line, "[DELAY]", 7)) {
+            ff_get_line(s->pb, line, sizeof(line));
+            sscanf(line, "%d", &delay);
+        }
+
+        if (sscanf(line, "[%d:%d:%d]", &hh, &mm, &ss) == 3) {
+            const int64_t pos = avio_tell(s->pb);
+            int64_t pts_start = hh*3600LL + mm*60LL + ss + delay;
+
+            len = ff_get_line(s->pb, line, sizeof(line));
+            line[strcspn(line, "\r\n")] = 0;
+            if (!*line) {
+                if (sub)
+                    sub->duration = pts_start - sub->pts;
+            } else {
+                sub = ff_subtitles_queue_insert(&subviewer1->q, line, len, 0);
+                if (!sub)
+                    return AVERROR(ENOMEM);
+                sub->pos = pos;
+                sub->pts = pts_start;
+                sub->duration = -1;
+            }
+        }
+    }
+
+    ff_subtitles_queue_finalize(&subviewer1->q);
+    return 0;
+}
+
+static int subviewer1_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    SubViewer1Context *subviewer1 = s->priv_data;
+    return ff_subtitles_queue_read_packet(&subviewer1->q, pkt);
+}
+
+static int subviewer1_read_seek(AVFormatContext *s, int stream_index,
+                               int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
+{
+    SubViewer1Context *subviewer1 = s->priv_data;
+    return ff_subtitles_queue_seek(&subviewer1->q, s, stream_index,
+                                   min_ts, ts, max_ts, flags);
+}
+
+static int subviewer1_read_close(AVFormatContext *s)
+{
+    SubViewer1Context *subviewer1 = s->priv_data;
+    ff_subtitles_queue_clean(&subviewer1->q);
+    return 0;
+}
+
+AVInputFormat ff_subviewer1_demuxer = {
+    .name           = "subviewer1",
+    .long_name      = NULL_IF_CONFIG_SMALL("SubViewer v1 subtitle format"),
+    .priv_data_size = sizeof(SubViewer1Context),
+    .read_probe     = subviewer1_probe,
+    .read_header    = subviewer1_read_header,
+    .read_packet    = subviewer1_read_packet,
+    .read_seek2     = subviewer1_read_seek,
+    .read_close     = subviewer1_read_close,
+    .extensions     = "sub",
+};
diff --git a/libavformat/subviewerdec.c b/libavformat/subviewerdec.c
index 7691d82..7cacd97 100644
--- a/libavformat/subviewerdec.c
+++ b/libavformat/subviewerdec.c
@@ -27,6 +27,7 @@
 #include "avformat.h"
 #include "internal.h"
 #include "subtitles.h"
+#include "libavcodec/internal.h"
 #include "libavutil/avstring.h"
 #include "libavutil/bprint.h"
 #include "libavutil/intreadwrite.h"
@@ -70,7 +71,10 @@
     SubViewerContext *subviewer = s->priv_data;
     AVStream *st = avformat_new_stream(s, NULL);
     AVBPrint header;
-    int res = 0;
+    int res = 0, new_event = 1;
+    int64_t pts_start = AV_NOPTS_VALUE;
+    int duration = -1;
+    AVPacket *sub = NULL;
 
     if (!st)
         return AVERROR(ENOMEM);
@@ -82,12 +86,14 @@
 
     while (!url_feof(s->pb)) {
         char line[2048];
-        const int64_t pos = avio_tell(s->pb);
+        int64_t pos = 0;
         int len = ff_get_line(s->pb, line, sizeof(line));
 
         if (!len)
             break;
 
+        line[strcspn(line, "\r\n")] = 0;
+
         if (line[0] == '[' && strncmp(line, "[br]", 4)) {
 
             /* ignore event style, XXX: add to side_data? */
@@ -96,15 +102,12 @@
                 continue;
 
             if (!st->codec->extradata) { // header not finalized yet
-                av_bprintf(&header, "%s", line);
+                av_bprintf(&header, "%s\n", line);
                 if (!strncmp(line, "[END INFORMATION]", 17) || !strncmp(line, "[SUBTITLE]", 10)) {
                     /* end of header */
-                    av_bprint_finalize(&header, (char **)&st->codec->extradata);
-                    if (!st->codec->extradata) {
-                        res = AVERROR(ENOMEM);
+                    res = avpriv_bprint_to_extradata(st->codec, &header);
+                    if (res < 0)
                         goto end;
-                    }
-                    st->codec->extradata_size = header.len + 1;
                 } else if (strncmp(line, "[INFORMATION]", 13)) {
                     /* assume file metadata at this point */
                     int i, j = 0;
@@ -118,29 +121,35 @@
                         i++;
                     while (line[i] == ' ')
                         i++;
-                    while (j < sizeof(value) - 1 && line[i] && !strchr("]\r\n", line[i]))
+                    while (j < sizeof(value) - 1 && line[i] && line[i] != ']')
                         value[j++] = line[i++];
                     value[j] = 0;
 
                     av_dict_set(&s->metadata, key, value, 0);
                 }
             }
-        } else {
-            int64_t pts_start = AV_NOPTS_VALUE;
-            int duration = -1;
-            int timed_line = !read_ts(line, &pts_start, &duration);
-            AVPacket *sub;
-
-            sub = ff_subtitles_queue_insert(&subviewer->q, line, len, !timed_line);
+        } else if (read_ts(line, &pts_start, &duration) >= 0) {
+            new_event = 1;
+            pos = avio_tell(s->pb);
+        } else if (*line) {
+            if (!new_event) {
+                sub = ff_subtitles_queue_insert(&subviewer->q, "\n", 1, 1);
+                if (!sub) {
+                    res = AVERROR(ENOMEM);
+                    goto end;
+                }
+            }
+            sub = ff_subtitles_queue_insert(&subviewer->q, line, strlen(line), !new_event);
             if (!sub) {
                 res = AVERROR(ENOMEM);
                 goto end;
             }
-            if (timed_line) {
+            if (new_event) {
                 sub->pos = pos;
                 sub->pts = pts_start;
                 sub->duration = duration;
             }
+            new_event = 0;
         }
     }
 
@@ -181,6 +190,5 @@
     .read_packet    = subviewer_read_packet,
     .read_seek2     = subviewer_read_seek,
     .read_close     = subviewer_read_close,
-    .flags          = AVFMT_GENERIC_INDEX,
     .extensions     = "sub",
 };
diff --git a/libavformat/swfdec.c b/libavformat/swfdec.c
index 6918b01..54e0f6d 100644
--- a/libavformat/swfdec.c
+++ b/libavformat/swfdec.c
@@ -138,6 +138,32 @@
     return 0;
 }
 
+static AVStream *create_new_audio_stream(AVFormatContext *s, int id, int info)
+{
+    int sample_rate_code, sample_size_code;
+    AVStream *ast = avformat_new_stream(s, NULL);
+    if (!ast)
+        return NULL;
+    ast->id = id;
+    if (info & 1) {
+        ast->codec->channels       = 2;
+        ast->codec->channel_layout = AV_CH_LAYOUT_STEREO;
+    } else {
+        ast->codec->channels       = 1;
+        ast->codec->channel_layout = AV_CH_LAYOUT_MONO;
+    }
+    ast->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+    ast->codec->codec_id   = ff_codec_get_id(swf_audio_codec_tags, info>>4 & 15);
+    ast->need_parsing = AVSTREAM_PARSE_FULL;
+    sample_rate_code = info>>2 & 3;
+    sample_size_code = info>>1 & 1;
+    if (!sample_size_code && ast->codec->codec_id == AV_CODEC_ID_PCM_S16LE)
+        ast->codec->codec_id = AV_CODEC_ID_PCM_U8;
+    ast->codec->sample_rate = 44100 >> (3 - sample_rate_code);
+    avpriv_set_pts_info(ast, 64, 1, ast->codec->sample_rate);
+    return ast;
+}
+
 static int swf_read_packet(AVFormatContext *s, AVPacket *pkt)
 {
     SWFContext *swf = s->priv_data;
@@ -155,6 +181,10 @@
         tag = get_swf_tag(pb, &len);
         if (tag < 0)
             return tag;
+        if (len < 0) {
+            av_log(s, AV_LOG_ERROR, "invalid tag length: %d\n", len);
+            return AVERROR_INVALIDDATA;
+        }
         if (tag == TAG_VIDEOSTREAM) {
             int ch_id = avio_rl16(pb);
             len -= 2;
@@ -180,7 +210,6 @@
             len -= 8;
         } else if (tag == TAG_STREAMHEAD || tag == TAG_STREAMHEAD2) {
             /* streaming found */
-            int sample_rate_code;
 
             for (i=0; i<s->nb_streams; i++) {
                 st = s->streams[i];
@@ -191,27 +220,12 @@
             avio_r8(pb);
             v = avio_r8(pb);
             swf->samples_per_frame = avio_rl16(pb);
-            ast = avformat_new_stream(s, NULL);
+            ast = create_new_audio_stream(s, -1, v); /* -1 to avoid clash with video stream ch_id */
             if (!ast)
                 return AVERROR(ENOMEM);
-            ast->id = -1; /* -1 to avoid clash with video stream ch_id */
-            if (v & 1) {
-                ast->codec->channels       = 2;
-                ast->codec->channel_layout = AV_CH_LAYOUT_STEREO;
-            } else {
-                ast->codec->channels       = 1;
-                ast->codec->channel_layout = AV_CH_LAYOUT_MONO;
-            }
-            ast->codec->codec_type = AVMEDIA_TYPE_AUDIO;
-            ast->codec->codec_id = ff_codec_get_id(swf_audio_codec_tags, (v>>4) & 15);
-            ast->need_parsing = AVSTREAM_PARSE_FULL;
-            sample_rate_code= (v>>2) & 3;
-            ast->codec->sample_rate = 44100 >> (3 - sample_rate_code);
-            avpriv_set_pts_info(ast, 64, 1, ast->codec->sample_rate);
             len -= 4;
         } else if (tag == TAG_DEFINESOUND) {
             /* audio stream */
-            int sample_rate_code;
             int ch_id = avio_rl16(pb);
 
             for (i=0; i<s->nb_streams; i++) {
@@ -220,22 +234,13 @@
                     goto skip;
             }
 
-            // FIXME: 8-bit uncompressed PCM audio will be interpreted as 16-bit
             // FIXME: The entire audio stream is stored in a single chunk/tag. Normally,
             // these are smaller audio streams in DEFINESOUND tags, but it's technically
             // possible they could be huge. Break it up into multiple packets if it's big.
             v = avio_r8(pb);
-            ast = avformat_new_stream(s, NULL);
+            ast = create_new_audio_stream(s, ch_id, v);
             if (!ast)
                 return AVERROR(ENOMEM);
-            ast->id = ch_id;
-            ast->codec->channels = 1 + (v&1);
-            ast->codec->codec_type = AVMEDIA_TYPE_AUDIO;
-            ast->codec->codec_id = ff_codec_get_id(swf_audio_codec_tags, (v>>4) & 15);
-            ast->need_parsing = AVSTREAM_PARSE_FULL;
-            sample_rate_code= (v>>2) & 3;
-            ast->codec->sample_rate = 44100 >> (3 - sample_rate_code);
-            avpriv_set_pts_info(ast, 64, 1, ast->codec->sample_rate);
             ast->duration = avio_rl32(pb); // number of samples
             if (((v>>4) & 15) == 2) { // MP3 sound data record
                 ast->skip_samples = avio_rl16(pb);
@@ -254,7 +259,10 @@
                 st = s->streams[i];
                 if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && st->id == ch_id) {
                     frame = avio_rl16(pb);
-                    if ((res = av_get_packet(pb, pkt, len-2)) < 0)
+                    len -= 2;
+                    if (len <= 0)
+                        goto skip;
+                    if ((res = av_get_packet(pb, pkt, len)) < 0)
                         return res;
                     pkt->pos = pos;
                     pkt->pts = frame;
@@ -392,17 +400,22 @@
             for (i = 0; i < s->nb_streams; i++) {
                 st = s->streams[i];
                 if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && st->id == -1) {
-            if (st->codec->codec_id == AV_CODEC_ID_MP3) {
-                avio_skip(pb, 4);
-                if ((res = av_get_packet(pb, pkt, len-4)) < 0)
-                    return res;
-            } else { // ADPCM, PCM
-                if ((res = av_get_packet(pb, pkt, len)) < 0)
-                    return res;
-            }
-            pkt->pos = pos;
-            pkt->stream_index = st->index;
-            return pkt->size;
+                    if (st->codec->codec_id == AV_CODEC_ID_MP3) {
+                        avio_skip(pb, 4);
+                        len -= 4;
+                        if (len <= 0)
+                            goto skip;
+                        if ((res = av_get_packet(pb, pkt, len)) < 0)
+                            return res;
+                    } else { // ADPCM, PCM
+                        if (len <= 0)
+                            goto skip;
+                        if ((res = av_get_packet(pb, pkt, len)) < 0)
+                            return res;
+                    }
+                    pkt->pos          = pos;
+                    pkt->stream_index = st->index;
+                    return pkt->size;
                 }
             }
         } else if (tag == TAG_JPEG2) {
@@ -422,7 +435,10 @@
                 st = vst;
             }
             avio_rl16(pb); /* BITMAP_ID */
-            if ((res = av_new_packet(pkt, len-2)) < 0)
+            len -= 2;
+            if (len < 4)
+                goto skip;
+            if ((res = av_new_packet(pkt, len)) < 0)
                 return res;
             avio_read(pb, pkt->data, 4);
             if (AV_RB32(pkt->data) == 0xffd8ffd9 ||
@@ -437,8 +453,13 @@
             pkt->pos = pos;
             pkt->stream_index = st->index;
             return pkt->size;
+        } else {
+            av_log(s, AV_LOG_DEBUG, "Unknown tag: %d\n", tag);
         }
     skip:
+        if(len<0)
+            av_log(s, AV_LOG_WARNING, "Cliping len %d\n", len);
+        len = FFMAX(0, len);
         avio_skip(pb, len);
     }
 }
diff --git a/libavformat/swfenc.c b/libavformat/swfenc.c
index a8fd9f9..5b7fd1f 100644
--- a/libavformat/swfenc.c
+++ b/libavformat/swfenc.c
@@ -192,6 +192,10 @@
                 return AVERROR_INVALIDDATA;
             }
             if (enc->codec_id == AV_CODEC_ID_MP3) {
+                if (!enc->frame_size) {
+                    av_log(s, AV_LOG_ERROR, "audio frame size not set\n");
+                    return -1;
+                }
                 swf->audio_enc = enc;
                 swf->audio_fifo= av_fifo_alloc(AUDIO_FIFO_SIZE);
                 if (!swf->audio_fifo)
@@ -457,7 +461,7 @@
     }
 
     av_fifo_generic_write(swf->audio_fifo, buf, size, NULL);
-    swf->sound_samples += av_get_audio_frame_duration(enc, size);
+    swf->sound_samples += enc->frame_size;
 
     /* if audio only stream make sure we add swf frames */
     if (!swf->video_enc)
diff --git a/libavformat/takdec.c b/libavformat/takdec.c
index a529017..377c10c 100644
--- a/libavformat/takdec.c
+++ b/libavformat/takdec.c
@@ -26,8 +26,8 @@
 #include "apetag.h"
 
 typedef struct TAKDemuxContext {
-    int      mlast_frame;
-    int64_t  data_end;
+    int     mlast_frame;
+    int64_t data_end;
 } TAKDemuxContext;
 
 static int tak_probe(AVProbeData *p)
@@ -40,7 +40,7 @@
 static int tak_read_header(AVFormatContext *s)
 {
     TAKDemuxContext *tc = s->priv_data;
-    AVIOContext *pb = s->pb;
+    AVIOContext *pb     = s->pb;
     GetBitContext gb;
     AVStream *st;
     uint8_t *buffer = NULL;
@@ -95,7 +95,7 @@
                 av_log(s, AV_LOG_VERBOSE, "%02x", md5[i]);
             av_log(s, AV_LOG_VERBOSE, "\n");
             break;
-            }
+        }
         case TAK_METADATA_END: {
             int64_t curpos = avio_tell(pb);
 
@@ -106,8 +106,7 @@
 
             tc->data_end += curpos;
             return 0;
-            break;
-            }
+        }
         default:
             ret = avio_skip(pb, size);
             if (ret < 0)
@@ -123,19 +122,19 @@
             st->codec->bits_per_coded_sample = ti.bps;
             if (ti.ch_layout)
                 st->codec->channel_layout = ti.ch_layout;
-            st->codec->sample_rate = ti.sample_rate;
-            st->codec->channels    = ti.channels;
-            st->start_time         = 0;
+            st->codec->sample_rate           = ti.sample_rate;
+            st->codec->channels              = ti.channels;
+            st->start_time                   = 0;
             avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
-            st->codec->extradata      = buffer;
-            st->codec->extradata_size = size;
-            buffer = NULL;
+            st->codec->extradata             = buffer;
+            st->codec->extradata_size        = size;
+            buffer                           = NULL;
         } else if (type == TAK_METADATA_LAST_FRAME) {
             if (size != 11)
                 return AVERROR_INVALIDDATA;
             tc->mlast_frame = 1;
-            tc->data_end = get_bits_longlong(&gb, TAK_LAST_FRAME_POS_BITS) +
-                           get_bits(&gb, TAK_LAST_FRAME_SIZE_BITS);
+            tc->data_end    = get_bits64(&gb, TAK_LAST_FRAME_POS_BITS) +
+                              get_bits(&gb, TAK_LAST_FRAME_SIZE_BITS);
             av_freep(&buffer);
         } else if (type == TAK_METADATA_ENCODER) {
             av_log(s, AV_LOG_VERBOSE, "encoder version: %0X\n",
diff --git a/libavformat/tedcaptionsdec.c b/libavformat/tedcaptionsdec.c
new file mode 100644
index 0000000..85bed0a
--- /dev/null
+++ b/libavformat/tedcaptionsdec.c
@@ -0,0 +1,365 @@
+/*
+ * TED Talks captions format decoder
+ * Copyright (c) 2012 Nicolas George
+ *
+ * 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/bprint.h"
+#include "libavutil/log.h"
+#include "libavutil/opt.h"
+#include "avformat.h"
+#include "internal.h"
+#include "subtitles.h"
+
+typedef struct {
+    AVClass *class;
+    int64_t start_time;
+    FFDemuxSubtitlesQueue subs;
+} TEDCaptionsDemuxer;
+
+static const AVOption tedcaptions_options[] = {
+    { "start_time", "set the start time (offset) of the subtitles, in ms",
+      offsetof(TEDCaptionsDemuxer, start_time), FF_OPT_TYPE_INT64,
+      { .i64 = 15000 }, INT64_MIN, INT64_MAX,
+      AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_DECODING_PARAM },
+    { NULL },
+};
+
+static const AVClass tedcaptions_demuxer_class = {
+    .class_name = "tedcaptions_demuxer",
+    .item_name  = av_default_item_name,
+    .option     = tedcaptions_options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+#define BETWEEN(a, amin, amax) ((unsigned)((a) - (amin)) <= (amax) - (amin))
+
+#define HEX_DIGIT_TEST(c) (BETWEEN(c, '0', '9') || BETWEEN((c) | 32, 'a', 'z'))
+#define HEX_DIGIT_VAL(c) ((c) <= '9' ? (c) - '0' : ((c) | 32) - 'a' + 10)
+#define ERR_CODE(c) (c < 0 ? c : AVERROR_INVALIDDATA)
+
+static void av_bprint_utf8(AVBPrint *bp, unsigned c)
+{
+    int bytes, i;
+
+    if (c <= 0x7F) {
+        av_bprint_chars(bp, c, 1);
+        return;
+    }
+    bytes = (av_log2(c) - 2) / 5;
+    av_bprint_chars(bp, (c >> (bytes * 6)) | ((0xFF80 >> bytes) & 0xFF), 1);
+    for (i = bytes - 1; i >= 0; i--)
+        av_bprint_chars(bp, ((c >> (i * 6)) & 0x3F) | 0x80, 1);
+}
+
+static void next_byte(AVIOContext *pb, int *cur_byte)
+{
+    uint8_t b;
+    int ret = avio_read(pb, &b, 1);
+    *cur_byte = ret > 0 ? b : ret == 0 ? AVERROR_EOF : ret;
+}
+
+static void skip_spaces(AVIOContext *pb, int *cur_byte)
+{
+    while (*cur_byte == ' '  || *cur_byte == '\t' ||
+           *cur_byte == '\n' || *cur_byte == '\r')
+        next_byte(pb, cur_byte);
+}
+
+static int expect_byte(AVIOContext *pb, int *cur_byte, uint8_t c)
+{
+    skip_spaces(pb, cur_byte);
+    if (*cur_byte != c)
+        return ERR_CODE(*cur_byte);
+    next_byte(pb, cur_byte);
+    return 0;
+}
+
+static int parse_string(AVIOContext *pb, int *cur_byte, AVBPrint *bp, int full)
+{
+    int ret;
+
+    av_bprint_init(bp, 0, full ? -1 : 1);
+    ret = expect_byte(pb, cur_byte, '"');
+    if (ret < 0)
+        goto fail;
+    while (*cur_byte > 0 && *cur_byte != '"') {
+        if (*cur_byte == '\\') {
+            next_byte(pb, cur_byte);
+            if (*cur_byte < 0) {
+                ret = AVERROR_INVALIDDATA;
+                goto fail;
+            }
+            if ((*cur_byte | 32) == 'u') {
+                unsigned chr = 0, i;
+                for (i = 0; i < 4; i++) {
+                    next_byte(pb, cur_byte);
+                    if (!HEX_DIGIT_TEST(*cur_byte)) {
+                        ret = ERR_CODE(*cur_byte);
+                        goto fail;
+                    }
+                    chr = chr * 16 + HEX_DIGIT_VAL(*cur_byte);
+                }
+                av_bprint_utf8(bp, chr);
+            } else {
+                av_bprint_chars(bp, *cur_byte, 1);
+            }
+        } else {
+            av_bprint_chars(bp, *cur_byte, 1);
+        }
+        next_byte(pb, cur_byte);
+    }
+    ret = expect_byte(pb, cur_byte, '"');
+    if (ret < 0)
+        goto fail;
+    if (full && !av_bprint_is_complete(bp)) {
+        ret = AVERROR(ENOMEM);
+        goto fail;
+    }
+    return 0;
+
+fail:
+    av_bprint_finalize(bp, NULL);
+    return ret;
+}
+
+static int parse_label(AVIOContext *pb, int *cur_byte, AVBPrint *bp)
+{
+    int ret;
+
+    ret = parse_string(pb, cur_byte, bp, 0);
+    if (ret < 0)
+        return ret;
+    ret = expect_byte(pb, cur_byte, ':');
+    if (ret < 0)
+        return ret;
+    return 0;
+}
+
+static int parse_boolean(AVIOContext *pb, int *cur_byte, int *result)
+{
+    const char *text[] = { "false", "true" }, *p;
+    int i;
+
+    skip_spaces(pb, cur_byte);
+    for (i = 0; i < 2; i++) {
+        p = text[i];
+        if (*cur_byte != *p)
+            continue;
+        for (; *p; p++, next_byte(pb, cur_byte))
+            if (*cur_byte != *p)
+                return AVERROR_INVALIDDATA;
+        if (BETWEEN(*cur_byte | 32, 'a', 'z'))
+            return AVERROR_INVALIDDATA;
+        *result = i;
+        return 0;
+    }
+    return AVERROR_INVALIDDATA;
+}
+
+static int parse_int(AVIOContext *pb, int *cur_byte, int64_t *result)
+{
+    int64_t val = 0;
+
+    skip_spaces(pb, cur_byte);
+    if ((unsigned)*cur_byte - '0' > 9)
+        return AVERROR_INVALIDDATA;
+    while (BETWEEN(*cur_byte, '0', '9')) {
+        val = val * 10 + (*cur_byte - '0');
+        next_byte(pb, cur_byte);
+    }
+    *result = val;
+    return 0;
+}
+
+static int parse_file(AVIOContext *pb, FFDemuxSubtitlesQueue *subs)
+{
+    int ret, cur_byte, start_of_par;
+    AVBPrint label, content;
+    int64_t pos, start, duration;
+    AVPacket *pkt;
+
+    next_byte(pb, &cur_byte);
+    ret = expect_byte(pb, &cur_byte, '{');
+    if (ret < 0)
+        return AVERROR_INVALIDDATA;
+    ret = parse_label(pb, &cur_byte, &label);
+    if (ret < 0 || strcmp(label.str, "captions"))
+        return AVERROR_INVALIDDATA;
+    ret = expect_byte(pb, &cur_byte, '[');
+    if (ret < 0)
+        return AVERROR_INVALIDDATA;
+    while (1) {
+        content.size = 0;
+        start = duration = AV_NOPTS_VALUE;
+        ret = expect_byte(pb, &cur_byte, '{');
+        if (ret < 0)
+            return ret;
+        pos = avio_tell(pb) - 1;
+        while (1) {
+            ret = parse_label(pb, &cur_byte, &label);
+            if (ret < 0)
+                return ret;
+            if (!strcmp(label.str, "startOfParagraph")) {
+                ret = parse_boolean(pb, &cur_byte, &start_of_par);
+                if (ret < 0)
+                    return ret;
+            } else if (!strcmp(label.str, "content")) {
+                ret = parse_string(pb, &cur_byte, &content, 1);
+                if (ret < 0)
+                    return ret;
+            } else if (!strcmp(label.str, "startTime")) {
+                ret = parse_int(pb, &cur_byte, &start);
+                if (ret < 0)
+                    return ret;
+            } else if (!strcmp(label.str, "duration")) {
+                ret = parse_int(pb, &cur_byte, &duration);
+                if (ret < 0)
+                    return ret;
+            } else {
+                return AVERROR_INVALIDDATA;
+            }
+            skip_spaces(pb, &cur_byte);
+            if (cur_byte != ',')
+                break;
+            next_byte(pb, &cur_byte);
+        }
+        ret = expect_byte(pb, &cur_byte, '}');
+        if (ret < 0)
+            return ret;
+
+        if (!content.size || start == AV_NOPTS_VALUE ||
+            duration == AV_NOPTS_VALUE)
+            return AVERROR_INVALIDDATA;
+        pkt = ff_subtitles_queue_insert(subs, content.str, content.len, 0);
+        if (!pkt)
+            return AVERROR(ENOMEM);
+        pkt->pos      = pos;
+        pkt->pts      = start;
+        pkt->duration = duration;
+        av_bprint_finalize(&content, NULL);
+
+        skip_spaces(pb, &cur_byte);
+        if (cur_byte != ',')
+            break;
+        next_byte(pb, &cur_byte);
+    }
+    ret = expect_byte(pb, &cur_byte, ']');
+    if (ret < 0)
+        return ret;
+    ret = expect_byte(pb, &cur_byte, '}');
+    if (ret < 0)
+        return ret;
+    skip_spaces(pb, &cur_byte);
+    if (cur_byte != AVERROR_EOF)
+        return ERR_CODE(cur_byte);
+    return 0;
+}
+
+static av_cold int tedcaptions_read_header(AVFormatContext *avf)
+{
+    TEDCaptionsDemuxer *tc = avf->priv_data;
+    AVStream *st;
+    int ret, i;
+    AVPacket *last;
+
+    ret = parse_file(avf->pb, &tc->subs);
+    if (ret < 0) {
+        if (ret == AVERROR_INVALIDDATA)
+            av_log(avf, AV_LOG_ERROR, "Syntax error near offset %"PRId64".\n",
+                   avio_tell(avf->pb));
+        ff_subtitles_queue_clean(&tc->subs);
+        return ret;
+    }
+    ff_subtitles_queue_finalize(&tc->subs);
+    for (i = 0; i < tc->subs.nb_subs; i++)
+        tc->subs.subs[i].pts += tc->start_time;
+
+    last = &tc->subs.subs[tc->subs.nb_subs - 1];
+    st = avformat_new_stream(avf, NULL);
+    if (!st)
+        return AVERROR(ENOMEM);
+    st->codec->codec_type     = AVMEDIA_TYPE_SUBTITLE;
+    st->codec->codec_id       = CODEC_ID_TEXT;
+    avpriv_set_pts_info(st, 64, 1, 1000);
+    st->probe_packets = 0;
+    st->start_time    = 0;
+    st->duration      = last->pts + last->duration;
+    st->cur_dts       = 0;
+
+    return 0;
+}
+
+static int tedcaptions_read_packet(AVFormatContext *avf, AVPacket *packet)
+{
+    TEDCaptionsDemuxer *tc = avf->priv_data;
+
+    return ff_subtitles_queue_read_packet(&tc->subs, packet);
+}
+
+static int tedcaptions_read_close(AVFormatContext *avf)
+{
+    TEDCaptionsDemuxer *tc = avf->priv_data;
+
+    ff_subtitles_queue_clean(&tc->subs);
+    return 0;
+}
+
+static av_cold int tedcaptions_read_probe(AVProbeData *p)
+{
+    static const char *const tags[] = {
+        "\"captions\"", "\"duration\"", "\"content\"",
+        "\"startOfParagraph\"", "\"startTime\"",
+    };
+    unsigned i, count = 0;
+    const char *t;
+
+    if (p->buf[strspn(p->buf, " \t\r\n")] != '{')
+        return 0;
+    for (i = 0; i < FF_ARRAY_ELEMS(tags); i++) {
+        if (!(t = strstr(p->buf, tags[i])))
+            continue;
+        t += strlen(tags[i]);
+        t += strspn(t, " \t\r\n");
+        if (*t == ':')
+            count++;
+    }
+    return count == FF_ARRAY_ELEMS(tags) ? AVPROBE_SCORE_MAX :
+           count                         ? AVPROBE_SCORE_MAX / 2 : 0;
+}
+
+static int tedcaptions_read_seek(AVFormatContext *avf, int stream_index,
+                                 int64_t min_ts, int64_t ts, int64_t max_ts,
+                                 int flags)
+{
+    TEDCaptionsDemuxer *tc = avf->priv_data;
+    return ff_subtitles_queue_seek(&tc->subs, avf, stream_index,
+                                   min_ts, ts, max_ts, flags);
+}
+
+AVInputFormat ff_tedcaptions_demuxer = {
+    .name           = "tedcaptions",
+    .long_name      = NULL_IF_CONFIG_SMALL("TED Talks captions"),
+    .priv_data_size = sizeof(TEDCaptionsDemuxer),
+    .priv_class     = &tedcaptions_demuxer_class,
+    .read_header    = tedcaptions_read_header,
+    .read_packet    = tedcaptions_read_packet,
+    .read_close     = tedcaptions_read_close,
+    .read_probe     = tedcaptions_read_probe,
+    .read_seek2     = tedcaptions_read_seek,
+};
diff --git a/libavformat/tee.c b/libavformat/tee.c
new file mode 100644
index 0000000..f41327b
--- /dev/null
+++ b/libavformat/tee.c
@@ -0,0 +1,278 @@
+/*
+ * Tee pesudo-muxer
+ * Copyright (c) 2012 Nicolas George
+ *
+ * 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/avutil.h"
+#include "libavutil/avstring.h"
+#include "libavutil/opt.h"
+#include "avformat.h"
+
+#define MAX_SLAVES 16
+
+typedef struct TeeContext {
+    const AVClass *class;
+    unsigned nb_slaves;
+    AVFormatContext *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 AVClass tee_muxer_class = {
+    .class_name = "Tee muxer",
+    .item_name  = av_default_item_name,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+static int parse_slave_options(void *log, char *slave,
+                               AVDictionary **options, char **filename)
+{
+    const char *p;
+    char *key, *val;
+    int ret;
+
+    if (!strspn(slave, slave_opt_open)) {
+        *filename = slave;
+        return 0;
+    }
+    p = slave + 1;
+    if (strspn(p, slave_opt_close)) {
+        *filename = (char *)p + 1;
+        return 0;
+    }
+    while (1) {
+        ret = av_opt_get_key_value(&p, "=", slave_opt_delim, 0, &key, &val);
+        if (ret < 0) {
+            av_log(log, AV_LOG_ERROR, "No option found near \"%s\"\n", p);
+            goto fail;
+        }
+        ret = av_dict_set(options, key, val,
+                          AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
+        if (ret < 0)
+            goto fail;
+        if (strspn(p, slave_opt_close))
+            break;
+        p++;
+    }
+    *filename = (char *)p + 1;
+    return 0;
+
+fail:
+    av_dict_free(options);
+    return ret;
+}
+
+static int open_slave(AVFormatContext *avf, char *slave, AVFormatContext **ravf)
+{
+    int i, ret;
+    AVDictionary *options = NULL;
+    AVDictionaryEntry *entry;
+    char *filename;
+    char *format = NULL;
+    AVFormatContext *avf2 = NULL;
+    AVStream *st, *st2;
+
+    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);
+    }
+
+    avformat_alloc_output_context2(&avf2, NULL, format, filename);
+    if (ret < 0)
+        goto fail;
+    av_free(format);
+
+    for (i = 0; i < avf->nb_streams; i++) {
+        st = avf->streams[i];
+        if (!(st2 = avformat_new_stream(avf2, NULL))) {
+            ret = AVERROR(ENOMEM);
+            goto fail;
+        }
+        st2->id = st->id;
+        st2->r_frame_rate        = st->r_frame_rate;
+        st2->time_base           = st->time_base;
+        st2->start_time          = st->start_time;
+        st2->duration            = st->duration;
+        st2->nb_frames           = st->nb_frames;
+        st2->disposition         = st->disposition;
+        st2->sample_aspect_ratio = st->sample_aspect_ratio;
+        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;
+    }
+
+    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;
+        }
+    }
+
+    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;
+    }
+    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;
+    }
+
+    *ravf = avf2;
+    return 0;
+
+fail:
+    av_dict_free(&options);
+    return ret;
+}
+
+static void close_slaves(AVFormatContext *avf)
+{
+    TeeContext *tee = avf->priv_data;
+    AVFormatContext *avf2;
+    unsigned i;
+
+    for (i = 0; i < tee->nb_slaves; i++) {
+        avf2 = tee->slaves[i];
+        avio_close(avf2->pb);
+        avf2->pb = NULL;
+        avformat_free_context(avf2);
+        tee->slaves[i] = NULL;
+    }
+}
+
+static int tee_write_header(AVFormatContext *avf)
+{
+    TeeContext *tee = avf->priv_data;
+    unsigned nb_slaves = 0, i;
+    const char *filename = avf->filename;
+    char *slaves[MAX_SLAVES];
+    int ret;
+
+    while (*filename) {
+        if (nb_slaves == MAX_SLAVES) {
+            av_log(avf, AV_LOG_ERROR, "Maximum %d slave muxers reached.\n",
+                   MAX_SLAVES);
+            ret = AVERROR_PATCHWELCOME;
+            goto fail;
+        }
+        if (!(slaves[nb_slaves++] = av_get_token(&filename, slave_delim))) {
+            ret = AVERROR(ENOMEM);
+            goto fail;
+        }
+        if (strspn(filename, slave_delim))
+            filename++;
+    }
+
+    for (i = 0; i < nb_slaves; i++) {
+        if ((ret = open_slave(avf, slaves[i], &tee->slaves[i])) < 0)
+            goto fail;
+        av_freep(&slaves[i]);
+    }
+
+    tee->nb_slaves = nb_slaves;
+    return 0;
+
+fail:
+    for (i = 0; i < nb_slaves; i++)
+        av_freep(&slaves[i]);
+    close_slaves(avf);
+    return ret;
+}
+
+static int tee_write_trailer(AVFormatContext *avf)
+{
+    TeeContext *tee = avf->priv_data;
+    AVFormatContext *avf2;
+    int ret_all = 0, ret;
+    unsigned i;
+
+    for (i = 0; i < tee->nb_slaves; i++) {
+        avf2 = tee->slaves[i];
+        if ((ret = av_write_trailer(avf2)) < 0)
+            if (!ret_all)
+                ret_all = ret;
+        if (!(avf2->oformat->flags & AVFMT_NOFILE)) {
+            if ((ret = avio_close(avf2->pb)) < 0)
+                if (!ret_all)
+                    ret_all = ret;
+            avf2->pb = NULL;
+        }
+    }
+    close_slaves(avf);
+    return ret_all;
+}
+
+static int tee_write_packet(AVFormatContext *avf, AVPacket *pkt)
+{
+    TeeContext *tee = avf->priv_data;
+    AVFormatContext *avf2;
+    AVPacket pkt2;
+    int ret_all = 0, ret;
+    unsigned i, s;
+    AVRational tb, tb2;
+
+    for (i = 0; i < tee->nb_slaves; i++) {
+        avf2 = tee->slaves[i];
+        s = pkt->stream_index;
+        if (s >= avf2->nb_streams) {
+            if (!ret_all)
+                ret_all = AVERROR(EINVAL);
+            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;
+        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);
+        if ((ret = av_interleaved_write_frame(avf2, &pkt2)) < 0)
+            if (!ret_all)
+                ret_all = ret;
+    }
+    return ret_all;
+}
+
+AVOutputFormat ff_tee_muxer = {
+    .name              = "tee",
+    .long_name         = NULL_IF_CONFIG_SMALL("Multiple muxer tee"),
+    .priv_data_size    = sizeof(TeeContext),
+    .write_header      = tee_write_header,
+    .write_trailer     = tee_write_trailer,
+    .write_packet      = tee_write_packet,
+    .priv_class        = &tee_muxer_class,
+    .flags             = AVFMT_NOFILE,
+};
diff --git a/libavformat/thp.c b/libavformat/thp.c
index 4463484..3717b8f 100644
--- a/libavformat/thp.c
+++ b/libavformat/thp.c
@@ -110,6 +110,8 @@
             st->codec->width = avio_rb32(pb);
             st->codec->height = avio_rb32(pb);
             st->codec->sample_rate = av_q2d(thp->fps);
+            st->nb_frames =
+            st->duration = thp->framecnt;
             thp->vst = st;
             thp->video_stream_index = st->index;
 
diff --git a/libavformat/tls.c b/libavformat/tls.c
index 38dd70c..2c85d1d 100644
--- a/libavformat/tls.c
+++ b/libavformat/tls.c
@@ -172,10 +172,6 @@
 
     ff_tls_init();
 
-    proxy_path = getenv("http_proxy");
-    use_proxy = (proxy_path != NULL) && !getenv("no_proxy") &&
-        av_strstart(proxy_path, "http://", NULL);
-
     av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port, path, sizeof(path), uri);
     ff_url_join(buf, sizeof(buf), "tcp", NULL, host, port, "%s", path);
 
@@ -185,6 +181,10 @@
         freeaddrinfo(ai);
     }
 
+    proxy_path = getenv("http_proxy");
+    use_proxy = !ff_http_match_no_proxy(getenv("no_proxy"), host) &&
+                proxy_path != NULL && av_strstart(proxy_path, "http://", NULL);
+
     if (use_proxy) {
         char proxy_host[200], proxy_auth[200], dest[200];
         int proxy_port;
diff --git a/libavformat/url-test.c b/libavformat/url-test.c
index ceaffe8..ee5f06e 100644
--- a/libavformat/url-test.c
+++ b/libavformat/url-test.c
@@ -20,9 +20,6 @@
 
 #include "internal.h"
 
-#undef printf
-#undef exit
-
 static void test(const char *base, const char *rel)
 {
     char buf[200], buf2[200];
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 3bd97ee..d23f53e 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -78,6 +78,27 @@
     return ts > (RELATIVE_TS_BASE - (1LL<<48));
 }
 
+/**
+ * Wrap a given time stamp, if there is an indication for an overflow
+ *
+ * @param st stream
+ * @param timestamp the time stamp to wrap
+ * @return resulting time stamp
+ */
+static int64_t wrap_timestamp(AVStream *st, int64_t timestamp)
+{
+    if (st->pts_wrap_behavior != AV_PTS_WRAP_IGNORE &&
+        st->pts_wrap_reference != AV_NOPTS_VALUE && timestamp != AV_NOPTS_VALUE) {
+        if (st->pts_wrap_behavior == AV_PTS_WRAP_ADD_OFFSET &&
+            timestamp < st->pts_wrap_reference)
+            return timestamp + (1ULL<<st->pts_wrap_bits);
+        else if (st->pts_wrap_behavior == AV_PTS_WRAP_SUB_OFFSET &&
+            timestamp >= st->pts_wrap_reference)
+            return timestamp - (1ULL<<st->pts_wrap_bits);
+    }
+    return timestamp;
+}
+
 /** head of registered input format linked list */
 static AVInputFormat *first_iformat = NULL;
 /** head of registered output format linked list */
@@ -413,13 +434,16 @@
 {
     AVProbeData pd = { filename ? filename : "", NULL, -offset };
     unsigned char *buf = NULL;
-    int ret = 0, probe_size;
+    uint8_t *mime_type;
+    int ret = 0, probe_size, buf_offset = 0;
 
     if (!max_probe_size) {
         max_probe_size = PROBE_BUF_MAX;
     } else if (max_probe_size > PROBE_BUF_MAX) {
         max_probe_size = PROBE_BUF_MAX;
     } else if (max_probe_size < PROBE_BUF_MIN) {
+        av_log(logctx, AV_LOG_ERROR,
+               "Specified probe size value %u cannot be < %u\n", max_probe_size, PROBE_BUF_MIN);
         return AVERROR(EINVAL);
     }
 
@@ -427,10 +451,16 @@
         return AVERROR(EINVAL);
     }
 
+    if (!*fmt && pb->av_class && av_opt_get(pb, "mime_type", AV_OPT_SEARCH_CHILDREN, &mime_type) >= 0 && mime_type) {
+        if (!av_strcasecmp(mime_type, "audio/aacp")) {
+            *fmt = av_find_input_format("aac");
+        }
+        av_freep(&mime_type);
+    }
+
     for(probe_size= PROBE_BUF_MIN; probe_size<=max_probe_size && !*fmt;
         probe_size = FFMIN(probe_size<<1, FFMAX(max_probe_size, probe_size+1))) {
         int score = probe_size < max_probe_size ? AVPROBE_SCORE_RETRY : 0;
-        int buf_offset = (probe_size == PROBE_BUF_MIN) ? 0 : probe_size>>1;
         void *buftmp;
 
         if (probe_size < offset) {
@@ -453,7 +483,7 @@
             score = 0;
             ret = 0;            /* error was end of file, nothing read */
         }
-        pd.buf_size += ret;
+        pd.buf_size = buf_offset += ret;
         pd.buf = &buf[offset];
 
         memset(pd.buf + pd.buf_size, 0, AVPROBE_PADDING_SIZE);
@@ -631,6 +661,21 @@
 
 /*******************************************************/
 
+static void force_codec_ids(AVFormatContext *s, AVStream *st)
+{
+    switch(st->codec->codec_type){
+    case AVMEDIA_TYPE_VIDEO:
+        if(s->video_codec_id)   st->codec->codec_id= s->video_codec_id;
+        break;
+    case AVMEDIA_TYPE_AUDIO:
+        if(s->audio_codec_id)   st->codec->codec_id= s->audio_codec_id;
+        break;
+    case AVMEDIA_TYPE_SUBTITLE:
+        if(s->subtitle_codec_id)st->codec->codec_id= s->subtitle_codec_id;
+        break;
+    }
+}
+
 static void probe_codec(AVFormatContext *s, AVStream *st, const AVPacket *pkt)
 {
     if(st->request_probe>0){
@@ -671,25 +716,11 @@
                 }else
                     av_log(s, AV_LOG_WARNING, "probed stream %d failed\n", st->index);
             }
+            force_codec_ids(s, st);
         }
     }
 }
 
-static void force_codec_ids(AVFormatContext *s, AVStream *st)
-{
-    switch(st->codec->codec_type){
-    case AVMEDIA_TYPE_VIDEO:
-        if(s->video_codec_id)   st->codec->codec_id= s->video_codec_id;
-        break;
-    case AVMEDIA_TYPE_AUDIO:
-        if(s->audio_codec_id)   st->codec->codec_id= s->audio_codec_id;
-        break;
-    case AVMEDIA_TYPE_SUBTITLE:
-        if(s->subtitle_codec_id)st->codec->codec_id= s->subtitle_codec_id;
-        break;
-    }
-}
-
 int ff_read_packet(AVFormatContext *s, AVPacket *pkt)
 {
     int ret, i;
@@ -744,6 +775,8 @@
         }
 
         st= s->streams[pkt->stream_index];
+        pkt->dts = wrap_timestamp(st, pkt->dts);
+        pkt->pts = wrap_timestamp(st, pkt->pts);
 
         force_codec_ids(s, st);
 
@@ -800,6 +833,13 @@
     if (enc->frame_size > 1)
         return enc->frame_size;
 
+    //For WMA we currently have no other means to calculate duration thus we
+    //do it here by assuming CBR, which is true for all known cases.
+    if(!mux && enc->bit_rate>0 && size>0 && enc->sample_rate>0 && enc->block_align>1) {
+        if (enc->codec_id == AV_CODEC_ID_WMAV1 || enc->codec_id == AV_CODEC_ID_WMAV2)
+            return  ((int64_t)size * 8 * enc->sample_rate) / enc->bit_rate;
+    }
+
     return -1;
 }
 
@@ -893,8 +933,67 @@
     return NULL;
 }
 
+static int update_wrap_reference(AVFormatContext *s, AVStream *st, int stream_index)
+{
+    if (s->correct_ts_overflow && st->pts_wrap_bits < 63 &&
+        st->pts_wrap_reference == AV_NOPTS_VALUE && st->first_dts != AV_NOPTS_VALUE) {
+        int i;
+
+        // reference time stamp should be 60 s before first time stamp
+        int64_t pts_wrap_reference = st->first_dts - av_rescale(60, st->time_base.den, st->time_base.num);
+        // if first time stamp is not more than 1/8 and 60s before the wrap point, subtract rather than add wrap offset
+        int pts_wrap_behavior = (st->first_dts < (1LL<<st->pts_wrap_bits) - (1LL<<st->pts_wrap_bits-3)) ||
+            (st->first_dts < (1LL<<st->pts_wrap_bits) - av_rescale(60, st->time_base.den, st->time_base.num)) ?
+            AV_PTS_WRAP_ADD_OFFSET : AV_PTS_WRAP_SUB_OFFSET;
+
+        AVProgram *first_program = av_find_program_from_stream(s, NULL, stream_index);
+
+        if (!first_program) {
+            int default_stream_index = av_find_default_stream_index(s);
+            if (s->streams[default_stream_index]->pts_wrap_reference == AV_NOPTS_VALUE) {
+                for (i=0; i<s->nb_streams; i++) {
+                    s->streams[i]->pts_wrap_reference = pts_wrap_reference;
+                    s->streams[i]->pts_wrap_behavior = pts_wrap_behavior;
+                }
+            }
+            else {
+                st->pts_wrap_reference = s->streams[default_stream_index]->pts_wrap_reference;
+                st->pts_wrap_behavior = s->streams[default_stream_index]->pts_wrap_behavior;
+            }
+        }
+        else {
+            AVProgram *program = first_program;
+            while (program) {
+                if (program->pts_wrap_reference != AV_NOPTS_VALUE) {
+                    pts_wrap_reference = program->pts_wrap_reference;
+                    pts_wrap_behavior = program->pts_wrap_behavior;
+                    break;
+                }
+                program = av_find_program_from_stream(s, program, stream_index);
+            }
+
+            // update every program with differing pts_wrap_reference
+            program = first_program;
+            while(program) {
+                if (program->pts_wrap_reference != pts_wrap_reference) {
+                    for (i=0; i<program->nb_stream_indexes; i++) {
+                        s->streams[program->stream_index[i]]->pts_wrap_reference = pts_wrap_reference;
+                        s->streams[program->stream_index[i]]->pts_wrap_behavior = pts_wrap_behavior;
+                    }
+
+                    program->pts_wrap_reference = pts_wrap_reference;
+                    program->pts_wrap_behavior = pts_wrap_behavior;
+                }
+                program = av_find_program_from_stream(s, program, stream_index);
+            }
+        }
+        return 1;
+    }
+    return 0;
+}
+
 static void update_initial_timestamps(AVFormatContext *s, int stream_index,
-                                      int64_t dts, int64_t pts)
+                                      int64_t dts, int64_t pts, AVPacket *pkt)
 {
     AVStream *st= s->streams[stream_index];
     AVPacketList *pktl= s->parse_queue ? s->parse_queue : s->packet_buffer;
@@ -936,6 +1035,16 @@
                 pktl->pkt.dts= pts_buffer[0];
         }
     }
+
+    if (update_wrap_reference(s, st, stream_index) && st->pts_wrap_behavior == AV_PTS_WRAP_SUB_OFFSET) {
+        // correct first time stamps to negative values
+        st->first_dts = wrap_timestamp(st, st->first_dts);
+        st->cur_dts = wrap_timestamp(st, st->cur_dts);
+        pkt->dts = wrap_timestamp(st, pkt->dts);
+        pkt->pts = wrap_timestamp(st, pkt->pts);
+        pts = wrap_timestamp(st, pts);
+    }
+
     if (st->start_time == AV_NOPTS_VALUE)
         st->start_time = pts;
 }
@@ -956,11 +1065,11 @@
             }
         }
         if(pktl && pktl->pkt.dts != st->first_dts) {
-            av_log(s, AV_LOG_DEBUG, "first_dts %s not matching first dts %s in que\n", av_ts2str(st->first_dts), av_ts2str(pktl->pkt.dts));
+            av_log(s, AV_LOG_DEBUG, "first_dts %s not matching first dts %s in the queue\n", av_ts2str(st->first_dts), av_ts2str(pktl->pkt.dts));
             return;
         }
         if(!pktl) {
-            av_log(s, AV_LOG_DEBUG, "first_dts %s but no packet with dts in ques\n", av_ts2str(st->first_dts));
+            av_log(s, AV_LOG_DEBUG, "first_dts %s but no packet with dts in the queue\n", av_ts2str(st->first_dts));
             return;
         }
         pktl= s->parse_queue ? s->parse_queue : s->packet_buffer;
@@ -1081,7 +1190,7 @@
             /* PTS = presentation timestamp */
             if (pkt->dts == AV_NOPTS_VALUE)
                 pkt->dts = st->last_IP_pts;
-            update_initial_timestamps(s, pkt->stream_index, pkt->dts, pkt->pts);
+            update_initial_timestamps(s, pkt->stream_index, pkt->dts, pkt->pts, pkt);
             if (pkt->dts == AV_NOPTS_VALUE)
                 pkt->dts = st->cur_dts;
 
@@ -1100,25 +1209,11 @@
                    pkt->duration                ) {
             int duration = pkt->duration;
 
-            if(st->cur_dts != AV_NOPTS_VALUE && pkt->pts != AV_NOPTS_VALUE && duration){
-                int64_t old_diff= FFABS(st->cur_dts - duration - pkt->pts);
-                int64_t new_diff= FFABS(st->cur_dts - pkt->pts);
-                if(   old_diff < new_diff && old_diff < (duration>>3)
-                   && st->codec->codec_type == AVMEDIA_TYPE_VIDEO
-                   && (!strcmp(s->iformat->name, "mpeg") ||
-                       !strcmp(s->iformat->name, "mpegts"))){
-                    pkt->pts += duration;
-                    av_log(s, AV_LOG_WARNING, "Adjusting PTS forward\n");
-//                    av_log(NULL, AV_LOG_DEBUG, "id:%d old:%"PRId64" new:%"PRId64" dur:%d cur:%s size:%d\n",
-//                           pkt->stream_index, old_diff, new_diff, pkt->duration, av_ts2str(st->cur_dts), pkt->size);
-                }
-            }
-
             /* presentation is not delayed : PTS and DTS are the same */
             if (pkt->pts == AV_NOPTS_VALUE)
                 pkt->pts = pkt->dts;
             update_initial_timestamps(s, pkt->stream_index, pkt->pts,
-                                      pkt->pts);
+                                      pkt->pts, pkt);
             if (pkt->pts == AV_NOPTS_VALUE)
                 pkt->pts = st->cur_dts;
             pkt->dts = pkt->pts;
@@ -1135,7 +1230,7 @@
             pkt->dts= st->pts_buffer[0];
     }
     if(st->codec->codec_id == AV_CODEC_ID_H264){ // we skipped it above so we try here
-        update_initial_timestamps(s, pkt->stream_index, pkt->dts, pkt->pts); // this should happen on the first packet
+        update_initial_timestamps(s, pkt->stream_index, pkt->dts, pkt->pts, pkt); // this should happen on the first packet
     }
     if(pkt->dts > st->cur_dts)
         st->cur_dts = pkt->dts;
@@ -1622,6 +1717,7 @@
 int av_add_index_entry(AVStream *st,
                        int64_t pos, int64_t timestamp, int size, int distance, int flags)
 {
+    timestamp = wrap_timestamp(st, timestamp);
     return ff_add_index_entry(&st->index_entries, &st->nb_index_entries,
                               &st->index_entries_allocated_size, pos,
                               timestamp, size, distance, flags);
@@ -1668,6 +1764,15 @@
                                      wanted_timestamp, flags);
 }
 
+static int64_t ff_read_timestamp(AVFormatContext *s, int stream_index, int64_t *ppos, int64_t pos_limit,
+                                 int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t ))
+{
+    int64_t ts = read_timestamp(s, stream_index, ppos, pos_limit);
+    if (stream_index >= 0)
+        ts = wrap_timestamp(s->streams[stream_index], ts);
+    return ts;
+}
+
 int ff_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts, int flags)
 {
     AVInputFormat *avif= s->iformat;
@@ -1743,7 +1848,7 @@
 
     if(ts_min == AV_NOPTS_VALUE){
         pos_min = s->data_offset;
-        ts_min = read_timestamp(s, stream_index, &pos_min, INT64_MAX);
+        ts_min = ff_read_timestamp(s, stream_index, &pos_min, INT64_MAX, read_timestamp);
         if (ts_min == AV_NOPTS_VALUE)
             return -1;
     }
@@ -1758,16 +1863,16 @@
         filesize = avio_size(s->pb);
         pos_max = filesize - 1;
         do{
-            pos_max -= step;
-            ts_max = read_timestamp(s, stream_index, &pos_max, pos_max + step);
+            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 >= 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= read_timestamp(s, stream_index, &tmp_pos, INT64_MAX);
+            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;
@@ -1814,7 +1919,7 @@
             pos= pos_limit;
         start_pos= pos;
 
-        ts = read_timestamp(s, stream_index, &pos, INT64_MAX); //may pass pos_limit instead of -1
+        ts = ff_read_timestamp(s, stream_index, &pos, INT64_MAX, read_timestamp); //may pass pos_limit instead of -1
         if(pos == pos_max)
             no_change++;
         else
@@ -1843,9 +1948,9 @@
     ts  = (flags & AVSEEK_FLAG_BACKWARD) ?  ts_min :  ts_max;
 #if 0
     pos_min = pos;
-    ts_min = read_timestamp(s, stream_index, &pos_min, INT64_MAX);
+    ts_min = ff_read_timestamp(s, stream_index, &pos_min, INT64_MAX, read_timestamp);
     pos_min++;
-    ts_max = read_timestamp(s, stream_index, &pos_min, INT64_MAX);
+    ts_max = ff_read_timestamp(s, stream_index, &pos_min, INT64_MAX, read_timestamp);
     av_dlog(s, "pos=0x%"PRIx64" %s<=%s<=%s\n",
             pos, av_ts2str(ts_min), av_ts2str(target_ts), av_ts2str(ts_max));
 #endif
@@ -1990,9 +2095,24 @@
     if(min_ts > ts || max_ts < ts)
         return -1;
 
+    if(s->seek2any>0)
+        flags |= AVSEEK_FLAG_ANY;
+
     if (s->iformat->read_seek2) {
         int ret;
         ff_read_frame_flush(s);
+
+        if (stream_index == -1 && s->nb_streams == 1) {
+            AVRational time_base = s->streams[0]->time_base;
+            ts = av_rescale_q(ts, AV_TIME_BASE_Q, time_base);
+            min_ts = av_rescale_rnd(min_ts, time_base.den,
+                                    time_base.num * (int64_t)AV_TIME_BASE,
+                                    AV_ROUND_UP   | AV_ROUND_PASS_MINMAX);
+            max_ts = av_rescale_rnd(max_ts, time_base.den,
+                                    time_base.num * (int64_t)AV_TIME_BASE,
+                                    AV_ROUND_DOWN | AV_ROUND_PASS_MINMAX);
+        }
+
         ret = s->iformat->read_seek2(s, stream_index, min_ts, ts, max_ts, flags);
 
         if (ret >= 0)
@@ -2018,6 +2138,7 @@
     }
 
     // try some generic seek like seek_frame_generic() but with new ts semantics
+    return -1; //unreachable
 }
 
 /*******************************************************/
@@ -2220,8 +2341,6 @@
                     duration -= st->start_time;
                 else
                     duration -= st->first_dts;
-                if (duration < 0)
-                    duration += 1LL<<st->pts_wrap_bits;
                 if (duration > 0) {
                     if (st->duration == AV_NOPTS_VALUE || st->duration < duration)
                         st->duration = duration;
@@ -2473,10 +2592,25 @@
 
 unsigned int av_codec_get_tag(const AVCodecTag * const *tags, enum AVCodecID id)
 {
+    unsigned int tag;
+    if (!av_codec_get_tag2(tags, id, &tag))
+        return 0;
+    return tag;
+}
+
+int av_codec_get_tag2(const AVCodecTag * const *tags, enum AVCodecID id,
+                      unsigned int *tag)
+{
     int i;
     for(i=0; tags && tags[i]; i++){
-        int tag= ff_codec_get_tag(tags[i], id);
-        if(tag) return tag;
+        const AVCodecTag *codec_tags = tags[i];
+        while (codec_tags->id != AV_CODEC_ID_NONE) {
+            if (codec_tags->id == id) {
+                *tag = codec_tags->tag;
+                return 1;
+            }
+            codec_tags++;
+        }
     }
     return 0;
 }
@@ -2638,6 +2772,8 @@
                 fps_analyze_framecount *= 2;
             if (ic->fps_probe_size >= 0)
                 fps_analyze_framecount = ic->fps_probe_size;
+            if (st->disposition & AV_DISPOSITION_ATTACHED_PIC)
+                fps_analyze_framecount = 0;
             /* variable fps and no guess at the real fps */
             if(   tb_unreliable(st->codec) && !(st->r_frame_rate.num && st->avg_frame_rate.num)
                && st->info->duration_count < fps_analyze_framecount
@@ -2665,7 +2801,7 @@
         /* we did not get all the codec info, but we read too much data */
         if (read_size >= ic->probesize) {
             ret = count;
-            av_log(ic, AV_LOG_DEBUG, "Probe buffer size limit %d reached\n", ic->probesize);
+            av_log(ic, AV_LOG_DEBUG, "Probe buffer size limit of %d bytes reached\n", ic->probesize);
             for (i = 0; i < ic->nb_streams; i++)
                 if (!ic->streams[i]->r_frame_rate.num &&
                     ic->streams[i]->info->duration_count <= 1)
@@ -2738,7 +2874,7 @@
                 t = FFMAX(t, av_rescale_q(st->codec_info_nb_frames, av_inv_q(st->avg_frame_rate), AV_TIME_BASE_Q));
 
             if (t >= ic->max_analyze_duration) {
-                av_log(ic, AV_LOG_WARNING, "max_analyze_duration %d reached at %"PRId64"\n", ic->max_analyze_duration, t);
+                av_log(ic, AV_LOG_WARNING, "max_analyze_duration %d reached at %"PRId64" microseconds\n", ic->max_analyze_duration, t);
                 break;
             }
             if (pkt->duration) {
@@ -2750,13 +2886,17 @@
         {
             int64_t last = st->info->last_dts;
 
-            if(pkt->dts != AV_NOPTS_VALUE && last != AV_NOPTS_VALUE && pkt->dts > last){
+            if(   pkt->dts != AV_NOPTS_VALUE && last != AV_NOPTS_VALUE && pkt->dts > last
+               && pkt->dts - (uint64_t)last < INT64_MAX){
                 double dts= (is_relative(pkt->dts) ?  pkt->dts - RELATIVE_TS_BASE : pkt->dts) * av_q2d(st->time_base);
                 int64_t duration= pkt->dts - last;
 
+                if (!st->info->duration_error)
+                    st->info->duration_error = av_mallocz(sizeof(st->info->duration_error[0])*2);
+
 //                 if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
 //                     av_log(NULL, AV_LOG_ERROR, "%f\n", dts);
-                for (i=0; i<FF_ARRAY_ELEMS(st->info->duration_error[0][0]); i++) {
+                for (i=0; i<MAX_STD_TIMEBASES; i++) {
                     int framerate= get_std_framerate(i);
                     double sdts= dts*framerate/(1001*12);
                     for(j=0; j<2; j++){
@@ -2850,7 +2990,7 @@
         if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
             if(st->codec->codec_id == AV_CODEC_ID_RAWVIDEO && !st->codec->codec_tag && !st->codec->bits_per_coded_sample){
                 uint32_t tag= avcodec_pix_fmt_to_codec_tag(st->codec->pix_fmt);
-                if(ff_find_pix_fmt(ff_raw_pix_fmt_tags, tag) == st->codec->pix_fmt)
+                if (avpriv_find_pix_fmt(ff_raw_pix_fmt_tags, tag) == st->codec->pix_fmt)
                     st->codec->codec_tag= tag;
             }
 
@@ -2884,12 +3024,12 @@
             // ipmovie.c produces.
             if (tb_unreliable(st->codec) && st->info->duration_count > 15 && st->info->duration_gcd > FFMAX(1, st->time_base.den/(500LL*st->time_base.num)) && !st->r_frame_rate.num)
                 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den, st->time_base.den, st->time_base.num * st->info->duration_gcd, INT_MAX);
-            if (st->info->duration_count && !st->r_frame_rate.num
+            if (st->info->duration_count>1 && !st->r_frame_rate.num
                 && tb_unreliable(st->codec)) {
                 int num = 0;
                 double best_error= 0.01;
 
-                for (j=0; j<FF_ARRAY_ELEMS(st->info->duration_error[0][0]); j++) {
+                for (j=0; j<MAX_STD_TIMEBASES; j++) {
                     int k;
 
                     if(st->info->codec_info_duration && st->info->codec_info_duration*av_q2d(st->time_base) < (1001*12.0)/get_std_framerate(j))
@@ -2950,8 +3090,11 @@
 
  find_stream_info_err:
     for (i=0; i < ic->nb_streams; i++) {
+        st = ic->streams[i];
         if (ic->streams[i]->codec)
             ic->streams[i]->codec->thread_count = 0;
+        if (st->info)
+            av_freep(&st->info->duration_error);
         av_freep(&ic->streams[i]->info);
     }
     if(ic->pb)
@@ -3071,6 +3214,8 @@
     av_freep(&st->codec->subtitle_header);
     av_freep(&st->codec);
     av_freep(&st->priv_data);
+    if (st->info)
+        av_freep(&st->info->duration_error);
     av_freep(&st->info);
     av_freep(&st->probe_data.buf);
     av_freep(&s->streams[ --s->nb_streams ]);
@@ -3184,6 +3329,8 @@
     st->cur_dts = s->iformat ? RELATIVE_TS_BASE : 0;
     st->first_dts = AV_NOPTS_VALUE;
     st->probe_packets = MAX_PROBE_PACKETS;
+    st->pts_wrap_reference = AV_NOPTS_VALUE;
+    st->pts_wrap_behavior = AV_PTS_WRAP_IGNORE;
 
     /* default pts setting is MPEG-like */
     avpriv_set_pts_info(st, 33, 1, 90000);
@@ -3223,6 +3370,8 @@
         program->discard = AVDISCARD_NONE;
     }
     program->id = id;
+    program->pts_wrap_reference = AV_NOPTS_VALUE;
+    program->pts_wrap_behavior = AV_PTS_WRAP_IGNORE;
 
     program->start_time =
     program->end_time   = AV_NOPTS_VALUE;
@@ -3524,7 +3673,6 @@
                               const uint8_t *buf, int size)
 {
     int len, i, j, c;
-#undef fprintf
 #define PRINT(...) do { if (!f) av_log(avcl, level, __VA_ARGS__); else fprintf(f, __VA_ARGS__); } while(0)
 
     for(i=0;i<size;i+=16) {
@@ -3562,7 +3710,6 @@
 
 static void pkt_dump_internal(void *avcl, FILE *f, int level, AVPacket *pkt, int dump_payload, AVRational time_base)
 {
-#undef fprintf
 #define PRINT(...) do { if (!f) av_log(avcl, level, __VA_ARGS__); else fprintf(f, __VA_ARGS__); } while(0)
     PRINT("stream #%d:\n", pkt->stream_index);
     PRINT("  keyframe=%d\n", ((pkt->flags & AV_PKT_FLAG_KEY) != 0));
@@ -3813,6 +3960,10 @@
         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);
 }
 
@@ -4130,3 +4281,152 @@
     av_log(s, AV_LOG_ERROR, "Invalid stream specifier: %s.\n", spec);
     return AVERROR(EINVAL);
 }
+
+void ff_generate_avci_extradata(AVStream *st)
+{
+    static const uint8_t avci100_1080p_extradata[] = {
+        // SPS
+        0x00, 0x00, 0x00, 0x01, 0x67, 0x7a, 0x10, 0x29,
+        0xb6, 0xd4, 0x20, 0x22, 0x33, 0x19, 0xc6, 0x63,
+        0x23, 0x21, 0x01, 0x11, 0x98, 0xce, 0x33, 0x19,
+        0x18, 0x21, 0x02, 0x56, 0xb9, 0x3d, 0x7d, 0x7e,
+        0x4f, 0xe3, 0x3f, 0x11, 0xf1, 0x9e, 0x08, 0xb8,
+        0x8c, 0x54, 0x43, 0xc0, 0x78, 0x02, 0x27, 0xe2,
+        0x70, 0x1e, 0x30, 0x10, 0x10, 0x14, 0x00, 0x00,
+        0x03, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0xca,
+        0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        // PPS
+        0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x33, 0x48,
+        0xd0
+    };
+    static const uint8_t avci100_1080i_extradata[] = {
+        // SPS
+        0x00, 0x00, 0x00, 0x01, 0x67, 0x7a, 0x10, 0x29,
+        0xb6, 0xd4, 0x20, 0x22, 0x33, 0x19, 0xc6, 0x63,
+        0x23, 0x21, 0x01, 0x11, 0x98, 0xce, 0x33, 0x19,
+        0x18, 0x21, 0x03, 0x3a, 0x46, 0x65, 0x6a, 0x65,
+        0x24, 0xad, 0xe9, 0x12, 0x32, 0x14, 0x1a, 0x26,
+        0x34, 0xad, 0xa4, 0x41, 0x82, 0x23, 0x01, 0x50,
+        0x2b, 0x1a, 0x24, 0x69, 0x48, 0x30, 0x40, 0x2e,
+        0x11, 0x12, 0x08, 0xc6, 0x8c, 0x04, 0x41, 0x28,
+        0x4c, 0x34, 0xf0, 0x1e, 0x01, 0x13, 0xf2, 0xe0,
+        0x3c, 0x60, 0x20, 0x20, 0x28, 0x00, 0x00, 0x03,
+        0x00, 0x08, 0x00, 0x00, 0x03, 0x01, 0x94, 0x00,
+        // PPS
+        0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x33, 0x48,
+        0xd0
+    };
+    static const uint8_t avci50_1080i_extradata[] = {
+        // SPS
+        0x00, 0x00, 0x00, 0x01, 0x67, 0x6e, 0x10, 0x28,
+        0xa6, 0xd4, 0x20, 0x32, 0x33, 0x0c, 0x71, 0x18,
+        0x88, 0x62, 0x10, 0x19, 0x19, 0x86, 0x38, 0x8c,
+        0x44, 0x30, 0x21, 0x02, 0x56, 0x4e, 0x6e, 0x61,
+        0x87, 0x3e, 0x73, 0x4d, 0x98, 0x0c, 0x03, 0x06,
+        0x9c, 0x0b, 0x73, 0xe6, 0xc0, 0xb5, 0x18, 0x63,
+        0x0d, 0x39, 0xe0, 0x5b, 0x02, 0xd4, 0xc6, 0x19,
+        0x1a, 0x79, 0x8c, 0x32, 0x34, 0x24, 0xf0, 0x16,
+        0x81, 0x13, 0xf7, 0xff, 0x80, 0x02, 0x00, 0x01,
+        0xf1, 0x80, 0x80, 0x80, 0xa0, 0x00, 0x00, 0x03,
+        0x00, 0x20, 0x00, 0x00, 0x06, 0x50, 0x80, 0x00,
+        // PPS
+        0x00, 0x00, 0x00, 0x01, 0x68, 0xee, 0x31, 0x12,
+        0x11
+    };
+    static const uint8_t avci100_720p_extradata[] = {
+        // SPS
+        0x00, 0x00, 0x00, 0x01, 0x67, 0x7a, 0x10, 0x29,
+        0xb6, 0xd4, 0x20, 0x2a, 0x33, 0x1d, 0xc7, 0x62,
+        0xa1, 0x08, 0x40, 0x54, 0x66, 0x3b, 0x8e, 0xc5,
+        0x42, 0x02, 0x10, 0x25, 0x64, 0x2c, 0x89, 0xe8,
+        0x85, 0xe4, 0x21, 0x4b, 0x90, 0x83, 0x06, 0x95,
+        0xd1, 0x06, 0x46, 0x97, 0x20, 0xc8, 0xd7, 0x43,
+        0x08, 0x11, 0xc2, 0x1e, 0x4c, 0x91, 0x0f, 0x01,
+        0x40, 0x16, 0xec, 0x07, 0x8c, 0x04, 0x04, 0x05,
+        0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x03,
+        0x00, 0x64, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00,
+        // PPS
+        0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x31, 0x12,
+        0x11
+    };
+    int size = 0;
+    const uint8_t *data = 0;
+    if (st->codec->width == 1920) {
+        if (st->codec->field_order == AV_FIELD_PROGRESSIVE) {
+            data = avci100_1080p_extradata;
+            size = sizeof(avci100_1080p_extradata);
+        } else {
+            data = avci100_1080i_extradata;
+            size = sizeof(avci100_1080i_extradata);
+        }
+    } else if (st->codec->width == 1440) {
+        data = avci50_1080i_extradata;
+        size = sizeof(avci50_1080i_extradata);
+    } else if (st->codec->width == 1280) {
+        data = avci100_720p_extradata;
+        size = sizeof(avci100_720p_extradata);
+    }
+    if (!size)
+        return;
+    av_freep(&st->codec->extradata);
+    st->codec->extradata_size = 0;
+    st->codec->extradata = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE);
+    if (!st->codec->extradata)
+        return;
+    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/version.h b/libavformat/version.h
index d82b948..082ab99 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -30,8 +30,8 @@
 #include "libavutil/avutil.h"
 
 #define LIBAVFORMAT_VERSION_MAJOR 54
-#define LIBAVFORMAT_VERSION_MINOR 42
-#define LIBAVFORMAT_VERSION_MICRO 100
+#define LIBAVFORMAT_VERSION_MINOR 63
+#define LIBAVFORMAT_VERSION_MICRO 102
 
 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
                                                LIBAVFORMAT_VERSION_MINOR, \
diff --git a/libavformat/vivo.c b/libavformat/vivo.c
index e3487f6..e0a1814 100644
--- a/libavformat/vivo.c
+++ b/libavformat/vivo.c
@@ -226,9 +226,11 @@
     vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
 
     if (vivo->version == 1) {
-        vst->codec->codec_id = CODEC_ID_H263;
-        ast->codec->codec_id = CODEC_ID_G723_1;
+        vst->codec->codec_id = AV_CODEC_ID_H263;
+        ast->codec->codec_id = AV_CODEC_ID_G723_1;
         ast->codec->bits_per_coded_sample = 8;
+        ast->codec->block_align = 24;
+        ast->codec->bit_rate = 6400;
     }
 
     ast->start_time        = 0;
diff --git a/libavformat/vplayerdec.c b/libavformat/vplayerdec.c
new file mode 100644
index 0000000..73a48db
--- /dev/null
+++ b/libavformat/vplayerdec.c
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2012 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
+ * VPlayer subtitles format demuxer
+ */
+
+#include "avformat.h"
+#include "internal.h"
+#include "subtitles.h"
+
+typedef struct {
+    FFDemuxSubtitlesQueue q;
+} VPlayerContext;
+
+static int vplayer_probe(AVProbeData *p)
+{
+    char c;
+    const unsigned char *ptr = p->buf;
+
+    if (sscanf(ptr, "%*d:%*d:%*d.%*d%c", &c) == 1 && strchr(": =", c))
+        return AVPROBE_SCORE_MAX;
+    return 0;
+}
+
+static int64_t read_ts(char **line)
+{
+    char c;
+    int hh, mm, ss, ms, len;
+
+    if (sscanf(*line, "%d:%d:%d.%d%c%n",
+               &hh, &mm, &ss, &ms, &c, &len) >= 5) {
+        *line += len;
+        return (hh*3600LL + mm*60LL + ss) * 100LL + ms;
+    }
+    return AV_NOPTS_VALUE;
+}
+
+static int vplayer_read_header(AVFormatContext *s)
+{
+    VPlayerContext *vplayer = s->priv_data;
+    AVStream *st = avformat_new_stream(s, NULL);
+
+    if (!st)
+        return AVERROR(ENOMEM);
+    avpriv_set_pts_info(st, 64, 1, 100);
+    st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
+    st->codec->codec_id   = AV_CODEC_ID_VPLAYER;
+
+    while (!url_feof(s->pb)) {
+        char line[4096];
+        char *p = line;
+        const int64_t pos = avio_tell(s->pb);
+        int len = ff_get_line(s->pb, line, sizeof(line));
+        int64_t pts_start;
+
+        if (!len)
+            break;
+
+        line[strcspn(line, "\r\n")] = 0;
+
+        pts_start = read_ts(&p);
+        if (pts_start != AV_NOPTS_VALUE) {
+            AVPacket *sub;
+
+            sub = ff_subtitles_queue_insert(&vplayer->q, p, strlen(p), 0);
+            if (!sub)
+                return AVERROR(ENOMEM);
+            sub->pos = pos;
+            sub->pts = pts_start;
+            sub->duration = -1;
+        }
+    }
+
+    ff_subtitles_queue_finalize(&vplayer->q);
+    return 0;
+}
+
+static int vplayer_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    VPlayerContext *vplayer = s->priv_data;
+    return ff_subtitles_queue_read_packet(&vplayer->q, pkt);
+}
+
+static int vplayer_read_seek(AVFormatContext *s, int stream_index,
+                             int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
+{
+    VPlayerContext *vplayer = s->priv_data;
+    return ff_subtitles_queue_seek(&vplayer->q, s, stream_index,
+                                   min_ts, ts, max_ts, flags);
+}
+
+static int vplayer_read_close(AVFormatContext *s)
+{
+    VPlayerContext *vplayer = s->priv_data;
+    ff_subtitles_queue_clean(&vplayer->q);
+    return 0;
+}
+
+AVInputFormat ff_vplayer_demuxer = {
+    .name           = "vplayer",
+    .long_name      = NULL_IF_CONFIG_SMALL("VPlayer subtitles"),
+    .priv_data_size = sizeof(VPlayerContext),
+    .read_probe     = vplayer_probe,
+    .read_header    = vplayer_read_header,
+    .read_packet    = vplayer_read_packet,
+    .read_seek2     = vplayer_read_seek,
+    .read_close     = vplayer_read_close,
+    .extensions     = "txt",
+};
diff --git a/libavformat/w64.c b/libavformat/w64.c
new file mode 100644
index 0000000..7bf5502
--- /dev/null
+++ b/libavformat/w64.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2009 Daniel Verkamp
+ *
+ * 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 "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_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_fact[16] = { 'f', 'a', 'c', 't',
+    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 };
diff --git a/libavcodec/arm/dsputil_init_vfp.c b/libavformat/w64.h
similarity index 66%
copy from libavcodec/arm/dsputil_init_vfp.c
copy to libavformat/w64.h
index 5713c71..0ec3fa9 100644
--- a/libavcodec/arm/dsputil_init_vfp.c
+++ b/libavformat/w64.h
@@ -1,6 +1,4 @@
 /*
- * Copyright (c) 2008 Siarhei Siamashka <ssvb@users.sourceforge.net>
- *
  * This file is part of FFmpeg.
  *
  * FFmpeg is free software; you can redistribute it and/or
@@ -18,13 +16,16 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavcodec/dsputil.h"
-#include "dsputil_arm.h"
+#ifndef AVFORMAT_W64_H
+#define AVFORMAT_W64_H
 
-void ff_vector_fmul_reverse_vfp(float *dst, const float *src0,
-                                const float *src1, int len);
+#include <stdint.h>
 
-void ff_dsputil_init_vfp(DSPContext* c, AVCodecContext *avctx)
-{
-    c->vector_fmul_reverse = ff_vector_fmul_reverse_vfp;
-}
+extern const uint8_t ff_w64_guid_riff[16];
+extern const uint8_t ff_w64_guid_wave[16];
+extern const uint8_t ff_w64_guid_fmt [16];
+extern const uint8_t ff_w64_guid_fact[16];
+extern const uint8_t ff_w64_guid_data[16];
+extern const uint8_t ff_w64_guid_summarylist[16];
+
+#endif /* AVFORMAT_W64_H */
diff --git a/libavformat/wavdec.c b/libavformat/wavdec.c
index 62bf263..782fa64 100644
--- a/libavformat/wavdec.c
+++ b/libavformat/wavdec.c
@@ -33,8 +33,10 @@
 #include "avio_internal.h"
 #include "pcm.h"
 #include "riff.h"
+#include "w64.h"
 #include "avio.h"
 #include "metadata.h"
+#include "spdif.h"
 
 typedef struct WAVDemuxContext {
     const AVClass *class;
@@ -48,6 +50,7 @@
     int smv_eof;
     int audio_eof;
     int ignore_length;
+    int spdif;
 } WAVDemuxContext;
 
 
@@ -365,7 +368,7 @@
 
     avio_seek(pb, data_ofs, SEEK_SET);
 
-    if (!sample_count && st->codec->channels && 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;
@@ -396,9 +399,6 @@
     return -1;
 }
 
-static const uint8_t guid_data[16] = { 'd', 'a', 't', 'a',
-    0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A };
-
 #define MAX_SIZE 4096
 
 static int wav_read_packet(AVFormatContext *s,
@@ -409,6 +409,21 @@
     AVStream *st;
     WAVDemuxContext *wav = s->priv_data;
 
+    if (CONFIG_SPDIF_DEMUXER && wav->spdif == 0 &&
+        s->streams[0]->codec->codec_tag == 1) {
+        enum AVCodecID codec;
+        ret = ff_spdif_probe(s->pb->buffer, s->pb->buf_end - s->pb->buffer,
+                             &codec);
+        if (ret > AVPROBE_SCORE_MAX / 2) {
+            s->streams[0]->codec->codec_id = codec;
+            wav->spdif = 1;
+        } else {
+            wav->spdif = -1;
+        }
+    }
+    if (CONFIG_SPDIF_DEMUXER && wav->spdif == 1)
+        return ff_spdif_read_packet(s, pkt);
+
     if (wav->smv_data_ofs > 0) {
         int64_t audio_dts, video_dts;
 smv_retry:
@@ -455,7 +470,7 @@
         left= INT_MAX;
     if (left <= 0){
         if (CONFIG_W64_DEMUXER && wav->w64)
-            left = find_guid(s->pb, guid_data) - 24;
+            left = find_guid(s->pb, ff_w64_guid_data) - 24;
         else
             left = find_tag(s->pb, MKTAG('d', 'a', 't', 'a'));
         if (left < 0) {
@@ -541,21 +556,12 @@
 
 
 #if CONFIG_W64_DEMUXER
-static const uint8_t guid_riff[16] = { 'r', 'i', 'f', 'f',
-    0x2E, 0x91, 0xCF, 0x11, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 };
-
-static const uint8_t guid_wave[16] = { 'w', 'a', 'v', 'e',
-    0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A };
-
-static const uint8_t guid_fmt [16] = { 'f', 'm', 't', ' ',
-    0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A };
-
 static int w64_probe(AVProbeData *p)
 {
     if (p->buf_size <= 40)
         return 0;
-    if (!memcmp(p->buf,      guid_riff, 16) &&
-        !memcmp(p->buf + 24, guid_wave, 16))
+    if (!memcmp(p->buf,      ff_w64_guid_riff, 16) &&
+        !memcmp(p->buf + 24, ff_w64_guid_wave, 16))
         return AVPROBE_SCORE_MAX;
     else
         return 0;
@@ -563,7 +569,7 @@
 
 static int w64_read_header(AVFormatContext *s)
 {
-    int64_t size;
+    int64_t size, data_ofs = 0;
     AVIOContext *pb  = s->pb;
     WAVDemuxContext    *wav = s->priv_data;
     AVStream *st;
@@ -571,46 +577,98 @@
     int ret;
 
     avio_read(pb, guid, 16);
-    if (memcmp(guid, guid_riff, 16))
+    if (memcmp(guid, ff_w64_guid_riff, 16))
         return -1;
 
     if (avio_rl64(pb) < 16 + 8 + 16 + 8 + 16 + 8) /* riff + wave + fmt + sizes */
         return -1;
 
     avio_read(pb, guid, 16);
-    if (memcmp(guid, guid_wave, 16)) {
+    if (memcmp(guid, ff_w64_guid_wave, 16)) {
         av_log(s, AV_LOG_ERROR, "could not find wave guid\n");
         return -1;
     }
 
-    size = find_guid(pb, guid_fmt);
-    if (size < 0) {
-        av_log(s, AV_LOG_ERROR, "could not find fmt guid\n");
-        return -1;
-    }
+    wav->w64 = 1;
 
     st = avformat_new_stream(s, NULL);
     if (!st)
         return AVERROR(ENOMEM);
 
-    /* subtract chunk header size - normal wav file doesn't count it */
-    ret = ff_get_wav_header(pb, st->codec, size - 24);
-    if (ret < 0)
-        return ret;
-    avio_skip(pb, FFALIGN(size, INT64_C(8)) - size);
+    while (!url_feof(pb)) {
+        if (avio_read(pb, guid, 16) != 16)
+            break;
+        size = avio_rl64(pb);
+        if (size <= 24 || INT64_MAX - size < avio_tell(pb))
+            return AVERROR_INVALIDDATA;
+
+        if (!memcmp(guid, ff_w64_guid_fmt, 16)) {
+            /* subtract chunk header size - normal wav file doesn't count it */
+            ret = ff_get_wav_header(pb, st->codec, size - 24);
+            if (ret < 0)
+                return ret;
+            avio_skip(pb, FFALIGN(size, INT64_C(8)) - size);
+
+            avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
+        } else if (!memcmp(guid, ff_w64_guid_fact, 16)) {
+            int64_t samples;
+
+            samples = avio_rl64(pb);
+            if (samples > 0)
+                st->duration = samples;
+        } else if (!memcmp(guid, ff_w64_guid_data, 16)) {
+            wav->data_end = avio_tell(pb) + size - 24;
+
+            data_ofs = avio_tell(pb);
+            if (!pb->seekable)
+                break;
+
+            avio_skip(pb, size - 24);
+        } else if (!memcmp(guid, ff_w64_guid_summarylist, 16)) {
+            int64_t start, end, cur;
+            uint32_t count, chunk_size, i;
+
+            start = avio_tell(pb);
+            end = start + size;
+            count = avio_rl32(pb);
+
+            for (i = 0; i < count; i++) {
+                char chunk_key[5], *value;
+
+                if (url_feof(pb) || (cur = avio_tell(pb)) < 0 || cur > end - 8 /* = tag + size */)
+                    break;
+
+                chunk_key[4] = 0;
+                avio_read(pb, chunk_key, 4);
+                chunk_size = avio_rl32(pb);
+
+                value = av_mallocz(chunk_size + 1);
+                if (!value)
+                    return AVERROR(ENOMEM);
+
+                ret = avio_get_str16le(pb, chunk_size, value, chunk_size);
+                avio_skip(pb, chunk_size - ret);
+
+                av_dict_set(&s->metadata, chunk_key, value, AV_DICT_DONT_STRDUP_VAL);
+            }
+
+            avio_skip(pb, end - avio_tell(pb));
+        } else {
+            av_log(s, AV_LOG_DEBUG, "unknown guid: "FF_PRI_GUID"\n", FF_ARG_GUID(guid));
+            avio_skip(pb, size - 24);
+        }
+    }
+
+    if (!data_ofs)
+        return AVERROR_EOF;
+
+    ff_metadata_conv_ctx(s, NULL, wav_metadata_conv);
+    ff_metadata_conv_ctx(s, NULL, ff_riff_info_conv);
 
     handle_stream_probing(st);
     st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
 
-    avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
-
-    size = find_guid(pb, guid_data);
-    if (size < 0) {
-        av_log(s, AV_LOG_ERROR, "could not find data guid\n");
-        return -1;
-    }
-    wav->data_end = avio_tell(pb) + size - 24;
-    wav->w64      = 1;
+    avio_seek(pb, data_ofs, SEEK_SET);
 
     return 0;
 }
diff --git a/libavformat/wavenc.c b/libavformat/wavenc.c
index 5a4b085..fea38cf 100644
--- a/libavformat/wavenc.c
+++ b/libavformat/wavenc.c
@@ -2,6 +2,12 @@
  * WAV muxer
  * Copyright (c) 2001, 2002 Fabrice Bellard
  *
+ * Sony Wave64 muxer
+ * Copyright (c) 2012 Paul B Mahol
+ *
+ * WAV muxer RF64 support
+ * Copyright (c) 2013 Daniel Verkamp <daniel@drv.nu>
+ *
  * This file is part of FFmpeg.
  *
  * FFmpeg is free software; you can redistribute it and/or
@@ -33,16 +39,23 @@
 #include "internal.h"
 #include "riff.h"
 
+#define RF64_AUTO   (-1)
+#define RF64_NEVER  0
+#define RF64_ALWAYS 1
+
 typedef struct WAVMuxContext {
     const AVClass *class;
     int64_t data;
     int64_t fact_pos;
+    int64_t ds64;
     int64_t minpts;
     int64_t maxpts;
     int last_duration;
     int write_bext;
+    int rf64;
 } WAVMuxContext;
 
+#if CONFIG_WAV_MUXER
 static inline void bwf_write_bext_string(AVFormatContext *s, const char *key, int maxlen)
 {
     AVDictionaryEntry *tag;
@@ -103,10 +116,24 @@
     AVIOContext *pb = s->pb;
     int64_t fmt;
 
-    ffio_wfourcc(pb, "RIFF");
-    avio_wl32(pb, 0); /* file length */
+    if (wav->rf64 == RF64_ALWAYS) {
+        ffio_wfourcc(pb, "RF64");
+        avio_wl32(pb, -1); /* RF64 chunk size: use size in ds64 */
+    } else {
+        ffio_wfourcc(pb, "RIFF");
+        avio_wl32(pb, 0); /* file length */
+    }
+
     ffio_wfourcc(pb, "WAVE");
 
+    if (wav->rf64 != RF64_NEVER) {
+        /* write empty ds64 chunk or JUNK chunk to reserve space for ds64 */
+        ffio_wfourcc(pb, wav->rf64 == RF64_ALWAYS ? "ds64" : "JUNK");
+        avio_wl32(pb, 28); /* chunk size */
+        wav->ds64 = avio_tell(pb);
+        ffio_fill(pb, 0, 28);
+    }
+
     /* format header */
     fmt = ff_start_tag(pb, "fmt ");
     if (ff_put_wav_header(pb, s->streams[0]->codec) < 0) {
@@ -159,29 +186,63 @@
 {
     AVIOContext *pb  = s->pb;
     WAVMuxContext    *wav = s->priv_data;
-    int64_t file_size;
+    int64_t file_size, data_size;
+    int64_t number_of_samples = 0;
+    int rf64 = 0;
 
     avio_flush(pb);
 
     if (s->pb->seekable) {
-        ff_end_tag(pb, wav->data);
-
         /* update file size */
         file_size = avio_tell(pb);
-        avio_seek(pb, 4, SEEK_SET);
-        avio_wl32(pb, (uint32_t)(file_size - 8));
-        avio_seek(pb, file_size, SEEK_SET);
+        data_size = file_size - wav->data;
+        if (wav->rf64 == RF64_ALWAYS || (wav->rf64 == RF64_AUTO && file_size - 8 > UINT32_MAX)) {
+            rf64 = 1;
+        } else {
+            avio_seek(pb, 4, SEEK_SET);
+            avio_wl32(pb, (uint32_t)(file_size - 8));
+            avio_seek(pb, file_size, SEEK_SET);
 
-        avio_flush(pb);
+            ff_end_tag(pb, wav->data);
+            avio_flush(pb);
+        }
+
+        number_of_samples = av_rescale(wav->maxpts - wav->minpts + wav->last_duration,
+                                       s->streams[0]->codec->sample_rate * (int64_t)s->streams[0]->time_base.num,
+                                       s->streams[0]->time_base.den);
 
         if(s->streams[0]->codec->codec_tag != 0x01) {
             /* Update num_samps in fact chunk */
-            int number_of_samples;
-            number_of_samples = av_rescale(wav->maxpts - wav->minpts + wav->last_duration,
-                                           s->streams[0]->codec->sample_rate * (int64_t)s->streams[0]->time_base.num,
-                                           s->streams[0]->time_base.den);
             avio_seek(pb, wav->fact_pos, SEEK_SET);
-            avio_wl32(pb, number_of_samples);
+            if (rf64 || (wav->rf64 == RF64_AUTO && number_of_samples > UINT32_MAX)) {
+                rf64 = 1;
+                avio_wl32(pb, -1);
+            } else {
+                avio_wl32(pb, number_of_samples);
+                avio_seek(pb, file_size, SEEK_SET);
+                avio_flush(pb);
+            }
+        }
+
+        if (rf64) {
+            /* overwrite RIFF with RF64 */
+            avio_seek(pb, 0, SEEK_SET);
+            ffio_wfourcc(pb, "RF64");
+            avio_wl32(pb, -1);
+
+            /* write ds64 chunk (overwrite JUNK if rf64 == RF64_AUTO) */
+            avio_seek(pb, wav->ds64 - 8, SEEK_SET);
+            ffio_wfourcc(pb, "ds64");
+            avio_wl32(pb, 28);                  /* ds64 chunk size */
+            avio_wl64(pb, file_size - 8);       /* RF64 chunk size */
+            avio_wl64(pb, data_size);           /* data chunk size */
+            avio_wl64(pb, number_of_samples);   /* fact chunk number of samples */
+            avio_wl32(pb, 0);                   /* number of table entries for non-'data' chunks */
+
+            /* write -1 in data chunk size */
+            avio_seek(pb, wav->data - 4, SEEK_SET);
+            avio_wl32(pb, -1);
+
             avio_seek(pb, file_size, SEEK_SET);
             avio_flush(pb);
         }
@@ -193,6 +254,10 @@
 #define ENC AV_OPT_FLAG_ENCODING_PARAM
 static const AVOption options[] = {
     { "write_bext", "Write BEXT chunk.", OFFSET(write_bext), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, ENC },
+    { "rf64",       "Use RF64 header rather than RIFF for large files.",    OFFSET(rf64), AV_OPT_TYPE_INT,   { .i64 = RF64_NEVER  },-1, 1, ENC, "rf64" },
+    { "auto",       "Write RF64 header if file grows large enough.",        0,            AV_OPT_TYPE_CONST, { .i64 = RF64_AUTO   }, 0, 0, ENC, "rf64" },
+    { "always",     "Always write RF64 header regardless of file size.",    0,            AV_OPT_TYPE_CONST, { .i64 = RF64_ALWAYS }, 0, 0, ENC, "rf64" },
+    { "never",      "Never write RF64 header regardless of file size.",     0,            AV_OPT_TYPE_CONST, { .i64 = RF64_NEVER  }, 0, 0, ENC, "rf64" },
     { NULL },
 };
 
@@ -218,3 +283,101 @@
     .codec_tag         = (const AVCodecTag* const []){ ff_codec_wav_tags, 0 },
     .priv_class        = &wav_muxer_class,
 };
+#endif /* CONFIG_WAV_MUXER */
+
+#if CONFIG_W64_MUXER
+#include "w64.h"
+
+static void start_guid(AVIOContext *pb, const uint8_t *guid, int64_t *pos)
+{
+    *pos = avio_tell(pb);
+
+    avio_write(pb, guid, 16);
+    avio_wl64(pb, INT64_MAX);
+}
+
+static void end_guid(AVIOContext *pb, int64_t start)
+{
+    int64_t end, pos = avio_tell(pb);
+
+    end = FFALIGN(pos, 8);
+    ffio_fill(pb, 0, end - pos);
+    avio_seek(pb, start + 16, SEEK_SET);
+    avio_wl64(pb, end - start);
+    avio_seek(pb, end, SEEK_SET);
+}
+
+static int w64_write_header(AVFormatContext *s)
+{
+    WAVMuxContext *wav = s->priv_data;
+    AVIOContext *pb = s->pb;
+    int64_t start;
+    int ret;
+
+    avio_write(pb, ff_w64_guid_riff, sizeof(ff_w64_guid_riff));
+    avio_wl64(pb, -1);
+    avio_write(pb, ff_w64_guid_wave, sizeof(ff_w64_guid_wave));
+    start_guid(pb, ff_w64_guid_fmt, &start);
+    if ((ret = ff_put_wav_header(pb, s->streams[0]->codec)) < 0) {
+        av_log(s, AV_LOG_ERROR, "%s codec not supported\n",
+               s->streams[0]->codec->codec ? s->streams[0]->codec->codec->name : "NONE");
+        return ret;
+    }
+    end_guid(pb, start);
+
+    if (s->streams[0]->codec->codec_tag != 0x01 /* hence for all other than PCM */
+        && s->pb->seekable) {
+        start_guid(pb, ff_w64_guid_fact, &wav->fact_pos);
+        avio_wl64(pb, 0);
+        end_guid(pb, wav->fact_pos);
+    }
+
+    start_guid(pb, ff_w64_guid_data, &wav->data);
+
+    return 0;
+}
+
+static int w64_write_trailer(AVFormatContext *s)
+{
+    AVIOContext    *pb = s->pb;
+    WAVMuxContext *wav = s->priv_data;
+    int64_t file_size;
+
+    if (pb->seekable) {
+        end_guid(pb, wav->data);
+
+        file_size = avio_tell(pb);
+        avio_seek(pb, 16, SEEK_SET);
+        avio_wl64(pb, file_size);
+
+        if (s->streams[0]->codec->codec_tag != 0x01) {
+            int64_t number_of_samples;
+
+            number_of_samples = av_rescale(wav->maxpts - wav->minpts + wav->last_duration,
+                                           s->streams[0]->codec->sample_rate * (int64_t)s->streams[0]->time_base.num,
+                                           s->streams[0]->time_base.den);
+            avio_seek(pb, wav->fact_pos + 24, SEEK_SET);
+            avio_wl64(pb, number_of_samples);
+        }
+
+        avio_seek(pb, file_size, SEEK_SET);
+        avio_flush(pb);
+    }
+
+    return 0;
+}
+
+AVOutputFormat ff_w64_muxer = {
+    .name              = "w64",
+    .long_name         = NULL_IF_CONFIG_SMALL("Sony Wave64"),
+    .extensions        = "w64",
+    .priv_data_size    = sizeof(WAVMuxContext),
+    .audio_codec       = AV_CODEC_ID_PCM_S16LE,
+    .video_codec       = AV_CODEC_ID_NONE,
+    .write_header      = w64_write_header,
+    .write_packet      = wav_write_packet,
+    .write_trailer     = w64_write_trailer,
+    .flags             = AVFMT_TS_NONSTRICT,
+    .codec_tag         = (const AVCodecTag* const []){ ff_codec_wav_tags, 0 },
+};
+#endif /* CONFIG_W64_MUXER */
diff --git a/libavformat/webvttdec.c b/libavformat/webvttdec.c
index 7288e8f..694a020 100644
--- a/libavformat/webvttdec.c
+++ b/libavformat/webvttdec.c
@@ -54,29 +54,6 @@
     return AV_NOPTS_VALUE;
 }
 
-static int64_t extract_cue(AVBPrint *buf, AVIOContext *pb)
-{
-    int prev_chr_is_eol = 0;
-    int64_t pos = avio_tell(pb);
-
-    av_bprint_clear(buf);
-    for (;;) {
-        char c = avio_r8(pb);
-        if (!c)
-            break;
-        if (c == '\r' || c == '\n') {
-            if (prev_chr_is_eol)
-                break;
-            prev_chr_is_eol = (c == '\n');
-        } else
-            prev_chr_is_eol = 0;
-        if (c != '\r')
-            av_bprint_chars(buf, c, 1);
-    }
-    av_bprint_chars(buf, '\0', 1);
-    return pos;
-}
-
 static int webvtt_read_header(AVFormatContext *s)
 {
     WebVTTContext *webvtt = s->priv_data;
@@ -94,17 +71,21 @@
     av_bprint_init(&cue,    0, AV_BPRINT_SIZE_UNLIMITED);
 
     for (;;) {
-        int i, len;
-        int64_t pos = extract_cue(&cue, s->pb);
+        int i;
+        int64_t pos;
         AVPacket *sub;
-        const char *p = cue.str;
-        const char *identifier = p;
+        const char *p, *identifier;
         //const char *settings = NULL;
         int64_t ts_start, ts_end;
 
-        if (!*p) // EOF
+        ff_subtitles_read_chunk(s->pb, &cue);
+
+        if (!cue.len)
             break;
 
+        p = identifier = cue.str;
+        pos = avio_tell(s->pb);
+
         /* ignore header chunk */
         if (!strncmp(p, "\xEF\xBB\xBFWEBVTT", 9) ||
             !strncmp(p, "WEBVTT", 6))
@@ -143,8 +124,7 @@
             p++;
 
         /* create packet */
-        len = cue.str + cue.len - p - 1;
-        sub = ff_subtitles_queue_insert(&webvtt->q, p, len, 0);
+        sub = ff_subtitles_queue_insert(&webvtt->q, p, strlen(p), 0);
         if (!sub) {
             res = AVERROR(ENOMEM);
             goto end;
@@ -192,6 +172,5 @@
     .read_packet    = webvtt_read_packet,
     .read_seek2     = webvtt_read_seek,
     .read_close     = webvtt_read_close,
-    .flags          = AVFMT_GENERIC_INDEX,
     .extensions     = "vtt",
 };
diff --git a/libavformat/westwood_vqa.c b/libavformat/westwood_vqa.c
index 708f3e5..c996dad 100644
--- a/libavformat/westwood_vqa.c
+++ b/libavformat/westwood_vqa.c
@@ -233,7 +233,8 @@
                 switch (chunk_type) {
                 case SND1_TAG:
                     /* unpacked size is stored in header */
-                    pkt->duration = AV_RL16(pkt->data) / wsvqa->channels;
+                    if(pkt->data)
+                        pkt->duration = AV_RL16(pkt->data) / wsvqa->channels;
                     break;
                 case SND2_TAG:
                     /* 2 samples/byte, 1 or 2 samples per frame depending on stereo */
diff --git a/libavformat/wtvdec.c b/libavformat/wtvdec.c
index 0706145..e423370 100644
--- a/libavformat/wtvdec.c
+++ b/libavformat/wtvdec.c
@@ -149,7 +149,7 @@
     WtvFile *wf;
     uint8_t *buffer;
 
-    if (avio_seek(s->pb, first_sector << WTV_SECTOR_BITS, SEEK_SET) < 0)
+    if (avio_seek(s->pb, (int64_t)first_sector << WTV_SECTOR_BITS, SEEK_SET) < 0)
         return NULL;
 
     wf = av_mallocz(sizeof(WtvFile));
@@ -200,6 +200,9 @@
         return NULL;
     }
 
+    if ((int64_t)wf->sectors[wf->nb_sectors - 1] << WTV_SECTOR_BITS > avio_tell(s->pb))
+        av_log(s, AV_LOG_WARNING, "truncated file\n");
+
     /* check length */
     length &= 0xFFFFFFFFFFFF;
     if (length > ((int64_t)wf->nb_sectors << wf->sector_bits)) {
@@ -414,6 +417,7 @@
     char description[1024];
     unsigned int filesize;
     AVStream *st;
+    int ret;
     int64_t pos = avio_tell(pb);
 
     avio_get_str16le(pb, INT_MAX, mime, sizeof(mime));
@@ -430,21 +434,30 @@
     if (!st)
         goto done;
     av_dict_set(&st->metadata, "title", description, 0);
+    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
     st->codec->codec_id   = AV_CODEC_ID_MJPEG;
-    st->codec->codec_type = AVMEDIA_TYPE_ATTACHMENT;
-    st->codec->extradata  = av_mallocz(filesize);
-    if (!st->codec->extradata)
+    ret = av_get_packet(pb, &st->attached_pic, filesize);
+    if (ret < 0)
         goto done;
-    st->codec->extradata_size = filesize;
-    avio_read(pb, st->codec->extradata, filesize);
+    st->attached_pic.stream_index = st->index;
+    st->attached_pic.flags       |= AV_PKT_FLAG_KEY;
+    st->disposition              |= AV_DISPOSITION_ATTACHED_PIC;
 done:
     avio_seek(pb, pos + length, SEEK_SET);
 }
 
 static void get_tag(AVFormatContext *s, AVIOContext *pb, const char *key, int type, int length)
 {
-    int buf_size = FFMAX(2*length, LEN_PRETTY_GUID) + 1;
-    char *buf = av_malloc(buf_size);
+    int buf_size;
+    char *buf;
+
+    if (!strcmp(key, "WM/MediaThumbType")) {
+        avio_skip(pb, length);
+        return;
+    }
+
+    buf_size = FFMAX(2*length, LEN_PRETTY_GUID) + 1;
+    buf = av_malloc(buf_size);
     if (!buf)
         return;
 
@@ -922,7 +935,7 @@
     avio_skip(s->pb, 4);
     root_sector = avio_rl32(s->pb);
 
-    avio_seek(s->pb, root_sector << WTV_SECTOR_BITS, SEEK_SET);
+    avio_seek(s->pb, (int64_t)root_sector << WTV_SECTOR_BITS, SEEK_SET);
     root_size = avio_read(s->pb, root, root_size);
     if (root_size < 0)
         return AVERROR_INVALIDDATA;
diff --git a/libavformat/wtvenc.c b/libavformat/wtvenc.c
index 8300662..22917a4 100644
--- a/libavformat/wtvenc.c
+++ b/libavformat/wtvenc.c
@@ -103,6 +103,8 @@
 
     int64_t last_pts;
     int64_t last_serial;
+
+    AVPacket thumbnail;
 } WtvContext;
 
 
@@ -378,6 +380,8 @@
 
     for (i = 0; i < s->nb_streams; i++) {
         st = s->streams[i];
+        if (st->codec->codec_id == AV_CODEC_ID_MJPEG)
+            continue;
         ret = write_stream_codec(s, st);
         if (ret < 0) {
             av_log(s, AV_LOG_ERROR, "write stream codec failed codec_type(0x%x)\n", st->codec->codec_type);
@@ -389,6 +393,8 @@
 
     for (i = 0; i < s->nb_streams; i++) {
         st = s->streams[i];
+        if (st->codec->codec_id == AV_CODEC_ID_MJPEG)
+            continue;
         ret  = write_stream_data(s, st);
         if (ret < 0) {
             av_log(s, AV_LOG_ERROR, "write stream data failed codec_type(0x%x)\n", st->codec->codec_type);
@@ -425,6 +431,11 @@
     AVIOContext *pb = s->pb;
     WtvContext  *wctx = s->priv_data;
 
+    if (s->streams[pkt->stream_index]->codec->codec_id == AV_CODEC_ID_MJPEG && !wctx->thumbnail.size) {
+        av_copy_packet(&wctx->thumbnail, pkt);
+        return 0;
+    }
+
     /* emit sync chunk and 'timeline.table.0.entries.Event' record every 50 frames */
     if (wctx->serial - (wctx->nb_sp_pairs ? wctx->sp_pairs[wctx->nb_sp_pairs - 1].serial : 0) >= 50)
         write_sync(s);
@@ -546,7 +557,7 @@
     write_pad(pb, WTV_SECTOR_SIZE - ((nb_sectors << 2) % WTV_SECTOR_SIZE));
 }
 
-static int write_fat_sector(AVFormatContext *s, int64_t start_pos, int nb_sectors, int sector_bits, int depth)
+static int64_t write_fat_sector(AVFormatContext *s, int64_t start_pos, int nb_sectors, int sector_bits, int depth)
 {
     int64_t start_sector = start_pos >> WTV_SECTOR_BITS;
     int shift = sector_bits - WTV_SECTOR_BITS;
@@ -590,27 +601,66 @@
     avio_wl64(pb, wctx->last_serial);
 }
 
-static void write_tag(AVIOContext *pb, const char *key, const char *value)
+static void write_metadata_header(AVIOContext *pb, int type, const char *key, int value_size)
 {
     ff_put_guid(pb, &ff_metadata_guid);
-    avio_wl32(pb, 1);
-    avio_wl32(pb, strlen(value)*2 + 2);
+    avio_wl32(pb, type);
+    avio_wl32(pb, value_size);
     avio_put_str16le(pb, key);
+}
+
+static int metadata_header_size(const char *key)
+{
+    return 16 + 4 + 4 + strlen(key)*2 + 2;
+}
+
+static void write_tag_int32(AVIOContext *pb, const char *key, int value)
+{
+    write_metadata_header(pb, 0, key, 4);
+    avio_wl32(pb, value);
+}
+
+static void write_tag(AVIOContext *pb, const char *key, const char *value)
+{
+    write_metadata_header(pb, 1, key, strlen(value)*2 + 2);
     avio_put_str16le(pb, value);
 }
 
+static int attachment_value_size(const AVPacket *pkt, const AVDictionaryEntry *e)
+{
+    return strlen("image/jpeg")*2 + 2 + 1 + (e ? strlen(e->value)*2 : 0) + 2 + 4 + pkt->size;
+}
+
 static void write_table_entries_attrib(AVFormatContext *s)
 {
+    WtvContext *wctx = s->priv_data;
+    AVIOContext *pb = s->pb;
     AVDictionaryEntry *tag = 0;
 
     //FIXME: translate special tags (e.g. WM/Bitrate) to binary representation
     ff_metadata_conv(&s->metadata, ff_asf_metadata_conv, NULL);
     while ((tag = av_dict_get(s->metadata, "", tag, AV_DICT_IGNORE_SUFFIX)))
-        write_tag(s->pb, tag->key, tag->value);
+        write_tag(pb, tag->key, tag->value);
+
+    if (wctx->thumbnail.size) {
+        AVStream *st = s->streams[wctx->thumbnail.stream_index];
+        tag = av_dict_get(st->metadata, "title", NULL, 0);
+        write_metadata_header(pb, 2, "WM/Picture", attachment_value_size(&wctx->thumbnail, tag));
+
+        avio_put_str16le(pb, "image/jpeg");
+        avio_w8(pb, 0x10);
+        avio_put_str16le(pb, tag ? tag->value : "");
+
+        avio_wl32(pb, wctx->thumbnail.size);
+        avio_write(pb, wctx->thumbnail.data, wctx->thumbnail.size);
+
+        write_tag_int32(pb, "WM/MediaThumbType", 2);
+    }
 }
 
 static void write_table_redirector_legacy_attrib(AVFormatContext *s)
 {
+    WtvContext *wctx = s->priv_data;
     AVIOContext *pb = s->pb;
     AVDictionaryEntry *tag = 0;
     int64_t pos = 0;
@@ -618,7 +668,16 @@
     //FIXME: translate special tags to binary representation
     while ((tag = av_dict_get(s->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
         avio_wl64(pb, pos);
-        pos += 16 + 4 + 4 + strlen(tag->key)*2 + 2 + strlen(tag->value)*2 + 2;
+        pos += metadata_header_size(tag->key) + strlen(tag->value)*2 + 2;
+    }
+
+    if (wctx->thumbnail.size) {
+        AVStream *st = s->streams[wctx->thumbnail.stream_index];
+        avio_wl64(pb, pos);
+        pos += metadata_header_size("WM/Picture") + attachment_value_size(&wctx->thumbnail, av_dict_get(st->metadata, "title", NULL, 0));
+
+        avio_wl64(pb, pos);
+        pos += metadata_header_size("WM/MediaThumbType") + 4;
     }
 }
 
@@ -672,11 +731,10 @@
 
     //write fat table
     if (w->depth > 0) {
-        w->first_sector = write_fat_sector(s, start_pos, nb_sectors, sector_bits, w->depth);
+        w->first_sector = write_fat_sector(s, start_pos, nb_sectors, sector_bits, w->depth) >> WTV_SECTOR_BITS;
     } else {
-        w->first_sector = start_pos;
+        w->first_sector = start_pos >> WTV_SECTOR_BITS;
     }
-    w->first_sector >>= WTV_SECTOR_BITS;
 
     w->length |= 1ULL<<60;
     if (sector_bits == WTV_SECTOR_BITS)
@@ -733,6 +791,7 @@
 
     av_free(wctx->sp_pairs);
     av_free(wctx->st_pairs);
+    av_free_packet(&wctx->thumbnail);
     return 0;
 }
 
diff --git a/libavformat/yop.c b/libavformat/yop.c
index 8f140ce..d1c0129 100644
--- a/libavformat/yop.c
+++ b/libavformat/yop.c
@@ -106,6 +106,8 @@
     yop->palette_size       = video_dec->extradata[0] * 3 + 4;
     yop->audio_block_length = AV_RL16(video_dec->extradata + 6);
 
+    video_dec->bit_rate     = 8 * (yop->frame_size - yop->audio_block_length) * frame_rate;
+
     // 1840 samples per frame, 1 nibble per sample; hence 1840/2 = 920
     if (yop->audio_block_length < 920 ||
         yop->audio_block_length + yop->palette_size >= yop->frame_size) {
diff --git a/libavformat/yuv4mpeg.c b/libavformat/yuv4mpeg.c
index bb038c9..f34a4af 100644
--- a/libavformat/yuv4mpeg.c
+++ b/libavformat/yuv4mpeg.c
@@ -18,6 +18,8 @@
  * 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/pixdesc.h"
 #include "avformat.h"
 #include "internal.h"
 #include "libavutil/pixdesc.h"
@@ -26,11 +28,6 @@
 #define Y4M_FRAME_MAGIC "FRAME"
 #define Y4M_LINE_MAX 256
 
-struct frame_attributes {
-    int interlaced_frame;
-    int top_field_first;
-};
-
 #if CONFIG_YUV4MPEGPIPE_MUXER
 static int yuv4_generate_header(AVFormatContext *s, char* buf)
 {
@@ -56,6 +53,13 @@
     inter = 'p'; /* progressive is the default */
     if (st->codec->coded_frame && st->codec->coded_frame->interlaced_frame)
         inter = st->codec->coded_frame->top_field_first ? 't' : 'b';
+    if (st->codec->field_order == AV_FIELD_PROGRESSIVE) {
+        inter = 'p';
+    } else if (st->codec->field_order == AV_FIELD_TB || st->codec->field_order == AV_FIELD_TT) {
+        inter = 't';
+    } else if (st->codec->field_order == AV_FIELD_BT || st->codec->field_order == AV_FIELD_BB) {
+        inter = 'b';
+    }
 
     switch (st->codec->pix_fmt) {
     case AV_PIX_FMT_GRAY8:
@@ -211,8 +215,8 @@
     if (st->codec->pix_fmt != AV_PIX_FMT_GRAY8 &&
         st->codec->pix_fmt != AV_PIX_FMT_GRAY16) {
         // Adjust for smaller Cb and Cr planes
-        avcodec_get_chroma_sub_sample(st->codec->pix_fmt, &h_chroma_shift,
-                                      &v_chroma_shift);
+        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;
 
@@ -276,7 +280,7 @@
                    av_get_pix_fmt_name(s->streams[0]->codec->pix_fmt));
             return AVERROR(EINVAL);
         }
-        av_log(s, AV_LOG_WARNING, "Warning: generating non standart YUV stream. "
+        av_log(s, AV_LOG_WARNING, "Warning: generating non standard YUV stream. "
                "Mjpegtools will not work.\n");
         break;
     default:
@@ -317,7 +321,7 @@
 {
     char header[MAX_YUV4_HEADER + 10];  // Include headroom for
                                         // the longest option
-    char *tokstart, *tokend, *header_end;
+    char *tokstart, *tokend, *header_end, interlaced = '?';
     int i;
     AVIOContext *pb = s->pb;
     int width = -1, height  = -1, raten   = 0,
@@ -325,7 +329,6 @@
     enum AVPixelFormat pix_fmt = AV_PIX_FMT_NONE, alt_pix_fmt = AV_PIX_FMT_NONE;
     enum AVChromaLocation chroma_sample_location = AVCHROMA_LOC_UNSPECIFIED;
     AVStream *st;
-    struct frame_attributes *s1 = s->priv_data;
 
     for (i = 0; i < MAX_YUV4_HEADER; i++) {
         header[i] = avio_r8(pb);
@@ -341,8 +344,6 @@
     if (strncmp(header, Y4M_MAGIC, strlen(Y4M_MAGIC)))
         return -1;
 
-    s1->interlaced_frame = 0;
-    s1->top_field_first = 0;
     header_end = &header[i + 1]; // Include space
     for (tokstart = &header[strlen(Y4M_MAGIC) + 1];
          tokstart < header_end; tokstart++) {
@@ -423,28 +424,7 @@
                 tokstart++;
             break;
         case 'I': // Interlace type
-            switch (*tokstart++){
-            case '?':
-                break;
-            case 'p':
-                s1->interlaced_frame = 0;
-                break;
-            case 't':
-                s1->interlaced_frame = 1;
-                s1->top_field_first = 1;
-                break;
-            case 'b':
-                s1->interlaced_frame = 1;
-                s1->top_field_first = 0;
-                break;
-            case 'm':
-                av_log(s, AV_LOG_ERROR, "YUV4MPEG stream contains mixed "
-                       "interlaced and non-interlaced frames.\n");
-                return -1;
-            default:
-                av_log(s, AV_LOG_ERROR, "YUV4MPEG has invalid header.\n");
-                return -1;
-            }
+            interlaced = *tokstart++;
             break;
         case 'F': // Frame rate
             sscanf(tokstart, "%d:%d", &raten, &rated); // 0:0 if unknown
@@ -545,6 +525,27 @@
     st->sample_aspect_ratio           = (AVRational){ aspectn, aspectd };
     st->codec->chroma_sample_location = chroma_sample_location;
 
+    switch (interlaced){
+    case 'p':
+        st->codec->field_order = AV_FIELD_PROGRESSIVE;
+        break;
+    case 't':
+        st->codec->field_order = AV_FIELD_TB;
+        break;
+    case 'b':
+        st->codec->field_order = AV_FIELD_BT;
+        break;
+    case 'm':
+        av_log(s, AV_LOG_ERROR, "YUV4MPEG stream contains mixed "
+               "interlaced and non-interlaced frames.\n");
+    case '?':
+        st->codec->field_order = AV_FIELD_UNKNOWN;
+        break;
+    default:
+        av_log(s, AV_LOG_ERROR, "YUV4MPEG has invalid header.\n");
+        return AVERROR(EINVAL);
+    }
+
     return 0;
 }
 
@@ -554,7 +555,6 @@
     char header[MAX_FRAME_HEADER+1];
     int packet_size, width, height, ret;
     AVStream *st = s->streams[0];
-    struct frame_attributes *s1 = s->priv_data;
 
     for (i = 0; i < MAX_FRAME_HEADER; i++) {
         header[i] = avio_r8(s->pb);
@@ -586,11 +586,6 @@
     else if (ret != packet_size)
         return s->pb->eof_reached ? AVERROR_EOF : AVERROR(EIO);
 
-    if (st->codec->coded_frame) {
-        st->codec->coded_frame->interlaced_frame = s1->interlaced_frame;
-        st->codec->coded_frame->top_field_first  = s1->top_field_first;
-    }
-
     pkt->stream_index = 0;
     return 0;
 }
@@ -608,7 +603,6 @@
 AVInputFormat ff_yuv4mpegpipe_demuxer = {
     .name           = "yuv4mpegpipe",
     .long_name      = NULL_IF_CONFIG_SMALL("YUV4MPEG pipe"),
-    .priv_data_size = sizeof(struct frame_attributes),
     .read_probe     = yuv4_probe,
     .read_header    = yuv4_read_header,
     .read_packet    = yuv4_read_packet,
diff --git a/libavresample/Makefile b/libavresample/Makefile
index c0c20a9..6805280 100644
--- a/libavresample/Makefile
+++ b/libavresample/Makefile
@@ -8,6 +8,7 @@
        audio_data.o                                                     \
        audio_mix.o                                                      \
        audio_mix_matrix.o                                               \
+       dither.o                                                         \
        options.o                                                        \
        resample.o                                                       \
        utils.o                                                          \
diff --git a/libavresample/audio_convert.c b/libavresample/audio_convert.c
index dcf8a39..371617c 100644
--- a/libavresample/audio_convert.c
+++ b/libavresample/audio_convert.c
@@ -29,6 +29,7 @@
 #include "libavutil/samplefmt.h"
 #include "audio_convert.h"
 #include "audio_data.h"
+#include "dither.h"
 
 enum ConvFuncType {
     CONV_FUNC_TYPE_FLAT,
@@ -46,8 +47,10 @@
 
 struct AudioConvert {
     AVAudioResampleContext *avr;
+    DitherContext *dc;
     enum AVSampleFormat in_fmt;
     enum AVSampleFormat out_fmt;
+    int apply_map;
     int channels;
     int planes;
     int ptr_align;
@@ -246,10 +249,19 @@
     SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBL)
 }
 
+void ff_audio_convert_free(AudioConvert **ac)
+{
+    if (!*ac)
+        return;
+    ff_dither_free(&(*ac)->dc);
+    av_freep(ac);
+}
+
 AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr,
                                      enum AVSampleFormat out_fmt,
                                      enum AVSampleFormat in_fmt,
-                                     int channels)
+                                     int channels, int sample_rate,
+                                     int apply_map)
 {
     AudioConvert *ac;
     int in_planar, out_planar;
@@ -262,6 +274,19 @@
     ac->out_fmt  = out_fmt;
     ac->in_fmt   = in_fmt;
     ac->channels = channels;
+    ac->apply_map = apply_map;
+
+    if (avr->dither_method != AV_RESAMPLE_DITHER_NONE          &&
+        av_get_packed_sample_fmt(out_fmt) == AV_SAMPLE_FMT_S16 &&
+        av_get_bytes_per_sample(in_fmt) > 2) {
+        ac->dc = ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate,
+                                 apply_map);
+        if (!ac->dc) {
+            av_free(ac);
+            return NULL;
+        }
+        return ac;
+    }
 
     in_planar  = av_sample_fmt_is_planar(in_fmt);
     out_planar = av_sample_fmt_is_planar(out_fmt);
@@ -288,6 +313,16 @@
 {
     int use_generic = 1;
     int len         = in->nb_samples;
+    int p;
+
+    if (ac->dc) {
+        /* dithered conversion */
+        av_dlog(ac->avr, "%d samples - audio_convert: %s to %s (dithered)\n",
+                len, av_get_sample_fmt_name(ac->in_fmt),
+                av_get_sample_fmt_name(ac->out_fmt));
+
+        return ff_convert_dither(ac->dc, out, in);
+    }
 
     /* determine whether to use the optimized function based on pointer and
        samples alignment in both the input and output */
@@ -305,32 +340,73 @@
             av_get_sample_fmt_name(ac->out_fmt),
             use_generic ? ac->func_descr_generic : ac->func_descr);
 
-    switch (ac->func_type) {
-    case CONV_FUNC_TYPE_FLAT: {
-        int p;
-        if (!in->is_planar)
-            len *= in->channels;
-        if (use_generic) {
-            for (p = 0; p < ac->planes; p++)
-                ac->conv_flat_generic(out->data[p], in->data[p], len);
-        } else {
-            for (p = 0; p < ac->planes; p++)
-                ac->conv_flat(out->data[p], in->data[p], len);
+    if (ac->apply_map) {
+        ChannelMapInfo *map = &ac->avr->ch_map_info;
+
+        if (!av_sample_fmt_is_planar(ac->out_fmt)) {
+            av_log(ac->avr, AV_LOG_ERROR, "cannot remap packed format during conversion\n");
+            return AVERROR(EINVAL);
         }
-        break;
-    }
-    case CONV_FUNC_TYPE_INTERLEAVE:
-        if (use_generic)
-            ac->conv_interleave_generic(out->data[0], in->data, len, ac->channels);
-        else
-            ac->conv_interleave(out->data[0], in->data, len, ac->channels);
-        break;
-    case CONV_FUNC_TYPE_DEINTERLEAVE:
-        if (use_generic)
-            ac->conv_deinterleave_generic(out->data, in->data[0], len, ac->channels);
-        else
-            ac->conv_deinterleave(out->data, in->data[0], len, ac->channels);
-        break;
+
+        if (map->do_remap) {
+            if (av_sample_fmt_is_planar(ac->in_fmt)) {
+                conv_func_flat *convert = use_generic ? ac->conv_flat_generic :
+                                                        ac->conv_flat;
+
+                for (p = 0; p < ac->planes; p++)
+                    if (map->channel_map[p] >= 0)
+                        convert(out->data[p], in->data[map->channel_map[p]], len);
+            } else {
+                uint8_t *data[AVRESAMPLE_MAX_CHANNELS];
+                conv_func_deinterleave *convert = use_generic ?
+                                                  ac->conv_deinterleave_generic :
+                                                  ac->conv_deinterleave;
+
+                for (p = 0; p < ac->channels; p++)
+                    data[map->input_map[p]] = out->data[p];
+
+                convert(data, in->data[0], len, ac->channels);
+            }
+        }
+        if (map->do_copy || map->do_zero) {
+            for (p = 0; p < ac->planes; p++) {
+                if (map->channel_copy[p])
+                    memcpy(out->data[p], out->data[map->channel_copy[p]],
+                           len * out->stride);
+                else if (map->channel_zero[p])
+                    av_samples_set_silence(&out->data[p], 0, len, 1, ac->out_fmt);
+            }
+        }
+    } else {
+        switch (ac->func_type) {
+        case CONV_FUNC_TYPE_FLAT: {
+            if (!in->is_planar)
+                len *= in->channels;
+            if (use_generic) {
+                for (p = 0; p < ac->planes; p++)
+                    ac->conv_flat_generic(out->data[p], in->data[p], len);
+            } else {
+                for (p = 0; p < ac->planes; p++)
+                    ac->conv_flat(out->data[p], in->data[p], len);
+            }
+            break;
+        }
+        case CONV_FUNC_TYPE_INTERLEAVE:
+            if (use_generic)
+                ac->conv_interleave_generic(out->data[0], in->data, len,
+                                            ac->channels);
+            else
+                ac->conv_interleave(out->data[0], in->data, len, ac->channels);
+            break;
+        case CONV_FUNC_TYPE_DEINTERLEAVE:
+            if (use_generic)
+                ac->conv_deinterleave_generic(out->data, in->data[0], len,
+                                              ac->channels);
+            else
+                ac->conv_deinterleave(out->data, in->data[0], len,
+                                      ac->channels);
+            break;
+        }
     }
 
     out->nb_samples = in->nb_samples;
diff --git a/libavresample/audio_convert.h b/libavresample/audio_convert.h
index bc27223..6a3089d 100644
--- a/libavresample/audio_convert.h
+++ b/libavresample/audio_convert.h
@@ -23,10 +23,9 @@
 
 #include "libavutil/samplefmt.h"
 #include "avresample.h"
+#include "internal.h"
 #include "audio_data.h"
 
-typedef struct AudioConvert AudioConvert;
-
 /**
  * Set conversion function if the parameters match.
  *
@@ -54,16 +53,28 @@
 /**
  * Allocate and initialize AudioConvert context for sample format conversion.
  *
- * @param avr      AVAudioResampleContext
- * @param out_fmt  output sample format
- * @param in_fmt   input sample format
- * @param channels number of channels
- * @return         newly-allocated AudioConvert context
+ * @param avr         AVAudioResampleContext
+ * @param out_fmt     output sample format
+ * @param in_fmt      input sample format
+ * @param channels    number of channels
+ * @param sample_rate sample rate (used for dithering)
+ * @param apply_map   apply channel map during conversion
+ * @return            newly-allocated AudioConvert context
  */
 AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr,
                                      enum AVSampleFormat out_fmt,
                                      enum AVSampleFormat in_fmt,
-                                     int channels);
+                                     int channels, int sample_rate,
+                                     int apply_map);
+
+/**
+ * Free AudioConvert.
+ *
+ * The AudioConvert must have been previously allocated with ff_audio_convert_alloc().
+ *
+ * @param ac  AudioConvert struct
+ */
+void ff_audio_convert_free(AudioConvert **ac);
 
 /**
  * Convert audio data from one sample format to another.
diff --git a/libavresample/audio_data.c b/libavresample/audio_data.c
index 199a68c..c52f518 100644
--- a/libavresample/audio_data.c
+++ b/libavresample/audio_data.c
@@ -213,7 +213,7 @@
     av_freep(a);
 }
 
-int ff_audio_data_copy(AudioData *dst, AudioData *src)
+int ff_audio_data_copy(AudioData *dst, AudioData *src, ChannelMapInfo *map)
 {
     int ret, p;
 
@@ -221,6 +221,11 @@
     if (dst->sample_fmt != src->sample_fmt || dst->channels < src->channels)
         return AVERROR(EINVAL);
 
+    if (map && !src->is_planar) {
+        av_log(src, AV_LOG_ERROR, "cannot remap packed format during copy\n");
+        return AVERROR(EINVAL);
+    }
+
     /* if the input is empty, just empty the output */
     if (!src->nb_samples) {
         dst->nb_samples = 0;
@@ -233,8 +238,29 @@
         return ret;
 
     /* copy data */
-    for (p = 0; p < src->planes; p++)
-        memcpy(dst->data[p], src->data[p], src->nb_samples * src->stride);
+    if (map) {
+        if (map->do_remap) {
+            for (p = 0; p < src->planes; p++) {
+                if (map->channel_map[p] >= 0)
+                    memcpy(dst->data[p], src->data[map->channel_map[p]],
+                           src->nb_samples * src->stride);
+            }
+        }
+        if (map->do_copy || map->do_zero) {
+            for (p = 0; p < src->planes; p++) {
+                if (map->channel_copy[p])
+                    memcpy(dst->data[p], dst->data[map->channel_copy[p]],
+                           src->nb_samples * src->stride);
+                else if (map->channel_zero[p])
+                    av_samples_set_silence(&dst->data[p], 0, src->nb_samples,
+                                           1, dst->sample_fmt);
+            }
+        }
+    } else {
+        for (p = 0; p < src->planes; p++)
+            memcpy(dst->data[p], src->data[p], src->nb_samples * src->stride);
+    }
+
     dst->nb_samples = src->nb_samples;
 
     return 0;
diff --git a/libavresample/audio_data.h b/libavresample/audio_data.h
index 558e7e6..97236bb 100644
--- a/libavresample/audio_data.h
+++ b/libavresample/audio_data.h
@@ -27,11 +27,12 @@
 #include "libavutil/log.h"
 #include "libavutil/samplefmt.h"
 #include "avresample.h"
+#include "internal.h"
 
 /**
  * Audio buffer used for intermediate storage between conversion phases.
  */
-typedef struct AudioData {
+struct AudioData {
     const AVClass *class;               /**< AVClass for logging            */
     uint8_t *data[AVRESAMPLE_MAX_CHANNELS]; /**< data plane pointers        */
     uint8_t *buffer;                    /**< data buffer                    */
@@ -50,7 +51,7 @@
     int ptr_align;                      /**< minimum data pointer alignment */
     int samples_align;                  /**< allocated samples alignment    */
     const char *name;                   /**< name for debug logging         */
-} AudioData;
+};
 
 int ff_audio_data_set_channels(AudioData *a, int channels);
 
@@ -117,9 +118,10 @@
  *
  * @param out  output AudioData
  * @param in   input AudioData
+ * @param map  channel map, NULL if not remapping
  * @return     0 on success, negative AVERROR value on error
  */
-int ff_audio_data_copy(AudioData *out, AudioData *in);
+int ff_audio_data_copy(AudioData *out, AudioData *in, ChannelMapInfo *map);
 
 /**
  * Append data from one AudioData to the end of another.
diff --git a/libavresample/audio_mix.c b/libavresample/audio_mix.c
index dd2f33d..b69bfbc 100644
--- a/libavresample/audio_mix.c
+++ b/libavresample/audio_mix.c
@@ -30,14 +30,42 @@
 
 static const char *coeff_type_names[] = { "q8", "q15", "flt" };
 
+struct AudioMix {
+    AVAudioResampleContext *avr;
+    enum AVSampleFormat fmt;
+    enum AVMixCoeffType coeff_type;
+    uint64_t in_layout;
+    uint64_t out_layout;
+    int in_channels;
+    int out_channels;
+
+    int ptr_align;
+    int samples_align;
+    int has_optimized_func;
+    const char *func_descr;
+    const char *func_descr_generic;
+    mix_func *mix;
+    mix_func *mix_generic;
+
+    int in_matrix_channels;
+    int out_matrix_channels;
+    int output_zero[AVRESAMPLE_MAX_CHANNELS];
+    int input_skip[AVRESAMPLE_MAX_CHANNELS];
+    int output_skip[AVRESAMPLE_MAX_CHANNELS];
+    int16_t *matrix_q8[AVRESAMPLE_MAX_CHANNELS];
+    int32_t *matrix_q15[AVRESAMPLE_MAX_CHANNELS];
+    float   *matrix_flt[AVRESAMPLE_MAX_CHANNELS];
+    void   **matrix;
+};
+
 void ff_audio_mix_set_func(AudioMix *am, enum AVSampleFormat fmt,
                            enum AVMixCoeffType coeff_type, int in_channels,
                            int out_channels, int ptr_align, int samples_align,
                            const char *descr, void *mix_func)
 {
     if (fmt == am->fmt && coeff_type == am->coeff_type &&
-        ( in_channels ==  am->in_channels ||  in_channels == 0) &&
-        (out_channels == am->out_channels || out_channels == 0)) {
+        ( in_channels ==  am->in_matrix_channels ||  in_channels == 0) &&
+        (out_channels == am->out_matrix_channels || out_channels == 0)) {
         char chan_str[16];
         am->mix           = mix_func;
         am->func_descr    = descr;
@@ -59,11 +87,12 @@
         } else if (out_channels) {
                 snprintf(chan_str, sizeof(chan_str), "[any to %d] ",
                          out_channels);
+        } else {
+            snprintf(chan_str, sizeof(chan_str), "[any to any] ");
         }
         av_log(am->avr, AV_LOG_DEBUG, "audio_mix: found function: [fmt=%s] "
                "[c=%s] %s(%s)\n", av_get_sample_fmt_name(fmt),
-               coeff_type_names[coeff_type],
-               (in_channels || out_channels) ? chan_str : "", descr);
+               coeff_type_names[coeff_type], chan_str, descr);
     }
 }
 
@@ -255,6 +284,13 @@
 
 static int mix_function_init(AudioMix *am)
 {
+    am->func_descr = am->func_descr_generic = "n/a";
+    am->mix = am->mix_generic = NULL;
+
+    /* no need to set a mix function when we're skipping mixing */
+    if (!am->in_matrix_channels || !am->out_matrix_channels)
+        return 0;
+
     /* any-to-any C versions */
 
     ff_audio_mix_set_func(am, AV_SAMPLE_FMT_FLTP, AV_MIX_COEFF_TYPE_FLT,
@@ -302,35 +338,42 @@
     return 0;
 }
 
-int ff_audio_mix_init(AVAudioResampleContext *avr)
+AudioMix *ff_audio_mix_alloc(AVAudioResampleContext *avr)
 {
+    AudioMix *am;
     int ret;
 
+    am = av_mallocz(sizeof(*am));
+    if (!am)
+        return NULL;
+    am->avr = avr;
+
     if (avr->internal_sample_fmt != AV_SAMPLE_FMT_S16P &&
         avr->internal_sample_fmt != AV_SAMPLE_FMT_FLTP) {
         av_log(avr, AV_LOG_ERROR, "Unsupported internal format for "
                "mixing: %s\n",
                av_get_sample_fmt_name(avr->internal_sample_fmt));
-        return AVERROR(EINVAL);
+        goto error;
     }
 
+    am->fmt          = avr->internal_sample_fmt;
+    am->coeff_type   = avr->mix_coeff_type;
+    am->in_layout    = avr->in_channel_layout;
+    am->out_layout   = avr->out_channel_layout;
+    am->in_channels  = avr->in_channels;
+    am->out_channels = avr->out_channels;
+
     /* build matrix if the user did not already set one */
-    if (avr->am->matrix) {
-        if (avr->am->coeff_type != avr->mix_coeff_type      ||
-            avr->am->in_layout  != avr->in_channel_layout   ||
-            avr->am->out_layout != avr->out_channel_layout) {
-            av_log(avr, AV_LOG_ERROR,
-                   "Custom matrix does not match current parameters\n");
-            return AVERROR(EINVAL);
-        }
+    if (avr->mix_matrix) {
+        ret = ff_audio_mix_set_matrix(am, avr->mix_matrix, avr->in_channels);
+        if (ret < 0)
+            goto error;
+        av_freep(&avr->mix_matrix);
     } else {
-        int i, j;
-        char in_layout_name[128];
-        char out_layout_name[128];
         double *matrix_dbl = av_mallocz(avr->out_channels * avr->in_channels *
                                         sizeof(*matrix_dbl));
         if (!matrix_dbl)
-            return AVERROR(ENOMEM);
+            goto error;
 
         ret = avresample_build_matrix(avr->in_channel_layout,
                                       avr->out_channel_layout,
@@ -343,49 +386,34 @@
                                       avr->matrix_encoding);
         if (ret < 0) {
             av_free(matrix_dbl);
-            return ret;
+            goto error;
         }
 
-        av_get_channel_layout_string(in_layout_name, sizeof(in_layout_name),
-                                     avr->in_channels, avr->in_channel_layout);
-        av_get_channel_layout_string(out_layout_name, sizeof(out_layout_name),
-                                     avr->out_channels, avr->out_channel_layout);
-        av_log(avr, AV_LOG_DEBUG, "audio_mix: %s to %s\n",
-               in_layout_name, out_layout_name);
-        for (i = 0; i < avr->out_channels; i++) {
-            for (j = 0; j < avr->in_channels; j++) {
-                av_log(avr, AV_LOG_DEBUG, "  %0.3f ",
-                       matrix_dbl[i * avr->in_channels + j]);
-            }
-            av_log(avr, AV_LOG_DEBUG, "\n");
-        }
-
-        ret = avresample_set_matrix(avr, matrix_dbl, avr->in_channels);
+        ret = ff_audio_mix_set_matrix(am, matrix_dbl, avr->in_channels);
         if (ret < 0) {
+            av_log(avr, AV_LOG_ERROR, "error setting mix matrix\n");
             av_free(matrix_dbl);
-            return ret;
+            goto error;
         }
+
         av_free(matrix_dbl);
     }
 
-    avr->am->fmt          = avr->internal_sample_fmt;
-    avr->am->coeff_type   = avr->mix_coeff_type;
-    avr->am->in_layout    = avr->in_channel_layout;
-    avr->am->out_layout   = avr->out_channel_layout;
-    avr->am->in_channels  = avr->in_channels;
-    avr->am->out_channels = avr->out_channels;
+    return am;
 
-    ret = mix_function_init(avr->am);
-    if (ret < 0)
-        return ret;
-
-    return 0;
+error:
+    av_free(am);
+    return NULL;
 }
 
-void ff_audio_mix_close(AudioMix *am)
+void ff_audio_mix_free(AudioMix **am_p)
 {
-    if (!am)
+    AudioMix *am;
+
+    if (!*am_p)
         return;
+    am = *am_p;
+
     if (am->matrix) {
         av_free(am->matrix[0]);
         am->matrix = NULL;
@@ -393,12 +421,15 @@
     memset(am->matrix_q8,  0, sizeof(am->matrix_q8 ));
     memset(am->matrix_q15, 0, sizeof(am->matrix_q15));
     memset(am->matrix_flt, 0, sizeof(am->matrix_flt));
+
+    av_freep(am_p);
 }
 
 int ff_audio_mix(AudioMix *am, AudioData *src)
 {
     int use_generic = 1;
     int len = src->nb_samples;
+    int i, j;
 
     /* determine whether to use the optimized function based on pointer and
        samples alignment in both the input and output */
@@ -414,13 +445,295 @@
             src->nb_samples, am->in_channels, am->out_channels,
             use_generic ? am->func_descr_generic : am->func_descr);
 
-    if (use_generic)
-        am->mix_generic(src->data, am->matrix, len, am->out_channels,
-                        am->in_channels);
-    else
-        am->mix(src->data, am->matrix, len, am->out_channels, am->in_channels);
+    if (am->in_matrix_channels && am->out_matrix_channels) {
+        uint8_t **data;
+        uint8_t *data0[AVRESAMPLE_MAX_CHANNELS];
+
+        if (am->out_matrix_channels < am->out_channels ||
+             am->in_matrix_channels <  am->in_channels) {
+            for (i = 0, j = 0; i < FFMAX(am->in_channels, am->out_channels); i++) {
+                if (am->input_skip[i] || am->output_skip[i] || am->output_zero[i])
+                    continue;
+                data0[j++] = src->data[i];
+            }
+            data = data0;
+        } else {
+            data = src->data;
+        }
+
+        if (use_generic)
+            am->mix_generic(data, am->matrix, len, am->out_matrix_channels,
+                            am->in_matrix_channels);
+        else
+            am->mix(data, am->matrix, len, am->out_matrix_channels,
+                    am->in_matrix_channels);
+    }
+
+    if (am->out_matrix_channels < am->out_channels) {
+        for (i = 0; i < am->out_channels; i++)
+            if (am->output_zero[i])
+                av_samples_set_silence(&src->data[i], 0, len, 1, am->fmt);
+    }
 
     ff_audio_data_set_channels(src, am->out_channels);
 
     return 0;
 }
+
+int ff_audio_mix_get_matrix(AudioMix *am, double *matrix, int stride)
+{
+    int i, o, i0, o0;
+
+    if ( am->in_channels <= 0 ||  am->in_channels > AVRESAMPLE_MAX_CHANNELS ||
+        am->out_channels <= 0 || am->out_channels > AVRESAMPLE_MAX_CHANNELS) {
+        av_log(am->avr, AV_LOG_ERROR, "Invalid channel counts\n");
+        return AVERROR(EINVAL);
+    }
+
+#define GET_MATRIX_CONVERT(suffix, scale)                                   \
+    if (!am->matrix_ ## suffix[0]) {                                        \
+        av_log(am->avr, AV_LOG_ERROR, "matrix is not set\n");               \
+        return AVERROR(EINVAL);                                             \
+    }                                                                       \
+    for (o = 0, o0 = 0; o < am->out_channels; o++) {                        \
+        for (i = 0, i0 = 0; i < am->in_channels; i++) {                     \
+            if (am->input_skip[i] || am->output_zero[o])                    \
+                matrix[o * stride + i] = 0.0;                               \
+            else                                                            \
+                matrix[o * stride + i] = am->matrix_ ## suffix[o0][i0] *    \
+                                         (scale);                           \
+            if (!am->input_skip[i])                                         \
+                i0++;                                                       \
+        }                                                                   \
+        if (!am->output_zero[o])                                            \
+            o0++;                                                           \
+    }
+
+    switch (am->coeff_type) {
+    case AV_MIX_COEFF_TYPE_Q8:
+        GET_MATRIX_CONVERT(q8, 1.0 / 256.0);
+        break;
+    case AV_MIX_COEFF_TYPE_Q15:
+        GET_MATRIX_CONVERT(q15, 1.0 / 32768.0);
+        break;
+    case AV_MIX_COEFF_TYPE_FLT:
+        GET_MATRIX_CONVERT(flt, 1.0);
+        break;
+    default:
+        av_log(am->avr, AV_LOG_ERROR, "Invalid mix coeff type\n");
+        return AVERROR(EINVAL);
+    }
+
+    return 0;
+}
+
+static void reduce_matrix(AudioMix *am, const double *matrix, int stride)
+{
+    int i, o;
+
+    memset(am->output_zero, 0, sizeof(am->output_zero));
+    memset(am->input_skip,  0, sizeof(am->input_skip));
+    memset(am->output_skip, 0, sizeof(am->output_skip));
+
+    /* exclude output channels if they can be zeroed instead of mixed */
+    for (o = 0; o < am->out_channels; o++) {
+        int zero = 1;
+
+        /* check if the output is always silent */
+        for (i = 0; i < am->in_channels; i++) {
+            if (matrix[o * stride + i] != 0.0) {
+                zero = 0;
+                break;
+            }
+        }
+        /* check if the corresponding input channel makes a contribution to
+           any output channel */
+        if (o < am->in_channels) {
+            for (i = 0; i < am->out_channels; i++) {
+                if (matrix[i * stride + o] != 0.0) {
+                    zero = 0;
+                    break;
+                }
+            }
+        }
+        if (zero) {
+            am->output_zero[o] = 1;
+            am->out_matrix_channels--;
+        }
+    }
+    if (am->out_matrix_channels == 0) {
+        am->in_matrix_channels = 0;
+        return;
+    }
+
+    /* skip input channels that contribute fully only to the corresponding
+       output channel */
+    for (i = 0; i < FFMIN(am->in_channels, am->out_channels); i++) {
+        int skip = 1;
+
+        for (o = 0; o < am->out_channels; o++) {
+            int i0;
+            if ((o != i && matrix[o * stride + i] != 0.0) ||
+                (o == i && matrix[o * stride + i] != 1.0)) {
+                skip = 0;
+                break;
+            }
+            /* if the input contributes fully to the output, also check that no
+               other inputs contribute to this output */
+            if (o == i) {
+                for (i0 = 0; i0 < am->in_channels; i0++) {
+                    if (i0 != i && matrix[o * stride + i0] != 0.0) {
+                        skip = 0;
+                        break;
+                    }
+                }
+            }
+        }
+        if (skip) {
+            am->input_skip[i] = 1;
+            am->in_matrix_channels--;
+        }
+    }
+    /* skip input channels that do not contribute to any output channel */
+    for (; i < am->in_channels; i++) {
+        int contrib = 0;
+
+        for (o = 0; o < am->out_channels; o++) {
+            if (matrix[o * stride + i] != 0.0) {
+                contrib = 1;
+                break;
+            }
+        }
+        if (!contrib) {
+            am->input_skip[i] = 1;
+            am->in_matrix_channels--;
+        }
+    }
+    if (am->in_matrix_channels == 0) {
+        am->out_matrix_channels = 0;
+        return;
+    }
+
+    /* skip output channels that only get full contribution from the
+       corresponding input channel */
+    for (o = 0; o < FFMIN(am->in_channels, am->out_channels); o++) {
+        int skip = 1;
+        int o0;
+
+        for (i = 0; i < am->in_channels; i++) {
+            if ((o != i && matrix[o * stride + i] != 0.0) ||
+                (o == i && matrix[o * stride + i] != 1.0)) {
+                skip = 0;
+                break;
+            }
+        }
+        /* check if the corresponding input channel makes a contribution to
+           any other output channel */
+        i = o;
+        for (o0 = 0; o0 < am->out_channels; o0++) {
+            if (o0 != i && matrix[o0 * stride + i] != 0.0) {
+                skip = 0;
+                break;
+            }
+        }
+        if (skip) {
+            am->output_skip[o] = 1;
+            am->out_matrix_channels--;
+        }
+    }
+    if (am->out_matrix_channels == 0) {
+        am->in_matrix_channels = 0;
+        return;
+    }
+}
+
+int ff_audio_mix_set_matrix(AudioMix *am, const double *matrix, int stride)
+{
+    int i, o, i0, o0, ret;
+    char in_layout_name[128];
+    char out_layout_name[128];
+
+    if ( am->in_channels <= 0 ||  am->in_channels > AVRESAMPLE_MAX_CHANNELS ||
+        am->out_channels <= 0 || am->out_channels > AVRESAMPLE_MAX_CHANNELS) {
+        av_log(am->avr, AV_LOG_ERROR, "Invalid channel counts\n");
+        return AVERROR(EINVAL);
+    }
+
+    if (am->matrix) {
+        av_free(am->matrix[0]);
+        am->matrix = NULL;
+    }
+
+    am->in_matrix_channels  = am->in_channels;
+    am->out_matrix_channels = am->out_channels;
+
+    reduce_matrix(am, matrix, stride);
+
+#define CONVERT_MATRIX(type, expr)                                          \
+    am->matrix_## type[0] = av_mallocz(am->out_matrix_channels *            \
+                                       am->in_matrix_channels  *            \
+                                       sizeof(*am->matrix_## type[0]));     \
+    if (!am->matrix_## type[0])                                             \
+        return AVERROR(ENOMEM);                                             \
+    for (o = 0, o0 = 0; o < am->out_channels; o++) {                        \
+        if (am->output_zero[o] || am->output_skip[o])                       \
+            continue;                                                       \
+        if (o0 > 0)                                                         \
+            am->matrix_## type[o0] = am->matrix_## type[o0 - 1] +           \
+                                     am->in_matrix_channels;                \
+        for (i = 0, i0 = 0; i < am->in_channels; i++) {                     \
+            double v;                                                       \
+            if (am->input_skip[i])                                          \
+                continue;                                                   \
+            v = matrix[o * stride + i];                                     \
+            am->matrix_## type[o0][i0] = expr;                              \
+            i0++;                                                           \
+        }                                                                   \
+        o0++;                                                               \
+    }                                                                       \
+    am->matrix = (void **)am->matrix_## type;
+
+    if (am->in_matrix_channels && am->out_matrix_channels) {
+        switch (am->coeff_type) {
+        case AV_MIX_COEFF_TYPE_Q8:
+            CONVERT_MATRIX(q8, av_clip_int16(lrint(256.0 * v)))
+            break;
+        case AV_MIX_COEFF_TYPE_Q15:
+            CONVERT_MATRIX(q15, av_clipl_int32(llrint(32768.0 * v)))
+            break;
+        case AV_MIX_COEFF_TYPE_FLT:
+            CONVERT_MATRIX(flt, v)
+            break;
+        default:
+            av_log(am->avr, AV_LOG_ERROR, "Invalid mix coeff type\n");
+            return AVERROR(EINVAL);
+        }
+    }
+
+    ret = mix_function_init(am);
+    if (ret < 0)
+        return ret;
+
+    av_get_channel_layout_string(in_layout_name, sizeof(in_layout_name),
+                                 am->in_channels, am->in_layout);
+    av_get_channel_layout_string(out_layout_name, sizeof(out_layout_name),
+                                 am->out_channels, am->out_layout);
+    av_log(am->avr, AV_LOG_DEBUG, "audio_mix: %s to %s\n",
+           in_layout_name, out_layout_name);
+    av_log(am->avr, AV_LOG_DEBUG, "matrix size: %d x %d\n",
+           am->in_matrix_channels, am->out_matrix_channels);
+    for (o = 0; o < am->out_channels; o++) {
+        for (i = 0; i < am->in_channels; i++) {
+            if (am->output_zero[o])
+                av_log(am->avr, AV_LOG_DEBUG, "  (ZERO)");
+            else if (am->input_skip[i] || am->output_skip[o])
+                av_log(am->avr, AV_LOG_DEBUG, "  (SKIP)");
+            else
+                av_log(am->avr, AV_LOG_DEBUG, "  %0.3f ",
+                       matrix[o * am->in_channels + i]);
+        }
+        av_log(am->avr, AV_LOG_DEBUG, "\n");
+    }
+
+    return 0;
+}
diff --git a/libavresample/audio_mix.h b/libavresample/audio_mix.h
index 2199fff..5bae5ab 100644
--- a/libavresample/audio_mix.h
+++ b/libavresample/audio_mix.h
@@ -25,34 +25,12 @@
 
 #include "libavutil/samplefmt.h"
 #include "avresample.h"
+#include "internal.h"
 #include "audio_data.h"
 
 typedef void (mix_func)(uint8_t **src, void **matrix, int len, int out_ch,
                         int in_ch);
 
-typedef struct AudioMix {
-    AVAudioResampleContext *avr;
-    enum AVSampleFormat fmt;
-    enum AVMixCoeffType coeff_type;
-    uint64_t in_layout;
-    uint64_t out_layout;
-    int in_channels;
-    int out_channels;
-
-    int ptr_align;
-    int samples_align;
-    int has_optimized_func;
-    const char *func_descr;
-    const char *func_descr_generic;
-    mix_func *mix;
-    mix_func *mix_generic;
-
-    int16_t *matrix_q8[AVRESAMPLE_MAX_CHANNELS];
-    int32_t *matrix_q15[AVRESAMPLE_MAX_CHANNELS];
-    float   *matrix_flt[AVRESAMPLE_MAX_CHANNELS];
-    void   **matrix;
-} AudioMix;
-
 /**
  * Set mixing function if the parameters match.
  *
@@ -79,28 +57,36 @@
                            const char *descr, void *mix_func);
 
 /**
- * Initialize the AudioMix context in the AVAudioResampleContext.
+ * Allocate and initialize an AudioMix context.
  *
  * The parameters in the AVAudioResampleContext are used to initialize the
- * AudioMix context and set the mixing matrix.
+ * AudioMix context.
  *
  * @param avr  AVAudioResampleContext
- * @return     0 on success, negative AVERROR code on failure
+ * @return     newly-allocated AudioMix context.
  */
-int ff_audio_mix_init(AVAudioResampleContext *avr);
+AudioMix *ff_audio_mix_alloc(AVAudioResampleContext *avr);
 
 /**
- * Close an AudioMix context.
- *
- * This clears and frees the mixing matrix arrays.
+ * Free an AudioMix context.
  */
-void ff_audio_mix_close(AudioMix *am);
+void ff_audio_mix_free(AudioMix **am);
 
 /**
  * Apply channel mixing to audio data using the current mixing matrix.
  */
 int ff_audio_mix(AudioMix *am, AudioData *src);
 
+/**
+ * Get the current mixing matrix.
+ */
+int ff_audio_mix_get_matrix(AudioMix *am, double *matrix, int stride);
+
+/**
+ * Set the current mixing matrix.
+ */
+int ff_audio_mix_set_matrix(AudioMix *am, const double *matrix, int stride);
+
 /* arch-specific initialization functions */
 
 void ff_audio_mix_init_x86(AudioMix *am);
diff --git a/libavresample/audio_mix_matrix.c b/libavresample/audio_mix_matrix.c
index 01a9336..8da1b48 100644
--- a/libavresample/audio_mix_matrix.c
+++ b/libavresample/audio_mix_matrix.c
@@ -287,115 +287,3 @@
 
     return 0;
 }
-
-int avresample_get_matrix(AVAudioResampleContext *avr, double *matrix,
-                          int stride)
-{
-    int in_channels, out_channels, i, o;
-
-    in_channels  = av_get_channel_layout_nb_channels(avr->in_channel_layout);
-    out_channels = av_get_channel_layout_nb_channels(avr->out_channel_layout);
-
-    if ( in_channels <= 0 ||  in_channels > AVRESAMPLE_MAX_CHANNELS ||
-        out_channels <= 0 || out_channels > AVRESAMPLE_MAX_CHANNELS) {
-        av_log(avr, AV_LOG_ERROR, "Invalid channel layouts\n");
-        return AVERROR(EINVAL);
-    }
-
-    switch (avr->mix_coeff_type) {
-    case AV_MIX_COEFF_TYPE_Q8:
-        if (!avr->am->matrix_q8[0]) {
-            av_log(avr, AV_LOG_ERROR, "matrix is not set\n");
-            return AVERROR(EINVAL);
-        }
-        for (o = 0; o < out_channels; o++)
-            for (i = 0; i < in_channels; i++)
-                matrix[o * stride + i] = avr->am->matrix_q8[o][i] / 256.0;
-        break;
-    case AV_MIX_COEFF_TYPE_Q15:
-        if (!avr->am->matrix_q15[0]) {
-            av_log(avr, AV_LOG_ERROR, "matrix is not set\n");
-            return AVERROR(EINVAL);
-        }
-        for (o = 0; o < out_channels; o++)
-            for (i = 0; i < in_channels; i++)
-                matrix[o * stride + i] = avr->am->matrix_q15[o][i] / 32768.0;
-        break;
-    case AV_MIX_COEFF_TYPE_FLT:
-        if (!avr->am->matrix_flt[0]) {
-            av_log(avr, AV_LOG_ERROR, "matrix is not set\n");
-            return AVERROR(EINVAL);
-        }
-        for (o = 0; o < out_channels; o++)
-            for (i = 0; i < in_channels; i++)
-                matrix[o * stride + i] = avr->am->matrix_flt[o][i];
-        break;
-    default:
-        av_log(avr, AV_LOG_ERROR, "Invalid mix coeff type\n");
-        return AVERROR(EINVAL);
-    }
-
-    return 0;
-}
-
-int avresample_set_matrix(AVAudioResampleContext *avr, const double *matrix,
-                          int stride)
-{
-    int in_channels, out_channels, i, o;
-
-    in_channels  = av_get_channel_layout_nb_channels(avr->in_channel_layout);
-    out_channels = av_get_channel_layout_nb_channels(avr->out_channel_layout);
-
-    if ( in_channels <= 0 ||  in_channels > AVRESAMPLE_MAX_CHANNELS ||
-        out_channels <= 0 || out_channels > AVRESAMPLE_MAX_CHANNELS) {
-        av_log(avr, AV_LOG_ERROR, "Invalid channel layouts\n");
-        return AVERROR(EINVAL);
-    }
-
-    if (avr->am->matrix) {
-        av_free(avr->am->matrix[0]);
-        avr->am->matrix = NULL;
-    }
-
-#define CONVERT_MATRIX(type, expr)                                          \
-    avr->am->matrix_## type[0] = av_mallocz(out_channels * in_channels *    \
-                                            sizeof(*avr->am->matrix_## type[0])); \
-    if (!avr->am->matrix_## type[0])                                        \
-        return AVERROR(ENOMEM);                                             \
-    for (o = 0; o < out_channels; o++) {                                    \
-        if (o > 0)                                                          \
-            avr->am->matrix_## type[o] = avr->am->matrix_## type[o - 1] +   \
-                                         in_channels;                       \
-        for (i = 0; i < in_channels; i++) {                                 \
-            double v = matrix[o * stride + i];                              \
-            avr->am->matrix_## type[o][i] = expr;                           \
-        }                                                                   \
-    }                                                                       \
-    avr->am->matrix = (void **)avr->am->matrix_## type;
-
-    switch (avr->mix_coeff_type) {
-    case AV_MIX_COEFF_TYPE_Q8:
-        CONVERT_MATRIX(q8, av_clip_int16(lrint(256.0 * v)))
-        break;
-    case AV_MIX_COEFF_TYPE_Q15:
-        CONVERT_MATRIX(q15, av_clipl_int32(llrint(32768.0 * v)))
-        break;
-    case AV_MIX_COEFF_TYPE_FLT:
-        CONVERT_MATRIX(flt, v)
-        break;
-    default:
-        av_log(avr, AV_LOG_ERROR, "Invalid mix coeff type\n");
-        return AVERROR(EINVAL);
-    }
-
-    /* TODO: detect situations where we can just swap around pointers
-             instead of doing matrix multiplications with 0.0 and 1.0 */
-
-    /* set AudioMix params */
-    avr->am->in_layout    = avr->in_channel_layout;
-    avr->am->out_layout   = avr->out_channel_layout;
-    avr->am->in_channels  = in_channels;
-    avr->am->out_channels = out_channels;
-
-    return 0;
-}
diff --git a/libavresample/avresample-test.c b/libavresample/avresample-test.c
index ab49e48..81e9bf0 100644
--- a/libavresample/avresample-test.c
+++ b/libavresample/avresample-test.c
@@ -100,7 +100,7 @@
         a += M_PI * 1000.0 * 2.0 / sample_rate;
     }
 
-    /* 1 second of varing frequency between 100 and 10000 Hz */
+    /* 1 second of varying frequency between 100 and 10000 Hz */
     a = 0;
     for (i = 0; i < 1 * sample_rate && k < nb_samples; i++, k++) {
         v = sin(a) * 0.30;
diff --git a/libavresample/avresample.h b/libavresample/avresample.h
index affeeeb..d26f2ca 100644
--- a/libavresample/avresample.h
+++ b/libavresample/avresample.h
@@ -49,7 +49,7 @@
  * av_opt_set_int(avr, "in_sample_rate",     48000,                0);
  * av_opt_set_int(avr, "out_sample_rate",    44100,                0);
  * av_opt_set_int(avr, "in_sample_fmt",      AV_SAMPLE_FMT_FLTP,   0);
- * av_opt_set_int(avr, "out_sample_fmt,      AV_SAMPLE_FMT_S16,    0);
+ * av_opt_set_int(avr, "out_sample_fmt",     AV_SAMPLE_FMT_S16,    0);
  * @endcode
  *
  * Once the context is initialized, it must be opened with avresample_open(). If
@@ -119,6 +119,15 @@
     AV_RESAMPLE_FILTER_TYPE_KAISER,             /**< Kaiser Windowed Sinc */
 };
 
+enum AVResampleDitherMethod {
+    AV_RESAMPLE_DITHER_NONE,            /**< Do not use dithering */
+    AV_RESAMPLE_DITHER_RECTANGULAR,     /**< Rectangular Dither */
+    AV_RESAMPLE_DITHER_TRIANGULAR,      /**< Triangular Dither*/
+    AV_RESAMPLE_DITHER_TRIANGULAR_HP,   /**< Triangular Dither with High Pass */
+    AV_RESAMPLE_DITHER_TRIANGULAR_NS,   /**< Triangular Dither with Noise Shaping */
+    AV_RESAMPLE_DITHER_NB,              /**< Number of dither types. Not part of ABI. */
+};
+
 /**
  * Return the LIBAVRESAMPLE_VERSION_INT constant.
  */
@@ -216,6 +225,9 @@
 /**
  * Get the current channel mixing matrix.
  *
+ * If no custom matrix has been previously set or the AVAudioResampleContext is
+ * not open, an error is returned.
+ *
  * @param avr     audio resample context
  * @param matrix  mixing coefficients; matrix[i + stride * o] is the weight of
  *                input channel i in output channel o.
@@ -231,7 +243,8 @@
  * Allows for setting a custom mixing matrix, overriding the default matrix
  * generated internally during avresample_open(). This function can be called
  * anytime on an allocated context, either before or after calling
- * avresample_open(). avresample_convert() always uses the current matrix.
+ * avresample_open(), as long as the channel layouts have been set.
+ * avresample_convert() always uses the current matrix.
  * Calling avresample_close() on the context will clear the current matrix.
  *
  * @see avresample_close()
@@ -246,13 +259,42 @@
                           int stride);
 
 /**
+ * Set a customized input channel mapping.
+ *
+ * This function can only be called when the allocated context is not open.
+ * Also, the input channel layout must have already been set.
+ *
+ * Calling avresample_close() on the context will clear the channel mapping.
+ *
+ * The map for each input channel specifies the channel index in the source to
+ * use for that particular channel, or -1 to mute the channel. Source channels
+ * can be duplicated by using the same index for multiple input channels.
+ *
+ * Examples:
+ *
+ * Reordering 5.1 AAC order (C,L,R,Ls,Rs,LFE) to Libav order (L,R,C,LFE,Ls,Rs):
+ * { 1, 2, 0, 5, 3, 4 }
+ *
+ * Muting the 3rd channel in 4-channel input:
+ * { 0, 1, -1, 3 }
+ *
+ * Duplicating the left channel of stereo input:
+ * { 0, 0 }
+ *
+ * @param avr         audio resample context
+ * @param channel_map customized input channel mapping
+ * @return            0 on success, negative AVERROR code on failure
+ */
+int avresample_set_channel_mapping(AVAudioResampleContext *avr,
+                                   const int *channel_map);
+
+/**
  * Set compensation for resampling.
  *
- * This can be called anytime after avresample_open(). If resampling was not
- * being done previously, the AVAudioResampleContext is closed and reopened
- * with resampling enabled. In this case, any samples remaining in the output
- * FIFO and the current channel mixing matrix will be restored after reopening
- * the context.
+ * This can be called anytime after avresample_open(). If resampling is not
+ * automatically enabled because of a sample rate conversion, the
+ * "force_resampling" option must have been set to 1 when opening the context
+ * in order to use resampling compensation.
  *
  * @param avr                    audio resample context
  * @param sample_delta           compensation delta, in samples
diff --git a/libavresample/dither.c b/libavresample/dither.c
new file mode 100644
index 0000000..f24bf5c
--- /dev/null
+++ b/libavresample/dither.c
@@ -0,0 +1,439 @@
+/*
+ * Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
+ *
+ * Triangular with Noise Shaping is based on opusfile.
+ * Copyright (c) 1994-2012 by the Xiph.Org Foundation and contributors
+ *
+ * This file is part of Libav.
+ *
+ * Libav 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,
+ * 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
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Dithered Audio Sample Quantization
+ *
+ * Converts from dbl, flt, or s32 to s16 using dithering.
+ */
+
+#include <math.h>
+#include <stdint.h>
+
+#include "libavutil/common.h"
+#include "libavutil/lfg.h"
+#include "libavutil/mem.h"
+#include "libavutil/samplefmt.h"
+#include "audio_convert.h"
+#include "dither.h"
+#include "internal.h"
+
+typedef struct DitherState {
+    int mute;
+    unsigned int seed;
+    AVLFG lfg;
+    float *noise_buf;
+    int noise_buf_size;
+    int noise_buf_ptr;
+    float dither_a[4];
+    float dither_b[4];
+} DitherState;
+
+struct DitherContext {
+    DitherDSPContext  ddsp;
+    enum AVResampleDitherMethod method;
+    int apply_map;
+    ChannelMapInfo *ch_map_info;
+
+    int mute_dither_threshold;  // threshold for disabling dither
+    int mute_reset_threshold;   // threshold for resetting noise shaping
+    const float *ns_coef_b;     // noise shaping coeffs
+    const float *ns_coef_a;     // noise shaping coeffs
+
+    int channels;
+    DitherState *state;         // dither states for each channel
+
+    AudioData *flt_data;        // input data in fltp
+    AudioData *s16_data;        // dithered output in s16p
+    AudioConvert *ac_in;        // converter for input to fltp
+    AudioConvert *ac_out;       // converter for s16p to s16 (if needed)
+
+    void (*quantize)(int16_t *dst, const float *src, float *dither, int len);
+    int samples_align;
+};
+
+/* mute threshold, in seconds */
+#define MUTE_THRESHOLD_SEC 0.000333
+
+/* scale factor for 16-bit output.
+   The signal is attenuated slightly to avoid clipping */
+#define S16_SCALE 32753.0f
+
+/* scale to convert lfg from INT_MIN/INT_MAX to -0.5/0.5 */
+#define LFG_SCALE (1.0f / (2.0f * INT32_MAX))
+
+/* noise shaping coefficients */
+
+static const float ns_48_coef_b[4] = {
+    2.2374f, -0.7339f, -0.1251f, -0.6033f
+};
+
+static const float ns_48_coef_a[4] = {
+    0.9030f, 0.0116f, -0.5853f, -0.2571f
+};
+
+static const float ns_44_coef_b[4] = {
+    2.2061f, -0.4707f, -0.2534f, -0.6213f
+};
+
+static const float ns_44_coef_a[4] = {
+    1.0587f, 0.0676f, -0.6054f, -0.2738f
+};
+
+static void dither_int_to_float_rectangular_c(float *dst, int *src, int len)
+{
+    int i;
+    for (i = 0; i < len; i++)
+        dst[i] = src[i] * LFG_SCALE;
+}
+
+static void dither_int_to_float_triangular_c(float *dst, int *src0, int len)
+{
+    int i;
+    int *src1  = src0 + len;
+
+    for (i = 0; i < len; i++) {
+        float r = src0[i] * LFG_SCALE;
+        r      += src1[i] * LFG_SCALE;
+        dst[i]  = r;
+    }
+}
+
+static void quantize_c(int16_t *dst, const float *src, float *dither, int len)
+{
+    int i;
+    for (i = 0; i < len; i++)
+        dst[i] = av_clip_int16(lrintf(src[i] * S16_SCALE + dither[i]));
+}
+
+#define SQRT_1_6 0.40824829046386301723f
+
+static void dither_highpass_filter(float *src, int len)
+{
+    int i;
+
+    /* filter is from libswresample in FFmpeg */
+    for (i = 0; i < len - 2; i++)
+        src[i] = (-src[i] + 2 * src[i + 1] - src[i + 2]) * SQRT_1_6;
+}
+
+static int generate_dither_noise(DitherContext *c, DitherState *state,
+                                 int min_samples)
+{
+    int i;
+    int nb_samples  = FFALIGN(min_samples, 16) + 16;
+    int buf_samples = nb_samples *
+                      (c->method == AV_RESAMPLE_DITHER_RECTANGULAR ? 1 : 2);
+    unsigned int *noise_buf_ui;
+
+    av_freep(&state->noise_buf);
+    state->noise_buf_size = state->noise_buf_ptr = 0;
+
+    state->noise_buf = av_malloc(buf_samples * sizeof(*state->noise_buf));
+    if (!state->noise_buf)
+        return AVERROR(ENOMEM);
+    state->noise_buf_size = FFALIGN(min_samples, 16);
+    noise_buf_ui          = (unsigned int *)state->noise_buf;
+
+    av_lfg_init(&state->lfg, state->seed);
+    for (i = 0; i < buf_samples; i++)
+        noise_buf_ui[i] = av_lfg_get(&state->lfg);
+
+    c->ddsp.dither_int_to_float(state->noise_buf, noise_buf_ui, nb_samples);
+
+    if (c->method == AV_RESAMPLE_DITHER_TRIANGULAR_HP)
+        dither_highpass_filter(state->noise_buf, nb_samples);
+
+    return 0;
+}
+
+static void quantize_triangular_ns(DitherContext *c, DitherState *state,
+                                   int16_t *dst, const float *src,
+                                   int nb_samples)
+{
+    int i, j;
+    float *dither = &state->noise_buf[state->noise_buf_ptr];
+
+    if (state->mute > c->mute_reset_threshold)
+        memset(state->dither_a, 0, sizeof(state->dither_a));
+
+    for (i = 0; i < nb_samples; i++) {
+        float err = 0;
+        float sample = src[i] * S16_SCALE;
+
+        for (j = 0; j < 4; j++) {
+            err += c->ns_coef_b[j] * state->dither_b[j] -
+                   c->ns_coef_a[j] * state->dither_a[j];
+        }
+        for (j = 3; j > 0; j--) {
+            state->dither_a[j] = state->dither_a[j - 1];
+            state->dither_b[j] = state->dither_b[j - 1];
+        }
+        state->dither_a[0] = err;
+        sample -= err;
+
+        if (state->mute > c->mute_dither_threshold) {
+            dst[i]             = av_clip_int16(lrintf(sample));
+            state->dither_b[0] = 0;
+        } else {
+            dst[i]             = av_clip_int16(lrintf(sample + dither[i]));
+            state->dither_b[0] = av_clipf(dst[i] - sample, -1.5f, 1.5f);
+        }
+
+        state->mute++;
+        if (src[i])
+            state->mute = 0;
+    }
+}
+
+static int convert_samples(DitherContext *c, int16_t **dst, float * const *src,
+                           int channels, int nb_samples)
+{
+    int ch, ret;
+    int aligned_samples = FFALIGN(nb_samples, 16);
+
+    for (ch = 0; ch < channels; ch++) {
+        DitherState *state = &c->state[ch];
+
+        if (state->noise_buf_size < aligned_samples) {
+            ret = generate_dither_noise(c, state, nb_samples);
+            if (ret < 0)
+                return ret;
+        } else if (state->noise_buf_size - state->noise_buf_ptr < aligned_samples) {
+            state->noise_buf_ptr = 0;
+        }
+
+        if (c->method == AV_RESAMPLE_DITHER_TRIANGULAR_NS) {
+            quantize_triangular_ns(c, state, dst[ch], src[ch], nb_samples);
+        } else {
+            c->quantize(dst[ch], src[ch],
+                        &state->noise_buf[state->noise_buf_ptr],
+                        FFALIGN(nb_samples, c->samples_align));
+        }
+
+        state->noise_buf_ptr += aligned_samples;
+    }
+
+    return 0;
+}
+
+int ff_convert_dither(DitherContext *c, AudioData *dst, AudioData *src)
+{
+    int ret;
+    AudioData *flt_data;
+
+    /* output directly to dst if it is planar */
+    if (dst->sample_fmt == AV_SAMPLE_FMT_S16P)
+        c->s16_data = dst;
+    else {
+        /* make sure s16_data is large enough for the output */
+        ret = ff_audio_data_realloc(c->s16_data, src->nb_samples);
+        if (ret < 0)
+            return ret;
+    }
+
+    if (src->sample_fmt != AV_SAMPLE_FMT_FLTP || c->apply_map) {
+        /* make sure flt_data is large enough for the input */
+        ret = ff_audio_data_realloc(c->flt_data, src->nb_samples);
+        if (ret < 0)
+            return ret;
+        flt_data = c->flt_data;
+    }
+
+    if (src->sample_fmt != AV_SAMPLE_FMT_FLTP) {
+        /* convert input samples to fltp and scale to s16 range */
+        ret = ff_audio_convert(c->ac_in, flt_data, src);
+        if (ret < 0)
+            return ret;
+    } else if (c->apply_map) {
+        ret = ff_audio_data_copy(flt_data, src, c->ch_map_info);
+        if (ret < 0)
+            return ret;
+    } else {
+        flt_data = src;
+    }
+
+    /* check alignment and padding constraints */
+    if (c->method != AV_RESAMPLE_DITHER_TRIANGULAR_NS) {
+        int ptr_align     = FFMIN(flt_data->ptr_align,     c->s16_data->ptr_align);
+        int samples_align = FFMIN(flt_data->samples_align, c->s16_data->samples_align);
+        int aligned_len   = FFALIGN(src->nb_samples, c->ddsp.samples_align);
+
+        if (!(ptr_align % c->ddsp.ptr_align) && samples_align >= aligned_len) {
+            c->quantize      = c->ddsp.quantize;
+            c->samples_align = c->ddsp.samples_align;
+        } else {
+            c->quantize      = quantize_c;
+            c->samples_align = 1;
+        }
+    }
+
+    ret = convert_samples(c, (int16_t **)c->s16_data->data,
+                          (float * const *)flt_data->data, src->channels,
+                          src->nb_samples);
+    if (ret < 0)
+        return ret;
+
+    c->s16_data->nb_samples = src->nb_samples;
+
+    /* interleave output to dst if needed */
+    if (dst->sample_fmt == AV_SAMPLE_FMT_S16) {
+        ret = ff_audio_convert(c->ac_out, dst, c->s16_data);
+        if (ret < 0)
+            return ret;
+    } else
+        c->s16_data = NULL;
+
+    return 0;
+}
+
+void ff_dither_free(DitherContext **cp)
+{
+    DitherContext *c = *cp;
+    int ch;
+
+    if (!c)
+        return;
+    ff_audio_data_free(&c->flt_data);
+    ff_audio_data_free(&c->s16_data);
+    ff_audio_convert_free(&c->ac_in);
+    ff_audio_convert_free(&c->ac_out);
+    for (ch = 0; ch < c->channels; ch++)
+        av_free(c->state[ch].noise_buf);
+    av_free(c->state);
+    av_freep(cp);
+}
+
+static void dither_init(DitherDSPContext *ddsp,
+                        enum AVResampleDitherMethod method)
+{
+    ddsp->quantize      = quantize_c;
+    ddsp->ptr_align     = 1;
+    ddsp->samples_align = 1;
+
+    if (method == AV_RESAMPLE_DITHER_RECTANGULAR)
+        ddsp->dither_int_to_float = dither_int_to_float_rectangular_c;
+    else
+        ddsp->dither_int_to_float = dither_int_to_float_triangular_c;
+
+    if (ARCH_X86)
+        ff_dither_init_x86(ddsp, method);
+}
+
+DitherContext *ff_dither_alloc(AVAudioResampleContext *avr,
+                               enum AVSampleFormat out_fmt,
+                               enum AVSampleFormat in_fmt,
+                               int channels, int sample_rate, int apply_map)
+{
+    AVLFG seed_gen;
+    DitherContext *c;
+    int ch;
+
+    if (av_get_packed_sample_fmt(out_fmt) != AV_SAMPLE_FMT_S16 ||
+        av_get_bytes_per_sample(in_fmt) <= 2) {
+        av_log(avr, AV_LOG_ERROR, "dithering %s to %s is not supported\n",
+               av_get_sample_fmt_name(in_fmt), av_get_sample_fmt_name(out_fmt));
+        return NULL;
+    }
+
+    c = av_mallocz(sizeof(*c));
+    if (!c)
+        return NULL;
+
+    c->apply_map = apply_map;
+    if (apply_map)
+        c->ch_map_info = &avr->ch_map_info;
+
+    if (avr->dither_method == AV_RESAMPLE_DITHER_TRIANGULAR_NS &&
+        sample_rate != 48000 && sample_rate != 44100) {
+        av_log(avr, AV_LOG_WARNING, "sample rate must be 48000 or 44100 Hz "
+               "for triangular_ns dither. using triangular_hp instead.\n");
+        avr->dither_method = AV_RESAMPLE_DITHER_TRIANGULAR_HP;
+    }
+    c->method = avr->dither_method;
+    dither_init(&c->ddsp, c->method);
+
+    if (c->method == AV_RESAMPLE_DITHER_TRIANGULAR_NS) {
+        if (sample_rate == 48000) {
+            c->ns_coef_b = ns_48_coef_b;
+            c->ns_coef_a = ns_48_coef_a;
+        } else {
+            c->ns_coef_b = ns_44_coef_b;
+            c->ns_coef_a = ns_44_coef_a;
+        }
+    }
+
+    /* Either s16 or s16p output format is allowed, but s16p is used
+       internally, so we need to use a temp buffer and interleave if the output
+       format is s16 */
+    if (out_fmt != AV_SAMPLE_FMT_S16P) {
+        c->s16_data = ff_audio_data_alloc(channels, 1024, AV_SAMPLE_FMT_S16P,
+                                          "dither s16 buffer");
+        if (!c->s16_data)
+            goto fail;
+
+        c->ac_out = ff_audio_convert_alloc(avr, out_fmt, AV_SAMPLE_FMT_S16P,
+                                           channels, sample_rate, 0);
+        if (!c->ac_out)
+            goto fail;
+    }
+
+    if (in_fmt != AV_SAMPLE_FMT_FLTP || c->apply_map) {
+        c->flt_data = ff_audio_data_alloc(channels, 1024, AV_SAMPLE_FMT_FLTP,
+                                          "dither flt buffer");
+        if (!c->flt_data)
+            goto fail;
+    }
+    if (in_fmt != AV_SAMPLE_FMT_FLTP) {
+        c->ac_in = ff_audio_convert_alloc(avr, AV_SAMPLE_FMT_FLTP, in_fmt,
+                                          channels, sample_rate, c->apply_map);
+        if (!c->ac_in)
+            goto fail;
+    }
+
+    c->state = av_mallocz(channels * sizeof(*c->state));
+    if (!c->state)
+        goto fail;
+    c->channels = channels;
+
+    /* calculate thresholds for turning off dithering during periods of
+       silence to avoid replacing digital silence with quiet dither noise */
+    c->mute_dither_threshold = lrintf(sample_rate * MUTE_THRESHOLD_SEC);
+    c->mute_reset_threshold  = c->mute_dither_threshold * 4;
+
+    /* initialize dither states */
+    av_lfg_init(&seed_gen, 0xC0FFEE);
+    for (ch = 0; ch < channels; ch++) {
+        DitherState *state = &c->state[ch];
+        state->mute = c->mute_reset_threshold + 1;
+        state->seed = av_lfg_get(&seed_gen);
+        generate_dither_noise(c, state, FFMAX(32768, sample_rate / 2));
+    }
+
+    return c;
+
+fail:
+    ff_dither_free(&c);
+    return NULL;
+}
diff --git a/libavresample/dither.h b/libavresample/dither.h
new file mode 100644
index 0000000..8db3714
--- /dev/null
+++ b/libavresample/dither.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
+ *
+ * This file is part of Libav.
+ *
+ * Libav 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,
+ * 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
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVRESAMPLE_DITHER_H
+#define AVRESAMPLE_DITHER_H
+
+#include "avresample.h"
+#include "audio_data.h"
+
+typedef struct DitherContext DitherContext;
+
+typedef struct DitherDSPContext {
+    /**
+     * Convert samples from flt to s16 with added dither noise.
+     *
+     * @param dst    destination float array, range -0.5 to 0.5
+     * @param src    source int array, range INT_MIN to INT_MAX.
+     * @param dither float dither noise array
+     * @param len    number of samples
+     */
+    void (*quantize)(int16_t *dst, const float *src, float *dither, int len);
+
+    int ptr_align;      ///< src and dst constraits for quantize()
+    int samples_align;  ///< len constraits for quantize()
+
+    /**
+     * Convert dither noise from int to float with triangular distribution.
+     *
+     * @param dst  destination float array, range -0.5 to 0.5
+     *             constraints: 32-byte aligned
+     * @param src0 source int array, range INT_MIN to INT_MAX.
+     *             the array size is len * 2
+     *             constraints: 32-byte aligned
+     * @param len  number of output noise samples
+     *             constraints: multiple of 16
+     */
+    void (*dither_int_to_float)(float *dst, int *src0, int len);
+} DitherDSPContext;
+
+/**
+ * Allocate and initialize a DitherContext.
+ *
+ * The parameters in the AVAudioResampleContext are used to initialize the
+ * DitherContext.
+ *
+ * @param avr  AVAudioResampleContext
+ * @return     newly-allocated DitherContext
+ */
+DitherContext *ff_dither_alloc(AVAudioResampleContext *avr,
+                               enum AVSampleFormat out_fmt,
+                               enum AVSampleFormat in_fmt,
+                               int channels, int sample_rate, int apply_map);
+
+/**
+ * Free a DitherContext.
+ *
+ * @param c  DitherContext
+ */
+void ff_dither_free(DitherContext **c);
+
+/**
+ * Convert audio sample format with dithering.
+ *
+ * @param c    DitherContext
+ * @param dst  destination audio data
+ * @param src  source audio data
+ * @return     0 if ok, negative AVERROR code on failure
+ */
+int ff_convert_dither(DitherContext *c, AudioData *dst, AudioData *src);
+
+/* arch-specific initialization functions */
+
+void ff_dither_init_x86(DitherDSPContext *ddsp,
+                        enum AVResampleDitherMethod method);
+
+#endif /* AVRESAMPLE_DITHER_H */
diff --git a/libavresample/internal.h b/libavresample/internal.h
index 006b6fd..057f89a 100644
--- a/libavresample/internal.h
+++ b/libavresample/internal.h
@@ -26,10 +26,29 @@
 #include "libavutil/opt.h"
 #include "libavutil/samplefmt.h"
 #include "avresample.h"
-#include "audio_convert.h"
-#include "audio_data.h"
-#include "audio_mix.h"
-#include "resample.h"
+
+typedef struct AudioData AudioData;
+typedef struct AudioConvert AudioConvert;
+typedef struct AudioMix AudioMix;
+typedef struct ResampleContext ResampleContext;
+
+enum RemapPoint {
+    REMAP_NONE,
+    REMAP_IN_COPY,
+    REMAP_IN_CONVERT,
+    REMAP_OUT_COPY,
+    REMAP_OUT_CONVERT,
+};
+
+typedef struct ChannelMapInfo {
+    int channel_map[AVRESAMPLE_MAX_CHANNELS];   /**< source index of each output channel, -1 if not remapped */
+    int do_remap;                               /**< remap needed */
+    int channel_copy[AVRESAMPLE_MAX_CHANNELS];  /**< dest index to copy from */
+    int do_copy;                                /**< copy needed */
+    int channel_zero[AVRESAMPLE_MAX_CHANNELS];  /**< dest index to zero */
+    int do_zero;                                /**< zeroing needed */
+    int input_map[AVRESAMPLE_MAX_CHANNELS];     /**< dest index of each input channel */
+} ChannelMapInfo;
 
 struct AVAudioResampleContext {
     const AVClass *av_class;        /**< AVClass for logging and AVOptions  */
@@ -53,6 +72,7 @@
     double cutoff;                              /**< resampling cutoff frequency. 1.0 corresponds to half the output sample rate */
     enum AVResampleFilterType filter_type;      /**< resampling filter type */
     int kaiser_beta;                            /**< beta value for Kaiser window (only applicable if filter_type == AV_FILTER_TYPE_KAISER) */
+    enum AVResampleDitherMethod dither_method;  /**< dither method          */
 
     int in_channels;        /**< number of input channels                   */
     int out_channels;       /**< number of output channels                  */
@@ -63,6 +83,7 @@
     int resample_needed;    /**< resampling is needed                       */
     int in_convert_needed;  /**< input sample format conversion is needed   */
     int out_convert_needed; /**< output sample format conversion is needed  */
+    int in_copy_needed;     /**< input data copy is needed                  */
 
     AudioData *in_buffer;           /**< buffer for converted input         */
     AudioData *resample_out_buffer; /**< buffer for output from resampler   */
@@ -74,6 +95,16 @@
     ResampleContext *resample;  /**< resampling context                      */
     AudioMix *am;               /**< channel mixing context                  */
     enum AVMatrixEncoding matrix_encoding;      /**< matrixed stereo encoding */
+
+    /**
+     * mix matrix
+     * only used if avresample_set_matrix() is called before avresample_open()
+     */
+    double *mix_matrix;
+
+    int use_channel_map;
+    enum RemapPoint remap_point;
+    ChannelMapInfo ch_map_info;
 };
 
 #endif /* AVRESAMPLE_INTERNAL_H */
diff --git a/libavresample/options.c b/libavresample/options.c
index 8f64370..39c415b 100644
--- a/libavresample/options.c
+++ b/libavresample/options.c
@@ -40,7 +40,17 @@
     { "out_channel_layout",     "Output Channel Layout",    OFFSET(out_channel_layout),     AV_OPT_TYPE_INT64,  { .i64 = 0              }, INT64_MIN,            INT64_MAX,              PARAM },
     { "out_sample_fmt",         "Output Sample Format",     OFFSET(out_sample_fmt),         AV_OPT_TYPE_INT,    { .i64 = AV_SAMPLE_FMT_S16 }, AV_SAMPLE_FMT_U8,     AV_SAMPLE_FMT_NB-1,     PARAM },
     { "out_sample_rate",        "Output Sample Rate",       OFFSET(out_sample_rate),        AV_OPT_TYPE_INT,    { .i64 = 48000          }, 1,                    INT_MAX,                PARAM },
-    { "internal_sample_fmt",    "Internal Sample Format",   OFFSET(internal_sample_fmt),    AV_OPT_TYPE_INT,    { .i64 = AV_SAMPLE_FMT_NONE }, AV_SAMPLE_FMT_NONE,   AV_SAMPLE_FMT_NB-1,     PARAM },
+    { "internal_sample_fmt",    "Internal Sample Format",   OFFSET(internal_sample_fmt),    AV_OPT_TYPE_INT,    { .i64 = AV_SAMPLE_FMT_NONE }, AV_SAMPLE_FMT_NONE,   AV_SAMPLE_FMT_NB-1,     PARAM, "internal_sample_fmt" },
+        {"u8" ,  "8-bit unsigned integer",        0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_U8   }, INT_MIN, INT_MAX, PARAM, "internal_sample_fmt"},
+        {"s16",  "16-bit signed integer",         0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_S16  }, INT_MIN, INT_MAX, PARAM, "internal_sample_fmt"},
+        {"s32",  "32-bit signed integer",         0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_S32  }, INT_MIN, INT_MAX, PARAM, "internal_sample_fmt"},
+        {"flt",  "32-bit float",                  0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_FLT  }, INT_MIN, INT_MAX, PARAM, "internal_sample_fmt"},
+        {"dbl",  "64-bit double",                 0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_DBL  }, INT_MIN, INT_MAX, PARAM, "internal_sample_fmt"},
+        {"u8p" , "8-bit unsigned integer planar", 0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_U8P  }, INT_MIN, INT_MAX, PARAM, "internal_sample_fmt"},
+        {"s16p", "16-bit signed integer planar",  0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_S16P }, INT_MIN, INT_MAX, PARAM, "internal_sample_fmt"},
+        {"s32p", "32-bit signed integer planar",  0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_S32P }, INT_MIN, INT_MAX, PARAM, "internal_sample_fmt"},
+        {"fltp", "32-bit float planar",           0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_FLTP }, INT_MIN, INT_MAX, PARAM, "internal_sample_fmt"},
+        {"dblp", "64-bit double planar",          0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_DBLP }, INT_MIN, INT_MAX, PARAM, "internal_sample_fmt"},
     { "mix_coeff_type",         "Mixing Coefficient Type",  OFFSET(mix_coeff_type),         AV_OPT_TYPE_INT,    { .i64 = AV_MIX_COEFF_TYPE_FLT }, AV_MIX_COEFF_TYPE_Q8, AV_MIX_COEFF_TYPE_NB-1, PARAM, "mix_coeff_type" },
         { "q8",  "16-bit 8.8 Fixed-Point",   0, AV_OPT_TYPE_CONST, { .i64 = AV_MIX_COEFF_TYPE_Q8  }, INT_MIN, INT_MAX, PARAM, "mix_coeff_type" },
         { "q15", "32-bit 17.15 Fixed-Point", 0, AV_OPT_TYPE_CONST, { .i64 = AV_MIX_COEFF_TYPE_Q15 }, INT_MIN, INT_MAX, PARAM, "mix_coeff_type" },
@@ -54,6 +64,8 @@
     { "phase_shift",            "Resampling Phase Shift",   OFFSET(phase_shift),            AV_OPT_TYPE_INT,    { .i64 = 10             }, 0,                    30, /* ??? */           PARAM },
     { "linear_interp",          "Use Linear Interpolation", OFFSET(linear_interp),          AV_OPT_TYPE_INT,    { .i64 = 0              }, 0,                    1,                      PARAM },
     { "cutoff",                 "Cutoff Frequency Ratio",   OFFSET(cutoff),                 AV_OPT_TYPE_DOUBLE, { .dbl = 0.8            }, 0.0,                  1.0,                    PARAM },
+    /* duplicate option in order to work with avconv */
+    { "resample_cutoff",        "Cutoff Frequency Ratio",   OFFSET(cutoff),                 AV_OPT_TYPE_DOUBLE, { .dbl = 0.8            }, 0.0,                  1.0,                    PARAM },
     { "matrix_encoding",        "Matrixed Stereo Encoding", OFFSET(matrix_encoding),        AV_OPT_TYPE_INT,    {.i64 =  AV_MATRIX_ENCODING_NONE}, AV_MATRIX_ENCODING_NONE,     AV_MATRIX_ENCODING_NB-1, PARAM, "matrix_encoding" },
         { "none",  "None",               0, AV_OPT_TYPE_CONST, { .i64 = AV_MATRIX_ENCODING_NONE  }, INT_MIN, INT_MAX, PARAM, "matrix_encoding" },
         { "dolby", "Dolby",              0, AV_OPT_TYPE_CONST, { .i64 = AV_MATRIX_ENCODING_DOLBY }, INT_MIN, INT_MAX, PARAM, "matrix_encoding" },
@@ -63,6 +75,12 @@
         { "blackman_nuttall", "Blackman Nuttall Windowed Sinc", 0, AV_OPT_TYPE_CONST, { .i64 = AV_RESAMPLE_FILTER_TYPE_BLACKMAN_NUTTALL }, INT_MIN, INT_MAX, PARAM, "filter_type" },
         { "kaiser",           "Kaiser Windowed Sinc",           0, AV_OPT_TYPE_CONST, { .i64 = AV_RESAMPLE_FILTER_TYPE_KAISER           }, INT_MIN, INT_MAX, PARAM, "filter_type" },
     { "kaiser_beta",            "Kaiser Window Beta",       OFFSET(kaiser_beta),            AV_OPT_TYPE_INT,    { .i64 = 9              }, 2,                    16,                     PARAM },
+    { "dither_method",          "Dither Method",            OFFSET(dither_method),          AV_OPT_TYPE_INT,    { .i64 = AV_RESAMPLE_DITHER_NONE }, 0, AV_RESAMPLE_DITHER_NB-1, PARAM, "dither_method"},
+        {"none",          "No Dithering",                         0, AV_OPT_TYPE_CONST, { .i64 = AV_RESAMPLE_DITHER_NONE          }, INT_MIN, INT_MAX, PARAM, "dither_method"},
+        {"rectangular",   "Rectangular Dither",                   0, AV_OPT_TYPE_CONST, { .i64 = AV_RESAMPLE_DITHER_RECTANGULAR   }, INT_MIN, INT_MAX, PARAM, "dither_method"},
+        {"triangular",    "Triangular Dither",                    0, AV_OPT_TYPE_CONST, { .i64 = AV_RESAMPLE_DITHER_TRIANGULAR    }, INT_MIN, INT_MAX, PARAM, "dither_method"},
+        {"triangular_hp", "Triangular Dither With High Pass",     0, AV_OPT_TYPE_CONST, { .i64 = AV_RESAMPLE_DITHER_TRIANGULAR_HP }, INT_MIN, INT_MAX, PARAM, "dither_method"},
+        {"triangular_ns", "Triangular Dither With Noise Shaping", 0, AV_OPT_TYPE_CONST, { .i64 = AV_RESAMPLE_DITHER_TRIANGULAR_NS }, INT_MIN, INT_MAX, PARAM, "dither_method"},
     { NULL },
 };
 
@@ -84,13 +102,6 @@
     avr->av_class = &av_resample_context_class;
     av_opt_set_defaults(avr);
 
-    avr->am = av_mallocz(sizeof(*avr->am));
-    if (!avr->am) {
-        av_free(avr);
-        return NULL;
-    }
-    avr->am->avr = avr;
-
     return avr;
 }
 
diff --git a/libavresample/resample.c b/libavresample/resample.c
index 381d673..69c9bab 100644
--- a/libavresample/resample.c
+++ b/libavresample/resample.c
@@ -23,6 +23,7 @@
 #include "libavutil/libm.h"
 #include "libavutil/log.h"
 #include "internal.h"
+#include "resample.h"
 #include "audio_data.h"
 
 struct ResampleContext {
@@ -255,10 +256,12 @@
     if (!compensation_distance && sample_delta)
         return AVERROR(EINVAL);
 
-    /* if resampling was not enabled previously, re-initialize the
-       AVAudioResampleContext and force resampling */
     if (!avr->resample_needed) {
+#if FF_API_RESAMPLE_CLOSE_OPEN
+        /* if resampling was not enabled previously, re-initialize the
+           AVAudioResampleContext and force resampling */
         int fifo_samples;
+        int restore_matrix = 0;
         double matrix[AVRESAMPLE_MAX_CHANNELS * AVRESAMPLE_MAX_CHANNELS] = { 0 };
 
         /* buffer any remaining samples in the output FIFO before closing */
@@ -274,9 +277,12 @@
                 goto reinit_fail;
         }
         /* save the channel mixing matrix */
-        ret = avresample_get_matrix(avr, matrix, AVRESAMPLE_MAX_CHANNELS);
-        if (ret < 0)
-            goto reinit_fail;
+        if (avr->am) {
+            ret = avresample_get_matrix(avr, matrix, AVRESAMPLE_MAX_CHANNELS);
+            if (ret < 0)
+                goto reinit_fail;
+            restore_matrix = 1;
+        }
 
         /* close the AVAudioResampleContext */
         avresample_close(avr);
@@ -284,9 +290,11 @@
         avr->force_resampling = 1;
 
         /* restore the channel mixing matrix */
-        ret = avresample_set_matrix(avr, matrix, AVRESAMPLE_MAX_CHANNELS);
-        if (ret < 0)
-            goto reinit_fail;
+        if (restore_matrix) {
+            ret = avresample_set_matrix(avr, matrix, AVRESAMPLE_MAX_CHANNELS);
+            if (ret < 0)
+                goto reinit_fail;
+        }
 
         /* re-open the AVAudioResampleContext */
         ret = avresample_open(avr);
@@ -301,6 +309,10 @@
                 goto reinit_fail;
             ff_audio_data_free(&fifo_buf);
         }
+#else
+        av_log(avr, AV_LOG_ERROR, "Unable to set resampling compensation\n");
+        return AVERROR(EINVAL);
+#endif
     }
     c = avr->resample;
     c->compensation_distance = compensation_distance;
diff --git a/libavresample/resample.h b/libavresample/resample.h
index 7534e26..4544dab 100644
--- a/libavresample/resample.h
+++ b/libavresample/resample.h
@@ -22,10 +22,9 @@
 #define AVRESAMPLE_RESAMPLE_H
 
 #include "avresample.h"
+#include "internal.h"
 #include "audio_data.h"
 
-typedef struct ResampleContext ResampleContext;
-
 /**
  * Allocate and initialize a ResampleContext.
  *
diff --git a/libavresample/utils.c b/libavresample/utils.c
index 5591f15..c159e33 100644
--- a/libavresample/utils.c
+++ b/libavresample/utils.c
@@ -26,8 +26,11 @@
 #include "libavutil/opt.h"
 
 #include "avresample.h"
-#include "audio_data.h"
 #include "internal.h"
+#include "audio_data.h"
+#include "audio_convert.h"
+#include "audio_mix.h"
+#include "resample.h"
 
 int avresample_open(AVAudioResampleContext *avr)
 {
@@ -49,7 +52,7 @@
     avr->resample_channels = FFMIN(avr->in_channels, avr->out_channels);
     avr->downmix_needed    = avr->in_channels  > avr->out_channels;
     avr->upmix_needed      = avr->out_channels > avr->in_channels ||
-                             (!avr->downmix_needed && (avr->am->matrix ||
+                             (!avr->downmix_needed && (avr->mix_matrix ||
                               avr->in_channel_layout != avr->out_channel_layout));
     avr->mixing_needed     = avr->downmix_needed || avr->upmix_needed;
 
@@ -93,20 +96,84 @@
                av_get_sample_fmt_name(avr->internal_sample_fmt));
     }
 
-    /* set sample format conversion parameters */
+    /* treat all mono as planar for easier comparison */
     if (avr->in_channels == 1)
         avr->in_sample_fmt = av_get_planar_sample_fmt(avr->in_sample_fmt);
     if (avr->out_channels == 1)
         avr->out_sample_fmt = av_get_planar_sample_fmt(avr->out_sample_fmt);
-    avr->in_convert_needed = (avr->resample_needed || avr->mixing_needed) &&
-                              avr->in_sample_fmt != avr->internal_sample_fmt;
+
+    /* we may need to add an extra conversion in order to remap channels if
+       the output format is not planar */
+    if (avr->use_channel_map && !avr->mixing_needed && !avr->resample_needed &&
+        !av_sample_fmt_is_planar(avr->out_sample_fmt)) {
+        avr->internal_sample_fmt = av_get_planar_sample_fmt(avr->out_sample_fmt);
+    }
+
+    /* set sample format conversion parameters */
     if (avr->resample_needed || avr->mixing_needed)
+        avr->in_convert_needed = avr->in_sample_fmt != avr->internal_sample_fmt;
+    else
+        avr->in_convert_needed = avr->use_channel_map &&
+                                 !av_sample_fmt_is_planar(avr->out_sample_fmt);
+
+    if (avr->resample_needed || avr->mixing_needed || avr->in_convert_needed)
         avr->out_convert_needed = avr->internal_sample_fmt != avr->out_sample_fmt;
     else
         avr->out_convert_needed = avr->in_sample_fmt != avr->out_sample_fmt;
 
+    avr->in_copy_needed = !avr->in_convert_needed && (avr->mixing_needed ||
+                          (avr->use_channel_map && avr->resample_needed));
+
+    if (avr->use_channel_map) {
+        if (avr->in_copy_needed) {
+            avr->remap_point = REMAP_IN_COPY;
+            av_dlog(avr, "remap channels during in_copy\n");
+        } else if (avr->in_convert_needed) {
+            avr->remap_point = REMAP_IN_CONVERT;
+            av_dlog(avr, "remap channels during in_convert\n");
+        } else if (avr->out_convert_needed) {
+            avr->remap_point = REMAP_OUT_CONVERT;
+            av_dlog(avr, "remap channels during out_convert\n");
+        } else {
+            avr->remap_point = REMAP_OUT_COPY;
+            av_dlog(avr, "remap channels during out_copy\n");
+        }
+
+#ifdef DEBUG
+        {
+            int ch;
+            av_dlog(avr, "output map: ");
+            if (avr->ch_map_info.do_remap)
+                for (ch = 0; ch < avr->in_channels; ch++)
+                    av_dlog(avr, " % 2d", avr->ch_map_info.channel_map[ch]);
+            else
+                av_dlog(avr, "n/a");
+            av_dlog(avr, "\n");
+            av_dlog(avr, "copy map:   ");
+            if (avr->ch_map_info.do_copy)
+                for (ch = 0; ch < avr->in_channels; ch++)
+                    av_dlog(avr, " % 2d", avr->ch_map_info.channel_copy[ch]);
+            else
+                av_dlog(avr, "n/a");
+            av_dlog(avr, "\n");
+            av_dlog(avr, "zero map:   ");
+            if (avr->ch_map_info.do_zero)
+                for (ch = 0; ch < avr->in_channels; ch++)
+                    av_dlog(avr, " % 2d", avr->ch_map_info.channel_zero[ch]);
+            else
+                av_dlog(avr, "n/a");
+            av_dlog(avr, "\n");
+            av_dlog(avr, "input map:  ");
+            for (ch = 0; ch < avr->in_channels; ch++)
+                av_dlog(avr, " % 2d", avr->ch_map_info.input_map[ch]);
+            av_dlog(avr, "\n");
+        }
+#endif
+    } else
+        avr->remap_point = REMAP_NONE;
+
     /* allocate buffers */
-    if (avr->mixing_needed || avr->in_convert_needed) {
+    if (avr->in_copy_needed || avr->in_convert_needed) {
         avr->in_buffer = ff_audio_data_alloc(FFMAX(avr->in_channels, avr->out_channels),
                                              0, avr->internal_sample_fmt,
                                              "in_buffer");
@@ -142,7 +209,9 @@
     /* setup contexts */
     if (avr->in_convert_needed) {
         avr->ac_in = ff_audio_convert_alloc(avr, avr->internal_sample_fmt,
-                                            avr->in_sample_fmt, avr->in_channels);
+                                            avr->in_sample_fmt, avr->in_channels,
+                                            avr->in_sample_rate,
+                                            avr->remap_point == REMAP_IN_CONVERT);
         if (!avr->ac_in) {
             ret = AVERROR(ENOMEM);
             goto error;
@@ -155,7 +224,9 @@
         else
             src_fmt = avr->in_sample_fmt;
         avr->ac_out = ff_audio_convert_alloc(avr, avr->out_sample_fmt, src_fmt,
-                                             avr->out_channels);
+                                             avr->out_channels,
+                                             avr->out_sample_rate,
+                                             avr->remap_point == REMAP_OUT_CONVERT);
         if (!avr->ac_out) {
             ret = AVERROR(ENOMEM);
             goto error;
@@ -169,9 +240,11 @@
         }
     }
     if (avr->mixing_needed) {
-        ret = ff_audio_mix_init(avr);
-        if (ret < 0)
+        avr->am = ff_audio_mix_alloc(avr);
+        if (!avr->am) {
+            ret = AVERROR(ENOMEM);
             goto error;
+        }
     }
 
     return 0;
@@ -188,11 +261,13 @@
     ff_audio_data_free(&avr->out_buffer);
     av_audio_fifo_free(avr->out_fifo);
     avr->out_fifo = NULL;
-    av_freep(&avr->ac_in);
-    av_freep(&avr->ac_out);
+    ff_audio_convert_free(&avr->ac_in);
+    ff_audio_convert_free(&avr->ac_out);
     ff_audio_resample_free(&avr->resample);
-    ff_audio_mix_close(avr->am);
-    return;
+    ff_audio_mix_free(&avr->am);
+    av_freep(&avr->mix_matrix);
+
+    avr->use_channel_map = 0;
 }
 
 void avresample_free(AVAudioResampleContext **avr)
@@ -200,7 +275,6 @@
     if (!*avr)
         return;
     avresample_close(*avr);
-    av_freep(&(*avr)->am);
     av_opt_free(*avr);
     av_freep(avr);
 }
@@ -236,7 +310,9 @@
            data in the output FIFO */
         av_dlog(avr, "[copy] %s to output\n", converted->name);
         output->nb_samples = 0;
-        ret = ff_audio_data_copy(output, converted);
+        ret = ff_audio_data_copy(output, converted,
+                                 avr->remap_point == REMAP_OUT_COPY ?
+                                 &avr->ch_map_info : NULL);
         if (ret < 0)
             return ret;
         av_dlog(avr, "[end conversion]\n");
@@ -300,11 +376,24 @@
             /* in some rare cases we can copy input to output and upmix
                directly in the output buffer */
             av_dlog(avr, "[copy] %s to output\n", current_buffer->name);
-            ret = ff_audio_data_copy(&output_buffer, current_buffer);
+            ret = ff_audio_data_copy(&output_buffer, current_buffer,
+                                     avr->remap_point == REMAP_OUT_COPY ?
+                                     &avr->ch_map_info : NULL);
             if (ret < 0)
                 return ret;
             current_buffer = &output_buffer;
-        } else if (avr->mixing_needed || avr->in_convert_needed) {
+        } else if (avr->remap_point == REMAP_OUT_COPY &&
+                   (!direct_output || out_samples < in_samples)) {
+            /* if remapping channels during output copy, we may need to
+             * use an intermediate buffer in order to remap before adding
+             * samples to the output fifo */
+            av_dlog(avr, "[copy] %s to out_buffer\n", current_buffer->name);
+            ret = ff_audio_data_copy(avr->out_buffer, current_buffer,
+                                     &avr->ch_map_info);
+            if (ret < 0)
+                return ret;
+            current_buffer = avr->out_buffer;
+        } else if (avr->in_copy_needed || avr->in_convert_needed) {
             /* if needed, copy or convert input to in_buffer, and downmix if
                applicable */
             if (avr->in_convert_needed) {
@@ -319,7 +408,9 @@
                     return ret;
             } else {
                 av_dlog(avr, "[copy] %s to in_buffer\n", current_buffer->name);
-                ret = ff_audio_data_copy(avr->in_buffer, current_buffer);
+                ret = ff_audio_data_copy(avr->in_buffer, current_buffer,
+                                         avr->remap_point == REMAP_IN_COPY ?
+                                         &avr->ch_map_info : NULL);
                 if (ret < 0)
                     return ret;
             }
@@ -404,6 +495,117 @@
                                   current_buffer);
 }
 
+int avresample_get_matrix(AVAudioResampleContext *avr, double *matrix,
+                          int stride)
+{
+    int in_channels, out_channels, i, o;
+
+    if (avr->am)
+        return ff_audio_mix_get_matrix(avr->am, matrix, stride);
+
+    in_channels  = av_get_channel_layout_nb_channels(avr->in_channel_layout);
+    out_channels = av_get_channel_layout_nb_channels(avr->out_channel_layout);
+
+    if ( in_channels <= 0 ||  in_channels > AVRESAMPLE_MAX_CHANNELS ||
+        out_channels <= 0 || out_channels > AVRESAMPLE_MAX_CHANNELS) {
+        av_log(avr, AV_LOG_ERROR, "Invalid channel layouts\n");
+        return AVERROR(EINVAL);
+    }
+
+    if (!avr->mix_matrix) {
+        av_log(avr, AV_LOG_ERROR, "matrix is not set\n");
+        return AVERROR(EINVAL);
+    }
+
+    for (o = 0; o < out_channels; o++)
+        for (i = 0; i < in_channels; i++)
+            matrix[o * stride + i] = avr->mix_matrix[o * in_channels + i];
+
+    return 0;
+}
+
+int avresample_set_matrix(AVAudioResampleContext *avr, const double *matrix,
+                          int stride)
+{
+    int in_channels, out_channels, i, o;
+
+    if (avr->am)
+        return ff_audio_mix_set_matrix(avr->am, matrix, stride);
+
+    in_channels  = av_get_channel_layout_nb_channels(avr->in_channel_layout);
+    out_channels = av_get_channel_layout_nb_channels(avr->out_channel_layout);
+
+    if ( in_channels <= 0 ||  in_channels > AVRESAMPLE_MAX_CHANNELS ||
+        out_channels <= 0 || out_channels > AVRESAMPLE_MAX_CHANNELS) {
+        av_log(avr, AV_LOG_ERROR, "Invalid channel layouts\n");
+        return AVERROR(EINVAL);
+    }
+
+    if (avr->mix_matrix)
+        av_freep(&avr->mix_matrix);
+    avr->mix_matrix = av_malloc(in_channels * out_channels *
+                                sizeof(*avr->mix_matrix));
+    if (!avr->mix_matrix)
+        return AVERROR(ENOMEM);
+
+    for (o = 0; o < out_channels; o++)
+        for (i = 0; i < in_channels; i++)
+            avr->mix_matrix[o * in_channels + i] = matrix[o * stride + i];
+
+    return 0;
+}
+
+int avresample_set_channel_mapping(AVAudioResampleContext *avr,
+                                   const int *channel_map)
+{
+    ChannelMapInfo *info = &avr->ch_map_info;
+    int in_channels, ch, i;
+
+    in_channels = av_get_channel_layout_nb_channels(avr->in_channel_layout);
+    if (in_channels <= 0 ||  in_channels > AVRESAMPLE_MAX_CHANNELS) {
+        av_log(avr, AV_LOG_ERROR, "Invalid input channel layout\n");
+        return AVERROR(EINVAL);
+    }
+
+    memset(info, 0, sizeof(*info));
+    memset(info->input_map, -1, sizeof(info->input_map));
+
+    for (ch = 0; ch < in_channels; ch++) {
+        if (channel_map[ch] >= in_channels) {
+            av_log(avr, AV_LOG_ERROR, "Invalid channel map\n");
+            return AVERROR(EINVAL);
+        }
+        if (channel_map[ch] < 0) {
+            info->channel_zero[ch] =  1;
+            info->channel_map[ch]  = -1;
+            info->do_zero          =  1;
+        } else if (info->input_map[channel_map[ch]] >= 0) {
+            info->channel_copy[ch] = info->input_map[channel_map[ch]];
+            info->channel_map[ch]  = -1;
+            info->do_copy          =  1;
+        } else {
+            info->channel_map[ch]            = channel_map[ch];
+            info->input_map[channel_map[ch]] = ch;
+            info->do_remap                   =  1;
+        }
+    }
+    /* Fill-in unmapped input channels with unmapped output channels.
+       This is used when remapping during conversion from interleaved to
+       planar format. */
+    for (ch = 0, i = 0; ch < in_channels && i < in_channels; ch++, i++) {
+        while (ch < in_channels && info->input_map[ch] >= 0)
+            ch++;
+        while (i < in_channels && info->channel_map[i] >= 0)
+            i++;
+        if (ch >= in_channels || i >= in_channels)
+            break;
+        info->input_map[ch] = i;
+    }
+
+    avr->use_channel_map = 1;
+    return 0;
+}
+
 int avresample_available(AVAudioResampleContext *avr)
 {
     return av_audio_fifo_size(avr->out_fifo);
diff --git a/libavresample/version.h b/libavresample/version.h
index 53ba802..387d097 100644
--- a/libavresample/version.h
+++ b/libavresample/version.h
@@ -20,7 +20,7 @@
 #define AVRESAMPLE_VERSION_H
 
 #define LIBAVRESAMPLE_VERSION_MAJOR  1
-#define LIBAVRESAMPLE_VERSION_MINOR  0
+#define LIBAVRESAMPLE_VERSION_MINOR  1
 #define LIBAVRESAMPLE_VERSION_MICRO  0
 
 #define LIBAVRESAMPLE_VERSION_INT  AV_VERSION_INT(LIBAVRESAMPLE_VERSION_MAJOR, \
@@ -39,4 +39,8 @@
  * the public API and may change, break or disappear at any time.
  */
 
+#ifndef FF_API_RESAMPLE_CLOSE_OPEN
+#define FF_API_RESAMPLE_CLOSE_OPEN (LIBAVRESAMPLE_VERSION_MAJOR < 2)
+#endif
+
 #endif /* AVRESAMPLE_VERSION_H */
diff --git a/libavresample/x86/Makefile b/libavresample/x86/Makefile
index 65bed89..2e8786f 100644
--- a/libavresample/x86/Makefile
+++ b/libavresample/x86/Makefile
@@ -1,5 +1,7 @@
 OBJS      += x86/audio_convert_init.o                                   \
              x86/audio_mix_init.o                                       \
+             x86/dither_init.o                                          \
 
 YASM-OBJS += x86/audio_convert.o                                        \
              x86/audio_mix.o                                            \
+             x86/dither.o                                               \
diff --git a/libavresample/x86/audio_mix.asm b/libavresample/x86/audio_mix.asm
index a3f1af5..9353593 100644
--- a/libavresample/x86/audio_mix.asm
+++ b/libavresample/x86/audio_mix.asm
@@ -266,29 +266,20 @@
 %else
     %assign matrix_elements_stack 0
 %endif
+%assign matrix_stack_size matrix_elements_stack * mmsize
 
-cglobal mix_%1_to_%2_%3_flt, 3,in_channels+2,needed_mmregs+matrix_elements_mm, src0, src1, len, src2, src3, src4, src5, src6, src7
+%assign needed_stack_size -1 * matrix_stack_size
+%if ARCH_X86_32 && in_channels >= 7
+%assign needed_stack_size needed_stack_size - 16
+%endif
 
-; get aligned stack space if needed
-%if matrix_elements_stack > 0
-    %if mmsize == 32
-    %assign bkpreg %1 + 1
-    %define bkpq r %+ bkpreg %+ q
-    mov           bkpq, rsp
-    and           rsp, ~(mmsize-1)
-    sub           rsp, matrix_elements_stack * mmsize
-    %else
-    %assign matrix_stack_size matrix_elements_stack * mmsize
-    %assign pad matrix_stack_size + (mmsize - gprsize) - (stack_offset & (mmsize - gprsize))
-    ; on x86-32 for 7 and 8 channels we need more stack space for src pointers
-    %if ARCH_X86_32 && in_channels >= 7
-    %assign pad pad + 0x10
+cglobal mix_%1_to_%2_%3_flt, 3,in_channels+2,needed_mmregs+matrix_elements_mm, needed_stack_size, src0, src1, len, src2, src3, src4, src5, src6, src7
+
+; define src pointers on stack if needed
+%if matrix_elements_stack > 0 && ARCH_X86_32 && in_channels >= 7
     %define src5m [rsp+matrix_stack_size+0]
     %define src6m [rsp+matrix_stack_size+4]
     %define src7m [rsp+matrix_stack_size+8]
-    %endif
-    SUB           rsp, pad
-    %endif
 %endif
 
 ; load matrix pointers
@@ -469,14 +460,6 @@
 
     add          lenq, mmsize
     jl .loop
-; restore stack pointer
-%if matrix_elements_stack > 0
-    %if mmsize == 32
-    mov           rsp, bkpq
-    %else
-    ADD           rsp, pad
-    %endif
-%endif
 ; zero ymm high halves
 %if mmsize == 32
     vzeroupper
diff --git a/libavresample/x86/dither.asm b/libavresample/x86/dither.asm
new file mode 100644
index 0000000..757f280
--- /dev/null
+++ b/libavresample/x86/dither.asm
@@ -0,0 +1,117 @@
+;******************************************************************************
+;* x86 optimized dithering format conversion
+;* Copyright (c) 2012 Justin Ruggles <justin.ruggles@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/x86/x86util.asm"
+
+SECTION_RODATA 32
+
+; 1.0f / (2.0f * INT32_MAX)
+pf_dither_scale: times 8 dd 2.32830643762e-10
+
+pf_s16_scale: times 4 dd 32753.0
+
+SECTION_TEXT
+
+;------------------------------------------------------------------------------
+; void ff_quantize(int16_t *dst, float *src, float *dither, int len);
+;------------------------------------------------------------------------------
+
+INIT_XMM sse2
+cglobal quantize, 4,4,3, dst, src, dither, len
+    lea         lenq, [2*lend]
+    add         dstq, lenq
+    lea         srcq, [srcq+2*lenq]
+    lea      ditherq, [ditherq+2*lenq]
+    neg         lenq
+    mova          m2, [pf_s16_scale]
+.loop:
+    mulps         m0, m2, [srcq+2*lenq]
+    mulps         m1, m2, [srcq+2*lenq+mmsize]
+    addps         m0, [ditherq+2*lenq]
+    addps         m1, [ditherq+2*lenq+mmsize]
+    cvtps2dq      m0, m0
+    cvtps2dq      m1, m1
+    packssdw      m0, m1
+    mova     [dstq+lenq], m0
+    add         lenq, mmsize
+    jl .loop
+    REP_RET
+
+;------------------------------------------------------------------------------
+; void ff_dither_int_to_float_rectangular(float *dst, int *src, int len)
+;------------------------------------------------------------------------------
+
+%macro DITHER_INT_TO_FLOAT_RECTANGULAR 0
+cglobal dither_int_to_float_rectangular, 3,3,3, dst, src, len
+    lea         lenq, [4*lend]
+    add         srcq, lenq
+    add         dstq, lenq
+    neg         lenq
+    mova          m0, [pf_dither_scale]
+.loop:
+    cvtdq2ps      m1, [srcq+lenq]
+    cvtdq2ps      m2, [srcq+lenq+mmsize]
+    mulps         m1, m1, m0
+    mulps         m2, m2, m0
+    mova  [dstq+lenq], m1
+    mova  [dstq+lenq+mmsize], m2
+    add         lenq, 2*mmsize
+    jl .loop
+    REP_RET
+%endmacro
+
+INIT_XMM sse2
+DITHER_INT_TO_FLOAT_RECTANGULAR
+INIT_YMM avx
+DITHER_INT_TO_FLOAT_RECTANGULAR
+
+;------------------------------------------------------------------------------
+; void ff_dither_int_to_float_triangular(float *dst, int *src0, int len)
+;------------------------------------------------------------------------------
+
+%macro DITHER_INT_TO_FLOAT_TRIANGULAR 0
+cglobal dither_int_to_float_triangular, 3,4,5, dst, src0, len, src1
+    lea         lenq, [4*lend]
+    lea        src1q, [src0q+2*lenq]
+    add        src0q, lenq
+    add         dstq, lenq
+    neg         lenq
+    mova          m0, [pf_dither_scale]
+.loop:
+    cvtdq2ps      m1, [src0q+lenq]
+    cvtdq2ps      m2, [src0q+lenq+mmsize]
+    cvtdq2ps      m3, [src1q+lenq]
+    cvtdq2ps      m4, [src1q+lenq+mmsize]
+    addps         m1, m1, m3
+    addps         m2, m2, m4
+    mulps         m1, m1, m0
+    mulps         m2, m2, m0
+    mova  [dstq+lenq], m1
+    mova  [dstq+lenq+mmsize], m2
+    add         lenq, 2*mmsize
+    jl .loop
+    REP_RET
+%endmacro
+
+INIT_XMM sse2
+DITHER_INT_TO_FLOAT_TRIANGULAR
+INIT_YMM avx
+DITHER_INT_TO_FLOAT_TRIANGULAR
diff --git a/libavresample/x86/dither_init.c b/libavresample/x86/dither_init.c
new file mode 100644
index 0000000..6532887
--- /dev/null
+++ b/libavresample/x86/dither_init.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2012 Justin Ruggles <justin.ruggles@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 "config.h"
+#include "libavutil/cpu.h"
+#include "libavutil/x86/cpu.h"
+#include "libavresample/dither.h"
+
+extern void ff_quantize_sse2(int16_t *dst, const float *src, float *dither,
+                             int len);
+
+extern void ff_dither_int_to_float_rectangular_sse2(float *dst, int *src, int len);
+extern void ff_dither_int_to_float_rectangular_avx(float *dst, int *src, int len);
+
+extern void ff_dither_int_to_float_triangular_sse2(float *dst, int *src0, int len);
+extern void ff_dither_int_to_float_triangular_avx(float *dst, int *src0, int len);
+
+av_cold void ff_dither_init_x86(DitherDSPContext *ddsp,
+                                enum AVResampleDitherMethod method)
+{
+    int mm_flags = av_get_cpu_flags();
+
+    if (EXTERNAL_SSE2(mm_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)) {
+            ddsp->dither_int_to_float = ff_dither_int_to_float_rectangular_sse2;
+        }
+        if (EXTERNAL_AVX(mm_flags)) {
+            ddsp->dither_int_to_float = ff_dither_int_to_float_rectangular_avx;
+        }
+    } else {
+        if (EXTERNAL_SSE2(mm_flags)) {
+            ddsp->dither_int_to_float = ff_dither_int_to_float_triangular_sse2;
+        }
+        if (EXTERNAL_AVX(mm_flags)) {
+            ddsp->dither_int_to_float = ff_dither_int_to_float_triangular_avx;
+        }
+    }
+}
diff --git a/libavutil/Makefile b/libavutil/Makefile
index 61ddc9a..544c33f 100644
--- a/libavutil/Makefile
+++ b/libavutil/Makefile
@@ -22,6 +22,7 @@
           eval.h                                                        \
           fifo.h                                                        \
           file.h                                                        \
+          hmac.h                                                        \
           imgutils.h                                                    \
           intfloat.h                                                    \
           intfloat_readwrite.h                                          \
@@ -72,6 +73,7 @@
        fifo.o                                                           \
        file.o                                                           \
        float_dsp.o                                                      \
+       hmac.o                                                           \
        imgutils.o                                                       \
        intfloat_readwrite.o                                             \
        intmath.o                                                        \
@@ -117,6 +119,7 @@
             eval                                                        \
             file                                                        \
             fifo                                                        \
+            hmac                                                        \
             lfg                                                         \
             lls                                                         \
             md5                                                         \
diff --git a/libavutil/arm/Makefile b/libavutil/arm/Makefile
index ac7eca6..5da44b0 100644
--- a/libavutil/arm/Makefile
+++ b/libavutil/arm/Makefile
@@ -1,8 +1,8 @@
 OBJS += arm/cpu.o                                                       \
         arm/float_dsp_init_arm.o                                        \
 
-ARMVFP-OBJS += arm/float_dsp_init_vfp.o                                 \
-               arm/float_dsp_vfp.o                                      \
+VFP-OBJS += arm/float_dsp_init_vfp.o                                    \
+            arm/float_dsp_vfp.o                                         \
 
 NEON-OBJS += arm/float_dsp_init_neon.o                                  \
              arm/float_dsp_neon.o                                       \
diff --git a/libavutil/arm/asm.S b/libavutil/arm/asm.S
index bb7c383..6061e47 100644
--- a/libavutil/arm/asm.S
+++ b/libavutil/arm/asm.S
@@ -46,7 +46,7 @@
 
 #if   HAVE_NEON
         .fpu            neon
-#elif HAVE_ARMVFP
+#elif HAVE_VFP
         .fpu            vfp
 #endif
 
@@ -89,7 +89,7 @@
 \name:
 .endm
 
-#if !HAVE_ARMV6T2
+#if !HAVE_ARMV6T2_EXTERNAL
 .macro  movw    rd, val
         mov     \rd, \val &  255
         orr     \rd, \val & ~255
@@ -97,7 +97,7 @@
 #endif
 
 .macro  mov32   rd, val
-#if HAVE_ARMV6T2
+#if HAVE_ARMV6T2_EXTERNAL
         movw            \rd, #(\val) & 0xffff
     .if (\val) >> 16
         movt            \rd, #(\val) >> 16
@@ -146,7 +146,7 @@
 .macro  movrel rd, val
 #if CONFIG_PIC
         ldpic           \rd, \val
-#elif HAVE_ARMV6T2 && !defined(__APPLE__)
+#elif HAVE_ARMV6T2_EXTERNAL && !defined(__APPLE__)
         movw            \rd, #:lower16:\val
         movt            \rd, #:upper16:\val
 #else
diff --git a/libavutil/arm/bswap.h b/libavutil/arm/bswap.h
index c10c35f..ae5fdb7 100644
--- a/libavutil/arm/bswap.h
+++ b/libavutil/arm/bswap.h
@@ -35,7 +35,7 @@
 
 #elif HAVE_INLINE_ASM
 
-#if HAVE_ARMV6
+#if HAVE_ARMV6_INLINE
 #define av_bswap16 av_bswap16
 static av_always_inline av_const unsigned av_bswap16(unsigned x)
 {
@@ -48,7 +48,7 @@
 #define av_bswap32 av_bswap32
 static av_always_inline av_const uint32_t av_bswap32(uint32_t x)
 {
-#if HAVE_ARMV6
+#if HAVE_ARMV6_INLINE
     __asm__("rev %0, %0" : "+r"(x));
 #else
     uint32_t t;
@@ -57,7 +57,7 @@
              "mov %0, %0, ror #8      \n\t"
              "eor %0, %0, %1, lsr #8  \n\t"
              : "+r"(x), "=&r"(t));
-#endif /* HAVE_ARMV6 */
+#endif /* HAVE_ARMV6_INLINE */
     return x;
 }
 #endif /* !AV_GCC_VERSION_AT_LEAST(4,5) */
diff --git a/libavutil/arm/cpu.c b/libavutil/arm/cpu.c
index 33dca1c..b4aabc3 100644
--- a/libavutil/arm/cpu.c
+++ b/libavutil/arm/cpu.c
@@ -19,12 +19,128 @@
 #include "libavutil/cpu.h"
 #include "config.h"
 
+#define CORE_FLAG(f) \
+    (AV_CPU_FLAG_ ## f * (HAVE_ ## f ## _EXTERNAL || HAVE_ ## f ## _INLINE))
+
+#define CORE_CPU_FLAGS                          \
+    (CORE_FLAG(ARMV5TE) |                       \
+     CORE_FLAG(ARMV6)   |                       \
+     CORE_FLAG(ARMV6T2) |                       \
+     CORE_FLAG(VFP)     |                       \
+     CORE_FLAG(VFPV3)   |                       \
+     CORE_FLAG(NEON))
+
+#if defined __linux__ || defined __ANDROID__
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include "libavutil/avstring.h"
+
+#define AT_HWCAP        16
+
+/* Relevant HWCAP values from kernel headers */
+#define HWCAP_VFP       (1 << 6)
+#define HWCAP_EDSP      (1 << 7)
+#define HWCAP_THUMBEE   (1 << 11)
+#define HWCAP_NEON      (1 << 12)
+#define HWCAP_VFPv3     (1 << 13)
+#define HWCAP_TLS       (1 << 15)
+
+static int get_hwcap(uint32_t *hwcap)
+{
+    struct { uint32_t a_type; uint32_t a_val; } auxv;
+    FILE *f = fopen("/proc/self/auxv", "r");
+    int err = -1;
+
+    if (!f)
+        return -1;
+
+    while (fread(&auxv, sizeof(auxv), 1, f) > 0) {
+        if (auxv.a_type == AT_HWCAP) {
+            *hwcap = auxv.a_val;
+            err = 0;
+            break;
+        }
+    }
+
+    fclose(f);
+    return err;
+}
+
+static int get_cpuinfo(uint32_t *hwcap)
+{
+    FILE *f = fopen("/proc/cpuinfo", "r");
+    char buf[200];
+
+    if (!f)
+        return -1;
+
+    *hwcap = 0;
+    while (fgets(buf, sizeof(buf), f)) {
+        if (av_strstart(buf, "Features", NULL)) {
+            if (strstr(buf, " edsp "))
+                *hwcap |= HWCAP_EDSP;
+            if (strstr(buf, " tls "))
+                *hwcap |= HWCAP_TLS;
+            if (strstr(buf, " thumbee "))
+                *hwcap |= HWCAP_THUMBEE;
+            if (strstr(buf, " vfp "))
+                *hwcap |= HWCAP_VFP;
+            if (strstr(buf, " vfpv3 "))
+                *hwcap |= HWCAP_VFPv3;
+            if (strstr(buf, " neon "))
+                *hwcap |= HWCAP_NEON;
+            break;
+        }
+    }
+    fclose(f);
+    return 0;
+}
+
+int ff_get_cpu_flags_arm(void)
+{
+    int flags = CORE_CPU_FLAGS;
+    uint32_t hwcap;
+
+    if (get_hwcap(&hwcap) < 0)
+        if (get_cpuinfo(&hwcap) < 0)
+            return flags;
+
+#define check_cap(cap, flag) do {               \
+        if (hwcap & HWCAP_ ## cap)              \
+            flags |= AV_CPU_FLAG_ ## flag;      \
+    } while (0)
+
+    /* No flags explicitly indicate v6 or v6T2 so check others which
+       imply support. */
+    check_cap(EDSP,    ARMV5TE);
+    check_cap(TLS,     ARMV6);
+    check_cap(THUMBEE, ARMV6T2);
+    check_cap(VFP,     VFP);
+    check_cap(VFPv3,   VFPV3);
+    check_cap(NEON,    NEON);
+
+    /* The v6 checks above are not reliable so let higher flags
+       trickle down. */
+    if (flags & (AV_CPU_FLAG_VFPV3 | AV_CPU_FLAG_NEON))
+        flags |= AV_CPU_FLAG_ARMV6T2;
+    if (flags & AV_CPU_FLAG_ARMV6T2)
+        flags |= AV_CPU_FLAG_ARMV6;
+
+    return flags;
+}
+
+#else
+
 int ff_get_cpu_flags_arm(void)
 {
     return AV_CPU_FLAG_ARMV5TE * HAVE_ARMV5TE |
            AV_CPU_FLAG_ARMV6   * HAVE_ARMV6   |
            AV_CPU_FLAG_ARMV6T2 * HAVE_ARMV6T2 |
-           AV_CPU_FLAG_VFP     * HAVE_ARMVFP  |
+           AV_CPU_FLAG_VFP     * HAVE_VFP     |
            AV_CPU_FLAG_VFPV3   * HAVE_VFPV3   |
            AV_CPU_FLAG_NEON    * HAVE_NEON;
 }
+
+#endif
diff --git a/libavutil/arm/cpu.h b/libavutil/arm/cpu.h
index 72e16d4..91c959a 100644
--- a/libavutil/arm/cpu.h
+++ b/libavutil/arm/cpu.h
@@ -25,7 +25,7 @@
 #define have_armv5te(flags) (HAVE_ARMV5TE && ((flags) & AV_CPU_FLAG_ARMV5TE))
 #define have_armv6(flags)   (HAVE_ARMV6   && ((flags) & AV_CPU_FLAG_ARMV6))
 #define have_armv6t2(flags) (HAVE_ARMV6T2 && ((flags) & AV_CPU_FLAG_ARMV6T2))
-#define have_vfp(flags)     (HAVE_ARMVFP  && ((flags) & AV_CPU_FLAG_VFP))
+#define have_vfp(flags)     (HAVE_VFP     && ((flags) & AV_CPU_FLAG_VFP))
 #define have_vfpv3(flags)   (HAVE_VFPV3   && ((flags) & AV_CPU_FLAG_VFPV3))
 #define have_neon(flags)    (HAVE_NEON    && ((flags) & AV_CPU_FLAG_NEON))
 
diff --git a/libavutil/arm/float_dsp_init_neon.c b/libavutil/arm/float_dsp_init_neon.c
index 88eb4b3..a7245ad9 100644
--- a/libavutil/arm/float_dsp_init_neon.c
+++ b/libavutil/arm/float_dsp_init_neon.c
@@ -32,9 +32,27 @@
 void ff_vector_fmul_scalar_neon(float *dst, const float *src, float mul,
                                 int len);
 
+void ff_vector_fmul_window_neon(float *dst, const float *src0,
+                                const float *src1, const float *win, int len);
+
+void ff_vector_fmul_add_neon(float *dst, const float *src0, const float *src1,
+                             const float *src2, int len);
+
+void ff_vector_fmul_reverse_neon(float *dst, const float *src0,
+                                 const float *src1, int len);
+
+void ff_butterflies_float_neon(float *v1, float *v2, int len);
+
+float ff_scalarproduct_float_neon(const float *v1, const float *v2, int len);
+
 void ff_float_dsp_init_neon(AVFloatDSPContext *fdsp)
 {
     fdsp->vector_fmul = ff_vector_fmul_neon;
     fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_neon;
     fdsp->vector_fmul_scalar = ff_vector_fmul_scalar_neon;
+    fdsp->vector_fmul_window = ff_vector_fmul_window_neon;
+    fdsp->vector_fmul_add    = ff_vector_fmul_add_neon;
+    fdsp->vector_fmul_reverse = ff_vector_fmul_reverse_neon;
+    fdsp->butterflies_float = ff_butterflies_float_neon;
+    fdsp->scalarproduct_float = ff_scalarproduct_float_neon;
 }
diff --git a/libavutil/arm/float_dsp_init_vfp.c b/libavutil/arm/float_dsp_init_vfp.c
index 7abc332..f7e2f54 100644
--- a/libavutil/arm/float_dsp_init_vfp.c
+++ b/libavutil/arm/float_dsp_init_vfp.c
@@ -25,10 +25,14 @@
 void ff_vector_fmul_vfp(float *dst, const float *src0, const float *src1,
                         int len);
 
+void ff_vector_fmul_reverse_vfp(float *dst, const float *src0,
+                                const float *src1, int len);
+
 void ff_float_dsp_init_vfp(AVFloatDSPContext *fdsp)
 {
     int cpu_flags = av_get_cpu_flags();
 
     if (!have_vfpv3(cpu_flags))
         fdsp->vector_fmul = ff_vector_fmul_vfp;
+    fdsp->vector_fmul_reverse = ff_vector_fmul_reverse_vfp;
 }
diff --git a/libavutil/arm/float_dsp_neon.S b/libavutil/arm/float_dsp_neon.S
index 6d7bd52..559b565 100644
--- a/libavutil/arm/float_dsp_neon.S
+++ b/libavutil/arm/float_dsp_neon.S
@@ -146,3 +146,126 @@
         bx              lr
         .unreq          len
 endfunc
+
+function ff_vector_fmul_window_neon, export=1
+        push            {r4,r5,lr}
+        ldr             lr,  [sp, #12]
+        sub             r2,  r2,  #8
+        sub             r5,  lr,  #2
+        add             r2,  r2,  r5, lsl #2
+        add             r4,  r3,  r5, lsl #3
+        add             ip,  r0,  r5, lsl #3
+        mov             r5,  #-16
+        vld1.32         {d0,d1},  [r1,:128]!
+        vld1.32         {d2,d3},  [r2,:128], r5
+        vld1.32         {d4,d5},  [r3,:128]!
+        vld1.32         {d6,d7},  [r4,:128], r5
+1:      subs            lr,  lr,  #4
+        vmul.f32        d22, d0,  d4
+        vrev64.32       q3,  q3
+        vmul.f32        d23, d1,  d5
+        vrev64.32       q1,  q1
+        vmul.f32        d20, d0,  d7
+        vmul.f32        d21, d1,  d6
+        beq             2f
+        vmla.f32        d22, d3,  d7
+        vld1.32         {d0,d1},  [r1,:128]!
+        vmla.f32        d23, d2,  d6
+        vld1.32         {d18,d19},[r2,:128], r5
+        vmls.f32        d20, d3,  d4
+        vld1.32         {d24,d25},[r3,:128]!
+        vmls.f32        d21, d2,  d5
+        vld1.32         {d6,d7},  [r4,:128], r5
+        vmov            q1,  q9
+        vrev64.32       q11, q11
+        vmov            q2,  q12
+        vswp            d22, d23
+        vst1.32         {d20,d21},[r0,:128]!
+        vst1.32         {d22,d23},[ip,:128], r5
+        b               1b
+2:      vmla.f32        d22, d3,  d7
+        vmla.f32        d23, d2,  d6
+        vmls.f32        d20, d3,  d4
+        vmls.f32        d21, d2,  d5
+        vrev64.32       q11, q11
+        vswp            d22, d23
+        vst1.32         {d20,d21},[r0,:128]!
+        vst1.32         {d22,d23},[ip,:128], r5
+        pop             {r4,r5,pc}
+endfunc
+
+function ff_vector_fmul_add_neon, export=1
+        ldr             r12, [sp]
+        vld1.32         {q0-q1},  [r1,:128]!
+        vld1.32         {q8-q9},  [r2,:128]!
+        vld1.32         {q2-q3},  [r3,:128]!
+        vmul.f32        q10, q0,  q8
+        vmul.f32        q11, q1,  q9
+1:      vadd.f32        q12, q2,  q10
+        vadd.f32        q13, q3,  q11
+        pld             [r1, #16]
+        pld             [r2, #16]
+        pld             [r3, #16]
+        subs            r12, r12, #8
+        beq             2f
+        vld1.32         {q0},     [r1,:128]!
+        vld1.32         {q8},     [r2,:128]!
+        vmul.f32        q10, q0,  q8
+        vld1.32         {q1},     [r1,:128]!
+        vld1.32         {q9},     [r2,:128]!
+        vmul.f32        q11, q1,  q9
+        vld1.32         {q2-q3},  [r3,:128]!
+        vst1.32         {q12-q13},[r0,:128]!
+        b               1b
+2:      vst1.32         {q12-q13},[r0,:128]!
+        bx              lr
+endfunc
+
+function ff_vector_fmul_reverse_neon, export=1
+        add             r2,  r2,  r3,  lsl #2
+        sub             r2,  r2,  #32
+        mov             r12, #-32
+        vld1.32         {q0-q1},  [r1,:128]!
+        vld1.32         {q2-q3},  [r2,:128], r12
+1:      pld             [r1, #32]
+        vrev64.32       q3,  q3
+        vmul.f32        d16, d0,  d7
+        vmul.f32        d17, d1,  d6
+        pld             [r2, #-32]
+        vrev64.32       q2,  q2
+        vmul.f32        d18, d2,  d5
+        vmul.f32        d19, d3,  d4
+        subs            r3,  r3,  #8
+        beq             2f
+        vld1.32         {q0-q1},  [r1,:128]!
+        vld1.32         {q2-q3},  [r2,:128], r12
+        vst1.32         {q8-q9},  [r0,:128]!
+        b               1b
+2:      vst1.32         {q8-q9},  [r0,:128]!
+        bx              lr
+endfunc
+
+function ff_butterflies_float_neon, export=1
+1:      vld1.32         {q0},[r0,:128]
+        vld1.32         {q1},[r1,:128]
+        vsub.f32        q2,  q0,  q1
+        vadd.f32        q1,  q0,  q1
+        vst1.32         {q2},[r1,:128]!
+        vst1.32         {q1},[r0,:128]!
+        subs            r2,  r2,  #4
+        bgt             1b
+        bx              lr
+endfunc
+
+function ff_scalarproduct_float_neon, export=1
+        vmov.f32        q2,  #0.0
+1:      vld1.32         {q0},[r0,:128]!
+        vld1.32         {q1},[r1,:128]!
+        vmla.f32        q2,  q0,  q1
+        subs            r2,  r2,  #4
+        bgt             1b
+        vadd.f32        d0,  d4,  d5
+        vpadd.f32       d0,  d0,  d0
+NOVFP   vmov.32         r0,  d0[0]
+        bx              lr
+endfunc
diff --git a/libavutil/arm/float_dsp_vfp.S b/libavutil/arm/float_dsp_vfp.S
index db63e5a6..8695fbd 100644
--- a/libavutil/arm/float_dsp_vfp.S
+++ b/libavutil/arm/float_dsp_vfp.S
@@ -66,3 +66,72 @@
         vpop            {d8-d15}
         bx              lr
 endfunc
+
+/**
+ * ARM VFP optimized implementation of 'vector_fmul_reverse_c' function.
+ * Assume that len is a positive number and is multiple of 8
+ */
+@ void ff_vector_fmul_reverse_vfp(float *dst, const float *src0,
+@                                 const float *src1, int len)
+function ff_vector_fmul_reverse_vfp, export=1
+        vpush           {d8-d15}
+        add             r2,  r2,  r3, lsl #2
+        vldmdb          r2!, {s0-s3}
+        vldmia          r1!, {s8-s11}
+        vldmdb          r2!, {s4-s7}
+        vldmia          r1!, {s12-s15}
+        vmul.f32        s8,  s3,  s8
+        vmul.f32        s9,  s2,  s9
+        vmul.f32        s10, s1,  s10
+        vmul.f32        s11, s0,  s11
+1:
+        subs            r3,  r3,  #16
+        it              ge
+        vldmdbge        r2!, {s16-s19}
+        vmul.f32        s12, s7,  s12
+        it              ge
+        vldmiage        r1!, {s24-s27}
+        vmul.f32        s13, s6,  s13
+        it              ge
+        vldmdbge        r2!, {s20-s23}
+        vmul.f32        s14, s5,  s14
+        it              ge
+        vldmiage        r1!, {s28-s31}
+        vmul.f32        s15, s4,  s15
+        it              ge
+        vmulge.f32      s24, s19, s24
+        it              gt
+        vldmdbgt        r2!, {s0-s3}
+        it              ge
+        vmulge.f32      s25, s18, s25
+        vstmia          r0!, {s8-s13}
+        it              ge
+        vmulge.f32      s26, s17, s26
+        it              gt
+        vldmiagt        r1!, {s8-s11}
+        itt             ge
+        vmulge.f32      s27, s16, s27
+        vmulge.f32      s28, s23, s28
+        it              gt
+        vldmdbgt        r2!, {s4-s7}
+        it              ge
+        vmulge.f32      s29, s22, s29
+        vstmia          r0!, {s14-s15}
+        ittt            ge
+        vmulge.f32      s30, s21, s30
+        vmulge.f32      s31, s20, s31
+        vmulge.f32      s8,  s3,  s8
+        it              gt
+        vldmiagt        r1!, {s12-s15}
+        itttt           ge
+        vmulge.f32      s9,  s2,  s9
+        vmulge.f32      s10, s1,  s10
+        vstmiage        r0!, {s24-s27}
+        vmulge.f32      s11, s0,  s11
+        it              ge
+        vstmiage        r0!, {s28-s31}
+        bgt             1b
+
+        vpop            {d8-d15}
+        bx              lr
+endfunc
diff --git a/libavutil/arm/intmath.h b/libavutil/arm/intmath.h
index 0980a6f..fd52648 100644
--- a/libavutil/arm/intmath.h
+++ b/libavutil/arm/intmath.h
@@ -28,7 +28,7 @@
 
 #if HAVE_INLINE_ASM
 
-#if HAVE_ARMV6
+#if HAVE_ARMV6_INLINE
 
 #define av_clip_uint8 av_clip_uint8_arm
 static av_always_inline av_const unsigned av_clip_uint8_arm(int a)
@@ -86,7 +86,7 @@
     return r;
 }
 
-#endif /* HAVE_ARMV6 */
+#endif /* HAVE_ARMV6_INLINE */
 
 #if HAVE_ASM_MOD_Q
 
diff --git a/libavutil/avassert.h b/libavutil/avassert.h
index e100d0b..41f5e0e 100644
--- a/libavutil/avassert.h
+++ b/libavutil/avassert.h
@@ -36,7 +36,7 @@
  */
 #define av_assert0(cond) do {                                           \
     if (!(cond)) {                                                      \
-        av_log(NULL, AV_LOG_FATAL, "Assertion %s failed at %s:%d\n",    \
+        av_log(NULL, AV_LOG_PANIC, "Assertion %s failed at %s:%d\n",    \
                AV_STRINGIFY(cond), __FILE__, __LINE__);                 \
         abort();                                                        \
     }                                                                   \
diff --git a/libavutil/avstring.c b/libavutil/avstring.c
index 802d0f8..e2422c0 100644
--- a/libavutil/avstring.c
+++ b/libavutil/avstring.c
@@ -24,8 +24,11 @@
 #include <stdio.h>
 #include <string.h>
 #include <ctype.h>
-#include "avstring.h"
+
+#include "config.h"
+#include "common.h"
 #include "mem.h"
+#include "avstring.h"
 
 int av_strstart(const char *str, const char *pfx, const char **ptr)
 {
@@ -54,14 +57,28 @@
     if (!*s2)
         return (char*)(intptr_t)s1;
 
-    do {
+    do
         if (av_stristart(s1, s2, NULL))
             return (char*)(intptr_t)s1;
-    } while (*s1++);
+    while (*s1++);
 
     return NULL;
 }
 
+char *av_strnstr(const char *haystack, const char *needle, size_t hay_length)
+{
+    size_t needle_len = strlen(needle);
+    if (!needle_len)
+        return (char*)haystack;
+    while (hay_length >= needle_len) {
+        hay_length--;
+        if (!memcmp(haystack, needle, needle_len))
+            return (char*)haystack;
+        haystack++;
+    }
+    return NULL;
+}
+
 size_t av_strlcpy(char *dst, const char *src, size_t size)
 {
     size_t len = 0;
@@ -120,8 +137,9 @@
 
 char *av_d2str(double d)
 {
-    char *str= av_malloc(16);
-    if(str) snprintf(str, 16, "%f", d);
+    char *str = av_malloc(16);
+    if (str)
+        snprintf(str, 16, "%f", d);
     return str;
 }
 
@@ -129,32 +147,33 @@
 
 char *av_get_token(const char **buf, const char *term)
 {
-    char *out = av_malloc(strlen(*buf) + 1);
-    char *ret= out, *end= out;
+    char *out     = av_malloc(strlen(*buf) + 1);
+    char *ret     = out, *end = out;
     const char *p = *buf;
-    if (!out) return NULL;
+    if (!out)
+        return NULL;
     p += strspn(p, WHITESPACES);
 
-    while(*p && !strspn(p, term)) {
+    while (*p && !strspn(p, term)) {
         char c = *p++;
-        if(c == '\\' && *p){
+        if (c == '\\' && *p) {
             *out++ = *p++;
-            end= out;
-        }else if(c == '\''){
-            while(*p && *p != '\'')
+            end    = out;
+        } else if (c == '\'') {
+            while (*p && *p != '\'')
                 *out++ = *p++;
-            if(*p){
+            if (*p) {
                 p++;
-                end= out;
+                end = out;
             }
-        }else{
+        } else {
             *out++ = c;
         }
     }
 
-    do{
+    do
         *out-- = 0;
-    }while(out >= end && strspn(out, WHITESPACES));
+    while (out >= end && strspn(out, WHITESPACES));
 
     *buf = p;
 
@@ -211,55 +230,87 @@
     return c1 - c2;
 }
 
-#ifdef TEST
+const char *av_basename(const char *path)
+{
+    char *p = strrchr(path, '/');
 
-#include "common.h"
-#undef printf
+#if HAVE_DOS_PATHS
+    char *q = strrchr(path, '\\');
+    char *d = strchr(path, ':');
+
+    p = FFMAX3(p, q, d);
+#endif
+
+    if (!p)
+        return path;
+
+    return p + 1;
+}
+
+const char *av_dirname(char *path)
+{
+    char *p = strrchr(path, '/');
+
+#if HAVE_DOS_PATHS
+    char *q = strrchr(path, '\\');
+    char *d = strchr(path, ':');
+
+    d = d ? d + 1 : d;
+
+    p = FFMAX3(p, q, d);
+#endif
+
+    if (!p)
+        return ".";
+
+    *p = '\0';
+
+    return path;
+}
+
+#ifdef TEST
 
 int main(void)
 {
     int i;
+    const char *strings[] = {
+        "''",
+        "",
+        ":",
+        "\\",
+        "'",
+        "    ''    :",
+        "    ''  ''  :",
+        "foo   '' :",
+        "'foo'",
+        "foo     ",
+        "  '  foo  '  ",
+        "foo\\",
+        "foo':  blah:blah",
+        "foo\\:  blah:blah",
+        "foo\'",
+        "'foo :  '  :blahblah",
+        "\\ :blah",
+        "     foo",
+        "      foo       ",
+        "      foo     \\ ",
+        "foo ':blah",
+        " foo   bar    :   blahblah",
+        "\\f\\o\\o",
+        "'foo : \\ \\  '   : blahblah",
+        "'\\fo\\o:': blahblah",
+        "\\'fo\\o\\:':  foo  '  :blahblah"
+    };
 
     printf("Testing av_get_token()\n");
-    {
-        const char *strings[] = {
-            "''",
-            "",
-            ":",
-            "\\",
-            "'",
-            "    ''    :",
-            "    ''  ''  :",
-            "foo   '' :",
-            "'foo'",
-            "foo     ",
-            "  '  foo  '  ",
-            "foo\\",
-            "foo':  blah:blah",
-            "foo\\:  blah:blah",
-            "foo\'",
-            "'foo :  '  :blahblah",
-            "\\ :blah",
-            "     foo",
-            "      foo       ",
-            "      foo     \\ ",
-            "foo ':blah",
-            " foo   bar    :   blahblah",
-            "\\f\\o\\o",
-            "'foo : \\ \\  '   : blahblah",
-            "'\\fo\\o:': blahblah",
-            "\\'fo\\o\\:':  foo  '  :blahblah"
-        };
-
-        for (i=0; i < FF_ARRAY_ELEMS(strings); i++) {
-            const char *p = strings[i];
-            char *q;
-            printf("|%s|", p);
-            q = av_get_token(&p, ":");
-            printf(" -> |%s|", q);
-            printf(" + |%s|\n", p);
-            av_free(q);
-        }
+    for (i = 0; i < FF_ARRAY_ELEMS(strings); i++) {
+        const char *p = strings[i];
+        char *q;
+        printf("|%s|", p);
+        q = av_get_token(&p, ":");
+        printf(" -> |%s|", q);
+        printf(" + |%s|\n", p);
+        av_free(q);
     }
 
     return 0;
diff --git a/libavutil/avstring.h b/libavutil/avstring.h
index f73d6e7..b08d78e 100644
--- a/libavutil/avstring.h
+++ b/libavutil/avstring.h
@@ -67,6 +67,21 @@
 char *av_stristr(const char *haystack, const char *needle);
 
 /**
+ * Locate the first occurrence of the string needle in the string haystack
+ * where not more than hay_length characters are searched. A zero-length
+ * string needle is considered to match at the start of haystack.
+ *
+ * This function is a length-limited version of the standard strstr().
+ *
+ * @param haystack   string to search in
+ * @param needle     string to search for
+ * @param hay_length length of string to search in
+ * @return           pointer to the located match within haystack
+ *                   or a null pointer if no match
+ */
+char *av_strnstr(const char *haystack, const char *needle, size_t hay_length);
+
+/**
  * Copy the string src to dst, but no more than size - 1 bytes, and
  * null-terminate dst.
  *
@@ -202,6 +217,22 @@
  */
 int av_strncasecmp(const char *a, const char *b, size_t n);
 
+
+/**
+ * Thread safe basename.
+ * @param path the path, on DOS both \ and / are considered separators.
+ * @return pointer to the basename substring.
+ */
+const char *av_basename(const char *path);
+
+/**
+ * Thread safe dirname.
+ * @param path the path, on DOS both \ and / are considered separators.
+ * @return the path with the separator replaced by the string terminator or ".".
+ * @note the function may change the input string.
+ */
+const char *av_dirname(char *path);
+
 /**
  * @}
  */
diff --git a/libavutil/avutil.h b/libavutil/avutil.h
index 8f63e3b..78deff1 100644
--- a/libavutil/avutil.h
+++ b/libavutil/avutil.h
@@ -35,13 +35,13 @@
  * provided by FFmpeg.
  *
  * @li @ref libavc "libavcodec" encoding/decoding library
- * @li @subpage 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 libswresample "libswresample" audio resampling, format conversion and mixing
- * @li @subpage libpostproc post processing library
- * @li @subpage libswscale  color conversion and scaling 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
  */
 
 /**
diff --git a/libavutil/base64.c b/libavutil/base64.c
index d907805..87e2dfd 100644
--- a/libavutil/base64.c
+++ b/libavutil/base64.c
@@ -125,7 +125,7 @@
     *dst++ = v >> 4;
 out1:
 out0:
-    return bits & 1 ? -1 : dst - out;
+    return bits & 1 ? AVERROR_INVALIDDATA : dst - out;
 }
 
 /*****************************************************************************
@@ -175,8 +175,6 @@
 #ifdef TEST
 // LCOV_EXCL_START
 
-#undef printf
-
 #define MAX_DATA_SIZE    1024
 #define MAX_ENCODED_SIZE 2048
 
diff --git a/libavutil/base64.h b/libavutil/base64.h
index b095576..514498e 100644
--- a/libavutil/base64.h
+++ b/libavutil/base64.h
@@ -46,15 +46,17 @@
  * Encode data to base64 and null-terminate.
  *
  * @param out      buffer for encoded data
- * @param out_size size in bytes of the output buffer, must be at
- *                 least AV_BASE64_SIZE(in_size)
- * @param in_size  size in bytes of the 'in' buffer
- * @return         'out' or NULL in case of error
+ * @param out_size size in bytes of the out buffer (including the
+ *                 null terminator), must be at least AV_BASE64_SIZE(in_size)
+ * @param in       input buffer containing the data to encode
+ * @param in_size  size in bytes of the in buffer
+ * @return         out or NULL in case of error
  */
 char *av_base64_encode(char *out, int out_size, const uint8_t *in, int in_size);
 
 /**
- * Calculate the output size needed to base64-encode x bytes.
+ * Calculate the output size needed to base64-encode x bytes to a
+ * null-terminated string.
  */
 #define AV_BASE64_SIZE(x)  (((x)+2) / 3 * 4 + 1)
 
diff --git a/libavutil/blowfish.c b/libavutil/blowfish.c
index cdc2952..5ad74c1 100644
--- a/libavutil/blowfish.c
+++ b/libavutil/blowfish.c
@@ -420,7 +420,6 @@
 
 #ifdef TEST
 #include <stdio.h>
-#undef printf
 
 #define NUM_VARIABLE_KEY_TESTS 34
 
@@ -523,7 +522,6 @@
 
 #define IV "blowfish"
 
-#undef exit
 static void test_blowfish(AVBlowfish *ctx, uint8_t *dst, const uint8_t *src,
                           const uint8_t *ref, int len, uint8_t *iv, int dir,
                           const char *test)
diff --git a/libavutil/channel_layout.c b/libavutil/channel_layout.c
index ef6bad7..e582760 100644
--- a/libavutil/channel_layout.c
+++ b/libavutil/channel_layout.c
@@ -97,7 +97,8 @@
     { "7.0",         7,  AV_CH_LAYOUT_7POINT0 },
     { "7.0(front)",  7,  AV_CH_LAYOUT_7POINT0_FRONT },
     { "7.1",         8,  AV_CH_LAYOUT_7POINT1 },
-    { "7.1(wide)",   8,  AV_CH_LAYOUT_7POINT1_WIDE },
+    { "7.1(wide)",   8,  AV_CH_LAYOUT_7POINT1_WIDE_BACK },
+    { "7.1(wide-side)",   8,  AV_CH_LAYOUT_7POINT1_WIDE },
     { "octagonal",   8,  AV_CH_LAYOUT_OCTAGONAL },
     { "downmix",     2,  AV_CH_LAYOUT_STEREO_DOWNMIX, },
 };
diff --git a/libavutil/common.h b/libavutil/common.h
index 0f36309..778c757 100644
--- a/libavutil/common.h
+++ b/libavutil/common.h
@@ -97,6 +97,9 @@
  */
 static av_always_inline av_const int av_clip_c(int a, int amin, int amax)
 {
+#if defined(HAVE_AV_CONFIG_H) && defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2
+    if (amin > amax) abort();
+#endif
     if      (a < amin) return amin;
     else if (a > amax) return amax;
     else               return a;
@@ -111,6 +114,9 @@
  */
 static av_always_inline av_const int64_t av_clip64_c(int64_t a, int64_t amin, int64_t amax)
 {
+#if defined(HAVE_AV_CONFIG_H) && defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2
+    if (amin > amax) abort();
+#endif
     if      (a < amin) return amin;
     else if (a > amax) return amax;
     else               return a;
@@ -216,6 +222,9 @@
  */
 static av_always_inline av_const float av_clipf_c(float a, float amin, float amax)
 {
+#if defined(HAVE_AV_CONFIG_H) && defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2
+    if (amin > amax) abort();
+#endif
     if      (a < amin) return amin;
     else if (a > amax) return amax;
     else               return a;
diff --git a/libavutil/cpu.c b/libavutil/cpu.c
index e14b413..a1d1547 100644
--- a/libavutil/cpu.c
+++ b/libavutil/cpu.c
@@ -175,7 +175,6 @@
 }
 #ifdef TEST
 
-#undef printf
 #include <stdio.h>
 
 static const struct {
diff --git a/libavutil/crc.c b/libavutil/crc.c
index bba8cb1..9ee5efe 100644
--- a/libavutil/crc.c
+++ b/libavutil/crc.c
@@ -24,7 +24,192 @@
 #include "crc.h"
 
 #if CONFIG_HARDCODED_TABLES
-#include "crc_data.h"
+static const AVCRC av_crc_table[AV_CRC_MAX][257] = {
+    [AV_CRC_8_ATM] = {
+        0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15, 0x38, 0x3F, 0x36, 0x31,
+        0x24, 0x23, 0x2A, 0x2D, 0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65,
+        0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D, 0xE0, 0xE7, 0xEE, 0xE9,
+        0xFC, 0xFB, 0xF2, 0xF5, 0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD,
+        0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85, 0xA8, 0xAF, 0xA6, 0xA1,
+        0xB4, 0xB3, 0xBA, 0xBD, 0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2,
+        0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA, 0xB7, 0xB0, 0xB9, 0xBE,
+        0xAB, 0xAC, 0xA5, 0xA2, 0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A,
+        0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32, 0x1F, 0x18, 0x11, 0x16,
+        0x03, 0x04, 0x0D, 0x0A, 0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42,
+        0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A, 0x89, 0x8E, 0x87, 0x80,
+        0x95, 0x92, 0x9B, 0x9C, 0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4,
+        0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC, 0xC1, 0xC6, 0xCF, 0xC8,
+        0xDD, 0xDA, 0xD3, 0xD4, 0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C,
+        0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44, 0x19, 0x1E, 0x17, 0x10,
+        0x05, 0x02, 0x0B, 0x0C, 0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34,
+        0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B, 0x76, 0x71, 0x78, 0x7F,
+        0x6A, 0x6D, 0x64, 0x63, 0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B,
+        0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13, 0xAE, 0xA9, 0xA0, 0xA7,
+        0xB2, 0xB5, 0xBC, 0xBB, 0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83,
+        0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB, 0xE6, 0xE1, 0xE8, 0xEF,
+        0xFA, 0xFD, 0xF4, 0xF3, 0x01
+    },
+    [AV_CRC_16_ANSI] = {
+        0x0000, 0x0580, 0x0F80, 0x0A00, 0x1B80, 0x1E00, 0x1400, 0x1180,
+        0x3380, 0x3600, 0x3C00, 0x3980, 0x2800, 0x2D80, 0x2780, 0x2200,
+        0x6380, 0x6600, 0x6C00, 0x6980, 0x7800, 0x7D80, 0x7780, 0x7200,
+        0x5000, 0x5580, 0x5F80, 0x5A00, 0x4B80, 0x4E00, 0x4400, 0x4180,
+        0xC380, 0xC600, 0xCC00, 0xC980, 0xD800, 0xDD80, 0xD780, 0xD200,
+        0xF000, 0xF580, 0xFF80, 0xFA00, 0xEB80, 0xEE00, 0xE400, 0xE180,
+        0xA000, 0xA580, 0xAF80, 0xAA00, 0xBB80, 0xBE00, 0xB400, 0xB180,
+        0x9380, 0x9600, 0x9C00, 0x9980, 0x8800, 0x8D80, 0x8780, 0x8200,
+        0x8381, 0x8601, 0x8C01, 0x8981, 0x9801, 0x9D81, 0x9781, 0x9201,
+        0xB001, 0xB581, 0xBF81, 0xBA01, 0xAB81, 0xAE01, 0xA401, 0xA181,
+        0xE001, 0xE581, 0xEF81, 0xEA01, 0xFB81, 0xFE01, 0xF401, 0xF181,
+        0xD381, 0xD601, 0xDC01, 0xD981, 0xC801, 0xCD81, 0xC781, 0xC201,
+        0x4001, 0x4581, 0x4F81, 0x4A01, 0x5B81, 0x5E01, 0x5401, 0x5181,
+        0x7381, 0x7601, 0x7C01, 0x7981, 0x6801, 0x6D81, 0x6781, 0x6201,
+        0x2381, 0x2601, 0x2C01, 0x2981, 0x3801, 0x3D81, 0x3781, 0x3201,
+        0x1001, 0x1581, 0x1F81, 0x1A01, 0x0B81, 0x0E01, 0x0401, 0x0181,
+        0x0383, 0x0603, 0x0C03, 0x0983, 0x1803, 0x1D83, 0x1783, 0x1203,
+        0x3003, 0x3583, 0x3F83, 0x3A03, 0x2B83, 0x2E03, 0x2403, 0x2183,
+        0x6003, 0x6583, 0x6F83, 0x6A03, 0x7B83, 0x7E03, 0x7403, 0x7183,
+        0x5383, 0x5603, 0x5C03, 0x5983, 0x4803, 0x4D83, 0x4783, 0x4203,
+        0xC003, 0xC583, 0xCF83, 0xCA03, 0xDB83, 0xDE03, 0xD403, 0xD183,
+        0xF383, 0xF603, 0xFC03, 0xF983, 0xE803, 0xED83, 0xE783, 0xE203,
+        0xA383, 0xA603, 0xAC03, 0xA983, 0xB803, 0xBD83, 0xB783, 0xB203,
+        0x9003, 0x9583, 0x9F83, 0x9A03, 0x8B83, 0x8E03, 0x8403, 0x8183,
+        0x8002, 0x8582, 0x8F82, 0x8A02, 0x9B82, 0x9E02, 0x9402, 0x9182,
+        0xB382, 0xB602, 0xBC02, 0xB982, 0xA802, 0xAD82, 0xA782, 0xA202,
+        0xE382, 0xE602, 0xEC02, 0xE982, 0xF802, 0xFD82, 0xF782, 0xF202,
+        0xD002, 0xD582, 0xDF82, 0xDA02, 0xCB82, 0xCE02, 0xC402, 0xC182,
+        0x4382, 0x4602, 0x4C02, 0x4982, 0x5802, 0x5D82, 0x5782, 0x5202,
+        0x7002, 0x7582, 0x7F82, 0x7A02, 0x6B82, 0x6E02, 0x6402, 0x6182,
+        0x2002, 0x2582, 0x2F82, 0x2A02, 0x3B82, 0x3E02, 0x3402, 0x3182,
+        0x1382, 0x1602, 0x1C02, 0x1982, 0x0802, 0x0D82, 0x0782, 0x0202,
+        0x0001
+    },
+    [AV_CRC_16_CCITT] = {
+        0x0000, 0x2110, 0x4220, 0x6330, 0x8440, 0xA550, 0xC660, 0xE770,
+        0x0881, 0x2991, 0x4AA1, 0x6BB1, 0x8CC1, 0xADD1, 0xCEE1, 0xEFF1,
+        0x3112, 0x1002, 0x7332, 0x5222, 0xB552, 0x9442, 0xF772, 0xD662,
+        0x3993, 0x1883, 0x7BB3, 0x5AA3, 0xBDD3, 0x9CC3, 0xFFF3, 0xDEE3,
+        0x6224, 0x4334, 0x2004, 0x0114, 0xE664, 0xC774, 0xA444, 0x8554,
+        0x6AA5, 0x4BB5, 0x2885, 0x0995, 0xEEE5, 0xCFF5, 0xACC5, 0x8DD5,
+        0x5336, 0x7226, 0x1116, 0x3006, 0xD776, 0xF666, 0x9556, 0xB446,
+        0x5BB7, 0x7AA7, 0x1997, 0x3887, 0xDFF7, 0xFEE7, 0x9DD7, 0xBCC7,
+        0xC448, 0xE558, 0x8668, 0xA778, 0x4008, 0x6118, 0x0228, 0x2338,
+        0xCCC9, 0xEDD9, 0x8EE9, 0xAFF9, 0x4889, 0x6999, 0x0AA9, 0x2BB9,
+        0xF55A, 0xD44A, 0xB77A, 0x966A, 0x711A, 0x500A, 0x333A, 0x122A,
+        0xFDDB, 0xDCCB, 0xBFFB, 0x9EEB, 0x799B, 0x588B, 0x3BBB, 0x1AAB,
+        0xA66C, 0x877C, 0xE44C, 0xC55C, 0x222C, 0x033C, 0x600C, 0x411C,
+        0xAEED, 0x8FFD, 0xECCD, 0xCDDD, 0x2AAD, 0x0BBD, 0x688D, 0x499D,
+        0x977E, 0xB66E, 0xD55E, 0xF44E, 0x133E, 0x322E, 0x511E, 0x700E,
+        0x9FFF, 0xBEEF, 0xDDDF, 0xFCCF, 0x1BBF, 0x3AAF, 0x599F, 0x788F,
+        0x8891, 0xA981, 0xCAB1, 0xEBA1, 0x0CD1, 0x2DC1, 0x4EF1, 0x6FE1,
+        0x8010, 0xA100, 0xC230, 0xE320, 0x0450, 0x2540, 0x4670, 0x6760,
+        0xB983, 0x9893, 0xFBA3, 0xDAB3, 0x3DC3, 0x1CD3, 0x7FE3, 0x5EF3,
+        0xB102, 0x9012, 0xF322, 0xD232, 0x3542, 0x1452, 0x7762, 0x5672,
+        0xEAB5, 0xCBA5, 0xA895, 0x8985, 0x6EF5, 0x4FE5, 0x2CD5, 0x0DC5,
+        0xE234, 0xC324, 0xA014, 0x8104, 0x6674, 0x4764, 0x2454, 0x0544,
+        0xDBA7, 0xFAB7, 0x9987, 0xB897, 0x5FE7, 0x7EF7, 0x1DC7, 0x3CD7,
+        0xD326, 0xF236, 0x9106, 0xB016, 0x5766, 0x7676, 0x1546, 0x3456,
+        0x4CD9, 0x6DC9, 0x0EF9, 0x2FE9, 0xC899, 0xE989, 0x8AB9, 0xABA9,
+        0x4458, 0x6548, 0x0678, 0x2768, 0xC018, 0xE108, 0x8238, 0xA328,
+        0x7DCB, 0x5CDB, 0x3FEB, 0x1EFB, 0xF98B, 0xD89B, 0xBBAB, 0x9ABB,
+        0x754A, 0x545A, 0x376A, 0x167A, 0xF10A, 0xD01A, 0xB32A, 0x923A,
+        0x2EFD, 0x0FED, 0x6CDD, 0x4DCD, 0xAABD, 0x8BAD, 0xE89D, 0xC98D,
+        0x267C, 0x076C, 0x645C, 0x454C, 0xA23C, 0x832C, 0xE01C, 0xC10C,
+        0x1FEF, 0x3EFF, 0x5DCF, 0x7CDF, 0x9BAF, 0xBABF, 0xD98F, 0xF89F,
+        0x176E, 0x367E, 0x554E, 0x745E, 0x932E, 0xB23E, 0xD10E, 0xF01E,
+        0x0001
+    },
+    [AV_CRC_32_IEEE] = {
+        0x00000000, 0xB71DC104, 0x6E3B8209, 0xD926430D, 0xDC760413, 0x6B6BC517,
+        0xB24D861A, 0x0550471E, 0xB8ED0826, 0x0FF0C922, 0xD6D68A2F, 0x61CB4B2B,
+        0x649B0C35, 0xD386CD31, 0x0AA08E3C, 0xBDBD4F38, 0x70DB114C, 0xC7C6D048,
+        0x1EE09345, 0xA9FD5241, 0xACAD155F, 0x1BB0D45B, 0xC2969756, 0x758B5652,
+        0xC836196A, 0x7F2BD86E, 0xA60D9B63, 0x11105A67, 0x14401D79, 0xA35DDC7D,
+        0x7A7B9F70, 0xCD665E74, 0xE0B62398, 0x57ABE29C, 0x8E8DA191, 0x39906095,
+        0x3CC0278B, 0x8BDDE68F, 0x52FBA582, 0xE5E66486, 0x585B2BBE, 0xEF46EABA,
+        0x3660A9B7, 0x817D68B3, 0x842D2FAD, 0x3330EEA9, 0xEA16ADA4, 0x5D0B6CA0,
+        0x906D32D4, 0x2770F3D0, 0xFE56B0DD, 0x494B71D9, 0x4C1B36C7, 0xFB06F7C3,
+        0x2220B4CE, 0x953D75CA, 0x28803AF2, 0x9F9DFBF6, 0x46BBB8FB, 0xF1A679FF,
+        0xF4F63EE1, 0x43EBFFE5, 0x9ACDBCE8, 0x2DD07DEC, 0x77708634, 0xC06D4730,
+        0x194B043D, 0xAE56C539, 0xAB068227, 0x1C1B4323, 0xC53D002E, 0x7220C12A,
+        0xCF9D8E12, 0x78804F16, 0xA1A60C1B, 0x16BBCD1F, 0x13EB8A01, 0xA4F64B05,
+        0x7DD00808, 0xCACDC90C, 0x07AB9778, 0xB0B6567C, 0x69901571, 0xDE8DD475,
+        0xDBDD936B, 0x6CC0526F, 0xB5E61162, 0x02FBD066, 0xBF469F5E, 0x085B5E5A,
+        0xD17D1D57, 0x6660DC53, 0x63309B4D, 0xD42D5A49, 0x0D0B1944, 0xBA16D840,
+        0x97C6A5AC, 0x20DB64A8, 0xF9FD27A5, 0x4EE0E6A1, 0x4BB0A1BF, 0xFCAD60BB,
+        0x258B23B6, 0x9296E2B2, 0x2F2BAD8A, 0x98366C8E, 0x41102F83, 0xF60DEE87,
+        0xF35DA999, 0x4440689D, 0x9D662B90, 0x2A7BEA94, 0xE71DB4E0, 0x500075E4,
+        0x892636E9, 0x3E3BF7ED, 0x3B6BB0F3, 0x8C7671F7, 0x555032FA, 0xE24DF3FE,
+        0x5FF0BCC6, 0xE8ED7DC2, 0x31CB3ECF, 0x86D6FFCB, 0x8386B8D5, 0x349B79D1,
+        0xEDBD3ADC, 0x5AA0FBD8, 0xEEE00C69, 0x59FDCD6D, 0x80DB8E60, 0x37C64F64,
+        0x3296087A, 0x858BC97E, 0x5CAD8A73, 0xEBB04B77, 0x560D044F, 0xE110C54B,
+        0x38368646, 0x8F2B4742, 0x8A7B005C, 0x3D66C158, 0xE4408255, 0x535D4351,
+        0x9E3B1D25, 0x2926DC21, 0xF0009F2C, 0x471D5E28, 0x424D1936, 0xF550D832,
+        0x2C769B3F, 0x9B6B5A3B, 0x26D61503, 0x91CBD407, 0x48ED970A, 0xFFF0560E,
+        0xFAA01110, 0x4DBDD014, 0x949B9319, 0x2386521D, 0x0E562FF1, 0xB94BEEF5,
+        0x606DADF8, 0xD7706CFC, 0xD2202BE2, 0x653DEAE6, 0xBC1BA9EB, 0x0B0668EF,
+        0xB6BB27D7, 0x01A6E6D3, 0xD880A5DE, 0x6F9D64DA, 0x6ACD23C4, 0xDDD0E2C0,
+        0x04F6A1CD, 0xB3EB60C9, 0x7E8D3EBD, 0xC990FFB9, 0x10B6BCB4, 0xA7AB7DB0,
+        0xA2FB3AAE, 0x15E6FBAA, 0xCCC0B8A7, 0x7BDD79A3, 0xC660369B, 0x717DF79F,
+        0xA85BB492, 0x1F467596, 0x1A163288, 0xAD0BF38C, 0x742DB081, 0xC3307185,
+        0x99908A5D, 0x2E8D4B59, 0xF7AB0854, 0x40B6C950, 0x45E68E4E, 0xF2FB4F4A,
+        0x2BDD0C47, 0x9CC0CD43, 0x217D827B, 0x9660437F, 0x4F460072, 0xF85BC176,
+        0xFD0B8668, 0x4A16476C, 0x93300461, 0x242DC565, 0xE94B9B11, 0x5E565A15,
+        0x87701918, 0x306DD81C, 0x353D9F02, 0x82205E06, 0x5B061D0B, 0xEC1BDC0F,
+        0x51A69337, 0xE6BB5233, 0x3F9D113E, 0x8880D03A, 0x8DD09724, 0x3ACD5620,
+        0xE3EB152D, 0x54F6D429, 0x7926A9C5, 0xCE3B68C1, 0x171D2BCC, 0xA000EAC8,
+        0xA550ADD6, 0x124D6CD2, 0xCB6B2FDF, 0x7C76EEDB, 0xC1CBA1E3, 0x76D660E7,
+        0xAFF023EA, 0x18EDE2EE, 0x1DBDA5F0, 0xAAA064F4, 0x738627F9, 0xC49BE6FD,
+        0x09FDB889, 0xBEE0798D, 0x67C63A80, 0xD0DBFB84, 0xD58BBC9A, 0x62967D9E,
+        0xBBB03E93, 0x0CADFF97, 0xB110B0AF, 0x060D71AB, 0xDF2B32A6, 0x6836F3A2,
+        0x6D66B4BC, 0xDA7B75B8, 0x035D36B5, 0xB440F7B1, 0x00000001
+    },
+    [AV_CRC_32_IEEE_LE] = {
+        0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
+        0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
+        0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
+        0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
+        0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
+        0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
+        0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
+        0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
+        0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
+        0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
+        0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106,
+        0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
+        0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
+        0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
+        0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
+        0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
+        0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
+        0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
+        0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA,
+        0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
+        0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
+        0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
+        0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84,
+        0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
+        0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
+        0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
+        0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,
+        0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
+        0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
+        0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
+        0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28,
+        0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
+        0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
+        0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
+        0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
+        0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
+        0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
+        0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
+        0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
+        0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
+        0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
+        0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
+        0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D, 0x00000001
+    },
+};
 #else
 static struct {
     uint8_t  le;
@@ -113,7 +298,6 @@
 }
 
 #ifdef TEST
-#undef printf
 int main(void)
 {
     uint8_t buf[1999];
diff --git a/libavutil/crc_data.h b/libavutil/crc_data.h
deleted file mode 100644
index afa25e7..0000000
--- a/libavutil/crc_data.h
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * copyright (c) 2008 Aurelien Jacobs <aurel@gnuage.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
- */
-
-#ifndef AVUTIL_CRC_DATA_H
-#define AVUTIL_CRC_DATA_H
-
-#include "crc.h"
-
-static const AVCRC av_crc_table[AV_CRC_MAX][257] = {
-    [AV_CRC_8_ATM] = {
-        0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15, 0x38, 0x3F, 0x36, 0x31,
-        0x24, 0x23, 0x2A, 0x2D, 0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65,
-        0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D, 0xE0, 0xE7, 0xEE, 0xE9,
-        0xFC, 0xFB, 0xF2, 0xF5, 0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD,
-        0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85, 0xA8, 0xAF, 0xA6, 0xA1,
-        0xB4, 0xB3, 0xBA, 0xBD, 0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2,
-        0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA, 0xB7, 0xB0, 0xB9, 0xBE,
-        0xAB, 0xAC, 0xA5, 0xA2, 0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A,
-        0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32, 0x1F, 0x18, 0x11, 0x16,
-        0x03, 0x04, 0x0D, 0x0A, 0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42,
-        0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A, 0x89, 0x8E, 0x87, 0x80,
-        0x95, 0x92, 0x9B, 0x9C, 0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4,
-        0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC, 0xC1, 0xC6, 0xCF, 0xC8,
-        0xDD, 0xDA, 0xD3, 0xD4, 0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C,
-        0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44, 0x19, 0x1E, 0x17, 0x10,
-        0x05, 0x02, 0x0B, 0x0C, 0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34,
-        0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B, 0x76, 0x71, 0x78, 0x7F,
-        0x6A, 0x6D, 0x64, 0x63, 0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B,
-        0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13, 0xAE, 0xA9, 0xA0, 0xA7,
-        0xB2, 0xB5, 0xBC, 0xBB, 0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83,
-        0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB, 0xE6, 0xE1, 0xE8, 0xEF,
-        0xFA, 0xFD, 0xF4, 0xF3, 0x01
-    },
-    [AV_CRC_16_ANSI] = {
-        0x0000, 0x0580, 0x0F80, 0x0A00, 0x1B80, 0x1E00, 0x1400, 0x1180,
-        0x3380, 0x3600, 0x3C00, 0x3980, 0x2800, 0x2D80, 0x2780, 0x2200,
-        0x6380, 0x6600, 0x6C00, 0x6980, 0x7800, 0x7D80, 0x7780, 0x7200,
-        0x5000, 0x5580, 0x5F80, 0x5A00, 0x4B80, 0x4E00, 0x4400, 0x4180,
-        0xC380, 0xC600, 0xCC00, 0xC980, 0xD800, 0xDD80, 0xD780, 0xD200,
-        0xF000, 0xF580, 0xFF80, 0xFA00, 0xEB80, 0xEE00, 0xE400, 0xE180,
-        0xA000, 0xA580, 0xAF80, 0xAA00, 0xBB80, 0xBE00, 0xB400, 0xB180,
-        0x9380, 0x9600, 0x9C00, 0x9980, 0x8800, 0x8D80, 0x8780, 0x8200,
-        0x8381, 0x8601, 0x8C01, 0x8981, 0x9801, 0x9D81, 0x9781, 0x9201,
-        0xB001, 0xB581, 0xBF81, 0xBA01, 0xAB81, 0xAE01, 0xA401, 0xA181,
-        0xE001, 0xE581, 0xEF81, 0xEA01, 0xFB81, 0xFE01, 0xF401, 0xF181,
-        0xD381, 0xD601, 0xDC01, 0xD981, 0xC801, 0xCD81, 0xC781, 0xC201,
-        0x4001, 0x4581, 0x4F81, 0x4A01, 0x5B81, 0x5E01, 0x5401, 0x5181,
-        0x7381, 0x7601, 0x7C01, 0x7981, 0x6801, 0x6D81, 0x6781, 0x6201,
-        0x2381, 0x2601, 0x2C01, 0x2981, 0x3801, 0x3D81, 0x3781, 0x3201,
-        0x1001, 0x1581, 0x1F81, 0x1A01, 0x0B81, 0x0E01, 0x0401, 0x0181,
-        0x0383, 0x0603, 0x0C03, 0x0983, 0x1803, 0x1D83, 0x1783, 0x1203,
-        0x3003, 0x3583, 0x3F83, 0x3A03, 0x2B83, 0x2E03, 0x2403, 0x2183,
-        0x6003, 0x6583, 0x6F83, 0x6A03, 0x7B83, 0x7E03, 0x7403, 0x7183,
-        0x5383, 0x5603, 0x5C03, 0x5983, 0x4803, 0x4D83, 0x4783, 0x4203,
-        0xC003, 0xC583, 0xCF83, 0xCA03, 0xDB83, 0xDE03, 0xD403, 0xD183,
-        0xF383, 0xF603, 0xFC03, 0xF983, 0xE803, 0xED83, 0xE783, 0xE203,
-        0xA383, 0xA603, 0xAC03, 0xA983, 0xB803, 0xBD83, 0xB783, 0xB203,
-        0x9003, 0x9583, 0x9F83, 0x9A03, 0x8B83, 0x8E03, 0x8403, 0x8183,
-        0x8002, 0x8582, 0x8F82, 0x8A02, 0x9B82, 0x9E02, 0x9402, 0x9182,
-        0xB382, 0xB602, 0xBC02, 0xB982, 0xA802, 0xAD82, 0xA782, 0xA202,
-        0xE382, 0xE602, 0xEC02, 0xE982, 0xF802, 0xFD82, 0xF782, 0xF202,
-        0xD002, 0xD582, 0xDF82, 0xDA02, 0xCB82, 0xCE02, 0xC402, 0xC182,
-        0x4382, 0x4602, 0x4C02, 0x4982, 0x5802, 0x5D82, 0x5782, 0x5202,
-        0x7002, 0x7582, 0x7F82, 0x7A02, 0x6B82, 0x6E02, 0x6402, 0x6182,
-        0x2002, 0x2582, 0x2F82, 0x2A02, 0x3B82, 0x3E02, 0x3402, 0x3182,
-        0x1382, 0x1602, 0x1C02, 0x1982, 0x0802, 0x0D82, 0x0782, 0x0202,
-        0x0001
-    },
-    [AV_CRC_16_CCITT] = {
-        0x0000, 0x2110, 0x4220, 0x6330, 0x8440, 0xA550, 0xC660, 0xE770,
-        0x0881, 0x2991, 0x4AA1, 0x6BB1, 0x8CC1, 0xADD1, 0xCEE1, 0xEFF1,
-        0x3112, 0x1002, 0x7332, 0x5222, 0xB552, 0x9442, 0xF772, 0xD662,
-        0x3993, 0x1883, 0x7BB3, 0x5AA3, 0xBDD3, 0x9CC3, 0xFFF3, 0xDEE3,
-        0x6224, 0x4334, 0x2004, 0x0114, 0xE664, 0xC774, 0xA444, 0x8554,
-        0x6AA5, 0x4BB5, 0x2885, 0x0995, 0xEEE5, 0xCFF5, 0xACC5, 0x8DD5,
-        0x5336, 0x7226, 0x1116, 0x3006, 0xD776, 0xF666, 0x9556, 0xB446,
-        0x5BB7, 0x7AA7, 0x1997, 0x3887, 0xDFF7, 0xFEE7, 0x9DD7, 0xBCC7,
-        0xC448, 0xE558, 0x8668, 0xA778, 0x4008, 0x6118, 0x0228, 0x2338,
-        0xCCC9, 0xEDD9, 0x8EE9, 0xAFF9, 0x4889, 0x6999, 0x0AA9, 0x2BB9,
-        0xF55A, 0xD44A, 0xB77A, 0x966A, 0x711A, 0x500A, 0x333A, 0x122A,
-        0xFDDB, 0xDCCB, 0xBFFB, 0x9EEB, 0x799B, 0x588B, 0x3BBB, 0x1AAB,
-        0xA66C, 0x877C, 0xE44C, 0xC55C, 0x222C, 0x033C, 0x600C, 0x411C,
-        0xAEED, 0x8FFD, 0xECCD, 0xCDDD, 0x2AAD, 0x0BBD, 0x688D, 0x499D,
-        0x977E, 0xB66E, 0xD55E, 0xF44E, 0x133E, 0x322E, 0x511E, 0x700E,
-        0x9FFF, 0xBEEF, 0xDDDF, 0xFCCF, 0x1BBF, 0x3AAF, 0x599F, 0x788F,
-        0x8891, 0xA981, 0xCAB1, 0xEBA1, 0x0CD1, 0x2DC1, 0x4EF1, 0x6FE1,
-        0x8010, 0xA100, 0xC230, 0xE320, 0x0450, 0x2540, 0x4670, 0x6760,
-        0xB983, 0x9893, 0xFBA3, 0xDAB3, 0x3DC3, 0x1CD3, 0x7FE3, 0x5EF3,
-        0xB102, 0x9012, 0xF322, 0xD232, 0x3542, 0x1452, 0x7762, 0x5672,
-        0xEAB5, 0xCBA5, 0xA895, 0x8985, 0x6EF5, 0x4FE5, 0x2CD5, 0x0DC5,
-        0xE234, 0xC324, 0xA014, 0x8104, 0x6674, 0x4764, 0x2454, 0x0544,
-        0xDBA7, 0xFAB7, 0x9987, 0xB897, 0x5FE7, 0x7EF7, 0x1DC7, 0x3CD7,
-        0xD326, 0xF236, 0x9106, 0xB016, 0x5766, 0x7676, 0x1546, 0x3456,
-        0x4CD9, 0x6DC9, 0x0EF9, 0x2FE9, 0xC899, 0xE989, 0x8AB9, 0xABA9,
-        0x4458, 0x6548, 0x0678, 0x2768, 0xC018, 0xE108, 0x8238, 0xA328,
-        0x7DCB, 0x5CDB, 0x3FEB, 0x1EFB, 0xF98B, 0xD89B, 0xBBAB, 0x9ABB,
-        0x754A, 0x545A, 0x376A, 0x167A, 0xF10A, 0xD01A, 0xB32A, 0x923A,
-        0x2EFD, 0x0FED, 0x6CDD, 0x4DCD, 0xAABD, 0x8BAD, 0xE89D, 0xC98D,
-        0x267C, 0x076C, 0x645C, 0x454C, 0xA23C, 0x832C, 0xE01C, 0xC10C,
-        0x1FEF, 0x3EFF, 0x5DCF, 0x7CDF, 0x9BAF, 0xBABF, 0xD98F, 0xF89F,
-        0x176E, 0x367E, 0x554E, 0x745E, 0x932E, 0xB23E, 0xD10E, 0xF01E,
-        0x0001
-    },
-    [AV_CRC_32_IEEE] = {
-        0x00000000, 0xB71DC104, 0x6E3B8209, 0xD926430D, 0xDC760413, 0x6B6BC517,
-        0xB24D861A, 0x0550471E, 0xB8ED0826, 0x0FF0C922, 0xD6D68A2F, 0x61CB4B2B,
-        0x649B0C35, 0xD386CD31, 0x0AA08E3C, 0xBDBD4F38, 0x70DB114C, 0xC7C6D048,
-        0x1EE09345, 0xA9FD5241, 0xACAD155F, 0x1BB0D45B, 0xC2969756, 0x758B5652,
-        0xC836196A, 0x7F2BD86E, 0xA60D9B63, 0x11105A67, 0x14401D79, 0xA35DDC7D,
-        0x7A7B9F70, 0xCD665E74, 0xE0B62398, 0x57ABE29C, 0x8E8DA191, 0x39906095,
-        0x3CC0278B, 0x8BDDE68F, 0x52FBA582, 0xE5E66486, 0x585B2BBE, 0xEF46EABA,
-        0x3660A9B7, 0x817D68B3, 0x842D2FAD, 0x3330EEA9, 0xEA16ADA4, 0x5D0B6CA0,
-        0x906D32D4, 0x2770F3D0, 0xFE56B0DD, 0x494B71D9, 0x4C1B36C7, 0xFB06F7C3,
-        0x2220B4CE, 0x953D75CA, 0x28803AF2, 0x9F9DFBF6, 0x46BBB8FB, 0xF1A679FF,
-        0xF4F63EE1, 0x43EBFFE5, 0x9ACDBCE8, 0x2DD07DEC, 0x77708634, 0xC06D4730,
-        0x194B043D, 0xAE56C539, 0xAB068227, 0x1C1B4323, 0xC53D002E, 0x7220C12A,
-        0xCF9D8E12, 0x78804F16, 0xA1A60C1B, 0x16BBCD1F, 0x13EB8A01, 0xA4F64B05,
-        0x7DD00808, 0xCACDC90C, 0x07AB9778, 0xB0B6567C, 0x69901571, 0xDE8DD475,
-        0xDBDD936B, 0x6CC0526F, 0xB5E61162, 0x02FBD066, 0xBF469F5E, 0x085B5E5A,
-        0xD17D1D57, 0x6660DC53, 0x63309B4D, 0xD42D5A49, 0x0D0B1944, 0xBA16D840,
-        0x97C6A5AC, 0x20DB64A8, 0xF9FD27A5, 0x4EE0E6A1, 0x4BB0A1BF, 0xFCAD60BB,
-        0x258B23B6, 0x9296E2B2, 0x2F2BAD8A, 0x98366C8E, 0x41102F83, 0xF60DEE87,
-        0xF35DA999, 0x4440689D, 0x9D662B90, 0x2A7BEA94, 0xE71DB4E0, 0x500075E4,
-        0x892636E9, 0x3E3BF7ED, 0x3B6BB0F3, 0x8C7671F7, 0x555032FA, 0xE24DF3FE,
-        0x5FF0BCC6, 0xE8ED7DC2, 0x31CB3ECF, 0x86D6FFCB, 0x8386B8D5, 0x349B79D1,
-        0xEDBD3ADC, 0x5AA0FBD8, 0xEEE00C69, 0x59FDCD6D, 0x80DB8E60, 0x37C64F64,
-        0x3296087A, 0x858BC97E, 0x5CAD8A73, 0xEBB04B77, 0x560D044F, 0xE110C54B,
-        0x38368646, 0x8F2B4742, 0x8A7B005C, 0x3D66C158, 0xE4408255, 0x535D4351,
-        0x9E3B1D25, 0x2926DC21, 0xF0009F2C, 0x471D5E28, 0x424D1936, 0xF550D832,
-        0x2C769B3F, 0x9B6B5A3B, 0x26D61503, 0x91CBD407, 0x48ED970A, 0xFFF0560E,
-        0xFAA01110, 0x4DBDD014, 0x949B9319, 0x2386521D, 0x0E562FF1, 0xB94BEEF5,
-        0x606DADF8, 0xD7706CFC, 0xD2202BE2, 0x653DEAE6, 0xBC1BA9EB, 0x0B0668EF,
-        0xB6BB27D7, 0x01A6E6D3, 0xD880A5DE, 0x6F9D64DA, 0x6ACD23C4, 0xDDD0E2C0,
-        0x04F6A1CD, 0xB3EB60C9, 0x7E8D3EBD, 0xC990FFB9, 0x10B6BCB4, 0xA7AB7DB0,
-        0xA2FB3AAE, 0x15E6FBAA, 0xCCC0B8A7, 0x7BDD79A3, 0xC660369B, 0x717DF79F,
-        0xA85BB492, 0x1F467596, 0x1A163288, 0xAD0BF38C, 0x742DB081, 0xC3307185,
-        0x99908A5D, 0x2E8D4B59, 0xF7AB0854, 0x40B6C950, 0x45E68E4E, 0xF2FB4F4A,
-        0x2BDD0C47, 0x9CC0CD43, 0x217D827B, 0x9660437F, 0x4F460072, 0xF85BC176,
-        0xFD0B8668, 0x4A16476C, 0x93300461, 0x242DC565, 0xE94B9B11, 0x5E565A15,
-        0x87701918, 0x306DD81C, 0x353D9F02, 0x82205E06, 0x5B061D0B, 0xEC1BDC0F,
-        0x51A69337, 0xE6BB5233, 0x3F9D113E, 0x8880D03A, 0x8DD09724, 0x3ACD5620,
-        0xE3EB152D, 0x54F6D429, 0x7926A9C5, 0xCE3B68C1, 0x171D2BCC, 0xA000EAC8,
-        0xA550ADD6, 0x124D6CD2, 0xCB6B2FDF, 0x7C76EEDB, 0xC1CBA1E3, 0x76D660E7,
-        0xAFF023EA, 0x18EDE2EE, 0x1DBDA5F0, 0xAAA064F4, 0x738627F9, 0xC49BE6FD,
-        0x09FDB889, 0xBEE0798D, 0x67C63A80, 0xD0DBFB84, 0xD58BBC9A, 0x62967D9E,
-        0xBBB03E93, 0x0CADFF97, 0xB110B0AF, 0x060D71AB, 0xDF2B32A6, 0x6836F3A2,
-        0x6D66B4BC, 0xDA7B75B8, 0x035D36B5, 0xB440F7B1, 0x00000001
-    },
-    [AV_CRC_32_IEEE_LE] = {
-        0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
-        0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
-        0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
-        0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
-        0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
-        0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
-        0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
-        0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
-        0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
-        0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
-        0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106,
-        0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
-        0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
-        0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
-        0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
-        0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
-        0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
-        0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
-        0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA,
-        0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
-        0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
-        0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
-        0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84,
-        0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
-        0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
-        0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
-        0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,
-        0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
-        0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
-        0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
-        0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28,
-        0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
-        0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
-        0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
-        0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
-        0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
-        0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
-        0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
-        0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
-        0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
-        0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
-        0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
-        0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D, 0x00000001
-    },
-};
-
-#endif /* AVUTIL_CRC_DATA_H */
diff --git a/libavutil/des.c b/libavutil/des.c
index 32ac26f..a7a5074 100644
--- a/libavutil/des.c
+++ b/libavutil/des.c
@@ -337,10 +337,6 @@
 }
 
 #ifdef TEST
-// LCOV_EXCL_START
-#undef printf
-#undef rand
-#undef srand
 #include <stdlib.h>
 #include <stdio.h>
 #include "libavutil/time.h"
@@ -442,5 +438,4 @@
 #endif
     return 0;
 }
-// LCOV_EXCL_STOP
 #endif
diff --git a/libavutil/dict.c b/libavutil/dict.c
index 7e7d1cc..967c9e2 100644
--- a/libavutil/dict.c
+++ b/libavutil/dict.c
@@ -94,10 +94,13 @@
             m->elems[m->count].value = (char*)(intptr_t)value;
         } else if (oldval && flags & AV_DICT_APPEND) {
             int len = strlen(oldval) + strlen(value) + 1;
-            if (!(oldval = av_realloc(oldval, len)))
+            char *newval = av_mallocz(len);
+            if (!newval)
                 return AVERROR(ENOMEM);
-            av_strlcat(oldval, value, len);
-            m->elems[m->count].value = oldval;
+            av_strlcat(newval, oldval, len);
+            av_freep(&oldval);
+            av_strlcat(newval, value, len);
+            m->elems[m->count].value = newval;
         } else
             m->elems[m->count].value = av_strdup(value);
         m->count++;
@@ -110,6 +113,53 @@
     return 0;
 }
 
+static int parse_key_value_pair(AVDictionary **pm, const char **buf,
+                                const char *key_val_sep, const char *pairs_sep,
+                                int flags)
+{
+    char *key = av_get_token(buf, key_val_sep);
+    char *val = NULL;
+    int ret;
+
+    if (key && *key && strspn(*buf, key_val_sep)) {
+        (*buf)++;
+        val = av_get_token(buf, pairs_sep);
+    }
+
+    if (key && *key && val && *val)
+        ret = av_dict_set(pm, key, val, flags);
+    else
+        ret = AVERROR(EINVAL);
+
+    av_freep(&key);
+    av_freep(&val);
+
+    return ret;
+}
+
+int av_dict_parse_string(AVDictionary **pm, const char *str,
+                         const char *key_val_sep, const char *pairs_sep,
+                         int flags)
+{
+    int ret;
+
+    if (!str)
+        return 0;
+
+    /* ignore STRDUP flags */
+    flags &= ~(AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
+
+    while (*str) {
+        if ((ret = parse_key_value_pair(pm, &str, key_val_sep, pairs_sep, flags)) < 0)
+            return ret;
+
+        if (*str)
+            str++;
+    }
+
+    return 0;
+}
+
 void av_dict_free(AVDictionary **pm)
 {
     AVDictionary *m = *pm;
diff --git a/libavutil/dict.h b/libavutil/dict.h
index fde3650..38f03a4 100644
--- a/libavutil/dict.h
+++ b/libavutil/dict.h
@@ -113,6 +113,23 @@
 int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags);
 
 /**
+ * Parse the key/value pairs list and add to a dictionary.
+ *
+ * @param key_val_sep  a 0-terminated list of characters used to separate
+ *                     key from value
+ * @param pairs_sep    a 0-terminated list of characters used to separate
+ *                     two pairs from each other
+ * @param flags        flags to use when adding to dictionary.
+ *                     AV_DICT_DONT_STRDUP_KEY and AV_DICT_DONT_STRDUP_VAL
+ *                     are ignored since the key/value tokens will always
+ *                     be duplicated.
+ * @return             0 on success, negative AVERROR code on failure
+ */
+int av_dict_parse_string(AVDictionary **pm, const char *str,
+                         const char *key_val_sep, const char *pairs_sep,
+                         int flags);
+
+/**
  * Copy entries from one AVDictionary struct into another.
  * @param dst pointer to a pointer to a AVDictionary struct. If *dst is NULL,
  *            this function will allocate a struct for you and put it in *dst
diff --git a/libavutil/eval.c b/libavutil/eval.c
index 0d6bd15..5d20224 100644
--- a/libavutil/eval.c
+++ b/libavutil/eval.c
@@ -32,6 +32,7 @@
 #include "eval.h"
 #include "log.h"
 #include "mathematics.h"
+#include "time.h"
 
 typedef struct Parser {
     const AVClass *class;
@@ -94,7 +95,11 @@
         d = strtod(numstr, &next);
     /* if parsing succeeded, check for and interpret postfixes */
     if (next!=numstr) {
-        if (*next >= 'E' && *next <= 'z') {
+        if (next[0] == 'd' && next[1] == 'B') {
+            /* treat dB as decibels instead of decibytes */
+            d = pow(10, d / 20);
+            next += 2;
+        } else if (*next >= 'E' && *next <= 'z') {
             int e= si_prefixes[*next - 'E'];
             if (e) {
                 if (next[1] == 'i') {
@@ -139,7 +144,7 @@
         e_pow, e_mul, e_div, e_add,
         e_last, e_st, e_while, e_taylor, e_root, e_floor, e_ceil, e_trunc,
         e_sqrt, e_not, e_random, e_hypot, e_gcd,
-        e_if, e_ifnot,
+        e_if, e_ifnot, e_print,
     } type;
     double value; // is sign in other types
     union {
@@ -152,6 +157,11 @@
     double *var;
 };
 
+static double etime(double v)
+{
+    return av_gettime() * 0.000001;
+}
+
 static double eval_expr(Parser *p, AVExpr *e)
 {
     switch (e->type) {
@@ -170,8 +180,16 @@
         case e_trunc:  return e->value * trunc(eval_expr(p, e->param[0]));
         case e_sqrt:   return e->value * sqrt (eval_expr(p, e->param[0]));
         case e_not:    return e->value * (eval_expr(p, e->param[0]) == 0);
-        case e_if:     return e->value * ( eval_expr(p, e->param[0]) ? eval_expr(p, e->param[1]) : 0);
-        case e_ifnot:  return e->value * (!eval_expr(p, e->param[0]) ? eval_expr(p, e->param[1]) : 0);
+        case e_if:     return e->value * (eval_expr(p, e->param[0]) ? eval_expr(p, e->param[1]) :
+                                          e->param[2] ? eval_expr(p, e->param[2]) : 0);
+        case e_ifnot:  return e->value * (!eval_expr(p, e->param[0]) ? eval_expr(p, e->param[1]) :
+                                          e->param[2] ? eval_expr(p, e->param[2]) : 0);
+        case e_print: {
+            double x = eval_expr(p, e->param[0]);
+            int level = e->param[1] ? av_clip(eval_expr(p, e->param[1]), INT_MIN, INT_MAX) : AV_LOG_INFO;
+            av_log(p, level, "%f\n", x);
+            return x;
+        }
         case e_random:{
             int idx= av_clip(eval_expr(p, e->param[0]), 0, VARS-1);
             uint64_t r= isnan(p->var[idx]) ? 0 : p->var[idx];
@@ -249,7 +267,7 @@
             double d = eval_expr(p, e->param[0]);
             double d2 = eval_expr(p, e->param[1]);
             switch (e->type) {
-                case e_mod: return e->value * (d - floor(d/d2)*d2);
+                case e_mod: return e->value * (d - floor((!CONFIG_FTRAPV || d2) ? d / d2 : d * INFINITY) * d2);
                 case e_gcd: return e->value * av_gcd(d,d2);
                 case e_max: return e->value * (d >  d2 ?   d : d2);
                 case e_min: return e->value * (d <  d2 ?   d : d2);
@@ -373,6 +391,7 @@
     else if (strmatch(next, "exp"   )) d->a.func0 = exp;
     else if (strmatch(next, "log"   )) d->a.func0 = log;
     else if (strmatch(next, "abs"   )) d->a.func0 = fabs;
+    else if (strmatch(next, "time"  )) d->a.func0 = etime;
     else if (strmatch(next, "squish")) d->type = e_squish;
     else if (strmatch(next, "gauss" )) d->type = e_gauss;
     else if (strmatch(next, "mod"   )) d->type = e_mod;
@@ -396,6 +415,7 @@
     else if (strmatch(next, "sqrt"  )) d->type = e_sqrt;
     else if (strmatch(next, "not"   )) d->type = e_not;
     else if (strmatch(next, "pow"   )) d->type = e_pow;
+    else if (strmatch(next, "print" )) d->type = e_print;
     else if (strmatch(next, "random")) d->type = e_random;
     else if (strmatch(next, "hypot" )) d->type = e_hypot;
     else if (strmatch(next, "gcd"   )) d->type = e_gcd;
@@ -448,16 +468,31 @@
     return parse_primary(e, p);
 }
 
+static int parse_dB(AVExpr **e, Parser *p, int *sign)
+{
+    /* do not filter out the negative sign when parsing a dB value.
+       for example, -3dB is not the same as -(3dB) */
+    if (*p->s == '-') {
+        char *next;
+        double av_unused v = strtod(p->s, &next);
+        if (next != p->s && next[0] == 'd' && next[1] == 'B') {
+            *sign = 0;
+            return parse_primary(e, p);
+        }
+    }
+    return parse_pow(e, p, sign);
+}
+
 static int parse_factor(AVExpr **e, Parser *p)
 {
     int sign, sign2, ret;
     AVExpr *e0, *e1, *e2;
-    if ((ret = parse_pow(&e0, p, &sign)) < 0)
+    if ((ret = parse_dB(&e0, p, &sign)) < 0)
         return ret;
     while(p->s[0]=='^'){
         e1 = e0;
         p->s++;
-        if ((ret = parse_pow(&e2, p, &sign2)) < 0) {
+        if ((ret = parse_dB(&e2, p, &sign2)) < 0) {
             av_expr_free(e1);
             return ret;
         }
@@ -573,6 +608,11 @@
         case e_not:
         case e_random:
             return verify_expr(e->param[0]) && !e->param[1];
+        case e_print:
+            return verify_expr(e->param[0])
+                   && (!e->param[1] || verify_expr(e->param[1]));
+        case e_if:
+        case e_ifnot:
         case e_taylor:
             return verify_expr(e->param[0]) && verify_expr(e->param[1])
                    && (!e->param[2] || verify_expr(e->param[2]));
@@ -660,8 +700,6 @@
 }
 
 #ifdef TEST
-// LCOV_EXCL_START
-#undef printf
 #include <string.h>
 
 static const double const_values[] = {
@@ -746,13 +784,19 @@
         "not(1)",
         "not(NAN)",
         "not(0)",
+        "6.0206dB",
+        "-3.0103dB",
         "pow(0,1.23)",
         "pow(PI,1.23)",
         "PI^1.23",
         "pow(-1,1.23)",
         "if(1, 2)",
+        "if(1, 1, 2)",
+        "if(0, 1, 2)",
         "ifnot(0, 23)",
         "ifnot(1, NaN) + if(0, 1)",
+        "ifnot(1, 1, 2)",
+        "ifnot(0, 1, 2)",
         "taylor(1, 1)",
         "taylor(eq(mod(ld(1),4),1)-eq(mod(ld(1),4),3), PI/2, 1)",
         "root(sin(ld(0))-1, 2)",
@@ -761,7 +805,7 @@
         "squish(2)",
         "gauss(0.1)",
         "hypot(4,3)",
-        "gcd(30,55)*min(9,1)",
+        "gcd(30,55)*print(min(9,1))",
         NULL
     };
 
@@ -797,5 +841,4 @@
 
     return 0;
 }
-// LCOV_EXCL_STOP
 #endif
diff --git a/libavutil/fifo.c b/libavutil/fifo.c
index 47328c4..bafa9e9 100644
--- a/libavutil/fifo.c
+++ b/libavutil/fifo.c
@@ -149,8 +149,6 @@
 
 #ifdef TEST
 
-#undef printf
-
 int main(void)
 {
     /* create a FIFO buffer */
diff --git a/libavutil/float_dsp.c b/libavutil/float_dsp.c
index 7b55187..7641313 100644
--- a/libavutil/float_dsp.c
+++ b/libavutil/float_dsp.c
@@ -47,11 +47,85 @@
         dst[i] = src[i] * mul;
 }
 
+static void vector_dmul_scalar_c(double *dst, const double *src, double mul,
+                                 int len)
+{
+    int i;
+    for (i = 0; i < len; i++)
+        dst[i] = src[i] * mul;
+}
+
+static void vector_fmul_window_c(float *dst, const float *src0,
+                                 const float *src1, const float *win, int len)
+{
+    int i, j;
+
+    dst  += len;
+    win  += len;
+    src0 += len;
+
+    for (i = -len, j = len - 1; i < 0; i++, j--) {
+        float s0 = src0[i];
+        float s1 = src1[j];
+        float wi = win[i];
+        float wj = win[j];
+        dst[i] = s0 * wj - s1 * wi;
+        dst[j] = s0 * wi + s1 * wj;
+    }
+}
+
+static void vector_fmul_add_c(float *dst, const float *src0, const float *src1,
+                              const float *src2, int len){
+    int i;
+
+    for (i = 0; i < len; i++)
+        dst[i] = src0[i] * src1[i] + src2[i];
+}
+
+static void vector_fmul_reverse_c(float *dst, const float *src0,
+                                  const float *src1, int len)
+{
+    int i;
+
+    src1 += len-1;
+    for (i = 0; i < len; i++)
+        dst[i] = src0[i] * src1[-i];
+}
+
+static void butterflies_float_c(float *av_restrict v1, float *av_restrict v2,
+                                int len)
+{
+    int i;
+
+    for (i = 0; i < len; i++) {
+        float t = v1[i] - v2[i];
+        v1[i] += v2[i];
+        v2[i] = t;
+    }
+}
+
+float avpriv_scalarproduct_float_c(const float *v1, const float *v2, int len)
+{
+    float p = 0.0;
+    int i;
+
+    for (i = 0; i < len; i++)
+        p += v1[i] * v2[i];
+
+    return p;
+}
+
 void avpriv_float_dsp_init(AVFloatDSPContext *fdsp, int bit_exact)
 {
     fdsp->vector_fmul = vector_fmul_c;
     fdsp->vector_fmac_scalar = vector_fmac_scalar_c;
     fdsp->vector_fmul_scalar = vector_fmul_scalar_c;
+    fdsp->vector_dmul_scalar = vector_dmul_scalar_c;
+    fdsp->vector_fmul_window = vector_fmul_window_c;
+    fdsp->vector_fmul_add = vector_fmul_add_c;
+    fdsp->vector_fmul_reverse = vector_fmul_reverse_c;
+    fdsp->butterflies_float = butterflies_float_c;
+    fdsp->scalarproduct_float = avpriv_scalarproduct_float_c;
 
 #if ARCH_ARM
     ff_float_dsp_init_arm(fdsp);
diff --git a/libavutil/float_dsp.h b/libavutil/float_dsp.h
index b4e89cb..d0447d6 100644
--- a/libavutil/float_dsp.h
+++ b/libavutil/float_dsp.h
@@ -19,6 +19,8 @@
 #ifndef AVUTIL_FLOAT_DSP_H
 #define AVUTIL_FLOAT_DSP_H
 
+#include "config.h"
+
 typedef struct AVFloatDSPContext {
     /**
      * Calculate the product of two vectors of floats and store the result in
@@ -66,9 +68,111 @@
      */
     void (*vector_fmul_scalar)(float *dst, const float *src, float mul,
                                int len);
+
+    /**
+     * Multiply a vector of double by a scalar double.  Source and
+     * destination vectors must overlap exactly or not at all.
+     *
+     * @param dst result vector
+     *            constraints: 32-byte aligned
+     * @param src input vector
+     *            constraints: 32-byte aligned
+     * @param mul scalar value
+     * @param len length of vector
+     *            constraints: multiple of 8
+     */
+    void (*vector_dmul_scalar)(double *dst, const double *src, double mul,
+                               int len);
+
+    /**
+     * Overlap/add with window function.
+     * Used primarily by MDCT-based audio codecs.
+     * Source and destination vectors must overlap exactly or not at all.
+     *
+     * @param dst  result vector
+     *             constraints: 16-byte aligned
+     * @param src0 first source vector
+     *             constraints: 16-byte aligned
+     * @param src1 second source vector
+     *             constraints: 16-byte aligned
+     * @param win  half-window vector
+     *             constraints: 16-byte aligned
+     * @param len  length of vector
+     *             constraints: multiple of 4
+     */
+    void (*vector_fmul_window)(float *dst, const float *src0,
+                               const float *src1, const float *win, int len);
+
+    /**
+     * Calculate the product of two vectors of floats, add a third vector of
+     * floats and store the result in a vector of floats.
+     *
+     * @param dst  output vector
+     *             constraints: 32-byte aligned
+     * @param src0 first input vector
+     *             constraints: 32-byte aligned
+     * @param src1 second input vector
+     *             constraints: 32-byte aligned
+     * @param src1 third input vector
+     *             constraints: 32-byte aligned
+     * @param len  number of elements in the input
+     *             constraints: multiple of 16
+     */
+    void (*vector_fmul_add)(float *dst, const float *src0, const float *src1,
+                            const float *src2, int len);
+
+    /**
+     * Calculate the product of two vectors of floats, and store the result
+     * in a vector of floats. The second vector of floats is iterated over
+     * in reverse order.
+     *
+     * @param dst  output vector
+     *             constraints: 32-byte aligned
+     * @param src0 first input vector
+     *             constraints: 32-byte aligned
+     * @param src1 second input vector
+     *             constraints: 32-byte aligned
+     * @param src1 third input vector
+     *             constraints: 32-byte aligned
+     * @param len  number of elements in the input
+     *             constraints: multiple of 16
+     */
+    void (*vector_fmul_reverse)(float *dst, const float *src0,
+                                const float *src1, int len);
+
+    /**
+     * Calculate the sum and difference of two vectors of floats.
+     *
+     * @param v1  first input vector, sum output, 16-byte aligned
+     * @param v2  second input vector, difference output, 16-byte aligned
+     * @param len length of vectors, multiple of 4
+     */
+    void (*butterflies_float)(float *av_restrict v1, float *av_restrict v2, int len);
+
+    /**
+     * Calculate the scalar product of two vectors of floats.
+     *
+     * @param v1  first vector, 16-byte aligned
+     * @param v2  second vector, 16-byte aligned
+     * @param len length of vectors, multiple of 4
+     *
+     * @return sum of elementwise products
+     */
+    float (*scalarproduct_float)(const float *v1, const float *v2, int len);
 } AVFloatDSPContext;
 
 /**
+ * Return the scalar product of two vectors.
+ *
+ * @param v1  first input vector
+ * @param v2  first input vector
+ * @param len number of elements
+ *
+ * @return sum of elementwise products
+ */
+float avpriv_scalarproduct_float_c(const float *v1, const float *v2, int len);
+
+/**
  * Initialize a float DSP context.
  *
  * @param fdsp    float DSP context
diff --git a/libavutil/hmac.c b/libavutil/hmac.c
new file mode 100644
index 0000000..e5f1434
--- /dev/null
+++ b/libavutil/hmac.c
@@ -0,0 +1,186 @@
+/*
+ * 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 <string.h>
+
+#include "hmac.h"
+#include "md5.h"
+#include "sha.h"
+#include "mem.h"
+
+#define MAX_HASHLEN 20
+#define MAX_BLOCKLEN 64
+
+struct AVHMAC {
+    void *hash;
+    int blocklen, hashlen;
+    void (*final)(void*, uint8_t*);
+    void (*update)(void*, const uint8_t*, int len);
+    void (*init)(void*);
+    uint8_t key[MAX_BLOCKLEN];
+    int keylen;
+};
+
+static void sha1_init(void *ctx)
+{
+    av_sha_init(ctx, 160);
+}
+
+AVHMAC *av_hmac_alloc(enum AVHMACType type)
+{
+    AVHMAC *c = av_mallocz(sizeof(*c));
+    if (!c)
+        return NULL;
+    switch (type) {
+    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->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->hash     = av_sha_alloc();
+        break;
+    default:
+        av_free(c);
+        return NULL;
+    }
+    if (!c->hash) {
+        av_free(c);
+        return NULL;
+    }
+    return c;
+}
+
+void av_hmac_free(AVHMAC *c)
+{
+    if (!c)
+        return;
+    av_free(c->hash);
+    av_free(c);
+}
+
+void av_hmac_init(AVHMAC *c, const uint8_t *key, unsigned int keylen)
+{
+    int i;
+    uint8_t block[MAX_BLOCKLEN];
+    if (keylen > c->blocklen) {
+        c->init(c->hash);
+        c->update(c->hash, key, keylen);
+        c->final(c->hash, c->key);
+        c->keylen = c->hashlen;
+    } else {
+        memcpy(c->key, key, keylen);
+        c->keylen = keylen;
+    }
+    c->init(c->hash);
+    for (i = 0; i < c->keylen; i++)
+        block[i] = c->key[i] ^ 0x36;
+    for (i = c->keylen; i < c->blocklen; i++)
+        block[i] = 0x36;
+    c->update(c->hash, block, c->blocklen);
+}
+
+void av_hmac_update(AVHMAC *c, const uint8_t *data, unsigned int len)
+{
+    c->update(c->hash, data, len);
+}
+
+int av_hmac_final(AVHMAC *c, uint8_t *out, unsigned int outlen)
+{
+    uint8_t block[MAX_BLOCKLEN];
+    int i;
+    if (outlen < c->hashlen)
+        return AVERROR(EINVAL);
+    c->final(c->hash, out);
+    c->init(c->hash);
+    for (i = 0; i < c->keylen; i++)
+        block[i] = c->key[i] ^ 0x5C;
+    for (i = c->keylen; i < c->blocklen; i++)
+        block[i] = 0x5C;
+    c->update(c->hash, block, c->blocklen);
+    c->update(c->hash, out, c->hashlen);
+    c->final(c->hash, out);
+    return c->hashlen;
+}
+
+int av_hmac_calc(AVHMAC *c, const uint8_t *data, unsigned int len,
+                 const uint8_t *key, unsigned int keylen,
+                 uint8_t *out, unsigned int outlen)
+{
+    av_hmac_init(c, key, keylen);
+    av_hmac_update(c, data, len);
+    return av_hmac_final(c, out, outlen);
+}
+
+#ifdef TEST
+#include <stdio.h>
+
+static void test(AVHMAC *hmac, const uint8_t *key, int keylen,
+                 const uint8_t *data, int datalen)
+{
+    uint8_t buf[MAX_HASHLEN];
+    int out, i;
+    // Some of the test vectors are strings, where sizeof() includes the
+    // trailing null byte - remove that.
+    if (!key[keylen - 1])
+        keylen--;
+    if (!data[datalen - 1])
+        datalen--;
+    out = av_hmac_calc(hmac, data, datalen, key, keylen, buf, sizeof(buf));
+    for (i = 0; i < out; i++)
+        printf("%02x", buf[i]);
+    printf("\n");
+}
+
+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?";
+    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
+    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));
+    av_hmac_free(hmac);
+    return 0;
+}
+#endif /* TEST */
diff --git a/libavutil/hmac.h b/libavutil/hmac.h
new file mode 100644
index 0000000..aef84c6
--- /dev/null
+++ b/libavutil/hmac.h
@@ -0,0 +1,95 @@
+/*
+ * 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
+ */
+
+#ifndef AVUTIL_HMAC_H
+#define AVUTIL_HMAC_H
+
+#include <stdint.h>
+
+/**
+ * @defgroup lavu_hmac HMAC
+ * @ingroup lavu_crypto
+ * @{
+ */
+
+enum AVHMACType {
+    AV_HMAC_MD5,
+    AV_HMAC_SHA1,
+};
+
+typedef struct AVHMAC AVHMAC;
+
+/**
+ * Allocate an AVHMAC context.
+ * @param type The hash function used for the HMAC.
+ */
+AVHMAC *av_hmac_alloc(enum AVHMACType type);
+
+/**
+ * Free an AVHMAC context.
+ * @param ctx The context to free, may be NULL
+ */
+void av_hmac_free(AVHMAC *ctx);
+
+/**
+ * Initialize an AVHMAC context with an authentication key.
+ * @param ctx    The HMAC context
+ * @param key    The authentication key
+ * @param keylen The length of the key, in bytes
+ */
+void av_hmac_init(AVHMAC *ctx, const uint8_t *key, unsigned int keylen);
+
+/**
+ * Hash data with the HMAC.
+ * @param ctx  The HMAC context
+ * @param data The data to hash
+ * @param len  The length of the data, in bytes
+ */
+void av_hmac_update(AVHMAC *ctx, const uint8_t *data, unsigned int len);
+
+/**
+ * Finish hashing and output the HMAC digest.
+ * @param ctx    The HMAC context
+ * @param out    The output buffer to write the digest into
+ * @param outlen The length of the out buffer, in bytes
+ * @return       The number of bytes written to out, or a negative error code.
+ */
+int av_hmac_final(AVHMAC *ctx, uint8_t *out, unsigned int outlen);
+
+/**
+ * Hash an array of data with a key.
+ * @param ctx    The HMAC context
+ * @param data   The data to hash
+ * @param len    The length of the data, in bytes
+ * @param key    The authentication key
+ * @param keylen The length of the key, in bytes
+ * @param out    The output buffer to write the digest into
+ * @param outlen The length of the out buffer, in bytes
+ * @return       The number of bytes written to out, or a negative error code.
+ */
+int av_hmac_calc(AVHMAC *ctx, const uint8_t *data, unsigned int len,
+                 const uint8_t *key, unsigned int keylen,
+                 uint8_t *out, unsigned int outlen);
+
+/**
+ * @}
+ */
+
+#endif /* AVUTIL_HMAC_H */
diff --git a/libavutil/internal.h b/libavutil/internal.h
index cc977f6..a105fe6 100644
--- a/libavutil/internal.h
+++ b/libavutil/internal.h
@@ -40,6 +40,14 @@
 #include "cpu.h"
 #include "dict.h"
 
+#if ARCH_X86
+#   include "x86/emms.h"
+#endif
+
+#ifndef emms_c
+#   define emms_c()
+#endif
+
 #ifndef attribute_align_arg
 #if ARCH_X86_32 && AV_GCC_VERSION_AT_LEAST(4,2)
 #    define attribute_align_arg __attribute__((force_align_arg_pointer))
@@ -58,37 +66,31 @@
 #    define INT_BIT (CHAR_BIT * sizeof(int))
 #endif
 
-/* avoid usage of dangerous/inappropriate system functions */
-#undef  malloc
-#define malloc please_use_av_malloc
-#undef  free
-#define free please_use_av_free
-#undef  realloc
-#define realloc please_use_av_realloc
-#undef  rand
-#define rand rand_is_forbidden_due_to_state_trashing_use_av_lfg_get
-#undef  srand
-#define srand srand_is_forbidden_due_to_state_trashing_use_av_lfg_init
-#undef  random
-#define random random_is_forbidden_due_to_state_trashing_use_av_lfg_get
-#undef  sprintf
-#define sprintf sprintf_is_forbidden_due_to_security_issues_use_snprintf
-#undef  strcat
-#define strcat strcat_is_forbidden_due_to_security_issues_use_av_strlcat
-#undef  exit
-#define exit exit_is_forbidden
-#undef  printf
-#define printf please_use_av_log_instead_of_printf
-#undef  fprintf
-#define fprintf please_use_av_log_instead_of_fprintf
-#undef  puts
-#define puts please_use_av_log_instead_of_puts
-#undef  perror
-#define perror please_use_av_log_instead_of_perror
-#undef strcasecmp
-#define strcasecmp please_use_av_strcasecmp
-#undef strncasecmp
-#define strncasecmp please_use_av_strncasecmp
+// Some broken preprocessors need a second expansion
+// to be forced to tokenize __VA_ARGS__
+#define E1(x) x
+
+#define LOCAL_ALIGNED_A(a, t, v, s, o, ...)             \
+    uint8_t la_##v[sizeof(t s o) + (a)];                \
+    t (*v) o = (void *)FFALIGN((uintptr_t)la_##v, a)
+
+#define LOCAL_ALIGNED_D(a, t, v, s, o, ...)             \
+    DECLARE_ALIGNED(a, t, la_##v) s o;                  \
+    t (*v) o = la_##v
+
+#define LOCAL_ALIGNED(a, t, v, ...) E1(LOCAL_ALIGNED_A(a, t, v, __VA_ARGS__,,))
+
+#if HAVE_LOCAL_ALIGNED_8
+#   define LOCAL_ALIGNED_8(t, v, ...) E1(LOCAL_ALIGNED_D(8, t, v, __VA_ARGS__,,))
+#else
+#   define LOCAL_ALIGNED_8(t, v, ...) LOCAL_ALIGNED(8, t, v, __VA_ARGS__)
+#endif
+
+#if HAVE_LOCAL_ALIGNED_16
+#   define LOCAL_ALIGNED_16(t, v, ...) E1(LOCAL_ALIGNED_D(16, t, v, __VA_ARGS__,,))
+#else
+#   define LOCAL_ALIGNED_16(t, v, ...) LOCAL_ALIGNED(16, t, v, __VA_ARGS__)
+#endif
 
 #define FF_ALLOC_OR_GOTO(ctx, p, size, label)\
 {\
@@ -160,22 +162,4 @@
 #   define ONLY_IF_THREADS_ENABLED(x) NULL
 #endif
 
-#if HAVE_MMX_INLINE
-/**
- * Empty mmx state.
- * this must be called between any dsp function and float/double code.
- * for example sin(); dsp->idct_put(); emms_c(); cos()
- */
-static av_always_inline void emms_c(void)
-{
-    if(av_get_cpu_flags() & AV_CPU_FLAG_MMX)
-        __asm__ volatile ("emms" ::: "memory");
-}
-#elif HAVE_MMX && HAVE_MM_EMPTY
-#   include <mmintrin.h>
-#   define emms_c _mm_empty
-#else
-#   define emms_c()
-#endif /* HAVE_MMX_INLINE */
-
 #endif /* AVUTIL_INTERNAL_H */
diff --git a/libavutil/intreadwrite.h b/libavutil/intreadwrite.h
index 34e21d4..7ee6977 100644
--- a/libavutil/intreadwrite.h
+++ b/libavutil/intreadwrite.h
@@ -47,7 +47,7 @@
 
 /*
  * Arch-specific headers can provide any combination of
- * AV_[RW][BLN](16|24|32|64) and AV_(COPY|SWAP|ZERO)(64|128) macros.
+ * AV_[RW][BLN](16|24|32|48|64) and AV_(COPY|SWAP|ZERO)(64|128) macros.
  * Preprocessor symbols must be defined, even if these are implemented
  * as inline functions.
  */
@@ -114,6 +114,18 @@
 #       define AV_WN32(p, v) AV_WB32(p, v)
 #   endif
 
+#   if    defined(AV_RN48) && !defined(AV_RB48)
+#       define AV_RB48(p) AV_RN48(p)
+#   elif !defined(AV_RN48) &&  defined(AV_RB48)
+#       define AV_RN48(p) AV_RB48(p)
+#   endif
+
+#   if    defined(AV_WN48) && !defined(AV_WB48)
+#       define AV_WB48(p, v) AV_WN48(p, v)
+#   elif !defined(AV_WN48) &&  defined(AV_WB48)
+#       define AV_WN48(p, v) AV_WB48(p, v)
+#   endif
+
 #   if    defined(AV_RN64) && !defined(AV_RB64)
 #       define AV_RB64(p) AV_RN64(p)
 #   elif !defined(AV_RN64) &&  defined(AV_RB64)
@@ -164,6 +176,18 @@
 #       define AV_WN32(p, v) AV_WL32(p, v)
 #   endif
 
+#   if    defined(AV_RN48) && !defined(AV_RL48)
+#       define AV_RL48(p) AV_RN48(p)
+#   elif !defined(AV_RN48) &&  defined(AV_RL48)
+#       define AV_RN48(p) AV_RL48(p)
+#   endif
+
+#   if    defined(AV_WN48) && !defined(AV_WL48)
+#       define AV_WL48(p, v) AV_WN48(p, v)
+#   elif !defined(AV_WN48) &&  defined(AV_WL48)
+#       define AV_WN48(p, v) AV_WL48(p, v)
+#   endif
+
 #   if    defined(AV_RN64) && !defined(AV_RL64)
 #       define AV_RL64(p) AV_RN64(p)
 #   elif !defined(AV_RN64) &&  defined(AV_RL64)
@@ -436,6 +460,48 @@
     } while(0)
 #endif
 
+#ifndef AV_RB48
+#   define AV_RB48(x)                                     \
+    (((uint64_t)((const uint8_t*)(x))[0] << 40) |         \
+     ((uint64_t)((const uint8_t*)(x))[1] << 32) |         \
+     ((uint64_t)((const uint8_t*)(x))[2] << 24) |         \
+     ((uint64_t)((const uint8_t*)(x))[3] << 16) |         \
+     ((uint64_t)((const uint8_t*)(x))[4] <<  8) |         \
+      (uint64_t)((const uint8_t*)(x))[5])
+#endif
+#ifndef AV_WB48
+#   define AV_WB48(p, darg) do {                \
+        uint64_t d = (darg);                    \
+        ((uint8_t*)(p))[5] = (d);               \
+        ((uint8_t*)(p))[4] = (d)>>8;            \
+        ((uint8_t*)(p))[3] = (d)>>16;           \
+        ((uint8_t*)(p))[2] = (d)>>24;           \
+        ((uint8_t*)(p))[1] = (d)>>32;           \
+        ((uint8_t*)(p))[0] = (d)>>40;           \
+    } while(0)
+#endif
+
+#ifndef AV_RL48
+#   define AV_RL48(x)                                     \
+    (((uint64_t)((const uint8_t*)(x))[5] << 40) |         \
+     ((uint64_t)((const uint8_t*)(x))[4] << 32) |         \
+     ((uint64_t)((const uint8_t*)(x))[3] << 24) |         \
+     ((uint64_t)((const uint8_t*)(x))[2] << 16) |         \
+     ((uint64_t)((const uint8_t*)(x))[1] <<  8) |         \
+      (uint64_t)((const uint8_t*)(x))[0])
+#endif
+#ifndef AV_WL48
+#   define AV_WL48(p, darg) do {                \
+        uint64_t d = (darg);                    \
+        ((uint8_t*)(p))[0] = (d);               \
+        ((uint8_t*)(p))[1] = (d)>>8;            \
+        ((uint8_t*)(p))[2] = (d)>>16;           \
+        ((uint8_t*)(p))[3] = (d)>>24;           \
+        ((uint8_t*)(p))[4] = (d)>>32;           \
+        ((uint8_t*)(p))[5] = (d)>>40;           \
+    } while(0)
+#endif
+
 /*
  * The AV_[RW]NA macros access naturally aligned data
  * in a type-safe way.
diff --git a/libavutil/libm.h b/libavutil/libm.h
index bfcc21c..6c17b28 100644
--- a/libavutil/libm.h
+++ b/libavutil/libm.h
@@ -48,6 +48,13 @@
 #define powf(x, y) ((float)pow(x, y))
 #endif
 
+#if !HAVE_CBRT
+static av_always_inline double cbrt(double x)
+{
+    return x < 0 ? -pow(-x, 1.0 / 3.0) : pow(x, 1.0 / 3.0);
+}
+#endif
+
 #if !HAVE_CBRTF
 static av_always_inline float cbrtf(float x)
 {
diff --git a/libavutil/lls.c b/libavutil/lls.c
index dcefc2c..a27c7ae 100644
--- a/libavutil/lls.c
+++ b/libavutil/lls.c
@@ -28,15 +28,16 @@
 #include <math.h>
 #include <string.h>
 
+#include "version.h"
 #include "lls.h"
 
-void av_init_lls(LLSModel *m, int indep_count)
+void avpriv_init_lls(LLSModel *m, int indep_count)
 {
     memset(m, 0, sizeof(LLSModel));
     m->indep_count = indep_count;
 }
 
-void av_update_lls(LLSModel *m, double *var, double decay)
+void avpriv_update_lls(LLSModel *m, double *var, double decay)
 {
     int i, j;
 
@@ -48,7 +49,7 @@
     }
 }
 
-void av_solve_lls(LLSModel *m, double threshold, int min_order)
+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];
@@ -105,7 +106,7 @@
     }
 }
 
-double av_evaluate_lls(LLSModel *m, double *param, int order)
+double avpriv_evaluate_lls(LLSModel *m, double *param, int order)
 {
     int i;
     double out = 0;
@@ -116,6 +117,25 @@
     return out;
 }
 
+#if FF_API_LLS_PRIVATE
+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);
+}
+void av_solve_lls(LLSModel *m, double threshold, int min_order)
+{
+    avpriv_solve_lls(m, threshold, min_order);
+}
+double av_evaluate_lls(LLSModel *m, double *param, int order)
+{
+    return avpriv_evaluate_lls(m, param, order);
+}
+#endif /* FF_API_LLS_PRIVATE */
+
 #ifdef TEST
 
 #include <stdio.h>
@@ -129,7 +149,7 @@
     AVLFG lfg;
 
     av_lfg_init(&lfg, 1);
-    av_init_lls(&m, 3);
+    avpriv_init_lls(&m, 3);
 
     for (i = 0; i < 100; i++) {
         double var[4];
@@ -139,10 +159,10 @@
         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;
-        av_update_lls(&m, var, 0.99);
-        av_solve_lls(&m, 0.001, 0);
+        avpriv_update_lls(&m, var, 0.99);
+        avpriv_solve_lls(&m, 0.001, 0);
         for (order = 0; order < 3; order++) {
-            eval = av_evaluate_lls(&m, var + 1, order);
+            eval = avpriv_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 d168e59..c785d44 100644
--- a/libavutil/lls.h
+++ b/libavutil/lls.h
@@ -23,6 +23,8 @@
 #ifndef AVUTIL_LLS_H
 #define AVUTIL_LLS_H
 
+#include "version.h"
+
 #define MAX_VARS 32
 
 //FIXME avoid direct access to LLSModel from outside
@@ -30,16 +32,23 @@
 /**
  * Linear least squares model.
  */
-typedef struct LLSModel{
-    double covariance[MAX_VARS+1][MAX_VARS+1];
+typedef struct LLSModel {
+    double covariance[MAX_VARS + 1][MAX_VARS + 1];
     double coeff[MAX_VARS][MAX_VARS];
     double variance[MAX_VARS];
     int indep_count;
-}LLSModel;
+} LLSModel;
 
+void avpriv_init_lls(LLSModel *m, int indep_count);
+void avpriv_update_lls(LLSModel *m, double *param, double decay);
+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);
 void av_update_lls(LLSModel *m, double *param, double decay);
 void av_solve_lls(LLSModel *m, double threshold, int min_order);
 double av_evaluate_lls(LLSModel *m, double *param, int order);
+#endif /* FF_API_LLS_PRIVATE */
 
 #endif /* AVUTIL_LLS_H */
diff --git a/libavutil/log.c b/libavutil/log.c
index 57b3d5d..700e89f 100644
--- a/libavutil/log.c
+++ b/libavutil/log.c
@@ -99,7 +99,6 @@
 #endif
 static int use_color = -1;
 
-#undef fprintf
 static void colored_fputs(int level, const char *str)
 {
     if (use_color < 0) {
@@ -220,7 +219,6 @@
         is_atty = isatty(2) ? 1 : -1;
 #endif
 
-#undef fprintf
     if (print_prefix && (flags & AV_LOG_SKIP_REPEATED) && !strcmp(line, prev)){
         count++;
         if (is_atty == 1)
diff --git a/libavutil/log.h b/libavutil/log.h
index ba7315f..7ea95fa 100644
--- a/libavutil/log.h
+++ b/libavutil/log.h
@@ -40,6 +40,8 @@
     AV_CLASS_CATEGORY_NB, ///< not part of ABI/API
 }AVClassCategory;
 
+struct AVOptionRanges;
+
 /**
  * Describe the class of an AVClass context structure. That is an
  * arbitrary struct of which the first field is a pointer to an
@@ -80,10 +82,11 @@
     int log_level_offset_offset;
 
     /**
-     * Offset in the structure where a pointer to the parent context for loging is stored.
-     * for example a decoder that uses eval.c could pass its AVCodecContext to eval as such
-     * parent context. And a av_log() implementation could then display the parent context
-     * can be NULL of course
+     * Offset in the structure where a pointer to the parent context for
+     * logging is stored. For example a decoder could pass its AVCodecContext
+     * to eval as such a parent context, which an av_log() implementation
+     * could then leverage to display the parent context.
+     * The offset can be NULL.
      */
     int parent_log_context_offset;
 
@@ -93,7 +96,7 @@
     void* (*child_next)(void *obj, void *prev);
 
     /**
-     * Return an AVClass corresponding to next potential
+     * Return an AVClass corresponding to the next potential
      * AVOptions-enabled child.
      *
      * The difference between child_next and this is that
@@ -114,6 +117,12 @@
      * available since version (51 << 16 | 59 << 8 | 100)
      */
     AVClassCategory (*get_category)(void* ctx);
+
+    /**
+     * Callback to return the supported/allowed ranges.
+     * available since version (52.12)
+     */
+    int (*query_ranges)(struct AVOptionRanges **, void *obj, const char *key, int flags);
 } AVClass;
 
 /* av_log API */
diff --git a/libavutil/mathematics.c b/libavutil/mathematics.c
index 6c2f6c0..f9cf87d 100644
--- a/libavutil/mathematics.c
+++ b/libavutil/mathematics.c
@@ -61,7 +61,13 @@
     int64_t r=0;
     av_assert2(c > 0);
     av_assert2(b >=0);
-    av_assert2((unsigned)rnd<=5 && rnd!=4);
+    av_assert2((unsigned)(rnd&~AV_ROUND_PASS_MINMAX)<=5 && (rnd&~AV_ROUND_PASS_MINMAX)!=4);
+
+    if (rnd & AV_ROUND_PASS_MINMAX) {
+        if (a == INT64_MIN || a == INT64_MAX)
+            return a;
+        rnd -= AV_ROUND_PASS_MINMAX;
+    }
 
     if(a<0 && a != INT64_MIN) return -av_rescale_rnd(-a, b, c, rnd ^ ((rnd>>1)&1));
 
diff --git a/libavutil/mathematics.h b/libavutil/mathematics.h
index 0021d52..71f0392 100644
--- a/libavutil/mathematics.h
+++ b/libavutil/mathematics.h
@@ -70,6 +70,7 @@
     AV_ROUND_DOWN     = 2, ///< Round toward -infinity.
     AV_ROUND_UP       = 3, ///< Round toward +infinity.
     AV_ROUND_NEAR_INF = 5, ///< Round to nearest and halfway cases away from zero.
+    AV_ROUND_PASS_MINMAX = 8192, ///< Flag to pass INT64_MIN/MAX through instead of rescaling, this avoids special cases for AV_NOPTS_VALUE
 };
 
 /**
@@ -88,6 +89,9 @@
 /**
  * Rescale a 64-bit integer with specified rounding.
  * A simple a*b/c isn't possible as it can overflow.
+ *
+ * @return rescaled value a, or if AV_ROUND_PASS_MINMAX is set and a is
+ *         INT64_MIN or INT64_MAX then a is passed through unchanged.
  */
 int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding) av_const;
 
@@ -98,6 +102,9 @@
 
 /**
  * Rescale a 64-bit integer by 2 rational numbers with specified rounding.
+ *
+ * @return rescaled value a, or if AV_ROUND_PASS_MINMAX is set and a is
+ *         INT64_MIN or INT64_MAX then a is passed through unchanged.
  */
 int64_t av_rescale_q_rnd(int64_t a, AVRational bq, AVRational cq,
                          enum AVRounding) av_const;
diff --git a/libavutil/md5.c b/libavutil/md5.c
index d0d0d27..f8f08f1 100644
--- a/libavutil/md5.c
+++ b/libavutil/md5.c
@@ -180,7 +180,6 @@
 }
 
 #ifdef TEST
-#undef printf
 #include <stdio.h>
 
 static void print_md5(uint8_t *md5)
diff --git a/libavutil/mem.c b/libavutil/mem.c
index d73cdde..a7fe608 100644
--- a/libavutil/mem.c
+++ b/libavutil/mem.c
@@ -36,15 +36,11 @@
 #include <malloc.h>
 #endif
 
+#include "avassert.h"
 #include "avutil.h"
 #include "intreadwrite.h"
 #include "mem.h"
 
-/* here we can use OS-dependent allocation functions */
-#undef free
-#undef malloc
-#undef realloc
-
 #ifdef MALLOC_PREFIX
 
 #define malloc         AV_JOIN(MALLOC_PREFIX, malloc)
@@ -89,7 +85,7 @@
     ptr = malloc(size + ALIGN);
     if (!ptr)
         return ptr;
-    diff              = ((-(long)ptr - 1)&(ALIGN - 1)) + 1;
+    diff              = ((~(long)ptr)&(ALIGN - 1)) + 1;
     ptr               = (char *)ptr + diff;
     ((char *)ptr)[-1] = diff;
 #elif HAVE_POSIX_MEMALIGN
@@ -153,6 +149,7 @@
     if (!ptr)
         return av_malloc(size);
     diff = ((char *)ptr)[-1];
+    av_assert0(diff>0 && diff<=ALIGN);
     ptr = realloc((char *)ptr - diff, size + diff);
     if (ptr)
         ptr = (char *)ptr + diff;
@@ -182,8 +179,11 @@
 void av_free(void *ptr)
 {
 #if CONFIG_MEMALIGN_HACK
-    if (ptr)
-        free((char *)ptr - ((char *)ptr)[-1]);
+    if (ptr) {
+        int v= ((char *)ptr)[-1];
+        av_assert0(v>0 && v<=ALIGN);
+        free((char *)ptr - v);
+    }
 #elif HAVE_ALIGNED_MALLOC
     _aligned_free(ptr);
 #else
@@ -323,7 +323,10 @@
 void av_memcpy_backptr(uint8_t *dst, int back, int cnt)
 {
     const uint8_t *src = &dst[-back];
-    if (back <= 1) {
+    if (!back)
+        return;
+
+    if (back == 1) {
         memset(dst, *src, cnt);
     } else if (back == 2) {
         fill16(dst, cnt);
diff --git a/libavutil/mips/float_dsp_mips.c b/libavutil/mips/float_dsp_mips.c
index 8c3611d..06d52dc 100644
--- a/libavutil/mips/float_dsp_mips.c
+++ b/libavutil/mips/float_dsp_mips.c
@@ -27,6 +27,7 @@
  * SUCH DAMAGE.
  *
  * Author:  Branimir Vasic (bvasic@mips.com)
+ * Author:  Zoran Lukic (zoranl@mips.com)
  *
  * This file is part of FFmpeg.
  *
@@ -104,10 +105,279 @@
         );
     }
 }
+
+static void vector_fmul_scalar_mips(float *dst, const float *src, float mul,
+                                 int len)
+{
+    float temp0, temp1, temp2, temp3;
+    float *local_src = (float*)src;
+    float *end = local_src + len;
+
+    /* loop unrolled 4 times */
+    __asm__ volatile(
+        ".set    push                             \n\t"
+        ".set    noreorder                        \n\t"
+    "1:                                           \n\t"
+        "lwc1    %[temp0],   0(%[src])            \n\t"
+        "lwc1    %[temp1],   4(%[src])            \n\t"
+        "lwc1    %[temp2],   8(%[src])            \n\t"
+        "lwc1    %[temp3],   12(%[src])           \n\t"
+        "addiu   %[dst],     %[dst],     16       \n\t"
+        "mul.s   %[temp0],   %[temp0],   %[mul]   \n\t"
+        "mul.s   %[temp1],   %[temp1],   %[mul]   \n\t"
+        "mul.s   %[temp2],   %[temp2],   %[mul]   \n\t"
+        "mul.s   %[temp3],   %[temp3],   %[mul]   \n\t"
+        "addiu   %[src],     %[src],     16       \n\t"
+        "swc1    %[temp0],   -16(%[dst])          \n\t"
+        "swc1    %[temp1],   -12(%[dst])          \n\t"
+        "swc1    %[temp2],   -8(%[dst])           \n\t"
+        "bne     %[src],     %[end],     1b       \n\t"
+        " swc1   %[temp3],   -4(%[dst])           \n\t"
+        ".set    pop                              \n\t"
+
+        : [temp0]"=&f"(temp0), [temp1]"=&f"(temp1),
+          [temp2]"=&f"(temp2), [temp3]"=&f"(temp3),
+          [dst]"+r"(dst), [src]"+r"(local_src)
+        : [end]"r"(end), [mul]"f"(mul)
+        : "memory"
+    );
+}
+
+static void vector_fmul_window_mips(float *dst, const float *src0,
+        const float *src1, const float *win, int len)
+{
+    int i, j;
+    /*
+     * variables used in inline assembler
+     */
+    float * dst_i, * dst_j, * dst_i2, * dst_j2;
+    float temp, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
+
+    dst  += len;
+    win  += len;
+    src0 += len;
+
+    for (i = -len, j = len - 1; i < 0; i += 8, j -= 8) {
+
+        dst_i = dst + i;
+        dst_j = dst + j;
+
+        dst_i2 = dst + i + 4;
+        dst_j2 = dst + j - 4;
+
+        __asm__ volatile (
+            "mul.s   %[temp],   %[s1],       %[wi]            \n\t"
+            "mul.s   %[temp1],  %[s1],       %[wj]            \n\t"
+            "mul.s   %[temp2],  %[s11],      %[wi1]           \n\t"
+            "mul.s   %[temp3],  %[s11],      %[wj1]           \n\t"
+
+            "msub.s  %[temp],   %[temp],     %[s0],  %[wj]    \n\t"
+            "madd.s  %[temp1],  %[temp1],    %[s0],  %[wi]    \n\t"
+            "msub.s  %[temp2],  %[temp2],    %[s01], %[wj1]   \n\t"
+            "madd.s  %[temp3],  %[temp3],    %[s01], %[wi1]   \n\t"
+
+            "swc1    %[temp],   0(%[dst_i])                   \n\t" /* dst[i] = s0*wj - s1*wi; */
+            "swc1    %[temp1],  0(%[dst_j])                   \n\t" /* dst[j] = s0*wi + s1*wj; */
+            "swc1    %[temp2],  4(%[dst_i])                   \n\t" /* dst[i+1] = s01*wj1 - s11*wi1; */
+            "swc1    %[temp3], -4(%[dst_j])                   \n\t" /* dst[j-1] = s01*wi1 + s11*wj1; */
+
+            "mul.s   %[temp4],  %[s12],      %[wi2]           \n\t"
+            "mul.s   %[temp5],  %[s12],      %[wj2]           \n\t"
+            "mul.s   %[temp6],  %[s13],      %[wi3]           \n\t"
+            "mul.s   %[temp7],  %[s13],      %[wj3]           \n\t"
+
+            "msub.s  %[temp4],  %[temp4],    %[s02], %[wj2]   \n\t"
+            "madd.s  %[temp5],  %[temp5],    %[s02], %[wi2]   \n\t"
+            "msub.s  %[temp6],  %[temp6],    %[s03], %[wj3]   \n\t"
+            "madd.s  %[temp7],  %[temp7],    %[s03], %[wi3]   \n\t"
+
+            "swc1    %[temp4],  8(%[dst_i])                   \n\t" /* dst[i+2] = s02*wj2 - s12*wi2; */
+            "swc1    %[temp5], -8(%[dst_j])                   \n\t" /* dst[j-2] = s02*wi2 + s12*wj2; */
+            "swc1    %[temp6],  12(%[dst_i])                  \n\t" /* dst[i+2] = s03*wj3 - s13*wi3; */
+            "swc1    %[temp7], -12(%[dst_j])                  \n\t" /* dst[j-3] = s03*wi3 + s13*wj3; */
+            : [temp]"=&f"(temp),  [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
+              [temp3]"=&f"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5),
+              [temp6]"=&f"(temp6), [temp7]"=&f"(temp7)
+            : [dst_j]"r"(dst_j),     [dst_i]"r" (dst_i),
+              [s0] "f"(src0[i]),     [wj] "f"(win[j]),     [s1] "f"(src1[j]),
+              [wi] "f"(win[i]),      [s01]"f"(src0[i + 1]),[wj1]"f"(win[j - 1]),
+              [s11]"f"(src1[j - 1]), [wi1]"f"(win[i + 1]), [s02]"f"(src0[i + 2]),
+              [wj2]"f"(win[j - 2]),  [s12]"f"(src1[j - 2]),[wi2]"f"(win[i + 2]),
+              [s03]"f"(src0[i + 3]), [wj3]"f"(win[j - 3]), [s13]"f"(src1[j - 3]),
+              [wi3]"f"(win[i + 3])
+            : "memory"
+        );
+
+        __asm__ volatile (
+            "mul.s  %[temp],   %[s1],       %[wi]            \n\t"
+            "mul.s  %[temp1],  %[s1],       %[wj]            \n\t"
+            "mul.s  %[temp2],  %[s11],      %[wi1]           \n\t"
+            "mul.s  %[temp3],  %[s11],      %[wj1]           \n\t"
+
+            "msub.s %[temp],   %[temp],     %[s0],  %[wj]    \n\t"
+            "madd.s %[temp1],  %[temp1],    %[s0],  %[wi]    \n\t"
+            "msub.s %[temp2],  %[temp2],    %[s01], %[wj1]   \n\t"
+            "madd.s %[temp3],  %[temp3],    %[s01], %[wi1]   \n\t"
+
+            "swc1   %[temp],   0(%[dst_i2])                  \n\t" /* dst[i] = s0*wj - s1*wi; */
+            "swc1   %[temp1],  0(%[dst_j2])                  \n\t" /* dst[j] = s0*wi + s1*wj; */
+            "swc1   %[temp2],  4(%[dst_i2])                  \n\t" /* dst[i+1] = s01*wj1 - s11*wi1; */
+            "swc1   %[temp3], -4(%[dst_j2])                  \n\t" /* dst[j-1] = s01*wi1 + s11*wj1; */
+
+            "mul.s  %[temp4],  %[s12],      %[wi2]           \n\t"
+            "mul.s  %[temp5],  %[s12],      %[wj2]           \n\t"
+            "mul.s  %[temp6],  %[s13],      %[wi3]           \n\t"
+            "mul.s  %[temp7],  %[s13],      %[wj3]           \n\t"
+
+            "msub.s %[temp4],  %[temp4],    %[s02], %[wj2]   \n\t"
+            "madd.s %[temp5],  %[temp5],    %[s02], %[wi2]   \n\t"
+            "msub.s %[temp6],  %[temp6],    %[s03], %[wj3]   \n\t"
+            "madd.s %[temp7],  %[temp7],    %[s03], %[wi3]   \n\t"
+
+            "swc1   %[temp4],  8(%[dst_i2])                  \n\t" /* dst[i+2] = s02*wj2 - s12*wi2; */
+            "swc1   %[temp5], -8(%[dst_j2])                  \n\t" /* dst[j-2] = s02*wi2 + s12*wj2; */
+            "swc1   %[temp6],  12(%[dst_i2])                 \n\t" /* dst[i+2] = s03*wj3 - s13*wi3; */
+            "swc1   %[temp7], -12(%[dst_j2])                 \n\t" /* dst[j-3] = s03*wi3 + s13*wj3; */
+            : [temp]"=&f"(temp),
+              [temp1]"=&f"(temp1), [temp2]"=&f"(temp2), [temp3]"=&f"(temp3),
+              [temp4]"=&f"(temp4), [temp5]"=&f"(temp5), [temp6]"=&f"(temp6),
+              [temp7]  "=&f" (temp7)
+            : [dst_j2]"r"(dst_j2),   [dst_i2]"r"(dst_i2),
+              [s0] "f"(src0[i + 4]), [wj] "f"(win[j - 4]), [s1] "f"(src1[j - 4]),
+              [wi] "f"(win[i + 4]),  [s01]"f"(src0[i + 5]),[wj1]"f"(win[j - 5]),
+              [s11]"f"(src1[j - 5]), [wi1]"f"(win[i + 5]), [s02]"f"(src0[i + 6]),
+              [wj2]"f"(win[j - 6]),  [s12]"f"(src1[j - 6]),[wi2]"f"(win[i + 6]),
+              [s03]"f"(src0[i + 7]), [wj3]"f"(win[j - 7]), [s13]"f"(src1[j - 7]),
+              [wi3]"f"(win[i + 7])
+            : "memory"
+        );
+    }
+}
+
+static void butterflies_float_mips(float *av_restrict v1, float *av_restrict v2,
+                                int len)
+{
+    float temp0, temp1, temp2, temp3, temp4;
+    float temp5, temp6, temp7, temp8, temp9;
+    float temp10, temp11, temp12, temp13, temp14, temp15;
+    int pom;
+    pom = (len >> 2)-1;
+
+    /* loop unrolled 4 times */
+    __asm__ volatile (
+        "lwc1     %[temp0],    0(%[v1])                 \n\t"
+        "lwc1     %[temp1],    4(%[v1])                 \n\t"
+        "lwc1     %[temp2],    8(%[v1])                 \n\t"
+        "lwc1     %[temp3],    12(%[v1])                \n\t"
+        "lwc1     %[temp4],    0(%[v2])                 \n\t"
+        "lwc1     %[temp5],    4(%[v2])                 \n\t"
+        "lwc1     %[temp6],    8(%[v2])                 \n\t"
+        "lwc1     %[temp7],    12(%[v2])                \n\t"
+        "beq      %[pom],      $zero,       2f          \n\t"
+    "1:                                                 \n\t"
+        "sub.s    %[temp8],    %[temp0],    %[temp4]    \n\t"
+        "add.s    %[temp9],    %[temp0],    %[temp4]    \n\t"
+        "sub.s    %[temp10],   %[temp1],    %[temp5]    \n\t"
+        "add.s    %[temp11],   %[temp1],    %[temp5]    \n\t"
+        "sub.s    %[temp12],   %[temp2],    %[temp6]    \n\t"
+        "add.s    %[temp13],   %[temp2],    %[temp6]    \n\t"
+        "sub.s    %[temp14],   %[temp3],    %[temp7]    \n\t"
+        "add.s    %[temp15],   %[temp3],    %[temp7]    \n\t"
+        "addiu    %[v1],       %[v1],       16          \n\t"
+        "addiu    %[v2],       %[v2],       16          \n\t"
+        "addiu    %[pom],      %[pom],      -1          \n\t"
+        "lwc1     %[temp0],    0(%[v1])                 \n\t"
+        "lwc1     %[temp1],    4(%[v1])                 \n\t"
+        "lwc1     %[temp2],    8(%[v1])                 \n\t"
+        "lwc1     %[temp3],    12(%[v1])                \n\t"
+        "lwc1     %[temp4],    0(%[v2])                 \n\t"
+        "lwc1     %[temp5],    4(%[v2])                 \n\t"
+        "lwc1     %[temp6],    8(%[v2])                 \n\t"
+        "lwc1     %[temp7],    12(%[v2])                \n\t"
+        "swc1     %[temp9],    -16(%[v1])               \n\t"
+        "swc1     %[temp8],    -16(%[v2])               \n\t"
+        "swc1     %[temp11],   -12(%[v1])               \n\t"
+        "swc1     %[temp10],   -12(%[v2])               \n\t"
+        "swc1     %[temp13],   -8(%[v1])                \n\t"
+        "swc1     %[temp12],   -8(%[v2])                \n\t"
+        "swc1     %[temp15],   -4(%[v1])                \n\t"
+        "swc1     %[temp14],   -4(%[v2])                \n\t"
+        "bgtz     %[pom],      1b                       \n\t"
+    "2:                                                 \n\t"
+        "sub.s    %[temp8],    %[temp0],    %[temp4]    \n\t"
+        "add.s    %[temp9],    %[temp0],    %[temp4]    \n\t"
+        "sub.s    %[temp10],   %[temp1],    %[temp5]    \n\t"
+        "add.s    %[temp11],   %[temp1],    %[temp5]    \n\t"
+        "sub.s    %[temp12],   %[temp2],    %[temp6]    \n\t"
+        "add.s    %[temp13],   %[temp2],    %[temp6]    \n\t"
+        "sub.s    %[temp14],   %[temp3],    %[temp7]    \n\t"
+        "add.s    %[temp15],   %[temp3],    %[temp7]    \n\t"
+        "swc1     %[temp9],    0(%[v1])                 \n\t"
+        "swc1     %[temp8],    0(%[v2])                 \n\t"
+        "swc1     %[temp11],   4(%[v1])                 \n\t"
+        "swc1     %[temp10],   4(%[v2])                 \n\t"
+        "swc1     %[temp13],   8(%[v1])                 \n\t"
+        "swc1     %[temp12],   8(%[v2])                 \n\t"
+        "swc1     %[temp15],   12(%[v1])                \n\t"
+        "swc1     %[temp14],   12(%[v2])                \n\t"
+
+        : [v1]"+r"(v1), [v2]"+r"(v2), [pom]"+r"(pom), [temp0] "=&f" (temp0),
+          [temp1]"=&f"(temp1), [temp2]"=&f"(temp2), [temp3]"=&f"(temp3),
+          [temp4]"=&f"(temp4), [temp5]"=&f"(temp5), [temp6]"=&f"(temp6),
+          [temp7]"=&f"(temp7), [temp8]"=&f"(temp8), [temp9]"=&f"(temp9),
+          [temp10]"=&f"(temp10), [temp11]"=&f"(temp11), [temp12]"=&f"(temp12),
+          [temp13]"=&f"(temp13), [temp14]"=&f"(temp14), [temp15]"=&f"(temp15)
+        :
+        : "memory"
+    );
+}
+
+static void vector_fmul_reverse_mips(float *dst, const float *src0, const float *src1, int len){
+    int i;
+    float temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
+    src1 += len-1;
+
+    for(i=0; i<(len>>2); i++)
+    {
+        /* loop unrolled 4 times */
+        __asm__ volatile(
+            "lwc1      %[temp0],     0(%[src0])                 \n\t"
+            "lwc1      %[temp1],     0(%[src1])                 \n\t"
+            "lwc1      %[temp2],     4(%[src0])                 \n\t"
+            "lwc1      %[temp3],     -4(%[src1])                \n\t"
+            "lwc1      %[temp4],     8(%[src0])                 \n\t"
+            "lwc1      %[temp5],     -8(%[src1])                \n\t"
+            "lwc1      %[temp6],     12(%[src0])                \n\t"
+            "lwc1      %[temp7],     -12(%[src1])               \n\t"
+            "mul.s     %[temp0],     %[temp1],     %[temp0]     \n\t"
+            "mul.s     %[temp2],     %[temp3],     %[temp2]     \n\t"
+            "mul.s     %[temp4],     %[temp5],     %[temp4]     \n\t"
+            "mul.s     %[temp6],     %[temp7],     %[temp6]     \n\t"
+            "addiu     %[src0],      %[src0],      16           \n\t"
+            "addiu     %[src1],      %[src1],      -16          \n\t"
+            "addiu     %[dst],       %[dst],       16           \n\t"
+            "swc1      %[temp0],     -16(%[dst])                \n\t"
+            "swc1      %[temp2],     -12(%[dst])                \n\t"
+            "swc1      %[temp4],     -8(%[dst])                 \n\t"
+            "swc1      %[temp6],     -4(%[dst])                 \n\t"
+
+            : [dst]"+r"(dst), [src0]"+r"(src0), [src1]"+r"(src1),
+              [temp0]"=&f"(temp0), [temp1]"=&f"(temp1),[temp2]"=&f"(temp2),
+              [temp3]"=&f"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5),
+              [temp6]"=&f"(temp6), [temp7]"=&f"(temp7)
+            :
+            : "memory"
+        );
+    }
+}
 #endif /* HAVE_INLINE_ASM && HAVE_MIPSFPU */
 
 void ff_float_dsp_init_mips(AVFloatDSPContext *fdsp) {
 #if HAVE_INLINE_ASM && HAVE_MIPSFPU
     fdsp->vector_fmul = vector_fmul_mips;
+    fdsp->vector_fmul_scalar  = vector_fmul_scalar_mips;
+    fdsp->vector_fmul_window = vector_fmul_window_mips;
+    fdsp->butterflies_float = butterflies_float_mips;
+    fdsp->vector_fmul_reverse = vector_fmul_reverse_mips;
 #endif /* HAVE_INLINE_ASM && HAVE_MIPSFPU */
 }
diff --git a/libavutil/opt.c b/libavutil/opt.c
index 0ff45c8..61c76da 100644
--- a/libavutil/opt.c
+++ b/libavutil/opt.c
@@ -37,6 +37,8 @@
 #include "mathematics.h"
 #include "samplefmt.h"
 
+#include <float.h>
+
 #if FF_API_FIND_OPT
 //FIXME order them and do a bin search
 const AVOption *av_find_opt(void *v, const char *name, const char *unit, int mask, int flags)
@@ -63,7 +65,8 @@
     AVClass *class = *(AVClass**)obj;
     if (!last && class->option && class->option[0].name)
         return class->option;
-    if (last && last[1].name)           return ++last;
+    if (last && last[1].name)
+        return ++last;
     return NULL;
 }
 
@@ -184,10 +187,15 @@
         double d, num = 1;
         int64_t intnum = 1;
 
-        if (*val == '+' || *val == '-')
-            cmd = *(val++);
+        i = 0;
+        if (*val == '+' || *val == '-') {
+            if (o->type == AV_OPT_TYPE_FLAGS)
+                cmd = *(val++);
+            else if (!notfirst)
+                buf[i++] = *val;
+        }
 
-        for (i = 0; i < sizeof(buf) - 1 && val[i] && val[i] != '+' && val[i] != '-'; i++)
+        for (; i < sizeof(buf) - 1 && val[i] && val[i] != '+' && val[i] != '-'; i++)
             buf[i] = val[i];
         buf[i] = 0;
 
@@ -728,10 +736,31 @@
     return res & flag->default_val.i64;
 }
 
+static void log_value(void *av_log_obj, int level, double d)
+{
+    if      (d == INT_MAX) {
+        av_log(av_log_obj, level, "INT_MAX");
+    } else if (d == INT_MIN) {
+        av_log(av_log_obj, level, "INT_MIN");
+    } else if (d == (double)INT64_MAX) {
+        av_log(av_log_obj, level, "I64_MAX");
+    } else if (d == INT64_MIN) {
+        av_log(av_log_obj, level, "I64_MIN");
+    } else if (d == FLT_MAX) {
+        av_log(av_log_obj, level, "FLT_MAX");
+    } else if (d == FLT_MIN) {
+        av_log(av_log_obj, level, "FLT_MIN");
+    } else {
+        av_log(av_log_obj, level, "%g", d);
+    }
+}
+
 static void opt_list(void *obj, void *av_log_obj, const char *unit,
                      int req_flags, int rej_flags)
 {
     const AVOption *opt=NULL;
+    AVOptionRanges *r;
+    int i;
 
     while ((opt = av_opt_next(obj, opt))) {
         if (!(opt->flags & req_flags) || (opt->flags & rej_flags))
@@ -754,41 +783,41 @@
 
         switch (opt->type) {
             case AV_OPT_TYPE_FLAGS:
-                av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "<flags>");
+                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<flags>");
                 break;
             case AV_OPT_TYPE_INT:
-                av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "<int>");
+                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<int>");
                 break;
             case AV_OPT_TYPE_INT64:
-                av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "<int64>");
+                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<int64>");
                 break;
             case AV_OPT_TYPE_DOUBLE:
-                av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "<double>");
+                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<double>");
                 break;
             case AV_OPT_TYPE_FLOAT:
-                av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "<float>");
+                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<float>");
                 break;
             case AV_OPT_TYPE_STRING:
-                av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "<string>");
+                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<string>");
                 break;
             case AV_OPT_TYPE_RATIONAL:
-                av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "<rational>");
+                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<rational>");
                 break;
             case AV_OPT_TYPE_BINARY:
-                av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "<binary>");
+                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<binary>");
                 break;
             case AV_OPT_TYPE_IMAGE_SIZE:
-                av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "<image_size>");
+                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<image_size>");
                 break;
             case AV_OPT_TYPE_PIXEL_FMT:
-                av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "<pix_fmt>");
+                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<pix_fmt>");
                 break;
             case AV_OPT_TYPE_SAMPLE_FMT:
-                av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "<sample_fmt>");
+                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<sample_fmt>");
                 break;
             case AV_OPT_TYPE_CONST:
             default:
-                av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "");
+                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "");
                 break;
         }
         av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_ENCODING_PARAM) ? 'E' : '.');
@@ -800,6 +829,26 @@
 
         if (opt->help)
             av_log(av_log_obj, AV_LOG_INFO, " %s", opt->help);
+
+        if (av_opt_query_ranges(&r, obj, opt->name, AV_OPT_SEARCH_FAKE_OBJ) >= 0) {
+            switch (opt->type) {
+            case AV_OPT_TYPE_INT:
+            case AV_OPT_TYPE_INT64:
+            case AV_OPT_TYPE_DOUBLE:
+            case AV_OPT_TYPE_FLOAT:
+            case AV_OPT_TYPE_RATIONAL:
+                for (i = 0; i < r->nb_ranges; i++) {
+                    av_log(av_log_obj, AV_LOG_INFO, " (from ");
+                    log_value(av_log_obj, AV_LOG_INFO, r->range[i]->value_min);
+                    av_log(av_log_obj, AV_LOG_INFO, " to ");
+                    log_value(av_log_obj, AV_LOG_INFO, r->range[i]->value_max);
+                    av_log(av_log_obj, AV_LOG_INFO, ")");
+                }
+                break;
+            }
+            av_opt_freep_ranges(&r);
+        }
+
         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);
@@ -1161,9 +1210,95 @@
     return (uint8_t*)obj + opt->offset;
 }
 
-#ifdef TEST
+int av_opt_query_ranges(AVOptionRanges **ranges_arg, void *obj, const char *key, int flags)
+{
+    const AVClass *c = *(AVClass**)obj;
+    int (*callback)(AVOptionRanges **, void *obj, const char *key, int flags) = NULL;
 
-#undef printf
+    if (c->version > (52 << 16 | 11 << 8))
+        callback = c->query_ranges;
+
+    if (!callback)
+        callback = av_opt_query_ranges_default;
+
+    return callback(ranges_arg, obj, key, flags);
+}
+
+int av_opt_query_ranges_default(AVOptionRanges **ranges_arg, void *obj, const char *key, int flags)
+{
+    AVOptionRanges *ranges = av_mallocz(sizeof(*ranges));
+    AVOptionRange **range_array = av_mallocz(sizeof(void*));
+    AVOptionRange *range = av_mallocz(sizeof(*range));
+    const AVOption *field = av_opt_find(obj, key, NULL, 0, flags);
+    int ret;
+
+    *ranges_arg = NULL;
+
+    if (!ranges || !range || !range_array || !field) {
+        ret = AVERROR(ENOMEM);
+        goto fail;
+    }
+
+    ranges->range = range_array;
+    ranges->range[0] = range;
+    ranges->nb_ranges = 1;
+    range->is_range = 1;
+    range->value_min = field->min;
+    range->value_max = field->max;
+
+    switch (field->type) {
+    case AV_OPT_TYPE_INT:
+    case AV_OPT_TYPE_INT64:
+    case AV_OPT_TYPE_PIXEL_FMT:
+    case AV_OPT_TYPE_SAMPLE_FMT:
+    case AV_OPT_TYPE_FLOAT:
+    case AV_OPT_TYPE_DOUBLE:
+        break;
+    case AV_OPT_TYPE_STRING:
+        range->component_min = 0;
+        range->component_max = 0x10FFFF; // max unicode value
+        range->value_min = -1;
+        range->value_max = INT_MAX;
+        break;
+    case AV_OPT_TYPE_RATIONAL:
+        range->component_min = INT_MIN;
+        range->component_max = INT_MAX;
+        break;
+    case AV_OPT_TYPE_IMAGE_SIZE:
+        range->component_min = 0;
+        range->component_max = INT_MAX/128/8;
+        range->value_min = 0;
+        range->value_max = INT_MAX/8;
+        break;
+    default:
+        ret = AVERROR(ENOSYS);
+        goto fail;
+    }
+
+    *ranges_arg = ranges;
+    return 0;
+fail:
+    av_free(ranges);
+    av_free(range);
+    av_free(range_array);
+    return ret;
+}
+
+void av_opt_freep_ranges(AVOptionRanges **rangesp)
+{
+    int i;
+    AVOptionRanges *ranges = *rangesp;
+
+    for (i = 0; i < ranges->nb_ranges; i++) {
+        AVOptionRange *range = ranges->range[i];
+        av_freep(&range->str);
+        av_freep(&ranges->range[i]);
+    }
+    av_freep(&ranges->range);
+    av_freep(rangesp);
+}
+
+#ifdef TEST
 
 typedef struct TestContext
 {
diff --git a/libavutil/opt.h b/libavutil/opt.h
index bf84a9b..baf1b82 100644
--- a/libavutil/opt.h
+++ b/libavutil/opt.h
@@ -293,6 +293,25 @@
     const char *unit;
 } AVOption;
 
+/**
+ * A single allowed range of values, or a single allowed value.
+ */
+typedef struct AVOptionRange {
+    const char *str;
+    double value_min, value_max;             ///< For string ranges this represents the min/max length, for dimensions this represents the min/max pixel count
+    double component_min, component_max;     ///< For string this represents the unicode range for chars, 0-127 limits to ASCII
+    int is_range;                            ///< if set to 1 the struct encodes a range, if set to 0 a single value
+} AVOptionRange;
+
+/**
+ * List of AVOptionRange structs
+ */
+typedef struct AVOptionRanges {
+    AVOptionRange **range;
+    int nb_ranges;
+} AVOptionRanges;
+
+
 #if FF_API_FIND_OPT
 /**
  * Look for an option in obj. Look only for the options which
@@ -672,6 +691,41 @@
  *          or written to.
  */
 void *av_opt_ptr(const AVClass *avclass, void *obj, const char *name);
+
+/**
+ * Free an AVOptionRanges struct and set it to NULL.
+ */
+void av_opt_freep_ranges(AVOptionRanges **ranges);
+
+/**
+ * Get a list of allowed ranges for the given option.
+ *
+ * The returned list may depend on other fields in obj like for example profile.
+ *
+ * @param flags is a bitmask of flags, undefined flags should not be set and should be ignored
+ *              AV_OPT_SEARCH_FAKE_OBJ indicates that the obj is a double pointer to a AVClass instead of a full instance
+ *
+ * The result must be freed with av_opt_freep_ranges.
+ *
+ * @return >= 0 on success, a negative errro code otherwise
+ */
+int av_opt_query_ranges(AVOptionRanges **, void *obj, const char *key, int flags);
+
+/**
+ * Get a default list of allowed ranges for the given option.
+ *
+ * This list is constructed without using the AVClass.query_ranges() callback
+ * and can be used as fallback from within the callback.
+ *
+ * @param flags is a bitmask of flags, undefined flags should not be set and should be ignored
+ *              AV_OPT_SEARCH_FAKE_OBJ indicates that the obj is a double pointer to a AVClass instead of a full instance
+ *
+ * The result must be freed with av_opt_free_ranges.
+ *
+ * @return >= 0 on success, a negative errro code otherwise
+ */
+int av_opt_query_ranges_default(AVOptionRanges **, void *obj, const char *key, int flags);
+
 /**
  * @}
  */
diff --git a/libavutil/parseutils.c b/libavutil/parseutils.c
index f188e81..c67f971 100644
--- a/libavutil/parseutils.c
+++ b/libavutil/parseutils.c
@@ -31,8 +31,6 @@
 #include "random_seed.h"
 #include "parseutils.h"
 
-#undef time
-
 #ifdef TEST
 
 #define av_get_random_seed av_get_random_seed_deterministic
@@ -111,6 +109,12 @@
     { "hd480",     852, 480 },
     { "hd720",    1280, 720 },
     { "hd1080",   1920,1080 },
+    { "2k",       2048,1080 }, /* Digital Cinema System Specification */
+    { "2kflat",   1998,1080 },
+    { "2kscope",  2048, 858 },
+    { "4k",       4096,2160 }, /* Digital Cinema System Specification */
+    { "4kflat",   3996,2160 },
+    { "4kscope",  4096,1716 },
 };
 
 static const VideoRateAbbr video_rate_abbrs[]= {
@@ -584,6 +588,11 @@
         /* parse timestr as HH:MM:SS */
         q = av_small_strptime(p, "%J:%M:%S", &dt);
         if (!q) {
+            /* parse timestr as MM:SS */
+            q = av_small_strptime(p, "%M:%S", &dt);
+            dt.tm_hour = 0;
+        }
+        if (!q) {
             /* parse timestr as S+ */
             dt.tm_sec = strtol(p, (void *)&q, 10);
             if (q == p) /* the parsing didn't succeed */
@@ -676,15 +685,13 @@
 
 #ifdef TEST
 
-static uint32_t random = MKTAG('L','A','V','U');
+static uint32_t randomv = MKTAG('L','A','V','U');
 
 static uint32_t av_get_random_seed_deterministic(void)
 {
-    return random = random * 1664525 + 1013904223;
+    return randomv = randomv * 1664525 + 1013904223;
 }
 
-#undef printf
-
 int main(void)
 {
     printf("Testing av_parse_video_rate()\n");
diff --git a/libavutil/parseutils.h b/libavutil/parseutils.h
index 1f56a7a..3eb35fc 100644
--- a/libavutil/parseutils.h
+++ b/libavutil/parseutils.h
@@ -122,7 +122,7 @@
  * year-month-day.
  * - If a duration the syntax is:
  * @code
- * [-]HH:MM:SS[.m...]]]
+ * [-][HH:]MM:SS[.m...]
  * [-]S+[.m...]
  * @endcode
  * @param duration flag which tells how to interpret timestr, if not
diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c
index 0be8ae4..1016dba 100644
--- a/libavutil/pixdesc.c
+++ b/libavutil/pixdesc.c
@@ -706,10 +706,10 @@
         .log2_chroma_w = 1,
         .log2_chroma_h = 1,
         .comp = {
-            { 0, 1, 1, 0, 15 },        /* Y */
-            { 1, 1, 1, 0, 15 },        /* U */
-            { 2, 1, 1, 0, 15 },        /* V */
-            { 3, 1, 1, 0, 15 },        /* A */
+            { 0, 1, 1, 0, 9 },        /* Y */
+            { 1, 1, 1, 0, 9 },        /* U */
+            { 2, 1, 1, 0, 9 },        /* V */
+            { 3, 1, 1, 0, 9 },        /* A */
         },
         .flags = PIX_FMT_PLANAR | PIX_FMT_ALPHA,
     },
@@ -719,10 +719,10 @@
         .log2_chroma_w = 1,
         .log2_chroma_h = 0,
         .comp = {
-            { 0, 1, 1, 0, 15 },        /* Y */
-            { 1, 1, 1, 0, 15 },        /* U */
-            { 2, 1, 1, 0, 15 },        /* V */
-            { 3, 1, 1, 0, 15 },        /* A */
+            { 0, 1, 1, 0, 9 },        /* Y */
+            { 1, 1, 1, 0, 9 },        /* U */
+            { 2, 1, 1, 0, 9 },        /* V */
+            { 3, 1, 1, 0, 9 },        /* A */
         },
         .flags = PIX_FMT_BE | PIX_FMT_PLANAR | PIX_FMT_ALPHA,
     },
@@ -732,10 +732,10 @@
         .log2_chroma_w = 1,
         .log2_chroma_h = 0,
         .comp = {
-            { 0, 1, 1, 0, 15 },        /* Y */
-            { 1, 1, 1, 0, 15 },        /* U */
-            { 2, 1, 1, 0, 15 },        /* V */
-            { 3, 1, 1, 0, 15 },        /* A */
+            { 0, 1, 1, 0, 9 },        /* Y */
+            { 1, 1, 1, 0, 9 },        /* U */
+            { 2, 1, 1, 0, 9 },        /* V */
+            { 3, 1, 1, 0, 9 },        /* A */
         },
         .flags = PIX_FMT_PLANAR | PIX_FMT_ALPHA,
     },
@@ -745,10 +745,10 @@
         .log2_chroma_w = 0,
         .log2_chroma_h = 0,
         .comp = {
-            { 0, 1, 1, 0, 15 },        /* Y */
-            { 1, 1, 1, 0, 15 },        /* U */
-            { 2, 1, 1, 0, 15 },        /* V */
-            { 3, 1, 1, 0, 15 },        /* A */
+            { 0, 1, 1, 0, 9 },        /* Y */
+            { 1, 1, 1, 0, 9 },        /* U */
+            { 2, 1, 1, 0, 9 },        /* V */
+            { 3, 1, 1, 0, 9 },        /* A */
         },
         .flags = PIX_FMT_BE | PIX_FMT_PLANAR | PIX_FMT_ALPHA,
     },
@@ -758,10 +758,10 @@
         .log2_chroma_w = 0,
         .log2_chroma_h = 0,
         .comp = {
-            { 0, 1, 1, 0, 15 },        /* Y */
-            { 1, 1, 1, 0, 15 },        /* U */
-            { 2, 1, 1, 0, 15 },        /* V */
-            { 3, 1, 1, 0, 15 },        /* A */
+            { 0, 1, 1, 0, 9 },        /* Y */
+            { 1, 1, 1, 0, 9 },        /* U */
+            { 2, 1, 1, 0, 9 },        /* V */
+            { 3, 1, 1, 0, 9 },        /* A */
         },
         .flags = PIX_FMT_PLANAR | PIX_FMT_ALPHA,
     },
@@ -1654,6 +1654,12 @@
         },
         .flags = PIX_FMT_BE | PIX_FMT_PLANAR | PIX_FMT_RGB,
     },
+    [AV_PIX_FMT_VDPAU] = {
+        .name = "vdpau",
+        .log2_chroma_w = 1,
+        .log2_chroma_h = 1,
+        .flags = PIX_FMT_HWACCEL,
+    },
 };
 
 static enum AVPixelFormat get_pix_fmt_internal(const char *name)
@@ -1719,7 +1725,7 @@
     int steps[4] = {0};
 
     for (c = 0; c < pixdesc->nb_components; c++) {
-        AVComponentDescriptor *comp = &pixdesc->comp[c];
+        const AVComponentDescriptor *comp = &pixdesc->comp[c];
         int s = c == 1 || c == 2 ? 0 : log2_pixels;
         steps[comp->plane] = (comp->step_minus1 + 1) << s;
     }
@@ -1757,8 +1763,11 @@
 {
     if (!prev)
         return &av_pix_fmt_descriptors[0];
-    if (prev - av_pix_fmt_descriptors < FF_ARRAY_ELEMS(av_pix_fmt_descriptors) - 1)
-        return prev + 1;
+    while (prev - av_pix_fmt_descriptors < FF_ARRAY_ELEMS(av_pix_fmt_descriptors) - 1) {
+        prev++;
+        if (prev->name)
+            return prev;
+    }
     return NULL;
 }
 
diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h
index 8903b60..1c00ac4 100644
--- a/libavutil/pixfmt.h
+++ b/libavutil/pixfmt.h
@@ -59,9 +59,9 @@
  * allocating the picture.
  *
  * @note
- * make sure that all newly added big endian formats have pix_fmt&1==1
- * and that all newly added little endian formats have pix_fmt&1==0
- * this allows simpler detection of big vs little endian.
+ * Make sure that all newly added big-endian formats have pix_fmt & 1 == 1
+ * and that all newly added little-endian formats have pix_fmt & 1 == 0.
+ * This allows simpler detection of big vs little-endian.
  */
 enum AVPixelFormat {
     AV_PIX_FMT_NONE = -1,
@@ -166,12 +166,12 @@
     AV_PIX_FMT_BGRA64LE,  ///< packed RGBA 16:16:16:16, 64bpp, 16B, 16G, 16R, 16A, the 2-byte value for each R/G/B/A component is stored as little-endian
 #endif
     AV_PIX_FMT_GBRP,      ///< planar GBR 4:4:4 24bpp
-    AV_PIX_FMT_GBRP9BE,   ///< planar GBR 4:4:4 27bpp, big endian
-    AV_PIX_FMT_GBRP9LE,   ///< planar GBR 4:4:4 27bpp, little endian
-    AV_PIX_FMT_GBRP10BE,  ///< planar GBR 4:4:4 30bpp, big endian
-    AV_PIX_FMT_GBRP10LE,  ///< planar GBR 4:4:4 30bpp, little endian
-    AV_PIX_FMT_GBRP16BE,  ///< planar GBR 4:4:4 48bpp, big endian
-    AV_PIX_FMT_GBRP16LE,  ///< planar GBR 4:4:4 48bpp, little endian
+    AV_PIX_FMT_GBRP9BE,   ///< planar GBR 4:4:4 27bpp, big-endian
+    AV_PIX_FMT_GBRP9LE,   ///< planar GBR 4:4:4 27bpp, little-endian
+    AV_PIX_FMT_GBRP10BE,  ///< planar GBR 4:4:4 30bpp, big-endian
+    AV_PIX_FMT_GBRP10LE,  ///< planar GBR 4:4:4 30bpp, little-endian
+    AV_PIX_FMT_GBRP16BE,  ///< planar GBR 4:4:4 48bpp, big-endian
+    AV_PIX_FMT_GBRP16LE,  ///< planar GBR 4:4:4 48bpp, little-endian
 
     /**
      * duplicated pixel formats for compatibility with libav.
@@ -181,24 +181,26 @@
     AV_PIX_FMT_YUVA422P_LIBAV,  ///< planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
     AV_PIX_FMT_YUVA444P_LIBAV,  ///< planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
 
-    AV_PIX_FMT_YUVA420P9BE,  ///< planar YUV 4:2:0 22.5bpp, (1 Cr & Cb sample per 2x2 Y & A samples), big endian
-    AV_PIX_FMT_YUVA420P9LE,  ///< planar YUV 4:2:0 22.5bpp, (1 Cr & Cb sample per 2x2 Y & A samples), little endian
-    AV_PIX_FMT_YUVA422P9BE,  ///< planar YUV 4:2:2 27bpp, (1 Cr & Cb sample per 2x1 Y & A samples), big endian
-    AV_PIX_FMT_YUVA422P9LE,  ///< planar YUV 4:2:2 27bpp, (1 Cr & Cb sample per 2x1 Y & A samples), little endian
-    AV_PIX_FMT_YUVA444P9BE,  ///< planar YUV 4:4:4 36bpp, (1 Cr & Cb sample per 1x1 Y & A samples), big endian
-    AV_PIX_FMT_YUVA444P9LE,  ///< planar YUV 4:4:4 36bpp, (1 Cr & Cb sample per 1x1 Y & A samples), little endian
-    AV_PIX_FMT_YUVA420P10BE, ///< planar YUV 4:2:0 25bpp, (1 Cr & Cb sample per 2x2 Y & A samples, big endian)
-    AV_PIX_FMT_YUVA420P10LE, ///< planar YUV 4:2:0 25bpp, (1 Cr & Cb sample per 2x2 Y & A samples, little endian)
-    AV_PIX_FMT_YUVA422P10BE, ///< planar YUV 4:2:2 30bpp, (1 Cr & Cb sample per 2x1 Y & A samples, big endian)
-    AV_PIX_FMT_YUVA422P10LE, ///< planar YUV 4:2:2 30bpp, (1 Cr & Cb sample per 2x1 Y & A samples, little endian)
-    AV_PIX_FMT_YUVA444P10BE, ///< planar YUV 4:4:4 40bpp, (1 Cr & Cb sample per 1x1 Y & A samples, big endian)
-    AV_PIX_FMT_YUVA444P10LE, ///< planar YUV 4:4:4 40bpp, (1 Cr & Cb sample per 1x1 Y & A samples, little endian)
-    AV_PIX_FMT_YUVA420P16BE, ///< planar YUV 4:2:0 40bpp, (1 Cr & Cb sample per 2x2 Y & A samples, big endian)
-    AV_PIX_FMT_YUVA420P16LE, ///< planar YUV 4:2:0 40bpp, (1 Cr & Cb sample per 2x2 Y & A samples, little endian)
-    AV_PIX_FMT_YUVA422P16BE, ///< planar YUV 4:2:2 48bpp, (1 Cr & Cb sample per 2x1 Y & A samples, big endian)
-    AV_PIX_FMT_YUVA422P16LE, ///< planar YUV 4:2:2 48bpp, (1 Cr & Cb sample per 2x1 Y & A samples, little endian)
-    AV_PIX_FMT_YUVA444P16BE, ///< planar YUV 4:4:4 64bpp, (1 Cr & Cb sample per 1x1 Y & A samples, big endian)
-    AV_PIX_FMT_YUVA444P16LE, ///< planar YUV 4:4:4 64bpp, (1 Cr & Cb sample per 1x1 Y & A samples, little endian)
+    AV_PIX_FMT_YUVA420P9BE,  ///< planar YUV 4:2:0 22.5bpp, (1 Cr & Cb sample per 2x2 Y & A samples), big-endian
+    AV_PIX_FMT_YUVA420P9LE,  ///< planar YUV 4:2:0 22.5bpp, (1 Cr & Cb sample per 2x2 Y & A samples), little-endian
+    AV_PIX_FMT_YUVA422P9BE,  ///< planar YUV 4:2:2 27bpp, (1 Cr & Cb sample per 2x1 Y & A samples), big-endian
+    AV_PIX_FMT_YUVA422P9LE,  ///< planar YUV 4:2:2 27bpp, (1 Cr & Cb sample per 2x1 Y & A samples), little-endian
+    AV_PIX_FMT_YUVA444P9BE,  ///< planar YUV 4:4:4 36bpp, (1 Cr & Cb sample per 1x1 Y & A samples), big-endian
+    AV_PIX_FMT_YUVA444P9LE,  ///< planar YUV 4:4:4 36bpp, (1 Cr & Cb sample per 1x1 Y & A samples), little-endian
+    AV_PIX_FMT_YUVA420P10BE, ///< planar YUV 4:2:0 25bpp, (1 Cr & Cb sample per 2x2 Y & A samples, big-endian)
+    AV_PIX_FMT_YUVA420P10LE, ///< planar YUV 4:2:0 25bpp, (1 Cr & Cb sample per 2x2 Y & A samples, little-endian)
+    AV_PIX_FMT_YUVA422P10BE, ///< planar YUV 4:2:2 30bpp, (1 Cr & Cb sample per 2x1 Y & A samples, big-endian)
+    AV_PIX_FMT_YUVA422P10LE, ///< planar YUV 4:2:2 30bpp, (1 Cr & Cb sample per 2x1 Y & A samples, little-endian)
+    AV_PIX_FMT_YUVA444P10BE, ///< planar YUV 4:4:4 40bpp, (1 Cr & Cb sample per 1x1 Y & A samples, big-endian)
+    AV_PIX_FMT_YUVA444P10LE, ///< planar YUV 4:4:4 40bpp, (1 Cr & Cb sample per 1x1 Y & A samples, little-endian)
+    AV_PIX_FMT_YUVA420P16BE, ///< planar YUV 4:2:0 40bpp, (1 Cr & Cb sample per 2x2 Y & A samples, big-endian)
+    AV_PIX_FMT_YUVA420P16LE, ///< planar YUV 4:2:0 40bpp, (1 Cr & Cb sample per 2x2 Y & A samples, little-endian)
+    AV_PIX_FMT_YUVA422P16BE, ///< planar YUV 4:2:2 48bpp, (1 Cr & Cb sample per 2x1 Y & A samples, big-endian)
+    AV_PIX_FMT_YUVA422P16LE, ///< planar YUV 4:2:2 48bpp, (1 Cr & Cb sample per 2x1 Y & A samples, little-endian)
+    AV_PIX_FMT_YUVA444P16BE, ///< planar YUV 4:4:4 64bpp, (1 Cr & Cb sample per 1x1 Y & A samples, big-endian)
+    AV_PIX_FMT_YUVA444P16LE, ///< planar YUV 4:4:4 64bpp, (1 Cr & Cb sample per 1x1 Y & A samples, little-endian)
+
+    AV_PIX_FMT_VDPAU,     ///< HW acceleration through VDPAU, Picture.data[3] contains a VdpVideoSurface
 
 #ifndef AV_PIX_FMT_ABI_GIT_MASTER
     AV_PIX_FMT_RGBA64BE=0x123,  ///< packed RGBA 16:16:16:16, 64bpp, 16R, 16G, 16B, 16A, the 2-byte value for each R/G/B/A component is stored as big-endian
@@ -225,11 +227,10 @@
     AV_PIX_FMT_YUV444P12LE, ///< planar YUV 4:4:4,36bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
     AV_PIX_FMT_YUV444P14BE, ///< planar YUV 4:4:4,42bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian
     AV_PIX_FMT_YUV444P14LE, ///< planar YUV 4:4:4,42bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
-    AV_PIX_FMT_GBRP12BE,    ///< planar GBR 4:4:4 36bpp, big endian
-    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_GBRP12BE,    ///< planar GBR 4:4:4 36bpp, big-endian
+    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_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
diff --git a/libavutil/ppc/float_dsp_altivec.c b/libavutil/ppc/float_dsp_altivec.c
index 6340e6c..8cee82c 100644
--- a/libavutil/ppc/float_dsp_altivec.c
+++ b/libavutil/ppc/float_dsp_altivec.c
@@ -36,3 +36,89 @@
         vec_st(d1, 16, dst + i);
     }
 }
+
+void ff_vector_fmul_window_altivec(float *dst, const float *src0,
+                                   const float *src1, const float *win, int len)
+{
+    vector float zero, t0, t1, s0, s1, wi, wj;
+    const vector unsigned char reverse = vcprm(3, 2, 1, 0);
+    int i, j;
+
+    dst  += len;
+    win  += len;
+    src0 += len;
+
+    zero = (vector float)vec_splat_u32(0);
+
+    for (i = -len * 4, j = len * 4 - 16; i < 0; i += 16, j -= 16) {
+        s0 = vec_ld(i, src0);
+        s1 = vec_ld(j, src1);
+        wi = vec_ld(i, win);
+        wj = vec_ld(j, win);
+
+        s1 = vec_perm(s1, s1, reverse);
+        wj = vec_perm(wj, wj, reverse);
+
+        t0 = vec_madd(s0, wj, zero);
+        t0 = vec_nmsub(s1, wi, t0);
+        t1 = vec_madd(s0, wi, zero);
+        t1 = vec_madd(s1, wj, t1);
+        t1 = vec_perm(t1, t1, reverse);
+
+        vec_st(t0, i, dst);
+        vec_st(t1, j, dst);
+    }
+}
+
+void ff_vector_fmul_add_altivec(float *dst, const float *src0,
+                                const float *src1, const float *src2,
+                                int len)
+{
+    int i;
+    vector float d, s0, s1, s2, t0, t1, edges;
+    vector unsigned char align = vec_lvsr(0,dst),
+                         mask = vec_lvsl(0, dst);
+
+    for (i = 0; i < len - 3; i += 4) {
+        t0 = vec_ld(0, dst + i);
+        t1 = vec_ld(15, dst + i);
+        s0 = vec_ld(0, src0 + i);
+        s1 = vec_ld(0, src1 + i);
+        s2 = vec_ld(0, src2 + i);
+        edges = vec_perm(t1, t0, mask);
+        d = vec_madd(s0, s1, s2);
+        t1 = vec_perm(d, edges, align);
+        t0 = vec_perm(edges, d, align);
+        vec_st(t1, 15, dst + i);
+        vec_st(t0, 0, dst + i);
+    }
+}
+
+void ff_vector_fmul_reverse_altivec(float *dst, const float *src0,
+                                    const float *src1, int len)
+{
+    int i;
+    vector float d, s0, s1, h0, l0,
+                s2, s3, zero = (vector float) vec_splat_u32(0);
+
+    src1 += len-4;
+    for(i = 0; i < len - 7; i += 8) {
+        s1 = vec_ld(0, src1 - i);              // [a,b,c,d]
+        s0 = vec_ld(0, src0 + i);
+        l0 = vec_mergel(s1, s1);               // [c,c,d,d]
+        s3 = vec_ld(-16, src1 - i);
+        h0 = vec_mergeh(s1, s1);               // [a,a,b,b]
+        s2 = vec_ld(16, src0 + i);
+        s1 = vec_mergeh(vec_mergel(l0, h0),    // [d,b,d,b]
+                        vec_mergeh(l0, h0));   // [c,a,c,a]
+        // [d,c,b,a]
+        l0 = vec_mergel(s3, s3);
+        d = vec_madd(s0, s1, zero);
+        h0 = vec_mergeh(s3, s3);
+        vec_st(d, 0, dst + i);
+        s3 = vec_mergeh(vec_mergel(l0, h0),
+                        vec_mergeh(l0, h0));
+        d = vec_madd(s2, s3, zero);
+        vec_st(d, 16, dst + i);
+    }
+}
diff --git a/libavutil/ppc/float_dsp_altivec.h b/libavutil/ppc/float_dsp_altivec.h
index 20c89c2..b262a83 100644
--- a/libavutil/ppc/float_dsp_altivec.h
+++ b/libavutil/ppc/float_dsp_altivec.h
@@ -24,4 +24,15 @@
 extern void ff_vector_fmul_altivec(float *dst, const float *src0,
                                    const float *src1, int len);
 
+extern void ff_vector_fmul_window_altivec(float *dst, const float *src0,
+                                          const float *src1, const float *win,
+                                          int len);
+
+extern void ff_vector_fmul_add_altivec(float *dst, const float *src0,
+                                       const float *src1, const float *src2,
+                                       int len);
+
+extern void ff_vector_fmul_reverse_altivec(float *dst, const float *src0,
+                                           const float *src1, int len);
+
 #endif /* AVUTIL_PPC_FLOAT_DSP_ALTIVEC_H */
diff --git a/libavutil/ppc/float_dsp_init.c b/libavutil/ppc/float_dsp_init.c
index d0ae788..d9ca53e 100644
--- a/libavutil/ppc/float_dsp_init.c
+++ b/libavutil/ppc/float_dsp_init.c
@@ -32,5 +32,11 @@
         return;
 
     fdsp->vector_fmul = ff_vector_fmul_altivec;
+    fdsp->vector_fmul_add = ff_vector_fmul_add_altivec;
+    fdsp->vector_fmul_reverse = ff_vector_fmul_reverse_altivec;
+
+    if (!bit_exact) {
+        fdsp->vector_fmul_window = ff_vector_fmul_window_altivec;
+    }
 #endif
 }
diff --git a/libavutil/samplefmt.h b/libavutil/samplefmt.h
index e222ba2..529711f 100644
--- a/libavutil/samplefmt.h
+++ b/libavutil/samplefmt.h
@@ -37,7 +37,7 @@
  * [-1.0, 1.0]. Any values outside this range are beyond full volume level.
  *
  * @par
- * The data layout as used in av_samples_fill_arrays() and elsewhere in Libav
+ * The data layout as used in av_samples_fill_arrays() and elsewhere in FFmpeg
  * (such as AVFrame in libavcodec) is as follows:
  *
  * For planar sample formats, each audio channel is in a separate data plane,
diff --git a/libavutil/sha.c b/libavutil/sha.c
index 8d5ca45..9f630fc 100644
--- a/libavutil/sha.c
+++ b/libavutil/sha.c
@@ -332,7 +332,6 @@
 
 #ifdef TEST
 #include <stdio.h>
-#undef printf
 
 int main(void)
 {
diff --git a/libavutil/timecode.c b/libavutil/timecode.c
index 77d828d..d396032 100644
--- a/libavutil/timecode.c
+++ b/libavutil/timecode.c
@@ -35,18 +35,21 @@
 {
     /* only works for NTSC 29.97 and 59.94 */
     int drop_frames = 0;
-    int d = framenum / 17982;
-    int m = framenum % 17982;
+    int d, m, frames_per_10mins;
 
-    if (fps == 30)
+    if (fps == 30) {
         drop_frames = 2;
-    else if (fps == 60)
+        frames_per_10mins = 17982;
+    } else if (fps == 60) {
         drop_frames = 4;
-    else
+        frames_per_10mins = 35964;
+    } else
         return framenum;
 
-    //if (m < 2) m += 2; /* not needed since -2,-1 / 1798 in C returns 0 */
-    return framenum + 9 * drop_frames * d + drop_frames * ((m - 2) / 1798);
+    d = framenum / frames_per_10mins;
+    m = framenum % frames_per_10mins;
+
+    return framenum + 9 * drop_frames * d + drop_frames * ((m - drop_frames) / (frames_per_10mins / 10));
 }
 
 uint32_t av_timecode_get_smpte_from_framenum(const AVTimecode *tc, int framenum)
@@ -152,8 +155,8 @@
         av_log(log_ctx, AV_LOG_ERROR, "Timecode frame rate must be specified\n");
         return AVERROR(EINVAL);
     }
-    if ((tc->flags & AV_TIMECODE_FLAG_DROPFRAME) && tc->fps != 30) {
-        av_log(log_ctx, AV_LOG_ERROR, "Drop frame is only allowed with 30000/1001 FPS\n");
+    if ((tc->flags & AV_TIMECODE_FLAG_DROPFRAME) && tc->fps != 30 && tc->fps != 60) {
+        av_log(log_ctx, AV_LOG_ERROR, "Drop frame is only allowed with 30000/1001 or 60000/1001 FPS\n");
         return AVERROR(EINVAL);
     }
     if (check_fps(tc->fps) < 0) {
diff --git a/libavutil/tomi/intreadwrite.h b/libavutil/tomi/intreadwrite.h
index 778b804..7dec415 100644
--- a/libavutil/tomi/intreadwrite.h
+++ b/libavutil/tomi/intreadwrite.h
@@ -22,7 +22,9 @@
 #define AVUTIL_TOMI_INTREADWRITE_H
 
 #include <stdint.h>
+
 #include "config.h"
+#include "libavutil/attributes.h"
 
 #define AV_RB16 AV_RB16
 static av_always_inline uint16_t AV_RB16(const void *p)
diff --git a/libavutil/utils.c b/libavutil/utils.c
index 01c940c..fbfbc49 100644
--- a/libavutil/utils.c
+++ b/libavutil/utils.c
@@ -35,6 +35,11 @@
     av_assert0(LIBAVUTIL_VERSION_MICRO >= 100);
     av_assert0(HAVE_MMX2 == HAVE_MMXEXT);
 
+    if (av_sat_dadd32(1, 2) != 5) {
+        av_log(NULL, AV_LOG_FATAL, "Libavutil has been build with a broken binutils, please upgrade binutils and rebuild\n");
+        abort();
+    }
+
     return LIBAVUTIL_VERSION_INT;
 }
 
diff --git a/libavutil/version.h b/libavutil/version.h
index a44feda..cf65fff 100644
--- a/libavutil/version.h
+++ b/libavutil/version.h
@@ -75,8 +75,8 @@
  */
 
 #define LIBAVUTIL_VERSION_MAJOR  52
-#define LIBAVUTIL_VERSION_MINOR  11
-#define LIBAVUTIL_VERSION_MICRO 101
+#define LIBAVUTIL_VERSION_MINOR  17
+#define LIBAVUTIL_VERSION_MICRO 103
 
 #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
                                                LIBAVUTIL_VERSION_MINOR, \
@@ -129,6 +129,10 @@
 #ifndef FF_API_SAMPLES_UTILS_RETURN_ZERO
 #define FF_API_SAMPLES_UTILS_RETURN_ZERO (LIBAVUTIL_VERSION_MAJOR < 53)
 #endif
+#ifndef FF_API_LLS_PRIVATE
+#define FF_API_LLS_PRIVATE              (LIBAVUTIL_VERSION_MAJOR < 53)
+#endif
+
 
 /**
  * @}
diff --git a/libavutil/x86/Makefile b/libavutil/x86/Makefile
index 3dd696c..ae07470 100644
--- a/libavutil/x86/Makefile
+++ b/libavutil/x86/Makefile
@@ -2,4 +2,5 @@
         x86/float_dsp_init.o                                            \
 
 YASM-OBJS += x86/cpuid.o                                                \
+             x86/emms.o                                                 \
              x86/float_dsp.o                                            \
diff --git a/libavutil/x86/emms.asm b/libavutil/x86/emms.asm
new file mode 100644
index 0000000..0aad34a
--- /dev/null
+++ b/libavutil/x86/emms.asm
@@ -0,0 +1,30 @@
+;*****************************************************************************
+;* Copyright (C) 2013 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 "x86util.asm"
+
+SECTION .text
+
+;-----------------------------------------------------------------------------
+; void avpriv_emms_yasm(void)
+;-----------------------------------------------------------------------------
+cvisible emms_yasm, 0, 0
+    emms
+    RET
diff --git a/libavutil/x86/emms.h b/libavutil/x86/emms.h
new file mode 100644
index 0000000..a529b6b
--- /dev/null
+++ b/libavutil/x86/emms.h
@@ -0,0 +1,47 @@
+/*
+ * 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_X86_EMMS_H
+#define AVUTIL_X86_EMMS_H
+
+#include "config.h"
+#include "libavutil/attributes.h"
+#include "libavutil/cpu.h"
+
+void avpriv_emms_yasm(void);
+
+#if HAVE_MMX_INLINE
+#   define emms_c emms_c
+/**
+ * Empty mmx state.
+ * this must be called between any dsp function and float/double code.
+ * for example sin(); dsp->idct_put(); emms_c(); cos()
+ */
+static av_always_inline void emms_c(void)
+{
+    if(av_get_cpu_flags() & AV_CPU_FLAG_MMX)
+        __asm__ volatile ("emms" ::: "memory");
+}
+#elif HAVE_MMX && HAVE_MM_EMPTY
+#   include <mmintrin.h>
+#   define emms_c _mm_empty
+#elif HAVE_MMX_EXTERNAL
+#   define emms_c avpriv_emms_yasm
+#endif /* HAVE_MMX_INLINE */
+
+#endif /* AVUTIL_X86_EMMS_H */
diff --git a/libavutil/x86/float_dsp.asm b/libavutil/x86/float_dsp.asm
index a3200c6..004e6cf 100644
--- a/libavutil/x86/float_dsp.asm
+++ b/libavutil/x86/float_dsp.asm
@@ -120,3 +120,146 @@
 
 INIT_XMM sse
 VECTOR_FMUL_SCALAR
+
+;------------------------------------------------------------------------------
+; void ff_vector_dmul_scalar(double *dst, const double *src, double mul,
+;                            int len)
+;------------------------------------------------------------------------------
+
+%macro VECTOR_DMUL_SCALAR 0
+%if ARCH_X86_32
+cglobal vector_dmul_scalar, 3,4,3, dst, src, mul, len, lenaddr
+    mov          lenq, lenaddrm
+%elif UNIX64
+cglobal vector_dmul_scalar, 3,3,3, dst, src, len
+%else
+cglobal vector_dmul_scalar, 4,4,3, dst, src, mul, len
+%endif
+%if ARCH_X86_32
+    VBROADCASTSD   m0, mulm
+%else
+%if WIN64
+    movlhps      xmm2, xmm2
+%if cpuflag(avx)
+    vinsertf128  ymm2, ymm2, xmm2, 1
+%endif
+    SWAP 0, 2
+%else
+    movlhps      xmm0, xmm0
+%if cpuflag(avx)
+    vinsertf128  ymm0, ymm0, xmm0, 1
+%endif
+%endif
+%endif
+    lea          lenq, [lend*8-2*mmsize]
+.loop:
+    mulpd          m1, m0, [srcq+lenq       ]
+    mulpd          m2, m0, [srcq+lenq+mmsize]
+    mova   [dstq+lenq       ], m1
+    mova   [dstq+lenq+mmsize], m2
+    sub          lenq, 2*mmsize
+    jge .loop
+    REP_RET
+%endmacro
+
+INIT_XMM sse2
+VECTOR_DMUL_SCALAR
+%if HAVE_AVX_EXTERNAL
+INIT_YMM avx
+VECTOR_DMUL_SCALAR
+%endif
+
+;-----------------------------------------------------------------------------
+; vector_fmul_add(float *dst, const float *src0, const float *src1,
+;                 const float *src2, int len)
+;-----------------------------------------------------------------------------
+%macro VECTOR_FMUL_ADD 0
+cglobal vector_fmul_add, 5,5,2, dst, src0, src1, src2, len
+    lea       lenq, [lend*4 - 2*mmsize]
+ALIGN 16
+.loop:
+    mova    m0,   [src0q + lenq]
+    mova    m1,   [src0q + lenq + mmsize]
+    mulps   m0, m0, [src1q + lenq]
+    mulps   m1, m1, [src1q + lenq + mmsize]
+    addps   m0, m0, [src2q + lenq]
+    addps   m1, m1, [src2q + lenq + mmsize]
+    mova    [dstq + lenq], m0
+    mova    [dstq + lenq + mmsize], m1
+
+    sub     lenq,   2*mmsize
+    jge     .loop
+    REP_RET
+%endmacro
+
+INIT_XMM sse
+VECTOR_FMUL_ADD
+%if HAVE_AVX_EXTERNAL
+INIT_YMM avx
+VECTOR_FMUL_ADD
+%endif
+
+;-----------------------------------------------------------------------------
+; void vector_fmul_reverse(float *dst, const float *src0, const float *src1,
+;                          int len)
+;-----------------------------------------------------------------------------
+%macro VECTOR_FMUL_REVERSE 0
+cglobal vector_fmul_reverse, 4,4,2, dst, src0, src1, len
+    lea       lenq, [lend*4 - 2*mmsize]
+ALIGN 16
+.loop:
+%if cpuflag(avx)
+    vmovaps     xmm0, [src1q + 16]
+    vinsertf128 m0, m0, [src1q], 1
+    vshufps     m0, m0, m0, q0123
+    vmovaps     xmm1, [src1q + mmsize + 16]
+    vinsertf128 m1, m1, [src1q + mmsize], 1
+    vshufps     m1, m1, m1, q0123
+%else
+    mova    m0, [src1q]
+    mova    m1, [src1q + mmsize]
+    shufps  m0, m0, q0123
+    shufps  m1, m1, q0123
+%endif
+    mulps   m0, m0, [src0q + lenq + mmsize]
+    mulps   m1, m1, [src0q + lenq]
+    mova    [dstq + lenq + mmsize], m0
+    mova    [dstq + lenq], m1
+    add     src1q, 2*mmsize
+    sub     lenq,  2*mmsize
+    jge     .loop
+    REP_RET
+%endmacro
+
+INIT_XMM sse
+VECTOR_FMUL_REVERSE
+%if HAVE_AVX_EXTERNAL
+INIT_YMM avx
+VECTOR_FMUL_REVERSE
+%endif
+
+; float scalarproduct_float_sse(const float *v1, const float *v2, int len)
+INIT_XMM sse
+cglobal scalarproduct_float, 3,3,2, v1, v2, offset
+    neg   offsetq
+    shl   offsetq, 2
+    sub       v1q, offsetq
+    sub       v2q, offsetq
+    xorps    xmm0, xmm0
+.loop:
+    movaps   xmm1, [v1q+offsetq]
+    mulps    xmm1, [v2q+offsetq]
+    addps    xmm0, xmm1
+    add   offsetq, 16
+    js .loop
+    movhlps  xmm1, xmm0
+    addps    xmm0, xmm1
+    movss    xmm1, xmm0
+    shufps   xmm0, xmm0, 1
+    addss    xmm0, xmm1
+%if ARCH_X86_64 == 0
+    movss     r0m,  xmm0
+    fld dword r0m
+%endif
+    RET
+
diff --git a/libavutil/x86/float_dsp_init.c b/libavutil/x86/float_dsp_init.c
index 259fda1..5c6383b 100644
--- a/libavutil/x86/float_dsp_init.c
+++ b/libavutil/x86/float_dsp_init.c
@@ -21,6 +21,7 @@
 #include "libavutil/cpu.h"
 #include "libavutil/float_dsp.h"
 #include "cpu.h"
+#include "asm.h"
 
 extern void ff_vector_fmul_sse(float *dst, const float *src0, const float *src1,
                                int len);
@@ -35,17 +36,117 @@
 extern void ff_vector_fmul_scalar_sse(float *dst, const float *src, float mul,
                                       int len);
 
+extern void ff_vector_dmul_scalar_sse2(double *dst, const double *src,
+                                       double mul, int len);
+extern void ff_vector_dmul_scalar_avx(double *dst, const double *src,
+                                      double mul, int len);
+
+void ff_vector_fmul_add_sse(float *dst, const float *src0, const float *src1,
+                            const float *src2, int len);
+void ff_vector_fmul_add_avx(float *dst, const float *src0, const float *src1,
+                            const float *src2, int len);
+
+void ff_vector_fmul_reverse_sse(float *dst, const float *src0,
+                                const float *src1, int len);
+void ff_vector_fmul_reverse_avx(float *dst, const float *src0,
+                                const float *src1, int len);
+
+float ff_scalarproduct_float_sse(const float *v1, const float *v2, int order);
+
+#if HAVE_6REGS && HAVE_INLINE_ASM
+static void vector_fmul_window_3dnowext(float *dst, const float *src0,
+                                        const float *src1, const float *win,
+                                        int len)
+{
+    x86_reg i = -len * 4;
+    x86_reg j =  len * 4 - 8;
+    __asm__ volatile (
+        "1:                             \n"
+        "pswapd (%5, %1), %%mm1         \n"
+        "movq   (%5, %0), %%mm0         \n"
+        "pswapd (%4, %1), %%mm5         \n"
+        "movq   (%3, %0), %%mm4         \n"
+        "movq      %%mm0, %%mm2         \n"
+        "movq      %%mm1, %%mm3         \n"
+        "pfmul     %%mm4, %%mm2         \n" // src0[len + i] * win[len + i]
+        "pfmul     %%mm5, %%mm3         \n" // src1[j]       * win[len + j]
+        "pfmul     %%mm4, %%mm1         \n" // src0[len + i] * win[len + j]
+        "pfmul     %%mm5, %%mm0         \n" // src1[j]       * win[len + i]
+        "pfadd     %%mm3, %%mm2         \n"
+        "pfsub     %%mm0, %%mm1         \n"
+        "pswapd    %%mm2, %%mm2         \n"
+        "movq      %%mm1, (%2, %0)      \n"
+        "movq      %%mm2, (%2, %1)      \n"
+        "sub          $8, %1            \n"
+        "add          $8, %0            \n"
+        "jl           1b                \n"
+        "femms                          \n"
+        : "+r"(i), "+r"(j)
+        : "r"(dst + len), "r"(src0 + len), "r"(src1), "r"(win + len)
+    );
+}
+
+static void vector_fmul_window_sse(float *dst, const float *src0,
+                                   const float *src1, const float *win, int len)
+{
+    x86_reg i = -len * 4;
+    x86_reg j =  len * 4 - 16;
+    __asm__ volatile (
+        "1:                             \n"
+        "movaps      (%5, %1), %%xmm1   \n"
+        "movaps      (%5, %0), %%xmm0   \n"
+        "movaps      (%4, %1), %%xmm5   \n"
+        "movaps      (%3, %0), %%xmm4   \n"
+        "shufps $0x1b, %%xmm1, %%xmm1   \n"
+        "shufps $0x1b, %%xmm5, %%xmm5   \n"
+        "movaps        %%xmm0, %%xmm2   \n"
+        "movaps        %%xmm1, %%xmm3   \n"
+        "mulps         %%xmm4, %%xmm2   \n" // src0[len + i] * win[len + i]
+        "mulps         %%xmm5, %%xmm3   \n" // src1[j]       * win[len + j]
+        "mulps         %%xmm4, %%xmm1   \n" // src0[len + i] * win[len + j]
+        "mulps         %%xmm5, %%xmm0   \n" // src1[j]       * win[len + i]
+        "addps         %%xmm3, %%xmm2   \n"
+        "subps         %%xmm0, %%xmm1   \n"
+        "shufps $0x1b, %%xmm2, %%xmm2   \n"
+        "movaps        %%xmm1, (%2, %0) \n"
+        "movaps        %%xmm2, (%2, %1) \n"
+        "sub              $16, %1       \n"
+        "add              $16, %0       \n"
+        "jl                1b           \n"
+        : "+r"(i), "+r"(j)
+        : "r"(dst + len), "r"(src0 + len), "r"(src1), "r"(win + len)
+    );
+}
+#endif /* HAVE_6REGS && HAVE_INLINE_ASM */
+
 void ff_float_dsp_init_x86(AVFloatDSPContext *fdsp)
 {
     int mm_flags = av_get_cpu_flags();
 
+#if HAVE_6REGS && HAVE_INLINE_ASM
+    if (INLINE_AMD3DNOWEXT(mm_flags)) {
+        fdsp->vector_fmul_window  = vector_fmul_window_3dnowext;
+    }
+    if (INLINE_SSE(mm_flags)) {
+        fdsp->vector_fmul_window = vector_fmul_window_sse;
+    }
+#endif
     if (EXTERNAL_SSE(mm_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;
+        fdsp->vector_fmul_add    = ff_vector_fmul_add_sse;
+        fdsp->vector_fmul_reverse = ff_vector_fmul_reverse_sse;
+        fdsp->scalarproduct_float = ff_scalarproduct_float_sse;
+    }
+    if (EXTERNAL_SSE2(mm_flags)) {
+        fdsp->vector_dmul_scalar = ff_vector_dmul_scalar_sse2;
     }
     if (EXTERNAL_AVX(mm_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;
+        fdsp->vector_fmul_add    = ff_vector_fmul_add_avx;
+        fdsp->vector_fmul_reverse = ff_vector_fmul_reverse_avx;
     }
 }
diff --git a/libavutil/x86/x86inc.asm b/libavutil/x86/x86inc.asm
index 6753195..068e3cf 100644
--- a/libavutil/x86/x86inc.asm
+++ b/libavutil/x86/x86inc.asm
@@ -34,8 +34,12 @@
 ; as this feature might be useful for others as well.  Send patches or ideas
 ; to x264-devel@videolan.org .
 
-%ifndef program_name
-    %define program_name x264
+%ifndef private_prefix
+    %define private_prefix x264
+%endif
+
+%ifndef public_prefix
+    %define public_prefix private_prefix
 %endif
 
 %define WIN64  0
@@ -130,7 +134,12 @@
 ; %1 = number of arguments. loads them from stack if needed.
 ; %2 = number of registers used. pushes callee-saved regs if needed.
 ; %3 = number of xmm registers used. pushes callee-saved xmm regs if needed.
-; %4 = list of names to define to registers
+; %4 = (optional) stack size to be allocated. If not aligned (x86-32 ICC 10.x,
+;      MSVC or YMM), the stack will be manually aligned (to 16 or 32 bytes),
+;      and an extra register will be allocated to hold the original stack
+;      pointer (to not invalidate r0m etc.). To prevent the use of an extra
+;      register as stack pointer, request a negative stack size.
+; %4+/%5+ = list of names to define to registers
 ; PROLOGUE can also be invoked by adding the same options to cglobal
 
 ; e.g.
@@ -166,10 +175,10 @@
         %define r%1m  %2d
         %define r%1mp %2
     %elif ARCH_X86_64 ; memory
-        %define r%1m [rSTK + stack_offset + %3]
+        %define r%1m [rstk + stack_offset + %3]
         %define r%1mp qword r %+ %1 %+ m
     %else
-        %define r%1m [rSTK + stack_offset + %3]
+        %define r%1m [rstk + stack_offset + %3]
         %define r%1mp dword r %+ %1 %+ m
     %endif
     %define r%1  %2
@@ -231,15 +240,15 @@
 
 %macro PUSH 1
     push %1
-    %ifidn rSTK, rsp
+    %ifidn rstk, rsp
         %assign stack_offset stack_offset+gprsize
     %endif
 %endmacro
 
 %macro POP 1
     pop %1
-    %ifidn rSTK, rsp
-       %assign stack_offset stack_offset-gprsize
+    %ifidn rstk, rsp
+        %assign stack_offset stack_offset-gprsize
     %endif
 %endmacro
 
@@ -272,19 +281,15 @@
 
 %macro SUB 2
     sub %1, %2
-    %ifidn %1, rsp
-        %ifidn rSTK, rsp
-            %assign stack_offset stack_offset+(%2)
-        %endif
+    %ifidn %1, rstk
+        %assign stack_offset stack_offset+(%2)
     %endif
 %endmacro
 
 %macro ADD 2
     add %1, %2
-    %ifidn %1, rsp
-        %ifidn rSTK, rsp
-            %assign stack_offset stack_offset-(%2)
-        %endif
+    %ifidn %1, rstk
+        %assign stack_offset stack_offset-(%2)
     %endif
 %endmacro
 
@@ -341,41 +346,76 @@
     %assign n_arg_names %0
 %endmacro
 
-%macro ALLOC_STACK 1-2 ; stack_size, n_xmm_regs (for win64 only)
-    ASSERT %1 > 0
-    %assign stack_size_alignment ((mmsize + 8) & ~8)
-    %assign stack_size_aligned (%1 + stack_size_alignment - 1) & ~(stack_size_alignment - 1)
-    %if %0 == 2
-        %assign xmm_regs_used %2
-    %else
-        %assign xmm_regs_used 0
+%macro ALLOC_STACK 1-2 0 ; stack_size, n_xmm_regs (for win64 only)
+    %ifnum %1
+        %if %1 != 0
+            %assign %%stack_alignment ((mmsize + 15) & ~15)
+            %assign stack_size %1
+            %if stack_size < 0
+                %assign stack_size -stack_size
+            %endif
+            %if mmsize != 8
+                %assign xmm_regs_used %2
+            %endif
+            %if mmsize <= 16 && HAVE_ALIGNED_STACK
+                %assign stack_size_padded stack_size + %%stack_alignment - gprsize - (stack_offset & (%%stack_alignment - 1))
+                %if xmm_regs_used > 6
+                    %assign stack_size_padded stack_size_padded + (xmm_regs_used - 6) * 16
+                %endif
+                SUB rsp, stack_size_padded
+            %else
+                %assign %%reg_num (regs_used - 1)
+                %xdefine rstk r %+ %%reg_num
+                ; align stack, and save original stack location directly above
+                ; it, i.e. in [rsp+stack_size_padded], so we can restore the
+                ; stack in a single instruction (i.e. mov rsp, rstk or mov
+                ; rsp, [rsp+stack_size_padded])
+                mov  rstk, rsp
+                %assign stack_size_padded stack_size
+                %if xmm_regs_used > 6
+                    %assign stack_size_padded stack_size_padded + (xmm_regs_used - 6) * 16
+                    %if mmsize == 32 && xmm_regs_used & 1
+                        ; re-align to 32 bytes
+                        %assign stack_size_padded (stack_size_padded + 16)
+                    %endif
+                %endif
+                %if %1 < 0 ; need to store rsp on stack
+                    sub  rsp, gprsize+stack_size_padded
+                    and  rsp, ~(%%stack_alignment-1)
+                    %xdefine rstkm [rsp+stack_size_padded]
+                    mov rstkm, rstk
+                %else ; can keep rsp in rstk during whole function
+                    sub  rsp, stack_size_padded
+                    and  rsp, ~(%%stack_alignment-1)
+                    %xdefine rstkm rstk
+                %endif
+            %endif
+            %if xmm_regs_used > 6
+                WIN64_PUSH_XMM
+            %endif
+        %endif
     %endif
-    %if mmsize <= 16 && HAVE_ALIGNED_STACK
-        %assign stack_size_padded stack_size_aligned + stack_size_alignment - gprsize - (stack_offset & (stack_size_alignment - 1))
-        %if xmm_regs_used > 6
-            %assign stack_size_padded stack_size_padded + (xmm_regs_used - 6) * 16
+%endmacro
+
+%macro SETUP_STACK_POINTER 1
+    %ifnum %1
+        %if %1 != 0 && (HAVE_ALIGNED_STACK == 0 || mmsize == 32)
+            %if %1 > 0
+                %assign regs_used (regs_used + 1)
+            %elif ARCH_X86_64 && regs_used == num_args && num_args <= 4 + UNIX64 * 2
+                %warning "Stack pointer will overwrite register argument"
+            %endif
         %endif
-        SUB rsp, stack_size_padded
-        %if xmm_regs_used > 6
-            WIN64_PUSH_XMM
-        %endif
-    %else
-        %assign reg_num (regs_used - 1)
-        %xdefine rSTK r %+ reg_num
-        ; align stack, and save original stack location directly above it, i.e.
-        ; in [rsp+stack_size_padded], so we can restore the stack in a single
-        ; instruction (i.e. mov rsp, [rsp+stack_size_padded])
-        mov  rSTK, rsp
-        %assign stack_size_padded stack_size_aligned
-        %if xmm_regs_used > 6
-            %assign stack_size_padded stack_size_padded + (xmm_regs_used - 6) * 16
-        %endif
-        sub  rsp, gprsize+stack_size_padded
-        and  rsp, ~(stack_size_alignment-1)
-        mov [rsp+stack_size_padded], rSTK
-        %if xmm_regs_used > 6
-            WIN64_PUSH_XMM
-        %endif
+    %endif
+%endmacro
+
+%macro DEFINE_ARGS_INTERNAL 3+
+    %ifnum %2
+        DEFINE_ARGS %3
+    %elif %1 == 4
+        DEFINE_ARGS %2
+    %elif %1 > 4
+        DEFINE_ARGS %2, %3
     %endif
 %endmacro
 
@@ -397,36 +437,26 @@
 DECLARE_REG 13, R14, 112
 DECLARE_REG 14, R15, 120
 
-%macro PROLOGUE 2-5+ 0 ; #args, #regs, #xmm_regs, arg_names...
+%macro PROLOGUE 2-5+ 0 ; #args, #regs, #xmm_regs, [stack_size,] arg_names...
     %assign num_args %1
     %assign regs_used %2
     ASSERT regs_used >= num_args
+    SETUP_STACK_POINTER %4
     ASSERT regs_used <= 15
     PUSH_IF_USED 7, 8, 9, 10, 11, 12, 13, 14
-    %assign xmm_regs_used 0
-    %ifnum %4
-        %if %4 > 0
-            ALLOC_STACK %4, %3
-        %endif
-    %endif
-    %if mmsize != 8 && stack_size_aligned == 0
+    ALLOC_STACK %4, %3
+    %if mmsize != 8 && stack_size == 0
         WIN64_SPILL_XMM %3
     %endif
     LOAD_IF_USED 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
-    %ifnum %4
-        DEFINE_ARGS %5
-    %elif %0 == 4
-        DEFINE_ARGS %4
-    %elif %0 > 4
-        DEFINE_ARGS %4, %5
-    %endif
+    DEFINE_ARGS_INTERNAL %0, %4, %5
 %endmacro
 
 %macro WIN64_PUSH_XMM 0
     %assign %%i xmm_regs_used
     %rep (xmm_regs_used-6)
         %assign %%i %%i-1
-        movdqa [rsp + (%%i-6)*16 + stack_size_aligned], xmm %+ %%i
+        movdqa [rsp + (%%i-6)*16 + stack_size + (~stack_offset&8)], xmm %+ %%i
     %endrep
 %endmacro
 
@@ -434,8 +464,7 @@
     %assign xmm_regs_used %1
     ASSERT xmm_regs_used <= 16
     %if xmm_regs_used > 6
-        %assign stack_size_padded (xmm_regs_used-6)*16+16-gprsize-(stack_offset&15)
-        SUB rsp, stack_size_padded
+        SUB rsp, (xmm_regs_used-6)*16+16
         WIN64_PUSH_XMM
     %endif
 %endmacro
@@ -445,12 +474,15 @@
         %assign %%i xmm_regs_used
         %rep (xmm_regs_used-6)
             %assign %%i %%i-1
-            movdqa xmm %+ %%i, [%1 + (%%i-6)*16+stack_size_aligned]
+            movdqa xmm %+ %%i, [%1 + (%%i-6)*16+stack_size+(~stack_offset&8)]
         %endrep
+        %if stack_size_padded == 0
+            add %1, (xmm_regs_used-6)*16+16
+        %endif
     %endif
     %if stack_size_padded > 0
-        %if stack_size_aligned != 0 && (mmsize == 32 || HAVE_ALIGNED_STACK == 0)
-            mov rsp, [rsp+stack_size_padded]
+        %if stack_size > 0 && (mmsize == 32 || HAVE_ALIGNED_STACK == 0)
+            mov rsp, rstkm
         %else
             add %1, stack_size_padded
         %endif
@@ -463,7 +495,7 @@
     %assign xmm_regs_used 0
 %endmacro
 
-%define has_epilogue regs_used > 7 || xmm_regs_used > 6 || mmsize == 32 || stack_size_aligned > 0
+%define has_epilogue regs_used > 7 || xmm_regs_used > 6 || mmsize == 32 || stack_size > 0
 
 %macro RET 0
     WIN64_RESTORE_XMM_INTERNAL rsp
@@ -492,33 +524,24 @@
 DECLARE_REG 13, R14, 64
 DECLARE_REG 14, R15, 72
 
-%macro PROLOGUE 2-5+ ; #args, #regs, #xmm_regs, arg_names...
+%macro PROLOGUE 2-5+ ; #args, #regs, #xmm_regs, [stack_size,] arg_names...
     %assign num_args %1
     %assign regs_used %2
     ASSERT regs_used >= num_args
+    SETUP_STACK_POINTER %4
     ASSERT regs_used <= 15
     PUSH_IF_USED 9, 10, 11, 12, 13, 14
-    %ifnum %4
-        %if %4 > 0
-            ALLOC_STACK %4
-        %endif
-    %endif
+    ALLOC_STACK %4
     LOAD_IF_USED 6, 7, 8, 9, 10, 11, 12, 13, 14
-    %ifnum %4
-        DEFINE_ARGS %5
-    %elif %0 == 4
-        DEFINE_ARGS %4
-    %elif %0 > 4
-        DEFINE_ARGS %4, %5
-    %endif
+    DEFINE_ARGS_INTERNAL %0, %4, %5
 %endmacro
 
-%define has_epilogue regs_used > 9 || mmsize == 32 || stack_size_aligned > 0
+%define has_epilogue regs_used > 9 || mmsize == 32 || stack_size > 0
 
 %macro RET 0
 %if stack_size_padded > 0
 %if mmsize == 32 || HAVE_ALIGNED_STACK == 0
-    mov rsp, [rsp+stack_size_padded]
+    mov rsp, rstkm
 %else
     add rsp, stack_size_padded
 %endif
@@ -543,7 +566,7 @@
 
 %macro DECLARE_ARG 1-*
     %rep %0
-        %define r%1m [rSTK + stack_offset + 4*%1 + 4]
+        %define r%1m [rstk + stack_offset + 4*%1 + 4]
         %define r%1mp dword r%1m
         %rotate 1
     %endrep
@@ -551,38 +574,30 @@
 
 DECLARE_ARG 7, 8, 9, 10, 11, 12, 13, 14
 
-%macro PROLOGUE 2-5+ ; #args, #regs, #xmm_regs, arg_names...
+%macro PROLOGUE 2-5+ ; #args, #regs, #xmm_regs, [stack_size,] arg_names...
     %assign num_args %1
     %assign regs_used %2
+    ASSERT regs_used >= num_args
     %if num_args > 7
         %assign num_args 7
     %endif
     %if regs_used > 7
         %assign regs_used 7
     %endif
-    ASSERT regs_used >= num_args
+    SETUP_STACK_POINTER %4
+    ASSERT regs_used <= 7
     PUSH_IF_USED 3, 4, 5, 6
-    %ifnum %4
-        %if %4 > 0
-            ALLOC_STACK %4
-        %endif
-    %endif
+    ALLOC_STACK %4
     LOAD_IF_USED 0, 1, 2, 3, 4, 5, 6
-    %ifnum %4
-        DEFINE_ARGS %5
-    %elif %0 == 4
-        DEFINE_ARGS %4
-    %elif %0 > 4
-        DEFINE_ARGS %4, %5
-    %endif
+    DEFINE_ARGS_INTERNAL %0, %4, %5
 %endmacro
 
-%define has_epilogue regs_used > 3 || mmsize == 32 || stack_size_aligned > 0
+%define has_epilogue regs_used > 3 || mmsize == 32 || stack_size > 0
 
 %macro RET 0
 %if stack_size_padded > 0
 %if mmsize == 32 || HAVE_ALIGNED_STACK == 0
-    mov rsp, [rsp+stack_size_padded]
+    mov rsp, rstkm
 %else
     add rsp, stack_size_padded
 %endif
@@ -601,6 +616,8 @@
 %endmacro
 %macro WIN64_RESTORE_XMM 1
 %endmacro
+%macro WIN64_PUSH_XMM 0
+%endmacro
 %endif
 
 %macro REP_RET 0
@@ -630,35 +647,48 @@
 ; Applies any symbol mangling needed for C linkage, and sets up a define such that
 ; subsequent uses of the function name automatically refer to the mangled version.
 ; Appends cpuflags to the function name if cpuflags has been specified.
+; The "" empty default parameter is a workaround for nasm, which fails if SUFFIX
+; is empty and we call cglobal_internal with just %1 %+ SUFFIX (without %2).
 %macro cglobal 1-2+ "" ; name, [PROLOGUE args]
-    cglobal_internal %1 %+ SUFFIX, %2
+    cglobal_internal 1, %1 %+ SUFFIX, %2
 %endmacro
-%macro cglobal_internal 1-2+
-    %ifndef cglobaled_%1
-        %xdefine %1 mangle(program_name %+ _ %+ %1)
-        %xdefine %1.skip_prologue %1 %+ .skip_prologue
-        CAT_XDEFINE cglobaled_, %1, 1
-    %endif
-    %xdefine current_function %1
-    %ifidn __OUTPUT_FORMAT__,elf
-        global %1:function hidden
+%macro cvisible 1-2+ "" ; name, [PROLOGUE args]
+    cglobal_internal 0, %1 %+ SUFFIX, %2
+%endmacro
+%macro cglobal_internal 2-3+
+    %if %1
+        %xdefine %%FUNCTION_PREFIX private_prefix
+        %xdefine %%VISIBILITY hidden
     %else
-        global %1
+        %xdefine %%FUNCTION_PREFIX public_prefix
+        %xdefine %%VISIBILITY
+    %endif
+    %ifndef cglobaled_%2
+        %xdefine %2 mangle(%%FUNCTION_PREFIX %+ _ %+ %2)
+        %xdefine %2.skip_prologue %2 %+ .skip_prologue
+        CAT_XDEFINE cglobaled_, %2, 1
+    %endif
+    %xdefine current_function %2
+    %ifidn __OUTPUT_FORMAT__,elf
+        global %2:function %%VISIBILITY
+    %else
+        global %2
     %endif
     align function_align
-    %1:
+    %2:
     RESET_MM_PERMUTATION ; not really needed, but makes disassembly somewhat nicer
-    %xdefine rSTK rsp
+    %xdefine rstk rsp
     %assign stack_offset 0
-    %assign stack_size_aligned 0
+    %assign stack_size 0
     %assign stack_size_padded 0
-    %ifnidn %2, ""
-        PROLOGUE %2
+    %assign xmm_regs_used 0
+    %ifnidn %3, ""
+        PROLOGUE %3
     %endif
 %endmacro
 
 %macro cextern 1
-    %xdefine %1 mangle(program_name %+ _ %+ %1)
+    %xdefine %1 mangle(private_prefix %+ _ %+ %1)
     CAT_XDEFINE cglobaled_, %1, 1
     extern %1
 %endmacro
@@ -671,7 +701,7 @@
 %endmacro
 
 %macro const 2+
-    %xdefine %1 mangle(program_name %+ _ %+ %1)
+    %xdefine %1 mangle(private_prefix %+ _ %+ %1)
     global %1
     %1: %2
 %endmacro
@@ -1089,6 +1119,7 @@
 AVX_INSTR cmpsd, 1, 0, 0
 AVX_INSTR cmpss, 1, 0, 0
 AVX_INSTR cvtdq2ps, 1, 0, 0
+AVX_INSTR cvtpd2dq, 1, 0, 0
 AVX_INSTR cvtps2dq, 1, 0, 0
 AVX_INSTR divpd, 1, 0, 0
 AVX_INSTR divps, 1, 0, 0
diff --git a/libavutil/x86/x86util.asm b/libavutil/x86/x86util.asm
index c11df90..8908444 100644
--- a/libavutil/x86/x86util.asm
+++ b/libavutil/x86/x86util.asm
@@ -23,7 +23,8 @@
 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 ;******************************************************************************
 
-%define program_name ff
+%define private_prefix ff
+%define public_prefix  avpriv
 %define cpuflags_mmxext cpuflags_mmx2
 
 %include "libavutil/x86/x86inc.asm"
@@ -172,14 +173,33 @@
     psignw     %1, %2
 %endmacro
 
-%macro ABS1_MMX 2    ; a, tmp
+%macro ABS1 2
+%if cpuflag(ssse3)
+    pabsw   %1, %1
+%elif cpuflag(mmxext) ; a, tmp
+    pxor    %2, %2
+    psubw   %2, %1
+    pmaxsw  %1, %2
+%else ; a, tmp
     pxor       %2, %2
     pcmpgtw    %2, %1
     pxor       %1, %2
     psubw      %1, %2
+%endif
 %endmacro
 
-%macro ABS2_MMX 4    ; a, b, tmp0, tmp1
+%macro ABS2 4
+%if cpuflag(ssse3)
+    pabsw   %1, %1
+    pabsw   %2, %2
+%elif cpuflag(mmxext) ; a, b, tmp0, tmp1
+    pxor    %3, %3
+    pxor    %4, %4
+    psubw   %3, %1
+    psubw   %4, %2
+    pmaxsw  %1, %3
+    pmaxsw  %2, %4
+%else ; a, b, tmp0, tmp1
     pxor       %3, %3
     pxor       %4, %4
     pcmpgtw    %3, %1
@@ -188,45 +208,31 @@
     pxor       %2, %4
     psubw      %1, %3
     psubw      %2, %4
+%endif
 %endmacro
 
-%macro ABS1_MMXEXT 2 ; a, tmp
-    pxor    %2, %2
-    psubw   %2, %1
-    pmaxsw  %1, %2
-%endmacro
-
-%macro ABS2_MMXEXT 4 ; a, b, tmp0, tmp1
-    pxor    %3, %3
-    pxor    %4, %4
-    psubw   %3, %1
-    psubw   %4, %2
-    pmaxsw  %1, %3
-    pmaxsw  %2, %4
-%endmacro
-
-%macro ABS1_SSSE3 2
-    pabsw   %1, %1
-%endmacro
-
-%macro ABS2_SSSE3 4
-    pabsw   %1, %1
-    pabsw   %2, %2
-%endmacro
-
-%macro ABSB_MMX 2
+%macro ABSB 2 ; source mmreg, temp mmreg (unused for ssse3)
+%if cpuflag(ssse3)
+    pabsb   %1, %1
+%else
     pxor    %2, %2
     psubb   %2, %1
     pminub  %1, %2
+%endif
 %endmacro
 
-%macro ABSB2_MMX 4
+%macro ABSB2 4 ; src1, src2, tmp1, tmp2 (tmp1/2 unused for SSSE3)
+%if cpuflag(ssse3)
+    pabsb   %1, %1
+    pabsb   %2, %2
+%else
     pxor    %3, %3
     pxor    %4, %4
     psubb   %3, %1
     psubb   %4, %2
     pminub  %1, %3
     pminub  %2, %4
+%endif
 %endmacro
 
 %macro ABSD2_MMX 4
@@ -240,25 +246,11 @@
     psubd   %2, %4
 %endmacro
 
-%macro ABSB_SSSE3 2
-    pabsb   %1, %1
-%endmacro
-
-%macro ABSB2_SSSE3 4
-    pabsb   %1, %1
-    pabsb   %2, %2
-%endmacro
-
 %macro ABS4 6
     ABS2 %1, %2, %5, %6
     ABS2 %3, %4, %5, %6
 %endmacro
 
-%define ABS1 ABS1_MMX
-%define ABS2 ABS2_MMX
-%define ABSB ABSB_MMX
-%define ABSB2 ABSB2_MMX
-
 %macro SPLATB_LOAD 3
 %if cpuflag(ssse3)
     movd      %1, [%2-3]
@@ -310,6 +302,14 @@
 %endif
 %endmacro
 
+%macro PAVGB 2
+%if cpuflag(mmxext)
+    pavgb   %1, %2
+%elif cpuflag(3dnow)
+    pavgusb %1, %2
+%endif
+%endmacro
+
 %macro PSHUFLW 1+
     %if mmsize == 8
         pshufw %1
@@ -631,6 +631,17 @@
 %endif
 %endmacro
 
+%macro VBROADCASTSD 2 ; dst xmm/ymm, src m64
+%if cpuflag(avx) && mmsize == 32
+    vbroadcastsd %1, %2
+%elif cpuflag(sse3)
+    movddup      %1, %2
+%else ; sse2
+    movsd        %1, %2
+    movlhps      %1, %1
+%endif
+%endmacro
+
 %macro SHUFFLE_MASK_W 8
     %rep 8
         %if %1>=0x80
diff --git a/libavutil/xtea.c b/libavutil/xtea.c
index 28780fb..e729c91 100644
--- a/libavutil/xtea.c
+++ b/libavutil/xtea.c
@@ -39,10 +39,12 @@
                            int decrypt, uint8_t *iv)
 {
     uint32_t v0, v1;
+#if !CONFIG_SMALL
     uint32_t k0 = ctx->key[0];
     uint32_t k1 = ctx->key[1];
     uint32_t k2 = ctx->key[2];
     uint32_t k3 = ctx->key[3];
+#endif
 
     v0 = AV_RB32(src);
     v1 = AV_RB32(src + 4);
@@ -183,7 +185,6 @@
 
 #ifdef TEST
 #include <stdio.h>
-#undef printf
 
 #define XTEA_NUM_TESTS 6
 
@@ -220,7 +221,6 @@
     { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }
 };
 
-#undef exit
 static void test_xtea(AVXTEA *ctx, uint8_t *dst, const uint8_t *src,
                       const uint8_t *ref, int len, uint8_t *iv, int dir,
                       const char *test)
diff --git a/libpostproc/postprocess.c b/libpostproc/postprocess.c
index afe3f13..facfd2c 100644
--- a/libpostproc/postprocess.c
+++ b/libpostproc/postprocess.c
@@ -381,11 +381,10 @@
 static inline void horizX1Filter(uint8_t *src, int stride, int QP)
 {
     int y;
-    static uint64_t *lut= NULL;
-    if(lut==NULL)
+    static uint64_t lut[256];
+    if(!lut[255])
     {
         int i;
-        lut = av_malloc(256*8);
         for(i=0; i<256; i++)
         {
             int v= i < 128 ? 2*i : 2*(i-256);
@@ -618,11 +617,7 @@
 
 /* -pp Command line Help
 */
-#if LIBPOSTPROC_VERSION_INT < (52<<16)
-const char *const pp_help=
-#else
 const char pp_help[] =
-#endif
 "Available postprocessing filters:\n"
 "Filters                        Options\n"
 "short  long name       short   long option     Description\n"
@@ -872,7 +867,7 @@
     c->stride= stride;
     c->qpStride= qpStride;
 
-    reallocAlign((void **)&c->tempDst, 8, stride*24);
+    reallocAlign((void **)&c->tempDst, 8, stride*24+32);
     reallocAlign((void **)&c->tempSrc, 8, stride*24);
     reallocAlign((void **)&c->tempBlocks, 8, 2*16*8);
     reallocAlign((void **)&c->yHistogram, 8, 256*sizeof(uint64_t));
diff --git a/libpostproc/postprocess.h b/libpostproc/postprocess.h
index b1a357a..928e01f 100644
--- a/libpostproc/postprocess.h
+++ b/libpostproc/postprocess.h
@@ -23,8 +23,13 @@
 
 /**
  * @file
- * @brief
- *     external postprocessing API
+ * @ingroup lpp
+ * external API header
+ */
+
+/**
+ * @defgroup lpp Libpostproc
+ * @{
  */
 
 #include "libpostproc/version.h"
@@ -94,4 +99,8 @@
 
 #define PP_PICT_TYPE_QP2  0x00000010 ///< MPEG2 style QScale
 
+/**
+ * @}
+ */
+
 #endif /* POSTPROC_POSTPROCESS_H */
diff --git a/libpostproc/postprocess_template.c b/libpostproc/postprocess_template.c
index 0b77545..ad0404f 100644
--- a/libpostproc/postprocess_template.c
+++ b/libpostproc/postprocess_template.c
@@ -128,7 +128,7 @@
         "movq %%mm0, %%mm4                      \n\t"
         PMAXUB(%%mm1, %%mm4)
         PMINUB(%%mm1, %%mm3, %%mm5)
-        "psubb %%mm1, %%mm0                     \n\t" // mm0 = differnece
+        "psubb %%mm1, %%mm0                     \n\t" // mm0 = difference
         "paddb %%mm7, %%mm0                     \n\t"
         "pcmpgtb %%mm6, %%mm0                   \n\t"
 
@@ -1089,7 +1089,7 @@
 #if !TEMPLATE_PP_ALTIVEC
 static inline void RENAME(dering)(uint8_t src[], int stride, PPContext *c)
 {
-#if TEMPLATE_PP_MMXEXT || TEMPLATE_PP_3DNOW
+#if HAVE_7REGS && (TEMPLATE_PP_MMXEXT || TEMPLATE_PP_3DNOW)
     DECLARE_ALIGNED(8, uint64_t, tmp)[3];
     __asm__ volatile(
         "pxor %%mm6, %%mm6                      \n\t"
@@ -1315,7 +1315,7 @@
         : : "r" (src), "r" ((x86_reg)stride), "m" (c->pQPb), "m"(c->pQPb2), "q"(tmp)
         : "%"REG_a, "%"REG_d
     );
-#else //TEMPLATE_PP_MMXEXT || TEMPLATE_PP_3DNOW
+#else // HAVE_7REGS && (TEMPLATE_PP_MMXEXT || TEMPLATE_PP_3DNOW)
     int y;
     int min=255;
     int max=0;
@@ -1324,6 +1324,7 @@
     int s[10];
     const int QP2= c->QP/2 + 1;
 
+    src --;
     for(y=1; y<9; y++){
         int x;
         p= src + stride*y;
@@ -2558,7 +2559,7 @@
         "movq (%%"REG_a"), %%mm1                \n\t"
         "movq %%mm1, %%mm3                      \n\t"
         "movq %%mm1, %%mm4                      \n\t"
-        "psubb %%mm1, %%mm0                     \n\t" // mm0 = differnece
+        "psubb %%mm1, %%mm0                     \n\t" // mm0 = difference
         "paddb %%mm7, %%mm0                     \n\t"
         "pcmpgtb %%mm6, %%mm0                   \n\t"
 
@@ -3077,7 +3078,7 @@
 
 /**
  * Copy a block from src to dst and fixes the blacklevel.
- * levelFix == 0 -> do not touch the brighness & contrast
+ * levelFix == 0 -> do not touch the brightness & contrast
  */
 #undef REAL_SCALED_CPY
 #undef SCALED_CPY
@@ -3259,7 +3260,7 @@
     //FIXME remove
     uint64_t * const yHistogram= c.yHistogram;
     uint8_t * const tempSrc= srcStride > 0 ? c.tempSrc : c.tempSrc - 23*srcStride;
-    uint8_t * const tempDst= dstStride > 0 ? c.tempDst : c.tempDst - 23*dstStride;
+    uint8_t * const tempDst= (dstStride > 0 ? c.tempDst : c.tempDst - 23*dstStride) + 32;
     //const int mbWidth= isColor ? (width+7)>>3 : (width+15)>>4;
 
 #if TEMPLATE_PP_MMX
@@ -3350,7 +3351,7 @@
 
         // From this point on it is guaranteed that we can read and write 16 lines downward
         // finish 1 block before the next otherwise we might have a problem
-        // with the L1 Cache of the P4 ... or only a few blocks at a time or soemthing
+        // with the L1 Cache of the P4 ... or only a few blocks at a time or something
         for(x=0; x<width; x+=BLOCK_SIZE){
 
 #if TEMPLATE_PP_MMXEXT
@@ -3459,7 +3460,7 @@
 
         // From this point on it is guaranteed that we can read and write 16 lines downward
         // finish 1 block before the next otherwise we might have a problem
-        // with the L1 Cache of the P4 ... or only a few blocks at a time or soemthing
+        // with the L1 Cache of the P4 ... or only a few blocks at a time or something
         for(x=0; x<width; x+=BLOCK_SIZE){
             const int stride= dstStride;
 #if TEMPLATE_PP_MMX
diff --git a/libpostproc/version.h b/libpostproc/version.h
index 35e1772..d0d3d43 100644
--- a/libpostproc/version.h
+++ b/libpostproc/version.h
@@ -28,11 +28,9 @@
 
 #include "libavutil/avutil.h"
 
-#ifndef LIBPOSTPROC_VERSION_MAJOR
 #define LIBPOSTPROC_VERSION_MAJOR 52
 #define LIBPOSTPROC_VERSION_MINOR  2
 #define LIBPOSTPROC_VERSION_MICRO 100
-#endif
 
 #define LIBPOSTPROC_VERSION_INT AV_VERSION_INT(LIBPOSTPROC_VERSION_MAJOR, \
                                                LIBPOSTPROC_VERSION_MINOR, \
diff --git a/library.mak b/library.mak
index 470795c..e849cc2 100644
--- a/library.mak
+++ b/library.mak
@@ -4,6 +4,7 @@
 
 LIBVERSION := $(lib$(NAME)_VERSION)
 LIBMAJOR   := $(lib$(NAME)_VERSION_MAJOR)
+LIBMINOR   := $(lib$(NAME)_VERSION_MINOR)
 INCINSTDIR := $(INCDIR)/lib$(NAME)
 
 INSTHEADERS := $(INSTHEADERS) $(HEADERS:%=$(SUBDIR)%)
@@ -62,7 +63,7 @@
 
 clean::
 	$(RM) $(addprefix $(SUBDIR),*-example$(EXESUF) *-test$(EXESUF) $(CLEANFILES) $(CLEANSUFFIXES) $(LIBSUFFIXES)) \
-	    $(CLEANSUFFIXES:%=$(SUBDIR)$(ARCH)/%) $(HOSTOBJS) $(HOSTPROGS)
+	    $(CLEANSUFFIXES:%=$(SUBDIR)$(ARCH)/%)
 
 distclean:: clean
 	$(RM) $(DISTCLEANSUFFIXES:%=$(SUBDIR)%) $(DISTCLEANSUFFIXES:%=$(SUBDIR)$(ARCH)/%)
@@ -71,7 +72,7 @@
 	$(Q)mkdir -p "$(SHLIBDIR)"
 	$$(INSTALL) -m 755 $$< "$(SHLIBDIR)/$(SLIB_INSTALL_NAME)"
 	$$(STRIP) "$(SHLIBDIR)/$(SLIB_INSTALL_NAME)"
-	$(Q)$(foreach F,$(SLIB_INSTALL_LINKS),cd "$(SHLIBDIR)" && $(LN_S) $(SLIB_INSTALL_NAME) $(F);)
+	$(Q)$(foreach F,$(SLIB_INSTALL_LINKS),(cd "$(SHLIBDIR)" && $(LN_S) $(SLIB_INSTALL_NAME) $(F));)
 	$(if $(SLIB_INSTALL_EXTRA_SHLIB),$$(INSTALL) -m 644 $(SLIB_INSTALL_EXTRA_SHLIB:%=$(SUBDIR)%) "$(SHLIBDIR)")
 	$(if $(SLIB_INSTALL_EXTRA_LIB),$(Q)mkdir -p "$(LIBDIR)")
 	$(if $(SLIB_INSTALL_EXTRA_LIB),$$(INSTALL) -m 644 $(SLIB_INSTALL_EXTRA_LIB:%=$(SUBDIR)%) "$(LIBDIR)")
@@ -85,7 +86,7 @@
 	$(Q)mkdir -p "$(INCINSTDIR)"
 	$$(INSTALL) -m 644 $$^ "$(INCINSTDIR)"
 
-install-lib$(NAME)-pkgconfig: $(SUBDIR)lib$(NAME).pc
+install-lib$(NAME)-pkgconfig: $(SUBDIR)lib$(FULLNAME).pc
 	$(Q)mkdir -p "$(LIBDIR)/pkgconfig"
 	$$(INSTALL) -m 644 $$^ "$(LIBDIR)/pkgconfig"
 
@@ -99,7 +100,7 @@
 
 uninstall-headers::
 	$(RM) $(addprefix "$(INCINSTDIR)/",$(HEADERS) $(BUILT_HEADERS))
-	$(RM) "$(LIBDIR)/pkgconfig/lib$(NAME).pc"
+	$(RM) "$(LIBDIR)/pkgconfig/lib$(FULLNAME).pc"
 	-rmdir "$(INCINSTDIR)"
 endef
 
diff --git a/libswresample/Makefile b/libswresample/Makefile
index 4c3ec1c..9d9f10c 100644
--- a/libswresample/Makefile
+++ b/libswresample/Makefile
@@ -13,4 +13,6 @@
        resample.o                            \
        swresample.o                          \
 
+OBJS-$(CONFIG_LIBSOXR) += soxr_resample.o
+
 TESTPROGS = swresample
diff --git a/libswresample/arm/audio_convert_init.c b/libswresample/arm/audio_convert_init.c
index 9fdb174..ec9e62e 100644
--- a/libswresample/arm/audio_convert_init.c
+++ b/libswresample/arm/audio_convert_init.c
@@ -61,5 +61,7 @@
             ac->simd_f = conv_fltp_to_s16_2ch_neon;
         if(out_fmt == AV_SAMPLE_FMT_S16 && in_fmt == AV_SAMPLE_FMT_FLTP && channels >  2)
             ac->simd_f = conv_fltp_to_s16_nch_neon;
+        if(ac->simd_f)
+            ac->in_simd_align_mask = ac->out_simd_align_mask = 15;
     }
 }
diff --git a/libswresample/audioconvert.c b/libswresample/audioconvert.c
index d2e3722..4ba0ff1 100644
--- a/libswresample/audioconvert.c
+++ b/libswresample/audioconvert.c
@@ -170,12 +170,28 @@
     int ch;
     int off=0;
     const int os= (out->planar ? 1 :out->ch_count) *out->bps;
+    unsigned misaligned = 0;
 
     av_assert0(ctx->channels == out->ch_count);
 
+    if (ctx->in_simd_align_mask) {
+        int planes = in->planar ? in->ch_count : 1;
+        unsigned m = 0;
+        for (ch = 0; ch < planes; ch++)
+            m |= (intptr_t)in->ch[ch];
+        misaligned |= m & ctx->in_simd_align_mask;
+    }
+    if (ctx->out_simd_align_mask) {
+        int planes = out->planar ? out->ch_count : 1;
+        unsigned m = 0;
+        for (ch = 0; ch < planes; ch++)
+            m |= (intptr_t)out->ch[ch];
+        misaligned |= m & ctx->out_simd_align_mask;
+    }
+
     //FIXME optimize common cases
 
-    if(ctx->simd_f && !ctx->ch_map){
+    if(ctx->simd_f && !ctx->ch_map && !misaligned){
         off = len&~15;
         av_assert1(off>=0);
         av_assert1(off<=len);
diff --git a/libswresample/audioconvert.h b/libswresample/audioconvert.h
index d8af003..2e983df 100644
--- a/libswresample/audioconvert.h
+++ b/libswresample/audioconvert.h
@@ -38,6 +38,8 @@
 
 typedef struct AudioConvert {
     int channels;
+    int  in_simd_align_mask;
+    int out_simd_align_mask;
     conv_func_type *conv_f;
     simd_func_type *simd_f;
     const int *ch_map;
diff --git a/libswresample/dither.c b/libswresample/dither.c
index 79113f4..d0193dd 100644
--- a/libswresample/dither.c
+++ b/libswresample/dither.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Michael Niedermayer (michaelni@gmx.at)
+ * Copyright (C) 2012-2013 Michael Niedermayer (michaelni@gmx.at)
  *
  * This file is part of libswresample
  *
@@ -21,12 +21,65 @@
 #include "libavutil/avassert.h"
 #include "swresample_internal.h"
 
-void swri_get_dither(SwrContext *s, void *dst, int len, unsigned seed, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt) {
-    double scale = 0;
+#include "noise_shaping_data.c"
+
+void swri_get_dither(SwrContext *s, void *dst, int len, unsigned seed, enum AVSampleFormat noise_fmt) {
+    double scale = s->dither.noise_scale;
 #define TMP_EXTRA 2
     double *tmp = av_malloc((len + TMP_EXTRA) * sizeof(double));
     int i;
 
+    for(i=0; i<len + TMP_EXTRA; i++){
+        double v;
+        seed = seed* 1664525 + 1013904223;
+
+        switch(s->dither.method){
+            case SWR_DITHER_RECTANGULAR: v= ((double)seed) / UINT_MAX - 0.5; break;
+            default:
+                av_assert0(s->dither.method < SWR_DITHER_NB);
+                v = ((double)seed) / UINT_MAX;
+                seed = seed*1664525 + 1013904223;
+                v-= ((double)seed) / UINT_MAX;
+                break;
+        }
+        tmp[i] = v;
+    }
+
+    for(i=0; i<len; i++){
+        double v;
+
+        switch(s->dither.method){
+            default:
+                av_assert0(s->dither.method < SWR_DITHER_NB);
+                v = tmp[i];
+                break;
+            case SWR_DITHER_TRIANGULAR_HIGHPASS :
+                v = (- tmp[i] + 2*tmp[i+1] - tmp[i+2]) / sqrt(6);
+                break;
+        }
+
+        v*= scale;
+
+        switch(noise_fmt){
+            case AV_SAMPLE_FMT_S16P: ((int16_t*)dst)[i] = v; break;
+            case AV_SAMPLE_FMT_S32P: ((int32_t*)dst)[i] = v; break;
+            case AV_SAMPLE_FMT_FLTP: ((float  *)dst)[i] = v; break;
+            case AV_SAMPLE_FMT_DBLP: ((double *)dst)[i] = v; break;
+            default: av_assert0(0);
+        }
+    }
+
+    av_free(tmp);
+}
+
+int swri_dither_init(SwrContext *s, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt)
+{
+    int i;
+    double scale = 0;
+
+    if (s->dither.method > SWR_DITHER_TRIANGULAR_HIGHPASS && s->dither.method <= SWR_DITHER_NS)
+        return AVERROR(EINVAL);
+
     out_fmt = av_get_packed_sample_fmt(out_fmt);
     in_fmt  = av_get_packed_sample_fmt( in_fmt);
 
@@ -39,49 +92,56 @@
     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;
 
-    scale *= s->dither_scale;
+    scale *= s->dither.scale;
 
-    for(i=0; i<len + TMP_EXTRA; i++){
-        double v;
-        seed = seed* 1664525 + 1013904223;
+    if (out_fmt == AV_SAMPLE_FMT_S32 && s->dither.output_sample_bits)
+        scale *= 1<<(32-s->dither.output_sample_bits);
 
-        switch(s->dither_method){
-            case SWR_DITHER_RECTANGULAR: v= ((double)seed) / UINT_MAX - 0.5; break;
-            case SWR_DITHER_TRIANGULAR :
-            case SWR_DITHER_TRIANGULAR_HIGHPASS :
-                v = ((double)seed) / UINT_MAX;
-                seed = seed*1664525 + 1013904223;
-                v-= ((double)seed) / UINT_MAX;
-                break;
-            default: av_assert0(0);
-        }
-        tmp[i] = v;
-    }
-
-    for(i=0; i<len; i++){
-        double v;
-
-        switch(s->dither_method){
-            case SWR_DITHER_RECTANGULAR:
-            case SWR_DITHER_TRIANGULAR :
-                v = tmp[i];
-                break;
-            case SWR_DITHER_TRIANGULAR_HIGHPASS :
-                v = (- tmp[i] + 2*tmp[i+1] - tmp[i+2]) / sqrt(6);
-                break;
-            default: av_assert0(0);
-        }
-
-        v*= scale;
-
-        switch(in_fmt){
-            case AV_SAMPLE_FMT_S16: ((int16_t*)dst)[i] = v; break;
-            case AV_SAMPLE_FMT_S32: ((int32_t*)dst)[i] = v; break;
-            case AV_SAMPLE_FMT_FLT: ((float  *)dst)[i] = v; break;
-            case AV_SAMPLE_FMT_DBL: ((double *)dst)[i] = v; break;
-            default: av_assert0(0);
+    s->dither.ns_pos = 0;
+    s->dither.noise_scale=   scale;
+    s->dither.ns_scale   =   scale;
+    s->dither.ns_scale_1 = scale ? 1/scale : 0;
+    memset(s->dither.ns_errors, 0, sizeof(s->dither.ns_errors));
+    for (i=0; filters[i].coefs; i++) {
+        const filter_t *f = &filters[i];
+        if (fabs(s->out_sample_rate - f->rate) / f->rate <= .05 && f->name == s->dither.method) {
+            int j;
+            s->dither.ns_taps = f->len;
+            for (j=0; j<f->len; j++)
+                s->dither.ns_coeffs[j] = f->coefs[j];
+            s->dither.ns_scale_1 *= 1 - exp(f->gain_cB * M_LN10 * 0.005) * 2 / (1<<(8*av_get_bytes_per_sample(out_fmt)));
+            break;
         }
     }
+    if (!filters[i].coefs && s->dither.method > SWR_DITHER_NS) {
+        av_log(s, AV_LOG_WARNING, "Requested noise shaping dither not available at this sampling rate, using triangular hp dither\n");
+        s->dither.method = SWR_DITHER_TRIANGULAR_HIGHPASS;
+    }
 
-    av_free(tmp);
+    av_assert0(!s->preout.count);
+    s->dither.noise = s->preout;
+    s->dither.temp  = s->preout;
+    if (s->dither.method > SWR_DITHER_NS) {
+        s->dither.noise.bps = 4;
+        s->dither.noise.fmt = AV_SAMPLE_FMT_FLTP;
+        s->dither.noise_scale = 1;
+    }
+
+    return 0;
 }
+
+#define TEMPLATE_DITHER_S16
+#include "dither_template.c"
+#undef TEMPLATE_DITHER_S16
+
+#define TEMPLATE_DITHER_S32
+#include "dither_template.c"
+#undef TEMPLATE_DITHER_S32
+
+#define TEMPLATE_DITHER_FLT
+#include "dither_template.c"
+#undef TEMPLATE_DITHER_FLT
+
+#define TEMPLATE_DITHER_DBL
+#include "dither_template.c"
+#undef TEMPLATE_DITHER_DBL
diff --git a/libswresample/dither_template.c b/libswresample/dither_template.c
new file mode 100644
index 0000000..4af7312
--- /dev/null
+++ b/libswresample/dither_template.c
@@ -0,0 +1,67 @@
+
+#if defined(TEMPLATE_DITHER_DBL)
+#    define RENAME(N) N ## _double
+#    define DELEM  double
+#    define CLIP(v)
+
+#elif defined(TEMPLATE_DITHER_FLT)
+#    define RENAME(N) N ## _float
+#    define DELEM  float
+#    define CLIP(v)
+
+#elif defined(TEMPLATE_DITHER_S32)
+#    define RENAME(N) N ## _int32
+#    define DELEM  int32_t
+#    define CLIP(v) v = FFMAX(FFMIN(v, INT32_MAX), INT32_MIN)
+
+#elif defined(TEMPLATE_DITHER_S16)
+#    define RENAME(N) N ## _int16
+#    define DELEM  int16_t
+#    define CLIP(v) v = FFMAX(FFMIN(v, INT16_MAX), INT16_MIN)
+
+#else
+ERROR
+#endif
+
+void RENAME(swri_noise_shaping)(SwrContext *s, AudioData *dsts, const AudioData *srcs, const AudioData *noises, int count){
+    int pos = s->dither.ns_pos;
+    int i, j, ch;
+    int taps  = s->dither.ns_taps;
+    float S   = s->dither.ns_scale;
+    float S_1 = s->dither.ns_scale_1;
+
+    av_assert2((taps&3) != 2);
+    av_assert2((taps&3) != 3 || s->dither.ns_coeffs[taps] == 0);
+
+    for (ch=0; ch<srcs->ch_count; ch++) {
+        const float *noise = ((const float *)noises->ch[ch]) + s->dither.noise_pos;
+        const DELEM *src = (const DELEM*)srcs->ch[ch];
+        DELEM *dst = (DELEM*)dsts->ch[ch];
+        float *ns_errors = s->dither.ns_errors[ch];
+        const float *ns_coeffs = s->dither.ns_coeffs;
+        pos  = s->dither.ns_pos;
+        for (i=0; i<count; i++) {
+            double d1, d = src[i]*S_1;
+            for(j=0; j<taps-2; j+=4) {
+                d -= ns_coeffs[j    ] * ns_errors[pos + j    ]
+                    +ns_coeffs[j + 1] * ns_errors[pos + j + 1]
+                    +ns_coeffs[j + 2] * ns_errors[pos + j + 2]
+                    +ns_coeffs[j + 3] * ns_errors[pos + j + 3];
+            }
+            if(j < taps)
+                d -= ns_coeffs[j] * ns_errors[pos + j];
+            pos = pos ? pos - 1 : taps - 1;
+            d1 = rint(d + noise[i]);
+            ns_errors[pos + taps] = ns_errors[pos] = d1 - d;
+            d1 *= S;
+            CLIP(d1);
+            dst[i] = d1;
+        }
+    }
+
+    s->dither.ns_pos = pos;
+}
+
+#undef RENAME
+#undef DELEM
+#undef CLIP
diff --git a/libswresample/noise_shaping_data.c b/libswresample/noise_shaping_data.c
new file mode 100644
index 0000000..77e0f2e
--- /dev/null
+++ b/libswresample/noise_shaping_data.c
@@ -0,0 +1,224 @@
+/* Effect: dither/noise-shape   Copyright (c) 2008-9 robs@users.sourceforge.net
+ *
+ * This library 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.
+ *
+ * This library 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 this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+typedef struct {
+  int  rate;
+  enum {fir, iir} type;
+  size_t len;
+  int gain_cB; /* Chosen so clips are few if any, but not guaranteed none. */
+  double const * coefs;
+  enum SwrDitherType name;
+} filter_t;
+
+static double const lip44[] = {2.033, -2.165, 1.959, -1.590, .6149};
+static double const fwe44[] = {
+  2.412, -3.370, 3.937, -4.174, 3.353, -2.205, 1.281, -.569, .0847};
+static double const mew44[] = {
+  1.662, -1.263, .4827, -.2913, .1268, -.1124, .03252, -.01265, -.03524};
+static double const iew44[] = {
+  2.847, -4.685, 6.214, -7.184, 6.639, -5.032, 3.263, -1.632, .4191};
+static double const ges44[] = {
+  2.2061, -.4706, -.2534, -.6214, 1.0587, .0676, -.6054, -.2738};
+static double const ges48[] = {
+  2.2374, -.7339, -.1251, -.6033, .903, .0116, -.5853, -.2571};
+
+static double const shi48[] = {
+  2.8720729351043701172,  -5.0413231849670410156,   6.2442994117736816406,
+  -5.8483986854553222656, 3.7067542076110839844,  -1.0495119094848632812,
+  -1.1830236911773681641,   2.1126792430877685547, -1.9094531536102294922,
+  0.99913084506988525391, -0.17090806365013122559, -0.32615602016448974609,
+  0.39127644896507263184, -0.26876461505889892578,  0.097676105797290802002,
+  -0.023473845794796943665,
+};
+static double const shi44[] = {
+  2.6773197650909423828,  -4.8308925628662109375,   6.570110321044921875,
+  -7.4572014808654785156, 6.7263274192810058594,  -4.8481650352478027344,
+  2.0412089824676513672,   0.7006359100341796875, -2.9537565708160400391,
+  4.0800385475158691406,  -4.1845216751098632812,   3.3311812877655029297,
+  -2.1179926395416259766,   0.879302978515625,      -0.031759146600961685181,
+  -0.42382788658142089844, 0.47882103919982910156, -0.35490813851356506348,
+  0.17496839165687561035, -0.060908168554306030273,
+};
+static double const shi38[] = {
+  1.6335992813110351562,  -2.2615492343902587891,   2.4077029228210449219,
+  -2.6341717243194580078, 2.1440362930297851562,  -1.8153258562088012695,
+  1.0816224813461303711,  -0.70302653312683105469, 0.15991993248462677002,
+  0.041549518704414367676, -0.29416576027870178223,  0.2518316805362701416,
+  -0.27766478061676025391,  0.15785403549671173096, -0.10165894031524658203,
+  0.016833892092108726501,
+};
+static double const shi32[] =
+{ /* dmaker 32000: bestmax=4.99659 (inverted) */
+0.82118552923202515,
+-1.0063692331314087,
+0.62341964244842529,
+-1.0447187423706055,
+0.64532512426376343,
+-0.87615132331848145,
+0.52219754457473755,
+-0.67434263229370117,
+0.44954317808151245,
+-0.52557498216629028,
+0.34567299485206604,
+-0.39618203043937683,
+0.26791760325431824,
+-0.28936097025871277,
+0.1883765310049057,
+-0.19097308814525604,
+0.10431359708309174,
+-0.10633844882249832,
+0.046832218766212463,
+-0.039653312414884567,
+};
+static double const shi22[] =
+{ /* dmaker 22050: bestmax=5.77762 (inverted) */
+0.056581053882837296,
+-0.56956905126571655,
+-0.40727734565734863,
+-0.33870288729667664,
+-0.29810553789138794,
+-0.19039161503314972,
+-0.16510021686553955,
+-0.13468159735202789,
+-0.096633769571781158,
+-0.081049129366874695,
+-0.064953058958053589,
+-0.054459091275930405,
+-0.043378707021474838,
+-0.03660014271736145,
+-0.026256965473294258,
+-0.018786206841468811,
+-0.013387725688517094,
+-0.0090983230620622635,
+-0.0026585909072309732,
+-0.00042083300650119781,
+};
+static double const shi16[] =
+{ /* dmaker 16000: bestmax=5.97128 (inverted) */
+-0.37251132726669312,
+-0.81423574686050415,
+-0.55010956525802612,
+-0.47405767440795898,
+-0.32624706625938416,
+-0.3161766529083252,
+-0.2286367267370224,
+-0.22916607558727264,
+-0.19565616548061371,
+-0.18160104751586914,
+-0.15423151850700378,
+-0.14104481041431427,
+-0.11844276636838913,
+-0.097583092749118805,
+-0.076493598520755768,
+-0.068106919527053833,
+-0.041881654411554337,
+-0.036922425031661987,
+-0.019364040344953537,
+-0.014994367957115173,
+};
+static double const shi11[] =
+{ /* dmaker 11025: bestmax=5.9406 (inverted) */
+-0.9264228343963623,
+-0.98695987462997437,
+-0.631156325340271,
+-0.51966935396194458,
+-0.39738872647285461,
+-0.35679301619529724,
+-0.29720726609230042,
+-0.26310476660728455,
+-0.21719355881214142,
+-0.18561814725399017,
+-0.15404847264289856,
+-0.12687471508979797,
+-0.10339745879173279,
+-0.083688631653785706,
+-0.05875682458281517,
+-0.046893671154975891,
+-0.027950936928391457,
+-0.020740609616041183,
+-0.009366452693939209,
+-0.0060260160826146603,
+};
+static double const shi08[] =
+{ /* dmaker 8000: bestmax=5.56234 (inverted) */
+-1.202863335609436,
+-0.94103097915649414,
+-0.67878556251525879,
+-0.57650017738342285,
+-0.50004476308822632,
+-0.44349345564842224,
+-0.37833768129348755,
+-0.34028723835945129,
+-0.29413089156150818,
+-0.24994957447052002,
+-0.21715600788593292,
+-0.18792112171649933,
+-0.15268312394618988,
+-0.12135542929172516,
+-0.099610626697540283,
+-0.075273610651493073,
+-0.048787496984004974,
+-0.042586319148540497,
+-0.028991291299462318,
+-0.011869125068187714,
+};
+static double const shl48[] = {
+  2.3925774097442626953,  -3.4350297451019287109,   3.1853709220886230469,
+  -1.8117271661758422852, -0.20124770700931549072,  1.4759907722473144531,
+  -1.7210904359817504883,   0.97746700048446655273, -0.13790138065814971924,
+  -0.38185903429985046387,  0.27421241998672485352,  0.066584214568138122559,
+  -0.35223302245140075684,  0.37672343850135803223, -0.23964276909828186035,
+  0.068674825131893157959,
+};
+static double const shl44[] = {
+  2.0833916664123535156,  -3.0418450832366943359,   3.2047898769378662109,
+  -2.7571926116943359375, 1.4978630542755126953,  -0.3427594602108001709,
+  -0.71733748912811279297,  1.0737057924270629883, -1.0225815773010253906,
+  0.56649994850158691406, -0.20968692004680633545, -0.065378531813621520996,
+  0.10322438180446624756, -0.067442022264003753662, -0.00495197344571352005,
+  0,
+};
+static double const shh44[] = {
+   3.0259189605712890625, -6.0268716812133789062,   9.195003509521484375,
+   -11.824929237365722656, 12.767142295837402344, -11.917946815490722656,
+   9.1739168167114257812,  -5.3712320327758789062, 1.1393624544143676758,
+   2.4484779834747314453,  -4.9719839096069335938,   6.0392003059387207031,
+   -5.9359521865844726562,  4.903278350830078125,   -3.5527443885803222656,
+   2.1909697055816650391, -1.1672389507293701172,  0.4903914332389831543,
+   -0.16519790887832641602,  0.023217858746647834778,
+};
+
+static const filter_t filters[] = {
+  {44100, fir,  5, 210, lip44,          SWR_DITHER_NS_LIPSHITZ},
+  {46000, fir,  9, 276, fwe44,          SWR_DITHER_NS_F_WEIGHTED},
+  {46000, fir,  9, 160, mew44,          SWR_DITHER_NS_MODIFIED_E_WEIGHTED},
+  {46000, fir,  9, 321, iew44,          SWR_DITHER_NS_IMPROVED_E_WEIGHTED},
+//   {48000, iir,  4, 220, ges48, SWR_DITHER_NS_GESEMANN},
+//   {44100, iir,  4, 230, ges44, SWR_DITHER_NS_GESEMANN},
+  {48000, fir, 16, 301, shi48,          SWR_DITHER_NS_SHIBATA},
+  {44100, fir, 20, 333, shi44,          SWR_DITHER_NS_SHIBATA},
+  {37800, fir, 16, 240, shi38,          SWR_DITHER_NS_SHIBATA},
+  {32000, fir, 20, 240/*TBD*/, shi32,   SWR_DITHER_NS_SHIBATA},
+  {22050, fir, 20, 240/*TBD*/, shi22,   SWR_DITHER_NS_SHIBATA},
+  {16000, fir, 20, 240/*TBD*/, shi16,   SWR_DITHER_NS_SHIBATA},
+  {11025, fir, 20, 240/*TBD*/, shi11,   SWR_DITHER_NS_SHIBATA},
+  { 8000, fir, 20, 240/*TBD*/, shi08,   SWR_DITHER_NS_SHIBATA},
+  {48000, fir, 16, 250, shl48,          SWR_DITHER_NS_LOW_SHIBATA},
+  {44100, fir, 15, 250, shl44,          SWR_DITHER_NS_LOW_SHIBATA},
+  {44100, fir, 20, 383, shh44,          SWR_DITHER_NS_HIGH_SHIBATA},
+  {    0, fir,  0,   0,  NULL,          SWR_DITHER_NONE},
+};
diff --git a/libswresample/rematrix_template.c b/libswresample/rematrix_template.c
index a0d3fd1..b8ca901 100644
--- a/libswresample/rematrix_template.c
+++ b/libswresample/rematrix_template.c
@@ -19,21 +19,18 @@
  */
 
 #if defined(TEMPLATE_REMATRIX_FLT)
-#    define ONE (1.0)
 #    define R(x) x
 #    define SAMPLE float
 #    define COEFF float
 #    define INTER float
 #    define RENAME(x) x ## _float
 #elif defined(TEMPLATE_REMATRIX_DBL)
-#    define ONE (1.0)
 #    define R(x) x
 #    define SAMPLE double
 #    define COEFF double
 #    define INTER double
 #    define RENAME(x) x ## _double
 #elif defined(TEMPLATE_REMATRIX_S16)
-#    define ONE (-32768)
 #    define R(x) (((x) + 16384)>>15)
 #    define SAMPLE int16_t
 #    define COEFF int
@@ -96,7 +93,6 @@
     return NULL;
 }
 
-#undef ONE
 #undef R
 #undef SAMPLE
 #undef COEFF
diff --git a/libswresample/resample.c b/libswresample/resample.c
index 2096e43..fb9da7c 100644
--- a/libswresample/resample.c
+++ b/libswresample/resample.c
@@ -142,7 +142,7 @@
             break;
         case AV_SAMPLE_FMT_S32P:
             for(i=0;i<tap_count;i++)
-                ((int32_t*)filter)[ph * alloc + i] = av_clip(lrintf(tab[i] * scale / norm), INT32_MIN, INT32_MAX);
+                ((int32_t*)filter)[ph * alloc + i] = av_clipl_int32(llrint(tab[i] * scale / norm));
             break;
         case AV_SAMPLE_FMT_FLTP:
             for(i=0;i<tap_count;i++)
@@ -195,8 +195,10 @@
     return 0;
 }
 
-ResampleContext *swri_resample_init(ResampleContext *c, int out_rate, int in_rate, int filter_size, int phase_shift, int linear,
-                                    double cutoff, enum AVSampleFormat format, enum SwrFilterType filter_type, int kaiser_beta){
+static ResampleContext *resample_init(ResampleContext *c, int out_rate, int in_rate, int filter_size, int phase_shift, int linear,
+                                    double cutoff0, enum AVSampleFormat format, enum SwrFilterType filter_type, int kaiser_beta,
+                                    double precision, int cheby){
+    double cutoff = cutoff0? cutoff0 : 0.97;
     double factor= FFMIN(out_rate * cutoff / in_rate, 1.0);
     int phase_count= 1<<phase_shift;
 
@@ -233,7 +235,7 @@
         c->factor        = factor;
         c->filter_length = FFMAX((int)ceil(filter_size/factor), 1);
         c->filter_alloc  = FFALIGN(c->filter_length, 8);
-        c->filter_bank   = av_mallocz(c->filter_alloc*(phase_count+1)*c->felem_size);
+        c->filter_bank   = av_calloc(c->filter_alloc, (phase_count+1)*c->felem_size);
         c->filter_type   = filter_type;
         c->kaiser_beta   = kaiser_beta;
         if (!c->filter_bank)
@@ -259,28 +261,14 @@
     return NULL;
 }
 
-void swri_resample_free(ResampleContext **c){
+static void resample_free(ResampleContext **c){
     if(!*c)
         return;
     av_freep(&(*c)->filter_bank);
     av_freep(c);
 }
 
-int swr_set_compensation(struct SwrContext *s, int sample_delta, int compensation_distance){
-    ResampleContext *c;
-    int ret;
-
-    if (!s || compensation_distance < 0)
-        return AVERROR(EINVAL);
-    if (!compensation_distance && sample_delta)
-        return AVERROR(EINVAL);
-    if (!s->resample) {
-        s->flags |= SWR_FLAG_RESAMPLE;
-        ret = swr_init(s);
-        if (ret < 0)
-            return ret;
-    }
-    c= s->resample;
+static int set_compensation(ResampleContext *c, int sample_delta, int compensation_distance){
     c->compensation_distance= compensation_distance;
     if (compensation_distance)
         c->dst_incr = c->ideal_dst_incr - c->ideal_dst_incr * (int64_t)sample_delta / compensation_distance;
@@ -322,7 +310,7 @@
 
 #endif // HAVE_MMXEXT_INLINE
 
-int swri_multiple_resample(ResampleContext *c, AudioData *dst, int dst_size, AudioData *src, int src_size, int *consumed){
+static int multiple_resample(ResampleContext *c, AudioData *dst, int dst_size, AudioData *src, int src_size, int *consumed){
     int i, ret= -1;
     int av_unused mm_flags = av_get_cpu_flags();
     int need_emms= 0;
@@ -348,17 +336,37 @@
     return ret;
 }
 
-int64_t swr_get_delay(struct SwrContext *s, int64_t base){
+static int64_t get_delay(struct SwrContext *s, int64_t base){
     ResampleContext *c = s->resample;
-    if(c){
-        int64_t num = s->in_buffer_count - (c->filter_length-1)/2;
-        num <<= c->phase_shift;
-        num -= c->index;
-        num *= c->src_incr;
-        num -= c->frac;
-
-        return av_rescale(num, base, s->in_sample_rate*(int64_t)c->src_incr << c->phase_shift);
-    }else{
-        return (s->in_buffer_count*base + (s->in_sample_rate>>1))/ s->in_sample_rate;
-    }
+    int64_t num = s->in_buffer_count - (c->filter_length-1)/2;
+    num <<= c->phase_shift;
+    num -= c->index;
+    num *= c->src_incr;
+    num -= c->frac;
+    return av_rescale(num, base, s->in_sample_rate*(int64_t)c->src_incr << c->phase_shift);
 }
+
+static int resample_flush(struct SwrContext *s) {
+    AudioData *a= &s->in_buffer;
+    int i, j, ret;
+    if((ret = swri_realloc_audio(a, s->in_buffer_index + 2*s->in_buffer_count)) < 0)
+        return ret;
+    av_assert0(a->planar);
+    for(i=0; i<a->ch_count; i++){
+        for(j=0; j<s->in_buffer_count; j++){
+            memcpy(a->ch[i] + (s->in_buffer_index+s->in_buffer_count+j  )*a->bps,
+                a->ch[i] + (s->in_buffer_index+s->in_buffer_count-j-1)*a->bps, a->bps);
+        }
+    }
+    s->in_buffer_count += (s->in_buffer_count+1)/2;
+    return 0;
+}
+
+struct Resampler const swri_resampler={
+  resample_init,
+  resample_free,
+  multiple_resample,
+  resample_flush,
+  set_compensation,
+  get_delay,
+};
diff --git a/libswresample/resample_template.c b/libswresample/resample_template.c
index 855296f..5bc12bc 100644
--- a/libswresample/resample_template.c
+++ b/libswresample/resample_template.c
@@ -151,7 +151,7 @@
                 break;
             }else if(sample_index < 0){
                 for(i=0; i<c->filter_length; i++)
-                    val += src[FFABS(sample_index + i)] * filter[i];
+                    val += src[FFABS(sample_index + i)] * (FELEM2)filter[i];
             }else if(c->linear){
                 FELEM2 v2=0;
                 for(i=0; i<c->filter_length; i++){
@@ -195,13 +195,6 @@
         c->dst_incr= dst_incr_frac + c->src_incr*dst_incr;
         c->compensation_distance= compensation_distance;
     }
-#if 0
-    if(update_ctx && !c->compensation_distance){
-#undef rand
-        av_resample_compensate(c, rand() % (8000*2) - 8000, 8000*2);
-av_log(NULL, AV_LOG_DEBUG, "%d %d %d\n", c->dst_incr, c->ideal_dst_incr, c->compensation_distance);
-    }
-#endif
 
     return dst_index;
 }
diff --git a/libswresample/soxr_resample.c b/libswresample/soxr_resample.c
new file mode 100644
index 0000000..4c000db
--- /dev/null
+++ b/libswresample/soxr_resample.c
@@ -0,0 +1,93 @@
+/*
+ * audio resampling with soxr
+ * Copyright (c) 2012 Rob Sykes <robs@users.sourceforge.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
+ */
+
+/**
+ * @file
+ * audio resampling with soxr
+ */
+
+#include "libavutil/log.h"
+#include "swresample_internal.h"
+
+#include <soxr.h>
+
+static struct ResampleContext *create(struct ResampleContext *c, int out_rate, int in_rate, int filter_size, int phase_shift, int linear,
+        double cutoff, enum AVSampleFormat format, enum SwrFilterType filter_type, int kaiser_beta, double precision, int cheby){
+    soxr_error_t error;
+
+    soxr_datatype_t type =
+        format == AV_SAMPLE_FMT_S16P? SOXR_INT16_S :
+        format == AV_SAMPLE_FMT_S16 ? SOXR_INT16_I :
+        format == AV_SAMPLE_FMT_S32P? SOXR_INT32_S :
+        format == AV_SAMPLE_FMT_S32 ? SOXR_INT32_I :
+        format == AV_SAMPLE_FMT_FLTP? SOXR_FLOAT32_S :
+        format == AV_SAMPLE_FMT_FLT ? SOXR_FLOAT32_I :
+        format == AV_SAMPLE_FMT_DBLP? SOXR_FLOAT64_S :
+        format == AV_SAMPLE_FMT_DBL ? SOXR_FLOAT64_I : (soxr_datatype_t)-1;
+
+    soxr_io_spec_t io_spec = soxr_io_spec(type, type);
+
+    soxr_quality_spec_t q_spec = soxr_quality_spec((int)((precision-2)/4), (SOXR_HI_PREC_CLOCK|SOXR_ROLLOFF_NONE)*!!cheby);
+    q_spec.precision = linear? 0 : precision;
+#if !defined SOXR_VERSION /* Deprecated @ March 2013: */
+    q_spec.bw_pc = cutoff? FFMAX(FFMIN(cutoff,.995),.8)*100 : q_spec.bw_pc;
+#else
+    q_spec.passband_end = cutoff? FFMAX(FFMIN(cutoff,.995),.8) : q_spec.passband_end;
+#endif
+
+    soxr_delete((soxr_t)c);
+    c = (struct ResampleContext *)
+        soxr_create(in_rate, out_rate, 0, &error, &io_spec, &q_spec, 0);
+    if (!c)
+        av_log(NULL, AV_LOG_ERROR, "soxr_create: %s\n", error);
+    return c;
+}
+
+static void destroy(struct ResampleContext * *c){
+    soxr_delete((soxr_t)*c);
+    *c = NULL;
+}
+
+static int flush(struct SwrContext *s){
+    soxr_process((soxr_t)s->resample, NULL, 0, NULL, NULL, 0, NULL);
+    return 0;
+}
+
+static int process(
+        struct ResampleContext * c, AudioData *dst, int dst_size,
+        AudioData *src, int src_size, int *consumed){
+    size_t idone, odone;
+    soxr_error_t error = soxr_set_error((soxr_t)c, soxr_set_num_channels((soxr_t)c, src->ch_count));
+    error = soxr_process((soxr_t)c, src->ch, (size_t)src_size,
+            &idone, dst->ch, (size_t)dst_size, &odone);
+    *consumed = (int)idone;
+    return error? -1 : odone;
+}
+
+static int64_t get_delay(struct SwrContext *s, int64_t base){
+    double delay_s = soxr_delay((soxr_t)s->resample) / s->out_sample_rate;
+    return (int64_t)(delay_s * base + .5);
+}
+
+struct Resampler const soxr_resampler={
+    create, destroy, process, flush, NULL /* set_compensation */, get_delay,
+};
+
diff --git a/libswresample/swresample-test.c b/libswresample/swresample-test.c
index 7f50cb4..379d385 100644
--- a/libswresample/swresample-test.c
+++ b/libswresample/swresample-test.c
@@ -65,7 +65,7 @@
     switch(f){
     case AV_SAMPLE_FMT_U8 : ((uint8_t*)p)[index]= av_clip_uint8 (lrint((v+1.0)*127));     break;
     case AV_SAMPLE_FMT_S16: ((int16_t*)p)[index]= av_clip_int16 (lrint(v*32767));         break;
-    case AV_SAMPLE_FMT_S32: ((int32_t*)p)[index]= av_clipl_int32(lrint(v*2147483647));    break;
+    case AV_SAMPLE_FMT_S32: ((int32_t*)p)[index]= av_clipl_int32(llrint(v*2147483647));   break;
     case AV_SAMPLE_FMT_FLT: ((float  *)p)[index]= v;                                      break;
     case AV_SAMPLE_FMT_DBL: ((double *)p)[index]= v;                                      break;
     default: av_assert2(0);
diff --git a/libswresample/swresample.c b/libswresample/swresample.c
index c1668da..9b71b2e 100644
--- a/libswresample/swresample.c
+++ b/libswresample/swresample.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2012 Michael Niedermayer (michaelni@gmx.at)
+ * Copyright (C) 2011-2013 Michael Niedermayer (michaelni@gmx.at)
  *
  * This file is part of libswresample
  *
@@ -73,17 +73,35 @@
 {"swr_flags"            , "set flags"                   , OFFSET(flags          ), AV_OPT_TYPE_FLAGS, {.i64=0                     }, 0      , UINT_MAX  , PARAM, "flags"},
 {"res"                  , "force resampling"            , 0                      , AV_OPT_TYPE_CONST, {.i64=SWR_FLAG_RESAMPLE     }, INT_MIN, INT_MAX   , PARAM, "flags"},
 
-{"dither_scale"         , "set dither scale"            , OFFSET(dither_scale   ), AV_OPT_TYPE_FLOAT, {.dbl=1                     }, 0      , INT_MAX   , PARAM},
+{"dither_scale"         , "set dither scale"            , OFFSET(dither.scale   ), AV_OPT_TYPE_FLOAT, {.dbl=1                     }, 0      , INT_MAX   , PARAM},
 
-{"dither_method"        , "set dither method"           , OFFSET(dither_method  ), AV_OPT_TYPE_INT  , {.i64=0                     }, 0      , SWR_DITHER_NB-1, PARAM, "dither_method"},
+{"dither_method"        , "set dither method"           , OFFSET(dither.method  ), AV_OPT_TYPE_INT  , {.i64=0                     }, 0      , SWR_DITHER_NB-1, PARAM, "dither_method"},
 {"rectangular"          , "select rectangular dither"   , 0                      , AV_OPT_TYPE_CONST, {.i64=SWR_DITHER_RECTANGULAR}, INT_MIN, INT_MAX   , PARAM, "dither_method"},
 {"triangular"           , "select triangular dither"    , 0                      , AV_OPT_TYPE_CONST, {.i64=SWR_DITHER_TRIANGULAR }, INT_MIN, INT_MAX   , PARAM, "dither_method"},
-{"triangular_hp"        , "select triangular dither with high pass" , 0                 , AV_OPT_TYPE_CONST, {.i64=SWR_DITHER_TRIANGULAR_HIGHPASS }, INT_MIN, INT_MAX, PARAM, "dither_method"},
+{"triangular_hp"        , "select triangular dither with high pass" , 0          , AV_OPT_TYPE_CONST, {.i64=SWR_DITHER_TRIANGULAR_HIGHPASS }, INT_MIN, INT_MAX, PARAM, "dither_method"},
+{"lipshitz"             , "select lipshitz noise shaping dither" , 0             , AV_OPT_TYPE_CONST, {.i64=SWR_DITHER_NS_LIPSHITZ}, INT_MIN, INT_MAX, PARAM, "dither_method"},
+{"shibata"              , "select shibata noise shaping dither" , 0              , AV_OPT_TYPE_CONST, {.i64=SWR_DITHER_NS_SHIBATA }, INT_MIN, INT_MAX, PARAM, "dither_method"},
+{"low_shibata"          , "select low shibata noise shaping dither" , 0          , AV_OPT_TYPE_CONST, {.i64=SWR_DITHER_NS_LOW_SHIBATA }, INT_MIN, INT_MAX, PARAM, "dither_method"},
+{"high_shibata"         , "select high shibata noise shaping dither" , 0         , AV_OPT_TYPE_CONST, {.i64=SWR_DITHER_NS_HIGH_SHIBATA }, INT_MIN, INT_MAX, PARAM, "dither_method"},
+{"f_weighted"           , "select f-weighted noise shaping dither" , 0           , AV_OPT_TYPE_CONST, {.i64=SWR_DITHER_NS_F_WEIGHTED }, INT_MIN, INT_MAX, PARAM, "dither_method"},
+{"modified_e_weighted"  , "select modified-e-weighted noise shaping dither" , 0  , AV_OPT_TYPE_CONST, {.i64=SWR_DITHER_NS_MODIFIED_E_WEIGHTED }, INT_MIN, INT_MAX, PARAM, "dither_method"},
+{"improved_e_weighted"  , "select improved-e-weighted noise shaping dither" , 0  , AV_OPT_TYPE_CONST, {.i64=SWR_DITHER_NS_IMPROVED_E_WEIGHTED }, INT_MIN, INT_MAX, PARAM, "dither_method"},
 
-{"filter_size"          , "set resampling filter size"  , OFFSET(filter_size)    , AV_OPT_TYPE_INT  , {.i64=16                    }, 0      , INT_MAX   , PARAM },
-{"phase_shift"          , "set resampling phase shift"  , OFFSET(phase_shift)    , AV_OPT_TYPE_INT  , {.i64=10                    }, 0      , 30        , PARAM },
+{"filter_size"          , "set swr resampling filter size", OFFSET(filter_size)  , AV_OPT_TYPE_INT  , {.i64=32                    }, 0      , INT_MAX   , PARAM },
+{"phase_shift"          , "set swr resampling phase shift", OFFSET(phase_shift)  , AV_OPT_TYPE_INT  , {.i64=10                    }, 0      , 24        , PARAM },
 {"linear_interp"        , "enable linear interpolation" , OFFSET(linear_interp)  , AV_OPT_TYPE_INT  , {.i64=0                     }, 0      , 1         , PARAM },
-{"cutoff"               , "set cutoff frequency ratio"  , OFFSET(cutoff)         , AV_OPT_TYPE_DOUBLE,{.dbl=0.8                   }, 0      , 1         , PARAM },
+{"cutoff"               , "set cutoff frequency ratio"  , OFFSET(cutoff)         , AV_OPT_TYPE_DOUBLE,{.dbl=0.                    }, 0      , 1         , PARAM },
+
+/* duplicate option in order to work with avconv */
+{"resample_cutoff"      , "set cutoff frequency ratio"  , OFFSET(cutoff)         , AV_OPT_TYPE_DOUBLE,{.dbl=0.                    }, 0      , 1         , PARAM },
+
+{"resampler"            , "set resampling Engine"       , OFFSET(engine)         , AV_OPT_TYPE_INT  , {.i64=0                     }, 0      , SWR_ENGINE_NB-1, PARAM, "resampler"},
+{"swr"                  , "select SW Resampler"         , 0                      , AV_OPT_TYPE_CONST, {.i64=SWR_ENGINE_SWR        }, INT_MIN, INT_MAX   , PARAM, "resampler"},
+{"soxr"                 , "select SoX Resampler"        , 0                      , AV_OPT_TYPE_CONST, {.i64=SWR_ENGINE_SOXR       }, INT_MIN, INT_MAX   , PARAM, "resampler"},
+{"precision"            , "set soxr resampling precision (in bits)"
+                                                        , OFFSET(precision)      , AV_OPT_TYPE_DOUBLE,{.dbl=20.0                  }, 15.0   , 33.0      , PARAM },
+{"cheby"                , "enable soxr Chebyshev passband & higher-precision irrational ratio approximation"
+                                                        , OFFSET(cheby)          , AV_OPT_TYPE_INT  , {.i64=0                     }, 0      , 1         , PARAM },
 {"min_comp"             , "set minimum difference between timestamps and audio data (in seconds) below which no timestamp compensation of either kind is applied"
                                                         , OFFSET(min_compensation),AV_OPT_TYPE_FLOAT ,{.dbl=FLT_MAX               }, 0      , FLT_MAX   , PARAM },
 {"min_hard_comp"        , "set minimum difference between timestamps and audio data (in seconds) to trigger padding/trimming the data."
@@ -92,19 +110,24 @@
                                                         , OFFSET(soft_compensation_duration),AV_OPT_TYPE_FLOAT ,{.dbl=1                     }, 0      , INT_MAX   , PARAM },
 {"max_soft_comp"        , "set maximum factor by which data is stretched/squeezed to make it match the timestamps."
                                                         , OFFSET(max_soft_compensation),AV_OPT_TYPE_FLOAT ,{.dbl=0                     }, INT_MIN, INT_MAX   , PARAM },
+{"async"                , "simplified 1 parameter audio timestamp matching, 0(disabled), 1(filling and trimming), >1(maximum stretch/squeeze in samples per second)"
+                                                        , OFFSET(async)          , AV_OPT_TYPE_FLOAT ,{.dbl=0                     }, INT_MIN, INT_MAX   , PARAM },
+{"first_pts"            , "Assume the first pts should be this value (in samples)."
+                                                        , OFFSET(firstpts_in_samples), AV_OPT_TYPE_INT64 ,{.i64=AV_NOPTS_VALUE    }, INT64_MIN,INT64_MAX, PARAM },
 
 { "matrix_encoding"     , "set matrixed stereo encoding" , OFFSET(matrix_encoding), AV_OPT_TYPE_INT   ,{.i64 = AV_MATRIX_ENCODING_NONE}, AV_MATRIX_ENCODING_NONE,     AV_MATRIX_ENCODING_NB-1, PARAM, "matrix_encoding" },
     { "none",  "select none",               0, AV_OPT_TYPE_CONST, { .i64 = AV_MATRIX_ENCODING_NONE  }, INT_MIN, INT_MAX, PARAM, "matrix_encoding" },
     { "dolby", "select Dolby",              0, AV_OPT_TYPE_CONST, { .i64 = AV_MATRIX_ENCODING_DOLBY }, INT_MIN, INT_MAX, PARAM, "matrix_encoding" },
     { "dplii", "select Dolby Pro Logic II", 0, AV_OPT_TYPE_CONST, { .i64 = AV_MATRIX_ENCODING_DPLII }, INT_MIN, INT_MAX, PARAM, "matrix_encoding" },
 
-{ "filter_type"         , "select filter type"          , OFFSET(filter_type)    , AV_OPT_TYPE_INT  , { .i64 = SWR_FILTER_TYPE_KAISER }, SWR_FILTER_TYPE_CUBIC, SWR_FILTER_TYPE_KAISER, PARAM, "filter_type" },
+{ "filter_type"         , "select swr filter type"      , OFFSET(filter_type)    , AV_OPT_TYPE_INT  , { .i64 = SWR_FILTER_TYPE_KAISER }, SWR_FILTER_TYPE_CUBIC, SWR_FILTER_TYPE_KAISER, PARAM, "filter_type" },
     { "cubic"           , "select cubic"                , 0                      , AV_OPT_TYPE_CONST, { .i64 = SWR_FILTER_TYPE_CUBIC            }, INT_MIN, INT_MAX, PARAM, "filter_type" },
     { "blackman_nuttall", "select Blackman Nuttall Windowed Sinc", 0             , AV_OPT_TYPE_CONST, { .i64 = SWR_FILTER_TYPE_BLACKMAN_NUTTALL }, INT_MIN, INT_MAX, PARAM, "filter_type" },
     { "kaiser"          , "select Kaiser Windowed Sinc" , 0                      , AV_OPT_TYPE_CONST, { .i64 = SWR_FILTER_TYPE_KAISER           }, INT_MIN, INT_MAX, PARAM, "filter_type" },
 
-{ "kaiser_beta"         , "set Kaiser Window Beta"      , OFFSET(kaiser_beta)    , AV_OPT_TYPE_INT  , {.i64=9                     }, 2      , 16        , PARAM },
+{ "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 },
 {0}
 };
 
@@ -201,11 +224,15 @@
         free_temp(&s->midbuf);
         free_temp(&s->preout);
         free_temp(&s->in_buffer);
-        free_temp(&s->dither);
+        free_temp(&s->silence);
+        free_temp(&s->drop_temp);
+        free_temp(&s->dither.noise);
+        free_temp(&s->dither.temp);
         swri_audio_convert_free(&s-> in_convert);
         swri_audio_convert_free(&s->out_convert);
         swri_audio_convert_free(&s->full_convert);
-        swri_resample_free(&s->resample);
+        if (s->resampler)
+            s->resampler->free(&s->resample);
         swri_rematrix_free(s);
     }
 
@@ -213,6 +240,7 @@
 }
 
 av_cold int swr_init(struct SwrContext *s){
+    int ret;
     s->in_buffer_index= 0;
     s->in_buffer_count= 0;
     s->resample_in_constraint= 0;
@@ -220,7 +248,10 @@
     free_temp(&s->midbuf);
     free_temp(&s->preout);
     free_temp(&s->in_buffer);
-    free_temp(&s->dither);
+    free_temp(&s->silence);
+    free_temp(&s->drop_temp);
+    free_temp(&s->dither.noise);
+    free_temp(&s->dither.temp);
     memset(s->in.ch, 0, sizeof(s->in.ch));
     memset(s->out.ch, 0, sizeof(s->out.ch));
     swri_audio_convert_free(&s-> in_convert);
@@ -239,9 +270,51 @@
         return AVERROR(EINVAL);
     }
 
+    if(av_get_channel_layout_nb_channels(s-> in_ch_layout) > SWR_CH_MAX) {
+        av_log(s, AV_LOG_WARNING, "Input channel layout 0x%"PRIx64" is invalid or unsupported.\n", s-> in_ch_layout);
+        s->in_ch_layout = 0;
+    }
+
+    if(av_get_channel_layout_nb_channels(s->out_ch_layout) > SWR_CH_MAX) {
+        av_log(s, AV_LOG_WARNING, "Output channel layout 0x%"PRIx64" is invalid or unsupported.\n", s->out_ch_layout);
+        s->out_ch_layout = 0;
+    }
+
+    switch(s->engine){
+#if CONFIG_LIBSOXR
+        extern struct Resampler const soxr_resampler;
+        case SWR_ENGINE_SOXR: s->resampler = &soxr_resampler; break;
+#endif
+        case SWR_ENGINE_SWR : s->resampler = &swri_resampler; break;
+        default:
+            av_log(s, AV_LOG_ERROR, "Requested resampling engine is unavailable\n");
+            return AVERROR(EINVAL);
+    }
+
+    if(!s->used_ch_count)
+        s->used_ch_count= s->in.ch_count;
+
+    if(s->used_ch_count && s-> in_ch_layout && s->used_ch_count != av_get_channel_layout_nb_channels(s-> in_ch_layout)){
+        av_log(s, AV_LOG_WARNING, "Input channel layout has a different number of channels than the number of used channels, ignoring layout\n");
+        s-> in_ch_layout= 0;
+    }
+
+    if(!s-> in_ch_layout)
+        s-> in_ch_layout= av_get_default_channel_layout(s->used_ch_count);
+    if(!s->out_ch_layout)
+        s->out_ch_layout= av_get_default_channel_layout(s->out.ch_count);
+
+    s->rematrix= s->out_ch_layout  !=s->in_ch_layout || s->rematrix_volume!=1.0 ||
+                 s->rematrix_custom;
+
     if(s->int_sample_fmt == AV_SAMPLE_FMT_NONE){
         if(av_get_planar_sample_fmt(s->in_sample_fmt) <= AV_SAMPLE_FMT_S16P){
             s->int_sample_fmt= AV_SAMPLE_FMT_S16P;
+        }else if(   av_get_planar_sample_fmt(s-> in_sample_fmt) == AV_SAMPLE_FMT_S32P
+                 && av_get_planar_sample_fmt(s->out_sample_fmt) == AV_SAMPLE_FMT_S32P
+                 && !s->rematrix
+                 && s->engine != SWR_ENGINE_SOXR){
+            s->int_sample_fmt= AV_SAMPLE_FMT_S32P;
         }else if(av_get_planar_sample_fmt(s->in_sample_fmt) <= AV_SAMPLE_FMT_FLTP){
             s->int_sample_fmt= AV_SAMPLE_FMT_FLTP;
         }else{
@@ -261,10 +334,26 @@
     set_audiodata_fmt(&s-> in, s-> in_sample_fmt);
     set_audiodata_fmt(&s->out, s->out_sample_fmt);
 
+    if (s->firstpts_in_samples != AV_NOPTS_VALUE) {
+        if (!s->async && s->min_compensation >= FLT_MAX/2)
+            s->async = 1;
+        s->firstpts =
+        s->outpts   = s->firstpts_in_samples * s->out_sample_rate;
+    } else
+        s->firstpts = AV_NOPTS_VALUE;
+
+    if (s->async) {
+        if (s->min_compensation >= FLT_MAX/2)
+            s->min_compensation = 0.001;
+        if (s->async > 1.0001) {
+            s->max_soft_compensation = s->async / (double) s->in_sample_rate;
+        }
+    }
+
     if (s->out_sample_rate!=s->in_sample_rate || (s->flags & SWR_FLAG_RESAMPLE)){
-        s->resample = swri_resample_init(s->resample, s->out_sample_rate, s->in_sample_rate, s->filter_size, s->phase_shift, s->linear_interp, s->cutoff, s->int_sample_fmt, s->filter_type, s->kaiser_beta);
+        s->resample = s->resampler->init(s->resample, s->out_sample_rate, s->in_sample_rate, s->filter_size, s->phase_shift, s->linear_interp, s->cutoff, s->int_sample_fmt, s->filter_type, s->kaiser_beta, s->precision, s->cheby);
     }else
-        swri_resample_free(&s->resample);
+        s->resampler->free(&s->resample);
     if(    s->int_sample_fmt != AV_SAMPLE_FMT_S16P
         && s->int_sample_fmt != AV_SAMPLE_FMT_S32P
         && s->int_sample_fmt != AV_SAMPLE_FMT_FLTP
@@ -274,22 +363,6 @@
         return -1;
     }
 
-    if(!s->used_ch_count)
-        s->used_ch_count= s->in.ch_count;
-
-    if(s->used_ch_count && s-> in_ch_layout && s->used_ch_count != av_get_channel_layout_nb_channels(s-> in_ch_layout)){
-        av_log(s, AV_LOG_WARNING, "Input channel layout has a different number of channels than the number of used channels, ignoring layout\n");
-        s-> in_ch_layout= 0;
-    }
-
-    if(!s-> in_ch_layout)
-        s-> in_ch_layout= av_get_default_channel_layout(s->used_ch_count);
-    if(!s->out_ch_layout)
-        s->out_ch_layout= av_get_default_channel_layout(s->out.ch_count);
-
-    s->rematrix= s->out_ch_layout  !=s->in_ch_layout || s->rematrix_volume!=1.0 ||
-                 s->rematrix_custom;
-
 #define RSC 1 //FIXME finetune
     if(!s-> in.ch_count)
         s-> in.ch_count= av_get_channel_layout_nb_channels(s-> in_ch_layout);
@@ -305,7 +378,11 @@
     }
 
     if ((!s->out_ch_layout || !s->in_ch_layout) && s->used_ch_count != s->out.ch_count && !s->rematrix_custom) {
-        av_log(s, AV_LOG_ERROR, "Rematrix is needed but there is not enough information to do it\n");
+        char l1[1024], l2[1024];
+        av_get_channel_layout_string(l1, sizeof(l1), s-> in.ch_count, s-> in_ch_layout);
+        av_get_channel_layout_string(l2, sizeof(l2), s->out.ch_count, s->out_ch_layout);
+        av_log(s, AV_LOG_ERROR, "Rematrix is needed between %s and %s "
+               "but there is not enough information to do it\n", l1, l2);
         return -1;
     }
 
@@ -314,8 +391,10 @@
     s->resample_first= RSC*s->out.ch_count/s->in.ch_count - RSC < s->out_sample_rate/(float)s-> in_sample_rate - 1.0;
 
     s->in_buffer= s->in;
+    s->silence  = s->in;
+    s->drop_temp= s->out;
 
-    if(!s->resample && !s->rematrix && !s->channel_map && !s->dither_method){
+    if(!s->resample && !s->rematrix && !s->channel_map && !s->dither.method){
         s->full_convert = swri_audio_convert_alloc(s->out_sample_fmt,
                                                    s-> in_sample_fmt, s-> in.ch_count, NULL, 0);
         return 0;
@@ -326,6 +405,8 @@
     s->out_convert= swri_audio_convert_alloc(s->out_sample_fmt,
                                              s->int_sample_fmt, s->out.ch_count, NULL, 0);
 
+    if (!s->in_convert || !s->out_convert)
+        return AVERROR(ENOMEM);
 
     s->postin= s->in;
     s->preout= s->out;
@@ -351,15 +432,16 @@
         set_audiodata_fmt(&s->in_buffer, s->int_sample_fmt);
     }
 
-    s->dither = s->preout;
+    if ((ret = swri_dither_init(s, s->out_sample_fmt, s->int_sample_fmt)) < 0)
+        return ret;
 
-    if(s->rematrix || s->dither_method)
+    if(s->rematrix || s->dither.method)
         return swri_rematrix_init(s);
 
     return 0;
 }
 
-static int realloc_audio(AudioData *a, int count){
+int swri_realloc_audio(AudioData *a, int count){
     int i, countb;
     AudioData old;
 
@@ -463,7 +545,7 @@
         int ret, size, consumed;
         if(!s->resample_in_constraint && s->in_buffer_count){
             buf_set(&tmp, &s->in_buffer, s->in_buffer_index);
-            ret= swri_multiple_resample(s->resample, &out, out_count, &tmp, s->in_buffer_count, &consumed);
+            ret= s->resampler->multiple_resample(s->resample, &out, out_count, &tmp, s->in_buffer_count, &consumed);
             out_count -= ret;
             ret_sum += ret;
             buf_set(&out, &out, ret);
@@ -481,9 +563,9 @@
             }
         }
 
-        if(in_count && !s->in_buffer_count){
+        if((s->flushed || in_count) && !s->in_buffer_count){
             s->in_buffer_index=0;
-            ret= swri_multiple_resample(s->resample, &out, out_count, &in, in_count, &consumed);
+            ret= s->resampler->multiple_resample(s->resample, &out, out_count, &in, in_count, &consumed);
             out_count -= ret;
             ret_sum += ret;
             buf_set(&out, &out, ret);
@@ -499,7 +581,7 @@
             copy(&s->in_buffer, &tmp, s->in_buffer_count);
             s->in_buffer_index=0;
         }else
-            if((ret=realloc_audio(&s->in_buffer, size)) < 0)
+            if((ret=swri_realloc_audio(&s->in_buffer, size)) < 0)
                 return ret;
 
         if(in_count){
@@ -539,18 +621,18 @@
 //     in_max= out_count*(int64_t)s->in_sample_rate / s->out_sample_rate + resample_filter_taps;
 //     in_count= FFMIN(in_count, in_in + 2 - s->hist_buffer_count);
 
-    if((ret=realloc_audio(&s->postin, in_count))<0)
+    if((ret=swri_realloc_audio(&s->postin, in_count))<0)
         return ret;
     if(s->resample_first){
         av_assert0(s->midbuf.ch_count == s->used_ch_count);
-        if((ret=realloc_audio(&s->midbuf, out_count))<0)
+        if((ret=swri_realloc_audio(&s->midbuf, out_count))<0)
             return ret;
     }else{
         av_assert0(s->midbuf.ch_count ==  s->out.ch_count);
-        if((ret=realloc_audio(&s->midbuf,  in_count))<0)
+        if((ret=swri_realloc_audio(&s->midbuf,  in_count))<0)
             return ret;
     }
-    if((ret=realloc_audio(&s->preout, out_count))<0)
+    if((ret=swri_realloc_audio(&s->preout, out_count))<0)
         return ret;
 
     postin= &s->postin;
@@ -598,28 +680,54 @@
     }
 
     if(preout != out && out_count){
-        if(s->dither_method){
+        AudioData *conv_src = preout;
+        if(s->dither.method){
             int ch;
             int dither_count= FFMAX(out_count, 1<<16);
-            av_assert0(preout != in);
 
-            if((ret=realloc_audio(&s->dither, dither_count))<0)
+            if (preout == in) {
+                conv_src = &s->dither.temp;
+                if((ret=swri_realloc_audio(&s->dither.temp, dither_count))<0)
+                    return ret;
+            }
+
+            if((ret=swri_realloc_audio(&s->dither.noise, dither_count))<0)
                 return ret;
             if(ret)
-                for(ch=0; ch<s->dither.ch_count; ch++)
-                    swri_get_dither(s, s->dither.ch[ch], s->dither.count, 12345678913579<<ch, s->out_sample_fmt, s->int_sample_fmt);
-            av_assert0(s->dither.ch_count == preout->ch_count);
+                for(ch=0; ch<s->dither.noise.ch_count; ch++)
+                    swri_get_dither(s, s->dither.noise.ch[ch], s->dither.noise.count, 12345678913579<<ch, s->dither.noise.fmt);
+            av_assert0(s->dither.noise.ch_count == preout->ch_count);
 
-            if(s->dither_pos + out_count > s->dither.count)
-                s->dither_pos = 0;
+            if(s->dither.noise_pos + out_count > s->dither.noise.count)
+                s->dither.noise_pos = 0;
 
-            for(ch=0; ch<preout->ch_count; ch++)
-                s->mix_2_1_f(preout->ch[ch], preout->ch[ch], s->dither.ch[ch] + s->dither.bps * s->dither_pos, s->native_one, 0, 0, out_count);
+            if (s->dither.method < SWR_DITHER_NS){
+                if (s->mix_2_1_simd) {
+                    int len1= out_count&~15;
+                    int off = len1 * preout->bps;
 
-            s->dither_pos += out_count;
+                    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);
+                    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);
+                } else {
+                    for(ch=0; ch<preout->ch_count; ch++)
+                        s->mix_2_1_f(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, out_count);
+                }
+            } else {
+                switch(s->int_sample_fmt) {
+                case AV_SAMPLE_FMT_S16P :swri_noise_shaping_int16(s, conv_src, preout, &s->dither.noise, out_count); break;
+                case AV_SAMPLE_FMT_S32P :swri_noise_shaping_int32(s, conv_src, preout, &s->dither.noise, out_count); break;
+                case AV_SAMPLE_FMT_FLTP :swri_noise_shaping_float(s, conv_src, preout, &s->dither.noise, out_count); break;
+                case AV_SAMPLE_FMT_DBLP :swri_noise_shaping_double(s,conv_src, preout, &s->dither.noise, out_count); break;
+                }
+            }
+            s->dither.noise_pos += out_count;
         }
 //FIXME packed doesnt need more than 1 chan here!
-        swri_audio_convert(s->out_convert, out, preout, out_count);
+        swri_audio_convert(s->out_convert, out, conv_src, out_count);
     }
     return out_count;
 }
@@ -629,47 +737,34 @@
     AudioData * in= &s->in;
     AudioData *out= &s->out;
 
-    if(s->drop_output > 0){
+    while(s->drop_output > 0){
         int ret;
-        AudioData tmp = s->out;
         uint8_t *tmp_arg[SWR_CH_MAX];
-        tmp.count = 0;
-        tmp.data  = NULL;
-        if((ret=realloc_audio(&tmp, s->drop_output))<0)
+#define MAX_DROP_STEP 16384
+        if((ret=swri_realloc_audio(&s->drop_temp, FFMIN(s->drop_output, MAX_DROP_STEP)))<0)
             return ret;
 
-        reversefill_audiodata(&tmp, tmp_arg);
+        reversefill_audiodata(&s->drop_temp, tmp_arg);
         s->drop_output *= -1; //FIXME find a less hackish solution
-        ret = swr_convert(s, tmp_arg, -s->drop_output, 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 doesnt matter
         s->drop_output *= -1;
-        if(ret>0)
+        in_count = 0;
+        if(ret>0) {
             s->drop_output -= ret;
+            continue;
+        }
 
-        av_freep(&tmp.data);
         if(s->drop_output || !out_arg)
             return 0;
-        in_count = 0;
     }
 
     if(!in_arg){
-        if(s->in_buffer_count){
-            if (s->resample && !s->flushed) {
-                AudioData *a= &s->in_buffer;
-                int i, j, ret;
-                if((ret=realloc_audio(a, s->in_buffer_index + 2*s->in_buffer_count)) < 0)
-                    return ret;
-                av_assert0(a->planar);
-                for(i=0; i<a->ch_count; i++){
-                    for(j=0; j<s->in_buffer_count; j++){
-                        memcpy(a->ch[i] + (s->in_buffer_index+s->in_buffer_count+j  )*a->bps,
-                            a->ch[i] + (s->in_buffer_index+s->in_buffer_count-j-1)*a->bps, a->bps);
-                    }
-                }
-                s->in_buffer_count += (s->in_buffer_count+1)/2;
-                s->resample_in_constraint = 0;
-                s->flushed = 1;
-            }
-        }else{
+        if(s->resample){
+            if (!s->flushed)
+                s->resampler->flush(s);
+            s->resample_in_constraint = 0;
+            s->flushed = 1;
+        }else if(!s->in_buffer_count){
             return 0;
         }
     }else
@@ -711,7 +806,7 @@
                     copy(&s->in_buffer, &tmp, s->in_buffer_count);
                     s->in_buffer_index=0;
                 }else
-                    if((ret=realloc_audio(&s->in_buffer, size)) < 0)
+                    if((ret=swri_realloc_audio(&s->in_buffer, size)) < 0)
                         return ret;
             }
 
@@ -748,40 +843,75 @@
 
 int swr_inject_silence(struct SwrContext *s, int count){
     int ret, i;
-    AudioData silence = s->in;
     uint8_t *tmp_arg[SWR_CH_MAX];
 
     if(count <= 0)
         return 0;
 
-    silence.count = 0;
-    silence.data  = NULL;
-    if((ret=realloc_audio(&silence, count))<0)
+#define MAX_SILENCE_STEP 16384
+    while (count > MAX_SILENCE_STEP) {
+        if ((ret = swr_inject_silence(s, MAX_SILENCE_STEP)) < 0)
+            return ret;
+        count -= MAX_SILENCE_STEP;
+    }
+
+    if((ret=swri_realloc_audio(&s->silence, count))<0)
         return ret;
 
-    if(silence.planar) for(i=0; i<silence.ch_count; i++) {
-        memset(silence.ch[i], silence.bps==1 ? 0x80 : 0, count*silence.bps);
+    if(s->silence.planar) for(i=0; i<s->silence.ch_count; i++) {
+        memset(s->silence.ch[i], s->silence.bps==1 ? 0x80 : 0, count*s->silence.bps);
     } else
-        memset(silence.ch[0], silence.bps==1 ? 0x80 : 0, count*silence.bps*silence.ch_count);
+        memset(s->silence.ch[0], s->silence.bps==1 ? 0x80 : 0, count*s->silence.bps*s->silence.ch_count);
 
-    reversefill_audiodata(&silence, tmp_arg);
+    reversefill_audiodata(&s->silence, tmp_arg);
     av_log(s, AV_LOG_VERBOSE, "adding %d audio samples of silence\n", count);
     ret = swr_convert(s, NULL, 0, (const uint8_t**)tmp_arg, count);
-    av_freep(&silence.data);
     return ret;
 }
 
+int64_t swr_get_delay(struct SwrContext *s, int64_t base){
+    if (s->resampler && s->resample){
+        return s->resampler->get_delay(s, base);
+    }else{
+        return (s->in_buffer_count*base + (s->in_sample_rate>>1))/ s->in_sample_rate;
+    }
+}
+
+int swr_set_compensation(struct SwrContext *s, int sample_delta, int compensation_distance){
+    int ret;
+
+    if (!s || compensation_distance < 0)
+        return AVERROR(EINVAL);
+    if (!compensation_distance && sample_delta)
+        return AVERROR(EINVAL);
+    if (!s->resample) {
+        s->flags |= SWR_FLAG_RESAMPLE;
+        ret = swr_init(s);
+        if (ret < 0)
+            return ret;
+    }
+    if (!s->resampler->set_compensation){
+        return AVERROR(EINVAL);
+    }else{
+        return s->resampler->set_compensation(s->resample, sample_delta, compensation_distance);
+    }
+}
+
 int64_t swr_next_pts(struct SwrContext *s, int64_t pts){
     if(pts == INT64_MIN)
         return s->outpts;
+
+    if (s->firstpts == AV_NOPTS_VALUE)
+        s->outpts = s->firstpts = pts;
+
     if(s->min_compensation >= FLT_MAX) {
         return (s->outpts = pts - swr_get_delay(s, s->in_sample_rate * (int64_t)s->out_sample_rate));
     } else {
-        int64_t delta = pts - swr_get_delay(s, s->in_sample_rate * (int64_t)s->out_sample_rate) - s->outpts;
+        int64_t delta = pts - swr_get_delay(s, s->in_sample_rate * (int64_t)s->out_sample_rate) - s->outpts + s->drop_output*(int64_t)s->in_sample_rate;
         double fdelta = delta /(double)(s->in_sample_rate * (int64_t)s->out_sample_rate);
 
         if(fabs(fdelta) > s->min_compensation) {
-            if(!s->outpts || fabs(fdelta) > s->min_hard_compensation){
+            if(s->outpts == s->firstpts || fabs(fdelta) > s->min_hard_compensation){
                 int ret;
                 if(delta > 0) ret = swr_inject_silence(s,  delta / s->out_sample_rate);
                 else          ret = swr_drop_output   (s, -delta / s-> in_sample_rate);
diff --git a/libswresample/swresample.h b/libswresample/swresample.h
index 6dd8a47..95e8a5a 100644
--- a/libswresample/swresample.h
+++ b/libswresample/swresample.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2012 Michael Niedermayer (michaelni@gmx.at)
+ * Copyright (C) 2011-2013 Michael Niedermayer (michaelni@gmx.at)
  *
  * This file is part of libswresample
  *
@@ -23,6 +23,7 @@
 
 /**
  * @file
+ * @ingroup lswr
  * libswresample public header
  */
 
@@ -47,8 +48,8 @@
  * av_opt_set_int(swr, "out_channel_layout", AV_CH_LAYOUT_STEREO,  0);
  * av_opt_set_int(swr, "in_sample_rate",     48000,                0);
  * av_opt_set_int(swr, "out_sample_rate",    44100,                0);
- * av_opt_set_sample_fmt(swr, "in_sample_fmt", AV_SAMPLE_FMT_FLTP, 0);
- * av_opt_set_sample_fmt(swr, "out_sample_fmt, AV_SAMPLE_FMT_S16,  0);
+ * av_opt_set_sample_fmt(swr, "in_sample_fmt",  AV_SAMPLE_FMT_FLTP, 0);
+ * av_opt_set_sample_fmt(swr, "out_sample_fmt", AV_SAMPLE_FMT_S16,  0);
  * @endcode
  *
  * Once all values have been set, it must be initialized with swr_init(). If
@@ -110,9 +111,25 @@
     SWR_DITHER_RECTANGULAR,
     SWR_DITHER_TRIANGULAR,
     SWR_DITHER_TRIANGULAR_HIGHPASS,
+
+    SWR_DITHER_NS = 64,         ///< not part of API/ABI
+    SWR_DITHER_NS_LIPSHITZ,
+    SWR_DITHER_NS_F_WEIGHTED,
+    SWR_DITHER_NS_MODIFIED_E_WEIGHTED,
+    SWR_DITHER_NS_IMPROVED_E_WEIGHTED,
+    SWR_DITHER_NS_SHIBATA,
+    SWR_DITHER_NS_LOW_SHIBATA,
+    SWR_DITHER_NS_HIGH_SHIBATA,
     SWR_DITHER_NB,              ///< not part of API/ABI
 };
 
+/** Resampling Engines */
+enum SwrEngine {
+    SWR_ENGINE_SWR,             /**< SW Resampler */
+    SWR_ENGINE_SOXR,            /**< SoX Resampler */
+    SWR_ENGINE_NB,              ///< not part of API/ABI
+};
+
 /** Resampling Filter Types */
 enum SwrFilterType {
     SWR_FILTER_TYPE_CUBIC,              /**< Cubic */
diff --git a/libswresample/swresample_internal.h b/libswresample/swresample_internal.h
index 459b1b0..17b85d5 100644
--- a/libswresample/swresample_internal.h
+++ b/libswresample/swresample_internal.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2012 Michael Niedermayer (michaelni@gmx.at)
+ * Copyright (C) 2011-2013 Michael Niedermayer (michaelni@gmx.at)
  *
  * This file is part of libswresample
  *
@@ -27,6 +27,8 @@
 
 #define SQRT3_2      1.22474487139158904909  /* sqrt(3/2) */
 
+#define NS_TAPS 20
+
 #if ARCH_X86_64
 typedef int64_t integer;
 #else
@@ -48,6 +50,22 @@
     enum AVSampleFormat fmt;    ///< sample format
 } AudioData;
 
+struct DitherContext {
+    enum SwrDitherType method;
+    int noise_pos;
+    float scale;
+    float noise_scale;                              ///< Noise scale
+    int ns_taps;                                    ///< Noise shaping dither taps
+    float ns_scale;                                 ///< Noise shaping dither scale
+    float ns_scale_1;                               ///< Noise shaping dither scale^-1
+    int ns_pos;                                     ///< Noise shaping dither position
+    float ns_coeffs[NS_TAPS];                       ///< Noise shaping filter coefficients
+    float ns_errors[SWR_CH_MAX][2*NS_TAPS];
+    AudioData noise;                                ///< noise used for dithering
+    AudioData temp;                                 ///< temporary storage when writing into the input buffer isnt possible
+    int output_sample_bits;                         ///< the number of used output bits, needed to scale dither correctly
+};
+
 struct SwrContext {
     const AVClass *av_class;                        ///< AVClass used for AVOption and av_log()
     int log_level_offset;                           ///< logging level offset
@@ -67,20 +85,25 @@
     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)
-    enum SwrDitherType dither_method;
-    int dither_pos;
-    float dither_scale;
+    enum SwrEngine engine;
+
+    struct DitherContext dither;
+
     int filter_size;                                /**< length of each FIR filter in the resampling filterbank relative to the cutoff frequency */
     int phase_shift;                                /**< log2 of the number of entries in the resampling polyphase filterbank */
     int linear_interp;                              /**< if 1 then the resampling FIR filter will be linearly interpolated */
-    double cutoff;                                  /**< resampling cutoff frequency. 1.0 corresponds to half the output sample rate */
-    enum SwrFilterType filter_type;                 /**< resampling filter type */
-    int kaiser_beta;                                /**< beta value for Kaiser window (only applicable if filter_type == AV_FILTER_TYPE_KAISER) */
+    double cutoff;                                  /**< resampling cutoff frequency (swr: 6dB point; soxr: 0dB point). 1.0 corresponds to half the output sample rate */
+    enum SwrFilterType filter_type;                 /**< swr resampling filter type */
+    int kaiser_beta;                                /**< swr beta value for Kaiser window (only applicable if filter_type == AV_FILTER_TYPE_KAISER) */
+    double precision;                               /**< soxr resampling precision (in bits) */
+    int cheby;                                      /**< soxr: if 1 then passband rolloff will be none (Chebyshev) & irrational ratio approximation precision will be higher */
 
-    float min_compensation;                         ///< minimum below which no compensation will happen
-    float min_hard_compensation;                    ///< minimum below which no silence inject / sample drop will happen
-    float soft_compensation_duration;               ///< duration over which soft compensation is applied
-    float max_soft_compensation;                    ///< maximum soft compensation in seconds over soft_compensation_duration
+    float min_compensation;                         ///< swr minimum below which no compensation will happen
+    float min_hard_compensation;                    ///< swr minimum below which no silence inject / sample drop will happen
+    float soft_compensation_duration;               ///< swr duration over which soft compensation is applied
+    float max_soft_compensation;                    ///< swr maximum soft compensation in seconds over soft_compensation_duration
+    float async;                                    ///< swr simple 1 parameter async, similar to ffmpegs -async
+    int64_t firstpts_in_samples;                    ///< swr first pts in samples
 
     int resample_first;                             ///< 1 if resampling must come first, 0 if rematrixing
     int rematrix;                                   ///< flag to indicate if rematrixing is needed (basically if input and output layouts mismatch)
@@ -92,18 +115,21 @@
     AudioData preout;                               ///< pre-output audio data: used for rematrix/resample
     AudioData out;                                  ///< converted output audio data
     AudioData in_buffer;                            ///< cached audio data (convert and resample purpose)
-    AudioData dither;                               ///< noise used for dithering
+    AudioData silence;                              ///< temporary with silence
+    AudioData drop_temp;                            ///< temporary used to discard output
     int in_buffer_index;                            ///< cached buffer position
     int in_buffer_count;                            ///< cached buffer length
     int resample_in_constraint;                     ///< 1 if the input end was reach before the output end, 0 otherwise
     int flushed;                                    ///< 1 if data is to be flushed and no further input is expected
     int64_t outpts;                                 ///< output PTS
+    int64_t firstpts;                               ///< first PTS
     int drop_output;                                ///< number of output samples to drop
 
     struct AudioConvert *in_convert;                ///< input conversion context
     struct AudioConvert *out_convert;               ///< output conversion context
     struct AudioConvert *full_convert;              ///< full conversion context (single conversion for input and output)
     struct ResampleContext *resample;               ///< resampling context
+    struct Resampler const *resampler;              ///< resampler virtual function table
 
     float matrix[SWR_CH_MAX][SWR_CH_MAX];           ///< floating point rematrixing coefficients
     uint8_t *native_matrix;
@@ -122,21 +148,43 @@
     /* TODO: callbacks for ASM optimizations */
 };
 
-struct ResampleContext *swri_resample_init(struct ResampleContext *, int out_rate, int in_rate, int filter_size, int phase_shift, int linear, double cutoff, enum AVSampleFormat, enum SwrFilterType, int kaiser_beta);
-void swri_resample_free(struct ResampleContext **c);
-int swri_multiple_resample(struct ResampleContext *c, AudioData *dst, int dst_size, AudioData *src, int src_size, int *consumed);
-void swri_resample_compensate(struct ResampleContext *c, int sample_delta, int compensation_distance);
+typedef struct ResampleContext * (* resample_init_func)(struct ResampleContext *c, int out_rate, int in_rate, int filter_size, int phase_shift, int linear,
+                                    double cutoff, enum AVSampleFormat format, enum SwrFilterType filter_type, int kaiser_beta, double precision, int cheby);
+typedef void    (* resample_free_func)(struct ResampleContext **c);
+typedef int     (* multiple_resample_func)(struct ResampleContext *c, AudioData *dst, int dst_size, AudioData *src, int src_size, int *consumed);
+typedef int     (* resample_flush_func)(struct SwrContext *c);
+typedef int     (* set_compensation_func)(struct ResampleContext *c, int sample_delta, int compensation_distance);
+typedef int64_t (* get_delay_func)(struct SwrContext *s, int64_t base);
+
+struct Resampler {
+  resample_init_func            init;
+  resample_free_func            free;
+  multiple_resample_func        multiple_resample;
+  resample_flush_func           flush;
+  set_compensation_func         set_compensation;
+  get_delay_func                get_delay;
+};
+
+extern struct Resampler const swri_resampler;
+
+int swri_realloc_audio(AudioData *a, int count);
 int swri_resample_int16(struct ResampleContext *c, int16_t *dst, const int16_t *src, int *consumed, int src_size, int dst_size, int update_ctx);
 int swri_resample_int32(struct ResampleContext *c, int32_t *dst, const int32_t *src, int *consumed, int src_size, int dst_size, int update_ctx);
 int swri_resample_float(struct ResampleContext *c, float   *dst, const float   *src, int *consumed, int src_size, int dst_size, int update_ctx);
 int swri_resample_double(struct ResampleContext *c,double  *dst, const double  *src, int *consumed, int src_size, int dst_size, int update_ctx);
 
+void swri_noise_shaping_int16 (SwrContext *s, AudioData *dsts, const AudioData *srcs, const AudioData *noises, int count);
+void swri_noise_shaping_int32 (SwrContext *s, AudioData *dsts, const AudioData *srcs, const AudioData *noises, int count);
+void swri_noise_shaping_float (SwrContext *s, AudioData *dsts, const AudioData *srcs, const AudioData *noises, int count);
+void swri_noise_shaping_double(SwrContext *s, AudioData *dsts, const AudioData *srcs, const AudioData *noises, int count);
+
 int swri_rematrix_init(SwrContext *s);
 void swri_rematrix_free(SwrContext *s);
 int swri_rematrix(SwrContext *s, AudioData *out, AudioData *in, int len, int mustcopy);
 void swri_rematrix_init_x86(struct SwrContext *s);
 
-void swri_get_dither(SwrContext *s, void *dst, int len, unsigned seed, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt);
+void swri_get_dither(SwrContext *s, void *dst, int len, unsigned seed, enum AVSampleFormat noise_fmt);
+int swri_dither_init(SwrContext *s, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt);
 
 void swri_audio_convert_init_arm(struct AudioConvert *ac,
                                  enum AVSampleFormat out_fmt,
diff --git a/libswscale/input.c b/libswscale/input.c
index d3aeb22..2def2de 100644
--- a/libswscale/input.c
+++ b/libswscale/input.c
@@ -729,7 +729,7 @@
         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);
+        dst[i] = ((RY * r + GY * g + BY * b + (33 << (RGB2YUV_SHIFT + bpc - 9))) >> (RGB2YUV_SHIFT + bpc - 14));
     }
 }
 
@@ -796,8 +796,8 @@
         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;
-        dstV[i] = (RV * r + GV * g + BV * b + (257 << (RGB2YUV_SHIFT + bpc - 9))) >> RGB2YUV_SHIFT;
+        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);
     }
 }
 #undef rdpx
diff --git a/libswscale/options.c b/libswscale/options.c
index f7d261c..fc571ac 100644
--- a/libswscale/options.c
+++ b/libswscale/options.c
@@ -51,6 +51,7 @@
     { "full_chroma_int", "full chroma interpolation",     0,                 AV_OPT_TYPE_CONST,  { .i64  = SWS_FULL_CHR_H_INT }, INT_MIN, INT_MAX,        VE, "sws_flags" },
     { "full_chroma_inp", "full chroma input",             0,                 AV_OPT_TYPE_CONST,  { .i64  = SWS_FULL_CHR_H_INP }, INT_MIN, INT_MAX,        VE, "sws_flags" },
     { "bitexact",        "",                              0,                 AV_OPT_TYPE_CONST,  { .i64  = SWS_BITEXACT       }, INT_MIN, INT_MAX,        VE, "sws_flags" },
+    { "error_diffusion", "error diffusion dither",        0,                 AV_OPT_TYPE_CONST,  { .i64  = SWS_ERROR_DIFFUSION}, INT_MIN, INT_MAX,        VE, "sws_flags" },
 
     { "srcw",            "source width",                  OFFSET(srcW),      AV_OPT_TYPE_INT,    { .i64 = 16                 }, 1,       INT_MAX,        VE },
     { "srch",            "source height",                 OFFSET(srcH),      AV_OPT_TYPE_INT,    { .i64 = 16                 }, 1,       INT_MAX,        VE },
diff --git a/libswscale/output.c b/libswscale/output.c
index 8c20068..d9745fb 100644
--- a/libswscale/output.c
+++ b/libswscale/output.c
@@ -333,6 +333,7 @@
     const uint8_t * const d128=dither_8x8_220[y&7];
     int i;
     unsigned acc = 0;
+    int err = 0;
 
     for (i = 0; i < dstW; i += 2) {
         int j;
@@ -349,12 +350,25 @@
             Y1 = av_clip_uint8(Y1);
             Y2 = av_clip_uint8(Y2);
         }
-        accumulate_bit(acc, Y1 + d128[(i + 0) & 7]);
-        accumulate_bit(acc, Y2 + d128[(i + 1) & 7]);
+        if (c->flags & SWS_ERROR_DIFFUSION) {
+            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);
+            Y1 -= 220*(acc&1);
+
+            err = Y2 + ((7*Y1 + 1*c->dither_error[0][i+1] + 5*c->dither_error[0][i+2] + 3*c->dither_error[0][i+3] + 8 - 256)>>4);
+            c->dither_error[0][i+1] = Y1;
+            acc = 2*acc + (err >= 128);
+            err -= 220*(acc&1);
+        } else {
+            accumulate_bit(acc, Y1 + d128[(i + 0) & 7]);
+            accumulate_bit(acc, Y2 + d128[(i + 1) & 7]);
+        }
         if ((i & 7) == 6) {
             output_pixel(*dest++, acc);
         }
     }
+    c->dither_error[0][i] = err;
 
     if (i & 6) {
         output_pixel(*dest, acc);
@@ -373,6 +387,29 @@
     int  yalpha1 = 4096 - yalpha;
     int i;
 
+    if (c->flags & SWS_ERROR_DIFFUSION) {
+        int err = 0;
+        int acc = 0;
+        for (i = 0; i < dstW; i +=2) {
+            int Y;
+
+            Y = (buf0[i + 0] * yalpha1 + buf1[i + 0] * yalpha) >> 19;
+            Y += (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 + (Y >= 128);
+            Y -= 220*(acc&1);
+
+            err = (buf0[i + 1] * yalpha1 + buf1[i + 1] * yalpha) >> 19;
+            err += (7*Y + 1*c->dither_error[0][i+1] + 5*c->dither_error[0][i+2] + 3*c->dither_error[0][i+3] + 8 - 256)>>4;
+            c->dither_error[0][i+1] = Y;
+            acc = 2*acc + (err >= 128);
+            err -= 220*(acc&1);
+
+            if ((i & 7) == 6)
+                output_pixel(*dest++, acc);
+        }
+        c->dither_error[0][i] = err;
+    } else {
     for (i = 0; i < dstW; i += 8) {
         int Y, acc = 0;
 
@@ -395,6 +432,7 @@
 
         output_pixel(*dest++, acc);
     }
+    }
 }
 
 static av_always_inline void
@@ -406,9 +444,31 @@
     const uint8_t * const d128 = dither_8x8_220[y & 7];
     int i;
 
+    if (c->flags & SWS_ERROR_DIFFUSION) {
+        int err = 0;
+        int acc = 0;
+        for (i = 0; i < dstW; i +=2) {
+            int Y;
+
+            Y = ((buf0[i + 0] + 64) >> 7);
+            Y += (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 + (Y >= 128);
+            Y -= 220*(acc&1);
+
+            err = ((buf0[i + 1] + 64) >> 7);
+            err += (7*Y + 1*c->dither_error[0][i+1] + 5*c->dither_error[0][i+2] + 3*c->dither_error[0][i+3] + 8 - 256)>>4;
+            c->dither_error[0][i+1] = Y;
+            acc = 2*acc + (err >= 128);
+            err -= 220*(acc&1);
+
+            if ((i & 7) == 6)
+                output_pixel(*dest++, acc);
+        }
+        c->dither_error[0][i] = err;
+    } else {
     for (i = 0; i < dstW; i += 8) {
         int acc = 0;
-
         accumulate_bit(acc, ((buf0[i + 0] + 64) >> 7) + d128[0]);
         accumulate_bit(acc, ((buf0[i + 1] + 64) >> 7) + d128[1]);
         accumulate_bit(acc, ((buf0[i + 2] + 64) >> 7) + d128[2]);
@@ -420,6 +480,7 @@
 
         output_pixel(*dest++, acc);
     }
+    }
 }
 
 #undef output_pixel
@@ -1166,6 +1227,8 @@
 {
     int i;
     int step = (target == AV_PIX_FMT_RGB24 || target == AV_PIX_FMT_BGR24) ? 3 : 4;
+    int err[4] = {0};
+    int isrgb8 = target == AV_PIX_FMT_BGR8 || target == AV_PIX_FMT_RGB8;
 
     for (i = 0; i < dstW; i++) {
         int j;
@@ -1240,9 +1303,48 @@
             dest[2] = R >> 22;
             dest[3] = hasAlpha ? A : 255;
             break;
+        case AV_PIX_FMT_BGR4_BYTE:
+        case AV_PIX_FMT_RGB4_BYTE:
+        case AV_PIX_FMT_BGR8:
+        case AV_PIX_FMT_RGB8:
+        {
+            int r,g,b;
+            R >>= 22;
+            G >>= 22;
+            B >>= 22;
+            R += (7*err[0] + 1*c->dither_error[0][i] + 5*c->dither_error[0][i+1] + 3*c->dither_error[0][i+2])>>4;
+            G += (7*err[1] + 1*c->dither_error[1][i] + 5*c->dither_error[1][i+1] + 3*c->dither_error[1][i+2])>>4;
+            B += (7*err[2] + 1*c->dither_error[2][i] + 5*c->dither_error[2][i+1] + 3*c->dither_error[2][i+2])>>4;
+            c->dither_error[0][i] = err[0];
+            c->dither_error[1][i] = err[1];
+            c->dither_error[2][i] = err[2];
+            r = R >> (isrgb8 ? 5 : 7);
+            g = G >> (isrgb8 ? 5 : 6);
+            b = B >> (isrgb8 ? 6 : 7);
+            r = av_clip(r, 0, isrgb8 ? 7 : 1);
+            g = av_clip(g, 0, isrgb8 ? 7 : 3);
+            b = av_clip(b, 0, isrgb8 ? 3 : 1);
+            err[0] = R - r*(isrgb8 ? 36 : 255);
+            err[1] = G - g*(isrgb8 ? 36 : 85);
+            err[2] = B - b*(isrgb8 ? 85 : 255);
+            if(target == AV_PIX_FMT_BGR4_BYTE) {
+                dest[0] = r + 2*g + 8*b;
+            } else if(target == AV_PIX_FMT_RGB4_BYTE) {
+                dest[0] = b + 2*g + 8*r;
+            } else if(target == AV_PIX_FMT_BGR8) {
+                dest[0] = r + 8*g + 64*b;
+            } else if(target == AV_PIX_FMT_RGB8) {
+                dest[0] = b + 4*g + 32*r;
+            } else
+                av_assert2(0);
+            step = 1;
+            break;}
         }
         dest += step;
     }
+    c->dither_error[0][i] = err[0];
+    c->dither_error[1][i] = err[1];
+    c->dither_error[2][i] = err[2];
 }
 
 #if CONFIG_SMALL
@@ -1265,13 +1367,96 @@
 YUV2RGBWRAPPERX(yuv2, rgb_full, bgr24_full,  AV_PIX_FMT_BGR24, 0)
 YUV2RGBWRAPPERX(yuv2, rgb_full, rgb24_full,  AV_PIX_FMT_RGB24, 0)
 
+YUV2RGBWRAPPERX(yuv2, rgb_full, bgr4_byte_full,  AV_PIX_FMT_BGR4_BYTE, 0)
+YUV2RGBWRAPPERX(yuv2, rgb_full, rgb4_byte_full,  AV_PIX_FMT_RGB4_BYTE, 0)
+YUV2RGBWRAPPERX(yuv2, rgb_full, bgr8_full,   AV_PIX_FMT_BGR8,  0)
+YUV2RGBWRAPPERX(yuv2, rgb_full, rgb8_full,   AV_PIX_FMT_RGB8,  0)
+
+static void
+yuv2gbrp_full_X_c(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 y)
+{
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->dstFormat);
+    int i;
+    int hasAlpha = 0;
+    uint16_t **dest16 = (uint16_t**)dest;
+    int SH = 22 + 7 - desc->comp[0].depth_minus1;
+
+    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;
+
+        for (j = 0; j < lumFilterSize; j++)
+            Y += lumSrc[j][i] * lumFilter[j];
+
+        for (j = 0; j < chrFilterSize; j++) {
+            U += chrUSrc[j][i] * chrFilter[j];
+            V += chrVSrc[j][i] * chrFilter[j];
+        }
+
+        Y >>= 10;
+        U >>= 10;
+        V >>= 10;
+
+        if (hasAlpha) {
+            A = 1 << 18;
+
+            for (j = 0; j < lumFilterSize; j++)
+                A += alpSrc[j][i] * lumFilter[j];
+
+            A >>= 19;
+
+            if (A & 0x100)
+                A = av_clip_uint8(A);
+        }
+
+        Y -= c->yuv2rgb_y_offset;
+        Y *= c->yuv2rgb_y_coeff;
+        Y += 1 << 21;
+        R = Y + V * c->yuv2rgb_v2r_coeff;
+        G = Y + V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
+        B = Y +                            U * c->yuv2rgb_u2b_coeff;
+
+        if ((R | G | B) & 0xC0000000) {
+            R = av_clip_uintp2(R, 30);
+            G = av_clip_uintp2(G, 30);
+            B = av_clip_uintp2(B, 30);
+        }
+
+        if (SH != 22) {
+            dest16[0][i] = G >> SH;
+            dest16[1][i] = B >> SH;
+            dest16[2][i] = R >> SH;
+        } else {
+            dest[0][i] = G >> 22;
+            dest[1][i] = B >> 22;
+            dest[2][i] = R >> 22;
+        }
+    }
+    if (SH != 22 && (!isBE(c->dstFormat)) != (!HAVE_BIGENDIAN)) {
+        for (i = 0; i < dstW; i++) {
+            dest16[0][i] = av_bswap16(dest16[0][i]);
+            dest16[1][i] = av_bswap16(dest16[1][i]);
+            dest16[2][i] = av_bswap16(dest16[2][i]);
+        }
+    }
+}
+
 av_cold void ff_sws_init_output_funcs(SwsContext *c,
                                       yuv2planar1_fn *yuv2plane1,
                                       yuv2planarX_fn *yuv2planeX,
                                       yuv2interleavedX_fn *yuv2nv12cX,
                                       yuv2packed1_fn *yuv2packed1,
                                       yuv2packed2_fn *yuv2packed2,
-                                      yuv2packedX_fn *yuv2packedX)
+                                      yuv2packedX_fn *yuv2packedX,
+                                      yuv2anyX_fn *yuv2anyX)
 {
     enum AVPixelFormat dstFormat = c->dstFormat;
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(dstFormat);
@@ -1365,8 +1550,33 @@
         case AV_PIX_FMT_BGR24:
             *yuv2packedX = yuv2bgr24_full_X_c;
             break;
+        case AV_PIX_FMT_BGR4_BYTE:
+            *yuv2packedX = yuv2bgr4_byte_full_X_c;
+            break;
+        case AV_PIX_FMT_RGB4_BYTE:
+            *yuv2packedX = yuv2rgb4_byte_full_X_c;
+            break;
+        case AV_PIX_FMT_BGR8:
+            *yuv2packedX = yuv2bgr8_full_X_c;
+            break;
+        case AV_PIX_FMT_RGB8:
+            *yuv2packedX = yuv2rgb8_full_X_c;
+            break;
+        case AV_PIX_FMT_GBRP:
+        case AV_PIX_FMT_GBRP9BE:
+        case AV_PIX_FMT_GBRP9LE:
+        case AV_PIX_FMT_GBRP10BE:
+        case AV_PIX_FMT_GBRP10LE:
+        case AV_PIX_FMT_GBRP12BE:
+        case AV_PIX_FMT_GBRP12LE:
+        case AV_PIX_FMT_GBRP14BE:
+        case AV_PIX_FMT_GBRP14LE:
+        case AV_PIX_FMT_GBRP16BE:
+        case AV_PIX_FMT_GBRP16LE:
+            *yuv2anyX = yuv2gbrp_full_X_c;
+            break;
         }
-        if(!*yuv2packedX)
+        if (!*yuv2packedX && !*yuv2anyX)
             goto YUV_PACKED;
     } else {
         YUV_PACKED:
diff --git a/libswscale/ppc/yuv2yuv_altivec.c b/libswscale/ppc/yuv2yuv_altivec.c
index 60d50a7..792deb9 100644
--- a/libswscale/ppc/yuv2yuv_altivec.c
+++ b/libswscale/ppc/yuv2yuv_altivec.c
@@ -1,5 +1,5 @@
 /*
- * AltiVec-enhanced yuv-to-yuv convertion routines.
+ * AltiVec-enhanced yuv-to-yuv conversion routines.
  *
  * Copyright (C) 2004 Romain Dolbeau <romain@dolbeau.org>
  * based on the equivalent C code in swscale.c
diff --git a/libswscale/swscale-test.c b/libswscale/swscale-test.c
index 40dec54..aece61e 100644
--- a/libswscale/swscale-test.c
+++ b/libswscale/swscale-test.c
@@ -51,7 +51,7 @@
      (x) == AV_PIX_FMT_RGB32_1 ||         \
      (x) == AV_PIX_FMT_YUVA420P)
 
-static uint64_t getSSD(uint8_t *src1, uint8_t *src2, int stride1,
+static uint64_t getSSD(const uint8_t *src1, const uint8_t *src2, int stride1,
                        int stride2, int w, int h)
 {
     int x, y;
@@ -124,7 +124,7 @@
             res = -1;
             goto end;
         }
-        sws_scale(srcContext, ref, refStride, 0, h, src, srcStride);
+        sws_scale(srcContext, (const uint8_t * const*)ref, refStride, 0, h, src, srcStride);
         sws_freeContext(srcContext);
 
         cur_srcFormat = srcFormat;
@@ -166,7 +166,7 @@
            flags);
     fflush(stdout);
 
-    sws_scale(dstContext, src, srcStride, 0, srcH, dst, dstStride);
+    sws_scale(dstContext, (const uint8_t * const*)src, srcStride, 0, srcH, dst, dstStride);
 
     for (i = 0; i < 4 && dstStride[i]; i++)
         crc = av_crc(av_crc_get_table(AV_CRC_32_IEEE), crc, dst[i],
@@ -198,7 +198,7 @@
             res = -1;
             goto end;
         }
-        sws_scale(outContext, dst, dstStride, 0, dstH, out, refStride);
+        sws_scale(outContext, (const uint8_t * const*)dst, dstStride, 0, dstH, out, refStride);
 
         ssdY = getSSD(ref[0], out[0], refStride[0], refStride[0], w, h);
         if (hasChroma(srcFormat) && hasChroma(dstFormat)) {
@@ -346,7 +346,7 @@
     enum AVPixelFormat srcFormat = AV_PIX_FMT_NONE;
     enum AVPixelFormat dstFormat = AV_PIX_FMT_NONE;
     uint8_t *rgb_data   = av_malloc(W * H * 4);
-    uint8_t *rgb_src[4] = { rgb_data, NULL, NULL, NULL };
+    const uint8_t * const rgb_src[4] = { rgb_data, NULL, NULL, NULL };
     int rgb_stride[4]   = { 4 * W, 0, 0, 0 };
     uint8_t *data       = av_malloc(4 * W * H);
     uint8_t *src[4]     = { data, data + W * H, data + W * H * 2, data + W * H * 3 };
diff --git a/libswscale/swscale.c b/libswscale/swscale.c
index 632e85a..bb90819 100644
--- a/libswscale/swscale.c
+++ b/libswscale/swscale.c
@@ -148,7 +148,7 @@
     }
 }
 
-// FIXME all pal and rgb srcFormats could do this convertion as well
+// FIXME all pal and rgb srcFormats could do this conversion as well
 // FIXME all scalers more complex than bilinear could do half of this transform
 static void chrRangeToJpeg_c(int16_t *dstU, int16_t *dstV, int width)
 {
@@ -369,6 +369,7 @@
     yuv2packed1_fn yuv2packed1       = c->yuv2packed1;
     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);
     int should_dither                = is9_OR_10BPS(c->srcFormat) ||
@@ -416,7 +417,8 @@
         }
     }
 
-    if ((int)dst[0]%16 || (int)dst[1]%16 || (int)dst[2]%16 || (int)src[0]%16 || (int)src[1]%16 || (int)src[2]%16
+    if (   (uintptr_t)dst[0]%16 || (uintptr_t)dst[1]%16 || (uintptr_t)dst[2]%16
+        || (uintptr_t)src[0]%16 || (uintptr_t)src[1]%16 || (uintptr_t)src[2]%16
         || dstStride[0]%16 || dstStride[1]%16 || dstStride[2]%16 || dstStride[3]%16
         || srcStride[0]%16 || srcStride[1]%16 || srcStride[2]%16 || srcStride[3]%16
     ) {
@@ -556,7 +558,7 @@
             /* hmm looks like we can't use MMX here without overwriting
              * this array's tail */
             ff_sws_init_output_funcs(c, &yuv2plane1, &yuv2planeX, &yuv2nv12cX,
-                                     &yuv2packed1, &yuv2packed2, &yuv2packedX);
+                                     &yuv2packed1, &yuv2packed2, &yuv2packedX, &yuv2anyX);
             use_mmx_vfilter= 0;
         }
 
@@ -586,8 +588,8 @@
 //                             || yuv2planeX == yuv2planeX_8_c) || !ARCH_X86);
 
                 if(use_mmx_vfilter){
-                    vLumFilter= c->lumMmxFilter;
-                    vChrFilter= c->chrMmxFilter;
+                    vLumFilter= (int16_t *)c->lumMmxFilter;
+                    vChrFilter= (int16_t *)c->chrMmxFilter;
                 }
 
                 if (vLumFilterSize == 1) {
@@ -618,7 +620,7 @@
 
                 if (CONFIG_SWSCALE_ALPHA && alpPixBuf) {
                     if(use_mmx_vfilter){
-                        vLumFilter= c->alpMmxFilter;
+                        vLumFilter= (int16_t *)c->alpMmxFilter;
                     }
                     if (vLumFilterSize == 1) {
                         yuv2plane1(alpSrcPtr[0], dest[3], dstW,
@@ -629,9 +631,9 @@
                                    dstW, c->lumDither8, 0);
                     }
                 }
-            } else {
-                av_assert1(lumSrcPtr  + vLumFilterSize - 1 < lumPixBuf  + vLumBufSize * 2);
-                av_assert1(chrUSrcPtr + vChrFilterSize - 1 < chrUPixBuf + vChrBufSize * 2);
+            } else if (yuv2packedX) {
+                av_assert1(lumSrcPtr  + vLumFilterSize - 1 < (const int16_t **)lumPixBuf  + vLumBufSize * 2);
+                av_assert1(chrUSrcPtr + vChrFilterSize - 1 < (const int16_t **)chrUPixBuf + vChrBufSize * 2);
                 if (c->yuv2packed1 && vLumFilterSize == 1 &&
                     vChrFilterSize <= 2) { // unscaled RGB
                     int chrAlpha = vChrFilterSize == 1 ? 0 : vChrFilter[2 * dstY + 1];
@@ -656,6 +658,13 @@
                                 chrUSrcPtr, chrVSrcPtr, vChrFilterSize,
                                 alpSrcPtr, dest[0], dstW, dstY);
                 }
+            } else {
+                av_assert1(!yuv2packed1 && !yuv2packed2);
+                yuv2anyX(c, vLumFilter + dstY * vLumFilterSize,
+                         lumSrcPtr, vLumFilterSize,
+                         vChrFilter + dstY * vChrFilterSize,
+                         chrUSrcPtr, chrVSrcPtr, vChrFilterSize,
+                         alpSrcPtr, dest, dstW, dstY);
             }
         }
     }
@@ -694,7 +703,7 @@
 
     ff_sws_init_output_funcs(c, &c->yuv2plane1, &c->yuv2planeX,
                              &c->yuv2nv12cX, &c->yuv2packed1,
-                             &c->yuv2packed2, &c->yuv2packedX);
+                             &c->yuv2packed2, &c->yuv2packedX, &c->yuv2anyX);
 
     ff_sws_init_input_funcs(c);
 
@@ -789,10 +798,17 @@
                                   const int dstStride[])
 {
     int i, ret;
-    const uint8_t *src2[4] = { srcSlice[0], srcSlice[1], srcSlice[2], srcSlice[3] };
-    uint8_t *dst2[4] = { dst[0], dst[1], dst[2], dst[3] };
+    const uint8_t *src2[4];
+    uint8_t *dst2[4];
     uint8_t *rgb0_tmp = NULL;
 
+    if (!srcSlice || !dstStride || !dst || !srcSlice) {
+        av_log(c, AV_LOG_ERROR, "One of the input parameters to sws_scale() is NULL, please check the calling code\n");
+        return 0;
+    }
+    memcpy(src2, srcSlice, sizeof(src2));
+    memcpy(dst2, dst, sizeof(dst2));
+
     // do not mess up sliceDir if we have a "trailing" 0-size slice
     if (srcSliceH == 0)
         return 0;
@@ -902,6 +918,11 @@
         src2[0] = base;
     }
 
+    if (!srcSliceY && (c->flags & SWS_BITEXACT) && (c->flags & SWS_ERROR_DIFFUSION) && 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));
+
+
     // copy strides, so they can safely be modified
     if (c->sliceDir == 1) {
         // slices go from top to bottom
diff --git a/libswscale/swscale.h b/libswscale/swscale.h
index 5189787..5f6ae0f 100644
--- a/libswscale/swscale.h
+++ b/libswscale/swscale.h
@@ -23,8 +23,13 @@
 
 /**
  * @file
- * @brief
- *     external api for the swscale stuff
+ * @ingroup lsws
+ * external API header
+ */
+
+/**
+ * @defgroup lsws Libswscale
+ * @{
  */
 
 #include <stdint.h>
@@ -77,6 +82,7 @@
 #define SWS_DIRECT_BGR        0x8000
 #define SWS_ACCURATE_RND      0x40000
 #define SWS_BITEXACT          0x80000
+#define SWS_ERROR_DIFFUSION  0x800000
 
 #if FF_API_SWS_CPU_CAPS
 /**
@@ -342,4 +348,8 @@
  */
 const AVClass *sws_get_class(void);
 
+/**
+ * @}
+ */
+
 #endif /* SWSCALE_SWSCALE_H */
diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h
index 6a942d6..83d3a00 100644
--- a/libswscale/swscale_internal.h
+++ b/libswscale/swscale_internal.h
@@ -223,6 +223,40 @@
                                const int16_t **alpSrc, uint8_t *dest,
                                int dstW, int y);
 
+/**
+ * Write one line of horizontally scaled Y/U/V/A to YUV/RGB
+ * output by doing multi-point vertical scaling between input pixels.
+ *
+ * @param c             SWS scaling context
+ * @param lumFilter     vertical luma/alpha scaling coefficients, 12bit [0,4096]
+ * @param lumSrc        scaled luma (Y) source data, 15bit for 8-10bit output,
+ *                      19-bit for 16bit output (in int32_t)
+ * @param lumFilterSize number of vertical luma/alpha input lines to scale
+ * @param chrFilter     vertical chroma scaling coefficients, 12bit [0,4096]
+ * @param chrUSrc       scaled chroma (U) source data, 15bit for 8-10bit output,
+ *                      19-bit for 16bit output (in int32_t)
+ * @param chrVSrc       scaled chroma (V) source data, 15bit for 8-10bit output,
+ *                      19-bit for 16bit output (in int32_t)
+ * @param chrFilterSize number of vertical chroma input lines to scale
+ * @param alpSrc        scaled alpha (A) source data, 15bit for 8-10bit output,
+ *                      19-bit for 16bit output (in int32_t)
+ * @param dest          pointer to the output planes. For 16bit output, this is
+ *                      uint16_t
+ * @param dstW          width of lumSrc and alpSrc in pixels, number of pixels
+ *                      to write into dest[]
+ * @param y             vertical line number for this output. This does not need
+ *                      to be used to calculate the offset in the destination,
+ *                      but can be used to generate comfort noise using dithering
+ *                      or some output formats.
+ */
+typedef void (*yuv2anyX_fn)(struct 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 y);
+
 /* This struct should be aligned on at least a 32-byte boundary. */
 typedef struct SwsContext {
     /**
@@ -327,6 +361,8 @@
     int table_gV[256 + 2*YUVRGB_TABLE_HEADROOM];
     uint8_t *table_bU[256 + 2*YUVRGB_TABLE_HEADROOM];
 
+    int *dither_error[4];
+
     //Colorspace stuff
     int contrast, brightness, saturation;    // for sws_getColorspaceDetails
     int srcColorspaceTable[4];
@@ -435,6 +471,7 @@
     yuv2packed1_fn yuv2packed1;
     yuv2packed2_fn yuv2packed2;
     yuv2packedX_fn yuv2packedX;
+    yuv2anyX_fn yuv2anyX;
 
     /// Unscaled conversion of luma plane to YV12 for horizontal scaler.
     void (*lumToYV12)(uint8_t *dst, const uint8_t *src, const uint8_t *src2, const uint8_t *src3,
@@ -679,6 +716,15 @@
     (           \
           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     \
     )
 
@@ -686,7 +732,7 @@
 {
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
     av_assert0(desc);
-    return desc->nb_components == 2 || desc->nb_components == 4;
+    return desc->flags & PIX_FMT_ALPHA;
 }
 
 #if 1
@@ -766,7 +812,8 @@
                               yuv2interleavedX_fn *yuv2nv12cX,
                               yuv2packed1_fn *yuv2packed1,
                               yuv2packed2_fn *yuv2packed2,
-                              yuv2packedX_fn *yuv2packedX);
+                              yuv2packedX_fn *yuv2packedX,
+                              yuv2anyX_fn *yuv2anyX);
 void ff_sws_init_swScale_altivec(SwsContext *c);
 void ff_sws_init_swScale_mmx(SwsContext *c);
 
diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c
index f35d1ba..8da73b2 100644
--- a/libswscale/swscale_unscaled.c
+++ b/libswscale/swscale_unscaled.c
@@ -488,6 +488,80 @@
     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)
+{
+    uint8_t *dest[3];
+    int x, h;
+
+    dest[0] = dst[0];
+    dest[1] = dst[1];
+    dest[2] = dst[2];
+
+    if (alpha_first)
+        src++;
+
+    for (h = 0; h < srcSliceH; h++) {
+        for (x = 0; x < width; x++) {
+            dest[0][x] = src[0];
+            dest[1][x] = src[1];
+            dest[2][x] = src[2];
+
+            src += inc_size;
+        }
+        src     += srcStride - width * inc_size;
+        dest[0] += dstStride[0];
+        dest[1] += dstStride[1];
+        dest[2] += dstStride[2];
+    }
+}
+
+static int rgbToPlanarRgbWrapper(SwsContext *c, const uint8_t *src[],
+                                 int srcStride[], int srcSliceY, int srcSliceH,
+                                 uint8_t *dst[], int dstStride[])
+{
+    int alpha_first = 0;
+    int stride102[] = { dstStride[1], dstStride[0], dstStride[2] };
+    int stride201[] = { dstStride[2], dstStride[0], dstStride[1] };
+    uint8_t *dst102[] = { dst[1] + srcSliceY * dstStride[1],
+                          dst[0] + srcSliceY * dstStride[0],
+                          dst[2] + srcSliceY * dstStride[2] };
+    uint8_t *dst201[] = { dst[2] + srcSliceY * dstStride[2],
+                          dst[0] + srcSliceY * dstStride[0],
+                          dst[1] + srcSliceY * dstStride[1] };
+
+    switch (c->srcFormat) {
+    case PIX_FMT_RGB24:
+        packedtogbr24p((const uint8_t *) src[0], srcStride[0], dst201,
+                       stride201, srcSliceH, alpha_first, 3, c->srcW);
+        break;
+    case PIX_FMT_BGR24:
+        packedtogbr24p((const uint8_t *) src[0], srcStride[0], dst102,
+                       stride102, srcSliceH, alpha_first, 3, c->srcW);
+        break;
+    case PIX_FMT_ARGB:
+        alpha_first = 1;
+    case PIX_FMT_RGBA:
+        packedtogbr24p((const uint8_t *) src[0], srcStride[0], dst201,
+                       stride201, srcSliceH, alpha_first, 4, c->srcW);
+        break;
+    case PIX_FMT_ABGR:
+        alpha_first = 1;
+    case PIX_FMT_BGRA:
+        packedtogbr24p((const uint8_t *) src[0], srcStride[0], dst102,
+                       stride102, srcSliceH, alpha_first, 4, c->srcW);
+        break;
+    default:
+        av_log(c, AV_LOG_ERROR,
+               "unsupported planar RGB conversion %s -> %s\n",
+               av_get_pix_fmt_name(c->srcFormat),
+               av_get_pix_fmt_name(c->dstFormat));
+    }
+
+    return srcSliceH;
+}
+
 #define isRGBA32(x) (            \
            (x) == AV_PIX_FMT_ARGB   \
         || (x) == AV_PIX_FMT_RGBA   \
@@ -605,6 +679,9 @@
         }
     }
 
+    if ((dstFormat == AV_PIX_FMT_RGB32_1 || dstFormat == AV_PIX_FMT_BGR32_1) && !isRGBA32(srcFormat) && ALT32_CORR<0)
+        return NULL;
+
     return conv;
 }
 
@@ -936,7 +1013,7 @@
     /* yuv2bgr */
     if ((srcFormat == AV_PIX_FMT_YUV420P || srcFormat == AV_PIX_FMT_YUV422P ||
          srcFormat == AV_PIX_FMT_YUVA420P) && isAnyRGB(dstFormat) &&
-        !(flags & SWS_ACCURATE_RND) && !(dstH & 1)) {
+        !(flags & (SWS_ACCURATE_RND|SWS_ERROR_DIFFUSION)) && !(dstH & 1)) {
         c->swScale = ff_yuv2rgb_get_func_ptr(c);
     }
 
@@ -957,17 +1034,21 @@
         && (!needsDither || (c->flags&(SWS_FAST_BILINEAR|SWS_POINT))))
         c->swScale= rgbToRgbWrapper;
 
-#define isByteRGB(f) (\
-        f == AV_PIX_FMT_RGB32   ||\
-        f == AV_PIX_FMT_RGB32_1 ||\
-        f == AV_PIX_FMT_RGB24   ||\
-        f == AV_PIX_FMT_BGR32   ||\
-        f == AV_PIX_FMT_BGR32_1 ||\
+#define isByteRGB(f) (             \
+        f == AV_PIX_FMT_RGB32   || \
+        f == AV_PIX_FMT_RGB32_1 || \
+        f == AV_PIX_FMT_RGB24   || \
+        f == AV_PIX_FMT_BGR32   || \
+        f == AV_PIX_FMT_BGR32_1 || \
         f == AV_PIX_FMT_BGR24)
 
-    if (isAnyRGB(srcFormat) && isPlanar(srcFormat) && isByteRGB(dstFormat))
+    if (srcFormat == AV_PIX_FMT_GBRP && isPlanar(srcFormat) && isByteRGB(dstFormat))
         c->swScale = planarRgbToRgbWrapper;
 
+    if (av_pix_fmt_desc_get(srcFormat)->comp[0].depth_minus1 == 7 &&
+        isPackedRGB(srcFormat) && dstFormat == AV_PIX_FMT_GBRP)
+        c->swScale = rgbToPlanarRgbWrapper;
+
     /* bswap 16 bits per pixel/component packed formats */
     if (IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGR444) ||
         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGR48)  ||
diff --git a/libswscale/utils.c b/libswscale/utils.c
index 7761441..932cf94 100644
--- a/libswscale/utils.c
+++ b/libswscale/utils.c
@@ -185,15 +185,15 @@
     [AV_PIX_FMT_YUV444P12LE] = { 1, 1 },
     [AV_PIX_FMT_YUV444P14BE] = { 1, 1 },
     [AV_PIX_FMT_YUV444P14LE] = { 1, 1 },
-    [AV_PIX_FMT_GBRP]        = { 1, 0 },
-    [AV_PIX_FMT_GBRP9LE]     = { 1, 0 },
-    [AV_PIX_FMT_GBRP9BE]     = { 1, 0 },
-    [AV_PIX_FMT_GBRP10LE]    = { 1, 0 },
-    [AV_PIX_FMT_GBRP10BE]    = { 1, 0 },
-    [AV_PIX_FMT_GBRP12LE]    = { 1, 0 },
-    [AV_PIX_FMT_GBRP12BE]    = { 1, 0 },
-    [AV_PIX_FMT_GBRP14LE]    = { 1, 0 },
-    [AV_PIX_FMT_GBRP14BE]    = { 1, 0 },
+    [AV_PIX_FMT_GBRP]        = { 1, 1 },
+    [AV_PIX_FMT_GBRP9LE]     = { 1, 1 },
+    [AV_PIX_FMT_GBRP9BE]     = { 1, 1 },
+    [AV_PIX_FMT_GBRP10LE]    = { 1, 1 },
+    [AV_PIX_FMT_GBRP10BE]    = { 1, 1 },
+    [AV_PIX_FMT_GBRP12LE]    = { 1, 1 },
+    [AV_PIX_FMT_GBRP12BE]    = { 1, 1 },
+    [AV_PIX_FMT_GBRP14LE]    = { 1, 1 },
+    [AV_PIX_FMT_GBRP14BE]    = { 1, 1 },
     [AV_PIX_FMT_GBRP16LE]    = { 1, 0 },
     [AV_PIX_FMT_GBRP16BE]    = { 1, 0 },
 };
@@ -888,8 +888,10 @@
 {
     SwsContext *c = av_mallocz(sizeof(SwsContext));
 
-    c->av_class = &sws_context_class;
-    av_opt_set_defaults(c);
+    if (c) {
+        c->av_class = &sws_context_class;
+        av_opt_set_defaults(c);
+    }
 
     return c;
 }
@@ -989,7 +991,6 @@
     getSubSampleFactors(&c->chrSrcHSubSample, &c->chrSrcVSubSample, srcFormat);
     getSubSampleFactors(&c->chrDstHSubSample, &c->chrDstVSubSample, dstFormat);
 
-
     if (isAnyRGB(dstFormat) && !(flags&SWS_FULL_CHR_H_INT)) {
         if (dstW&1) {
             av_log(c, AV_LOG_DEBUG, "Forcing full internal H chroma due to odd output size\n");
@@ -997,16 +998,52 @@
             c->flags = flags;
         }
     }
+
+    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 (!(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 (isPlanarRGB(dstFormat)) {
+        if (!(flags & SWS_FULL_CHR_H_INT)) {
+            av_log(c, AV_LOG_DEBUG,
+                   "%s output is not supported with half chroma resolution, switching to full\n",
+                   av_get_pix_fmt_name(dstFormat));
+            flags   |= SWS_FULL_CHR_H_INT;
+            c->flags = flags;
+        }
+    }
+
     /* reuse chroma for 2 pixels RGB/BGR unless user wants full
      * chroma interpolation */
     if (flags & SWS_FULL_CHR_H_INT &&
         isAnyRGB(dstFormat)        &&
+        !isPlanarRGB(dstFormat)    &&
         dstFormat != AV_PIX_FMT_RGBA  &&
         dstFormat != AV_PIX_FMT_ARGB  &&
         dstFormat != AV_PIX_FMT_BGRA  &&
         dstFormat != AV_PIX_FMT_ABGR  &&
         dstFormat != AV_PIX_FMT_RGB24 &&
-        dstFormat != AV_PIX_FMT_BGR24) {
+        dstFormat != AV_PIX_FMT_BGR24 &&
+        dstFormat != AV_PIX_FMT_BGR4_BYTE &&
+        dstFormat != AV_PIX_FMT_RGB4_BYTE &&
+        dstFormat != AV_PIX_FMT_BGR8 &&
+        dstFormat != AV_PIX_FMT_RGB8
+    ) {
         av_log(c, AV_LOG_WARNING,
                "full chroma interpolation for destination format '%s' not yet implemented\n",
                av_get_pix_fmt_name(dstFormat));
@@ -1027,6 +1064,11 @@
         srcFormat != AV_PIX_FMT_RGB8 && srcFormat != AV_PIX_FMT_BGR8 &&
         srcFormat != AV_PIX_FMT_RGB4 && srcFormat != AV_PIX_FMT_BGR4 &&
         srcFormat != AV_PIX_FMT_RGB4_BYTE && srcFormat != AV_PIX_FMT_BGR4_BYTE &&
+        srcFormat != AV_PIX_FMT_GBRP9BE   && srcFormat != AV_PIX_FMT_GBRP9LE  &&
+        srcFormat != AV_PIX_FMT_GBRP10BE  && srcFormat != AV_PIX_FMT_GBRP10LE &&
+        srcFormat != AV_PIX_FMT_GBRP12BE  && srcFormat != AV_PIX_FMT_GBRP12LE &&
+        srcFormat != AV_PIX_FMT_GBRP14BE  && srcFormat != AV_PIX_FMT_GBRP14LE &&
+        srcFormat != AV_PIX_FMT_GBRP16BE  && srcFormat != AV_PIX_FMT_GBRP16LE &&
         ((dstW >> c->chrDstHSubSample) <= (srcW >> 1) ||
          (flags & SWS_FAST_BILINEAR)))
         c->chrSrcHSubSample = 1;
@@ -1245,6 +1287,9 @@
                              c->vChrFilterPos[chrI];
     }
 
+    for (i = 0; i < 4; i++)
+        FF_ALLOCZ_OR_GOTO(c, c->dither_error[i], (c->dstW+2) * sizeof(int), fail);
+
     /* Allocate pixbufs (we use dynamic allocation because otherwise we would
      * need to allocate several megabytes to handle all possible cases) */
     FF_ALLOC_OR_GOTO(c, c->lumPixBuf,  c->vLumBufSize * 3 * sizeof(int16_t *), fail);
@@ -1738,6 +1783,9 @@
         av_freep(&c->alpPixBuf);
     }
 
+    for (i = 0; i < 4; i++)
+        av_freep(&c->dither_error[i]);
+
     av_freep(&c->vLumFilter);
     av_freep(&c->vChrFilter);
     av_freep(&c->hLumFilter);
diff --git a/libswscale/version.h b/libswscale/version.h
index 49e280d..c430f2d 100644
--- a/libswscale/version.h
+++ b/libswscale/version.h
@@ -27,8 +27,8 @@
 #include "libavutil/avutil.h"
 
 #define LIBSWSCALE_VERSION_MAJOR 2
-#define LIBSWSCALE_VERSION_MINOR 1
-#define LIBSWSCALE_VERSION_MICRO 103
+#define LIBSWSCALE_VERSION_MINOR 2
+#define LIBSWSCALE_VERSION_MICRO 100
 
 #define LIBSWSCALE_VERSION_INT  AV_VERSION_INT(LIBSWSCALE_VERSION_MAJOR, \
                                                LIBSWSCALE_VERSION_MINOR, \
diff --git a/libswscale/x86/input.asm b/libswscale/x86/input.asm
index 327b9f0..9d5a871 100644
--- a/libswscale/x86/input.asm
+++ b/libswscale/x86/input.asm
@@ -98,7 +98,7 @@
 %define coeff2 [%2_Ycoeff_3x56]
 %endif ; x86-32/64 && mmsize == 8/16
 %if (ARCH_X86_64 || mmsize == 8) && %0 == 3
-    jmp mangle(program_name %+ _ %+ %3 %+ 24ToY %+ SUFFIX).body
+    jmp mangle(private_prefix %+ _ %+ %3 %+ 24ToY %+ SUFFIX).body
 %else ; (ARCH_X86_64 && %0 == 3) || mmsize == 8
 .body:
 %if cpuflag(ssse3)
@@ -188,7 +188,7 @@
 %define coeffV2 [%2_Vcoeff_3x56]
 %endif ; x86-32/64
 %if ARCH_X86_64 && %0 == 3
-    jmp mangle(program_name %+ _ %+ %3 %+ 24ToUV %+ SUFFIX).body
+    jmp mangle(private_prefix %+ _ %+ %3 %+ 24ToUV %+ SUFFIX).body
 %else ; ARCH_X86_64 && %0 == 3
 .body:
 %if cpuflag(ssse3)
@@ -315,7 +315,7 @@
     mova           m5, [rgba_Ycoeff_%2%4]
     mova           m6, [rgba_Ycoeff_%3%5]
 %if %0 == 6
-    jmp mangle(program_name %+ _ %+ %6 %+ ToY %+ SUFFIX).body
+    jmp mangle(private_prefix %+ _ %+ %6 %+ ToY %+ SUFFIX).body
 %else ; %0 == 6
 .body:
 %if ARCH_X86_64
@@ -371,7 +371,7 @@
 %define coeffV2 [rgba_Vcoeff_%3%5]
 %endif ; x86-64/32
 %if ARCH_X86_64 && %0 == 6
-    jmp mangle(program_name %+ _ %+ %6 %+ ToUV %+ SUFFIX).body
+    jmp mangle(private_prefix %+ _ %+ %6 %+ ToUV %+ SUFFIX).body
 %else ; ARCH_X86_64 && %0 == 6
 .body:
 %if ARCH_X86_64
diff --git a/libswscale/x86/swscale.c b/libswscale/x86/swscale.c
index 02c454e..2f67b1b 100644
--- a/libswscale/x86/swscale.c
+++ b/libswscale/x86/swscale.c
@@ -226,10 +226,20 @@
                          :: "r"(dither)
                          );
     }
+    filterSize--;
     __asm__ volatile(
         "pxor      %%xmm0, %%xmm0\n\t"
         "punpcklbw %%xmm0, %%xmm3\n\t"
-        "psraw        $4, %%xmm3\n\t"
+        "movd          %0, %%xmm1\n\t"
+        "punpcklwd %%xmm1, %%xmm1\n\t"
+        "punpckldq %%xmm1, %%xmm1\n\t"
+        "punpcklqdq %%xmm1, %%xmm1\n\t"
+        "psllw         $3, %%xmm1\n\t"
+        "paddw     %%xmm1, %%xmm3\n\t"
+        "psraw         $4, %%xmm3\n\t"
+        ::"m"(filterSize)
+     );
+    __asm__ volatile(
         "movdqa    %%xmm3, %%xmm4\n\t"
         "movdqa    %%xmm3, %%xmm7\n\t"
         "movl %3, %%ecx\n\t"
diff --git a/libswscale/x86/swscale_template.c b/libswscale/x86/swscale_template.c
index 62265db..f2567c1 100644
--- a/libswscale/x86/swscale_template.c
+++ b/libswscale/x86/swscale_template.c
@@ -71,9 +71,20 @@
                            const uint8_t *dither, int offset)
 {
     dither_8to16(dither, offset);
-    __asm__ volatile(\
+    filterSize--;
+    __asm__ volatile(
+        "movd %0, %%mm1\n\t"
+        "punpcklwd %%mm1, %%mm1\n\t"
+        "punpckldq %%mm1, %%mm1\n\t"
+        "psllw        $3, %%mm1\n\t"
+        "paddw     %%mm1, %%mm3\n\t"
+        "paddw     %%mm1, %%mm4\n\t"
         "psraw        $4, %%mm3\n\t"
         "psraw        $4, %%mm4\n\t"
+        ::"m"(filterSize)
+     );
+
+    __asm__ volatile(\
         "movq    %%mm3, %%mm6\n\t"
         "movq    %%mm4, %%mm7\n\t"
         "movl %3, %%ecx\n\t"
diff --git a/libswscale/yuv2rgb.c b/libswscale/yuv2rgb.c
index 53b69d0..d12abda 100644
--- a/libswscale/yuv2rgb.c
+++ b/libswscale/yuv2rgb.c
@@ -919,7 +919,8 @@
         break;
     default:
         c->yuvTable = NULL;
-        av_log(c, AV_LOG_ERROR, "%ibpp not supported by yuv2rgb\n", bpp);
+        if(!isPlanar(c->dstFormat) || bpp <= 24)
+            av_log(c, AV_LOG_ERROR, "%ibpp not supported by yuv2rgb\n", bpp);
         return -1;
     }
     return 0;
diff --git a/tests/Makefile b/tests/Makefile
index dfb12b0..73ee2d9 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -81,23 +81,23 @@
 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/ffmpeg.mak
 include $(SRC_PATH)/tests/fate/ffprobe.mak
 include $(SRC_PATH)/tests/fate/filter.mak
 include $(SRC_PATH)/tests/fate/flac.mak
 include $(SRC_PATH)/tests/fate/fft.mak
+include $(SRC_PATH)/tests/fate/gif.mak
 include $(SRC_PATH)/tests/fate/h264.mak
 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/libavformat.mak
 include $(SRC_PATH)/tests/fate/libavutil.mak
-include $(SRC_PATH)/tests/fate/mapchan.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/mp3.mak
 include $(SRC_PATH)/tests/fate/mpc.mak
-include $(SRC_PATH)/tests/fate/options.mak
 include $(SRC_PATH)/tests/fate/pcm.mak
 include $(SRC_PATH)/tests/fate/probe.mak
 include $(SRC_PATH)/tests/fate/prores.mak
@@ -120,11 +120,15 @@
 FATE-$(CONFIG_FFPROBE) += $(FATE_FFPROBE)
 
 FATE_SAMPLES_AVCONV           += $(FATE_SAMPLES_AVCONV-yes)
+FATE_SAMPLES_FFMPEG           += $(FATE_SAMPLES_FFMPEG-yes)
 FATE_EXTERN-$(CONFIG_FFMPEG)  += $(FATE_SAMPLES_AVCONV) $(FATE_SAMPLES_FFMPEG) $(FATE_SAMPLES_FFPROBE)
 FATE_EXTERN += $(FATE_EXTERN-yes)
 
 FATE += $(FATE-yes)
 
+RSYNC_OPTIONS-$(HAVE_RSYNC_CONTIMEOUT) += --contimeout=60
+RSYNC_OPTIONS = -vrltLW --timeout=60 $(RSYNC_OPTIONS-yes)
+
 $(FATE_FFMPEG) $(FATE_SAMPLES_AVCONV) $(FATE_SAMPLES_FFMPEG): ffmpeg$(EXESUF)
 
 $(FATE_FFPROBE) $(FATE_SAMPLES_FFPROBE): ffprobe$(EXESUF)
@@ -133,7 +137,7 @@
 FATE += $(FATE_FULL) $(FATE_FULL-yes)
 FATE += $(FATE_EXTERN)
 fate-rsync:
-	rsync -vrltLW --timeout=60 --contimeout=60 rsync://fate-suite.ffmpeg.org/fate-suite/ $(SAMPLES)
+	rsync $(RSYNC_OPTIONS) rsync://fate-suite.ffmpeg.org/fate-suite/ $(SAMPLES)
 else
 fate::
 	@echo "warning: only a subset of the fate tests will be run because SAMPLES is not specified"
diff --git a/tests/audiogen.c b/tests/audiogen.c
index 07f0be3..09cf429 100644
--- a/tests/audiogen.c
+++ b/tests/audiogen.c
@@ -189,7 +189,7 @@
         a += (1000 * FRAC_ONE) / sample_rate;
     }
 
-    /* 1 second of varing frequency between 100 and 10000 Hz */
+    /* 1 second of varying frequency between 100 and 10000 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 1945d88..0520d62 100755
--- a/tests/fate-run.sh
+++ b/tests/fate-run.sh
@@ -78,7 +78,7 @@
     dec_opts="-threads $threads -thread_type $thread_type"
     ffmpeg_args="-nostats -cpuflags $cpuflags"
     for arg in $@; do
-        [ ${arg} = -i ] && ffmpeg_args="${ffmpeg_args} ${dec_opts}"
+        [ x${arg} = x-i ] && ffmpeg_args="${ffmpeg_args} ${dec_opts}"
         ffmpeg_args="${ffmpeg_args} ${arg}"
     done
     run ffmpeg ${ffmpeg_args}
@@ -166,6 +166,10 @@
 
 mkdir -p "$outdir"
 
+# Disable globbing: command arguments may contain globbing characters and
+# must be kept verbatim
+set -f
+
 exec 3>&2
 eval $command >"$outfile" 2>$errfile
 err=$?
diff --git a/tests/fate/ac3.mak b/tests/fate/ac3.mak
index 2985a0e..90dfc41 100644
--- a/tests/fate/ac3.mak
+++ b/tests/fate/ac3.mak
@@ -1,46 +1,46 @@
 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: REF = $(SAMPLES)/ac3/monsters_inc_2.0_192_small.pcm
+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: REF = $(SAMPLES)/ac3/millers_crossing_4.0.pcm
+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: REF = $(SAMPLES)/ac3/millers_crossing_4.0_mono.pcm
+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: REF = $(SAMPLES)/ac3/millers_crossing_4.0_stereo.pcm
+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: REF = $(SAMPLES)/ac3/monsters_inc_5.1_448_small.pcm
+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: REF = $(SAMPLES)/ac3/monsters_inc_5.1_448_small_mono.pcm
+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: REF = $(SAMPLES)/ac3/monsters_inc_5.1_448_small_stereo.pcm
+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: REF = $(SAMPLES)/eac3/csi_miami_5.1_256_spx_small.pcm
+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: REF = $(SAMPLES)/eac3/csi_miami_stereo_128_spx_small.pcm
+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: REF = $(SAMPLES)/eac3/matrix2_commentary1_stereo_192_small.pcm
+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: REF = $(SAMPLES)/eac3/serenity_english_5.1_1536_small.pcm
+fate-eac3-4: REF = $(SAMPLES)/eac3/serenity_english_5.1_1536_small_v2.pcm
 
 $(FATE_AC3) $(FATE_EAC3): CMP = oneoff
 
@@ -50,14 +50,14 @@
 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: CMP_SHIFT = -1024
-fate-ac3-encode: CMP_TARGET = 399.62
+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: CMP_SHIFT = -1024
-fate-eac3-encode: CMP_TARGET = 514.02
+fate-eac3-encode: CMP_TARGET = 516.94
 fate-eac3-encode: SIZE_TOLERANCE = 488
 fate-eac3-encode: FUZZ = 3
 
diff --git a/tests/fate/avfilter.mak b/tests/fate/avfilter.mak
index e69d6a1..15c8595 100644
--- a/tests/fate/avfilter.mak
+++ b/tests/fate/avfilter.mak
@@ -11,6 +11,7 @@
              fate-lavfi-fade                                            \
              fate-lavfi-field                                           \
              fate-lavfi-idet                                            \
+             fate-lavfi-il                                              \
              fate-lavfi-life                                            \
              fate-lavfi-null                                            \
              fate-lavfi-overlay                                         \
@@ -41,17 +42,17 @@
 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-$(CONFIG_MP_FILTER) += fate-lavfi-pp                         \
-             fate-lavfi-pp2                                             \
-             fate-lavfi-pp3                                             \
-             fate-lavfi-pp4                                             \
-             fate-lavfi-pp5                                             \
-             fate-lavfi-pp6                                             \
-
 FATE_LAVFI += $(FATE_LAVFI-yes)
 
 $(FATE_LAVFI): $(VREF) libavfilter/filtfmts-test$(EXESUF)
diff --git a/tests/fate/avformat.mak b/tests/fate/avformat.mak
index 77c6a2f..86fb071 100644
--- a/tests/fate/avformat.mak
+++ b/tests/fate/avformat.mak
@@ -1,6 +1,7 @@
 FATE_LAVF-$(call ENCDEC,  PCM_S16BE,             AIFF)               += aiff
 FATE_LAVF-$(call ENCDEC,  PCM_ALAW,              PCM_ALAW)           += alaw
 FATE_LAVF-$(call ENCDEC2, MSMPEG4V3,  MP2,       ASF)                += asf
+FATE_LAVF-$(call ENCDEC,  PCM_S16BE_PLANAR,      AST)                += ast
 FATE_LAVF-$(call ENCDEC,  PCM_S16BE,             AU)                 += au
 FATE_LAVF-$(call ENCDEC2, MPEG4,      MP2,       AVI)                += avi
 FATE_LAVF-$(call ENCDEC,  BMP,                   IMAGE2)             += bmp
@@ -12,6 +13,7 @@
 FATE_LAVF-$(call ENCDEC,  FLV,                   FLV)                += flv_fmt
 FATE_LAVF-$(call ENCDEC,  GIF,                   IMAGE2)             += gif
 FATE_LAVF-$(call ENCDEC2, MPEG2VIDEO, PCM_S16LE, GXF)                += gxf
+FATE_LAVF-$(call ENCDEC,  PCM_S16LE,             IRCAM)              += ircam
 FATE_LAVF-$(call ENCDEC,  MJPEG,                 IMAGE2)             += jpg
 FATE_LAVF-$(call ENCDEC2, MPEG4,      MP2,       MATROSKA)           += mkv
 FATE_LAVF-$(call ENCDEC,  ADPCM_YAMAHA,          MMF)                += mmf
@@ -43,6 +45,7 @@
 FATE_LAVF-$(call ENCDEC,  PCM_U8,                VOC)                += voc
 FATE_LAVF-$(call ENCDEC,  PCM_S16LE,             VOC)                += voc_s16
 FATE_LAVF-$(call ENCDEC,  PCM_S16LE,             WAV)                += wav
+FATE_LAVF-$(call ENCMUX,  PCM_S16LE,             W64)                += w64
 FATE_LAVF-$(call ENCDEC,  MP2,                   WTV)                += wtv
 FATE_LAVF-$(call ENCDEC,  XBM,                   IMAGE2)             += xbm
 FATE_LAVF-$(call ENCDEC,  XWD,                   IMAGE2)             += xwd
diff --git a/tests/fate/bmp.mak b/tests/fate/bmp.mak
index c660190..9e52ac0 100644
--- a/tests/fate/bmp.mak
+++ b/tests/fate/bmp.mak
@@ -37,5 +37,7 @@
 FATE_BMP += fate-bmp-rle8
 fate-bmp-rle8: CMD = framecrc -i $(SAMPLES)/bmp/testcompress8.bmp -pix_fmt rgb24
 
-FATE_SAMPLES_AVCONV += $(FATE_BMP)
-fate-bmp: $(FATE_BMP)
+FATE_BMP-$(call DEMDEC, IMAGE2, BMP) += $(FATE_BMP)
+
+FATE_SAMPLES_AVCONV += $(FATE_BMP-yes)
+fate-bmp: $(FATE_BMP-yes)
diff --git a/tests/fate/cdxl.mak b/tests/fate/cdxl.mak
index 86eaa09..11ff902 100644
--- a/tests/fate/cdxl.mak
+++ b/tests/fate/cdxl.mak
@@ -1,3 +1,6 @@
+FATE_CDXL += fate-cdxl-bitline-ham6
+fate-cdxl-bitline-ham6: CMD = framecrc -i $(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
 
@@ -10,8 +13,7 @@
 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 += fate-cdxl-bitline-ham6
-fate-cdxl-bitline-ham6: CMD = framecrc -i $(SAMPLES)/cdxl/bitline.cdxl -frames:v 10
+FATE_CDXL-$(call DEMDEC, CDXL, CDXL) += $(FATE_CDXL)
 
-FATE_SAMPLES_AVCONV += $(FATE_CDXL)
-fate-cdxl: $(FATE_CDXL)
+FATE_SAMPLES_AVCONV += $(FATE_CDXL-yes)
+fate-cdxl: $(FATE_CDXL-yes)
diff --git a/tests/fate/cover-art.mak b/tests/fate/cover-art.mak
index dadfcd8..56a384e 100644
--- a/tests/fate/cover-art.mak
+++ b/tests/fate/cover-art.mak
@@ -14,6 +14,14 @@
 fate-cover-art-wma: CMD = md5 -i $(SAMPLES)/cover_art/Californication_cover.wma -an -c:v copy -f rawvideo
 fate-cover-art-wma: REF = 0808bd0e1b61542a16e1906812dd924b
 
+FATE_COVER_ART += 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: REF = e6a8dd03687d5178bc13fc7d3316696e
+
+FATE_COVER_ART += 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: REF = 32e8bd4fad546f63d881a0256f083aea
+
 FATE_COVER_ART += 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: REF = 45333c983c45af54449dff10af144317
diff --git a/tests/fate/demux.mak b/tests/fate/demux.mak
index c46c863..189ef27 100644
--- a/tests/fate/demux.mak
+++ b/tests/fate/demux.mak
@@ -13,6 +13,9 @@
 FATE_SAMPLES_DEMUX-$(CONFIG_BINK_DEMUXER) += fate-bink-demux
 fate-bink-demux: CMD = crc -i $(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_SAMPLES_DEMUX-$(CONFIG_CAF_DEMUXER) += fate-caf
 fate-caf: CMD = crc -i $(SAMPLES)/caf/caf-pcm16.caf -c copy
 
@@ -22,6 +25,9 @@
 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_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_SAMPLES_DEMUX-$(CONFIG_IV8_DEMUXER) += fate-iv8-demux
 fate-iv8-demux: CMD = framecrc -i $(SAMPLES)/iv8/zzz-partial.mpg -vcodec copy
 
@@ -43,6 +49,9 @@
 FATE_SAMPLES_DEMUX-$(CONFIG_NC_DEMUXER) += fate-nc-demux
 fate-nc-demux: CMD = framecrc -i $(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_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
 
@@ -67,8 +76,8 @@
 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_SAMPLES_DEMUX-$(CONFIG_SIFF_DEMUXER) += fate-siff
-fate-siff: CMD = framecrc -i $(SAMPLES)/SIFF/INTRO_B.VB -t 3 -pix_fmt rgb24
+FATE_SAMPLES_DEMUX-$(CONFIG_SIFF_DEMUXER) += fate-siff-demux
+fate-siff-demux: CMD = framecrc -i $(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
diff --git a/tests/fate/dfa.mak b/tests/fate/dfa.mak
index 56f7bfe..4800d8a 100644
--- a/tests/fate/dfa.mak
+++ b/tests/fate/dfa.mak
@@ -31,5 +31,7 @@
 FATE_DFA += fate-dfa11
 fate-dfa11: CMD = framecrc -i $(SAMPLES)/chronomaster-dfa/0010.dfa -pix_fmt rgb24
 
-FATE_SAMPLES_AVCONV += $(FATE_DFA)
-fate-dfa: $(FATE_DFA)
+FATE_DFA-$(call DEMDEC, DFA, DFA) += $(FATE_DFA)
+
+FATE_SAMPLES_AVCONV += $(FATE_DFA-yes)
+fate-dfa: $(FATE_DFA-yes)
diff --git a/tests/fate/dpcm.mak b/tests/fate/dpcm.mak
index 14e77a2..abc25ed 100644
--- a/tests/fate/dpcm.mak
+++ b/tests/fate/dpcm.mak
@@ -1,14 +1,14 @@
-FATE_DPCM += fate-dpcm-idroq
+FATE_DPCM-$(call DEMDEC, ROQ, ROQ_DPCM) += fate-dpcm-idroq
 fate-dpcm-idroq: CMD = framecrc -i $(SAMPLES)/idroq/idlogo.roq -vn
 
-FATE_DPCM += fate-dpcm-interplay
+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 += fate-dpcm-sierra
+FATE_DPCM-$(call DEMDEC, SOL, SOL_DPCM) += fate-dpcm-sierra
 fate-dpcm-sierra: CMD = md5 -i $(SAMPLES)/sol/lsl7sample.sol -f s16le
 
-FATE_DPCM += fate-dpcm-xan
+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_SAMPLES_AVCONV += $(FATE_DPCM)
-fate-dpcm: $(FATE_DPCM)
+FATE_SAMPLES_AVCONV += $(FATE_DPCM-yes)
+fate-dpcm: $(FATE_DPCM-yes)
diff --git a/tests/fate/ea.mak b/tests/fate/ea.mak
index eb75708..81e14b8 100644
--- a/tests/fate/ea.mak
+++ b/tests/fate/ea.mak
@@ -4,15 +4,12 @@
 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_SAMPLES_EA-$(call DEMDEC, EA, EATGQ) += fate-ea-tgq
-fate-ea-tgq: CMD = framecrc -i $(SAMPLES)/ea-tgq/v27.tgq -an
-
-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_SAMPLES_EA-$(call DEMDEC, EA, EAMAD) += fate-ea-mad
 fate-ea-mad: CMD = framecrc -i $(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_TGV += fate-ea-tgv-1
 fate-ea-tgv-1: CMD = framecrc -i $(SAMPLES)/ea-tgv/INTRO8K-partial.TGV -pix_fmt rgb24 -an
 
@@ -22,5 +19,8 @@
 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_SAMPLES_FFMPEG += $(FATE_SAMPLES_EA-yes)
 fate-ea: $(FATE_SAMPLES_EA-yes)
diff --git a/tests/fate/ffmpeg.mak b/tests/fate/ffmpeg.mak
new file mode 100644
index 0000000..b98ccd8
--- /dev/null
+++ b/tests/fate/ffmpeg.mak
@@ -0,0 +1,29 @@
+FATE_MAPCHAN += fate-mapchan-6ch-extract-2
+fate-mapchan-6ch-extract-2: tests/data/asynth-22050-6.wav
+fate-mapchan-6ch-extract-2: CMD = ffmpeg -i $(TARGET_PATH)/tests/data/asynth-22050-6.wav -map_channel 0.0.0 -flags +bitexact -f wav md5: -map_channel 0.0.1 -flags +bitexact -f wav md5:
+
+FATE_MAPCHAN += fate-mapchan-6ch-extract-2-downmix-mono
+fate-mapchan-6ch-extract-2-downmix-mono: tests/data/asynth-22050-6.wav
+fate-mapchan-6ch-extract-2-downmix-mono: CMD = md5 -i $(TARGET_PATH)/tests/data/asynth-22050-6.wav -map_channel 0.0.1 -map_channel 0.0.0 -ac 1 -flags +bitexact -f wav
+
+FATE_MAPCHAN += fate-mapchan-silent-mono
+fate-mapchan-silent-mono: tests/data/asynth-22050-1.wav
+fate-mapchan-silent-mono: CMD = md5 -i $(TARGET_PATH)/tests/data/asynth-22050-1.wav -map_channel -1 -map_channel 0.0.0 -flags +bitexact -f wav
+
+FATE_FFMPEG += $(FATE_MAPCHAN)
+fate-mapchan: $(FATE_MAPCHAN)
+
+FATE_FFMPEG += fate-force_key_frames
+fate-force_key_frames: tests/data/vsynth2.yuv
+fate-force_key_frames: CMD = enc_dec \
+  "rawvideo -s 352x288 -pix_fmt yuv420p" tests/data/vsynth2.yuv \
+  avi "-c mpeg4 -g 240 -qscale 10 -force_key_frames 0.5,0:00:01.5" \
+  framecrc "" "" "-skip_frame nokey"
+
+FATE_SAMPLES_FFMPEG-$(call ALLYES, VOBSUB_DEMUXER DVDSUB_DECODER AVFILTER OVERLAY_FILTER DVDSUB_ENCODER) += fate-sub2video
+fate-sub2video: tests/data/vsynth2.yuv
+fate-sub2video: CMD = framecrc \
+  -f rawvideo -r 5 -s 352x288 -pix_fmt yuv420p -i tests/data/vsynth2.yuv \
+  -ss 132 -i $(SAMPLES)/sub/vobsub.idx \
+  -filter_complex "sws_flags=+accurate_rnd+bitexact;[0:0]scale=720:480[v];[v][1:0]overlay[v2]" \
+  -map "[v2]" -c:v rawvideo -map 1:s -c:s dvdsub
diff --git a/tests/fate/filter.mak b/tests/fate/filter.mak
index 66ff333..e974226 100644
--- a/tests/fate/filter.mak
+++ b/tests/fate/filter.mak
@@ -24,11 +24,11 @@
 fate-filter-asyncts: SRC = $(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.pcm
+fate-filter-asyncts: REF = $(SAMPLES)/nellymoser/nellymoser-discont-async-v2.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
+fate-filter-aresample: CMD = pcm -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
 
@@ -44,6 +44,14 @@
 
 FATE_FILTER-$(CONFIG_YADIF_FILTER) += $(FATE_YADIF)
 
+FATE_HQDN3D += fate-filter-hqdn3d
+fate-filter-hqdn3d: CMD = framecrc -idct simple -i $(SAMPLES)/smjpeg/scenwin.mjpg -vf hqdn3d -an
+FATE_FILTER-$(call ALLYES, SMJPEG_DEMUXER MJPEG_DECODER HQDN3D_FILTER) += $(FATE_HQDN3D)
+
+FATE_GRADFUN += fate-filter-gradfun
+fate-filter-gradfun: CMD = framecrc -i $(SAMPLES)/vmd/12.vmd -vf "sws_flags=+accurate_rnd+bitexact;gradfun=10:8" -an -frames:v 20
+FATE_FILTER-$(call ALLYES, VMD_DEMUXER VMDVIDEO_DECODER GRADFUN_FILTER) += $(FATE_GRADFUN)
+
 FATE_SAMPLES_AVCONV += $(FATE_FILTER-yes)
 
 #
@@ -60,7 +68,7 @@
 SILENCEDETECT_DEPS = FFPROBE LAVFI_INDEV AMOVIE_FILTER AMR_DEMUXER AMRWB_DECODER
 FATE_METADATA_FILTER-$(call ALLYES, $(SILENCEDETECT_DEPS)) += fate-filter-metadata-silencedetect
 fate-filter-metadata-silencedetect: SRC = $(SAMPLES)/amrwb/seed-12k65.awb
-fate-filter-metadata-silencedetect: CMD = run $(FILTER_METADATA_COMMAND) "amovie='$(SRC)',silencedetect=d=.1"
+fate-filter-metadata-silencedetect: CMD = run $(FILTER_METADATA_COMMAND) "amovie='$(SRC)',silencedetect=d=-20dB"
 
 FATE_SAMPLES_FFPROBE += $(FATE_METADATA_FILTER-yes)
 
diff --git a/tests/fate/gif.mak b/tests/fate/gif.mak
new file mode 100644
index 0000000..97b0545
--- /dev/null
+++ b/tests/fate/gif.mak
@@ -0,0 +1,13 @@
+FATE_GIF += fate-gif-color
+fate-gif-color: CMD = framecrc -i $(SAMPLES)/gif/tc217.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 += fate-gif-gray
+fate-gif-gray: CMD = framecrc -i $(SAMPLES)/gif/Newtons_cradle_animation_book_2.gif -pix_fmt bgra
+
+FATE_GIF-$(call DEMDEC, GIF, GIF) += $(FATE_GIF)
+
+FATE_SAMPLES_AVCONV += $(FATE_GIF-yes)
+fate-gif: $(FATE_GIF-yes)
diff --git a/tests/fate/h264.mak b/tests/fate/h264.mak
index 75fd58c..ca87b7d 100644
--- a/tests/fate/h264.mak
+++ b/tests/fate/h264.mak
@@ -183,8 +183,8 @@
             sva_nl2_e                                                   \
 
 FATE_H264  := $(FATE_H264:%=fate-h264-conformance-%)                    \
-              fate-h264-lossless                                        \
               fate-h264-extreme-plane-pred                              \
+              fate-h264-lossless                                        \
 
 FATE_H264-$(call DEMDEC, H264, H264) += $(FATE_H264)
 FATE_H264-$(call DEMDEC,  MOV, H264) += fate-h264-interlace-crop
@@ -193,146 +193,146 @@
 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-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
@@ -340,44 +340,44 @@
 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-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-interlace-crop: CMD = framecrc -i $(SAMPLES)/h264/interlaced_crop.mp4 -vframes 3
-fate-h264-lossless: CMD = framecrc -i $(SAMPLES)/h264/lossless.h264
-fate-h264-extreme-plane-pred: CMD = framemd5 -i $(SAMPLES)/h264/extreme-plane-pred.h264
-fate-h264-bsf-mp4toannexb: CMD = md5 -i $(SAMPLES)/h264/interlaced_crop.mp4 -vcodec copy -bsf h264_mp4toannexb -f h264
+fate-h264-bsf-mp4toannexb:                        CMD = md5 -i $(SAMPLES)/h264/interlaced_crop.mp4 -vcodec copy -bsf h264_mp4toannexb -f h264
+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
diff --git a/tests/fate/image.mak b/tests/fate/image.mak
index 8770c74..abafd5f 100644
--- a/tests/fate/image.mak
+++ b/tests/fate/image.mak
@@ -1,10 +1,10 @@
-FATE_IMAGE += fate-dpx
+FATE_IMAGE-$(call DEMDEC, IMAGE2, DPX) += fate-dpx
 fate-dpx: CMD = framecrc -i $(SAMPLES)/dpx/lighthouse_rgb48.dpx
 
-FATE_IMAGE += fate-pictor
+FATE_IMAGE-$(call DEMDEC, IMAGE2, PICTOR) += fate-pictor
 fate-pictor: CMD = framecrc -i $(SAMPLES)/pictor/MFISH.PIC -pix_fmt rgb24
 
-FATE_IMAGE += fate-ptx
+FATE_IMAGE-$(call DEMDEC, IMAGE2, PTX) += fate-ptx
 fate-ptx: CMD = framecrc -i $(SAMPLES)/ptx/_113kw_pic.ptx -pix_fmt rgb24
 
 FATE_SUNRASTER += fate-sunraster-1bit-raw
@@ -28,8 +28,10 @@
 FATE_SUNRASTER += fate-sunraster-24bit-rle
 fate-sunraster-24bit-rle: CMD = framecrc -i $(SAMPLES)/sunraster/lena-24bit-rle.sun
 
-FATE_IMAGE += $(FATE_SUNRASTER)
-fate-sunraster: $(FATE_SUNRASTER)
+FATE_SUNRASTER-$(call DEMDEC, IMAGE2, SUNRAST) += $(FATE_SUNRASTER)
+
+FATE_IMAGE += $(FATE_SUNRASTER-yes)
+fate-sunraster: $(FATE_SUNRASTER-yes)
 
 FATE_TARGA = CBW8       \
              CCM8       \
@@ -45,8 +47,10 @@
 FATE_TARGA := $(FATE_TARGA:%=fate-targa-conformance-%)  \
               fate-targa-top-to-bottom
 
-FATE_IMAGE += $(FATE_TARGA)
-fate-targa: $(FATE_TARGA)
+FATE_TARGA-$(call DEMDEC, IMAGE2, TARGA) += $(FATE_TARGA)
+
+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
@@ -67,12 +71,15 @@
 FATE_TIFF += fate-tiff-fax-g3s
 fate-tiff-fax-g3s: CMD = framecrc -i $(SAMPLES)/CCITT_fax/G31DS.TIF
 
-FATE_IMAGE += $(FATE_TIFF)
-fate-tiff: $(FATE_TIFF)
+FATE_TIFF-$(call DEMDEC, IMAGE2, TIFF) += $(FATE_TIFF)
+
+FATE_IMAGE += $(FATE_TIFF-yes)
+fate-tiff: $(FATE_TIFF-yes)
 
 FATE_IMAGE += fate-xface
 fate-xface: CMD = framecrc -i $(SAMPLES)/xface/lena.xface
 
+FATE_IMAGE += $(FATE_IMAGE-yes)
+
 FATE_SAMPLES_FFMPEG += $(FATE_IMAGE)
 fate-image: $(FATE_IMAGE)
-
diff --git a/tests/fate/libavformat.mak b/tests/fate/libavformat.mak
index b6eda42..8332246 100644
--- a/tests/fate/libavformat.mak
+++ b/tests/fate/libavformat.mak
@@ -1,3 +1,11 @@
+FATE_LIBAVFORMAT += fate-noproxy
+fate-noproxy: libavformat/noproxy-test$(EXESUF)
+fate-noproxy: CMD = run libavformat/noproxy-test
+
+FATE_LIBAVFORMAT += fate-srtp
+fate-srtp: libavformat/srtp-test$(EXESUF)
+fate-srtp: CMD = run libavformat/srtp-test
+
 FATE_LIBAVFORMAT += fate-url
 fate-url: libavformat/url-test$(EXESUF)
 fate-url: CMD = run libavformat/url-test
diff --git a/tests/fate/libavutil.mak b/tests/fate/libavutil.mak
index b2484a5..ac5e933 100644
--- a/tests/fate/libavutil.mak
+++ b/tests/fate/libavutil.mak
@@ -41,6 +41,10 @@
 fate-fifo: libavutil/fifo-test$(EXESUF)
 fate-fifo: CMD = run libavutil/fifo-test
 
+FATE_LIBAVUTIL += fate-hmac
+fate-hmac: libavutil/hmac-test$(EXESUF)
+fate-hmac: CMD = run libavutil/hmac-test
+
 FATE_LIBAVUTIL += fate-md5
 fate-md5: libavutil/md5-test$(EXESUF)
 fate-md5: CMD = run libavutil/md5-test
diff --git a/tests/fate/lossless-audio.mak b/tests/fate/lossless-audio.mak
index 50ebdd9..8dc0f06 100644
--- a/tests/fate/lossless-audio.mak
+++ b/tests/fate/lossless-audio.mak
@@ -7,6 +7,9 @@
 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_SAMPLES_LOSSLESS_AUDIO-$(call DEMDEC, RM, RALF) += fate-ralf
+fate-ralf: CMD = md5 -i $(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
 
@@ -16,6 +19,9 @@
 FATE_SAMPLES_LOSSLESS_AUDIO-$(call DEMDEC, TTA, TTA) += fate-lossless-tta
 fate-lossless-tta: CMD = crc -i $(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_SAMPLES_LOSSLESS_AUDIO-$(call DEMDEC, ASF, WMALOSSLESS) += fate-lossless-wma
 fate-lossless-wma: CMD = md5 -i $(SAMPLES)/lossless-audio/luckynight-partial.wma -f s16le
 
diff --git a/tests/fate/lossless-video.mak b/tests/fate/lossless-video.mak
index b648b08..f918ac4 100644
--- a/tests/fate/lossless-video.mak
+++ b/tests/fate/lossless-video.mak
@@ -1,9 +1,9 @@
-FATE_CLLC += fate-cllc-rgb
-fate-cllc-rgb: CMD = framecrc -i $(SAMPLES)/cllc/sample-cllc-rgb.avi
-
 FATE_CLLC += fate-cllc-argb
 fate-cllc-argb: CMD = framecrc -i $(SAMPLES)/cllc/sample-cllc-argb.avi
 
+FATE_CLLC += fate-cllc-rgb
+fate-cllc-rgb: CMD = framecrc -i $(SAMPLES)/cllc/sample-cllc-rgb.avi
+
 FATE_LOSSLESS_VIDEO-$(call DEMDEC, AVI, CLLC) += $(FATE_CLLC)
 fate-cllc: $(FATE_CLLC)
 
@@ -40,12 +40,12 @@
 FATE_LOSSLESS_VIDEO-$(call DEMDEC, AVI, VBLE) += fate-vble
 fate-vble: CMD = framecrc -i $(SAMPLES)/vble/flowers-partial-2MB.avi
 
-FATE_LOSSLESS_VIDEO-$(call DEMDEC, AVI, ZLIB) += fate-zlib
-fate-zlib: CMD = framecrc -i $(SAMPLES)/lcl/zlib-1frame.avi
-
 FATE_LOSSLESS_VIDEO-$(call DEMDEC, AVI, ZEROCODEC) += fate-zerocodec
 fate-zerocodec: CMD = framecrc -i $(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_LOSSLESS_VIDEO += $(FATE_LOSSLESS_VIDEO-yes)
 
 FATE_SAMPLES_FFMPEG += $(FATE_LOSSLESS_VIDEO)
diff --git a/tests/fate/mapchan.mak b/tests/fate/mapchan.mak
deleted file mode 100644
index d8b3ba0..0000000
--- a/tests/fate/mapchan.mak
+++ /dev/null
@@ -1,14 +0,0 @@
-FATE_MAPCHAN += fate-mapchan-6ch-extract-2
-fate-mapchan-6ch-extract-2: tests/data/asynth-22050-6.wav
-fate-mapchan-6ch-extract-2: CMD = ffmpeg -i $(TARGET_PATH)/tests/data/asynth-22050-6.wav -map_channel 0.0.0 -flags +bitexact -f wav md5: -map_channel 0.0.1 -flags +bitexact -f wav md5:
-
-FATE_MAPCHAN += fate-mapchan-6ch-extract-2-downmix-mono
-fate-mapchan-6ch-extract-2-downmix-mono: tests/data/asynth-22050-6.wav
-fate-mapchan-6ch-extract-2-downmix-mono: CMD = md5 -i $(TARGET_PATH)/tests/data/asynth-22050-6.wav -map_channel 0.0.1 -map_channel 0.0.0 -ac 1 -flags +bitexact -f wav
-
-FATE_MAPCHAN += fate-mapchan-silent-mono
-fate-mapchan-silent-mono: tests/data/asynth-22050-1.wav
-fate-mapchan-silent-mono: CMD = md5 -i $(TARGET_PATH)/tests/data/asynth-22050-1.wav -map_channel -1 -map_channel 0.0.0 -flags +bitexact -f wav
-
-FATE_FFMPEG += $(FATE_MAPCHAN)
-fate-mapchan: $(FATE_MAPCHAN)
diff --git a/tests/fate/microsoft.mak b/tests/fate/microsoft.mak
index a2b3f1f..10aeaf6 100644
--- a/tests/fate/microsoft.mak
+++ b/tests/fate/microsoft.mak
@@ -1,12 +1,12 @@
 FATE_MICROSOFT-$(call DEMDEC, AVI, MSMPEG4V1) += fate-msmpeg4v1
 fate-msmpeg4v1: CMD = framecrc -flags +bitexact -dct fastint -idct simple -i $(SAMPLES)/msmpeg4v1/mpg4.avi -an
 
-FATE_MSVIDEO1 += fate-msvideo1-16bit
-fate-msvideo1-16bit: CMD = framecrc -i $(SAMPLES)/cram/clock-cram16.avi -pix_fmt rgb24
-
 FATE_MSVIDEO1 += fate-msvideo1-8bit
 fate-msvideo1-8bit: CMD = framecrc -i $(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_MICROSOFT-$(call DEMDEC, AVI, MSVIDEO1) += $(FATE_MSVIDEO1)
 fate-msvideo1: $(FATE_MSVIDEO1)
 
@@ -33,12 +33,12 @@
 FATE_VC1-$(CONFIG_VC1_DEMUXER) += fate-vc1_sa10091
 fate-vc1_sa10091: CMD = framecrc -i $(SAMPLES)/vc1/SA10091.vc1
 
-FATE_VC1-$(CONFIG_VC1_DEMUXER) += fate-vc1_sa20021
-fate-vc1_sa20021: CMD = framecrc -i $(SAMPLES)/vc1/SA20021.vc1
-
 FATE_VC1-$(CONFIG_VC1_DEMUXER) += fate-vc1_sa10143
 fate-vc1_sa10143: CMD = framecrc -i $(SAMPLES)/vc1/SA10143.vc1
 
+FATE_VC1-$(CONFIG_VC1_DEMUXER) += fate-vc1_sa20021
+fate-vc1_sa20021: CMD = framecrc -i $(SAMPLES)/vc1/SA20021.vc1
+
 FATE_VC1-$(CONFIG_MOV_DEMUXER) += fate-vc1-ism
 fate-vc1-ism: CMD = framecrc -i $(SAMPLES)/isom/vc1-wmapro.ism -an
 
diff --git a/tests/fate/mp3.mak b/tests/fate/mp3.mak
index 2181fa6..1986061 100644
--- a/tests/fate/mp3.mak
+++ b/tests/fate/mp3.mak
@@ -30,11 +30,14 @@
 fate-mp3-float-extra_overread: CMD = pcm -c:a mp3float -i $(SAMPLES)/mpegaudio/extra_overread.mp3
 fate-mp3-float-extra_overread: REF = $(SAMPLES)/mpegaudio/extra_overread.pcm
 
-FATE_SAMPLES_AVCONV += $(FATE_MP3)
-fate-mp3: $(FATE_MP3)
 $(FATE_MP3): CMP = stddev
 $(FATE_MP3): FUZZ = 0.07
 
 ifdef HAVE_NEON
 fate-mp3-float-conf-hecommon: FUZZ = 0.70
 endif
+
+FATE_MP3-$(call DEMDEC, MP3, MP3FLOAT) += $(FATE_MP3)
+
+FATE_SAMPLES_AVCONV += $(FATE_MP3-yes)
+fate-mp3: $(FATE_MP3-yes)
diff --git a/tests/fate/options.mak b/tests/fate/options.mak
deleted file mode 100644
index 940d454..0000000
--- a/tests/fate/options.mak
+++ /dev/null
@@ -1,9 +0,0 @@
-FATE_OPTIONS += fate-options-force_key_frames
-fate-options-force_key_frames: tests/data/vsynth2.yuv
-fate-options-force_key_frames: CMD = enc_dec \
-  "rawvideo -s 352x288 -pix_fmt yuv420p" tests/data/vsynth2.yuv \
-  avi "-c mpeg4 -g 240 -qscale 10 -force_key_frames 0.5,0:00:01.5" \
-  framecrc "" "" "-skip_frame nokey"
-
-FATE_FFMPEG += $(FATE_OPTIONS)
-fate-options: $(FATE_OPTIONS)
diff --git a/tests/fate/real.mak b/tests/fate/real.mak
index 49b2eb4..0b9f202 100644
--- a/tests/fate/real.mak
+++ b/tests/fate/real.mak
@@ -12,9 +12,6 @@
 fate-ra-cook: CMP = oneoff
 fate-ra-cook: REF = $(SAMPLES)/real/ra_cook.pcm
 
-FATE_REAL-$(call DEMDEC, RM, RALF) += fate-ralf
-fate-ralf: CMD = md5 -i $(SAMPLES)/lossless-audio/luckynight-partial.rmvb -vn -f s16le
-
 FATE_REAL-$(call DEMDEC, RM, RV30) += fate-rv30
 fate-rv30: CMD = framecrc -flags +bitexact -dct fastint -idct simple -i $(SAMPLES)/real/rv30.rm -an
 
diff --git a/tests/fate/seek.mak b/tests/fate/seek.mak
index fa1f790..fe8d3ab 100644
--- a/tests/fate/seek.mak
+++ b/tests/fate/seek.mak
@@ -1,5 +1,13 @@
 # files from fate-acodec
 
+FATE_SEEK_ACODEC-$(call ENCDEC, ADPCM_IMA_QT,  AIFF)    += adpcm-ima_qt
+FATE_SEEK_ACODEC-$(call ENCDEC, ADPCM_IMA_WAV, WAV)     += adpcm-ima_wav
+FATE_SEEK_ACODEC-$(call ENCDEC, ADPCM_MS,      WAV)     += adpcm-ms
+FATE_SEEK_ACODEC-$(call ENCDEC, ADPCM_SWF,     FLV)     += adpcm-swf
+FATE_SEEK_ACODEC-$(call ENCDEC, ADPCM_YAMAHA,  WAV)     += adpcm-yamaha
+FATE_SEEK_ACODEC-$(call ENCDEC, ALAC,          MOV)     += alac
+FATE_SEEK_ACODEC-$(call ENCDEC, FLAC,          FLAC)    += flac
+FATE_SEEK_ACODEC-$(call ENCDEC, MP2,           MP2 MP3) += mp2
 FATE_SEEK_ACODEC-$(call ENCDEC, PCM_ALAW,      WAV)     += pcm-alaw
 FATE_SEEK_ACODEC-$(call ENCDEC, PCM_MULAW,     WAV)     += pcm-mulaw
 FATE_SEEK_ACODEC-$(call ENCDEC, PCM_S8,        MOV)     += pcm-s8
@@ -14,14 +22,6 @@
 FATE_SEEK_ACODEC-$(call ENCDEC, PCM_F32LE,     WAV)     += pcm-f32le
 FATE_SEEK_ACODEC-$(call ENCDEC, PCM_F64BE,     AU)      += pcm-f64be
 FATE_SEEK_ACODEC-$(call ENCDEC, PCM_F64LE,     WAV)     += pcm-f64le
-FATE_SEEK_ACODEC-$(call ENCDEC, ADPCM_IMA_QT,  AIFF)    += adpcm-ima_qt
-FATE_SEEK_ACODEC-$(call ENCDEC, ADPCM_IMA_WAV, WAV)     += adpcm-ima_wav
-FATE_SEEK_ACODEC-$(call ENCDEC, ADPCM_MS,      WAV)     += adpcm-ms
-FATE_SEEK_ACODEC-$(call ENCDEC, ADPCM_SWF,     FLV)     += adpcm-swf
-FATE_SEEK_ACODEC-$(call ENCDEC, ADPCM_YAMAHA,  WAV)     += adpcm-yamaha
-FATE_SEEK_ACODEC-$(call ENCDEC, ALAC,          MOV)     += alac
-FATE_SEEK_ACODEC-$(call ENCDEC, FLAC,          FLAC)    += flac
-FATE_SEEK_ACODEC-$(call ENCDEC, MP2,           MP2 MP3) += mp2
 
 fate-seek-acodec-adpcm-ima_qt:  SRC = fate/acodec-adpcm-ima_qt.aiff
 fate-seek-acodec-adpcm-ima_wav: SRC = fate/acodec-adpcm-ima_wav.wav
diff --git a/tests/fate/subtitles.mak b/tests/fate/subtitles.mak
index d939da9..8e586fb 100644
--- a/tests/fate/subtitles.mak
+++ b/tests/fate/subtitles.mak
@@ -1,33 +1,61 @@
-FATE_SUBTITLES += fate-sub-jacosub
+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 DEMDEC, JACOSUB, JACOSUB) += fate-sub-jacosub
 fate-sub-jacosub: CMD = md5 -i $(SAMPLES)/sub/JACOsub_capability_tester.jss -f ass
 
-FATE_SUBTITLES += fate-sub-microdvd
+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_SUBTITLES += fate-sub-movtext
+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_SUBTITLES_ASS-$(call DEMDEC, MOV, MOVTEXT) += fate-sub-movtext
 fate-sub-movtext: CMD = md5 -i $(SAMPLES)/sub/MovText_capability_tester.mp4 -f ass
 
-FATE_SUBTITLES += fate-sub-movtextenc
+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_SUBTITLES += fate-sub-realtext
+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_SUBTITLES_ASS-$(call DEMDEC, MPSUB, TEXT) += fate-sub-mpsub
+fate-sub-mpsub: CMD = md5 -i $(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_SUBTITLES_ASS-$(call DEMDEC, PJS, PJS) += fate-sub-pjs
+fate-sub-pjs: CMD = md5 -i $(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_SUBTITLES += fate-sub-sami
+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_SUBTITLES-$(call DEMDEC, SRT, SRT) += fate-sub-srt
+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_SUBTITLES += fate-sub-subripenc
+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_SUBTITLES += fate-sub-subviewer
+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 DEMDEC, SUBVIEWER, SUBVIEWER) += fate-sub-subviewer
 fate-sub-subviewer: CMD = md5 -i $(SAMPLES)/sub/SubViewer_capability_tester.sub -f ass
 
-FATE_SUBTITLES += fate-sub-webvtt
+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_SUBTITLES_ASS-$(call DEMDEC, WEBVTT, WEBVTT) += fate-sub-webvtt
 fate-sub-webvtt: CMD = md5 -i $(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_SUBTITLES-$(call ENCMUX, ASS, ASS) += $(FATE_SUBTITLES_ASS-yes)
 FATE_SUBTITLES += $(FATE_SUBTITLES-yes)
 
 FATE_SAMPLES_FFMPEG += $(FATE_SUBTITLES)
diff --git a/tests/fate/utvideo.mak b/tests/fate/utvideo.mak
index 44e0314..c6ce217 100644
--- a/tests/fate/utvideo.mak
+++ b/tests/fate/utvideo.mak
@@ -1,3 +1,9 @@
+FATE_UTVIDEO += fate-utvideo_rgb_left
+fate-utvideo_rgb_left: CMD = framecrc -i $(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 += fate-utvideo_rgba_left
 fate-utvideo_rgba_left: CMD = framecrc -i $(SAMPLES)/utvideo/utvideo_rgba_left.avi
 
@@ -7,12 +13,6 @@
 FATE_UTVIDEO += fate-utvideo_rgba_single_symbol
 fate-utvideo_rgba_single_symbol: CMD = framecrc -i $(SAMPLES)/utvideo/utvideo_rgba_single_symbol.avi
 
-FATE_UTVIDEO += fate-utvideo_rgb_left
-fate-utvideo_rgb_left: CMD = framecrc -i $(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 += fate-utvideo_yuv420_left
 fate-utvideo_yuv420_left: CMD = framecrc -i $(SAMPLES)/utvideo/utvideo_yuv420_left.avi
 
@@ -30,17 +30,14 @@
 
 fate-utvideoenc%: CMD = framemd5 -f image2 -vcodec pgmyuv -i $(TARGET_PATH)/tests/vsynth1/%02d.pgm -vcodec utvideo -sws_flags +accurate_rnd+bitexact ${OPTS}
 
-FATE_UTVIDEOENC += fate-utvideoenc_rgba_none
-fate-utvideoenc_rgba_none: OPTS = -pix_fmt rgba -pred 3
-
 FATE_UTVIDEOENC += fate-utvideoenc_rgba_left
 fate-utvideoenc_rgba_left: OPTS = -pix_fmt rgba -pred left
 
 FATE_UTVIDEOENC += fate-utvideoenc_rgba_median
 fate-utvideoenc_rgba_median: OPTS = -pix_fmt rgba -pred median
 
-FATE_UTVIDEOENC += fate-utvideoenc_rgb_none
-fate-utvideoenc_rgb_none: OPTS = -pix_fmt rgb24 -pred 3
+FATE_UTVIDEOENC += fate-utvideoenc_rgba_none
+fate-utvideoenc_rgba_none: OPTS = -pix_fmt rgba -pred 3
 
 FATE_UTVIDEOENC += fate-utvideoenc_rgb_left
 fate-utvideoenc_rgb_left: OPTS = -pix_fmt rgb24 -pred left
@@ -48,8 +45,8 @@
 FATE_UTVIDEOENC += fate-utvideoenc_rgb_median
 fate-utvideoenc_rgb_median: OPTS = -pix_fmt rgb24 -pred median
 
-FATE_UTVIDEOENC += fate-utvideoenc_yuv420_none
-fate-utvideoenc_yuv420_none: OPTS = -pix_fmt yuv420p -pred 3
+FATE_UTVIDEOENC += fate-utvideoenc_rgb_none
+fate-utvideoenc_rgb_none: OPTS = -pix_fmt rgb24 -pred 3
 
 FATE_UTVIDEOENC += fate-utvideoenc_yuv420_left
 fate-utvideoenc_yuv420_left: OPTS = -pix_fmt yuv420p -pred left
@@ -57,8 +54,8 @@
 FATE_UTVIDEOENC += fate-utvideoenc_yuv420_median
 fate-utvideoenc_yuv420_median: OPTS = -pix_fmt yuv420p -pred median
 
-FATE_UTVIDEOENC += fate-utvideoenc_yuv422_none
-fate-utvideoenc_yuv422_none: OPTS = -pix_fmt yuv422p -pred 3
+FATE_UTVIDEOENC += fate-utvideoenc_yuv420_none
+fate-utvideoenc_yuv420_none: OPTS = -pix_fmt yuv420p -pred 3
 
 FATE_UTVIDEOENC += fate-utvideoenc_yuv422_left
 fate-utvideoenc_yuv422_left: OPTS = -pix_fmt yuv422p -pred left
@@ -66,6 +63,9 @@
 FATE_UTVIDEOENC += fate-utvideoenc_yuv422_median
 fate-utvideoenc_yuv422_median: OPTS = -pix_fmt yuv422p -pred median
 
+FATE_UTVIDEOENC += fate-utvideoenc_yuv422_none
+fate-utvideoenc_yuv422_none: OPTS = -pix_fmt yuv422p -pred 3
+
 $(FATE_UTVIDEOENC): tests/vsynth1/00.pgm
 
 FATE_AVCONV-$(call ENCMUX, UTVIDEO, AVI) += $(FATE_UTVIDEOENC)
diff --git a/tests/fate/vcodec.mak b/tests/fate/vcodec.mak
index 6995c4a..f10e80c 100644
--- a/tests/fate/vcodec.mak
+++ b/tests/fate/vcodec.mak
@@ -163,27 +163,13 @@
 fate-vsynth%-mpeg4:              ENCOPTS = -qscale 10 -flags +mv4 -mbd bits
 fate-vsynth%-mpeg4:              FMT     = mp4
 
-fate-vsynth%-mpeg4-rc:           ENCOPTS = -b 400k -bf 2
-
-fate-vsynth%-mpeg4-adv:          ENCOPTS = -qscale 9 -flags +mv4+aic       \
-                                           -data_partitioning 1 -trellis 1 \
-                                           -mbd bits -ps 200
-
-fate-vsynth%-mpeg4-qprd:         ENCOPTS = -b 450k -bf 2 -trellis 1          \
-                                           -flags +mv4+mv0 -mpv_flags +qp_rd \
-                                           -cmp 2 -subcmp 2 -mbd rd
-
 fate-vsynth%-mpeg4-adap:         ENCOPTS = -b 550k -bf 2 -flags +mv4+mv0 \
                                            -trellis 1 -cmp 1 -subcmp 2   \
                                            -mbd rd -scplx_mask 0.3
 
-fate-vsynth%-mpeg4-qpel:         ENCOPTS = -qscale 7 -flags +mv4+qpel -mbd 2 \
-                                           -bf 2 -cmp 1 -subcmp 2
-
-fate-vsynth%-mpeg4-thread:       ENCOPTS = -b 500k -flags +mv4+aic         \
+fate-vsynth%-mpeg4-adv:          ENCOPTS = -qscale 9 -flags +mv4+aic       \
                                            -data_partitioning 1 -trellis 1 \
-                                           -mbd bits -ps 200 -bf 2         \
-                                           -threads 2 -slices 2
+                                           -mbd bits -ps 200
 
 fate-vsynth%-mpeg4-error:        ENCOPTS = -qscale 7 -flags +mv4+aic    \
                                            -data_partitioning 1 -mbd rd \
@@ -191,6 +177,20 @@
 
 fate-vsynth%-mpeg4-nr:           ENCOPTS = -qscale 8 -flags +mv4 -mbd rd -nr 200
 
+fate-vsynth%-mpeg4-qpel:         ENCOPTS = -qscale 7 -flags +mv4+qpel -mbd 2 \
+                                           -bf 2 -cmp 1 -subcmp 2
+
+fate-vsynth%-mpeg4-qprd:         ENCOPTS = -b 450k -bf 2 -trellis 1          \
+                                           -flags +mv4+mv0 -mpv_flags +qp_rd \
+                                           -cmp 2 -subcmp 2 -mbd rd
+
+fate-vsynth%-mpeg4-rc:           ENCOPTS = -b 400k -bf 2
+
+fate-vsynth%-mpeg4-thread:       ENCOPTS = -b 500k -flags +mv4+aic         \
+                                           -data_partitioning 1 -trellis 1 \
+                                           -mbd bits -ps 200 -bf 2         \
+                                           -threads 2 -slices 2
+
 FATE_VCODEC-$(call ENCDEC, MSMPEG4V3, AVI) += msmpeg4
 fate-vsynth%-msmpeg4:            ENCOPTS = -qscale 10
 
diff --git a/tests/fate/video.mak b/tests/fate/video.mak
index 5689f51..78049e5 100644
--- a/tests/fate/video.mak
+++ b/tests/fate/video.mak
@@ -51,6 +51,9 @@
 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_VIDEO-$(call DEMDEC, MPEGPS, CAVS) += fate-cavs
+fate-cavs: CMD = framecrc -i $(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
 
@@ -63,12 +66,12 @@
 FATE_VIDEO-$(call DEMDEC, AVS, AVS) += fate-creatureshock-avs
 fate-creatureshock-avs: CMD = framecrc -i $(SAMPLES)/creatureshock-avs/OUTATIME.AVS -pix_fmt rgb24
 
-FATE_CVID-$(CONFIG_AVI_DEMUXER) += fate-cvid-partial
-fate-cvid-partial: CMD = framecrc -i $(SAMPLES)/cvid/laracroft-cinepak-partial.avi -an
-
 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-$(CONFIG_AVI_DEMUXER) += fate-cvid-partial
+fate-cvid-partial: CMD = framecrc -i $(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
 
@@ -87,6 +90,9 @@
 FATE_VIDEO-$(call DEMDEC, ANM, ANM) += fate-deluxepaint-anm
 fate-deluxepaint-anm: CMD = framecrc -i $(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_TRUEMOTION1 += fate-truemotion1-15
 fate-truemotion1-15: CMD = framecrc -i $(SAMPLES)/duck/phant2-940.duk -pix_fmt rgb24 -an
 
@@ -251,6 +257,9 @@
 fate-v410enc: tests/vsynth1/00.pgm
 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_VIDEO-$(call DEMDEC, AVI, VCR1) += fate-vcr1
 fate-vcr1: CMD = framecrc -i $(SAMPLES)/vcr1/VCR1test.avi -an
 
diff --git a/tests/fate/vpx.mak b/tests/fate/vpx.mak
index fd9c905..061a1e8 100644
--- a/tests/fate/vpx.mak
+++ b/tests/fate/vpx.mak
@@ -1,10 +1,10 @@
-FATE_VP3-$(CONFIG_AVI_DEMUXER) += fate-vp31
+FATE_VP3-$(call DEMDEC, MATROSKA, THEORA) += fate-theora-coeff-level64
+fate-theora-coeff-level64: CMD = framecrc -i $(SAMPLES)/vp3/coeff_level64.mkv
+
+FATE_VP3-$(call DEMDEC, AVI, VP3) += fate-vp31
 fate-vp31: CMD = framecrc -i $(SAMPLES)/vp3/vp31.avi
 
-FATE_VP3-$(CONFIG_MATROSKA_DEMUXER) += fate-vp3-coeff-level64
-fate-vp3-coeff-level64: CMD = framecrc -i $(SAMPLES)/vp3/coeff_level64.mkv
-
-FATE_SAMPLES_AVCONV-$(CONFIG_VP3_DECODER) += $(FATE_VP3-yes)
+FATE_SAMPLES_AVCONV += $(FATE_VP3-yes)
 fate-vp3: $(FATE_VP3-yes)
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, VP5) += fate-vp5
@@ -22,6 +22,9 @@
 FATE_VP6-$(call DEMDEC, FLV, VP6F) += fate-vp6f
 fate-vp6f: CMD = framecrc -i $(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_SAMPLES_AVCONV += $(FATE_VP6-yes)
 fate-vp6: $(FATE_VP6-yes)
 
diff --git a/tests/fate/wavpack.mak b/tests/fate/wavpack.mak
index ef190fa..8a1c301 100644
--- a/tests/fate/wavpack.mak
+++ b/tests/fate/wavpack.mak
@@ -1,8 +1,5 @@
 # lossless
 
-FATE_WAVPACK += fate-wavpack-lossless-float
-fate-wavpack-lossless-float: CMD = md5 -i $(SAMPLES)/wavpack/lossless/32bit_float-partial.wv -f f32le
-
 FATE_WAVPACK += fate-wavpack-lossless-8bit
 fate-wavpack-lossless-8bit: CMD = md5 -i $(SAMPLES)/wavpack/lossless/8bit-partial.wv -f s8
 
@@ -18,10 +15,10 @@
 FATE_WAVPACK += fate-wavpack-lossless-32bit
 fate-wavpack-lossless-32bit: CMD = md5 -i $(SAMPLES)/wavpack/lossless/32bit_int-partial.wv -f s32le
 
-# lossy
+FATE_WAVPACK += fate-wavpack-lossless-float
+fate-wavpack-lossless-float: CMD = md5 -i $(SAMPLES)/wavpack/lossless/32bit_float-partial.wv -f f32le
 
-FATE_WAVPACK += fate-wavpack-lossy-float
-fate-wavpack-lossy-float: CMD = md5 -i $(SAMPLES)/wavpack/lossy/2.0_32-bit_float.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
@@ -35,6 +32,9 @@
 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 += fate-wavpack-lossy-float
+fate-wavpack-lossy-float: CMD = md5 -i $(SAMPLES)/wavpack/lossy/2.0_32-bit_float.wv -f f32le
+
 # channel configurations
 
 FATE_WAVPACK += fate-wavpack-channels-monofloat
@@ -71,18 +71,18 @@
 
 # special cases
 
-FATE_WAVPACK += fate-wavpack-cuesheet
-fate-wavpack-cuesheet: CMD = md5 -i $(SAMPLES)/wavpack/special/cue_sheet.wv -f s16le
-
-FATE_WAVPACK += fate-wavpack-zerolsbs
-fate-wavpack-zerolsbs: CMD = md5 -i $(SAMPLES)/wavpack/special/zero_lsbs.wv -f s16le
-
 FATE_WAVPACK += fate-wavpack-clipping
 fate-wavpack-clipping: CMD = md5 -i $(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 += fate-wavpack-falsestereo
 fate-wavpack-falsestereo: CMD = md5 -i $(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, MATROSKA, WAVPACK) += fate-wavpack-matroskamode
diff --git a/tests/lavf-regression.sh b/tests/lavf-regression.sh
index 64ebc0a..d0335c1 100755
--- a/tests/lavf-regression.sh
+++ b/tests/lavf-regression.sh
@@ -137,6 +137,8 @@
 fi
 
 if [ -n "$do_mkv" ] ; then
+do_lavf mkv "" "-acodec mp2 -ab 64k -vcodec mpeg4 \
+ -attach ${raw_src%/*}/00.pgm -metadata:s:t mimetype=image/x-portable-greymap"
 do_lavf mkv "" "-acodec mp2 -ab 64k -vcodec mpeg4"
 fi
 
@@ -326,6 +328,18 @@
 do_audio_only caf
 fi
 
+if [ -n "$do_ast" ] ; then
+do_audio_only ast "-ac 2" "-loopstart 1 -loopend 10"
+fi
+
+if [ -n "$do_ircam" ] ; then
+do_audio_only ircam
+fi
+
+if [ -n "$do_w64" ] ; then
+do_audio_only w64
+fi
+
 # pix_fmt conversions
 
 if [ -n "$do_pixfmt" ] ; then
diff --git a/tests/lavfi-regression.sh b/tests/lavfi-regression.sh
index 36586ef..d6aba4c 100755
--- a/tests/lavfi-regression.sh
+++ b/tests/lavfi-regression.sh
@@ -49,12 +49,12 @@
 do_lavfi "null"               "null"
 do_lavfi "overlay"            "split[m],scale=88:72,pad=96:80:4:4[o2];[m]fifo[o1],[o1][o2]overlay=240:16"
 do_lavfi "pad"                "pad=iw*1.5:ih*1.5:iw*0.3:ih*0.2"
-do_lavfi "pp"                 "mp=pp=be/de/tn/l5/al"
-do_lavfi "pp2"                "mp=pp=be/fq:16/fa/lb"
-do_lavfi "pp3"                "mp=pp=be/fq:8/ac/li"
-do_lavfi "pp4"                "mp=pp=be/ci"
-do_lavfi "pp5"                "mp=pp=md"
-do_lavfi "pp6"                "mp=pp=be/fd"
+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))"
@@ -63,7 +63,7 @@
 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=10:10:-1.5:10:10:-1.5"
+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"
@@ -76,16 +76,11 @@
 do_lavfi_colormatrix "colormatrix" bt709 fcc bt601 smpte240m
 
 do_lavfi_pixfmts(){
-    # if there are three parameters, the first param is the test name
-    if [ -n "$3" ]; then
-        testname=$1;
-        shift;
-    else
-        testname=pixfmts_$1;
-    fi
+    testname=$1;
     test ${test%_[bl]e} = $testname || return 0
-    filter=$1
-    filter_args=$2
+    filter=$2
+    filter_args=$3
+    prefilter_chain=$4
 
     showfiltfmts="$target_exec $target_path/libavfilter/filtfmts-test"
     scale_exclude_fmts=${outfile}${testname}_scale_exclude_fmts
@@ -102,25 +97,28 @@
     pix_fmts=$(comm -12 $scale_exclude_fmts $in_fmts)
 
     for pix_fmt in $pix_fmts; do
-        do_video_filter $pix_fmt "format=$pix_fmt,$filter=$filter_args" -pix_fmt $pix_fmt
+        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 "copy"    ""
-do_lavfi_pixfmts "crop"    "100:100:100:100"
-do_lavfi_pixfmts "hflip"   ""
-do_lavfi_pixfmts "field"   "field" "bottom"
-do_lavfi_pixfmts "null"    ""
-do_lavfi_pixfmts "pad"     "500:400:20:20"
-do_lavfi_pixfmts "pixdesctest" ""
-do_lavfi_pixfmts "scale"   "200:100"
-do_lavfi_pixfmts "super2xsai" ""
-do_lavfi_pixfmts "tinterlace_merge" "tinterlace" "merge"
-do_lavfi_pixfmts "tinterlace_pad"   "tinterlace" "pad"
-do_lavfi_pixfmts "vflip"   ""
+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
diff --git a/tests/ref/acodec/adpcm-ima_qt b/tests/ref/acodec/adpcm-ima_qt
index 8001527..ace5325 100644
--- a/tests/ref/acodec/adpcm-ima_qt
+++ b/tests/ref/acodec/adpcm-ima_qt
@@ -1,4 +1,4 @@
-23cbae1182e150ebf28e0abfb9cba127 *tests/data/fate/acodec-adpcm-ima_qt.aiff
+44691f14cf5bbef5005df27c692b93ab *tests/data/fate/acodec-adpcm-ima_qt.aiff
 281252 tests/data/fate/acodec-adpcm-ima_qt.aiff
 b0fafd002c38fb70acaddfda1a31ed61 *tests/data/fate/acodec-adpcm-ima_qt.out.wav
 stddev:  904.76 PSNR: 37.20 MAXDIFF:34029 bytes:  1058400/  1058560
diff --git a/tests/ref/acodec/roqaudio b/tests/ref/acodec/roqaudio
index ec28668..8632504 100644
--- a/tests/ref/acodec/roqaudio
+++ b/tests/ref/acodec/roqaudio
@@ -1,4 +1,4 @@
-c8ff13cf7ebece23af76502f5785202e *tests/data/fate/acodec-roqaudio.roq
+75859976d7098588aeaebbc5551484a9 *tests/data/fate/acodec-roqaudio.roq
 265992 tests/data/fate/acodec-roqaudio.roq
-709fd60aea880c73b375094ab5307c77 *tests/data/fate/acodec-roqaudio.out.wav
-stddev: 4610.71 PSNR: 23.05 MAXDIFF:43883 bytes:  1058400/  1058400
+be6d954adaf984f2dc65a3ff50b55f26 *tests/data/fate/acodec-roqaudio.out.wav
+stddev: 4481.70 PSNR: 23.30 MAXDIFF:46250 bytes:  1058400/  1058400
diff --git a/tests/ref/fate/brstm b/tests/ref/fate/brstm
new file mode 100644
index 0000000..d183b3f
--- /dev/null
+++ b/tests/ref/fate/brstm
@@ -0,0 +1 @@
+CRC=0x1feb92a8
diff --git a/tests/ref/fate/cavs b/tests/ref/fate/cavs
new file mode 100644
index 0000000..f9af8fa
--- /dev/null
+++ b/tests/ref/fate/cavs
@@ -0,0 +1,172 @@
+#tb 0: 1/25
+0,          0,          0,        1,   622080, 0x76183b91
+0,          1,          1,        1,   622080, 0x2ca5e808
+0,          2,          2,        1,   622080, 0xc503eda4
+0,          3,          3,        1,   622080, 0xa0dbf06c
+0,          4,          4,        1,   622080, 0xf4363cfa
+0,          5,          5,        1,   622080, 0xaa7dd9b8
+0,          6,          6,        1,   622080, 0x3ab6223b
+0,          7,          7,        1,   622080, 0xe402644b
+0,          8,          8,        1,   622080, 0xd0da3ade
+0,          9,          9,        1,   622080, 0x0aff6151
+0,         10,         10,        1,   622080, 0x02aea3d5
+0,         11,         11,        1,   622080, 0x5d8eeccd
+0,         12,         12,        1,   622080, 0x54384735
+0,         13,         13,        1,   622080, 0x890d71c2
+0,         14,         14,        1,   622080, 0xc60ae25b
+0,         15,         15,        1,   622080, 0xe589e774
+0,         16,         16,        1,   622080, 0x03471e74
+0,         17,         17,        1,   622080, 0x4e22302c
+0,         18,         18,        1,   622080, 0x00333583
+0,         19,         19,        1,   622080, 0xd6eae7d9
+0,         20,         20,        1,   622080, 0x72fe94f7
+0,         21,         21,        1,   622080, 0x3ebbad1e
+0,         22,         22,        1,   622080, 0x2fb1de4b
+0,         23,         23,        1,   622080, 0x3bfea6d2
+0,         24,         24,        1,   622080, 0x0fb551b2
+0,         25,         25,        1,   622080, 0xb203284f
+0,         26,         26,        1,   622080, 0xb3baac30
+0,         27,         27,        1,   622080, 0x15f2c1c7
+0,         28,         28,        1,   622080, 0xb2b530ce
+0,         29,         29,        1,   622080, 0xbbaaf241
+0,         30,         30,        1,   622080, 0x01bc9dfc
+0,         31,         31,        1,   622080, 0x8a449a42
+0,         32,         32,        1,   622080, 0xdc63d73f
+0,         33,         33,        1,   622080, 0xf06bc231
+0,         34,         34,        1,   622080, 0x19e04295
+0,         35,         35,        1,   622080, 0x1e7d1acd
+0,         36,         36,        1,   622080, 0x43878b48
+0,         37,         37,        1,   622080, 0xcd94b702
+0,         38,         38,        1,   622080, 0xd2706cf1
+0,         39,         39,        1,   622080, 0x47d636f3
+0,         40,         40,        1,   622080, 0x4a516acc
+0,         41,         41,        1,   622080, 0x52b7d89a
+0,         42,         42,        1,   622080, 0xc9ba03be
+0,         43,         43,        1,   622080, 0x6d17785e
+0,         44,         44,        1,   622080, 0x8264871b
+0,         45,         45,        1,   622080, 0xd59c84c0
+0,         46,         46,        1,   622080, 0x2b86d6cd
+0,         47,         47,        1,   622080, 0x9c5a5f51
+0,         48,         48,        1,   622080, 0x221f79ca
+0,         49,         49,        1,   622080, 0x98edb3ec
+0,         50,         50,        1,   622080, 0x9a31262c
+0,         51,         51,        1,   622080, 0x18f48378
+0,         52,         52,        1,   622080, 0x957c3d9c
+0,         53,         53,        1,   622080, 0x9cc6866e
+0,         54,         54,        1,   622080, 0x45613726
+0,         55,         55,        1,   622080, 0x7a6c5e65
+0,         56,         56,        1,   622080, 0x976d7a11
+0,         57,         57,        1,   622080, 0x192aea08
+0,         58,         58,        1,   622080, 0x8d4fc823
+0,         59,         59,        1,   622080, 0x1f9c55d7
+0,         60,         60,        1,   622080, 0xd4336d41
+0,         61,         61,        1,   622080, 0x7aa650cd
+0,         62,         62,        1,   622080, 0x8efaaeb1
+0,         63,         63,        1,   622080, 0x3d8c3053
+0,         64,         64,        1,   622080, 0x1e2b64b0
+0,         65,         65,        1,   622080, 0x0436b1a7
+0,         66,         66,        1,   622080, 0xc5120072
+0,         67,         67,        1,   622080, 0x0203b245
+0,         68,         68,        1,   622080, 0x9815582b
+0,         69,         69,        1,   622080, 0x3c60c359
+0,         70,         70,        1,   622080, 0x1a26b948
+0,         71,         71,        1,   622080, 0x56079812
+0,         72,         72,        1,   622080, 0x7b192a55
+0,         73,         73,        1,   622080, 0x335632ab
+0,         74,         74,        1,   622080, 0xd0c12eb8
+0,         75,         75,        1,   622080, 0x93bf46cb
+0,         76,         76,        1,   622080, 0xce67ce24
+0,         77,         77,        1,   622080, 0xff95bb26
+0,         78,         78,        1,   622080, 0x5e750705
+0,         79,         79,        1,   622080, 0x45a35725
+0,         80,         80,        1,   622080, 0xd8e93c39
+0,         81,         81,        1,   622080, 0xa9f8db50
+0,         82,         82,        1,   622080, 0xf90a862e
+0,         83,         83,        1,   622080, 0x5e5a4216
+0,         84,         84,        1,   622080, 0xaaf45ed6
+0,         85,         85,        1,   622080, 0x1933cda5
+0,         86,         86,        1,   622080, 0x7ff68d91
+0,         87,         87,        1,   622080, 0x10038fe9
+0,         88,         88,        1,   622080, 0x9b3425a6
+0,         89,         89,        1,   622080, 0x8d2a141d
+0,         90,         90,        1,   622080, 0x698a333e
+0,         91,         91,        1,   622080, 0x334685d1
+0,         92,         92,        1,   622080, 0x40317d40
+0,         93,         93,        1,   622080, 0xd3c6f519
+0,         94,         94,        1,   622080, 0xfc2210c2
+0,         95,         95,        1,   622080, 0x3761df34
+0,         96,         96,        1,   622080, 0xef25462a
+0,         97,         97,        1,   622080, 0x0fd38121
+0,         98,         98,        1,   622080, 0x184856a6
+0,         99,         99,        1,   622080, 0xc57c9f12
+0,        100,        100,        1,   622080, 0x39874291
+0,        101,        101,        1,   622080, 0x7c13cec4
+0,        102,        102,        1,   622080, 0xc4192a76
+0,        103,        103,        1,   622080, 0x2af404e3
+0,        104,        104,        1,   622080, 0x1ee18f41
+0,        105,        105,        1,   622080, 0xfb4d9ee5
+0,        106,        106,        1,   622080, 0x50aae4ff
+0,        107,        107,        1,   622080, 0x030f91fe
+0,        108,        108,        1,   622080, 0x3a3ee08c
+0,        109,        109,        1,   622080, 0x50121423
+0,        110,        110,        1,   622080, 0xda39e2d6
+0,        111,        111,        1,   622080, 0x9e13ccd6
+0,        112,        112,        1,   622080, 0xb72a22a7
+0,        113,        113,        1,   622080, 0xb76904d5
+0,        114,        114,        1,   622080, 0xcffa04a8
+0,        115,        115,        1,   622080, 0x2984bf3f
+0,        116,        116,        1,   622080, 0x274b5778
+0,        117,        117,        1,   622080, 0xf059413a
+0,        118,        118,        1,   622080, 0x969fae57
+0,        119,        119,        1,   622080, 0x75c29097
+0,        120,        120,        1,   622080, 0x2bf3b07d
+0,        121,        121,        1,   622080, 0x9f43271d
+0,        122,        122,        1,   622080, 0x67bf23f3
+0,        123,        123,        1,   622080, 0xa8edcf33
+0,        124,        124,        1,   622080, 0x17a0789e
+0,        125,        125,        1,   622080, 0x14b67cc7
+0,        126,        126,        1,   622080, 0x779215cd
+0,        127,        127,        1,   622080, 0x8b460a21
+0,        128,        128,        1,   622080, 0x0502ad7d
+0,        129,        129,        1,   622080, 0x6860678f
+0,        130,        130,        1,   622080, 0xe180469e
+0,        131,        131,        1,   622080, 0x9a992835
+0,        132,        132,        1,   622080, 0x2efafa33
+0,        133,        133,        1,   622080, 0xe24e59b2
+0,        134,        134,        1,   622080, 0xfb774d53
+0,        135,        135,        1,   622080, 0x3de4ea81
+0,        136,        136,        1,   622080, 0xaf9aa1d6
+0,        137,        137,        1,   622080, 0xa0e3722f
+0,        138,        138,        1,   622080, 0x81684492
+0,        139,        139,        1,   622080, 0xa4e971fb
+0,        140,        140,        1,   622080, 0x4a1903c8
+0,        141,        141,        1,   622080, 0x26304e4a
+0,        142,        142,        1,   622080, 0x867983a4
+0,        143,        143,        1,   622080, 0x2e7e4d13
+0,        144,        144,        1,   622080, 0x736f4682
+0,        145,        145,        1,   622080, 0x426a95fa
+0,        146,        146,        1,   622080, 0x2bc8850c
+0,        147,        147,        1,   622080, 0x047e77ab
+0,        148,        148,        1,   622080, 0x414ab77f
+0,        149,        149,        1,   622080, 0x42681090
+0,        150,        150,        1,   622080, 0x80744ccb
+0,        151,        151,        1,   622080, 0x50e2ecc0
+0,        152,        152,        1,   622080, 0x5c9fe70e
+0,        153,        153,        1,   622080, 0x016461ee
+0,        154,        154,        1,   622080, 0xd42f019a
+0,        155,        155,        1,   622080, 0x8171bf41
+0,        156,        156,        1,   622080, 0xf4d8ef7e
+0,        157,        157,        1,   622080, 0xf2d513c8
+0,        158,        158,        1,   622080, 0xb5b07704
+0,        159,        159,        1,   622080, 0x2168a07a
+0,        160,        160,        1,   622080, 0x840418f9
+0,        161,        161,        1,   622080, 0xd36f1b7c
+0,        162,        162,        1,   622080, 0x52532604
+0,        163,        163,        1,   622080, 0x0856d6eb
+0,        164,        164,        1,   622080, 0x21748734
+0,        165,        165,        1,   622080, 0xbd315c05
+0,        166,        166,        1,   622080, 0x1cea8103
+0,        167,        167,        1,   622080, 0x71f6e3cb
+0,        168,        168,        1,   622080, 0xb12d7aa7
+0,        169,        169,        1,   622080, 0x54dd2acb
+0,        170,        170,        1,   622080, 0xe8f93765
diff --git a/tests/ref/fate/cdgraphics b/tests/ref/fate/cdgraphics
index 1e5cc6f..a782059 100644
--- a/tests/ref/fate/cdgraphics
+++ b/tests/ref/fate/cdgraphics
@@ -1,20 +1,20 @@
 #tb 0: 1/300
-0,          0,          0,        1,   194400, 0xd919c635
-0,          1,          1,        1,   194400, 0xd919c635
-0,          2,          2,        1,   194400, 0x516a1007
-0,          3,          3,        1,   194400, 0x516a1007
-0,          4,          4,        1,   194400, 0x516a1007
-0,          5,          5,        1,   194400, 0x516a1007
-0,          6,          6,        1,   194400, 0x516a1007
-0,          7,          7,        1,   194400, 0x516a1007
-0,          8,          8,        1,   194400, 0x516a1007
-0,          9,          9,        1,   194400, 0x516a1007
-0,         10,         10,        1,   194400, 0x516a1007
-0,         11,         11,        1,   194400, 0x516a1007
-0,         12,         12,        1,   194400, 0x516a1007
-0,         13,         13,        1,   194400, 0x516a1007
-0,         14,         14,        1,   194400, 0x516a1007
-0,         15,         15,        1,   194400, 0x516a1007
+0,          0,          0,        1,   194400, 0x46ad80da
+0,          1,          1,        1,   194400, 0x46ad80da
+0,          2,          2,        1,   194400, 0x9392c3b9
+0,          3,          3,        1,   194400, 0x9392c3b9
+0,          4,          4,        1,   194400, 0x9392c3b9
+0,          5,          5,        1,   194400, 0x9392c3b9
+0,          6,          6,        1,   194400, 0x9392c3b9
+0,          7,          7,        1,   194400, 0x9392c3b9
+0,          8,          8,        1,   194400, 0x9392c3b9
+0,          9,          9,        1,   194400, 0x9392c3b9
+0,         10,         10,        1,   194400, 0x9392c3b9
+0,         11,         11,        1,   194400, 0x9392c3b9
+0,         12,         12,        1,   194400, 0x9392c3b9
+0,         13,         13,        1,   194400, 0x9392c3b9
+0,         14,         14,        1,   194400, 0x9392c3b9
+0,         15,         15,        1,   194400, 0x9392c3b9
 0,         16,         16,        1,   194400, 0x46ad80da
 0,         17,         17,        1,   194400, 0x46ad80da
 0,         18,         18,        1,   194400, 0x46ad80da
diff --git a/tests/ref/fate/cvid-grayscale b/tests/ref/fate/cvid-grayscale
index 87ca600..1b586b3 100644
--- a/tests/ref/fate/cvid-grayscale
+++ b/tests/ref/fate/cvid-grayscale
@@ -1,153 +1,153 @@
 #tb 0: 99561/500000
-0,          0,          0,        1,    11300, 0x46c78923
-0,          1,          1,        1,    11300, 0x3f2a1175
-0,          2,          2,        1,    11300, 0x722de221
-0,          3,          3,        1,    11300, 0x01746b88
-0,          4,          4,        1,    11300, 0x549587a7
-0,          5,          5,        1,    11300, 0x843ab943
-0,          6,          6,        1,    11300, 0x62fdee48
-0,          7,          7,        1,    11300, 0x74a62867
-0,          8,          8,        1,    11300, 0x35a20e2f
-0,          9,          9,        1,    11300, 0x4e9ef54d
-0,         10,         10,        1,    11300, 0xec7201f5
-0,         11,         11,        1,    11300, 0x363bfe27
-0,         12,         12,        1,    11300, 0x2aaab418
-0,         13,         13,        1,    11300, 0x6a48ab3f
-0,         14,         14,        1,    11300, 0x3fecea34
-0,         15,         15,        1,    11300, 0xa371f55e
-0,         16,         16,        1,    11300, 0xa86b147c
-0,         17,         17,        1,    11300, 0x49e9206e
-0,         18,         18,        1,    11300, 0x6c9a2155
-0,         19,         19,        1,    11300, 0x2c8a4798
-0,         20,         20,        1,    11300, 0x3485676c
-0,         21,         21,        1,    11300, 0xb0b293f2
-0,         22,         22,        1,    11300, 0xe4a9b068
-0,         23,         23,        1,    11300, 0xd68d0556
-0,         24,         24,        1,    11300, 0xc28e5193
-0,         25,         25,        1,    11300, 0xf6948483
-0,         26,         26,        1,    11300, 0xf21fbf57
-0,         27,         27,        1,    11300, 0x8345eb44
-0,         28,         28,        1,    11300, 0x8124f045
-0,         29,         29,        1,    11300, 0x18e31f10
-0,         30,         30,        1,    11300, 0xdb1943fc
-0,         31,         31,        1,    11300, 0x8701699f
-0,         32,         32,        1,    11300, 0xd7b18550
-0,         33,         33,        1,    11300, 0xa56faccc
-0,         34,         34,        1,    11300, 0xf8bcc17c
-0,         35,         35,        1,    11300, 0x446acab9
-0,         36,         36,        1,    11300, 0x755fd295
-0,         37,         37,        1,    11300, 0x92e3d100
-0,         38,         38,        1,    11300, 0x54895bb3
-0,         39,         39,        1,    11300, 0xd18bffda
-0,         40,         40,        1,    11300, 0x480dbe4f
-0,         41,         41,        1,    11300, 0x49ea9dbe
-0,         42,         42,        1,    11300, 0x00d3a003
-0,         43,         43,        1,    11300, 0xda7bbfb2
-0,         44,         44,        1,    11300, 0x9700d9c2
-0,         45,         45,        1,    11300, 0xa0a9e490
-0,         46,         46,        1,    11300, 0x00eb0979
-0,         47,         47,        1,    11300, 0x32b04630
-0,         48,         48,        1,    11300, 0xdfb73e51
-0,         49,         49,        1,    11300, 0x3d8e4f96
-0,         50,         50,        1,    11300, 0x2ca83271
-0,         51,         51,        1,    11300, 0xb5b123c0
-0,         52,         52,        1,    11300, 0x8a570e58
-0,         53,         53,        1,    11300, 0xc6c805bc
-0,         54,         54,        1,    11300, 0x27caf7a5
-0,         55,         55,        1,    11300, 0x5319ecb0
-0,         56,         56,        1,    11300, 0x5471e3fd
-0,         57,         57,        1,    11300, 0x6d68a6f4
-0,         58,         58,        1,    11300, 0x872b7194
-0,         59,         59,        1,    11300, 0x007c36bd
-0,         60,         60,        1,    11300, 0x2714f1b5
-0,         61,         61,        1,    11300, 0x6c8eb50f
-0,         62,         62,        1,    11300, 0xf5d57be8
-0,         63,         63,        1,    11300, 0x981f412b
-0,         64,         64,        1,    11300, 0x1a9804a1
-0,         65,         65,        1,    11300, 0xf0c1d24a
-0,         66,         66,        1,    11300, 0xa70a9d9b
-0,         67,         67,        1,    11300, 0x8c466876
-0,         68,         68,        1,    11300, 0xcf2e32df
-0,         69,         69,        1,    11300, 0xcb8cfebf
-0,         70,         70,        1,    11300, 0xb961ca99
-0,         71,         71,        1,    11300, 0x666d9619
-0,         72,         72,        1,    11300, 0x84bf5b55
-0,         73,         73,        1,    11300, 0xbfa22ccc
-0,         74,         74,        1,    11300, 0xcde41849
-0,         75,         75,        1,    11300, 0x71372dcd
-0,         76,         76,        1,    11300, 0x13402cfd
-0,         77,         77,        1,    11300, 0xdebdd321
-0,         78,         78,        1,    11300, 0xdda66de1
-0,         79,         79,        1,    11300, 0x7f4bb682
-0,         80,         80,        1,    11300, 0xf67fd528
-0,         81,         81,        1,    11300, 0xe739ff8c
-0,         82,         82,        1,    11300, 0x2e131774
-0,         83,         83,        1,    11300, 0xfa942811
-0,         84,         84,        1,    11300, 0x0cd93ac2
-0,         85,         85,        1,    11300, 0xd0445e0e
-0,         86,         86,        1,    11300, 0x3f3497c7
-0,         87,         87,        1,    11300, 0x11b5bd2c
-0,         88,         88,        1,    11300, 0xccd5e62a
-0,         89,         89,        1,    11300, 0xa9d4fcb5
-0,         90,         90,        1,    11300, 0x34aa1a03
-0,         91,         91,        1,    11300, 0x1ce6299e
-0,         92,         92,        1,    11300, 0x661c2745
-0,         93,         93,        1,    11300, 0x27d8a8b3
-0,         94,         94,        1,    11300, 0x9eb07467
-0,         95,         95,        1,    11300, 0x128374d2
-0,         96,         96,        1,    11300, 0x05c36ff5
-0,         97,         97,        1,    11300, 0x8a136bde
-0,         98,         98,        1,    11300, 0x15c47c99
-0,         99,         99,        1,    11300, 0xcc4a93f4
-0,        100,        100,        1,    11300, 0x19529b2b
-0,        101,        101,        1,    11300, 0x9943c076
-0,        102,        102,        1,    11300, 0xf898e583
-0,        103,        103,        1,    11300, 0x40f71f94
-0,        104,        104,        1,    11300, 0x5b604afb
-0,        105,        105,        1,    11300, 0x8c176af4
-0,        106,        106,        1,    11300, 0x0f1a6216
-0,        107,        107,        1,    11300, 0x38bbd13d
-0,        108,        108,        1,    11300, 0x90c8d1fc
-0,        109,        109,        1,    11300, 0x253000d7
-0,        110,        110,        1,    11300, 0xb94b03b1
-0,        111,        111,        1,    11300, 0xbc872268
-0,        112,        112,        1,    11300, 0xe77adb8c
-0,        113,        113,        1,    11300, 0xa38936b7
-0,        114,        114,        1,    11300, 0xd6153632
-0,        115,        115,        1,    11300, 0x1ae633cc
-0,        116,        116,        1,    11300, 0xb90c286e
-0,        117,        117,        1,    11300, 0xbc7e333d
-0,        118,        118,        1,    11300, 0x1b5421f8
-0,        119,        119,        1,    11300, 0xdde6506d
-0,        120,        120,        1,    11300, 0xd3eb757e
-0,        121,        121,        1,    11300, 0x5ad1929c
-0,        122,        122,        1,    11300, 0x4f6aa47d
-0,        123,        123,        1,    11300, 0xab3caf55
-0,        124,        124,        1,    11300, 0x5ff9b39a
-0,        125,        125,        1,    11300, 0x1454e12e
-0,        126,        126,        1,    11300, 0xf18216e8
-0,        127,        127,        1,    11300, 0x62144880
-0,        128,        128,        1,    11300, 0x54284241
-0,        129,        129,        1,    11300, 0x8e8c7228
-0,        130,        130,        1,    11300, 0xb498d06e
-0,        131,        131,        1,    11300, 0x7b1e6be1
-0,        132,        132,        1,    11300, 0x5e5ea1f4
-0,        133,        133,        1,    11300, 0x41eda28e
-0,        134,        134,        1,    11300, 0x7ba6aa92
-0,        135,        135,        1,    11300, 0xa8a8b1c7
-0,        136,        136,        1,    11300, 0x0d30bd08
-0,        137,        137,        1,    11300, 0xc610bf16
-0,        138,        138,        1,    11300, 0xed57c075
-0,        139,        139,        1,    11300, 0xb86dbfea
-0,        140,        140,        1,    11300, 0x0970c03d
-0,        141,        141,        1,    11300, 0x743ac2ac
-0,        142,        142,        1,    11300, 0x0a44c816
-0,        143,        143,        1,    11300, 0xe32acd6b
-0,        144,        144,        1,    11300, 0x209bcdab
-0,        145,        145,        1,    11300, 0x3cd0d105
-0,        146,        146,        1,    11300, 0xc0bcd330
-0,        147,        147,        1,    11300, 0x4785d6dc
-0,        148,        148,        1,    11300, 0xe85f9c90
-0,        149,        149,        1,    11300, 0xd4a72850
-0,        150,        150,        1,    11300, 0x04766e41
-0,        151,        151,        1,    11300, 0x04766e41
+0,          0,          0,        1,    22500, 0x0f8e562e
+0,          1,          1,        1,    22500, 0x507aef06
+0,          2,          2,        1,    22500, 0x059d6137
+0,          3,          3,        1,    22500, 0xfb1bfd4e
+0,          4,          4,        1,    22500, 0xe97a51ba
+0,          5,          5,        1,    22500, 0xfc77e68e
+0,          6,          6,        1,    22500, 0x7f1985ac
+0,          7,          7,        1,    22500, 0xdfb933eb
+0,          8,          8,        1,    22500, 0x6dafe534
+0,          9,          9,        1,    22500, 0xb7b69abb
+0,         10,         10,        1,    22500, 0xc435c086
+0,         11,         11,        1,    22500, 0xf8ddb549
+0,         12,         12,        1,    22500, 0x76c0d70d
+0,         13,         13,        1,    22500, 0x1120bc82
+0,         14,         14,        1,    22500, 0x3f7c7970
+0,         15,         15,        1,    22500, 0xd37c9aee
+0,         16,         16,        1,    22500, 0x7407f81b
+0,         17,         17,        1,    22500, 0xce2f1c00
+0,         18,         18,        1,    22500, 0x70921eb5
+0,         19,         19,        1,    22500, 0x0abc917e
+0,         20,         20,        1,    22500, 0xeff1f0fa
+0,         21,         21,        1,    22500, 0x5e0d769b
+0,         22,         22,        1,    22500, 0xc984cbfd
+0,         23,         23,        1,    22500, 0x73f1caa9
+0,         24,         24,        1,    22500, 0x9108af6f
+0,         25,         25,        1,    22500, 0x4f33484e
+0,         26,         26,        1,    22500, 0x9810f8ca
+0,         27,         27,        1,    22500, 0xa0b97ca0
+0,         28,         28,        1,    22500, 0xd9c28ba3
+0,         29,         29,        1,    22500, 0xc97e17e6
+0,         30,         30,        1,    22500, 0x85cf86aa
+0,         31,         31,        1,    22500, 0xf15ff793
+0,         32,         32,        1,    22500, 0x35c54ab5
+0,         33,         33,        1,    22500, 0xe80ec129
+0,         34,         34,        1,    22500, 0x3d6cff39
+0,         35,         35,        1,    22500, 0x54e41aff
+0,         36,         36,        1,    22500, 0xc1d63293
+0,         37,         37,        1,    22500, 0x362c2dd4
+0,         38,         38,        1,    22500, 0xa1f8cdcf
+0,         39,         39,        1,    22500, 0x5b59ba62
+0,         40,         40,        1,    22500, 0x6d02f5b2
+0,         41,         41,        1,    22500, 0x899293ff
+0,         42,         42,        1,    22500, 0xad0e9ace
+0,         43,         43,        1,    22500, 0x4263f9db
+0,         44,         44,        1,    22500, 0xff1e481a
+0,         45,         45,        1,    22500, 0x70c86884
+0,         46,         46,        1,    22500, 0x203ed712
+0,         47,         47,        1,    22500, 0x2f0e8d46
+0,         48,         48,        1,    22500, 0x215075a9
+0,         49,         49,        1,    22500, 0x9882a978
+0,         50,         50,        1,    22500, 0xc2fd5209
+0,         51,         51,        1,    22500, 0xe1c925f6
+0,         52,         52,        1,    22500, 0x012be5af
+0,         53,         53,        1,    22500, 0xa718cbdb
+0,         54,         54,        1,    22500, 0x2494a1c3
+0,         55,         55,        1,    22500, 0xeb8980e4
+0,         56,         56,        1,    22500, 0x7f2766cb
+0,         57,         57,        1,    22500, 0xdf3cafa1
+0,         58,         58,        1,    22500, 0x9a390f81
+0,         59,         59,        1,    22500, 0xfdad5eed
+0,         60,         60,        1,    22500, 0x94f58ff3
+0,         61,         61,        1,    22500, 0xd7c6d9f2
+0,         62,         62,        1,    22500, 0x48b72e7d
+0,         63,         63,        1,    22500, 0x8a7a7e37
+0,         64,         64,        1,    22500, 0x5413c88a
+0,         65,         65,        1,    22500, 0x3f4531b2
+0,         66,         66,        1,    22500, 0x152d9396
+0,         67,         67,        1,    22500, 0x2ac3f418
+0,         68,         68,        1,    22500, 0x0e1c5353
+0,         69,         69,        1,    22500, 0xe058b711
+0,         70,         70,        1,    22500, 0x262e1a9f
+0,         71,         71,        1,    22500, 0x20057d10
+0,         72,         72,        1,    22500, 0x65c5ccb5
+0,         73,         73,        1,    22500, 0x3e36411a
+0,         74,         74,        1,    22500, 0xd9740391
+0,         75,         75,        1,    22500, 0x53d1441d
+0,         76,         76,        1,    22500, 0x9a3941ad
+0,         77,         77,        1,    22500, 0x61553437
+0,         78,         78,        1,    22500, 0xfe0c0468
+0,         79,         79,        1,    22500, 0xd57bde4b
+0,         80,         80,        1,    22500, 0x4a183a4c
+0,         81,         81,        1,    22500, 0xd618b978
+0,         82,         82,        1,    22500, 0x6b480112
+0,         83,         83,        1,    22500, 0x7a1732e9
+0,         84,         84,        1,    22500, 0x45836afc
+0,         85,         85,        1,    22500, 0x3548d4e0
+0,         86,         86,        1,    22500, 0x476c821a
+0,         87,         87,        1,    22500, 0x6be5f249
+0,         88,         88,        1,    22500, 0xf79b6d52
+0,         89,         89,        1,    22500, 0x2edeb0f3
+0,         90,         90,        1,    22500, 0xbaf808bf
+0,         91,         91,        1,    22500, 0x71013790
+0,         92,         92,        1,    22500, 0xbf4e3085
+0,         93,         93,        1,    22500, 0x15c2b4de
+0,         94,         94,        1,    22500, 0x031d17fa
+0,         95,         95,        1,    22500, 0x3a2c193b
+0,         96,         96,        1,    22500, 0xb0420aa4
+0,         97,         97,        1,    22500, 0xe448fe50
+0,         98,         98,        1,    22500, 0x02173090
+0,         99,         99,        1,    22500, 0x4b2f76a1
+0,        100,        100,        1,    22500, 0xd6458c46
+0,        101,        101,        1,    22500, 0xa698fc27
+0,        102,        102,        1,    22500, 0xaeca6b5d
+0,        103,        103,        1,    22500, 0x4a591972
+0,        104,        104,        1,    22500, 0x19e49ba7
+0,        105,        105,        1,    22500, 0x1d4ffb92
+0,        106,        106,        1,    22500, 0xb1f8e0f8
+0,        107,        107,        1,    22500, 0x32c82e8b
+0,        108,        108,        1,    22500, 0x96e930c8
+0,        109,        109,        1,    22500, 0x0e6ebd2c
+0,        110,        110,        1,    22500, 0x315bc5ba
+0,        111,        111,        1,    22500, 0xb22321ee
+0,        112,        112,        1,    22500, 0xbe464d78
+0,        113,        113,        1,    22500, 0xdb4b5edb
+0,        114,        114,        1,    22500, 0x0ff65d4c
+0,        115,        115,        1,    22500, 0xff68561a
+0,        116,        116,        1,    22500, 0xa0033400
+0,        117,        117,        1,    22500, 0x5414546d
+0,        118,        118,        1,    22500, 0x7e43209e
+0,        119,        119,        1,    22500, 0x0037abfd
+0,        120,        120,        1,    22500, 0x3dd31b3f
+0,        121,        121,        1,    22500, 0xe0777299
+0,        122,        122,        1,    22500, 0x35a2a83c
+0,        123,        123,        1,    22500, 0x5282c8c4
+0,        124,        124,        1,    22500, 0x1ccdd593
+0,        125,        125,        1,    22500, 0x92525e5e
+0,        126,        126,        1,    22500, 0x5fa3ff5f
+0,        127,        127,        1,    22500, 0xd1169436
+0,        128,        128,        1,    22500, 0x07dc8179
+0,        129,        129,        1,    22500, 0x9a83113d
+0,        130,        130,        1,    22500, 0x9c722c1e
+0,        131,        131,        1,    22500, 0xccbcfe59
+0,        132,        132,        1,    22500, 0x8606a0a1
+0,        133,        133,        1,    22500, 0x2210a26f
+0,        134,        134,        1,    22500, 0xfc73ba7b
+0,        135,        135,        1,    22500, 0x731fd01a
+0,        136,        136,        1,    22500, 0x0e21f1dd
+0,        137,        137,        1,    22500, 0xf9c4f807
+0,        138,        138,        1,    22500, 0x2123fc24
+0,        139,        139,        1,    22500, 0xd42cfa83
+0,        140,        140,        1,    22500, 0x5927fb7c
+0,        141,        141,        1,    22500, 0xe32e02d8
+0,        142,        142,        1,    22500, 0xa5c11316
+0,        143,        143,        1,    22500, 0xb9112315
+0,        144,        144,        1,    22500, 0x78f223d5
+0,        145,        145,        1,    22500, 0x93202de3
+0,        146,        146,        1,    22500, 0x7eb03464
+0,        147,        147,        1,    22500, 0x899c3f68
+0,        148,        148,        1,    22500, 0xc2169075
+0,        149,        149,        1,    22500, 0x419f33a6
+0,        150,        150,        1,    22500, 0x3de50588
+0,        151,        151,        1,    22500, 0x3de50588
diff --git a/tests/ref/fate/cvid-partial b/tests/ref/fate/cvid-partial
index 907ef4a..bb368a1 100644
--- a/tests/ref/fate/cvid-partial
+++ b/tests/ref/fate/cvid-partial
@@ -1,80 +1,80 @@
 #tb 0: 1/12
-0,          0,          0,        1,   112400, 0x829180d8
-0,          1,          1,        1,   112400, 0xdbebac5b
-0,          2,          2,        1,   112400, 0xc5adc0f7
-0,          3,          3,        1,   112400, 0xbe1fc030
-0,          4,          4,        1,   112400, 0xe08ab460
-0,          5,          5,        1,   112400, 0xfde0dbc5
-0,          6,          6,        1,   112400, 0xed9242b0
-0,          7,          7,        1,   112400, 0x1ae3933a
-0,          8,          8,        1,   112400, 0xc82d2f5b
-0,          9,          9,        1,   112400, 0xbae9ddfc
-0,         10,         10,        1,   112400, 0xa350a1f7
-0,         11,         11,        1,   112400, 0x3cf78029
-0,         12,         12,        1,   112400, 0xaa0b82bf
-0,         13,         13,        1,   112400, 0x71aa4794
-0,         14,         14,        1,   112400, 0x2fe57373
-0,         15,         15,        1,   112400, 0x429c6f82
-0,         16,         16,        1,   112400, 0xfb2d917d
-0,         17,         17,        1,   112400, 0xcc84cb9a
-0,         18,         18,        1,   112400, 0xc68f0613
-0,         19,         19,        1,   112400, 0x05f30e6a
-0,         20,         20,        1,   112400, 0x5c5d853d
-0,         21,         21,        1,   112400, 0x01e0aff2
-0,         22,         22,        1,   112400, 0xc3b2cf4a
-0,         23,         23,        1,   112400, 0xc0a3cf19
-0,         24,         24,        1,   112400, 0xc743abda
-0,         25,         25,        1,   112400, 0x54bd17a2
-0,         26,         26,        1,   112400, 0x616ef28d
-0,         27,         27,        1,   112400, 0x04b51f59
-0,         28,         28,        1,   112400, 0x857511a2
-0,         29,         29,        1,   112400, 0x25c62440
-0,         30,         30,        1,   112400, 0x8c78198d
-0,         31,         31,        1,   112400, 0xc046c912
-0,         32,         32,        1,   112400, 0x0d828630
-0,         33,         33,        1,   112400, 0x48999b80
-0,         34,         34,        1,   112400, 0x9a869e77
-0,         35,         35,        1,   112400, 0x16d893df
-0,         36,         36,        1,   112400, 0xf6b86132
-0,         37,         37,        1,   112400, 0xfa564ea4
-0,         38,         38,        1,   112400, 0xdd473f69
-0,         39,         39,        1,   112400, 0xf89625a6
-0,         40,         40,        1,   112400, 0x823a58aa
-0,         41,         41,        1,   112400, 0x25e0fe43
-0,         42,         42,        1,   112400, 0x41034522
-0,         43,         43,        1,   112400, 0xb8da4f00
-0,         44,         44,        1,   112400, 0x9f684fce
-0,         45,         45,        1,   112400, 0xf7188710
-0,         46,         46,        1,   112400, 0x428fbfc6
-0,         47,         47,        1,   112400, 0x535bace0
-0,         48,         48,        1,   112400, 0x23216059
-0,         49,         49,        1,   112400, 0x9b8bbfa6
-0,         50,         50,        1,   112400, 0x932be522
-0,         51,         51,        1,   112400, 0xdbd31409
-0,         52,         52,        1,   112400, 0x0a69bf18
-0,         53,         53,        1,   112400, 0xa15ef128
-0,         54,         54,        1,   112400, 0x49a1fa92
-0,         55,         55,        1,   112400, 0xadeeaf62
-0,         56,         56,        1,   112400, 0xc1ce636e
-0,         57,         57,        1,   112400, 0x5ca544eb
-0,         58,         58,        1,   112400, 0x07230a36
-0,         59,         59,        1,   112400, 0x12ae2b53
-0,         60,         60,        1,   112400, 0x62453ef6
-0,         61,         61,        1,   112400, 0xe0588a98
-0,         62,         62,        1,   112400, 0xacd3927a
-0,         63,         63,        1,   112400, 0x5d3c6b01
-0,         64,         64,        1,   112400, 0xda671808
-0,         65,         65,        1,   112400, 0x61d0b492
-0,         66,         66,        1,   112400, 0x068b1293
-0,         67,         67,        1,   112400, 0x75b99287
-0,         68,         68,        1,   112400, 0xe657e7d6
-0,         69,         69,        1,   112400, 0x17873df6
-0,         70,         70,        1,   112400, 0xa8db5e31
-0,         71,         71,        1,   112400, 0x4f633b8e
-0,         72,         72,        1,   112400, 0x22266252
-0,         73,         73,        1,   112400, 0x308a6282
-0,         74,         74,        1,   112400, 0xfdb356ce
-0,         75,         75,        1,   112400, 0xe4394f1f
-0,         76,         76,        1,   112400, 0x8ca8649f
-0,         77,         77,        1,   112400, 0x804d44eb
-0,         78,         78,        1,   112400, 0x3864488b
+0,          0,          0,        1,   224400, 0xd8f2f310
+0,          1,          1,        1,   224400, 0xe38676c2
+0,          2,          2,        1,   224400, 0x7163b6ad
+0,          3,          3,        1,   224400, 0xa514b0f7
+0,          4,          4,        1,   224400, 0xeed48b96
+0,          5,          5,        1,   224400, 0x5e9f02b2
+0,          6,          6,        1,   224400, 0x70822c53
+0,          7,          7,        1,   224400, 0x93101067
+0,          8,          8,        1,   224400, 0x0710e900
+0,          9,          9,        1,   224400, 0x0e8add6a
+0,         10,         10,        1,   224400, 0x53fb2c5a
+0,         11,         11,        1,   224400, 0xa58cc02f
+0,         12,         12,        1,   224400, 0x0a5cc76b
+0,         13,         13,        1,   224400, 0xfa551631
+0,         14,         14,        1,   224400, 0xde9f99bf
+0,         15,         15,        1,   224400, 0xe66a8690
+0,         16,         16,        1,   224400, 0xd9e6f3d1
+0,         17,         17,        1,   224400, 0xa479a5c6
+0,         18,         18,        1,   224400, 0xdaa3531f
+0,         19,         19,        1,   224400, 0xde3e6843
+0,         20,         20,        1,   224400, 0x181adafd
+0,         21,         21,        1,   224400, 0x784b6429
+0,         22,         22,        1,   224400, 0x91cdc30e
+0,         23,         23,        1,   224400, 0x6e78be49
+0,         24,         24,        1,   224400, 0x7515644c
+0,         25,         25,        1,   224400, 0xcc32a91b
+0,         26,         26,        1,   224400, 0xc63e3831
+0,         27,         27,        1,   224400, 0xfb53b651
+0,         28,         28,        1,   224400, 0x12ec8a01
+0,         29,         29,        1,   224400, 0x136fcb2c
+0,         30,         30,        1,   224400, 0x827fa546
+0,         31,         31,        1,   224400, 0x1773b7f5
+0,         32,         32,        1,   224400, 0x732defc1
+0,         33,         33,        1,   224400, 0x84292372
+0,         34,         34,        1,   224400, 0x20f22365
+0,         35,         35,        1,   224400, 0xb39a0700
+0,         36,         36,        1,   224400, 0xf245706c
+0,         37,         37,        1,   224400, 0xdb702ae7
+0,         38,         38,        1,   224400, 0xadfefe5b
+0,         39,         39,        1,   224400, 0xa667adcb
+0,         40,         40,        1,   224400, 0x4d645191
+0,         41,         41,        1,   224400, 0x33802f58
+0,         42,         42,        1,   224400, 0x24eff4b8
+0,         43,         43,        1,   224400, 0x4dc817a6
+0,         44,         44,        1,   224400, 0x9a891d35
+0,         45,         45,        1,   224400, 0x2d0bb83b
+0,         46,         46,        1,   224400, 0xd13469c1
+0,         47,         47,        1,   224400, 0xd2e6302a
+0,         48,         48,        1,   224400, 0xc7594ee1
+0,         49,         49,        1,   224400, 0xc6da714c
+0,         50,         50,        1,   224400, 0xf675e838
+0,         51,         51,        1,   224400, 0xdc047c76
+0,         52,         52,        1,   224400, 0xe5727de5
+0,         53,         53,        1,   224400, 0x153b0f62
+0,         54,         54,        1,   224400, 0x65922f68
+0,         55,         55,        1,   224400, 0x04e04bfb
+0,         56,         56,        1,   224400, 0x1dde6c88
+0,         57,         57,        1,   224400, 0xed3905f2
+0,         58,         58,        1,   224400, 0x211a5996
+0,         59,         59,        1,   224400, 0xd010baaf
+0,         60,         60,        1,   224400, 0xcbc9f272
+0,         61,         61,        1,   224400, 0x7380d6f0
+0,         62,         62,        1,   224400, 0xfd0bf084
+0,         63,         63,        1,   224400, 0xc4d671d9
+0,         64,         64,        1,   224400, 0x84236aa5
+0,         65,         65,        1,   224400, 0x9c584ede
+0,         66,         66,        1,   224400, 0xdb0c6029
+0,         67,         67,        1,   224400, 0x775ae560
+0,         68,         68,        1,   224400, 0xe3800916
+0,         69,         69,        1,   224400, 0x9313a8e8
+0,         70,         70,        1,   224400, 0x3a5d07cc
+0,         71,         71,        1,   224400, 0x4651a10b
+0,         72,         72,        1,   224400, 0xc2d72183
+0,         73,         73,        1,   224400, 0xcd971625
+0,         74,         74,        1,   224400, 0x9fb0f3c2
+0,         75,         75,        1,   224400, 0x920ee561
+0,         76,         76,        1,   224400, 0x8a2c1bbf
+0,         77,         77,        1,   224400, 0x6150c072
+0,         78,         78,        1,   224400, 0x499dc869
diff --git a/tests/ref/fate/dirac b/tests/ref/fate/dirac
new file mode 100644
index 0000000..7781b4e
--- /dev/null
+++ b/tests/ref/fate/dirac
@@ -0,0 +1,3 @@
+#tb 0: 1/30
+0,          0,          0,        1,   115200, 0xf73819e8
+0,          1,          1,        1,   115200, 0x082e3788
diff --git a/tests/ref/fate/eval b/tests/ref/fate/eval
index 73a45d1..59e3fe4 100644
--- a/tests/ref/fate/eval
+++ b/tests/ref/fate/eval
@@ -184,6 +184,12 @@
 Evaluating 'not(0)'
 'not(0)' -> 1.000000
 
+Evaluating '6.0206dB'
+'6.0206dB' -> 2.000000
+
+Evaluating '-3.0103dB'
+'-3.0103dB' -> 0.707107
+
 Evaluating 'pow(0,1.23)'
 'pow(0,1.23)' -> 0.000000
 
@@ -199,12 +205,24 @@
 Evaluating 'if(1, 2)'
 'if(1, 2)' -> 2.000000
 
+Evaluating 'if(1, 1, 2)'
+'if(1, 1, 2)' -> 1.000000
+
+Evaluating 'if(0, 1, 2)'
+'if(0, 1, 2)' -> 2.000000
+
 Evaluating 'ifnot(0, 23)'
 'ifnot(0, 23)' -> 23.000000
 
 Evaluating 'ifnot(1, NaN) + if(0, 1)'
 'ifnot(1, NaN) + if(0, 1)' -> 0.000000
 
+Evaluating 'ifnot(1, 1, 2)'
+'ifnot(1, 1, 2)' -> 2.000000
+
+Evaluating 'ifnot(0, 1, 2)'
+'ifnot(0, 1, 2)' -> 1.000000
+
 Evaluating 'taylor(1, 1)'
 'taylor(1, 1)' -> 2.718282
 
@@ -229,8 +247,8 @@
 Evaluating 'hypot(4,3)'
 'hypot(4,3)' -> 5.000000
 
-Evaluating 'gcd(30,55)*min(9,1)'
-'gcd(30,55)*min(9,1)' -> 5.000000
+Evaluating 'gcd(30,55)*print(min(9,1))'
+'gcd(30,55)*print(min(9,1))' -> 5.000000
 
 12.700000 == 12.7
 0.931323 == 0.931322575
diff --git a/tests/ref/fate/ffprobe_compact b/tests/ref/fate/ffprobe_compact
index 69ba660..2c903d4 100644
--- a/tests/ref/fate/ffprobe_compact
+++ b/tests/ref/fate/ffprobe_compact
@@ -1,31 +1,31 @@
 packet|codec_type=audio|stream_index=0|pts=0|pts_time=0.000000|dts=0|dts_time=0.000000|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=2048|pos=572|flags=K
-frame|media_type=audio|key_frame=1|pkt_pts=0|pkt_pts_time=0.000000|pkt_dts=0|pkt_dts_time=0.000000|pkt_duration=1024|pkt_duration_time=0.023220|pkt_pos=572|sample_fmt=s16|nb_samples=1024|channels=1|channel_layout=unknown
+frame|media_type=audio|key_frame=1|pkt_pts=0|pkt_pts_time=0.000000|pkt_dts=0|pkt_dts_time=0.000000|pkt_duration=1024|pkt_duration_time=0.023220|pkt_pos=572|pkt_size=2048|sample_fmt=s16|nb_samples=1024|channels=1|channel_layout=unknown
 packet|codec_type=video|stream_index=1|pts=0|pts_time=0.000000|dts=0|dts_time=0.000000|duration=2048|duration_time=0.040000|convergence_duration=N/A|convergence_duration_time=N/A|size=230400|pos=2647|flags=K
-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=2048|pkt_duration_time=0.040000|pkt_pos=2647|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|reference=0
+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=2048|pkt_duration_time=0.040000|pkt_pos=2647|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|reference=0
 packet|codec_type=video|stream_index=2|pts=0|pts_time=0.000000|dts=0|dts_time=0.000000|duration=2048|duration_time=0.040000|convergence_duration=N/A|convergence_duration_time=N/A|size=30000|pos=233068|flags=K
-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=2048|pkt_duration_time=0.040000|pkt_pos=233068|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|reference=0
+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=2048|pkt_duration_time=0.040000|pkt_pos=233068|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|reference=0
 packet|codec_type=audio|stream_index=0|pts=1024|pts_time=0.023220|dts=1024|dts_time=0.023220|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=2048|pos=263073|flags=K
-frame|media_type=audio|key_frame=1|pkt_pts=1024|pkt_pts_time=0.023220|pkt_dts=1024|pkt_dts_time=0.023220|pkt_duration=1024|pkt_duration_time=0.023220|pkt_pos=263073|sample_fmt=s16|nb_samples=1024|channels=1|channel_layout=unknown
+frame|media_type=audio|key_frame=1|pkt_pts=1024|pkt_pts_time=0.023220|pkt_dts=1024|pkt_dts_time=0.023220|pkt_duration=1024|pkt_duration_time=0.023220|pkt_pos=263073|pkt_size=2048|sample_fmt=s16|nb_samples=1024|channels=1|channel_layout=unknown
 packet|codec_type=video|stream_index=1|pts=2048|pts_time=0.040000|dts=2048|dts_time=0.040000|duration=2048|duration_time=0.040000|convergence_duration=N/A|convergence_duration_time=N/A|size=230400|pos=265151|flags=K
-frame|media_type=video|key_frame=1|pkt_pts=2048|pkt_pts_time=0.040000|pkt_dts=2048|pkt_dts_time=0.040000|pkt_duration=2048|pkt_duration_time=0.040000|pkt_pos=265151|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|reference=0
+frame|media_type=video|key_frame=1|pkt_pts=2048|pkt_pts_time=0.040000|pkt_dts=2048|pkt_dts_time=0.040000|pkt_duration=2048|pkt_duration_time=0.040000|pkt_pos=265151|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|reference=0
 packet|codec_type=video|stream_index=2|pts=2048|pts_time=0.040000|dts=2048|dts_time=0.040000|duration=2048|duration_time=0.040000|convergence_duration=N/A|convergence_duration_time=N/A|size=30000|pos=495575|flags=K
-frame|media_type=video|key_frame=1|pkt_pts=2048|pkt_pts_time=0.040000|pkt_dts=2048|pkt_dts_time=0.040000|pkt_duration=2048|pkt_duration_time=0.040000|pkt_pos=495575|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|reference=0
+frame|media_type=video|key_frame=1|pkt_pts=2048|pkt_pts_time=0.040000|pkt_dts=2048|pkt_dts_time=0.040000|pkt_duration=2048|pkt_duration_time=0.040000|pkt_pos=495575|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|reference=0
 packet|codec_type=audio|stream_index=0|pts=2048|pts_time=0.046440|dts=2048|dts_time=0.046440|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=2048|pos=525580|flags=K
-frame|media_type=audio|key_frame=1|pkt_pts=2048|pkt_pts_time=0.046440|pkt_dts=2048|pkt_dts_time=0.046440|pkt_duration=1024|pkt_duration_time=0.023220|pkt_pos=525580|sample_fmt=s16|nb_samples=1024|channels=1|channel_layout=unknown
+frame|media_type=audio|key_frame=1|pkt_pts=2048|pkt_pts_time=0.046440|pkt_dts=2048|pkt_dts_time=0.046440|pkt_duration=1024|pkt_duration_time=0.023220|pkt_pos=525580|pkt_size=2048|sample_fmt=s16|nb_samples=1024|channels=1|channel_layout=unknown
 packet|codec_type=audio|stream_index=0|pts=3072|pts_time=0.069660|dts=3072|dts_time=0.069660|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=2048|pos=527651|flags=K
-frame|media_type=audio|key_frame=1|pkt_pts=3072|pkt_pts_time=0.069660|pkt_dts=3072|pkt_dts_time=0.069660|pkt_duration=1024|pkt_duration_time=0.023220|pkt_pos=527651|sample_fmt=s16|nb_samples=1024|channels=1|channel_layout=unknown
+frame|media_type=audio|key_frame=1|pkt_pts=3072|pkt_pts_time=0.069660|pkt_dts=3072|pkt_dts_time=0.069660|pkt_duration=1024|pkt_duration_time=0.023220|pkt_pos=527651|pkt_size=2048|sample_fmt=s16|nb_samples=1024|channels=1|channel_layout=unknown
 packet|codec_type=video|stream_index=1|pts=4096|pts_time=0.080000|dts=4096|dts_time=0.080000|duration=2048|duration_time=0.040000|convergence_duration=N/A|convergence_duration_time=N/A|size=230400|pos=529729|flags=K
-frame|media_type=video|key_frame=1|pkt_pts=4096|pkt_pts_time=0.080000|pkt_dts=4096|pkt_dts_time=0.080000|pkt_duration=2048|pkt_duration_time=0.040000|pkt_pos=529729|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|reference=0
+frame|media_type=video|key_frame=1|pkt_pts=4096|pkt_pts_time=0.080000|pkt_dts=4096|pkt_dts_time=0.080000|pkt_duration=2048|pkt_duration_time=0.040000|pkt_pos=529729|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|reference=0
 packet|codec_type=video|stream_index=2|pts=4096|pts_time=0.080000|dts=4096|dts_time=0.080000|duration=2048|duration_time=0.040000|convergence_duration=N/A|convergence_duration_time=N/A|size=30000|pos=760153|flags=K
-frame|media_type=video|key_frame=1|pkt_pts=4096|pkt_pts_time=0.080000|pkt_dts=4096|pkt_dts_time=0.080000|pkt_duration=2048|pkt_duration_time=0.040000|pkt_pos=760153|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|reference=0
+frame|media_type=video|key_frame=1|pkt_pts=4096|pkt_pts_time=0.080000|pkt_dts=4096|pkt_dts_time=0.080000|pkt_duration=2048|pkt_duration_time=0.040000|pkt_pos=760153|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|reference=0
 packet|codec_type=audio|stream_index=0|pts=4096|pts_time=0.092880|dts=4096|dts_time=0.092880|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=2048|pos=790158|flags=K
-frame|media_type=audio|key_frame=1|pkt_pts=4096|pkt_pts_time=0.092880|pkt_dts=4096|pkt_dts_time=0.092880|pkt_duration=1024|pkt_duration_time=0.023220|pkt_pos=790158|sample_fmt=s16|nb_samples=1024|channels=1|channel_layout=unknown
+frame|media_type=audio|key_frame=1|pkt_pts=4096|pkt_pts_time=0.092880|pkt_dts=4096|pkt_dts_time=0.092880|pkt_duration=1024|pkt_duration_time=0.023220|pkt_pos=790158|pkt_size=2048|sample_fmt=s16|nb_samples=1024|channels=1|channel_layout=unknown
 packet|codec_type=audio|stream_index=0|pts=5120|pts_time=0.116100|dts=5120|dts_time=0.116100|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=2048|pos=792229|flags=K
-frame|media_type=audio|key_frame=1|pkt_pts=5120|pkt_pts_time=0.116100|pkt_dts=5120|pkt_dts_time=0.116100|pkt_duration=1024|pkt_duration_time=0.023220|pkt_pos=792229|sample_fmt=s16|nb_samples=1024|channels=1|channel_layout=unknown
+frame|media_type=audio|key_frame=1|pkt_pts=5120|pkt_pts_time=0.116100|pkt_dts=5120|pkt_dts_time=0.116100|pkt_duration=1024|pkt_duration_time=0.023220|pkt_pos=792229|pkt_size=2048|sample_fmt=s16|nb_samples=1024|channels=1|channel_layout=unknown
 packet|codec_type=video|stream_index=1|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=230400|pos=794307|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=794307|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|reference=0
+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|reference=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|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|reference=0
+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|reference=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
diff --git a/tests/ref/fate/ffprobe_csv b/tests/ref/fate/ffprobe_csv
index d3a1fb9..94314d7 100644
--- a/tests/ref/fate/ffprobe_csv
+++ b/tests/ref/fate/ffprobe_csv
@@ -1,31 +1,31 @@
 packet,audio,0,0,0.000000,0,0.000000,1024,0.023220,N/A,N/A,2048,572,K
-frame,audio,1,0,0.000000,0,0.000000,1024,0.023220,572,s16,1024,1,unknown
+frame,audio,1,0,0.000000,0,0.000000,1024,0.023220,572,2048,s16,1024,1,unknown
 packet,video,1,0,0.000000,0,0.000000,2048,0.040000,N/A,N/A,230400,2647,K
-frame,video,1,0,0.000000,0,0.000000,2048,0.040000,2647,320,240,rgb24,1:1,I,0,0,0,0,0,0
+frame,video,1,0,0.000000,0,0.000000,2048,0.040000,2647,N/A,320,240,rgb24,1:1,I,0,0,0,0,0,0
 packet,video,2,0,0.000000,0,0.000000,2048,0.040000,N/A,N/A,30000,233068,K
-frame,video,1,0,0.000000,0,0.000000,2048,0.040000,233068,100,100,rgb24,1:1,I,0,0,0,0,0,0
+frame,video,1,0,0.000000,0,0.000000,2048,0.040000,233068,N/A,100,100,rgb24,1:1,I,0,0,0,0,0,0
 packet,audio,0,1024,0.023220,1024,0.023220,1024,0.023220,N/A,N/A,2048,263073,K
-frame,audio,1,1024,0.023220,1024,0.023220,1024,0.023220,263073,s16,1024,1,unknown
+frame,audio,1,1024,0.023220,1024,0.023220,1024,0.023220,263073,2048,s16,1024,1,unknown
 packet,video,1,2048,0.040000,2048,0.040000,2048,0.040000,N/A,N/A,230400,265151,K
-frame,video,1,2048,0.040000,2048,0.040000,2048,0.040000,265151,320,240,rgb24,1:1,I,0,0,0,0,0,0
+frame,video,1,2048,0.040000,2048,0.040000,2048,0.040000,265151,N/A,320,240,rgb24,1:1,I,0,0,0,0,0,0
 packet,video,2,2048,0.040000,2048,0.040000,2048,0.040000,N/A,N/A,30000,495575,K
-frame,video,1,2048,0.040000,2048,0.040000,2048,0.040000,495575,100,100,rgb24,1:1,I,0,0,0,0,0,0
+frame,video,1,2048,0.040000,2048,0.040000,2048,0.040000,495575,N/A,100,100,rgb24,1:1,I,0,0,0,0,0,0
 packet,audio,0,2048,0.046440,2048,0.046440,1024,0.023220,N/A,N/A,2048,525580,K
-frame,audio,1,2048,0.046440,2048,0.046440,1024,0.023220,525580,s16,1024,1,unknown
+frame,audio,1,2048,0.046440,2048,0.046440,1024,0.023220,525580,2048,s16,1024,1,unknown
 packet,audio,0,3072,0.069660,3072,0.069660,1024,0.023220,N/A,N/A,2048,527651,K
-frame,audio,1,3072,0.069660,3072,0.069660,1024,0.023220,527651,s16,1024,1,unknown
+frame,audio,1,3072,0.069660,3072,0.069660,1024,0.023220,527651,2048,s16,1024,1,unknown
 packet,video,1,4096,0.080000,4096,0.080000,2048,0.040000,N/A,N/A,230400,529729,K
-frame,video,1,4096,0.080000,4096,0.080000,2048,0.040000,529729,320,240,rgb24,1:1,I,0,0,0,0,0,0
+frame,video,1,4096,0.080000,4096,0.080000,2048,0.040000,529729,N/A,320,240,rgb24,1:1,I,0,0,0,0,0,0
 packet,video,2,4096,0.080000,4096,0.080000,2048,0.040000,N/A,N/A,30000,760153,K
-frame,video,1,4096,0.080000,4096,0.080000,2048,0.040000,760153,100,100,rgb24,1:1,I,0,0,0,0,0,0
+frame,video,1,4096,0.080000,4096,0.080000,2048,0.040000,760153,N/A,100,100,rgb24,1:1,I,0,0,0,0,0,0
 packet,audio,0,4096,0.092880,4096,0.092880,1024,0.023220,N/A,N/A,2048,790158,K
-frame,audio,1,4096,0.092880,4096,0.092880,1024,0.023220,790158,s16,1024,1,unknown
+frame,audio,1,4096,0.092880,4096,0.092880,1024,0.023220,790158,2048,s16,1024,1,unknown
 packet,audio,0,5120,0.116100,5120,0.116100,1024,0.023220,N/A,N/A,2048,792229,K
-frame,audio,1,5120,0.116100,5120,0.116100,1024,0.023220,792229,s16,1024,1,unknown
+frame,audio,1,5120,0.116100,5120,0.116100,1024,0.023220,792229,2048,s16,1024,1,unknown
 packet,video,1,6144,0.120000,6144,0.120000,2048,0.040000,N/A,N/A,230400,794307,K
-frame,video,1,6144,0.120000,6144,0.120000,2048,0.040000,794307,320,240,rgb24,1:1,I,0,0,0,0,0,0
+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,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,100,100,rgb24,1:1,I,0,0,0,0,0,0
+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,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
diff --git a/tests/ref/fate/ffprobe_default b/tests/ref/fate/ffprobe_default
index c30f1fb..4105293 100644
--- a/tests/ref/fate/ffprobe_default
+++ b/tests/ref/fate/ffprobe_default
@@ -23,6 +23,7 @@
 pkt_duration=1024
 pkt_duration_time=0.023220
 pkt_pos=572
+pkt_size=2048
 sample_fmt=s16
 nb_samples=1024
 channels=1
@@ -53,6 +54,7 @@
 pkt_duration=2048
 pkt_duration_time=0.040000
 pkt_pos=2647
+pkt_size=N/A
 width=320
 height=240
 pix_fmt=rgb24
@@ -90,6 +92,7 @@
 pkt_duration=2048
 pkt_duration_time=0.040000
 pkt_pos=233068
+pkt_size=N/A
 width=100
 height=100
 pix_fmt=rgb24
@@ -127,6 +130,7 @@
 pkt_duration=1024
 pkt_duration_time=0.023220
 pkt_pos=263073
+pkt_size=2048
 sample_fmt=s16
 nb_samples=1024
 channels=1
@@ -157,6 +161,7 @@
 pkt_duration=2048
 pkt_duration_time=0.040000
 pkt_pos=265151
+pkt_size=N/A
 width=320
 height=240
 pix_fmt=rgb24
@@ -194,6 +199,7 @@
 pkt_duration=2048
 pkt_duration_time=0.040000
 pkt_pos=495575
+pkt_size=N/A
 width=100
 height=100
 pix_fmt=rgb24
@@ -231,6 +237,7 @@
 pkt_duration=1024
 pkt_duration_time=0.023220
 pkt_pos=525580
+pkt_size=2048
 sample_fmt=s16
 nb_samples=1024
 channels=1
@@ -261,6 +268,7 @@
 pkt_duration=1024
 pkt_duration_time=0.023220
 pkt_pos=527651
+pkt_size=2048
 sample_fmt=s16
 nb_samples=1024
 channels=1
@@ -291,6 +299,7 @@
 pkt_duration=2048
 pkt_duration_time=0.040000
 pkt_pos=529729
+pkt_size=N/A
 width=320
 height=240
 pix_fmt=rgb24
@@ -328,6 +337,7 @@
 pkt_duration=2048
 pkt_duration_time=0.040000
 pkt_pos=760153
+pkt_size=N/A
 width=100
 height=100
 pix_fmt=rgb24
@@ -365,6 +375,7 @@
 pkt_duration=1024
 pkt_duration_time=0.023220
 pkt_pos=790158
+pkt_size=2048
 sample_fmt=s16
 nb_samples=1024
 channels=1
@@ -395,6 +406,7 @@
 pkt_duration=1024
 pkt_duration_time=0.023220
 pkt_pos=792229
+pkt_size=2048
 sample_fmt=s16
 nb_samples=1024
 channels=1
@@ -425,6 +437,7 @@
 pkt_duration=2048
 pkt_duration_time=0.040000
 pkt_pos=794307
+pkt_size=N/A
 width=320
 height=240
 pix_fmt=rgb24
@@ -462,6 +475,7 @@
 pkt_duration=2048
 pkt_duration_time=0.040000
 pkt_pos=1024731
+pkt_size=N/A
 width=100
 height=100
 pix_fmt=rgb24
diff --git a/tests/ref/fate/ffprobe_flat b/tests/ref/fate/ffprobe_flat
index 43dcabd..156f215 100644
--- a/tests/ref/fate/ffprobe_flat
+++ b/tests/ref/fate/ffprobe_flat
@@ -20,6 +20,7 @@
 packets_and_frames.frame.0.pkt_duration=1024
 packets_and_frames.frame.0.pkt_duration_time="0.023220"
 packets_and_frames.frame.0.pkt_pos="572"
+packets_and_frames.frame.0.pkt_size="2048"
 packets_and_frames.frame.0.sample_fmt="s16"
 packets_and_frames.frame.0.nb_samples=1024
 packets_and_frames.frame.0.channels=1
@@ -46,6 +47,7 @@
 packets_and_frames.frame.1.pkt_duration=2048
 packets_and_frames.frame.1.pkt_duration_time="0.040000"
 packets_and_frames.frame.1.pkt_pos="2647"
+packets_and_frames.frame.1.pkt_size="N/A"
 packets_and_frames.frame.1.width=320
 packets_and_frames.frame.1.height=240
 packets_and_frames.frame.1.pix_fmt="rgb24"
@@ -79,6 +81,7 @@
 packets_and_frames.frame.2.pkt_duration=2048
 packets_and_frames.frame.2.pkt_duration_time="0.040000"
 packets_and_frames.frame.2.pkt_pos="233068"
+packets_and_frames.frame.2.pkt_size="N/A"
 packets_and_frames.frame.2.width=100
 packets_and_frames.frame.2.height=100
 packets_and_frames.frame.2.pix_fmt="rgb24"
@@ -112,6 +115,7 @@
 packets_and_frames.frame.3.pkt_duration=1024
 packets_and_frames.frame.3.pkt_duration_time="0.023220"
 packets_and_frames.frame.3.pkt_pos="263073"
+packets_and_frames.frame.3.pkt_size="2048"
 packets_and_frames.frame.3.sample_fmt="s16"
 packets_and_frames.frame.3.nb_samples=1024
 packets_and_frames.frame.3.channels=1
@@ -138,6 +142,7 @@
 packets_and_frames.frame.4.pkt_duration=2048
 packets_and_frames.frame.4.pkt_duration_time="0.040000"
 packets_and_frames.frame.4.pkt_pos="265151"
+packets_and_frames.frame.4.pkt_size="N/A"
 packets_and_frames.frame.4.width=320
 packets_and_frames.frame.4.height=240
 packets_and_frames.frame.4.pix_fmt="rgb24"
@@ -171,6 +176,7 @@
 packets_and_frames.frame.5.pkt_duration=2048
 packets_and_frames.frame.5.pkt_duration_time="0.040000"
 packets_and_frames.frame.5.pkt_pos="495575"
+packets_and_frames.frame.5.pkt_size="N/A"
 packets_and_frames.frame.5.width=100
 packets_and_frames.frame.5.height=100
 packets_and_frames.frame.5.pix_fmt="rgb24"
@@ -204,6 +210,7 @@
 packets_and_frames.frame.6.pkt_duration=1024
 packets_and_frames.frame.6.pkt_duration_time="0.023220"
 packets_and_frames.frame.6.pkt_pos="525580"
+packets_and_frames.frame.6.pkt_size="2048"
 packets_and_frames.frame.6.sample_fmt="s16"
 packets_and_frames.frame.6.nb_samples=1024
 packets_and_frames.frame.6.channels=1
@@ -230,6 +237,7 @@
 packets_and_frames.frame.7.pkt_duration=1024
 packets_and_frames.frame.7.pkt_duration_time="0.023220"
 packets_and_frames.frame.7.pkt_pos="527651"
+packets_and_frames.frame.7.pkt_size="2048"
 packets_and_frames.frame.7.sample_fmt="s16"
 packets_and_frames.frame.7.nb_samples=1024
 packets_and_frames.frame.7.channels=1
@@ -256,6 +264,7 @@
 packets_and_frames.frame.8.pkt_duration=2048
 packets_and_frames.frame.8.pkt_duration_time="0.040000"
 packets_and_frames.frame.8.pkt_pos="529729"
+packets_and_frames.frame.8.pkt_size="N/A"
 packets_and_frames.frame.8.width=320
 packets_and_frames.frame.8.height=240
 packets_and_frames.frame.8.pix_fmt="rgb24"
@@ -289,6 +298,7 @@
 packets_and_frames.frame.9.pkt_duration=2048
 packets_and_frames.frame.9.pkt_duration_time="0.040000"
 packets_and_frames.frame.9.pkt_pos="760153"
+packets_and_frames.frame.9.pkt_size="N/A"
 packets_and_frames.frame.9.width=100
 packets_and_frames.frame.9.height=100
 packets_and_frames.frame.9.pix_fmt="rgb24"
@@ -322,6 +332,7 @@
 packets_and_frames.frame.10.pkt_duration=1024
 packets_and_frames.frame.10.pkt_duration_time="0.023220"
 packets_and_frames.frame.10.pkt_pos="790158"
+packets_and_frames.frame.10.pkt_size="2048"
 packets_and_frames.frame.10.sample_fmt="s16"
 packets_and_frames.frame.10.nb_samples=1024
 packets_and_frames.frame.10.channels=1
@@ -348,6 +359,7 @@
 packets_and_frames.frame.11.pkt_duration=1024
 packets_and_frames.frame.11.pkt_duration_time="0.023220"
 packets_and_frames.frame.11.pkt_pos="792229"
+packets_and_frames.frame.11.pkt_size="2048"
 packets_and_frames.frame.11.sample_fmt="s16"
 packets_and_frames.frame.11.nb_samples=1024
 packets_and_frames.frame.11.channels=1
@@ -374,6 +386,7 @@
 packets_and_frames.frame.12.pkt_duration=2048
 packets_and_frames.frame.12.pkt_duration_time="0.040000"
 packets_and_frames.frame.12.pkt_pos="794307"
+packets_and_frames.frame.12.pkt_size="N/A"
 packets_and_frames.frame.12.width=320
 packets_and_frames.frame.12.height=240
 packets_and_frames.frame.12.pix_fmt="rgb24"
@@ -407,6 +420,7 @@
 packets_and_frames.frame.13.pkt_duration=2048
 packets_and_frames.frame.13.pkt_duration_time="0.040000"
 packets_and_frames.frame.13.pkt_pos="1024731"
+packets_and_frames.frame.13.pkt_size="N/A"
 packets_and_frames.frame.13.width=100
 packets_and_frames.frame.13.height=100
 packets_and_frames.frame.13.pix_fmt="rgb24"
diff --git a/tests/ref/fate/ffprobe_ini b/tests/ref/fate/ffprobe_ini
index abaf3e1..0e324b6 100644
--- a/tests/ref/fate/ffprobe_ini
+++ b/tests/ref/fate/ffprobe_ini
@@ -25,6 +25,7 @@
 pkt_duration=1024
 pkt_duration_time=0.023220
 pkt_pos=572
+pkt_size=2048
 sample_fmt=s16
 nb_samples=1024
 channels=1
@@ -55,6 +56,7 @@
 pkt_duration=2048
 pkt_duration_time=0.040000
 pkt_pos=2647
+pkt_size=N/A
 width=320
 height=240
 pix_fmt=rgb24
@@ -92,6 +94,7 @@
 pkt_duration=2048
 pkt_duration_time=0.040000
 pkt_pos=233068
+pkt_size=N/A
 width=100
 height=100
 pix_fmt=rgb24
@@ -129,6 +132,7 @@
 pkt_duration=1024
 pkt_duration_time=0.023220
 pkt_pos=263073
+pkt_size=2048
 sample_fmt=s16
 nb_samples=1024
 channels=1
@@ -159,6 +163,7 @@
 pkt_duration=2048
 pkt_duration_time=0.040000
 pkt_pos=265151
+pkt_size=N/A
 width=320
 height=240
 pix_fmt=rgb24
@@ -196,6 +201,7 @@
 pkt_duration=2048
 pkt_duration_time=0.040000
 pkt_pos=495575
+pkt_size=N/A
 width=100
 height=100
 pix_fmt=rgb24
@@ -233,6 +239,7 @@
 pkt_duration=1024
 pkt_duration_time=0.023220
 pkt_pos=525580
+pkt_size=2048
 sample_fmt=s16
 nb_samples=1024
 channels=1
@@ -263,6 +270,7 @@
 pkt_duration=1024
 pkt_duration_time=0.023220
 pkt_pos=527651
+pkt_size=2048
 sample_fmt=s16
 nb_samples=1024
 channels=1
@@ -293,6 +301,7 @@
 pkt_duration=2048
 pkt_duration_time=0.040000
 pkt_pos=529729
+pkt_size=N/A
 width=320
 height=240
 pix_fmt=rgb24
@@ -330,6 +339,7 @@
 pkt_duration=2048
 pkt_duration_time=0.040000
 pkt_pos=760153
+pkt_size=N/A
 width=100
 height=100
 pix_fmt=rgb24
@@ -367,6 +377,7 @@
 pkt_duration=1024
 pkt_duration_time=0.023220
 pkt_pos=790158
+pkt_size=2048
 sample_fmt=s16
 nb_samples=1024
 channels=1
@@ -397,6 +408,7 @@
 pkt_duration=1024
 pkt_duration_time=0.023220
 pkt_pos=792229
+pkt_size=2048
 sample_fmt=s16
 nb_samples=1024
 channels=1
@@ -427,6 +439,7 @@
 pkt_duration=2048
 pkt_duration_time=0.040000
 pkt_pos=794307
+pkt_size=N/A
 width=320
 height=240
 pix_fmt=rgb24
@@ -464,6 +477,7 @@
 pkt_duration=2048
 pkt_duration_time=0.040000
 pkt_pos=1024731
+pkt_size=N/A
 width=100
 height=100
 pix_fmt=rgb24
diff --git a/tests/ref/fate/ffprobe_json b/tests/ref/fate/ffprobe_json
index 6b55d92..1864deb 100644
--- a/tests/ref/fate/ffprobe_json
+++ b/tests/ref/fate/ffprobe_json
@@ -25,6 +25,7 @@
             "pkt_duration": 1024,
             "pkt_duration_time": "0.023220",
             "pkt_pos": "572",
+            "pkt_size": "2048",
             "sample_fmt": "s16",
             "nb_samples": 1024,
             "channels": 1
@@ -128,6 +129,7 @@
             "pkt_duration": 1024,
             "pkt_duration_time": "0.023220",
             "pkt_pos": "263073",
+            "pkt_size": "2048",
             "sample_fmt": "s16",
             "nb_samples": 1024,
             "channels": 1
@@ -231,6 +233,7 @@
             "pkt_duration": 1024,
             "pkt_duration_time": "0.023220",
             "pkt_pos": "525580",
+            "pkt_size": "2048",
             "sample_fmt": "s16",
             "nb_samples": 1024,
             "channels": 1
@@ -260,6 +263,7 @@
             "pkt_duration": 1024,
             "pkt_duration_time": "0.023220",
             "pkt_pos": "527651",
+            "pkt_size": "2048",
             "sample_fmt": "s16",
             "nb_samples": 1024,
             "channels": 1
@@ -363,6 +367,7 @@
             "pkt_duration": 1024,
             "pkt_duration_time": "0.023220",
             "pkt_pos": "790158",
+            "pkt_size": "2048",
             "sample_fmt": "s16",
             "nb_samples": 1024,
             "channels": 1
@@ -392,6 +397,7 @@
             "pkt_duration": 1024,
             "pkt_duration_time": "0.023220",
             "pkt_pos": "792229",
+            "pkt_size": "2048",
             "sample_fmt": "s16",
             "nb_samples": 1024,
             "channels": 1
diff --git a/tests/ref/fate/ffprobe_xml b/tests/ref/fate/ffprobe_xml
index ca0908e..8d38202 100644
--- a/tests/ref/fate/ffprobe_xml
+++ b/tests/ref/fate/ffprobe_xml
@@ -2,29 +2,29 @@
 <ffprobe>
     <packets_and_frames>
         <packet codec_type="audio" stream_index="0" pts="0" pts_time="0.000000" dts="0" dts_time="0.000000" duration="1024" duration_time="0.023220" size="2048" pos="572" flags="K"/>
-        <frame media_type="audio" key_frame="1" pkt_pts="0" pkt_pts_time="0.000000" pkt_dts="0" pkt_dts_time="0.000000" pkt_duration="1024" pkt_duration_time="0.023220" pkt_pos="572" sample_fmt="s16" nb_samples="1024" channels="1"/>
+        <frame media_type="audio" key_frame="1" pkt_pts="0" pkt_pts_time="0.000000" pkt_dts="0" pkt_dts_time="0.000000" pkt_duration="1024" pkt_duration_time="0.023220" pkt_pos="572" pkt_size="2048" sample_fmt="s16" nb_samples="1024" channels="1"/>
         <packet codec_type="video" stream_index="1" pts="0" pts_time="0.000000" dts="0" dts_time="0.000000" duration="2048" duration_time="0.040000" size="230400" pos="2647" flags="K"/>
         <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="2048" pkt_duration_time="0.040000" pkt_pos="2647" 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" reference="0"/>
         <packet codec_type="video" stream_index="2" pts="0" pts_time="0.000000" dts="0" dts_time="0.000000" duration="2048" duration_time="0.040000" size="30000" pos="233068" flags="K"/>
         <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="2048" pkt_duration_time="0.040000" pkt_pos="233068" 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" reference="0"/>
         <packet codec_type="audio" stream_index="0" pts="1024" pts_time="0.023220" dts="1024" dts_time="0.023220" duration="1024" duration_time="0.023220" size="2048" pos="263073" flags="K"/>
-        <frame media_type="audio" key_frame="1" pkt_pts="1024" pkt_pts_time="0.023220" pkt_dts="1024" pkt_dts_time="0.023220" pkt_duration="1024" pkt_duration_time="0.023220" pkt_pos="263073" sample_fmt="s16" nb_samples="1024" channels="1"/>
+        <frame media_type="audio" key_frame="1" pkt_pts="1024" pkt_pts_time="0.023220" pkt_dts="1024" pkt_dts_time="0.023220" pkt_duration="1024" pkt_duration_time="0.023220" pkt_pos="263073" pkt_size="2048" sample_fmt="s16" nb_samples="1024" channels="1"/>
         <packet codec_type="video" stream_index="1" pts="2048" pts_time="0.040000" dts="2048" dts_time="0.040000" duration="2048" duration_time="0.040000" size="230400" pos="265151" flags="K"/>
         <frame media_type="video" key_frame="1" pkt_pts="2048" pkt_pts_time="0.040000" pkt_dts="2048" pkt_dts_time="0.040000" pkt_duration="2048" pkt_duration_time="0.040000" pkt_pos="265151" 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" reference="0"/>
         <packet codec_type="video" stream_index="2" pts="2048" pts_time="0.040000" dts="2048" dts_time="0.040000" duration="2048" duration_time="0.040000" size="30000" pos="495575" flags="K"/>
         <frame media_type="video" key_frame="1" pkt_pts="2048" pkt_pts_time="0.040000" pkt_dts="2048" pkt_dts_time="0.040000" pkt_duration="2048" pkt_duration_time="0.040000" pkt_pos="495575" 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" reference="0"/>
         <packet codec_type="audio" stream_index="0" pts="2048" pts_time="0.046440" dts="2048" dts_time="0.046440" duration="1024" duration_time="0.023220" size="2048" pos="525580" flags="K"/>
-        <frame media_type="audio" key_frame="1" pkt_pts="2048" pkt_pts_time="0.046440" pkt_dts="2048" pkt_dts_time="0.046440" pkt_duration="1024" pkt_duration_time="0.023220" pkt_pos="525580" sample_fmt="s16" nb_samples="1024" channels="1"/>
+        <frame media_type="audio" key_frame="1" pkt_pts="2048" pkt_pts_time="0.046440" pkt_dts="2048" pkt_dts_time="0.046440" pkt_duration="1024" pkt_duration_time="0.023220" pkt_pos="525580" pkt_size="2048" sample_fmt="s16" nb_samples="1024" channels="1"/>
         <packet codec_type="audio" stream_index="0" pts="3072" pts_time="0.069660" dts="3072" dts_time="0.069660" duration="1024" duration_time="0.023220" size="2048" pos="527651" flags="K"/>
-        <frame media_type="audio" key_frame="1" pkt_pts="3072" pkt_pts_time="0.069660" pkt_dts="3072" pkt_dts_time="0.069660" pkt_duration="1024" pkt_duration_time="0.023220" pkt_pos="527651" sample_fmt="s16" nb_samples="1024" channels="1"/>
+        <frame media_type="audio" key_frame="1" pkt_pts="3072" pkt_pts_time="0.069660" pkt_dts="3072" pkt_dts_time="0.069660" pkt_duration="1024" pkt_duration_time="0.023220" pkt_pos="527651" pkt_size="2048" sample_fmt="s16" nb_samples="1024" channels="1"/>
         <packet codec_type="video" stream_index="1" pts="4096" pts_time="0.080000" dts="4096" dts_time="0.080000" duration="2048" duration_time="0.040000" size="230400" pos="529729" flags="K"/>
         <frame media_type="video" key_frame="1" pkt_pts="4096" pkt_pts_time="0.080000" pkt_dts="4096" pkt_dts_time="0.080000" pkt_duration="2048" pkt_duration_time="0.040000" pkt_pos="529729" 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" reference="0"/>
         <packet codec_type="video" stream_index="2" pts="4096" pts_time="0.080000" dts="4096" dts_time="0.080000" duration="2048" duration_time="0.040000" size="30000" pos="760153" flags="K"/>
         <frame media_type="video" key_frame="1" pkt_pts="4096" pkt_pts_time="0.080000" pkt_dts="4096" pkt_dts_time="0.080000" pkt_duration="2048" pkt_duration_time="0.040000" pkt_pos="760153" 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" reference="0"/>
         <packet codec_type="audio" stream_index="0" pts="4096" pts_time="0.092880" dts="4096" dts_time="0.092880" duration="1024" duration_time="0.023220" size="2048" pos="790158" flags="K"/>
-        <frame media_type="audio" key_frame="1" pkt_pts="4096" pkt_pts_time="0.092880" pkt_dts="4096" pkt_dts_time="0.092880" pkt_duration="1024" pkt_duration_time="0.023220" pkt_pos="790158" sample_fmt="s16" nb_samples="1024" channels="1"/>
+        <frame media_type="audio" key_frame="1" pkt_pts="4096" pkt_pts_time="0.092880" pkt_dts="4096" pkt_dts_time="0.092880" pkt_duration="1024" pkt_duration_time="0.023220" pkt_pos="790158" pkt_size="2048" sample_fmt="s16" nb_samples="1024" channels="1"/>
         <packet codec_type="audio" stream_index="0" pts="5120" pts_time="0.116100" dts="5120" dts_time="0.116100" duration="1024" duration_time="0.023220" size="2048" pos="792229" flags="K"/>
-        <frame media_type="audio" key_frame="1" pkt_pts="5120" pkt_pts_time="0.116100" pkt_dts="5120" pkt_dts_time="0.116100" pkt_duration="1024" pkt_duration_time="0.023220" pkt_pos="792229" sample_fmt="s16" nb_samples="1024" channels="1"/>
+        <frame media_type="audio" key_frame="1" pkt_pts="5120" pkt_pts_time="0.116100" pkt_dts="5120" pkt_dts_time="0.116100" pkt_duration="1024" pkt_duration_time="0.023220" pkt_pos="792229" pkt_size="2048" sample_fmt="s16" nb_samples="1024" channels="1"/>
         <packet codec_type="video" stream_index="1" pts="6144" pts_time="0.120000" dts="6144" dts_time="0.120000" duration="2048" duration_time="0.040000" size="230400" pos="794307" 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="794307" 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" reference="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" size="30000" pos="1024731" flags="K"/>
diff --git a/tests/ref/fate/film-cvid b/tests/ref/fate/film-cvid
index 12b1f1c..3ca7b59 100644
--- a/tests/ref/fate/film-cvid
+++ b/tests/ref/fate/film-cvid
@@ -1,111 +1,111 @@
 #tb 0: 1/30
-0,          0,          0,        1,   107520, 0xa6c9fdd2
-0,          2,          2,        1,   107520, 0x61eb28c1
-0,          4,          4,        1,   107520, 0x45e20af7
-0,          6,          6,        1,   107520, 0x366970fc
-0,          8,          8,        1,   107520, 0xa392bcb3
-0,         10,         10,        1,   107520, 0xcf7bac98
-0,         12,         12,        1,   107520, 0x222eba53
-0,         14,         14,        1,   107520, 0x74e255a1
-0,         16,         16,        1,   107520, 0xc19eec6f
-0,         18,         18,        1,   107520, 0xa3880681
-0,         20,         20,        1,   107520, 0x957878db
-0,         22,         22,        1,   107520, 0x18340692
-0,         24,         24,        1,   107520, 0x9970f24d
-0,         26,         26,        1,   107520, 0xf08618aa
-0,         28,         28,        1,   107520, 0xee7324f0
-0,         30,         30,        1,   107520, 0xe15025b3
-0,         32,         32,        1,   107520, 0x8afa312e
-0,         34,         34,        1,   107520, 0x717a7d0f
-0,         36,         36,        1,   107520, 0x355c6e23
-0,         38,         38,        1,   107520, 0x7015a50f
-0,         40,         40,        1,   107520, 0xcdfc1a16
-0,         42,         42,        1,   107520, 0x38d929e7
-0,         44,         44,        1,   107520, 0x52913423
-0,         46,         46,        1,   107520, 0xe2c91c10
-0,         48,         48,        1,   107520, 0x85516e9c
-0,         50,         50,        1,   107520, 0xd1626030
-0,         52,         52,        1,   107520, 0xea7b16de
-0,         54,         54,        1,   107520, 0xa33eaa0d
-0,         56,         56,        1,   107520, 0x8e3be6a6
-0,         58,         58,        1,   107520, 0x14147bd6
-0,         60,         60,        1,   107520, 0x07d54bec
-0,         62,         62,        1,   107520, 0xe287a0a7
-0,         64,         64,        1,   107520, 0xc023a14d
-0,         66,         66,        1,   107520, 0x2437085d
-0,         68,         68,        1,   107520, 0x63823918
-0,         70,         70,        1,   107520, 0xbc17e198
-0,         72,         72,        1,   107520, 0x9d99bc81
-0,         74,         74,        1,   107520, 0x7e4ec71e
-0,         76,         76,        1,   107520, 0x55b98376
-0,         78,         78,        1,   107520, 0x356d8e9e
-0,         80,         80,        1,   107520, 0xf77e8a61
-0,         82,         82,        1,   107520, 0x5ae7c8c7
-0,         84,         84,        1,   107520, 0x8acf9322
-0,         86,         86,        1,   107520, 0x40a9177e
-0,         88,         88,        1,   107520, 0x3e0e4d8d
-0,         90,         90,        1,   107520, 0xd268865b
-0,         92,         92,        1,   107520, 0x89a4efeb
-0,         94,         94,        1,   107520, 0x70ca2478
-0,         96,         96,        1,   107520, 0xcc9ec981
-0,         98,         98,        1,   107520, 0xf0648459
-0,        100,        100,        1,   107520, 0x7e4a4cca
-0,        102,        102,        1,   107520, 0xb315dc65
-0,        104,        104,        1,   107520, 0x2aecc7b4
-0,        106,        106,        1,   107520, 0x81742f51
-0,        108,        108,        1,   107520, 0x3a1d7571
-0,        110,        110,        1,   107520, 0x3a1d7571
-0,        112,        112,        1,   107520, 0x3a1d7571
-0,        114,        114,        1,   107520, 0x3a1d7571
-0,        116,        116,        1,   107520, 0x3a1d7571
-0,        118,        118,        1,   107520, 0x3a1d7571
-0,        120,        120,        1,   107520, 0x3a1d7571
-0,        122,        122,        1,   107520, 0xe974733e
-0,        124,        124,        1,   107520, 0x999c6fbf
-0,        126,        126,        1,   107520, 0x26b56b6e
-0,        128,        128,        1,   107520, 0xc9f9647b
-0,        130,        130,        1,   107520, 0x6d025d00
-0,        132,        132,        1,   107520, 0xf9c056c1
-0,        134,        134,        1,   107520, 0xa5cc4d0b
-0,        136,        136,        1,   107520, 0x1a4c4236
-0,        138,        138,        1,   107520, 0xa9d538b6
-0,        140,        140,        1,   107520, 0x14682d00
-0,        142,        142,        1,   107520, 0x6236204f
-0,        144,        144,        1,   107520, 0x303e14aa
-0,        146,        146,        1,   107520, 0x943b0837
-0,        148,        148,        1,   107520, 0xfce5fd07
-0,        150,        150,        1,   107520, 0xd993f193
-0,        152,        152,        1,   107520, 0x4d48e7b4
-0,        154,        154,        1,   107520, 0x61ccdf83
-0,        156,        156,        1,   107520, 0xfb4fd608
-0,        158,        158,        1,   107520, 0x5efdcdb3
-0,        160,        160,        1,   107520, 0xb03ec886
-0,        162,        162,        1,   107520, 0xf464c343
-0,        164,        164,        1,   107520, 0xf464c343
-0,        166,        166,        1,   107520, 0xf464c343
-0,        168,        168,        1,   107520, 0xf464c343
-0,        170,        170,        1,   107520, 0xf464c343
-0,        172,        172,        1,   107520, 0xf464c343
-0,        174,        174,        1,   107520, 0xf464c343
-0,        176,        176,        1,   107520, 0xf464c343
-0,        178,        178,        1,   107520, 0xf464c343
-0,        180,        180,        1,   107520, 0xf464c343
-0,        182,        182,        1,   107520, 0xf464c343
-0,        184,        184,        1,   107520, 0xf2b2c712
-0,        186,        186,        1,   107520, 0xf2b2c712
-0,        188,        188,        1,   107520, 0xf2b2c712
-0,        190,        190,        1,   107520, 0xf2b2c712
-0,        192,        192,        1,   107520, 0xb95e6bc8
-0,        194,        194,        1,   107520, 0x33feee37
-0,        196,        196,        1,   107520, 0x36ee3cd5
-0,        198,        198,        1,   107520, 0x59096471
-0,        200,        200,        1,   107520, 0x53b470c6
-0,        202,        202,        1,   107520, 0xdb7c64ff
-0,        204,        204,        1,   107520, 0xe5a1596a
-0,        206,        206,        1,   107520, 0x8c8942eb
-0,        208,        208,        1,   107520, 0x5ecc379e
-0,        210,        210,        1,   107520, 0xea09432a
-0,        212,        212,        1,   107520, 0xe01e6b73
-0,        214,        214,        1,   107520, 0x1d13bba8
-0,        216,        216,        1,   107520, 0x3a993a6c
-0,        218,        218,        1,   107520, 0x2ede041a
+0,          0,          0,        1,   215040, 0x067c5362
+0,          2,          2,        1,   215040, 0xd9eacb98
+0,          4,          4,        1,   215040, 0x3c8a4cbd
+0,          6,          6,        1,   215040, 0xbdf996e1
+0,          8,          8,        1,   215040, 0x1b7fa123
+0,         10,         10,        1,   215040, 0x834b4a8d
+0,         12,         12,        1,   215040, 0xf4b1bebe
+0,         14,         14,        1,   215040, 0x088c3802
+0,         16,         16,        1,   215040, 0xf6ddedb9
+0,         18,         18,        1,   215040, 0x2791d538
+0,         20,         20,        1,   215040, 0x81fe4688
+0,         22,         22,        1,   215040, 0xad864fbd
+0,         24,         24,        1,   215040, 0xa637a97a
+0,         26,         26,        1,   215040, 0x2287e378
+0,         28,         28,        1,   215040, 0x13a017d7
+0,         30,         30,        1,   215040, 0x89a4acee
+0,         32,         32,        1,   215040, 0x97888ffc
+0,         34,         34,        1,   215040, 0x7c2c3b58
+0,         36,         36,        1,   215040, 0x2e3ab808
+0,         38,         38,        1,   215040, 0x2d553af2
+0,         40,         40,        1,   215040, 0x929c420e
+0,         42,         42,        1,   215040, 0x4841bd6d
+0,         44,         44,        1,   215040, 0xb350fbcd
+0,         46,         46,        1,   215040, 0x0d70b918
+0,         48,         48,        1,   215040, 0xf98b0f47
+0,         50,         50,        1,   215040, 0x748b8ff2
+0,         52,         52,        1,   215040, 0x62017c38
+0,         54,         54,        1,   215040, 0x46042bb4
+0,         56,         56,        1,   215040, 0xe7a74806
+0,         58,         58,        1,   215040, 0xb4c856e6
+0,         60,         60,        1,   215040, 0xb21a28dd
+0,         62,         62,        1,   215040, 0x2a6e0834
+0,         64,         64,        1,   215040, 0x7044d6ca
+0,         66,         66,        1,   215040, 0x17780335
+0,         68,         68,        1,   215040, 0x94f51e7a
+0,         70,         70,        1,   215040, 0x5beb5f5f
+0,         72,         72,        1,   215040, 0xc7d59527
+0,         74,         74,        1,   215040, 0x40f69049
+0,         76,         76,        1,   215040, 0x1f78740e
+0,         78,         78,        1,   215040, 0x49f7265d
+0,         80,         80,        1,   215040, 0x057ac5c9
+0,         82,         82,        1,   215040, 0x649bd476
+0,         84,         84,        1,   215040, 0x1c75aa43
+0,         86,         86,        1,   215040, 0xc4bd1e29
+0,         88,         88,        1,   215040, 0x5033fa74
+0,         90,         90,        1,   215040, 0xba5c949e
+0,         92,         92,        1,   215040, 0x2fa78a0e
+0,         94,         94,        1,   215040, 0x9d363dce
+0,         96,         96,        1,   215040, 0xd1dc82b0
+0,         98,         98,        1,   215040, 0xd25be322
+0,        100,        100,        1,   215040, 0xf1374ef9
+0,        102,        102,        1,   215040, 0x33467b42
+0,        104,        104,        1,   215040, 0x7ec7dfad
+0,        106,        106,        1,   215040, 0x706ed416
+0,        108,        108,        1,   215040, 0x6576b3eb
+0,        110,        110,        1,   215040, 0x6576b3eb
+0,        112,        112,        1,   215040, 0x6576b3eb
+0,        114,        114,        1,   215040, 0x6576b3eb
+0,        116,        116,        1,   215040, 0x6576b3eb
+0,        118,        118,        1,   215040, 0x6576b3eb
+0,        120,        120,        1,   215040, 0x6576b3eb
+0,        122,        122,        1,   215040, 0x6873993d
+0,        124,        124,        1,   215040, 0x8c2a84d8
+0,        126,        126,        1,   215040, 0xdd456bd5
+0,        128,        128,        1,   215040, 0x50fa4f3d
+0,        130,        130,        1,   215040, 0x00c4369c
+0,        132,        132,        1,   215040, 0xe4c220d2
+0,        134,        134,        1,   215040, 0xe43a033b
+0,        136,        136,        1,   215040, 0x72f6e32c
+0,        138,        138,        1,   215040, 0xb738c69c
+0,        140,        140,        1,   215040, 0x56bda3fe
+0,        142,        142,        1,   215040, 0xaa2f7da3
+0,        144,        144,        1,   215040, 0xf21f5c24
+0,        146,        146,        1,   215040, 0xd33e3579
+0,        148,        148,        1,   215040, 0x6a601495
+0,        150,        150,        1,   215040, 0xdfcff1e0
+0,        152,        152,        1,   215040, 0xa774d327
+0,        154,        154,        1,   215040, 0x8e9db8c9
+0,        156,        156,        1,   215040, 0xb4fd9689
+0,        158,        158,        1,   215040, 0xa80b77ff
+0,        160,        160,        1,   215040, 0x1d9c6568
+0,        162,        162,        1,   215040, 0x388c515a
+0,        164,        164,        1,   215040, 0x388c515a
+0,        166,        166,        1,   215040, 0x388c515a
+0,        168,        168,        1,   215040, 0x388c515a
+0,        170,        170,        1,   215040, 0x388c515a
+0,        172,        172,        1,   215040, 0x388c515a
+0,        174,        174,        1,   215040, 0x388c515a
+0,        176,        176,        1,   215040, 0x388c515a
+0,        178,        178,        1,   215040, 0x388c515a
+0,        180,        180,        1,   215040, 0x388c515a
+0,        182,        182,        1,   215040, 0x388c515a
+0,        184,        184,        1,   215040, 0x3aef5fee
+0,        186,        186,        1,   215040, 0x3aef5fee
+0,        188,        188,        1,   215040, 0x3aef5fee
+0,        190,        190,        1,   215040, 0x3aef5fee
+0,        192,        192,        1,   215040, 0x7f8e4b62
+0,        194,        194,        1,   215040, 0xbf9fcae8
+0,        196,        196,        1,   215040, 0x02f9a66c
+0,        198,        198,        1,   215040, 0x00ef062f
+0,        200,        200,        1,   215040, 0xe83b132c
+0,        202,        202,        1,   215040, 0x2701d21b
+0,        204,        204,        1,   215040, 0xbea79188
+0,        206,        206,        1,   215040, 0x6f6d3109
+0,        208,        208,        1,   215040, 0x4173f1e8
+0,        210,        210,        1,   215040, 0xd7adfce1
+0,        212,        212,        1,   215040, 0xa3825ffd
+0,        214,        214,        1,   215040, 0x41e63fe4
+0,        216,        216,        1,   215040, 0xb525b9c5
+0,        218,        218,        1,   215040, 0x00000000
diff --git a/tests/ref/fate/filter-delogo b/tests/ref/fate/filter-delogo
index e0f24cd..bc58777 100644
--- a/tests/ref/fate/filter-delogo
+++ b/tests/ref/fate/filter-delogo
@@ -8,13 +8,13 @@
 0,          6,          6,        1,   126720, 0x94a0f126
 0,          7,          7,        1,   126720, 0x0250f106
 0,          8,          8,        1,   126720, 0xcf6ab4bc
-0,          9,          9,        1,   126720, 0x44aeb57c
-0,         10,         10,        1,   126720, 0x33b0b5bc
-0,         11,         11,        1,   126720, 0xc4bab591
+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, 0x1459b85c
-0,         14,         14,        1,   126720, 0x806fb8dc
-0,         15,         15,        1,   126720, 0xd241b871
+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
@@ -28,83 +28,83 @@
 0,         26,         26,        1,   126720, 0x7af2ea86
 0,         27,         27,        1,   126720, 0x40d4b4eb
 0,         28,         28,        1,   126720, 0x49d00307
-0,         29,         29,        1,   126720, 0x44c8848e
-0,         30,         30,        1,   126720, 0xc6990101
-0,         31,         31,        1,   126720, 0x2e01b963
+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, 0x3457d592
-0,         34,         34,        1,   126720, 0x4f1ddb3c
-0,         35,         35,        1,   126720, 0x3980ace5
+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, 0x619fc554
-0,         38,         38,        1,   126720, 0x945fb39e
-0,         39,         39,        1,   126720, 0xb1d5e0ce
+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, 0x04d5783e
-0,         42,         42,        1,   126720, 0xbaa0479e
-0,         43,         43,        1,   126720, 0x20d88b01
+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, 0x1c6e09f6
-0,         46,         46,        1,   126720, 0xeec50fc5
-0,         47,         47,        1,   126720, 0xb3a92827
-0,         48,         48,        1,   126720, 0xf62dd2b6
-0,         49,         49,        1,   126720, 0x75b1e619
-0,         50,         50,        1,   126720, 0x6bbce2c0
-0,         51,         51,        1,   126720, 0xd93e023c
-0,         52,         52,        1,   126720, 0xbbe8e7c2
-0,         53,         53,        1,   126720, 0x2272ec17
-0,         54,         54,        1,   126720, 0xf5e4ee6e
-0,         55,         55,        1,   126720, 0x751d2607
-0,         56,         56,        1,   126720, 0x44c499c9
-0,         57,         57,        1,   126720, 0xddccd842
-0,         58,         58,        1,   126720, 0x508dd214
-0,         59,         59,        1,   126720, 0x8eb10272
-0,         60,         60,        1,   126720, 0x7224b1c6
-0,         61,         61,        1,   126720, 0x50ff456c
-0,         62,         62,        1,   126720, 0xa81e2731
-0,         63,         63,        1,   126720, 0x7e50456d
-0,         64,         64,        1,   126720, 0x44802978
-0,         65,         65,        1,   126720, 0x86e88743
-0,         66,         66,        1,   126720, 0x0b1087d6
-0,         67,         67,        1,   126720, 0xb0227d21
-0,         68,         68,        1,   126720, 0x29d10bd2
-0,         69,         69,        1,   126720, 0x04b43afa
-0,         70,         70,        1,   126720, 0xb48e9698
-0,         71,         71,        1,   126720, 0x75d760fb
-0,         72,         72,        1,   126720, 0xa2ab1fdb
-0,         73,         73,        1,   126720, 0xec30a5ee
-0,         74,         74,        1,   126720, 0xbdab7c8c
-0,         75,         75,        1,   126720, 0xac5c3f2c
-0,         76,         76,        1,   126720, 0xce6350be
-0,         77,         77,        1,   126720, 0xb109657a
-0,         78,         78,        1,   126720, 0x723865a4
-0,         79,         79,        1,   126720, 0xa9869124
-0,         80,         80,        1,   126720, 0xc41af558
-0,         81,         81,        1,   126720, 0xcbe6a402
-0,         82,         82,        1,   126720, 0xb6735ecb
-0,         83,         83,        1,   126720, 0xba3059f2
-0,         84,         84,        1,   126720, 0xe7d63b8d
-0,         85,         85,        1,   126720, 0x8f115906
-0,         86,         86,        1,   126720, 0xaf6a8dcb
-0,         87,         87,        1,   126720, 0xb73e846e
-0,         88,         88,        1,   126720, 0xedd6380f
-0,         89,         89,        1,   126720, 0xd9026acf
-0,         90,         90,        1,   126720, 0xa03a650b
-0,         91,         91,        1,   126720, 0x262765bc
-0,         92,         92,        1,   126720, 0xaaa9ded1
-0,         93,         93,        1,   126720, 0xe4f42665
-0,         94,         94,        1,   126720, 0x78daf760
-0,         95,         95,        1,   126720, 0x3b0c6ef8
-0,         96,         96,        1,   126720, 0xb745df80
-0,         97,         97,        1,   126720, 0x08e57b90
-0,         98,         98,        1,   126720, 0x6f883ab0
-0,         99,         99,        1,   126720, 0x934b4dd5
-0,        100,        100,        1,   126720, 0x762f108f
-0,        101,        101,        1,   126720, 0x91ee0f2b
-0,        102,        102,        1,   126720, 0x9af6e5e8
-0,        103,        103,        1,   126720, 0xdcd95e0a
-0,        104,        104,        1,   126720, 0x22c33a6e
-0,        105,        105,        1,   126720, 0x21c1b7f4
-0,        106,        106,        1,   126720, 0x0a66a1ed
-0,        107,        107,        1,   126720, 0x53fea81b
-0,        108,        108,        1,   126720, 0x597f5567
+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
diff --git a/tests/ref/fate/filter-gradfun b/tests/ref/fate/filter-gradfun
new file mode 100644
index 0000000..dca442f
--- /dev/null
+++ b/tests/ref/fate/filter-gradfun
@@ -0,0 +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
diff --git a/tests/ref/fate/filter-hqdn3d b/tests/ref/fate/filter-hqdn3d
new file mode 100644
index 0000000..d69e6db
--- /dev/null
+++ b/tests/ref/fate/filter-hqdn3d
@@ -0,0 +1,74 @@
+#tb 0: 1/9
+0,          0,          0,        1,   115200, 0x2c810465
+0,          1,          1,        1,   115200, 0x957c0563
+0,          2,          2,        1,   115200, 0x786c6d5b
+0,          3,          3,        1,   115200, 0xd5ef87d3
+0,          4,          4,        1,   115200, 0x3a2158e2
+0,          5,          5,        1,   115200, 0x19d7d048
+0,          6,          6,        1,   115200, 0x16d5e09a
+0,          7,          7,        1,   115200, 0x73cca454
+0,          8,          8,        1,   115200, 0x4d6be3bc
+0,          9,          9,        1,   115200, 0x672aad0f
+0,         10,         10,        1,   115200, 0x1bd103b7
+0,         11,         11,        1,   115200, 0xbc3a9c02
+0,         12,         12,        1,   115200, 0xa19cb68c
+0,         13,         13,        1,   115200, 0x83477b6c
+0,         14,         14,        1,   115200, 0x68b6898e
+0,         15,         15,        1,   115200, 0xebbc5701
+0,         16,         16,        1,   115200, 0x37e873db
+0,         17,         17,        1,   115200, 0xcf9e7ad1
+0,         18,         18,        1,   115200, 0x3fdffd3a
+0,         19,         19,        1,   115200, 0x413da058
+0,         20,         20,        1,   115200, 0xa432b2f6
+0,         21,         21,        1,   115200, 0x9c532b61
+0,         22,         22,        1,   115200, 0x40c03856
+0,         23,         23,        1,   115200, 0xf8310ec7
+0,         24,         24,        1,   115200, 0x89246da7
+0,         25,         25,        1,   115200, 0x501d4dd0
+0,         26,         26,        1,   115200, 0xe5151ebf
+0,         27,         27,        1,   115200, 0xc166e201
+0,         28,         28,        1,   115200, 0xded25b69
+0,         29,         29,        1,   115200, 0xb51ec43f
+0,         30,         30,        1,   115200, 0x9bba20eb
+0,         31,         31,        1,   115200, 0x7a7b9278
+0,         32,         32,        1,   115200, 0xe98475d0
+0,         33,         33,        1,   115200, 0x960dc933
+0,         34,         34,        1,   115200, 0xe93f558b
+0,         35,         35,        1,   115200, 0x37ae3e42
+0,         36,         36,        1,   115200, 0x0ecaf64a
+0,         37,         37,        1,   115200, 0xd5938191
+0,         38,         38,        1,   115200, 0xeb04510a
+0,         39,         39,        1,   115200, 0xf5729201
+0,         40,         40,        1,   115200, 0xb2c04015
+0,         41,         41,        1,   115200, 0xd883143e
+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,         55,         55,        1,   115200, 0x2c581d60
+0,         56,         56,        1,   115200, 0xd7a506ed
+0,         57,         57,        1,   115200, 0x35e09799
+0,         58,         58,        1,   115200, 0x2d4f5499
+0,         59,         59,        1,   115200, 0x92fdc85b
+0,         60,         60,        1,   115200, 0x33f4888a
+0,         61,         61,        1,   115200, 0x65e04e05
+0,         62,         62,        1,   115200, 0x14766728
+0,         63,         63,        1,   115200, 0x2a432c3f
+0,         64,         64,        1,   115200, 0x136a1362
+0,         65,         65,        1,   115200, 0xfbf4cb01
+0,         66,         66,        1,   115200, 0x7dcaff69
+0,         67,         67,        1,   115200, 0x5afd3b9e
+0,         68,         68,        1,   115200, 0x86fcb122
+0,         69,         69,        1,   115200, 0xc988b519
+0,         70,         70,        1,   115200, 0x48fd3e75
+0,         71,         71,        1,   115200, 0x2728a2d7
+0,         72,         72,        1,   115200, 0xa2ac6418
diff --git a/tests/ref/fate/filter-metadata-scenedetect b/tests/ref/fate/filter-metadata-scenedetect
index 0b344d9..dd5e3a4 100644
--- a/tests/ref/fate/filter-metadata-scenedetect
+++ b/tests/ref/fate/filter-metadata-scenedetect
@@ -1,10 +1,10 @@
-video|1|1620|2.700000|1620|2.700000|1|0.001667|155751|320|240|rgb24|1:1|I|0|0|0|0|0|0|1.000000
-video|1|4140|6.900000|4140|6.900000|1|0.001667|808205|320|240|rgb24|1:1|I|0|0|0|0|0|0|0.880000
-video|1|5800|9.666667|5800|9.666667|1|0.001667|928577|320|240|rgb24|1:1|I|0|0|0|0|0|0|1.000000
-video|1|6720|11.200000|6720|11.200000|1|0.001667|1027359|320|240|rgb24|1:1|I|0|0|0|0|0|0|0.460000
-video|1|8160|13.600000|8160|13.600000|1|0.001667|1247869|320|240|rgb24|1:1|I|0|0|0|0|0|0|1.000000
-video|1|9760|16.266667|9760|16.266667|1|0.001667|1337561|320|240|rgb24|1:1|I|0|0|0|0|0|0|1.000000
-video|1|14080|23.466667|14080|23.466667|1|0.001667|1994159|320|240|rgb24|1:1|I|0|0|0|0|0|0|0.840000
-video|1|15700|26.166667|15700|26.166667|1|0.001667|2145781|320|240|rgb24|1:1|I|0|0|0|0|0|0|1.000000
-video|1|18500|30.833333|18500|30.833333|1|0.001667|2507729|320|240|rgb24|1:1|I|0|0|0|0|0|0|0.470000
-video|1|21760|36.266667|21760|36.266667|1|0.001667|2932267|320|240|rgb24|1:1|I|0|0|0|0|0|0|1.000000
+video|1|1620|2.700000|1620|2.700000|1|0.001667|155751|N/A|320|240|rgb24|1:1|I|0|0|0|0|0|0|1.000000
+video|1|4140|6.900000|4140|6.900000|1|0.001667|808205|N/A|320|240|rgb24|1:1|I|0|0|0|0|0|0|0.880000
+video|1|5800|9.666667|5800|9.666667|1|0.001667|928577|N/A|320|240|rgb24|1:1|I|0|0|0|0|0|0|1.000000
+video|1|6720|11.200000|6720|11.200000|1|0.001667|1027359|N/A|320|240|rgb24|1:1|I|0|0|0|0|0|0|0.460000
+video|1|8160|13.600000|8160|13.600000|1|0.001667|1247869|N/A|320|240|rgb24|1:1|I|0|0|0|0|0|0|1.000000
+video|1|9760|16.266667|9760|16.266667|1|0.001667|1337561|N/A|320|240|rgb24|1:1|I|0|0|0|0|0|0|1.000000
+video|1|14080|23.466667|14080|23.466667|1|0.001667|1994159|N/A|320|240|rgb24|1:1|I|0|0|0|0|0|0|0.840000
+video|1|15700|26.166667|15700|26.166667|1|0.001667|2145781|N/A|320|240|rgb24|1:1|I|0|0|0|0|0|0|1.000000
+video|1|18500|30.833333|18500|30.833333|1|0.001667|2507729|N/A|320|240|rgb24|1:1|I|0|0|0|0|0|0|0.470000
+video|1|21760|36.266667|21760|36.266667|1|0.001667|2932267|N/A|320|240|rgb24|1:1|I|0|0|0|0|0|0|1.000000
diff --git a/tests/ref/fate/filter-metadata-silencedetect b/tests/ref/fate/filter-metadata-silencedetect
index 903d69e..ee42ec0 100644
--- a/tests/ref/fate/filter-metadata-silencedetect
+++ b/tests/ref/fate/filter-metadata-silencedetect
@@ -1,512 +1,512 @@
-audio|1|0|0.000000|0|0.000000|320|0.020000|44|dbl|320|1|mono
-audio|1|320|0.020000|320|0.020000|320|0.020000|77|dbl|320|1|mono
-audio|1|640|0.040000|640|0.040000|320|0.020000|110|dbl|320|1|mono
-audio|1|960|0.060000|960|0.060000|320|0.020000|143|dbl|320|1|mono
-audio|1|1280|0.080000|1280|0.080000|320|0.020000|176|dbl|320|1|mono
-audio|1|1600|0.100000|1600|0.100000|320|0.020000|209|dbl|320|1|mono
-audio|1|1920|0.120000|1920|0.120000|324|0.020250|242|dbl|320|1|mono|0.02
-audio|1|2240|0.140000|2240|0.140000|320|0.020000|275|dbl|320|1|mono
-audio|1|2560|0.160000|2560|0.160000|328|0.020500|308|dbl|320|1|mono|0.16|0.14
-audio|1|2880|0.180000|2880|0.180000|320|0.020000|341|dbl|320|1|mono
-audio|1|3200|0.200000|3200|0.200000|320|0.020000|374|dbl|320|1|mono
-audio|1|3520|0.220000|3520|0.220000|320|0.020000|407|dbl|320|1|mono
-audio|1|3840|0.240000|3840|0.240000|320|0.020000|440|dbl|320|1|mono
-audio|1|4160|0.260000|4160|0.260000|320|0.020000|473|dbl|320|1|mono
-audio|1|4480|0.280000|4480|0.280000|320|0.020000|506|dbl|320|1|mono
-audio|1|4800|0.300000|4800|0.300000|320|0.020000|539|dbl|320|1|mono
-audio|1|5120|0.320000|5120|0.320000|320|0.020000|572|dbl|320|1|mono
-audio|1|5440|0.340000|5440|0.340000|320|0.020000|605|dbl|320|1|mono
-audio|1|5760|0.360000|5760|0.360000|331|0.020688|638|dbl|320|1|mono|0.26|0.36|0.1
-audio|1|6080|0.380000|6080|0.380000|320|0.020000|671|dbl|320|1|mono
-audio|1|6400|0.400000|6400|0.400000|320|0.020000|704|dbl|320|1|mono
-audio|1|6720|0.420000|6720|0.420000|320|0.020000|737|dbl|320|1|mono
-audio|1|7040|0.440000|7040|0.440000|320|0.020000|770|dbl|320|1|mono
-audio|1|7360|0.460000|7360|0.460000|320|0.020000|803|dbl|320|1|mono
-audio|1|7680|0.480000|7680|0.480000|320|0.020000|836|dbl|320|1|mono
-audio|1|8000|0.500000|8000|0.500000|320|0.020000|869|dbl|320|1|mono
-audio|1|8320|0.520000|8320|0.520000|320|0.020000|902|dbl|320|1|mono
-audio|1|8640|0.540000|8640|0.540000|320|0.020000|935|dbl|320|1|mono
-audio|1|8960|0.560000|8960|0.560000|320|0.020000|968|dbl|320|1|mono
-audio|1|9280|0.580000|9280|0.580000|320|0.020000|1001|dbl|320|1|mono
-audio|1|9600|0.600000|9600|0.600000|320|0.020000|1034|dbl|320|1|mono
-audio|1|9920|0.620000|9920|0.620000|320|0.020000|1067|dbl|320|1|mono
-audio|1|10240|0.640000|10240|0.640000|320|0.020000|1100|dbl|320|1|mono
-audio|1|10560|0.660000|10560|0.660000|320|0.020000|1133|dbl|320|1|mono
-audio|1|10880|0.680000|10880|0.680000|320|0.020000|1166|dbl|320|1|mono
-audio|1|11200|0.700000|11200|0.700000|320|0.020000|1199|dbl|320|1|mono
-audio|1|11520|0.720000|11520|0.720000|320|0.020000|1232|dbl|320|1|mono
-audio|1|11840|0.740000|11840|0.740000|320|0.020000|1265|dbl|320|1|mono
-audio|1|12160|0.760000|12160|0.760000|320|0.020000|1298|dbl|320|1|mono
-audio|1|12480|0.780000|12480|0.780000|320|0.020000|1331|dbl|320|1|mono
-audio|1|12800|0.800000|12800|0.800000|320|0.020000|1364|dbl|320|1|mono
-audio|1|13120|0.820000|13120|0.820000|320|0.020000|1397|dbl|320|1|mono
-audio|1|13440|0.840000|13440|0.840000|320|0.020000|1430|dbl|320|1|mono
-audio|1|13760|0.860000|13760|0.860000|320|0.020000|1463|dbl|320|1|mono
-audio|1|14080|0.880000|14080|0.880000|320|0.020000|1496|dbl|320|1|mono
-audio|1|14400|0.900000|14400|0.900000|320|0.020000|1529|dbl|320|1|mono
-audio|1|14720|0.920000|14720|0.920000|320|0.020000|1562|dbl|320|1|mono
-audio|1|15040|0.940000|15040|0.940000|320|0.020000|1595|dbl|320|1|mono
-audio|1|15360|0.960000|15360|0.960000|320|0.020000|1628|dbl|320|1|mono
-audio|1|15680|0.980000|15680|0.980000|320|0.020000|1661|dbl|320|1|mono
-audio|1|16000|1.000000|16000|1.000000|320|0.020000|1694|dbl|320|1|mono
-audio|1|16320|1.020000|16320|1.020000|320|0.020000|1727|dbl|320|1|mono
-audio|1|16640|1.040000|16640|1.040000|320|0.020000|1760|dbl|320|1|mono
-audio|1|16960|1.060000|16960|1.060000|320|0.020000|1793|dbl|320|1|mono
-audio|1|17280|1.080000|17280|1.080000|320|0.020000|1826|dbl|320|1|mono
-audio|1|17600|1.100000|17600|1.100000|320|0.020000|1859|dbl|320|1|mono
-audio|1|17920|1.120000|17920|1.120000|320|0.020000|1892|dbl|320|1|mono
-audio|1|18240|1.140000|18240|1.140000|320|0.020000|1925|dbl|320|1|mono
-audio|1|18560|1.160000|18560|1.160000|320|0.020000|1958|dbl|320|1|mono
-audio|1|18880|1.180000|18880|1.180000|320|0.020000|1991|dbl|320|1|mono
-audio|1|19200|1.200000|19200|1.200000|320|0.020000|2024|dbl|320|1|mono
-audio|1|19520|1.220000|19520|1.220000|320|0.020000|2057|dbl|320|1|mono
-audio|1|19840|1.240000|19840|1.240000|320|0.020000|2090|dbl|320|1|mono
-audio|1|20160|1.260000|20160|1.260000|320|0.020000|2123|dbl|320|1|mono
-audio|1|20480|1.280000|20480|1.280000|320|0.020000|2156|dbl|320|1|mono
-audio|1|20800|1.300000|20800|1.300000|320|0.020000|2189|dbl|320|1|mono
-audio|1|21120|1.320000|21120|1.320000|320|0.020000|2222|dbl|320|1|mono
-audio|1|21440|1.340000|21440|1.340000|320|0.020000|2255|dbl|320|1|mono
-audio|1|21760|1.360000|21760|1.360000|320|0.020000|2288|dbl|320|1|mono
-audio|1|22080|1.380000|22080|1.380000|324|0.020250|2321|dbl|320|1|mono|1.28
-audio|1|22400|1.400000|22400|1.400000|320|0.020000|2354|dbl|320|1|mono
-audio|1|22720|1.420000|22720|1.420000|320|0.020000|2387|dbl|320|1|mono
-audio|1|23040|1.440000|23040|1.440000|320|0.020000|2420|dbl|320|1|mono
-audio|1|23360|1.460000|23360|1.460000|320|0.020000|2453|dbl|320|1|mono
-audio|1|23680|1.480000|23680|1.480000|320|0.020000|2486|dbl|320|1|mono
-audio|1|24000|1.500000|24000|1.500000|320|0.020000|2519|dbl|320|1|mono
-audio|1|24320|1.520000|24320|1.520000|320|0.020000|2552|dbl|320|1|mono
-audio|1|24640|1.540000|24640|1.540000|320|0.020000|2585|dbl|320|1|mono
-audio|1|24960|1.560000|24960|1.560000|320|0.020000|2618|dbl|320|1|mono
-audio|1|25280|1.580000|25280|1.580000|320|0.020000|2651|dbl|320|1|mono
-audio|1|25600|1.600000|25600|1.600000|320|0.020000|2684|dbl|320|1|mono
-audio|1|25920|1.620000|25920|1.620000|320|0.020000|2717|dbl|320|1|mono
-audio|1|26240|1.640000|26240|1.640000|320|0.020000|2750|dbl|320|1|mono
-audio|1|26560|1.660000|26560|1.660000|320|0.020000|2783|dbl|320|1|mono
-audio|1|26880|1.680000|26880|1.680000|320|0.020000|2816|dbl|320|1|mono
-audio|1|27200|1.700000|27200|1.700000|320|0.020000|2849|dbl|320|1|mono
-audio|1|27520|1.720000|27520|1.720000|320|0.020000|2882|dbl|320|1|mono
-audio|1|27840|1.740000|27840|1.740000|320|0.020000|2915|dbl|320|1|mono
-audio|1|28160|1.760000|28160|1.760000|320|0.020000|2948|dbl|320|1|mono
-audio|1|28480|1.780000|28480|1.780000|320|0.020000|2981|dbl|320|1|mono
-audio|1|28800|1.800000|28800|1.800000|320|0.020000|3014|dbl|320|1|mono
-audio|1|29120|1.820000|29120|1.820000|320|0.020000|3047|dbl|320|1|mono
-audio|1|29440|1.840000|29440|1.840000|320|0.020000|3080|dbl|320|1|mono
-audio|1|29760|1.860000|29760|1.860000|320|0.020000|3113|dbl|320|1|mono
-audio|1|30080|1.880000|30080|1.880000|320|0.020000|3146|dbl|320|1|mono
-audio|1|30400|1.900000|30400|1.900000|320|0.020000|3179|dbl|320|1|mono
-audio|1|30720|1.920000|30720|1.920000|320|0.020000|3212|dbl|320|1|mono
-audio|1|31040|1.940000|31040|1.940000|320|0.020000|3245|dbl|320|1|mono
-audio|1|31360|1.960000|31360|1.960000|320|0.020000|3278|dbl|320|1|mono
-audio|1|31680|1.980000|31680|1.980000|327|0.020438|3311|dbl|320|1|mono|1.98|0.7
-audio|1|32000|2.000000|32000|2.000000|320|0.020000|3344|dbl|320|1|mono
-audio|1|32320|2.020000|32320|2.020000|320|0.020000|3377|dbl|320|1|mono
-audio|1|32640|2.040000|32640|2.040000|320|0.020000|3410|dbl|320|1|mono
-audio|1|32960|2.060000|32960|2.060000|320|0.020000|3443|dbl|320|1|mono
-audio|1|33280|2.080000|33280|2.080000|320|0.020000|3476|dbl|320|1|mono
-audio|1|33600|2.100000|33600|2.100000|320|0.020000|3509|dbl|320|1|mono
-audio|1|33920|2.120000|33920|2.120000|320|0.020000|3542|dbl|320|1|mono
-audio|1|34240|2.140000|34240|2.140000|320|0.020000|3575|dbl|320|1|mono
-audio|1|34560|2.160000|34560|2.160000|320|0.020000|3608|dbl|320|1|mono
-audio|1|34880|2.180000|34880|2.180000|320|0.020000|3641|dbl|320|1|mono
-audio|1|35200|2.200000|35200|2.200000|320|0.020000|3674|dbl|320|1|mono
-audio|1|35520|2.220000|35520|2.220000|320|0.020000|3707|dbl|320|1|mono
-audio|1|35840|2.240000|35840|2.240000|320|0.020000|3740|dbl|320|1|mono
-audio|1|36160|2.260000|36160|2.260000|320|0.020000|3773|dbl|320|1|mono
-audio|1|36480|2.280000|36480|2.280000|320|0.020000|3806|dbl|320|1|mono
-audio|1|36800|2.300000|36800|2.300000|320|0.020000|3839|dbl|320|1|mono
-audio|1|37120|2.320000|37120|2.320000|320|0.020000|3872|dbl|320|1|mono
-audio|1|37440|2.340000|37440|2.340000|320|0.020000|3905|dbl|320|1|mono
-audio|1|37760|2.360000|37760|2.360000|320|0.020000|3938|dbl|320|1|mono
-audio|1|38080|2.380000|38080|2.380000|320|0.020000|3971|dbl|320|1|mono
-audio|1|38400|2.400000|38400|2.400000|320|0.020000|4004|dbl|320|1|mono
-audio|1|38720|2.420000|38720|2.420000|320|0.020000|4037|dbl|320|1|mono
-audio|1|39040|2.440000|39040|2.440000|320|0.020000|4070|dbl|320|1|mono
-audio|1|39360|2.460000|39360|2.460000|320|0.020000|4103|dbl|320|1|mono
-audio|1|39680|2.480000|39680|2.480000|320|0.020000|4136|dbl|320|1|mono
-audio|1|40000|2.500000|40000|2.500000|320|0.020000|4169|dbl|320|1|mono
-audio|1|40320|2.520000|40320|2.520000|320|0.020000|4202|dbl|320|1|mono
-audio|1|40640|2.540000|40640|2.540000|320|0.020000|4235|dbl|320|1|mono
-audio|1|40960|2.560000|40960|2.560000|320|0.020000|4268|dbl|320|1|mono
-audio|1|41280|2.580000|41280|2.580000|320|0.020000|4301|dbl|320|1|mono
-audio|1|41600|2.600000|41600|2.600000|320|0.020000|4334|dbl|320|1|mono
-audio|1|41920|2.620000|41920|2.620000|320|0.020000|4367|dbl|320|1|mono
-audio|1|42240|2.640000|42240|2.640000|320|0.020000|4400|dbl|320|1|mono
-audio|1|42560|2.660000|42560|2.660000|320|0.020000|4433|dbl|320|1|mono
-audio|1|42880|2.680000|42880|2.680000|320|0.020000|4466|dbl|320|1|mono
-audio|1|43200|2.700000|43200|2.700000|320|0.020000|4499|dbl|320|1|mono
-audio|1|43520|2.720000|43520|2.720000|320|0.020000|4532|dbl|320|1|mono
-audio|1|43840|2.740000|43840|2.740000|320|0.020000|4565|dbl|320|1|mono
-audio|1|44160|2.760000|44160|2.760000|320|0.020000|4598|dbl|320|1|mono
-audio|1|44480|2.780000|44480|2.780000|320|0.020000|4631|dbl|320|1|mono
-audio|1|44800|2.800000|44800|2.800000|320|0.020000|4664|dbl|320|1|mono
-audio|1|45120|2.820000|45120|2.820000|320|0.020000|4697|dbl|320|1|mono
-audio|1|45440|2.840000|45440|2.840000|320|0.020000|4730|dbl|320|1|mono
-audio|1|45760|2.860000|45760|2.860000|320|0.020000|4763|dbl|320|1|mono
-audio|1|46080|2.880000|46080|2.880000|320|0.020000|4796|dbl|320|1|mono
-audio|1|46400|2.900000|46400|2.900000|320|0.020000|4829|dbl|320|1|mono
-audio|1|46720|2.920000|46720|2.920000|320|0.020000|4862|dbl|320|1|mono
-audio|1|47040|2.940000|47040|2.940000|320|0.020000|4895|dbl|320|1|mono
-audio|1|47360|2.960000|47360|2.960000|320|0.020000|4928|dbl|320|1|mono
-audio|1|47680|2.980000|47680|2.980000|320|0.020000|4961|dbl|320|1|mono
-audio|1|48000|3.000000|48000|3.000000|320|0.020000|4994|dbl|320|1|mono
-audio|1|48320|3.020000|48320|3.020000|320|0.020000|5027|dbl|320|1|mono
-audio|1|48640|3.040000|48640|3.040000|320|0.020000|5060|dbl|320|1|mono
-audio|1|48960|3.060000|48960|3.060000|320|0.020000|5093|dbl|320|1|mono
-audio|1|49280|3.080000|49280|3.080000|320|0.020000|5126|dbl|320|1|mono
-audio|1|49600|3.100000|49600|3.100000|320|0.020000|5159|dbl|320|1|mono
-audio|1|49920|3.120000|49920|3.120000|320|0.020000|5192|dbl|320|1|mono
-audio|1|50240|3.140000|50240|3.140000|320|0.020000|5225|dbl|320|1|mono
-audio|1|50560|3.160000|50560|3.160000|320|0.020000|5258|dbl|320|1|mono
-audio|1|50880|3.180000|50880|3.180000|320|0.020000|5291|dbl|320|1|mono
-audio|1|51200|3.200000|51200|3.200000|320|0.020000|5324|dbl|320|1|mono
-audio|1|51520|3.220000|51520|3.220000|320|0.020000|5357|dbl|320|1|mono
-audio|1|51840|3.240000|51840|3.240000|320|0.020000|5390|dbl|320|1|mono
-audio|1|52160|3.260000|52160|3.260000|320|0.020000|5423|dbl|320|1|mono
-audio|1|52480|3.280000|52480|3.280000|320|0.020000|5456|dbl|320|1|mono
-audio|1|52800|3.300000|52800|3.300000|324|0.020250|5489|dbl|320|1|mono|3.2
-audio|1|53120|3.320000|53120|3.320000|320|0.020000|5522|dbl|320|1|mono
-audio|1|53440|3.340000|53440|3.340000|320|0.020000|5555|dbl|320|1|mono
-audio|1|53760|3.360000|53760|3.360000|320|0.020000|5588|dbl|320|1|mono
-audio|1|54080|3.380000|54080|3.380000|320|0.020000|5621|dbl|320|1|mono
-audio|1|54400|3.400000|54400|3.400000|320|0.020000|5654|dbl|320|1|mono
-audio|1|54720|3.420000|54720|3.420000|320|0.020000|5687|dbl|320|1|mono
-audio|1|55040|3.440000|55040|3.440000|320|0.020000|5720|dbl|320|1|mono
-audio|1|55360|3.460000|55360|3.460000|320|0.020000|5753|dbl|320|1|mono
-audio|1|55680|3.480000|55680|3.480000|320|0.020000|5786|dbl|320|1|mono
-audio|1|56000|3.500000|56000|3.500000|320|0.020000|5819|dbl|320|1|mono
-audio|1|56320|3.520000|56320|3.520000|320|0.020000|5852|dbl|320|1|mono
-audio|1|56640|3.540000|56640|3.540000|320|0.020000|5885|dbl|320|1|mono
-audio|1|56960|3.560000|56960|3.560000|320|0.020000|5918|dbl|320|1|mono
-audio|1|57280|3.580000|57280|3.580000|320|0.020000|5951|dbl|320|1|mono
-audio|1|57600|3.600000|57600|3.600000|320|0.020000|5984|dbl|320|1|mono
-audio|1|57920|3.620000|57920|3.620000|320|0.020000|6017|dbl|320|1|mono
-audio|1|58240|3.640000|58240|3.640000|320|0.020000|6050|dbl|320|1|mono
-audio|1|58560|3.660000|58560|3.660000|320|0.020000|6083|dbl|320|1|mono
-audio|1|58880|3.680000|58880|3.680000|320|0.020000|6116|dbl|320|1|mono
-audio|1|59200|3.700000|59200|3.700000|320|0.020000|6149|dbl|320|1|mono
-audio|1|59520|3.720000|59520|3.720000|320|0.020000|6182|dbl|320|1|mono
-audio|1|59840|3.740000|59840|3.740000|320|0.020000|6215|dbl|320|1|mono
-audio|1|60160|3.760000|60160|3.760000|320|0.020000|6248|dbl|320|1|mono
-audio|1|60480|3.780000|60480|3.780000|320|0.020000|6281|dbl|320|1|mono
-audio|1|60800|3.800000|60800|3.800000|320|0.020000|6314|dbl|320|1|mono
-audio|1|61120|3.820000|61120|3.820000|320|0.020000|6347|dbl|320|1|mono
-audio|1|61440|3.840000|61440|3.840000|320|0.020000|6380|dbl|320|1|mono
-audio|1|61760|3.860000|61760|3.860000|320|0.020000|6413|dbl|320|1|mono
-audio|1|62080|3.880000|62080|3.880000|320|0.020000|6446|dbl|320|1|mono
-audio|1|62400|3.900000|62400|3.900000|327|0.020438|6479|dbl|320|1|mono|3.9|0.7
-audio|1|62720|3.920000|62720|3.920000|320|0.020000|6512|dbl|320|1|mono
-audio|1|63040|3.940000|63040|3.940000|320|0.020000|6545|dbl|320|1|mono
-audio|1|63360|3.960000|63360|3.960000|320|0.020000|6578|dbl|320|1|mono
-audio|1|63680|3.980000|63680|3.980000|320|0.020000|6611|dbl|320|1|mono
-audio|1|64000|4.000000|64000|4.000000|320|0.020000|6644|dbl|320|1|mono
-audio|1|64320|4.020000|64320|4.020000|320|0.020000|6677|dbl|320|1|mono
-audio|1|64640|4.040000|64640|4.040000|320|0.020000|6710|dbl|320|1|mono
-audio|1|64960|4.060000|64960|4.060000|320|0.020000|6743|dbl|320|1|mono
-audio|1|65280|4.080000|65280|4.080000|320|0.020000|6776|dbl|320|1|mono
-audio|1|65600|4.100000|65600|4.100000|320|0.020000|6809|dbl|320|1|mono
-audio|1|65920|4.120000|65920|4.120000|320|0.020000|6842|dbl|320|1|mono
-audio|1|66240|4.140000|66240|4.140000|320|0.020000|6875|dbl|320|1|mono
-audio|1|66560|4.160000|66560|4.160000|320|0.020000|6908|dbl|320|1|mono
-audio|1|66880|4.180000|66880|4.180000|320|0.020000|6941|dbl|320|1|mono
-audio|1|67200|4.200000|67200|4.200000|320|0.020000|6974|dbl|320|1|mono
-audio|1|67520|4.220000|67520|4.220000|320|0.020000|7007|dbl|320|1|mono
-audio|1|67840|4.240000|67840|4.240000|320|0.020000|7040|dbl|320|1|mono
-audio|1|68160|4.260000|68160|4.260000|320|0.020000|7073|dbl|320|1|mono
-audio|1|68480|4.280000|68480|4.280000|320|0.020000|7106|dbl|320|1|mono
-audio|1|68800|4.300000|68800|4.300000|320|0.020000|7139|dbl|320|1|mono
-audio|1|69120|4.320000|69120|4.320000|320|0.020000|7172|dbl|320|1|mono
-audio|1|69440|4.340000|69440|4.340000|320|0.020000|7205|dbl|320|1|mono
-audio|1|69760|4.360000|69760|4.360000|320|0.020000|7238|dbl|320|1|mono
-audio|1|70080|4.380000|70080|4.380000|320|0.020000|7271|dbl|320|1|mono
-audio|1|70400|4.400000|70400|4.400000|320|0.020000|7304|dbl|320|1|mono
-audio|1|70720|4.420000|70720|4.420000|320|0.020000|7337|dbl|320|1|mono
-audio|1|71040|4.440000|71040|4.440000|320|0.020000|7370|dbl|320|1|mono
-audio|1|71360|4.460000|71360|4.460000|320|0.020000|7403|dbl|320|1|mono
-audio|1|71680|4.480000|71680|4.480000|320|0.020000|7436|dbl|320|1|mono
-audio|1|72000|4.500000|72000|4.500000|320|0.020000|7469|dbl|320|1|mono
-audio|1|72320|4.520000|72320|4.520000|320|0.020000|7502|dbl|320|1|mono
-audio|1|72640|4.540000|72640|4.540000|320|0.020000|7535|dbl|320|1|mono
-audio|1|72960|4.560000|72960|4.560000|320|0.020000|7568|dbl|320|1|mono
-audio|1|73280|4.580000|73280|4.580000|320|0.020000|7601|dbl|320|1|mono
-audio|1|73600|4.600000|73600|4.600000|320|0.020000|7634|dbl|320|1|mono
-audio|1|73920|4.620000|73920|4.620000|320|0.020000|7667|dbl|320|1|mono
-audio|1|74240|4.640000|74240|4.640000|320|0.020000|7700|dbl|320|1|mono
-audio|1|74560|4.660000|74560|4.660000|320|0.020000|7733|dbl|320|1|mono
-audio|1|74880|4.680000|74880|4.680000|320|0.020000|7766|dbl|320|1|mono
-audio|1|75200|4.700000|75200|4.700000|320|0.020000|7799|dbl|320|1|mono
-audio|1|75520|4.720000|75520|4.720000|320|0.020000|7832|dbl|320|1|mono
-audio|1|75840|4.740000|75840|4.740000|320|0.020000|7865|dbl|320|1|mono
-audio|1|76160|4.760000|76160|4.760000|320|0.020000|7898|dbl|320|1|mono
-audio|1|76480|4.780000|76480|4.780000|320|0.020000|7931|dbl|320|1|mono
-audio|1|76800|4.800000|76800|4.800000|320|0.020000|7964|dbl|320|1|mono
-audio|1|77120|4.820000|77120|4.820000|320|0.020000|7997|dbl|320|1|mono
-audio|1|77440|4.840000|77440|4.840000|320|0.020000|8030|dbl|320|1|mono
-audio|1|77760|4.860000|77760|4.860000|320|0.020000|8063|dbl|320|1|mono
-audio|1|78080|4.880000|78080|4.880000|320|0.020000|8096|dbl|320|1|mono
-audio|1|78400|4.900000|78400|4.900000|320|0.020000|8129|dbl|320|1|mono
-audio|1|78720|4.920000|78720|4.920000|320|0.020000|8162|dbl|320|1|mono
-audio|1|79040|4.940000|79040|4.940000|320|0.020000|8195|dbl|320|1|mono
-audio|1|79360|4.960000|79360|4.960000|320|0.020000|8228|dbl|320|1|mono
-audio|1|79680|4.980000|79680|4.980000|320|0.020000|8261|dbl|320|1|mono
-audio|1|80000|5.000000|80000|5.000000|324|0.020250|8294|dbl|320|1|mono|4.9
-audio|1|80320|5.020000|80320|5.020000|320|0.020000|8327|dbl|320|1|mono
-audio|1|80640|5.040000|80640|5.040000|320|0.020000|8360|dbl|320|1|mono
-audio|1|80960|5.060000|80960|5.060000|320|0.020000|8393|dbl|320|1|mono
-audio|1|81280|5.080000|81280|5.080000|320|0.020000|8426|dbl|320|1|mono
-audio|1|81600|5.100000|81600|5.100000|320|0.020000|8459|dbl|320|1|mono
-audio|1|81920|5.120000|81920|5.120000|320|0.020000|8492|dbl|320|1|mono
-audio|1|82240|5.140000|82240|5.140000|320|0.020000|8525|dbl|320|1|mono
-audio|1|82560|5.160000|82560|5.160000|320|0.020000|8558|dbl|320|1|mono
-audio|1|82880|5.180000|82880|5.180000|320|0.020000|8591|dbl|320|1|mono
-audio|1|83200|5.200000|83200|5.200000|320|0.020000|8624|dbl|320|1|mono
-audio|1|83520|5.220000|83520|5.220000|320|0.020000|8657|dbl|320|1|mono
-audio|1|83840|5.240000|83840|5.240000|320|0.020000|8690|dbl|320|1|mono
-audio|1|84160|5.260000|84160|5.260000|320|0.020000|8723|dbl|320|1|mono
-audio|1|84480|5.280000|84480|5.280000|320|0.020000|8756|dbl|320|1|mono
-audio|1|84800|5.300000|84800|5.300000|320|0.020000|8789|dbl|320|1|mono
-audio|1|85120|5.320000|85120|5.320000|320|0.020000|8822|dbl|320|1|mono
-audio|1|85440|5.340000|85440|5.340000|320|0.020000|8855|dbl|320|1|mono
-audio|1|85760|5.360000|85760|5.360000|320|0.020000|8888|dbl|320|1|mono
-audio|1|86080|5.380000|86080|5.380000|320|0.020000|8921|dbl|320|1|mono
-audio|1|86400|5.400000|86400|5.400000|320|0.020000|8954|dbl|320|1|mono
-audio|1|86720|5.420000|86720|5.420000|320|0.020000|8987|dbl|320|1|mono
-audio|1|87040|5.440000|87040|5.440000|328|0.020500|9020|dbl|320|1|mono|5.44|0.54
-audio|1|87360|5.460000|87360|5.460000|320|0.020000|9053|dbl|320|1|mono
-audio|1|87680|5.480000|87680|5.480000|320|0.020000|9086|dbl|320|1|mono
-audio|1|88000|5.500000|88000|5.500000|320|0.020000|9119|dbl|320|1|mono
-audio|1|88320|5.520000|88320|5.520000|320|0.020000|9152|dbl|320|1|mono
-audio|1|88640|5.540000|88640|5.540000|320|0.020000|9185|dbl|320|1|mono
-audio|1|88960|5.560000|88960|5.560000|320|0.020000|9218|dbl|320|1|mono
-audio|1|89280|5.580000|89280|5.580000|320|0.020000|9251|dbl|320|1|mono
-audio|1|89600|5.600000|89600|5.600000|320|0.020000|9284|dbl|320|1|mono
-audio|1|89920|5.620000|89920|5.620000|320|0.020000|9317|dbl|320|1|mono
-audio|1|90240|5.640000|90240|5.640000|320|0.020000|9350|dbl|320|1|mono
-audio|1|90560|5.660000|90560|5.660000|320|0.020000|9383|dbl|320|1|mono
-audio|1|90880|5.680000|90880|5.680000|320|0.020000|9416|dbl|320|1|mono
-audio|1|91200|5.700000|91200|5.700000|320|0.020000|9449|dbl|320|1|mono
-audio|1|91520|5.720000|91520|5.720000|320|0.020000|9482|dbl|320|1|mono
-audio|1|91840|5.740000|91840|5.740000|320|0.020000|9515|dbl|320|1|mono
-audio|1|92160|5.760000|92160|5.760000|320|0.020000|9548|dbl|320|1|mono
-audio|1|92480|5.780000|92480|5.780000|320|0.020000|9581|dbl|320|1|mono
-audio|1|92800|5.800000|92800|5.800000|320|0.020000|9614|dbl|320|1|mono
-audio|1|93120|5.820000|93120|5.820000|320|0.020000|9647|dbl|320|1|mono
-audio|1|93440|5.840000|93440|5.840000|320|0.020000|9680|dbl|320|1|mono
-audio|1|93760|5.860000|93760|5.860000|320|0.020000|9713|dbl|320|1|mono
-audio|1|94080|5.880000|94080|5.880000|320|0.020000|9746|dbl|320|1|mono
-audio|1|94400|5.900000|94400|5.900000|320|0.020000|9779|dbl|320|1|mono
-audio|1|94720|5.920000|94720|5.920000|320|0.020000|9812|dbl|320|1|mono
-audio|1|95040|5.940000|95040|5.940000|320|0.020000|9845|dbl|320|1|mono
-audio|1|95360|5.960000|95360|5.960000|320|0.020000|9878|dbl|320|1|mono
-audio|1|95680|5.980000|95680|5.980000|320|0.020000|9911|dbl|320|1|mono
-audio|1|96000|6.000000|96000|6.000000|320|0.020000|9944|dbl|320|1|mono
-audio|1|96320|6.020000|96320|6.020000|320|0.020000|9977|dbl|320|1|mono
-audio|1|96640|6.040000|96640|6.040000|320|0.020000|10010|dbl|320|1|mono
-audio|1|96960|6.060000|96960|6.060000|320|0.020000|10043|dbl|320|1|mono
-audio|1|97280|6.080000|97280|6.080000|320|0.020000|10076|dbl|320|1|mono
-audio|1|97600|6.100000|97600|6.100000|320|0.020000|10109|dbl|320|1|mono
-audio|1|97920|6.120000|97920|6.120000|320|0.020000|10142|dbl|320|1|mono
-audio|1|98240|6.140000|98240|6.140000|320|0.020000|10175|dbl|320|1|mono
-audio|1|98560|6.160000|98560|6.160000|320|0.020000|10208|dbl|320|1|mono
-audio|1|98880|6.180000|98880|6.180000|320|0.020000|10241|dbl|320|1|mono
-audio|1|99200|6.200000|99200|6.200000|320|0.020000|10274|dbl|320|1|mono
-audio|1|99520|6.220000|99520|6.220000|320|0.020000|10307|dbl|320|1|mono
-audio|1|99840|6.240000|99840|6.240000|320|0.020000|10340|dbl|320|1|mono
-audio|1|100160|6.260000|100160|6.260000|320|0.020000|10373|dbl|320|1|mono
-audio|1|100480|6.280000|100480|6.280000|320|0.020000|10406|dbl|320|1|mono
-audio|1|100800|6.300000|100800|6.300000|320|0.020000|10439|dbl|320|1|mono
-audio|1|101120|6.320000|101120|6.320000|320|0.020000|10472|dbl|320|1|mono
-audio|1|101440|6.340000|101440|6.340000|320|0.020000|10505|dbl|320|1|mono
-audio|1|101760|6.360000|101760|6.360000|320|0.020000|10538|dbl|320|1|mono
-audio|1|102080|6.380000|102080|6.380000|320|0.020000|10571|dbl|320|1|mono
-audio|1|102400|6.400000|102400|6.400000|320|0.020000|10604|dbl|320|1|mono
-audio|1|102720|6.420000|102720|6.420000|320|0.020000|10637|dbl|320|1|mono
-audio|1|103040|6.440000|103040|6.440000|320|0.020000|10670|dbl|320|1|mono
-audio|1|103360|6.460000|103360|6.460000|320|0.020000|10703|dbl|320|1|mono
-audio|1|103680|6.480000|103680|6.480000|320|0.020000|10736|dbl|320|1|mono
-audio|1|104000|6.500000|104000|6.500000|320|0.020000|10769|dbl|320|1|mono
-audio|1|104320|6.520000|104320|6.520000|320|0.020000|10802|dbl|320|1|mono
-audio|1|104640|6.540000|104640|6.540000|324|0.020250|10835|dbl|320|1|mono|6.44
-audio|1|104960|6.560000|104960|6.560000|320|0.020000|10868|dbl|320|1|mono
-audio|1|105280|6.580000|105280|6.580000|320|0.020000|10901|dbl|320|1|mono
-audio|1|105600|6.600000|105600|6.600000|320|0.020000|10934|dbl|320|1|mono
-audio|1|105920|6.620000|105920|6.620000|320|0.020000|10967|dbl|320|1|mono
-audio|1|106240|6.640000|106240|6.640000|320|0.020000|11000|dbl|320|1|mono
-audio|1|106560|6.660000|106560|6.660000|320|0.020000|11033|dbl|320|1|mono
-audio|1|106880|6.680000|106880|6.680000|320|0.020000|11066|dbl|320|1|mono
-audio|1|107200|6.700000|107200|6.700000|320|0.020000|11099|dbl|320|1|mono
-audio|1|107520|6.720000|107520|6.720000|320|0.020000|11132|dbl|320|1|mono
-audio|1|107840|6.740000|107840|6.740000|320|0.020000|11165|dbl|320|1|mono
-audio|1|108160|6.760000|108160|6.760000|320|0.020000|11198|dbl|320|1|mono
-audio|1|108480|6.780000|108480|6.780000|320|0.020000|11231|dbl|320|1|mono
-audio|1|108800|6.800000|108800|6.800000|320|0.020000|11264|dbl|320|1|mono
-audio|1|109120|6.820000|109120|6.820000|320|0.020000|11297|dbl|320|1|mono
-audio|1|109440|6.840000|109440|6.840000|320|0.020000|11330|dbl|320|1|mono
-audio|1|109760|6.860000|109760|6.860000|320|0.020000|11363|dbl|320|1|mono
-audio|1|110080|6.880000|110080|6.880000|320|0.020000|11396|dbl|320|1|mono
-audio|1|110400|6.900000|110400|6.900000|320|0.020000|11429|dbl|320|1|mono
-audio|1|110720|6.920000|110720|6.920000|320|0.020000|11462|dbl|320|1|mono
-audio|1|111040|6.940000|111040|6.940000|320|0.020000|11495|dbl|320|1|mono
-audio|1|111360|6.960000|111360|6.960000|320|0.020000|11528|dbl|320|1|mono
-audio|1|111680|6.980000|111680|6.980000|320|0.020000|11561|dbl|320|1|mono
-audio|1|112000|7.000000|112000|7.000000|320|0.020000|11594|dbl|320|1|mono
-audio|1|112320|7.020000|112320|7.020000|320|0.020000|11627|dbl|320|1|mono
-audio|1|112640|7.040000|112640|7.040000|320|0.020000|11660|dbl|320|1|mono
-audio|1|112960|7.060000|112960|7.060000|320|0.020000|11693|dbl|320|1|mono
-audio|1|113280|7.080000|113280|7.080000|320|0.020000|11726|dbl|320|1|mono
-audio|1|113600|7.100000|113600|7.100000|320|0.020000|11759|dbl|320|1|mono
-audio|1|113920|7.120000|113920|7.120000|320|0.020000|11792|dbl|320|1|mono
-audio|1|114240|7.140000|114240|7.140000|320|0.020000|11825|dbl|320|1|mono
-audio|1|114560|7.160000|114560|7.160000|320|0.020000|11858|dbl|320|1|mono
-audio|1|114880|7.180000|114880|7.180000|320|0.020000|11891|dbl|320|1|mono
-audio|1|115200|7.200000|115200|7.200000|320|0.020000|11924|dbl|320|1|mono
-audio|1|115520|7.220000|115520|7.220000|320|0.020000|11957|dbl|320|1|mono
-audio|1|115840|7.240000|115840|7.240000|320|0.020000|11990|dbl|320|1|mono
-audio|1|116160|7.260000|116160|7.260000|328|0.020500|12023|dbl|320|1|mono|7.26|0.82
-audio|1|116480|7.280000|116480|7.280000|320|0.020000|12056|dbl|320|1|mono
-audio|1|116800|7.300000|116800|7.300000|320|0.020000|12089|dbl|320|1|mono
-audio|1|117120|7.320000|117120|7.320000|320|0.020000|12122|dbl|320|1|mono
-audio|1|117440|7.340000|117440|7.340000|320|0.020000|12155|dbl|320|1|mono
-audio|1|117760|7.360000|117760|7.360000|320|0.020000|12188|dbl|320|1|mono
-audio|1|118080|7.380000|118080|7.380000|320|0.020000|12221|dbl|320|1|mono
-audio|1|118400|7.400000|118400|7.400000|320|0.020000|12254|dbl|320|1|mono
-audio|1|118720|7.420000|118720|7.420000|320|0.020000|12287|dbl|320|1|mono
-audio|1|119040|7.440000|119040|7.440000|320|0.020000|12320|dbl|320|1|mono
-audio|1|119360|7.460000|119360|7.460000|320|0.020000|12353|dbl|320|1|mono
-audio|1|119680|7.480000|119680|7.480000|320|0.020000|12386|dbl|320|1|mono
-audio|1|120000|7.500000|120000|7.500000|320|0.020000|12419|dbl|320|1|mono
-audio|1|120320|7.520000|120320|7.520000|320|0.020000|12452|dbl|320|1|mono
-audio|1|120640|7.540000|120640|7.540000|320|0.020000|12485|dbl|320|1|mono
-audio|1|120960|7.560000|120960|7.560000|320|0.020000|12518|dbl|320|1|mono
-audio|1|121280|7.580000|121280|7.580000|320|0.020000|12551|dbl|320|1|mono
-audio|1|121600|7.600000|121600|7.600000|320|0.020000|12584|dbl|320|1|mono
-audio|1|121920|7.620000|121920|7.620000|320|0.020000|12617|dbl|320|1|mono
-audio|1|122240|7.640000|122240|7.640000|320|0.020000|12650|dbl|320|1|mono
-audio|1|122560|7.660000|122560|7.660000|320|0.020000|12683|dbl|320|1|mono
-audio|1|122880|7.680000|122880|7.680000|320|0.020000|12716|dbl|320|1|mono
-audio|1|123200|7.700000|123200|7.700000|320|0.020000|12749|dbl|320|1|mono
-audio|1|123520|7.720000|123520|7.720000|320|0.020000|12782|dbl|320|1|mono
-audio|1|123840|7.740000|123840|7.740000|320|0.020000|12815|dbl|320|1|mono
-audio|1|124160|7.760000|124160|7.760000|320|0.020000|12848|dbl|320|1|mono
-audio|1|124480|7.780000|124480|7.780000|320|0.020000|12881|dbl|320|1|mono
-audio|1|124800|7.800000|124800|7.800000|320|0.020000|12914|dbl|320|1|mono
-audio|1|125120|7.820000|125120|7.820000|320|0.020000|12947|dbl|320|1|mono
-audio|1|125440|7.840000|125440|7.840000|320|0.020000|12980|dbl|320|1|mono
-audio|1|125760|7.860000|125760|7.860000|320|0.020000|13013|dbl|320|1|mono
-audio|1|126080|7.880000|126080|7.880000|320|0.020000|13046|dbl|320|1|mono
-audio|1|126400|7.900000|126400|7.900000|320|0.020000|13079|dbl|320|1|mono
-audio|1|126720|7.920000|126720|7.920000|320|0.020000|13112|dbl|320|1|mono
-audio|1|127040|7.940000|127040|7.940000|320|0.020000|13145|dbl|320|1|mono
-audio|1|127360|7.960000|127360|7.960000|320|0.020000|13178|dbl|320|1|mono
-audio|1|127680|7.980000|127680|7.980000|320|0.020000|13211|dbl|320|1|mono
-audio|1|128000|8.000000|128000|8.000000|320|0.020000|13244|dbl|320|1|mono
-audio|1|128320|8.020000|128320|8.020000|320|0.020000|13277|dbl|320|1|mono
-audio|1|128640|8.040000|128640|8.040000|320|0.020000|13310|dbl|320|1|mono
-audio|1|128960|8.060000|128960|8.060000|320|0.020000|13343|dbl|320|1|mono
-audio|1|129280|8.080000|129280|8.080000|320|0.020000|13376|dbl|320|1|mono
-audio|1|129600|8.100000|129600|8.100000|320|0.020000|13409|dbl|320|1|mono
-audio|1|129920|8.120000|129920|8.120000|320|0.020000|13442|dbl|320|1|mono
-audio|1|130240|8.140000|130240|8.140000|320|0.020000|13475|dbl|320|1|mono
-audio|1|130560|8.160000|130560|8.160000|320|0.020000|13508|dbl|320|1|mono
-audio|1|130880|8.180000|130880|8.180000|320|0.020000|13541|dbl|320|1|mono
-audio|1|131200|8.200000|131200|8.200000|320|0.020000|13574|dbl|320|1|mono
-audio|1|131520|8.220000|131520|8.220000|320|0.020000|13607|dbl|320|1|mono
-audio|1|131840|8.240000|131840|8.240000|320|0.020000|13640|dbl|320|1|mono
-audio|1|132160|8.260000|132160|8.260000|320|0.020000|13673|dbl|320|1|mono
-audio|1|132480|8.280000|132480|8.280000|320|0.020000|13706|dbl|320|1|mono
-audio|1|132800|8.300000|132800|8.300000|320|0.020000|13739|dbl|320|1|mono
-audio|1|133120|8.320000|133120|8.320000|320|0.020000|13772|dbl|320|1|mono
-audio|1|133440|8.340000|133440|8.340000|320|0.020000|13805|dbl|320|1|mono
-audio|1|133760|8.360000|133760|8.360000|320|0.020000|13838|dbl|320|1|mono
-audio|1|134080|8.380000|134080|8.380000|320|0.020000|13871|dbl|320|1|mono
-audio|1|134400|8.400000|134400|8.400000|320|0.020000|13904|dbl|320|1|mono
-audio|1|134720|8.420000|134720|8.420000|320|0.020000|13937|dbl|320|1|mono
-audio|1|135040|8.440000|135040|8.440000|320|0.020000|13970|dbl|320|1|mono
-audio|1|135360|8.460000|135360|8.460000|320|0.020000|14003|dbl|320|1|mono
-audio|1|135680|8.480000|135680|8.480000|320|0.020000|14036|dbl|320|1|mono
-audio|1|136000|8.500000|136000|8.500000|320|0.020000|14069|dbl|320|1|mono
-audio|1|136320|8.520000|136320|8.520000|320|0.020000|14102|dbl|320|1|mono
-audio|1|136640|8.540000|136640|8.540000|320|0.020000|14135|dbl|320|1|mono
-audio|1|136960|8.560000|136960|8.560000|320|0.020000|14168|dbl|320|1|mono
-audio|1|137280|8.580000|137280|8.580000|320|0.020000|14201|dbl|320|1|mono
-audio|1|137600|8.600000|137600|8.600000|324|0.020250|14234|dbl|320|1|mono|8.5
-audio|1|137920|8.620000|137920|8.620000|320|0.020000|14267|dbl|320|1|mono
-audio|1|138240|8.640000|138240|8.640000|320|0.020000|14300|dbl|320|1|mono
-audio|1|138560|8.660000|138560|8.660000|320|0.020000|14333|dbl|320|1|mono
-audio|1|138880|8.680000|138880|8.680000|328|0.020500|14366|dbl|320|1|mono|8.68|0.18
-audio|1|139200|8.700000|139200|8.700000|320|0.020000|14399|dbl|320|1|mono
-audio|1|139520|8.720000|139520|8.720000|320|0.020000|14432|dbl|320|1|mono
-audio|1|139840|8.740000|139840|8.740000|320|0.020000|14465|dbl|320|1|mono
-audio|1|140160|8.760000|140160|8.760000|320|0.020000|14498|dbl|320|1|mono
-audio|1|140480|8.780000|140480|8.780000|324|0.020250|14531|dbl|320|1|mono|8.68
-audio|1|140800|8.800000|140800|8.800000|320|0.020000|14564|dbl|320|1|mono
-audio|1|141120|8.820000|141120|8.820000|320|0.020000|14597|dbl|320|1|mono
-audio|1|141440|8.840000|141440|8.840000|320|0.020000|14630|dbl|320|1|mono
-audio|1|141760|8.860000|141760|8.860000|320|0.020000|14663|dbl|320|1|mono
-audio|1|142080|8.880000|142080|8.880000|320|0.020000|14696|dbl|320|1|mono
-audio|1|142400|8.900000|142400|8.900000|320|0.020000|14729|dbl|320|1|mono
-audio|1|142720|8.920000|142720|8.920000|320|0.020000|14762|dbl|320|1|mono
-audio|1|143040|8.940000|143040|8.940000|320|0.020000|14795|dbl|320|1|mono
-audio|1|143360|8.960000|143360|8.960000|320|0.020000|14828|dbl|320|1|mono
-audio|1|143680|8.980000|143680|8.980000|327|0.020438|14861|dbl|320|1|mono|8.98|0.3
-audio|1|144000|9.000000|144000|9.000000|320|0.020000|14894|dbl|320|1|mono
-audio|1|144320|9.020000|144320|9.020000|320|0.020000|14927|dbl|320|1|mono
-audio|1|144640|9.040000|144640|9.040000|320|0.020000|14960|dbl|320|1|mono
-audio|1|144960|9.060000|144960|9.060000|320|0.020000|14993|dbl|320|1|mono
-audio|1|145280|9.080000|145280|9.080000|320|0.020000|15026|dbl|320|1|mono
-audio|1|145600|9.100000|145600|9.100000|320|0.020000|15059|dbl|320|1|mono
-audio|1|145920|9.120000|145920|9.120000|320|0.020000|15092|dbl|320|1|mono
-audio|1|146240|9.140000|146240|9.140000|320|0.020000|15125|dbl|320|1|mono
-audio|1|146560|9.160000|146560|9.160000|320|0.020000|15158|dbl|320|1|mono
-audio|1|146880|9.180000|146880|9.180000|320|0.020000|15191|dbl|320|1|mono
-audio|1|147200|9.200000|147200|9.200000|320|0.020000|15224|dbl|320|1|mono
-audio|1|147520|9.220000|147520|9.220000|320|0.020000|15257|dbl|320|1|mono
-audio|1|147840|9.240000|147840|9.240000|320|0.020000|15290|dbl|320|1|mono
-audio|1|148160|9.260000|148160|9.260000|320|0.020000|15323|dbl|320|1|mono
-audio|1|148480|9.280000|148480|9.280000|320|0.020000|15356|dbl|320|1|mono
-audio|1|148800|9.300000|148800|9.300000|320|0.020000|15389|dbl|320|1|mono
-audio|1|149120|9.320000|149120|9.320000|320|0.020000|15422|dbl|320|1|mono
-audio|1|149440|9.340000|149440|9.340000|320|0.020000|15455|dbl|320|1|mono
-audio|1|149760|9.360000|149760|9.360000|320|0.020000|15488|dbl|320|1|mono
-audio|1|150080|9.380000|150080|9.380000|320|0.020000|15521|dbl|320|1|mono
-audio|1|150400|9.400000|150400|9.400000|320|0.020000|15554|dbl|320|1|mono
-audio|1|150720|9.420000|150720|9.420000|320|0.020000|15587|dbl|320|1|mono
-audio|1|151040|9.440000|151040|9.440000|320|0.020000|15620|dbl|320|1|mono
-audio|1|151360|9.460000|151360|9.460000|320|0.020000|15653|dbl|320|1|mono
-audio|1|151680|9.480000|151680|9.480000|320|0.020000|15686|dbl|320|1|mono
-audio|1|152000|9.500000|152000|9.500000|320|0.020000|15719|dbl|320|1|mono
-audio|1|152320|9.520000|152320|9.520000|320|0.020000|15752|dbl|320|1|mono
-audio|1|152640|9.540000|152640|9.540000|320|0.020000|15785|dbl|320|1|mono
-audio|1|152960|9.560000|152960|9.560000|320|0.020000|15818|dbl|320|1|mono
-audio|1|153280|9.580000|153280|9.580000|320|0.020000|15851|dbl|320|1|mono
-audio|1|153600|9.600000|153600|9.600000|320|0.020000|15884|dbl|320|1|mono
-audio|1|153920|9.620000|153920|9.620000|320|0.020000|15917|dbl|320|1|mono
-audio|1|154240|9.640000|154240|9.640000|320|0.020000|15950|dbl|320|1|mono
-audio|1|154560|9.660000|154560|9.660000|320|0.020000|15983|dbl|320|1|mono
-audio|1|154880|9.680000|154880|9.680000|320|0.020000|16016|dbl|320|1|mono
-audio|1|155200|9.700000|155200|9.700000|320|0.020000|16049|dbl|320|1|mono
-audio|1|155520|9.720000|155520|9.720000|320|0.020000|16082|dbl|320|1|mono
-audio|1|155840|9.740000|155840|9.740000|320|0.020000|16115|dbl|320|1|mono
-audio|1|156160|9.760000|156160|9.760000|320|0.020000|16148|dbl|320|1|mono
-audio|1|156480|9.780000|156480|9.780000|320|0.020000|16181|dbl|320|1|mono
-audio|1|156800|9.800000|156800|9.800000|320|0.020000|16214|dbl|320|1|mono
-audio|1|157120|9.820000|157120|9.820000|320|0.020000|16247|dbl|320|1|mono
-audio|1|157440|9.840000|157440|9.840000|320|0.020000|16280|dbl|320|1|mono
-audio|1|157760|9.860000|157760|9.860000|320|0.020000|16313|dbl|320|1|mono
-audio|1|158080|9.880000|158080|9.880000|320|0.020000|16346|dbl|320|1|mono
-audio|1|158400|9.900000|158400|9.900000|320|0.020000|16379|dbl|320|1|mono
-audio|1|158720|9.920000|158720|9.920000|320|0.020000|16412|dbl|320|1|mono
-audio|1|159040|9.940000|159040|9.940000|320|0.020000|16445|dbl|320|1|mono
-audio|1|159360|9.960000|159360|9.960000|320|0.020000|16478|dbl|320|1|mono
-audio|1|159680|9.980000|159680|9.980000|320|0.020000|16511|dbl|320|1|mono
-audio|1|160000|10.000000|160000|10.000000|320|0.020000|16544|dbl|320|1|mono
-audio|1|160320|10.020000|160320|10.020000|320|0.020000|16577|dbl|320|1|mono
-audio|1|160640|10.040000|160640|10.040000|320|0.020000|16610|dbl|320|1|mono
-audio|1|160960|10.060000|160960|10.060000|320|0.020000|16643|dbl|320|1|mono
-audio|1|161280|10.080000|161280|10.080000|320|0.020000|16676|dbl|320|1|mono
-audio|1|161600|10.100000|161600|10.100000|324|0.020250|16709|dbl|320|1|mono|10
-audio|1|161920|10.120000|161920|10.120000|320|0.020000|16742|dbl|320|1|mono
-audio|1|162240|10.140000|162240|10.140000|320|0.020000|16775|dbl|320|1|mono
-audio|1|162560|10.160000|162560|10.160000|320|0.020000|16808|dbl|320|1|mono
-audio|1|162880|10.180000|162880|10.180000|320|0.020000|16841|dbl|320|1|mono
-audio|1|163200|10.200000|163200|10.200000|320|0.020000|16874|dbl|320|1|mono
-audio|1|163520|10.220000|163520|10.220000|320|0.020000|16907|dbl|320|1|mono
+audio|1|0|0.000000|0|0.000000|320|0.020000|44|2560|dbl|320|1|mono
+audio|1|320|0.020000|320|0.020000|320|0.020000|77|2560|dbl|320|1|mono
+audio|1|640|0.040000|640|0.040000|320|0.020000|110|2560|dbl|320|1|mono
+audio|1|960|0.060000|960|0.060000|320|0.020000|143|2560|dbl|320|1|mono
+audio|1|1280|0.080000|1280|0.080000|320|0.020000|176|2560|dbl|320|1|mono
+audio|1|1600|0.100000|1600|0.100000|320|0.020000|209|2560|dbl|320|1|mono
+audio|1|1920|0.120000|1920|0.120000|324|0.020250|242|2560|dbl|320|1|mono|0.02
+audio|1|2240|0.140000|2240|0.140000|320|0.020000|275|2560|dbl|320|1|mono
+audio|1|2560|0.160000|2560|0.160000|328|0.020500|308|2560|dbl|320|1|mono|0.16|0.14
+audio|1|2880|0.180000|2880|0.180000|320|0.020000|341|2560|dbl|320|1|mono
+audio|1|3200|0.200000|3200|0.200000|320|0.020000|374|2560|dbl|320|1|mono
+audio|1|3520|0.220000|3520|0.220000|320|0.020000|407|2560|dbl|320|1|mono
+audio|1|3840|0.240000|3840|0.240000|320|0.020000|440|2560|dbl|320|1|mono
+audio|1|4160|0.260000|4160|0.260000|320|0.020000|473|2560|dbl|320|1|mono
+audio|1|4480|0.280000|4480|0.280000|320|0.020000|506|2560|dbl|320|1|mono
+audio|1|4800|0.300000|4800|0.300000|320|0.020000|539|2560|dbl|320|1|mono
+audio|1|5120|0.320000|5120|0.320000|320|0.020000|572|2560|dbl|320|1|mono
+audio|1|5440|0.340000|5440|0.340000|320|0.020000|605|2560|dbl|320|1|mono
+audio|1|5760|0.360000|5760|0.360000|331|0.020688|638|2560|dbl|320|1|mono|0.26|0.36|0.1
+audio|1|6080|0.380000|6080|0.380000|320|0.020000|671|2560|dbl|320|1|mono
+audio|1|6400|0.400000|6400|0.400000|320|0.020000|704|2560|dbl|320|1|mono
+audio|1|6720|0.420000|6720|0.420000|320|0.020000|737|2560|dbl|320|1|mono
+audio|1|7040|0.440000|7040|0.440000|320|0.020000|770|2560|dbl|320|1|mono
+audio|1|7360|0.460000|7360|0.460000|320|0.020000|803|2560|dbl|320|1|mono
+audio|1|7680|0.480000|7680|0.480000|320|0.020000|836|2560|dbl|320|1|mono
+audio|1|8000|0.500000|8000|0.500000|320|0.020000|869|2560|dbl|320|1|mono
+audio|1|8320|0.520000|8320|0.520000|320|0.020000|902|2560|dbl|320|1|mono
+audio|1|8640|0.540000|8640|0.540000|320|0.020000|935|2560|dbl|320|1|mono
+audio|1|8960|0.560000|8960|0.560000|320|0.020000|968|2560|dbl|320|1|mono
+audio|1|9280|0.580000|9280|0.580000|320|0.020000|1001|2560|dbl|320|1|mono
+audio|1|9600|0.600000|9600|0.600000|320|0.020000|1034|2560|dbl|320|1|mono
+audio|1|9920|0.620000|9920|0.620000|320|0.020000|1067|2560|dbl|320|1|mono
+audio|1|10240|0.640000|10240|0.640000|320|0.020000|1100|2560|dbl|320|1|mono
+audio|1|10560|0.660000|10560|0.660000|320|0.020000|1133|2560|dbl|320|1|mono
+audio|1|10880|0.680000|10880|0.680000|320|0.020000|1166|2560|dbl|320|1|mono
+audio|1|11200|0.700000|11200|0.700000|320|0.020000|1199|2560|dbl|320|1|mono
+audio|1|11520|0.720000|11520|0.720000|320|0.020000|1232|2560|dbl|320|1|mono
+audio|1|11840|0.740000|11840|0.740000|320|0.020000|1265|2560|dbl|320|1|mono
+audio|1|12160|0.760000|12160|0.760000|320|0.020000|1298|2560|dbl|320|1|mono
+audio|1|12480|0.780000|12480|0.780000|320|0.020000|1331|2560|dbl|320|1|mono
+audio|1|12800|0.800000|12800|0.800000|320|0.020000|1364|2560|dbl|320|1|mono
+audio|1|13120|0.820000|13120|0.820000|320|0.020000|1397|2560|dbl|320|1|mono
+audio|1|13440|0.840000|13440|0.840000|320|0.020000|1430|2560|dbl|320|1|mono
+audio|1|13760|0.860000|13760|0.860000|320|0.020000|1463|2560|dbl|320|1|mono
+audio|1|14080|0.880000|14080|0.880000|320|0.020000|1496|2560|dbl|320|1|mono
+audio|1|14400|0.900000|14400|0.900000|320|0.020000|1529|2560|dbl|320|1|mono
+audio|1|14720|0.920000|14720|0.920000|320|0.020000|1562|2560|dbl|320|1|mono
+audio|1|15040|0.940000|15040|0.940000|320|0.020000|1595|2560|dbl|320|1|mono
+audio|1|15360|0.960000|15360|0.960000|320|0.020000|1628|2560|dbl|320|1|mono
+audio|1|15680|0.980000|15680|0.980000|320|0.020000|1661|2560|dbl|320|1|mono
+audio|1|16000|1.000000|16000|1.000000|320|0.020000|1694|2560|dbl|320|1|mono
+audio|1|16320|1.020000|16320|1.020000|320|0.020000|1727|2560|dbl|320|1|mono
+audio|1|16640|1.040000|16640|1.040000|320|0.020000|1760|2560|dbl|320|1|mono
+audio|1|16960|1.060000|16960|1.060000|320|0.020000|1793|2560|dbl|320|1|mono
+audio|1|17280|1.080000|17280|1.080000|320|0.020000|1826|2560|dbl|320|1|mono
+audio|1|17600|1.100000|17600|1.100000|320|0.020000|1859|2560|dbl|320|1|mono
+audio|1|17920|1.120000|17920|1.120000|320|0.020000|1892|2560|dbl|320|1|mono
+audio|1|18240|1.140000|18240|1.140000|320|0.020000|1925|2560|dbl|320|1|mono
+audio|1|18560|1.160000|18560|1.160000|320|0.020000|1958|2560|dbl|320|1|mono
+audio|1|18880|1.180000|18880|1.180000|320|0.020000|1991|2560|dbl|320|1|mono
+audio|1|19200|1.200000|19200|1.200000|320|0.020000|2024|2560|dbl|320|1|mono
+audio|1|19520|1.220000|19520|1.220000|320|0.020000|2057|2560|dbl|320|1|mono
+audio|1|19840|1.240000|19840|1.240000|320|0.020000|2090|2560|dbl|320|1|mono
+audio|1|20160|1.260000|20160|1.260000|320|0.020000|2123|2560|dbl|320|1|mono
+audio|1|20480|1.280000|20480|1.280000|320|0.020000|2156|2560|dbl|320|1|mono
+audio|1|20800|1.300000|20800|1.300000|320|0.020000|2189|2560|dbl|320|1|mono
+audio|1|21120|1.320000|21120|1.320000|320|0.020000|2222|2560|dbl|320|1|mono
+audio|1|21440|1.340000|21440|1.340000|320|0.020000|2255|2560|dbl|320|1|mono
+audio|1|21760|1.360000|21760|1.360000|320|0.020000|2288|2560|dbl|320|1|mono
+audio|1|22080|1.380000|22080|1.380000|324|0.020250|2321|2560|dbl|320|1|mono|1.28
+audio|1|22400|1.400000|22400|1.400000|320|0.020000|2354|2560|dbl|320|1|mono
+audio|1|22720|1.420000|22720|1.420000|320|0.020000|2387|2560|dbl|320|1|mono
+audio|1|23040|1.440000|23040|1.440000|320|0.020000|2420|2560|dbl|320|1|mono
+audio|1|23360|1.460000|23360|1.460000|320|0.020000|2453|2560|dbl|320|1|mono
+audio|1|23680|1.480000|23680|1.480000|320|0.020000|2486|2560|dbl|320|1|mono
+audio|1|24000|1.500000|24000|1.500000|320|0.020000|2519|2560|dbl|320|1|mono
+audio|1|24320|1.520000|24320|1.520000|320|0.020000|2552|2560|dbl|320|1|mono
+audio|1|24640|1.540000|24640|1.540000|320|0.020000|2585|2560|dbl|320|1|mono
+audio|1|24960|1.560000|24960|1.560000|320|0.020000|2618|2560|dbl|320|1|mono
+audio|1|25280|1.580000|25280|1.580000|320|0.020000|2651|2560|dbl|320|1|mono
+audio|1|25600|1.600000|25600|1.600000|320|0.020000|2684|2560|dbl|320|1|mono
+audio|1|25920|1.620000|25920|1.620000|320|0.020000|2717|2560|dbl|320|1|mono
+audio|1|26240|1.640000|26240|1.640000|320|0.020000|2750|2560|dbl|320|1|mono
+audio|1|26560|1.660000|26560|1.660000|320|0.020000|2783|2560|dbl|320|1|mono
+audio|1|26880|1.680000|26880|1.680000|320|0.020000|2816|2560|dbl|320|1|mono
+audio|1|27200|1.700000|27200|1.700000|320|0.020000|2849|2560|dbl|320|1|mono
+audio|1|27520|1.720000|27520|1.720000|320|0.020000|2882|2560|dbl|320|1|mono
+audio|1|27840|1.740000|27840|1.740000|320|0.020000|2915|2560|dbl|320|1|mono
+audio|1|28160|1.760000|28160|1.760000|320|0.020000|2948|2560|dbl|320|1|mono
+audio|1|28480|1.780000|28480|1.780000|320|0.020000|2981|2560|dbl|320|1|mono
+audio|1|28800|1.800000|28800|1.800000|320|0.020000|3014|2560|dbl|320|1|mono
+audio|1|29120|1.820000|29120|1.820000|320|0.020000|3047|2560|dbl|320|1|mono
+audio|1|29440|1.840000|29440|1.840000|320|0.020000|3080|2560|dbl|320|1|mono
+audio|1|29760|1.860000|29760|1.860000|320|0.020000|3113|2560|dbl|320|1|mono
+audio|1|30080|1.880000|30080|1.880000|320|0.020000|3146|2560|dbl|320|1|mono
+audio|1|30400|1.900000|30400|1.900000|320|0.020000|3179|2560|dbl|320|1|mono
+audio|1|30720|1.920000|30720|1.920000|320|0.020000|3212|2560|dbl|320|1|mono
+audio|1|31040|1.940000|31040|1.940000|320|0.020000|3245|2560|dbl|320|1|mono
+audio|1|31360|1.960000|31360|1.960000|320|0.020000|3278|2560|dbl|320|1|mono
+audio|1|31680|1.980000|31680|1.980000|327|0.020438|3311|2560|dbl|320|1|mono|1.98|0.7
+audio|1|32000|2.000000|32000|2.000000|320|0.020000|3344|2560|dbl|320|1|mono
+audio|1|32320|2.020000|32320|2.020000|320|0.020000|3377|2560|dbl|320|1|mono
+audio|1|32640|2.040000|32640|2.040000|320|0.020000|3410|2560|dbl|320|1|mono
+audio|1|32960|2.060000|32960|2.060000|320|0.020000|3443|2560|dbl|320|1|mono
+audio|1|33280|2.080000|33280|2.080000|320|0.020000|3476|2560|dbl|320|1|mono
+audio|1|33600|2.100000|33600|2.100000|320|0.020000|3509|2560|dbl|320|1|mono
+audio|1|33920|2.120000|33920|2.120000|320|0.020000|3542|2560|dbl|320|1|mono
+audio|1|34240|2.140000|34240|2.140000|320|0.020000|3575|2560|dbl|320|1|mono
+audio|1|34560|2.160000|34560|2.160000|320|0.020000|3608|2560|dbl|320|1|mono
+audio|1|34880|2.180000|34880|2.180000|320|0.020000|3641|2560|dbl|320|1|mono
+audio|1|35200|2.200000|35200|2.200000|320|0.020000|3674|2560|dbl|320|1|mono
+audio|1|35520|2.220000|35520|2.220000|320|0.020000|3707|2560|dbl|320|1|mono
+audio|1|35840|2.240000|35840|2.240000|320|0.020000|3740|2560|dbl|320|1|mono
+audio|1|36160|2.260000|36160|2.260000|320|0.020000|3773|2560|dbl|320|1|mono
+audio|1|36480|2.280000|36480|2.280000|320|0.020000|3806|2560|dbl|320|1|mono
+audio|1|36800|2.300000|36800|2.300000|320|0.020000|3839|2560|dbl|320|1|mono
+audio|1|37120|2.320000|37120|2.320000|320|0.020000|3872|2560|dbl|320|1|mono
+audio|1|37440|2.340000|37440|2.340000|320|0.020000|3905|2560|dbl|320|1|mono
+audio|1|37760|2.360000|37760|2.360000|320|0.020000|3938|2560|dbl|320|1|mono
+audio|1|38080|2.380000|38080|2.380000|320|0.020000|3971|2560|dbl|320|1|mono
+audio|1|38400|2.400000|38400|2.400000|320|0.020000|4004|2560|dbl|320|1|mono
+audio|1|38720|2.420000|38720|2.420000|320|0.020000|4037|2560|dbl|320|1|mono
+audio|1|39040|2.440000|39040|2.440000|320|0.020000|4070|2560|dbl|320|1|mono
+audio|1|39360|2.460000|39360|2.460000|320|0.020000|4103|2560|dbl|320|1|mono
+audio|1|39680|2.480000|39680|2.480000|320|0.020000|4136|2560|dbl|320|1|mono
+audio|1|40000|2.500000|40000|2.500000|320|0.020000|4169|2560|dbl|320|1|mono
+audio|1|40320|2.520000|40320|2.520000|320|0.020000|4202|2560|dbl|320|1|mono
+audio|1|40640|2.540000|40640|2.540000|320|0.020000|4235|2560|dbl|320|1|mono
+audio|1|40960|2.560000|40960|2.560000|320|0.020000|4268|2560|dbl|320|1|mono
+audio|1|41280|2.580000|41280|2.580000|320|0.020000|4301|2560|dbl|320|1|mono
+audio|1|41600|2.600000|41600|2.600000|320|0.020000|4334|2560|dbl|320|1|mono
+audio|1|41920|2.620000|41920|2.620000|320|0.020000|4367|2560|dbl|320|1|mono
+audio|1|42240|2.640000|42240|2.640000|320|0.020000|4400|2560|dbl|320|1|mono
+audio|1|42560|2.660000|42560|2.660000|320|0.020000|4433|2560|dbl|320|1|mono
+audio|1|42880|2.680000|42880|2.680000|320|0.020000|4466|2560|dbl|320|1|mono
+audio|1|43200|2.700000|43200|2.700000|320|0.020000|4499|2560|dbl|320|1|mono
+audio|1|43520|2.720000|43520|2.720000|320|0.020000|4532|2560|dbl|320|1|mono
+audio|1|43840|2.740000|43840|2.740000|320|0.020000|4565|2560|dbl|320|1|mono
+audio|1|44160|2.760000|44160|2.760000|320|0.020000|4598|2560|dbl|320|1|mono
+audio|1|44480|2.780000|44480|2.780000|320|0.020000|4631|2560|dbl|320|1|mono
+audio|1|44800|2.800000|44800|2.800000|320|0.020000|4664|2560|dbl|320|1|mono
+audio|1|45120|2.820000|45120|2.820000|320|0.020000|4697|2560|dbl|320|1|mono
+audio|1|45440|2.840000|45440|2.840000|320|0.020000|4730|2560|dbl|320|1|mono
+audio|1|45760|2.860000|45760|2.860000|320|0.020000|4763|2560|dbl|320|1|mono
+audio|1|46080|2.880000|46080|2.880000|320|0.020000|4796|2560|dbl|320|1|mono
+audio|1|46400|2.900000|46400|2.900000|320|0.020000|4829|2560|dbl|320|1|mono
+audio|1|46720|2.920000|46720|2.920000|320|0.020000|4862|2560|dbl|320|1|mono
+audio|1|47040|2.940000|47040|2.940000|320|0.020000|4895|2560|dbl|320|1|mono
+audio|1|47360|2.960000|47360|2.960000|320|0.020000|4928|2560|dbl|320|1|mono
+audio|1|47680|2.980000|47680|2.980000|320|0.020000|4961|2560|dbl|320|1|mono
+audio|1|48000|3.000000|48000|3.000000|320|0.020000|4994|2560|dbl|320|1|mono
+audio|1|48320|3.020000|48320|3.020000|320|0.020000|5027|2560|dbl|320|1|mono
+audio|1|48640|3.040000|48640|3.040000|320|0.020000|5060|2560|dbl|320|1|mono
+audio|1|48960|3.060000|48960|3.060000|320|0.020000|5093|2560|dbl|320|1|mono
+audio|1|49280|3.080000|49280|3.080000|320|0.020000|5126|2560|dbl|320|1|mono
+audio|1|49600|3.100000|49600|3.100000|320|0.020000|5159|2560|dbl|320|1|mono
+audio|1|49920|3.120000|49920|3.120000|320|0.020000|5192|2560|dbl|320|1|mono
+audio|1|50240|3.140000|50240|3.140000|320|0.020000|5225|2560|dbl|320|1|mono
+audio|1|50560|3.160000|50560|3.160000|320|0.020000|5258|2560|dbl|320|1|mono
+audio|1|50880|3.180000|50880|3.180000|320|0.020000|5291|2560|dbl|320|1|mono
+audio|1|51200|3.200000|51200|3.200000|320|0.020000|5324|2560|dbl|320|1|mono
+audio|1|51520|3.220000|51520|3.220000|320|0.020000|5357|2560|dbl|320|1|mono
+audio|1|51840|3.240000|51840|3.240000|320|0.020000|5390|2560|dbl|320|1|mono
+audio|1|52160|3.260000|52160|3.260000|320|0.020000|5423|2560|dbl|320|1|mono
+audio|1|52480|3.280000|52480|3.280000|320|0.020000|5456|2560|dbl|320|1|mono
+audio|1|52800|3.300000|52800|3.300000|324|0.020250|5489|2560|dbl|320|1|mono|3.2
+audio|1|53120|3.320000|53120|3.320000|320|0.020000|5522|2560|dbl|320|1|mono
+audio|1|53440|3.340000|53440|3.340000|320|0.020000|5555|2560|dbl|320|1|mono
+audio|1|53760|3.360000|53760|3.360000|320|0.020000|5588|2560|dbl|320|1|mono
+audio|1|54080|3.380000|54080|3.380000|320|0.020000|5621|2560|dbl|320|1|mono
+audio|1|54400|3.400000|54400|3.400000|320|0.020000|5654|2560|dbl|320|1|mono
+audio|1|54720|3.420000|54720|3.420000|320|0.020000|5687|2560|dbl|320|1|mono
+audio|1|55040|3.440000|55040|3.440000|320|0.020000|5720|2560|dbl|320|1|mono
+audio|1|55360|3.460000|55360|3.460000|320|0.020000|5753|2560|dbl|320|1|mono
+audio|1|55680|3.480000|55680|3.480000|320|0.020000|5786|2560|dbl|320|1|mono
+audio|1|56000|3.500000|56000|3.500000|320|0.020000|5819|2560|dbl|320|1|mono
+audio|1|56320|3.520000|56320|3.520000|320|0.020000|5852|2560|dbl|320|1|mono
+audio|1|56640|3.540000|56640|3.540000|320|0.020000|5885|2560|dbl|320|1|mono
+audio|1|56960|3.560000|56960|3.560000|320|0.020000|5918|2560|dbl|320|1|mono
+audio|1|57280|3.580000|57280|3.580000|320|0.020000|5951|2560|dbl|320|1|mono
+audio|1|57600|3.600000|57600|3.600000|320|0.020000|5984|2560|dbl|320|1|mono
+audio|1|57920|3.620000|57920|3.620000|320|0.020000|6017|2560|dbl|320|1|mono
+audio|1|58240|3.640000|58240|3.640000|320|0.020000|6050|2560|dbl|320|1|mono
+audio|1|58560|3.660000|58560|3.660000|320|0.020000|6083|2560|dbl|320|1|mono
+audio|1|58880|3.680000|58880|3.680000|320|0.020000|6116|2560|dbl|320|1|mono
+audio|1|59200|3.700000|59200|3.700000|320|0.020000|6149|2560|dbl|320|1|mono
+audio|1|59520|3.720000|59520|3.720000|320|0.020000|6182|2560|dbl|320|1|mono
+audio|1|59840|3.740000|59840|3.740000|320|0.020000|6215|2560|dbl|320|1|mono
+audio|1|60160|3.760000|60160|3.760000|320|0.020000|6248|2560|dbl|320|1|mono
+audio|1|60480|3.780000|60480|3.780000|320|0.020000|6281|2560|dbl|320|1|mono
+audio|1|60800|3.800000|60800|3.800000|320|0.020000|6314|2560|dbl|320|1|mono
+audio|1|61120|3.820000|61120|3.820000|320|0.020000|6347|2560|dbl|320|1|mono
+audio|1|61440|3.840000|61440|3.840000|320|0.020000|6380|2560|dbl|320|1|mono
+audio|1|61760|3.860000|61760|3.860000|320|0.020000|6413|2560|dbl|320|1|mono
+audio|1|62080|3.880000|62080|3.880000|320|0.020000|6446|2560|dbl|320|1|mono
+audio|1|62400|3.900000|62400|3.900000|327|0.020438|6479|2560|dbl|320|1|mono|3.9|0.7
+audio|1|62720|3.920000|62720|3.920000|320|0.020000|6512|2560|dbl|320|1|mono
+audio|1|63040|3.940000|63040|3.940000|320|0.020000|6545|2560|dbl|320|1|mono
+audio|1|63360|3.960000|63360|3.960000|320|0.020000|6578|2560|dbl|320|1|mono
+audio|1|63680|3.980000|63680|3.980000|320|0.020000|6611|2560|dbl|320|1|mono
+audio|1|64000|4.000000|64000|4.000000|320|0.020000|6644|2560|dbl|320|1|mono
+audio|1|64320|4.020000|64320|4.020000|320|0.020000|6677|2560|dbl|320|1|mono
+audio|1|64640|4.040000|64640|4.040000|320|0.020000|6710|2560|dbl|320|1|mono
+audio|1|64960|4.060000|64960|4.060000|320|0.020000|6743|2560|dbl|320|1|mono
+audio|1|65280|4.080000|65280|4.080000|320|0.020000|6776|2560|dbl|320|1|mono
+audio|1|65600|4.100000|65600|4.100000|320|0.020000|6809|2560|dbl|320|1|mono
+audio|1|65920|4.120000|65920|4.120000|320|0.020000|6842|2560|dbl|320|1|mono
+audio|1|66240|4.140000|66240|4.140000|320|0.020000|6875|2560|dbl|320|1|mono
+audio|1|66560|4.160000|66560|4.160000|320|0.020000|6908|2560|dbl|320|1|mono
+audio|1|66880|4.180000|66880|4.180000|320|0.020000|6941|2560|dbl|320|1|mono
+audio|1|67200|4.200000|67200|4.200000|320|0.020000|6974|2560|dbl|320|1|mono
+audio|1|67520|4.220000|67520|4.220000|320|0.020000|7007|2560|dbl|320|1|mono
+audio|1|67840|4.240000|67840|4.240000|320|0.020000|7040|2560|dbl|320|1|mono
+audio|1|68160|4.260000|68160|4.260000|320|0.020000|7073|2560|dbl|320|1|mono
+audio|1|68480|4.280000|68480|4.280000|320|0.020000|7106|2560|dbl|320|1|mono
+audio|1|68800|4.300000|68800|4.300000|320|0.020000|7139|2560|dbl|320|1|mono
+audio|1|69120|4.320000|69120|4.320000|320|0.020000|7172|2560|dbl|320|1|mono
+audio|1|69440|4.340000|69440|4.340000|320|0.020000|7205|2560|dbl|320|1|mono
+audio|1|69760|4.360000|69760|4.360000|320|0.020000|7238|2560|dbl|320|1|mono
+audio|1|70080|4.380000|70080|4.380000|320|0.020000|7271|2560|dbl|320|1|mono
+audio|1|70400|4.400000|70400|4.400000|320|0.020000|7304|2560|dbl|320|1|mono
+audio|1|70720|4.420000|70720|4.420000|320|0.020000|7337|2560|dbl|320|1|mono
+audio|1|71040|4.440000|71040|4.440000|320|0.020000|7370|2560|dbl|320|1|mono
+audio|1|71360|4.460000|71360|4.460000|320|0.020000|7403|2560|dbl|320|1|mono
+audio|1|71680|4.480000|71680|4.480000|320|0.020000|7436|2560|dbl|320|1|mono
+audio|1|72000|4.500000|72000|4.500000|320|0.020000|7469|2560|dbl|320|1|mono
+audio|1|72320|4.520000|72320|4.520000|320|0.020000|7502|2560|dbl|320|1|mono
+audio|1|72640|4.540000|72640|4.540000|320|0.020000|7535|2560|dbl|320|1|mono
+audio|1|72960|4.560000|72960|4.560000|320|0.020000|7568|2560|dbl|320|1|mono
+audio|1|73280|4.580000|73280|4.580000|320|0.020000|7601|2560|dbl|320|1|mono
+audio|1|73600|4.600000|73600|4.600000|320|0.020000|7634|2560|dbl|320|1|mono
+audio|1|73920|4.620000|73920|4.620000|320|0.020000|7667|2560|dbl|320|1|mono
+audio|1|74240|4.640000|74240|4.640000|320|0.020000|7700|2560|dbl|320|1|mono
+audio|1|74560|4.660000|74560|4.660000|320|0.020000|7733|2560|dbl|320|1|mono
+audio|1|74880|4.680000|74880|4.680000|320|0.020000|7766|2560|dbl|320|1|mono
+audio|1|75200|4.700000|75200|4.700000|320|0.020000|7799|2560|dbl|320|1|mono
+audio|1|75520|4.720000|75520|4.720000|320|0.020000|7832|2560|dbl|320|1|mono
+audio|1|75840|4.740000|75840|4.740000|320|0.020000|7865|2560|dbl|320|1|mono
+audio|1|76160|4.760000|76160|4.760000|320|0.020000|7898|2560|dbl|320|1|mono
+audio|1|76480|4.780000|76480|4.780000|320|0.020000|7931|2560|dbl|320|1|mono
+audio|1|76800|4.800000|76800|4.800000|320|0.020000|7964|2560|dbl|320|1|mono
+audio|1|77120|4.820000|77120|4.820000|320|0.020000|7997|2560|dbl|320|1|mono
+audio|1|77440|4.840000|77440|4.840000|320|0.020000|8030|2560|dbl|320|1|mono
+audio|1|77760|4.860000|77760|4.860000|320|0.020000|8063|2560|dbl|320|1|mono
+audio|1|78080|4.880000|78080|4.880000|320|0.020000|8096|2560|dbl|320|1|mono
+audio|1|78400|4.900000|78400|4.900000|320|0.020000|8129|2560|dbl|320|1|mono
+audio|1|78720|4.920000|78720|4.920000|320|0.020000|8162|2560|dbl|320|1|mono
+audio|1|79040|4.940000|79040|4.940000|320|0.020000|8195|2560|dbl|320|1|mono
+audio|1|79360|4.960000|79360|4.960000|320|0.020000|8228|2560|dbl|320|1|mono
+audio|1|79680|4.980000|79680|4.980000|320|0.020000|8261|2560|dbl|320|1|mono
+audio|1|80000|5.000000|80000|5.000000|324|0.020250|8294|2560|dbl|320|1|mono|4.9
+audio|1|80320|5.020000|80320|5.020000|320|0.020000|8327|2560|dbl|320|1|mono
+audio|1|80640|5.040000|80640|5.040000|320|0.020000|8360|2560|dbl|320|1|mono
+audio|1|80960|5.060000|80960|5.060000|320|0.020000|8393|2560|dbl|320|1|mono
+audio|1|81280|5.080000|81280|5.080000|320|0.020000|8426|2560|dbl|320|1|mono
+audio|1|81600|5.100000|81600|5.100000|320|0.020000|8459|2560|dbl|320|1|mono
+audio|1|81920|5.120000|81920|5.120000|320|0.020000|8492|2560|dbl|320|1|mono
+audio|1|82240|5.140000|82240|5.140000|320|0.020000|8525|2560|dbl|320|1|mono
+audio|1|82560|5.160000|82560|5.160000|320|0.020000|8558|2560|dbl|320|1|mono
+audio|1|82880|5.180000|82880|5.180000|320|0.020000|8591|2560|dbl|320|1|mono
+audio|1|83200|5.200000|83200|5.200000|320|0.020000|8624|2560|dbl|320|1|mono
+audio|1|83520|5.220000|83520|5.220000|320|0.020000|8657|2560|dbl|320|1|mono
+audio|1|83840|5.240000|83840|5.240000|320|0.020000|8690|2560|dbl|320|1|mono
+audio|1|84160|5.260000|84160|5.260000|320|0.020000|8723|2560|dbl|320|1|mono
+audio|1|84480|5.280000|84480|5.280000|320|0.020000|8756|2560|dbl|320|1|mono
+audio|1|84800|5.300000|84800|5.300000|320|0.020000|8789|2560|dbl|320|1|mono
+audio|1|85120|5.320000|85120|5.320000|320|0.020000|8822|2560|dbl|320|1|mono
+audio|1|85440|5.340000|85440|5.340000|320|0.020000|8855|2560|dbl|320|1|mono
+audio|1|85760|5.360000|85760|5.360000|320|0.020000|8888|2560|dbl|320|1|mono
+audio|1|86080|5.380000|86080|5.380000|320|0.020000|8921|2560|dbl|320|1|mono
+audio|1|86400|5.400000|86400|5.400000|320|0.020000|8954|2560|dbl|320|1|mono
+audio|1|86720|5.420000|86720|5.420000|320|0.020000|8987|2560|dbl|320|1|mono
+audio|1|87040|5.440000|87040|5.440000|328|0.020500|9020|2560|dbl|320|1|mono|5.44|0.54
+audio|1|87360|5.460000|87360|5.460000|320|0.020000|9053|2560|dbl|320|1|mono
+audio|1|87680|5.480000|87680|5.480000|320|0.020000|9086|2560|dbl|320|1|mono
+audio|1|88000|5.500000|88000|5.500000|320|0.020000|9119|2560|dbl|320|1|mono
+audio|1|88320|5.520000|88320|5.520000|320|0.020000|9152|2560|dbl|320|1|mono
+audio|1|88640|5.540000|88640|5.540000|320|0.020000|9185|2560|dbl|320|1|mono
+audio|1|88960|5.560000|88960|5.560000|320|0.020000|9218|2560|dbl|320|1|mono
+audio|1|89280|5.580000|89280|5.580000|320|0.020000|9251|2560|dbl|320|1|mono
+audio|1|89600|5.600000|89600|5.600000|320|0.020000|9284|2560|dbl|320|1|mono
+audio|1|89920|5.620000|89920|5.620000|320|0.020000|9317|2560|dbl|320|1|mono
+audio|1|90240|5.640000|90240|5.640000|320|0.020000|9350|2560|dbl|320|1|mono
+audio|1|90560|5.660000|90560|5.660000|320|0.020000|9383|2560|dbl|320|1|mono
+audio|1|90880|5.680000|90880|5.680000|320|0.020000|9416|2560|dbl|320|1|mono
+audio|1|91200|5.700000|91200|5.700000|320|0.020000|9449|2560|dbl|320|1|mono
+audio|1|91520|5.720000|91520|5.720000|320|0.020000|9482|2560|dbl|320|1|mono
+audio|1|91840|5.740000|91840|5.740000|320|0.020000|9515|2560|dbl|320|1|mono
+audio|1|92160|5.760000|92160|5.760000|320|0.020000|9548|2560|dbl|320|1|mono
+audio|1|92480|5.780000|92480|5.780000|320|0.020000|9581|2560|dbl|320|1|mono
+audio|1|92800|5.800000|92800|5.800000|320|0.020000|9614|2560|dbl|320|1|mono
+audio|1|93120|5.820000|93120|5.820000|320|0.020000|9647|2560|dbl|320|1|mono
+audio|1|93440|5.840000|93440|5.840000|320|0.020000|9680|2560|dbl|320|1|mono
+audio|1|93760|5.860000|93760|5.860000|320|0.020000|9713|2560|dbl|320|1|mono
+audio|1|94080|5.880000|94080|5.880000|320|0.020000|9746|2560|dbl|320|1|mono
+audio|1|94400|5.900000|94400|5.900000|320|0.020000|9779|2560|dbl|320|1|mono
+audio|1|94720|5.920000|94720|5.920000|320|0.020000|9812|2560|dbl|320|1|mono
+audio|1|95040|5.940000|95040|5.940000|320|0.020000|9845|2560|dbl|320|1|mono
+audio|1|95360|5.960000|95360|5.960000|320|0.020000|9878|2560|dbl|320|1|mono
+audio|1|95680|5.980000|95680|5.980000|320|0.020000|9911|2560|dbl|320|1|mono
+audio|1|96000|6.000000|96000|6.000000|320|0.020000|9944|2560|dbl|320|1|mono
+audio|1|96320|6.020000|96320|6.020000|320|0.020000|9977|2560|dbl|320|1|mono
+audio|1|96640|6.040000|96640|6.040000|320|0.020000|10010|2560|dbl|320|1|mono
+audio|1|96960|6.060000|96960|6.060000|320|0.020000|10043|2560|dbl|320|1|mono
+audio|1|97280|6.080000|97280|6.080000|320|0.020000|10076|2560|dbl|320|1|mono
+audio|1|97600|6.100000|97600|6.100000|320|0.020000|10109|2560|dbl|320|1|mono
+audio|1|97920|6.120000|97920|6.120000|320|0.020000|10142|2560|dbl|320|1|mono
+audio|1|98240|6.140000|98240|6.140000|320|0.020000|10175|2560|dbl|320|1|mono
+audio|1|98560|6.160000|98560|6.160000|320|0.020000|10208|2560|dbl|320|1|mono
+audio|1|98880|6.180000|98880|6.180000|320|0.020000|10241|2560|dbl|320|1|mono
+audio|1|99200|6.200000|99200|6.200000|320|0.020000|10274|2560|dbl|320|1|mono
+audio|1|99520|6.220000|99520|6.220000|320|0.020000|10307|2560|dbl|320|1|mono
+audio|1|99840|6.240000|99840|6.240000|320|0.020000|10340|2560|dbl|320|1|mono
+audio|1|100160|6.260000|100160|6.260000|320|0.020000|10373|2560|dbl|320|1|mono
+audio|1|100480|6.280000|100480|6.280000|320|0.020000|10406|2560|dbl|320|1|mono
+audio|1|100800|6.300000|100800|6.300000|320|0.020000|10439|2560|dbl|320|1|mono
+audio|1|101120|6.320000|101120|6.320000|320|0.020000|10472|2560|dbl|320|1|mono
+audio|1|101440|6.340000|101440|6.340000|320|0.020000|10505|2560|dbl|320|1|mono
+audio|1|101760|6.360000|101760|6.360000|320|0.020000|10538|2560|dbl|320|1|mono
+audio|1|102080|6.380000|102080|6.380000|320|0.020000|10571|2560|dbl|320|1|mono
+audio|1|102400|6.400000|102400|6.400000|320|0.020000|10604|2560|dbl|320|1|mono
+audio|1|102720|6.420000|102720|6.420000|320|0.020000|10637|2560|dbl|320|1|mono
+audio|1|103040|6.440000|103040|6.440000|320|0.020000|10670|2560|dbl|320|1|mono
+audio|1|103360|6.460000|103360|6.460000|320|0.020000|10703|2560|dbl|320|1|mono
+audio|1|103680|6.480000|103680|6.480000|320|0.020000|10736|2560|dbl|320|1|mono
+audio|1|104000|6.500000|104000|6.500000|320|0.020000|10769|2560|dbl|320|1|mono
+audio|1|104320|6.520000|104320|6.520000|320|0.020000|10802|2560|dbl|320|1|mono
+audio|1|104640|6.540000|104640|6.540000|324|0.020250|10835|2560|dbl|320|1|mono|6.44
+audio|1|104960|6.560000|104960|6.560000|320|0.020000|10868|2560|dbl|320|1|mono
+audio|1|105280|6.580000|105280|6.580000|320|0.020000|10901|2560|dbl|320|1|mono
+audio|1|105600|6.600000|105600|6.600000|320|0.020000|10934|2560|dbl|320|1|mono
+audio|1|105920|6.620000|105920|6.620000|320|0.020000|10967|2560|dbl|320|1|mono
+audio|1|106240|6.640000|106240|6.640000|320|0.020000|11000|2560|dbl|320|1|mono
+audio|1|106560|6.660000|106560|6.660000|320|0.020000|11033|2560|dbl|320|1|mono
+audio|1|106880|6.680000|106880|6.680000|320|0.020000|11066|2560|dbl|320|1|mono
+audio|1|107200|6.700000|107200|6.700000|320|0.020000|11099|2560|dbl|320|1|mono
+audio|1|107520|6.720000|107520|6.720000|320|0.020000|11132|2560|dbl|320|1|mono
+audio|1|107840|6.740000|107840|6.740000|320|0.020000|11165|2560|dbl|320|1|mono
+audio|1|108160|6.760000|108160|6.760000|320|0.020000|11198|2560|dbl|320|1|mono
+audio|1|108480|6.780000|108480|6.780000|320|0.020000|11231|2560|dbl|320|1|mono
+audio|1|108800|6.800000|108800|6.800000|320|0.020000|11264|2560|dbl|320|1|mono
+audio|1|109120|6.820000|109120|6.820000|320|0.020000|11297|2560|dbl|320|1|mono
+audio|1|109440|6.840000|109440|6.840000|320|0.020000|11330|2560|dbl|320|1|mono
+audio|1|109760|6.860000|109760|6.860000|320|0.020000|11363|2560|dbl|320|1|mono
+audio|1|110080|6.880000|110080|6.880000|320|0.020000|11396|2560|dbl|320|1|mono
+audio|1|110400|6.900000|110400|6.900000|320|0.020000|11429|2560|dbl|320|1|mono
+audio|1|110720|6.920000|110720|6.920000|320|0.020000|11462|2560|dbl|320|1|mono
+audio|1|111040|6.940000|111040|6.940000|320|0.020000|11495|2560|dbl|320|1|mono
+audio|1|111360|6.960000|111360|6.960000|320|0.020000|11528|2560|dbl|320|1|mono
+audio|1|111680|6.980000|111680|6.980000|320|0.020000|11561|2560|dbl|320|1|mono
+audio|1|112000|7.000000|112000|7.000000|320|0.020000|11594|2560|dbl|320|1|mono
+audio|1|112320|7.020000|112320|7.020000|320|0.020000|11627|2560|dbl|320|1|mono
+audio|1|112640|7.040000|112640|7.040000|320|0.020000|11660|2560|dbl|320|1|mono
+audio|1|112960|7.060000|112960|7.060000|320|0.020000|11693|2560|dbl|320|1|mono
+audio|1|113280|7.080000|113280|7.080000|320|0.020000|11726|2560|dbl|320|1|mono
+audio|1|113600|7.100000|113600|7.100000|320|0.020000|11759|2560|dbl|320|1|mono
+audio|1|113920|7.120000|113920|7.120000|320|0.020000|11792|2560|dbl|320|1|mono
+audio|1|114240|7.140000|114240|7.140000|320|0.020000|11825|2560|dbl|320|1|mono
+audio|1|114560|7.160000|114560|7.160000|320|0.020000|11858|2560|dbl|320|1|mono
+audio|1|114880|7.180000|114880|7.180000|320|0.020000|11891|2560|dbl|320|1|mono
+audio|1|115200|7.200000|115200|7.200000|320|0.020000|11924|2560|dbl|320|1|mono
+audio|1|115520|7.220000|115520|7.220000|320|0.020000|11957|2560|dbl|320|1|mono
+audio|1|115840|7.240000|115840|7.240000|320|0.020000|11990|2560|dbl|320|1|mono
+audio|1|116160|7.260000|116160|7.260000|328|0.020500|12023|2560|dbl|320|1|mono|7.26|0.82
+audio|1|116480|7.280000|116480|7.280000|320|0.020000|12056|2560|dbl|320|1|mono
+audio|1|116800|7.300000|116800|7.300000|320|0.020000|12089|2560|dbl|320|1|mono
+audio|1|117120|7.320000|117120|7.320000|320|0.020000|12122|2560|dbl|320|1|mono
+audio|1|117440|7.340000|117440|7.340000|320|0.020000|12155|2560|dbl|320|1|mono
+audio|1|117760|7.360000|117760|7.360000|320|0.020000|12188|2560|dbl|320|1|mono
+audio|1|118080|7.380000|118080|7.380000|320|0.020000|12221|2560|dbl|320|1|mono
+audio|1|118400|7.400000|118400|7.400000|320|0.020000|12254|2560|dbl|320|1|mono
+audio|1|118720|7.420000|118720|7.420000|320|0.020000|12287|2560|dbl|320|1|mono
+audio|1|119040|7.440000|119040|7.440000|320|0.020000|12320|2560|dbl|320|1|mono
+audio|1|119360|7.460000|119360|7.460000|320|0.020000|12353|2560|dbl|320|1|mono
+audio|1|119680|7.480000|119680|7.480000|320|0.020000|12386|2560|dbl|320|1|mono
+audio|1|120000|7.500000|120000|7.500000|320|0.020000|12419|2560|dbl|320|1|mono
+audio|1|120320|7.520000|120320|7.520000|320|0.020000|12452|2560|dbl|320|1|mono
+audio|1|120640|7.540000|120640|7.540000|320|0.020000|12485|2560|dbl|320|1|mono
+audio|1|120960|7.560000|120960|7.560000|320|0.020000|12518|2560|dbl|320|1|mono
+audio|1|121280|7.580000|121280|7.580000|320|0.020000|12551|2560|dbl|320|1|mono
+audio|1|121600|7.600000|121600|7.600000|320|0.020000|12584|2560|dbl|320|1|mono
+audio|1|121920|7.620000|121920|7.620000|320|0.020000|12617|2560|dbl|320|1|mono
+audio|1|122240|7.640000|122240|7.640000|320|0.020000|12650|2560|dbl|320|1|mono
+audio|1|122560|7.660000|122560|7.660000|320|0.020000|12683|2560|dbl|320|1|mono
+audio|1|122880|7.680000|122880|7.680000|320|0.020000|12716|2560|dbl|320|1|mono
+audio|1|123200|7.700000|123200|7.700000|320|0.020000|12749|2560|dbl|320|1|mono
+audio|1|123520|7.720000|123520|7.720000|320|0.020000|12782|2560|dbl|320|1|mono
+audio|1|123840|7.740000|123840|7.740000|320|0.020000|12815|2560|dbl|320|1|mono
+audio|1|124160|7.760000|124160|7.760000|320|0.020000|12848|2560|dbl|320|1|mono
+audio|1|124480|7.780000|124480|7.780000|320|0.020000|12881|2560|dbl|320|1|mono
+audio|1|124800|7.800000|124800|7.800000|320|0.020000|12914|2560|dbl|320|1|mono
+audio|1|125120|7.820000|125120|7.820000|320|0.020000|12947|2560|dbl|320|1|mono
+audio|1|125440|7.840000|125440|7.840000|320|0.020000|12980|2560|dbl|320|1|mono
+audio|1|125760|7.860000|125760|7.860000|320|0.020000|13013|2560|dbl|320|1|mono
+audio|1|126080|7.880000|126080|7.880000|320|0.020000|13046|2560|dbl|320|1|mono
+audio|1|126400|7.900000|126400|7.900000|320|0.020000|13079|2560|dbl|320|1|mono
+audio|1|126720|7.920000|126720|7.920000|320|0.020000|13112|2560|dbl|320|1|mono
+audio|1|127040|7.940000|127040|7.940000|320|0.020000|13145|2560|dbl|320|1|mono
+audio|1|127360|7.960000|127360|7.960000|320|0.020000|13178|2560|dbl|320|1|mono
+audio|1|127680|7.980000|127680|7.980000|320|0.020000|13211|2560|dbl|320|1|mono
+audio|1|128000|8.000000|128000|8.000000|320|0.020000|13244|2560|dbl|320|1|mono
+audio|1|128320|8.020000|128320|8.020000|320|0.020000|13277|2560|dbl|320|1|mono
+audio|1|128640|8.040000|128640|8.040000|320|0.020000|13310|2560|dbl|320|1|mono
+audio|1|128960|8.060000|128960|8.060000|320|0.020000|13343|2560|dbl|320|1|mono
+audio|1|129280|8.080000|129280|8.080000|320|0.020000|13376|2560|dbl|320|1|mono
+audio|1|129600|8.100000|129600|8.100000|320|0.020000|13409|2560|dbl|320|1|mono
+audio|1|129920|8.120000|129920|8.120000|320|0.020000|13442|2560|dbl|320|1|mono
+audio|1|130240|8.140000|130240|8.140000|320|0.020000|13475|2560|dbl|320|1|mono
+audio|1|130560|8.160000|130560|8.160000|320|0.020000|13508|2560|dbl|320|1|mono
+audio|1|130880|8.180000|130880|8.180000|320|0.020000|13541|2560|dbl|320|1|mono
+audio|1|131200|8.200000|131200|8.200000|320|0.020000|13574|2560|dbl|320|1|mono
+audio|1|131520|8.220000|131520|8.220000|320|0.020000|13607|2560|dbl|320|1|mono
+audio|1|131840|8.240000|131840|8.240000|320|0.020000|13640|2560|dbl|320|1|mono
+audio|1|132160|8.260000|132160|8.260000|320|0.020000|13673|2560|dbl|320|1|mono
+audio|1|132480|8.280000|132480|8.280000|320|0.020000|13706|2560|dbl|320|1|mono
+audio|1|132800|8.300000|132800|8.300000|320|0.020000|13739|2560|dbl|320|1|mono
+audio|1|133120|8.320000|133120|8.320000|320|0.020000|13772|2560|dbl|320|1|mono
+audio|1|133440|8.340000|133440|8.340000|320|0.020000|13805|2560|dbl|320|1|mono
+audio|1|133760|8.360000|133760|8.360000|320|0.020000|13838|2560|dbl|320|1|mono
+audio|1|134080|8.380000|134080|8.380000|320|0.020000|13871|2560|dbl|320|1|mono
+audio|1|134400|8.400000|134400|8.400000|320|0.020000|13904|2560|dbl|320|1|mono
+audio|1|134720|8.420000|134720|8.420000|320|0.020000|13937|2560|dbl|320|1|mono
+audio|1|135040|8.440000|135040|8.440000|320|0.020000|13970|2560|dbl|320|1|mono
+audio|1|135360|8.460000|135360|8.460000|320|0.020000|14003|2560|dbl|320|1|mono
+audio|1|135680|8.480000|135680|8.480000|320|0.020000|14036|2560|dbl|320|1|mono
+audio|1|136000|8.500000|136000|8.500000|320|0.020000|14069|2560|dbl|320|1|mono
+audio|1|136320|8.520000|136320|8.520000|320|0.020000|14102|2560|dbl|320|1|mono
+audio|1|136640|8.540000|136640|8.540000|320|0.020000|14135|2560|dbl|320|1|mono
+audio|1|136960|8.560000|136960|8.560000|320|0.020000|14168|2560|dbl|320|1|mono
+audio|1|137280|8.580000|137280|8.580000|320|0.020000|14201|2560|dbl|320|1|mono
+audio|1|137600|8.600000|137600|8.600000|324|0.020250|14234|2560|dbl|320|1|mono|8.5
+audio|1|137920|8.620000|137920|8.620000|320|0.020000|14267|2560|dbl|320|1|mono
+audio|1|138240|8.640000|138240|8.640000|320|0.020000|14300|2560|dbl|320|1|mono
+audio|1|138560|8.660000|138560|8.660000|320|0.020000|14333|2560|dbl|320|1|mono
+audio|1|138880|8.680000|138880|8.680000|328|0.020500|14366|2560|dbl|320|1|mono|8.68|0.18
+audio|1|139200|8.700000|139200|8.700000|320|0.020000|14399|2560|dbl|320|1|mono
+audio|1|139520|8.720000|139520|8.720000|320|0.020000|14432|2560|dbl|320|1|mono
+audio|1|139840|8.740000|139840|8.740000|320|0.020000|14465|2560|dbl|320|1|mono
+audio|1|140160|8.760000|140160|8.760000|320|0.020000|14498|2560|dbl|320|1|mono
+audio|1|140480|8.780000|140480|8.780000|324|0.020250|14531|2560|dbl|320|1|mono|8.68
+audio|1|140800|8.800000|140800|8.800000|320|0.020000|14564|2560|dbl|320|1|mono
+audio|1|141120|8.820000|141120|8.820000|320|0.020000|14597|2560|dbl|320|1|mono
+audio|1|141440|8.840000|141440|8.840000|320|0.020000|14630|2560|dbl|320|1|mono
+audio|1|141760|8.860000|141760|8.860000|320|0.020000|14663|2560|dbl|320|1|mono
+audio|1|142080|8.880000|142080|8.880000|320|0.020000|14696|2560|dbl|320|1|mono
+audio|1|142400|8.900000|142400|8.900000|320|0.020000|14729|2560|dbl|320|1|mono
+audio|1|142720|8.920000|142720|8.920000|320|0.020000|14762|2560|dbl|320|1|mono
+audio|1|143040|8.940000|143040|8.940000|320|0.020000|14795|2560|dbl|320|1|mono
+audio|1|143360|8.960000|143360|8.960000|320|0.020000|14828|2560|dbl|320|1|mono
+audio|1|143680|8.980000|143680|8.980000|327|0.020438|14861|2560|dbl|320|1|mono|8.98|0.3
+audio|1|144000|9.000000|144000|9.000000|320|0.020000|14894|2560|dbl|320|1|mono
+audio|1|144320|9.020000|144320|9.020000|320|0.020000|14927|2560|dbl|320|1|mono
+audio|1|144640|9.040000|144640|9.040000|320|0.020000|14960|2560|dbl|320|1|mono
+audio|1|144960|9.060000|144960|9.060000|320|0.020000|14993|2560|dbl|320|1|mono
+audio|1|145280|9.080000|145280|9.080000|320|0.020000|15026|2560|dbl|320|1|mono
+audio|1|145600|9.100000|145600|9.100000|320|0.020000|15059|2560|dbl|320|1|mono
+audio|1|145920|9.120000|145920|9.120000|320|0.020000|15092|2560|dbl|320|1|mono
+audio|1|146240|9.140000|146240|9.140000|320|0.020000|15125|2560|dbl|320|1|mono
+audio|1|146560|9.160000|146560|9.160000|320|0.020000|15158|2560|dbl|320|1|mono
+audio|1|146880|9.180000|146880|9.180000|320|0.020000|15191|2560|dbl|320|1|mono
+audio|1|147200|9.200000|147200|9.200000|320|0.020000|15224|2560|dbl|320|1|mono
+audio|1|147520|9.220000|147520|9.220000|320|0.020000|15257|2560|dbl|320|1|mono
+audio|1|147840|9.240000|147840|9.240000|320|0.020000|15290|2560|dbl|320|1|mono
+audio|1|148160|9.260000|148160|9.260000|320|0.020000|15323|2560|dbl|320|1|mono
+audio|1|148480|9.280000|148480|9.280000|320|0.020000|15356|2560|dbl|320|1|mono
+audio|1|148800|9.300000|148800|9.300000|320|0.020000|15389|2560|dbl|320|1|mono
+audio|1|149120|9.320000|149120|9.320000|320|0.020000|15422|2560|dbl|320|1|mono
+audio|1|149440|9.340000|149440|9.340000|320|0.020000|15455|2560|dbl|320|1|mono
+audio|1|149760|9.360000|149760|9.360000|320|0.020000|15488|2560|dbl|320|1|mono
+audio|1|150080|9.380000|150080|9.380000|320|0.020000|15521|2560|dbl|320|1|mono
+audio|1|150400|9.400000|150400|9.400000|320|0.020000|15554|2560|dbl|320|1|mono
+audio|1|150720|9.420000|150720|9.420000|320|0.020000|15587|2560|dbl|320|1|mono
+audio|1|151040|9.440000|151040|9.440000|320|0.020000|15620|2560|dbl|320|1|mono
+audio|1|151360|9.460000|151360|9.460000|320|0.020000|15653|2560|dbl|320|1|mono
+audio|1|151680|9.480000|151680|9.480000|320|0.020000|15686|2560|dbl|320|1|mono
+audio|1|152000|9.500000|152000|9.500000|320|0.020000|15719|2560|dbl|320|1|mono
+audio|1|152320|9.520000|152320|9.520000|320|0.020000|15752|2560|dbl|320|1|mono
+audio|1|152640|9.540000|152640|9.540000|320|0.020000|15785|2560|dbl|320|1|mono
+audio|1|152960|9.560000|152960|9.560000|320|0.020000|15818|2560|dbl|320|1|mono
+audio|1|153280|9.580000|153280|9.580000|320|0.020000|15851|2560|dbl|320|1|mono
+audio|1|153600|9.600000|153600|9.600000|320|0.020000|15884|2560|dbl|320|1|mono
+audio|1|153920|9.620000|153920|9.620000|320|0.020000|15917|2560|dbl|320|1|mono
+audio|1|154240|9.640000|154240|9.640000|320|0.020000|15950|2560|dbl|320|1|mono
+audio|1|154560|9.660000|154560|9.660000|320|0.020000|15983|2560|dbl|320|1|mono
+audio|1|154880|9.680000|154880|9.680000|320|0.020000|16016|2560|dbl|320|1|mono
+audio|1|155200|9.700000|155200|9.700000|320|0.020000|16049|2560|dbl|320|1|mono
+audio|1|155520|9.720000|155520|9.720000|320|0.020000|16082|2560|dbl|320|1|mono
+audio|1|155840|9.740000|155840|9.740000|320|0.020000|16115|2560|dbl|320|1|mono
+audio|1|156160|9.760000|156160|9.760000|320|0.020000|16148|2560|dbl|320|1|mono
+audio|1|156480|9.780000|156480|9.780000|320|0.020000|16181|2560|dbl|320|1|mono
+audio|1|156800|9.800000|156800|9.800000|320|0.020000|16214|2560|dbl|320|1|mono
+audio|1|157120|9.820000|157120|9.820000|320|0.020000|16247|2560|dbl|320|1|mono
+audio|1|157440|9.840000|157440|9.840000|320|0.020000|16280|2560|dbl|320|1|mono
+audio|1|157760|9.860000|157760|9.860000|320|0.020000|16313|2560|dbl|320|1|mono
+audio|1|158080|9.880000|158080|9.880000|320|0.020000|16346|2560|dbl|320|1|mono
+audio|1|158400|9.900000|158400|9.900000|320|0.020000|16379|2560|dbl|320|1|mono
+audio|1|158720|9.920000|158720|9.920000|320|0.020000|16412|2560|dbl|320|1|mono
+audio|1|159040|9.940000|159040|9.940000|320|0.020000|16445|2560|dbl|320|1|mono
+audio|1|159360|9.960000|159360|9.960000|320|0.020000|16478|2560|dbl|320|1|mono
+audio|1|159680|9.980000|159680|9.980000|320|0.020000|16511|2560|dbl|320|1|mono
+audio|1|160000|10.000000|160000|10.000000|320|0.020000|16544|2560|dbl|320|1|mono
+audio|1|160320|10.020000|160320|10.020000|320|0.020000|16577|2560|dbl|320|1|mono
+audio|1|160640|10.040000|160640|10.040000|320|0.020000|16610|2560|dbl|320|1|mono
+audio|1|160960|10.060000|160960|10.060000|320|0.020000|16643|2560|dbl|320|1|mono
+audio|1|161280|10.080000|161280|10.080000|320|0.020000|16676|2560|dbl|320|1|mono
+audio|1|161600|10.100000|161600|10.100000|324|0.020250|16709|2560|dbl|320|1|mono|10
+audio|1|161920|10.120000|161920|10.120000|320|0.020000|16742|2560|dbl|320|1|mono
+audio|1|162240|10.140000|162240|10.140000|320|0.020000|16775|2560|dbl|320|1|mono
+audio|1|162560|10.160000|162560|10.160000|320|0.020000|16808|2560|dbl|320|1|mono
+audio|1|162880|10.180000|162880|10.180000|320|0.020000|16841|2560|dbl|320|1|mono
+audio|1|163200|10.200000|163200|10.200000|320|0.020000|16874|2560|dbl|320|1|mono
+audio|1|163520|10.220000|163520|10.220000|320|0.020000|16907|2560|dbl|320|1|mono
diff --git a/tests/ref/fate/filter-yadif-mode0 b/tests/ref/fate/filter-yadif-mode0
index 7014333..162ba96 100644
--- a/tests/ref/fate/filter-yadif-mode0
+++ b/tests/ref/fate/filter-yadif-mode0
@@ -1,32 +1,32 @@
 #tb 0: 1/25
-0,          9,          9,        1,   622080, 0x4440caef
-0,         10,         10,        1,   622080, 0xce67e69d
-0,         11,         11,        1,   622080, 0x1dbdc653
-0,         12,         12,        1,   622080, 0x55c791d0
-0,         13,         13,        1,   622080, 0x8193740b
-0,         14,         14,        1,   622080, 0x7125970f
-0,         15,         15,        1,   622080, 0xeb63783a
-0,         16,         16,        1,   622080, 0x7080590b
-0,         17,         17,        1,   622080, 0x13f8175b
-0,         18,         18,        1,   622080, 0x3e550e94
-0,         19,         19,        1,   622080, 0x7f9d66f7
-0,         20,         20,        1,   622080, 0x068eda80
-0,         21,         21,        1,   622080, 0x843997f7
-0,         22,         22,        1,   622080, 0x88207ca3
-0,         23,         23,        1,   622080, 0x353eed75
-0,         24,         24,        1,   622080, 0xf93e92b0
-0,         25,         25,        1,   622080, 0xd0811094
-0,         26,         26,        1,   622080, 0xb04a3141
-0,         27,         27,        1,   622080, 0x4ab84909
-0,         28,         28,        1,   622080, 0x4700b8f9
-0,         29,         29,        1,   622080, 0x6305aeba
-0,         30,         30,        1,   622080, 0x153faa3e
-0,         31,         31,        1,   622080, 0xae724063
-0,         32,         32,        1,   622080, 0xbe4fe779
-0,         33,         33,        1,   622080, 0x209ed8c7
-0,         34,         34,        1,   622080, 0xe2bbac96
-0,         35,         35,        1,   622080, 0xe945441e
-0,         36,         36,        1,   622080, 0x3590bd5d
-0,         37,         37,        1,   622080, 0x8f3ef716
-0,         38,         38,        1,   622080, 0x0109f125
-0,         39,         39,        1,   622080, 0x230c373f
+0,          9,          9,        1,   622080, 0x6331caee
+0,         10,         10,        1,   622080, 0xa459e690
+0,         11,         11,        1,   622080, 0x6429c648
+0,         12,         12,        1,   622080, 0xa49891ca
+0,         13,         13,        1,   622080, 0x2a887404
+0,         14,         14,        1,   622080, 0xe8d49705
+0,         15,         15,        1,   622080, 0x1b627835
+0,         16,         16,        1,   622080, 0x686858fd
+0,         17,         17,        1,   622080, 0x2675174f
+0,         18,         18,        1,   622080, 0x78470e7f
+0,         19,         19,        1,   622080, 0xffb366ec
+0,         20,         20,        1,   622080, 0xd575da72
+0,         21,         21,        1,   622080, 0x5fb297f7
+0,         22,         22,        1,   622080, 0xbac77ca0
+0,         23,         23,        1,   622080, 0x3276ed72
+0,         24,         24,        1,   622080, 0x264092b2
+0,         25,         25,        1,   622080, 0x20ba1094
+0,         26,         26,        1,   622080, 0x76cc3139
+0,         27,         27,        1,   622080, 0x469a4902
+0,         28,         28,        1,   622080, 0x0ed7b8f5
+0,         29,         29,        1,   622080, 0xdc51aeac
+0,         30,         30,        1,   622080, 0xee06aa36
+0,         31,         31,        1,   622080, 0x7372405f
+0,         32,         32,        1,   622080, 0x9e0ee776
+0,         33,         33,        1,   622080, 0x39e6d8c9
+0,         34,         34,        1,   622080, 0x51d9ac9a
+0,         35,         35,        1,   622080, 0x2b63441d
+0,         36,         36,        1,   622080, 0x58afbd5e
+0,         37,         37,        1,   622080, 0xb972f716
+0,         38,         38,        1,   622080, 0x6a6df129
+0,         39,         39,        1,   622080, 0x28b1373d
diff --git a/tests/ref/fate/filter-yadif-mode1 b/tests/ref/fate/filter-yadif-mode1
index 87c8d97..f1f513e 100644
--- a/tests/ref/fate/filter-yadif-mode1
+++ b/tests/ref/fate/filter-yadif-mode1
@@ -1,63 +1,63 @@
 #tb 0: 1/50
-0,         18,         18,        1,   622080, 0x4440caef
-0,         19,         19,        1,   622080, 0xa5cea88b
-0,         20,         20,        1,   622080, 0xce67e69d
-0,         21,         21,        1,   622080, 0x9a57891f
-0,         22,         22,        1,   622080, 0x1dbdc653
-0,         23,         23,        1,   622080, 0xc171c0c5
-0,         24,         24,        1,   622080, 0x55c791d0
-0,         25,         25,        1,   622080, 0x20db9890
-0,         26,         26,        1,   622080, 0x8193740b
-0,         27,         27,        1,   622080, 0xdb181d52
-0,         28,         28,        1,   622080, 0x7125970f
-0,         29,         29,        1,   622080, 0xc2b913d1
-0,         30,         30,        1,   622080, 0xeb63783a
-0,         31,         31,        1,   622080, 0xf1d9c5fb
-0,         32,         32,        1,   622080, 0x7080590b
-0,         33,         33,        1,   622080, 0xeda55774
-0,         34,         34,        1,   622080, 0x13f8175b
-0,         35,         35,        1,   622080, 0x01921a16
-0,         36,         36,        1,   622080, 0x3e550e94
-0,         37,         37,        1,   622080, 0xd5047bc9
-0,         38,         38,        1,   622080, 0x7f9d66f7
-0,         39,         39,        1,   622080, 0x2fc806ea
-0,         40,         40,        1,   622080, 0x068eda80
-0,         41,         41,        1,   622080, 0xf0e125a7
-0,         42,         42,        1,   622080, 0x843997f7
-0,         43,         43,        1,   622080, 0x4afe2976
-0,         44,         44,        1,   622080, 0x88207ca3
-0,         45,         45,        1,   622080, 0x637fcbfe
-0,         46,         46,        1,   622080, 0x353eed75
-0,         47,         47,        1,   622080, 0xd9a8f5ac
-0,         48,         48,        1,   622080, 0xf93e92b0
-0,         49,         49,        1,   622080, 0x4540039f
-0,         50,         50,        1,   622080, 0xd0811094
-0,         51,         51,        1,   622080, 0x3039906f
-0,         52,         52,        1,   622080, 0xb04a3141
-0,         53,         53,        1,   622080, 0xe62d2cfa
-0,         54,         54,        1,   622080, 0x4ab84909
-0,         55,         55,        1,   622080, 0x82de12ee
-0,         56,         56,        1,   622080, 0x4700b8f9
-0,         57,         57,        1,   622080, 0x7e849cc9
-0,         58,         58,        1,   622080, 0x6305aeba
-0,         59,         59,        1,   622080, 0x939bf771
-0,         60,         60,        1,   622080, 0x153faa3e
-0,         61,         61,        1,   622080, 0xb67f3233
-0,         62,         62,        1,   622080, 0xae724063
-0,         63,         63,        1,   622080, 0xed2b44b3
-0,         64,         64,        1,   622080, 0xbe4fe779
-0,         65,         65,        1,   622080, 0x380f8563
-0,         66,         66,        1,   622080, 0x209ed8c7
-0,         67,         67,        1,   622080, 0xb964d70f
-0,         68,         68,        1,   622080, 0xe2bbac96
-0,         69,         69,        1,   622080, 0x4f60f7f4
-0,         70,         70,        1,   622080, 0xe945441e
-0,         71,         71,        1,   622080, 0xded0b740
-0,         72,         72,        1,   622080, 0x3590bd5d
-0,         73,         73,        1,   622080, 0xb9a15294
-0,         74,         74,        1,   622080, 0x8f3ef716
-0,         75,         75,        1,   622080, 0x3e2301a8
-0,         76,         76,        1,   622080, 0x0109f125
-0,         77,         77,        1,   622080, 0x5252371e
-0,         78,         78,        1,   622080, 0x230c373f
-0,         79,         79,        1,   622080, 0x5a1ab1f1
+0,         18,         18,        1,   622080, 0x6331caee
+0,         19,         19,        1,   622080, 0x625da883
+0,         20,         20,        1,   622080, 0xa459e690
+0,         21,         21,        1,   622080, 0xce5d891e
+0,         22,         22,        1,   622080, 0x6429c648
+0,         23,         23,        1,   622080, 0x608cc0ba
+0,         24,         24,        1,   622080, 0xa49891ca
+0,         25,         25,        1,   622080, 0x9721987f
+0,         26,         26,        1,   622080, 0x2a887404
+0,         27,         27,        1,   622080, 0x60d71d47
+0,         28,         28,        1,   622080, 0xe8d49705
+0,         29,         29,        1,   622080, 0x821e13cb
+0,         30,         30,        1,   622080, 0x1b627835
+0,         31,         31,        1,   622080, 0x1806c5f4
+0,         32,         32,        1,   622080, 0x686858fd
+0,         33,         33,        1,   622080, 0xab865773
+0,         34,         34,        1,   622080, 0x2675174f
+0,         35,         35,        1,   622080, 0x43a61a14
+0,         36,         36,        1,   622080, 0x78470e7f
+0,         37,         37,        1,   622080, 0xeb877bc6
+0,         38,         38,        1,   622080, 0xffb366ec
+0,         39,         39,        1,   622080, 0xda0906e7
+0,         40,         40,        1,   622080, 0xd575da72
+0,         41,         41,        1,   622080, 0x23ae25a4
+0,         42,         42,        1,   622080, 0x5fb297f7
+0,         43,         43,        1,   622080, 0x99b32978
+0,         44,         44,        1,   622080, 0xbac77ca0
+0,         45,         45,        1,   622080, 0xc1cdcbf9
+0,         46,         46,        1,   622080, 0x3276ed72
+0,         47,         47,        1,   622080, 0x4061f5ab
+0,         48,         48,        1,   622080, 0x264092b2
+0,         49,         49,        1,   622080, 0xa4e2039e
+0,         50,         50,        1,   622080, 0x20ba1094
+0,         51,         51,        1,   622080, 0x984e906e
+0,         52,         52,        1,   622080, 0x76cc3139
+0,         53,         53,        1,   622080, 0xf70e2cf6
+0,         54,         54,        1,   622080, 0x469a4902
+0,         55,         55,        1,   622080, 0x235312e6
+0,         56,         56,        1,   622080, 0x0ed7b8f5
+0,         57,         57,        1,   622080, 0xd0269cc3
+0,         58,         58,        1,   622080, 0xdc51aeac
+0,         59,         59,        1,   622080, 0x1aa5f76e
+0,         60,         60,        1,   622080, 0xee06aa36
+0,         61,         61,        1,   622080, 0xa7103230
+0,         62,         62,        1,   622080, 0x7372405f
+0,         63,         63,        1,   622080, 0x8d7a44b5
+0,         64,         64,        1,   622080, 0x9e0ee776
+0,         65,         65,        1,   622080, 0xd41e8560
+0,         66,         66,        1,   622080, 0x39e6d8c9
+0,         67,         67,        1,   622080, 0x7a23d70c
+0,         68,         68,        1,   622080, 0x51d9ac9a
+0,         69,         69,        1,   622080, 0x8eacf7f2
+0,         70,         70,        1,   622080, 0x2b63441d
+0,         71,         71,        1,   622080, 0x9f71b742
+0,         72,         72,        1,   622080, 0x58afbd5e
+0,         73,         73,        1,   622080, 0x4d645292
+0,         74,         74,        1,   622080, 0xb972f716
+0,         75,         75,        1,   622080, 0xbb5d01a2
+0,         76,         76,        1,   622080, 0x6a6df129
+0,         77,         77,        1,   622080, 0x9e45371e
+0,         78,         78,        1,   622080, 0x28b1373d
+0,         79,         79,        1,   622080, 0xa1cdb1f2
diff --git a/tests/ref/fate/force_key_frames b/tests/ref/fate/force_key_frames
new file mode 100644
index 0000000..b93adca
--- /dev/null
+++ b/tests/ref/fate/force_key_frames
@@ -0,0 +1,4 @@
+5423335cd809e631a2e03f97585348e0 *tests/data/fate/force_key_frames.avi
+113308 tests/data/fate/force_key_frames.avi
+8f68ad2e602ecd87a3e0c097ba99d773 *tests/data/fate/force_key_frames.out.framecrc
+stddev:34363.01 PSNR:  5.61 MAXDIFF:56305 bytes:  7603200/      186
diff --git a/tests/ref/fate/fraps-v1 b/tests/ref/fate/fraps-v1
index 64392c3..29c7e37 100644
--- a/tests/ref/fate/fraps-v1
+++ b/tests/ref/fate/fraps-v1
@@ -1,2 +1,2 @@
 #tb 0: 1/25
-0,          0,          0,        1,   230400, 0x6bc891ff
+0,          0,          0,        1,   230400, 0x23c29d17
diff --git a/tests/ref/fate/gif-color b/tests/ref/fate/gif-color
new file mode 100644
index 0000000..6abb565
--- /dev/null
+++ b/tests/ref/fate/gif-color
@@ -0,0 +1,174 @@
+#tb 0: 1/100
+0,          0,          0,        1,   188356, 0xf0944065
+0,         10,         10,        1,   188356, 0x146ed4c4
+0,         20,         20,        1,   188356, 0x96866a6f
+0,         30,         30,        1,   188356, 0xe15e1f1c
+0,         40,         40,        1,   188356, 0x0662c1d0
+0,         50,         50,        1,   188356, 0x88fa6cc4
+0,         60,         60,        1,   188356, 0x3cce2f71
+0,         70,         70,        1,   188356, 0x1510f9f3
+0,         80,         80,        1,   188356, 0xf27e9fa8
+0,         90,         90,        1,   188356, 0x0f4b64a2
+0,        100,        100,        1,   188356, 0x3d2714a5
+0,        110,        110,        1,   188356, 0x392ce45d
+0,        120,        120,        1,   188356, 0x2eadb79f
+0,        130,        130,        1,   188356, 0x68109314
+0,        140,        140,        1,   188356, 0x4eca71ac
+0,        150,        150,        1,   188356, 0xa9aa5907
+0,        160,        160,        1,   188356, 0x2a5d08c0
+0,        170,        170,        1,   188356, 0x942bba84
+0,        180,        180,        1,   188356, 0xbee38983
+0,        190,        190,        1,   188356, 0xa0d65a5a
+0,        200,        200,        1,   188356, 0x47270bee
+0,        210,        210,        1,   188356, 0xc020dc40
+0,        220,        220,        1,   188356, 0x978dbc8f
+0,        230,        230,        1,   188356, 0x6b1e9f1b
+0,        240,        240,        1,   188356, 0xd8078bf4
+0,        250,        250,        1,   188356, 0x94ca7bd7
+0,        260,        260,        1,   188356, 0xac745e77
+0,        270,        270,        1,   188356, 0x73154f2c
+0,        280,        280,        1,   188356, 0x31200601
+0,        290,        290,        1,   188356, 0x6525dd42
+0,        300,        300,        1,   188356, 0xa29b985a
+0,        310,        310,        1,   188356, 0xe3e074d8
+0,        320,        320,        1,   188356, 0xb87b3222
+0,        330,        330,        1,   188356, 0x5b9a11f2
+0,        340,        340,        1,   188356, 0x25f7f8c9
+0,        350,        350,        1,   188356, 0x0235e93c
+0,        360,        360,        1,   188356, 0x2a42d643
+0,        370,        370,        1,   188356, 0xfb7acddb
+0,        380,        380,        1,   188356, 0xecbbbf5e
+0,        390,        390,        1,   188356, 0xeba4bc9a
+0,        400,        400,        1,   188356, 0x4317b36b
+0,        410,        410,        1,   188356, 0x7316ae1a
+0,        420,        420,        1,   188356, 0xb5ccad05
+0,        430,        430,        1,   188356, 0x38afb0dc
+0,        440,        440,        1,   188356, 0xf11cad55
+0,        450,        450,        1,   188356, 0x3d77b400
+0,        460,        460,        1,   188356, 0xf084b9b9
+0,        470,        470,        1,   188356, 0x02a4c584
+0,        480,        480,        1,   188356, 0x14f4d52e
+0,        490,        490,        1,   188356, 0x55118432
+0,        500,        500,        1,   188356, 0x4ad82e9f
+0,        510,        510,        1,   188356, 0xc6eafc52
+0,        520,        520,        1,   188356, 0xf4bdc575
+0,        530,        530,        1,   188356, 0x8429689e
+0,        540,        540,        1,   188356, 0xaa23019e
+0,        550,        550,        1,   188356, 0xaf52c3a5
+0,        560,        560,        1,   188356, 0x1d387c32
+0,        570,        570,        1,   188356, 0x543d5cd2
+0,        580,        580,        1,   188356, 0x8cdb399c
+0,        590,        590,        1,   188356, 0xcceb292f
+0,        600,        600,        1,   188356, 0xa87115e8
+0,        610,        610,        1,   188356, 0x9665ec8f
+0,        620,        620,        1,   188356, 0xad99baf4
+0,        630,        630,        1,   188356, 0xc6e5a2b5
+0,        640,        640,        1,   188356, 0xe2a48359
+0,        650,        650,        1,   188356, 0x3a270df0
+0,        660,        660,        1,   188356, 0xcc34826b
+0,        670,        670,        1,   188356, 0x15ec2dcc
+0,        680,        680,        1,   188356, 0x8874c5f9
+0,        690,        690,        1,   188356, 0x829966e8
+0,        700,        700,        1,   188356, 0x691f1ebb
+0,        710,        710,        1,   188356, 0x00e3e184
+0,        720,        720,        1,   188356, 0x97739332
+0,        730,        730,        1,   188356, 0x507769aa
+0,        740,        740,        1,   188356, 0xddfb3069
+0,        750,        750,        1,   188356, 0x7296f749
+0,        760,        760,        1,   188356, 0x0555ca32
+0,        770,        770,        1,   188356, 0x4554c683
+0,        780,        780,        1,   188356, 0x2398c10f
+0,        790,        790,        1,   188356, 0x1c5ccfa0
+0,        800,        800,        1,   188356, 0xa580f3c8
+0,        810,        810,        1,   188356, 0x4fadea78
+0,        820,        820,        1,   188356, 0x4a57db38
+0,        830,        830,        1,   188356, 0x9e98df6d
+0,        840,        840,        1,   188356, 0xfeb3dec9
+0,        850,        850,        1,   188356, 0xbf16ef7a
+0,        860,        860,        1,   188356, 0xdc23fc48
+0,        870,        870,        1,   188356, 0x3bf2e401
+0,        880,        880,        1,   188356, 0xc832bcf4
+0,        890,        890,        1,   188356, 0x977db44f
+0,        900,        900,        1,   188356, 0x18d39d96
+0,        910,        910,        1,   188356, 0x9adf60d8
+0,        920,        920,        1,   188356, 0x567b667a
+0,        930,        930,        1,   188356, 0xd4a45e8e
+0,        940,        940,        1,   188356, 0x94a24cc7
+0,        950,        950,        1,   188356, 0x086f0a53
+0,        960,        960,        1,   188356, 0xcbf3ebcb
+0,        970,        970,        1,   188356, 0x1a40a7b9
+0,        980,        980,        1,   188356, 0xe16d8964
+0,        990,        990,        1,   188356, 0x3edd7dfa
+0,       1000,       1000,        1,   188356, 0xba417fa5
+0,       1010,       1010,        1,   188356, 0x734a7611
+0,       1020,       1020,        1,   188356, 0xfa1e7b1e
+0,       1030,       1030,        1,   188356, 0x1af23355
+0,       1040,       1040,        1,   188356, 0x28d41390
+0,       1050,       1050,        1,   188356, 0x2838c58d
+0,       1060,       1060,        1,   188356, 0x4e2ba2a8
+0,       1070,       1070,        1,   188356, 0xcedc99ae
+0,       1080,       1080,        1,   188356, 0xb06ba12d
+0,       1090,       1090,        1,   188356, 0x38c997b6
+0,       1100,       1100,        1,   188356, 0x12dba0dc
+0,       1110,       1110,        1,   188356, 0x5f86496a
+0,       1120,       1120,        1,   188356, 0x0b74216d
+0,       1130,       1130,        1,   188356, 0xdbddbada
+0,       1140,       1140,        1,   188356, 0x7d168af2
+0,       1150,       1150,        1,   188356, 0x22d4462b
+0,       1160,       1160,        1,   188356, 0xc248265d
+0,       1170,       1170,        1,   188356, 0x37a41b0d
+0,       1180,       1180,        1,   188356, 0x9ebd24f1
+0,       1190,       1190,        1,   188356, 0xf21f1633
+0,       1200,       1200,        1,   188356, 0x1db62004
+0,       1210,       1210,        1,   188356, 0xcc241ac1
+0,       1220,       1220,        1,   188356, 0x224d2637
+0,       1230,       1230,        1,   188356, 0x1bd8390c
+0,       1240,       1240,        1,   188356, 0xd8e64966
+0,       1250,       1250,        1,   188356, 0x96e66287
+0,       1260,       1260,        1,   188356, 0xa83c9a32
+0,       1270,       1270,        1,   188356, 0x3a5faeba
+0,       1280,       1280,        1,   188356, 0x8200cd87
+0,       1290,       1290,        1,   188356, 0x6326e591
+0,       1300,       1300,        1,   188356, 0xb5d70993
+0,       1310,       1310,        1,   188356, 0x954d5da2
+0,       1320,       1320,        1,   188356, 0x38b1788b
+0,       1330,       1330,        1,   188356, 0x4aafa131
+0,       1340,       1340,        1,   188356, 0xaff2be78
+0,       1350,       1350,        1,   188356, 0x9bd7eb69
+0,       1360,       1360,        1,   188356, 0x0d2b17c9
+0,       1370,       1370,        1,   188356, 0xf5d8a764
+0,       1380,       1380,        1,   188356, 0xa302dfb2
+0,       1390,       1390,        1,   188356, 0xe8a32ac1
+0,       1400,       1400,        1,   188356, 0x50a8470d
+0,       1410,       1410,        1,   188356, 0x52826061
+0,       1420,       1420,        1,   188356, 0x26e88798
+0,       1430,       1430,        1,   188356, 0x1448acb8
+0,       1440,       1440,        1,   188356, 0xfb380972
+0,       1450,       1450,        1,   188356, 0x184976e8
+0,       1460,       1460,        1,   188356, 0xa349a871
+0,       1470,       1470,        1,   188356, 0x617ed8b1
+0,       1480,       1480,        1,   188356, 0xb6bc1425
+0,       1490,       1490,        1,   188356, 0xafe74efd
+0,       1500,       1500,        1,   188356, 0x0b8b61e5
+0,       1510,       1510,        1,   188356, 0xc6ad67a7
+0,       1520,       1520,        1,   188356, 0x4da186fe
+0,       1530,       1530,        1,   188356, 0xe08f9975
+0,       1540,       1540,        1,   188356, 0xa43f8ba4
+0,       1550,       1550,        1,   188356, 0xcad4b6b5
+0,       1560,       1560,        1,   188356, 0x7e70d51e
+0,       1570,       1570,        1,   188356, 0x429b0b5b
+0,       1580,       1580,        1,   188356, 0xea92350d
+0,       1590,       1590,        1,   188356, 0x9a7440f8
+0,       1600,       1600,        1,   188356, 0x63a2be6e
+0,       1610,       1610,        1,   188356, 0x59b64b50
+0,       1620,       1620,        1,   188356, 0x63c4a10e
+0,       1630,       1630,        1,   188356, 0x6146e5e0
+0,       1640,       1640,        1,   188356, 0x603b2ae5
+0,       1650,       1650,        1,   188356, 0x818bc774
+0,       1660,       1660,        1,   188356, 0xa5ce278f
+0,       1670,       1670,        1,   188356, 0x4d85684d
+0,       1680,       1680,        1,   188356, 0xbbda9cad
+0,       1690,       1690,        1,   188356, 0xfee2e78e
+0,       1700,       1700,        1,   188356, 0x681d2635
+0,       1710,       1710,        1,   188356, 0x05354903
+0,       1720,       1720,        1,   188356, 0x8eecac99
diff --git a/tests/ref/fate/gif-demux b/tests/ref/fate/gif-demux
new file mode 100644
index 0000000..547b9ce
--- /dev/null
+++ b/tests/ref/fate/gif-demux
@@ -0,0 +1,37 @@
+#tb 0: 1/100
+0,          0,          0,        5,    74699, 0xef7e91c8
+0,          5,          5,        2,    10079, 0x2892d9e2, F=0x0
+0,          7,          7,        2,    12369, 0xd7d73286, F=0x0
+0,          9,          9,        2,     8868, 0x4bb59b6d, F=0x0
+0,         11,         11,        2,     8249, 0x23d5d174, F=0x0
+0,         13,         13,        2,     8381, 0x10acf0cd, F=0x0
+0,         15,         15,        2,     8579, 0xdfe108b2, F=0x0
+0,         17,         17,        2,     8200, 0x46ec6c55, F=0x0
+0,         19,         19,        2,     7261, 0xaf328999, F=0x0
+0,         21,         21,        4,     7047, 0xab3d2bd0, F=0x0
+0,         25,         25,        2,     6486, 0xa1629769, F=0x0
+0,         27,         27,        2,     7278, 0x4c55b7ce, F=0x0
+0,         29,         29,        2,     7761, 0x54368171, F=0x0
+0,         31,         31,        2,     7794, 0xbde2dbcd, F=0x0
+0,         33,         33,        2,     7935, 0xe6202c65, F=0x0
+0,         35,         35,        2,     8499, 0x1d5ceb7e, F=0x0
+0,         37,         37,        2,     8841, 0xc962be37, F=0x0
+0,         39,         39,        2,     9281, 0x7ec29c31, F=0x0
+0,         41,         41,        5,     9606, 0x3de06d48, F=0x0
+0,         46,         46,        2,     6319, 0xb3e94478, F=0x0
+0,         48,         48,        2,     5521, 0xc8157edc, F=0x0
+0,         50,         50,        2,     5052, 0x23e8ea7c, F=0x0
+0,         52,         52,        2,     4651, 0xa73f25c9, F=0x0
+0,         54,         54,        2,     4477, 0x1ddcc2c3, F=0x0
+0,         56,         56,        2,     4736, 0x6ead0d5e, F=0x0
+0,         58,         58,        2,     4609, 0x8bc7faa3, F=0x0
+0,         60,         60,        2,     4474, 0x3926975e, F=0x0
+0,         62,         62,        4,     4381, 0x28c392d5, F=0x0
+0,         66,         66,        2,     4443, 0x9c33b143, F=0x0
+0,         68,         68,        2,     4540, 0xb1d1c8b9, F=0x0
+0,         70,         70,        2,     4530, 0x773bc617, F=0x0
+0,         72,         72,        2,     4558, 0xa1e8cdf3, F=0x0
+0,         74,         74,        2,     4633, 0x8f64fda7, F=0x0
+0,         76,         76,        2,     4700, 0x45f40805, F=0x0
+0,         78,         78,        2,     5117, 0x4eb4c5fb, F=0x0
+0,         80,         80,        2,     5370, 0xb10c6910, F=0x0
diff --git a/tests/ref/fate/gif-disposal-restore b/tests/ref/fate/gif-disposal-restore
new file mode 100644
index 0000000..0ce4112
--- /dev/null
+++ b/tests/ref/fate/gif-disposal-restore
@@ -0,0 +1,4 @@
+#tb 0: 1/100
+0,          0,          0,        1,   112320, 0xb8afe429
+0,         10,         10,        1,   112320, 0xae588a4b
+0,        310,        310,        1,   112320, 0xccdd27b7
diff --git a/tests/ref/fate/gif-gray b/tests/ref/fate/gif-gray
new file mode 100644
index 0000000..5a133bd
--- /dev/null
+++ b/tests/ref/fate/gif-gray
@@ -0,0 +1,37 @@
+#tb 0: 1/100
+0,          0,          0,        1,   691200, 0xef6c0f3d
+0,          5,          5,        1,   691200, 0xc18b32de
+0,          7,          7,        1,   691200, 0x2395a3d7
+0,          9,          9,        1,   691200, 0x81dc3cf2
+0,         11,         11,        1,   691200, 0xabe2390e
+0,         13,         13,        1,   691200, 0xb2955c2a
+0,         15,         15,        1,   691200, 0x868d9ca2
+0,         17,         17,        1,   691200, 0x3016c2b6
+0,         19,         19,        1,   691200, 0x4501cffa
+0,         21,         21,        1,   691200, 0x8661d79e
+0,         25,         25,        1,   691200, 0xbc96d02e
+0,         27,         27,        1,   691200, 0x5f90bf5e
+0,         29,         29,        1,   691200, 0xf18da09a
+0,         31,         31,        1,   691200, 0x540467ce
+0,         33,         33,        1,   691200, 0x60d24012
+0,         35,         35,        1,   691200, 0x24323d36
+0,         37,         37,        1,   691200, 0x9e07c84b
+0,         39,         39,        1,   691200, 0xc18b32de
+0,         41,         41,        1,   691200, 0xef6c0f3d
+0,         46,         46,        1,   691200, 0xc9461045
+0,         48,         48,        1,   691200, 0x23ed4b99
+0,         50,         50,        1,   691200, 0x7e351d69
+0,         52,         52,        1,   691200, 0x0513e0aa
+0,         54,         54,        1,   691200, 0x28a4b6f2
+0,         56,         56,        1,   691200, 0xce10a94e
+0,         58,         58,        1,   691200, 0x63929d4e
+0,         60,         60,        1,   691200, 0xd26c9bb6
+0,         62,         62,        1,   691200, 0xb2a29842
+0,         66,         66,        1,   691200, 0x9fd69a16
+0,         68,         68,        1,   691200, 0x10f99e46
+0,         70,         70,        1,   691200, 0xea95a9fa
+0,         72,         72,        1,   691200, 0x97dbb9d6
+0,         74,         74,        1,   691200, 0xf4e9e2d6
+0,         76,         76,        1,   691200, 0x46b1230d
+0,         78,         78,        1,   691200, 0xb4a54ccd
+0,         80,         80,        1,   691200, 0x40cc103d
diff --git a/tests/ref/fate/hmac b/tests/ref/fate/hmac
new file mode 100644
index 0000000..7d2a437
--- /dev/null
+++ b/tests/ref/fate/hmac
@@ -0,0 +1,6 @@
+9294727a3638bb1c13f48ef8158bfc9d
+750c783e6ab0b503eaa86e310a5db738
+56be34521d144c88dbb8c733f0e8b3f6
+467cb2560355d7fa3ab2d6b939e6e47c
+5a6ffd741d3e23b12f78b1baee9e609a
+8b4b9d11c9e186c58f2a53b08ddfa436
diff --git a/tests/ref/fate/idroq-video-encode b/tests/ref/fate/idroq-video-encode
index 24f3f0d..9d25b13 100644
--- a/tests/ref/fate/idroq-video-encode
+++ b/tests/ref/fate/idroq-video-encode
@@ -1 +1 @@
-2be5ade557acab688d58f1c5ec0773f4
+50fa863f7820bb22ddeb74d5adf5f0bc
diff --git a/tests/ref/fate/lossless-tta-encrypted b/tests/ref/fate/lossless-tta-encrypted
new file mode 100644
index 0000000..39aec95
--- /dev/null
+++ b/tests/ref/fate/lossless-tta-encrypted
@@ -0,0 +1 @@
+CRC=0x4563745f
diff --git a/tests/ref/fate/nistsphere-demux b/tests/ref/fate/nistsphere-demux
new file mode 100644
index 0000000..bb4874f
--- /dev/null
+++ b/tests/ref/fate/nistsphere-demux
@@ -0,0 +1 @@
+CRC=0xc4faddaf
diff --git a/tests/ref/fate/noproxy b/tests/ref/fate/noproxy
new file mode 100644
index 0000000..7707609
--- /dev/null
+++ b/tests/ref/fate/noproxy
@@ -0,0 +1,9 @@
+The pattern "(null)" does not match the hostname domain.com
+The pattern "example.com domain.com" matches the hostname domain.com
+The pattern "example.com other.com" does not match the hostname domain.com
+The pattern "example.com,domain.com" matches the hostname domain.com
+The pattern "example.com,domain.com" does not match the hostname otherdomain.com
+The pattern "example.com, *.domain.com" matches the hostname sub.domain.com
+The pattern "example.com, *.domain.com" matches the hostname domain.com
+The pattern "example.com, .domain.com" matches the hostname domain.com
+The pattern "*" matches the hostname domain.com
diff --git a/tests/ref/fate/nuv-rtjpeg-fh b/tests/ref/fate/nuv-rtjpeg-fh
index 151ef88..b2e04cb 100644
--- a/tests/ref/fate/nuv-rtjpeg-fh
+++ b/tests/ref/fate/nuv-rtjpeg-fh
@@ -1,51 +1,51 @@
 #tb 0: 1/50
-0,          0,          0,        1,   221184, 0xf48c94f6
-0,          2,          2,        1,   221184, 0x89b625b2
-0,          3,          3,        1,   221184, 0x37e04714
-0,          4,          4,        1,   221184, 0x4f4c5224
-0,          5,          5,        1,   221184, 0x9193c9f1
-0,          6,          6,        1,   221184, 0x5d1a6197
-0,          7,          7,        1,   221184, 0x40cd51e7
-0,          8,          8,        1,   221184, 0xb2c1a729
-0,         10,         10,        1,   221184, 0x998d6144
-0,         11,         11,        1,   221184, 0xf5d52311
-0,         12,         12,        1,   221184, 0xea9dd6bf
-0,         13,         13,        1,   221184, 0x0e2ed854
-0,         14,         14,        1,   221184, 0xe295ba58
-0,         15,         15,        1,   221184, 0x8aedbb69
-0,         16,         16,        1,   221184, 0x253c9aaa
-0,         17,         17,        1,   221184, 0x5eaf9fb1
-0,         18,         18,        1,   221184, 0xcdb5a0cb
-0,         19,         19,        1,   221184, 0xcdb5a0cb
-0,         20,         20,        1,   221184, 0x23f89994
-0,         21,         21,        1,   221184, 0x23f89994
-0,         22,         22,        1,   221184, 0x10dc98d6
-0,         23,         23,        1,   221184, 0x799b9d98
-0,         24,         24,        1,   221184, 0xb226996c
-0,         25,         25,        1,   221184, 0x0ac59a42
-0,         26,         26,        1,   221184, 0x87c2a654
-0,         27,         27,        1,   221184, 0xf4c1a711
-0,         28,         28,        1,   221184, 0xf60fa72e
-0,         29,         29,        1,   221184, 0xc8f8b6fc
-0,         30,         30,        1,   221184, 0xd709b813
-0,         31,         31,        1,   221184, 0x5fdfb76b
-0,         32,         32,        1,   221184, 0x5798b0aa
-0,         33,         33,        1,   221184, 0xf572b1c3
-0,         34,         34,        1,   221184, 0x14b0afdf
-0,         35,         35,        1,   221184, 0x0a66b5b8
-0,         36,         36,        1,   221184, 0xe316c620
-0,         37,         37,        1,   221184, 0xbc76c5c2
-0,         38,         38,        1,   221184, 0x77c7c5e5
-0,         39,         39,        1,   221184, 0xfc7ac63e
-0,         40,         40,        1,   221184, 0x05a29ffe
-0,         41,         41,        1,   221184, 0x9bffbf6c
-0,         42,         42,        1,   221184, 0x3c55be40
-0,         43,         43,        1,   221184, 0x6f46c14e
-0,         44,         44,        1,   221184, 0x9cf4ae70
-0,         45,         45,        1,   221184, 0xf205b2f8
-0,         46,         46,        1,   221184, 0x7180aff8
-0,         47,         47,        1,   221184, 0x125eaffe
-0,         48,         48,        1,   221184, 0x6970a32d
-0,         49,         49,        1,   221184, 0xaea79f62
-0,         50,         50,        1,   221184, 0x48d2a093
-0,         51,         51,        1,   221184, 0x10a59eb5
+0,         80,         80,        1,   221184, 0xdaf54f83
+0,         82,         82,        1,   221184, 0xeea3e3b4
+0,         83,         83,        1,   221184, 0x5f1a8525
+0,         84,         84,        1,   221184, 0x950bb170
+0,         85,         85,        1,   221184, 0x6262e94c
+0,         86,         86,        1,   221184, 0x28752197
+0,         87,         87,        1,   221184, 0x0c2811e7
+0,         88,         88,        1,   221184, 0xb2c1a729
+0,         90,         90,        1,   221184, 0x998d6144
+0,         91,         91,        1,   221184, 0xf5d52311
+0,         92,         92,        1,   221184, 0xea9dd6bf
+0,         93,         93,        1,   221184, 0x0e2ed854
+0,         94,         94,        1,   221184, 0xe295ba58
+0,         95,         95,        1,   221184, 0x8aedbb69
+0,         96,         96,        1,   221184, 0x253c9aaa
+0,         97,         97,        1,   221184, 0x5eaf9fb1
+0,         98,         98,        1,   221184, 0xcdb5a0cb
+0,         99,         99,        1,   221184, 0xcdb5a0cb
+0,        100,        100,        1,   221184, 0x23f89994
+0,        101,        101,        1,   221184, 0x23f89994
+0,        102,        102,        1,   221184, 0x10dc98d6
+0,        103,        103,        1,   221184, 0x799b9d98
+0,        104,        104,        1,   221184, 0xb226996c
+0,        105,        105,        1,   221184, 0x0ac59a42
+0,        106,        106,        1,   221184, 0x87c2a654
+0,        107,        107,        1,   221184, 0xf4c1a711
+0,        108,        108,        1,   221184, 0xf60fa72e
+0,        109,        109,        1,   221184, 0xc8f8b6fc
+0,        110,        110,        1,   221184, 0xd709b813
+0,        111,        111,        1,   221184, 0x5fdfb76b
+0,        112,        112,        1,   221184, 0x5798b0aa
+0,        113,        113,        1,   221184, 0xf572b1c3
+0,        114,        114,        1,   221184, 0x14b0afdf
+0,        115,        115,        1,   221184, 0x0a66b5b8
+0,        116,        116,        1,   221184, 0xe316c620
+0,        117,        117,        1,   221184, 0xbc76c5c2
+0,        118,        118,        1,   221184, 0x77c7c5e5
+0,        119,        119,        1,   221184, 0xfc7ac63e
+0,        120,        120,        1,   221184, 0x05a29ffe
+0,        121,        121,        1,   221184, 0x9bffbf6c
+0,        122,        122,        1,   221184, 0x3c55be40
+0,        123,        123,        1,   221184, 0x6f46c14e
+0,        124,        124,        1,   221184, 0x9cf4ae70
+0,        125,        125,        1,   221184, 0xf205b2f8
+0,        126,        126,        1,   221184, 0x7180aff8
+0,        127,        127,        1,   221184, 0x125eaffe
+0,        128,        128,        1,   221184, 0x6970a32d
+0,        129,        129,        1,   221184, 0xaea79f62
+0,        130,        130,        1,   221184, 0x48d2a093
+0,        131,        131,        1,   221184, 0x10a59eb5
diff --git a/tests/ref/fate/options-force_key_frames b/tests/ref/fate/options-force_key_frames
deleted file mode 100644
index 1288624..0000000
--- a/tests/ref/fate/options-force_key_frames
+++ /dev/null
@@ -1,4 +0,0 @@
-5423335cd809e631a2e03f97585348e0 *tests/data/fate/options-force_key_frames.avi
-113308 tests/data/fate/options-force_key_frames.avi
-8f68ad2e602ecd87a3e0c097ba99d773 *tests/data/fate/options-force_key_frames.out.framecrc
-stddev:34363.01 PSNR:  5.61 MAXDIFF:56305 bytes:  7603200/      186
diff --git a/tests/ref/fate/parseutils b/tests/ref/fate/parseutils
index 36756a8..5fa3bf4e 100644
--- a/tests/ref/fate/parseutils
+++ b/tests/ref/fate/parseutils
@@ -79,4 +79,4 @@
 -1:23:45.67              ->           -5025670000
 42.1729                  ->             +42172900
 -1729.42                 ->           -1729420000
-12:34                    -> error
+12:34                    ->            +754000000
diff --git a/tests/ref/fate/rv30 b/tests/ref/fate/rv30
index df002d9..70db647 100644
--- a/tests/ref/fate/rv30
+++ b/tests/ref/fate/rv30
@@ -8,13 +8,13 @@
 0,          6,          6,        1,   126720, 0x5e6ff4d7
 0,          7,          7,        1,   126720, 0xcc10f4b7
 0,          8,          8,        1,   126720, 0x763ab817
-0,          9,          9,        1,   126720, 0xeb6fb8d7
-0,         10,         10,        1,   126720, 0xda71b917
-0,         11,         11,        1,   126720, 0x0967b8f7
+0,          9,          9,        1,   126720, 0xe95fb8d7
+0,         10,         10,        1,   126720, 0xe2b1b917
+0,         11,         11,        1,   126720, 0x11abb8f7
 0,         12,         12,        1,   126720, 0x4b62b947
-0,         13,         13,        1,   126720, 0xbb1abbb7
-0,         14,         14,        1,   126720, 0x273fbc37
-0,         15,         15,        1,   126720, 0x16eebbd7
+0,         13,         13,        1,   126720, 0xcaf2bbb7
+0,         14,         14,        1,   126720, 0x2953bc37
+0,         15,         15,        1,   126720, 0x1dd9bbd7
 0,         16,         16,        1,   126720, 0x105eb927
 0,         17,         17,        1,   126720, 0x7fa3ae27
 0,         18,         18,        1,   126720, 0x722e99f7
@@ -28,83 +28,83 @@
 0,         26,         26,        1,   126720, 0x6ddaef32
 0,         27,         27,        1,   126720, 0xde1bb900
 0,         28,         28,        1,   126720, 0xac6c071b
-0,         29,         29,        1,   126720, 0x04e7897c
-0,         30,         30,        1,   126720, 0x5eee050f
-0,         31,         31,        1,   126720, 0xe675be59
+0,         29,         29,        1,   126720, 0x4a9f897c
+0,         30,         30,        1,   126720, 0xd8fa050f
+0,         31,         31,        1,   126720, 0x5d06be59
 0,         32,         32,        1,   126720, 0xdc3e0837
-0,         33,         33,        1,   126720, 0x68cfda2b
-0,         34,         34,        1,   126720, 0xe572dfc9
-0,         35,         35,        1,   126720, 0x582fb176
+0,         33,         33,        1,   126720, 0xcac6da2b
+0,         34,         34,        1,   126720, 0x6672dfc9
+0,         35,         35,        1,   126720, 0x7491b176
 0,         36,         36,        1,   126720, 0xa9477df0
-0,         37,         37,        1,   126720, 0xbc3cc34f
-0,         38,         38,        1,   126720, 0xcf8cb0e2
-0,         39,         39,        1,   126720, 0xcff1db35
+0,         37,         37,        1,   126720, 0xe976c34f
+0,         38,         38,        1,   126720, 0xdb7ab0e2
+0,         39,         39,        1,   126720, 0x1b42db35
 0,         40,         40,        1,   126720, 0xc6e10f9f
-0,         41,         41,        1,   126720, 0x75ae61b6
-0,         42,         42,        1,   126720, 0x12af3119
-0,         43,         43,        1,   126720, 0x85597543
+0,         41,         41,        1,   126720, 0x169d61b6
+0,         42,         42,        1,   126720, 0xc7623119
+0,         43,         43,        1,   126720, 0x5b9b7543
 0,         44,         44,        1,   126720, 0x68c27aca
-0,         45,         45,        1,   126720, 0x554fe3e4
-0,         46,         46,        1,   126720, 0x72ecea95
-0,         47,         47,        1,   126720, 0xf4d003d1
-0,         48,         48,        1,   126720, 0x9bf6a605
-0,         49,         49,        1,   126720, 0x5d00b5fe
-0,         50,         50,        1,   126720, 0x93f7b040
-0,         51,         51,        1,   126720, 0x0d6ad154
-0,         52,         52,        1,   126720, 0x4be8b4ea
-0,         53,         53,        1,   126720, 0xe39bba0d
-0,         54,         54,        1,   126720, 0x9c21bad8
-0,         55,         55,        1,   126720, 0xa567f25b
-0,         56,         56,        1,   126720, 0x7a82663a
-0,         57,         57,        1,   126720, 0x72f2a47d
-0,         58,         58,        1,   126720, 0x4f639ebe
-0,         59,         59,        1,   126720, 0xab0fce83
-0,         60,         60,        1,   126720, 0x6cf87d39
-0,         61,         61,        1,   126720, 0x534a10cc
-0,         62,         62,        1,   126720, 0x6bbcf44c
-0,         63,         63,        1,   126720, 0xfdca11d3
-0,         64,         64,        1,   126720, 0x7e58f5a6
-0,         65,         65,        1,   126720, 0x5fd753d8
-0,         66,         66,        1,   126720, 0x0c735615
-0,         67,         67,        1,   126720, 0x2a034ebf
-0,         68,         68,        1,   126720, 0xeaf3dd0b
-0,         69,         69,        1,   126720, 0x0eaf0c1b
-0,         70,         70,        1,   126720, 0xce5e6794
-0,         71,         71,        1,   126720, 0xf27c31c3
-0,         72,         72,        1,   126720, 0xb64af168
-0,         73,         73,        1,   126720, 0x14cf7974
-0,         74,         74,        1,   126720, 0x1c2a513d
-0,         75,         75,        1,   126720, 0xa3f515ab
-0,         76,         76,        1,   126720, 0xcfd62765
-0,         77,         77,        1,   126720, 0xbc513f2a
-0,         78,         78,        1,   126720, 0xbc303fae
-0,         79,         79,        1,   126720, 0x2f8f69b9
-0,         80,         80,        1,   126720, 0x0a22cc69
-0,         81,         81,        1,   126720, 0xd9f67585
-0,         82,         82,        1,   126720, 0x20403001
-0,         83,         83,        1,   126720, 0xf92b2a25
-0,         84,         84,        1,   126720, 0x3c170aad
-0,         85,         85,        1,   126720, 0x3378251f
-0,         86,         86,        1,   126720, 0xb3ed5911
-0,         87,         87,        1,   126720, 0x35d24ef8
-0,         88,         88,        1,   126720, 0x8da30275
-0,         89,         89,        1,   126720, 0xc15a3577
-0,         90,         90,        1,   126720, 0xf2942f53
-0,         91,         91,        1,   126720, 0x44d8304a
-0,         92,         92,        1,   126720, 0xd688a932
-0,         93,         93,        1,   126720, 0x0a24f256
-0,         94,         94,        1,   126720, 0xfab9c45d
-0,         95,         95,        1,   126720, 0x10e939ce
-0,         96,         96,        1,   126720, 0x97fcaa3a
-0,         97,         97,        1,   126720, 0x45464610
-0,         98,         98,        1,   126720, 0xfe2e057d
-0,         99,         99,        1,   126720, 0x0b6718ae
-0,        100,        100,        1,   126720, 0x5284da7b
-0,        101,        101,        1,   126720, 0x23efdc35
-0,        102,        102,        1,   126720, 0xc387b2b3
-0,        103,        103,        1,   126720, 0xc9e92bf1
-0,        104,        104,        1,   126720, 0xfbf20a01
-0,        105,        105,        1,   126720, 0x4d888b2e
-0,        106,        106,        1,   126720, 0xdd0d74df
-0,        107,        107,        1,   126720, 0x49d07aa4
-0,        108,        108,        1,   126720, 0x08382b8e
+0,         45,         45,        1,   126720, 0xa0e4e1c9
+0,         46,         46,        1,   126720, 0xbbdae87e
+0,         47,         47,        1,   126720, 0xe67e00a1
+0,         48,         48,        1,   126720, 0x648ea605
+0,         49,         49,        1,   126720, 0x5becb718
+0,         50,         50,        1,   126720, 0xb79ab1da
+0,         51,         51,        1,   126720, 0x0d52d1dc
+0,         52,         52,        1,   126720, 0x1277b853
+0,         53,         53,        1,   126720, 0xc57cbc83
+0,         54,         54,        1,   126720, 0x2126bdc3
+0,         55,         55,        1,   126720, 0x4c1ef41f
+0,         56,         56,        1,   126720, 0x185f6a2c
+0,         57,         57,        1,   126720, 0xb2b5a7d3
+0,         58,         58,        1,   126720, 0x32d7a26d
+0,         59,         59,        1,   126720, 0x0bffd118
+0,         60,         60,        1,   126720, 0x2eed823a
+0,         61,         61,        1,   126720, 0xc4c0147c
+0,         62,         62,        1,   126720, 0x1f8bf8ac
+0,         63,         63,        1,   126720, 0xfcb715e8
+0,         64,         64,        1,   126720, 0xc3e9fa9c
+0,         65,         65,        1,   126720, 0x9ad8572c
+0,         66,         66,        1,   126720, 0x2800596d
+0,         67,         67,        1,   126720, 0x3caa5094
+0,         68,         68,        1,   126720, 0x6162e000
+0,         69,         69,        1,   126720, 0x18200f2c
+0,         70,         70,        1,   126720, 0x649e699f
+0,         71,         71,        1,   126720, 0x5f513367
+0,         72,         72,        1,   126720, 0x71fbf4a8
+0,         73,         73,        1,   126720, 0x5bff7b97
+0,         74,         74,        1,   126720, 0xbad453d4
+0,         75,         75,        1,   126720, 0x56e6161d
+0,         76,         76,        1,   126720, 0x524f2980
+0,         77,         77,        1,   126720, 0x0589405a
+0,         78,         78,        1,   126720, 0x5c264043
+0,         79,         79,        1,   126720, 0x2394696f
+0,         80,         80,        1,   126720, 0x1aa0cd15
+0,         81,         81,        1,   126720, 0xd6ec7840
+0,         82,         82,        1,   126720, 0xde5531f0
+0,         83,         83,        1,   126720, 0x03a42c3a
+0,         84,         84,        1,   126720, 0xbdee0efb
+0,         85,         85,        1,   126720, 0xa6012736
+0,         86,         86,        1,   126720, 0x448f5ae6
+0,         87,         87,        1,   126720, 0x8a2550c3
+0,         88,         88,        1,   126720, 0x143104e7
+0,         89,         89,        1,   126720, 0x75db363d
+0,         90,         90,        1,   126720, 0x906d2f9d
+0,         91,         91,        1,   126720, 0xfc7b30ab
+0,         92,         92,        1,   126720, 0xd3edaa62
+0,         93,         93,        1,   126720, 0x6267f3fc
+0,         94,         94,        1,   126720, 0x87b6c67f
+0,         95,         95,        1,   126720, 0x84da3b79
+0,         96,         96,        1,   126720, 0x72fbae15
+0,         97,         97,        1,   126720, 0xb8474a80
+0,         98,         98,        1,   126720, 0xbeae088b
+0,         99,         99,        1,   126720, 0x538b1a14
+0,        100,        100,        1,   126720, 0x07bbddcd
+0,        101,        101,        1,   126720, 0x807ddf8f
+0,        102,        102,        1,   126720, 0x325bb46d
+0,        103,        103,        1,   126720, 0xd80c2f2a
+0,        104,        104,        1,   126720, 0xfc1b0dec
+0,        105,        105,        1,   126720, 0x46068ebc
+0,        106,        106,        1,   126720, 0xcd987941
+0,        107,        107,        1,   126720, 0x52f37f2e
+0,        108,        108,        1,   126720, 0xc96931a2
diff --git a/tests/ref/fate/siff-demux b/tests/ref/fate/siff-demux
new file mode 100644
index 0000000..692e504
--- /dev/null
+++ b/tests/ref/fate/siff-demux
@@ -0,0 +1,112 @@
+#tb 0: 1/12
+#tb 1: 1/22050
+0,          0,          0,        1,    15152, 0x14fc0f1f
+1,          0,          0,    22050,    22050, 0xa7d60d27
+0,          1,          1,        1,    15344, 0x31614bd7
+0,          2,          2,        1,    15163, 0x88c46248
+0,          3,          3,        1,    15152, 0x43c9c0e6
+0,          4,          4,        1,    15341, 0x813f6f01
+0,          5,          5,        1,    15152, 0x7598d01c
+0,          6,          6,        1,    15152, 0x40b5cdb1
+0,          7,          7,        1,    15347, 0xe061c843
+0,          8,          8,        1,    15159, 0x2e3c2242
+0,          9,          9,        1,    15151, 0x7201abc5
+0,         10,         10,        1,    15346, 0xeb5a349e
+0,         11,         11,        1,    15154, 0xda9907c9
+0,         12,         12,        1,    15159, 0x8d4d63b0
+1,      22050,      22050,    22050,    22050, 0xeb11185c
+0,         13,         13,        1,    15337, 0xd988436d
+0,         14,         14,        1,    15162, 0x0b495da7
+0,         15,         15,        1,    15164, 0xd8837439
+0,         16,         16,        1,    15339, 0x7ad372cc
+0,         17,         17,        1,    15161, 0xc45d4590
+0,         18,         18,        1,    15159, 0x5bdd9801
+0,         19,         19,        1,    15335, 0x8e17c83e
+0,         20,         20,        1,    15160, 0x5cdbdc04
+0,         21,         21,        1,    15157, 0xf480a643
+0,         22,         22,        1,    15346, 0x0c61b206
+0,         23,         23,        1,    15160, 0x05d9acfd
+0,         24,         24,        1,    15158, 0xebdc3ac4
+1,      44100,      44100,    22050,    22050, 0xd6dc0e17
+0,         25,         25,        1,    15334, 0xb51fd1b9
+0,         26,         26,        1,    15152, 0x81f74e5c
+0,         27,         27,        1,    15161, 0xafeca32c
+0,         28,         28,        1,    15347, 0x8f5e5874
+0,         29,         29,        1,    15157, 0xdeff353c
+0,         30,         30,        1,    15160, 0x93a19aa0
+0,         31,         31,        1,    15347, 0x94224071
+0,         32,         32,        1,    15153, 0x9982aff5
+0,         33,         33,        1,    15164, 0x044bcf2b
+0,         34,         34,        1,    15347, 0x40aca6e9
+0,         35,         35,        1,    15160, 0xf820e2c7
+0,         36,         36,        1,    15154, 0x457832b5
+1,      66150,      66150,    22050,    22050, 0x020412c4
+0,         37,         37,        1,    15334, 0xbb1704f0
+0,         38,         38,        1,    15156, 0xc0672ed1
+0,         39,         39,        1,    15159, 0x9a82c7c1
+0,         40,         40,        1,    15338, 0x03857aae
+0,         41,         41,        1,    15158, 0xe6177548
+0,         42,         42,        1,    15159, 0xf8ecafc4
+0,         43,         43,        1,    15345, 0x0a10882e
+0,         44,         44,        1,    15161, 0xec4339fb
+0,         45,         45,        1,    15157, 0x071935a2
+0,         46,         46,        1,    15340, 0x68aad418
+0,         47,         47,        1,    15151, 0x891bc3fe
+0,         48,         48,        1,    15153, 0xf522e54c
+1,      88200,      88200,    22050,    22050, 0x5d9606ae
+0,         49,         49,        1,    15346, 0x5a018842
+0,         50,         50,        1,    15164, 0x6842ac50
+0,         51,         51,        1,    15156, 0x32369159
+0,         52,         52,        1,    15347, 0xf5be31aa
+0,         53,         53,        1,    15157, 0xd2da28bd
+0,         54,         54,        1,    15152, 0x389feda6
+0,         55,         55,        1,    15345, 0x69187603
+0,         56,         56,        1,    15154, 0x5dc60365
+0,         57,         57,        1,    15159, 0x8c811193
+0,         58,         58,        1,    15344, 0x3db4bf13
+0,         59,         59,        1,    15156, 0xf729ebe1
+0,         60,         60,        1,    15162, 0xf10a4ce5
+1,     110250,     110250,    22050,    22050, 0x08171bca
+0,         61,         61,        1,    15345, 0x749b0604
+0,         62,         62,        1,    15160, 0xfe3bbbce
+0,         63,         63,        1,    15160, 0x6dcc4b85
+0,         64,         64,        1,    15337, 0xab87dd97
+0,         65,         65,        1,    15163, 0x1ce60db8
+0,         66,         66,        1,    15164, 0xfc4a2002
+0,         67,         67,        1,    15345, 0x9108e072
+0,         68,         68,        1,    15153, 0x83fc9055
+0,         69,         69,        1,    15155, 0xa1101e1a
+0,         70,         70,        1,    15343, 0x6418f0e9
+0,         71,         71,        1,    15157, 0x8c743049
+0,         72,         72,        1,    15153, 0x9c0e33eb
+1,     132300,     132300,    22050,    22050, 0xd43b0cf9
+0,         73,         73,        1,    15337, 0x64bae0b6
+0,         74,         74,        1,    15162, 0x5f6b91d5
+0,         75,         75,        1,    15162, 0x44e5dd3d
+0,         76,         76,        1,    15342, 0x968dc44c
+0,         77,         77,        1,    15158, 0x0e706c4d
+0,         78,         78,        1,    15153, 0xa7d2199a
+0,         79,         79,        1,    15345, 0x834d0f2e
+0,         80,         80,        1,    15163, 0x3d5d38c3
+0,         81,         81,        1,    15151, 0xf7d49515
+0,         82,         82,        1,    15337, 0x5f362f2a
+0,         83,         83,        1,    15162, 0xea87d814
+0,         84,         84,        1,    15164, 0xeb0a2662
+1,     154350,     154350,    22050,    22050, 0x486d1bc2
+0,         85,         85,        1,    15340, 0x772109e6
+0,         86,         86,        1,    15156, 0x9459cda5
+0,         87,         87,        1,    15152, 0x4f174e2d
+0,         88,         88,        1,    15343, 0x10d42a59
+0,         89,         89,        1,    15162, 0xd65ec2ec
+0,         90,         90,        1,    15156, 0x1e382319
+0,         91,         91,        1,    15335, 0xec904c2a
+0,         92,         92,        1,    15161, 0x56d49e44
+0,         93,         93,        1,    15154, 0x51d02cd0
+0,         94,         94,        1,    15340, 0xec3e14ee
+0,         95,         95,        1,    15160, 0xe43b5305
+0,         96,         96,        1,    15156, 0x8f2876a5
+1,     176400,     176400,    22050,    22050, 0x5c5508d3
+0,         97,         97,        1,    15340, 0xb26a9059
+0,         98,         98,        1,    15156, 0xf9570ec0
+0,         99,         99,        1,    15151, 0x862ffa1f
+1,     198450,     198450,     1984,     1984, 0x9cb4dfb7
diff --git a/tests/ref/fate/srtp b/tests/ref/fate/srtp
new file mode 100644
index 0000000..687a59f
--- /dev/null
+++ b/tests/ref/fate/srtp
@@ -0,0 +1,12 @@
+80e0123412345678123456780102030405
+Decrypted content matches input
+Decrypted content matches input
+Decrypted content matches input
+81c90007123456788765432100000000000012340000069ec73069ba000001fd
+Decrypted content matches input
+Decrypted content matches input
+Decrypted content matches input
+80e0123412345678123456780102030405
+81c90007123456788765432100000000000012340000069ec73069ba000001fd
+80e0123412345678123456780102030405
+81c90007123456788765432100000000000012340000069ec73069ba000001fd
diff --git a/tests/ref/fate/sub-aqtitle b/tests/ref/fate/sub-aqtitle
new file mode 100644
index 0000000..f6900e7
--- /dev/null
+++ b/tests/ref/fate/sub-aqtitle
@@ -0,0 +1 @@
+e888e1354cd0968895ab89cb169fec31
diff --git a/tests/ref/fate/sub-charenc b/tests/ref/fate/sub-charenc
new file mode 100644
index 0000000..3c4825e
--- /dev/null
+++ b/tests/ref/fate/sub-charenc
@@ -0,0 +1 @@
+a39d7e299a8e25b4ffece0f8d64bf19e
diff --git a/tests/ref/fate/sub-microdvd b/tests/ref/fate/sub-microdvd
index 9fc10fb..2059989 100644
--- a/tests/ref/fate/sub-microdvd
+++ b/tests/ref/fate/sub-microdvd
@@ -1 +1 @@
-6356b8c53169aae6a20bce34d0f7be87
+35e133576aa3881d2de8dbf39a8d6df7
diff --git a/tests/ref/fate/sub-microdvd-remux b/tests/ref/fate/sub-microdvd-remux
new file mode 100644
index 0000000..24b5d3d
--- /dev/null
+++ b/tests/ref/fate/sub-microdvd-remux
@@ -0,0 +1 @@
+669e51e357f8a8bd060f2499149c2ded
diff --git a/tests/ref/fate/sub-mpl2 b/tests/ref/fate/sub-mpl2
new file mode 100644
index 0000000..8835dd2
--- /dev/null
+++ b/tests/ref/fate/sub-mpl2
@@ -0,0 +1 @@
+3c2fb62002aec3af16d83135a0e3b0fc
diff --git a/tests/ref/fate/sub-mpsub b/tests/ref/fate/sub-mpsub
new file mode 100644
index 0000000..4e36648
--- /dev/null
+++ b/tests/ref/fate/sub-mpsub
@@ -0,0 +1 @@
+2c5fafec41479e1d09a32f85e8927d03
diff --git a/tests/ref/fate/sub-mpsub-frames b/tests/ref/fate/sub-mpsub-frames
new file mode 100644
index 0000000..d5bb44e
--- /dev/null
+++ b/tests/ref/fate/sub-mpsub-frames
@@ -0,0 +1 @@
+cbe6e45848ef77e3080487a88b122104
diff --git a/tests/ref/fate/sub-pjs b/tests/ref/fate/sub-pjs
new file mode 100644
index 0000000..8b382e7
--- /dev/null
+++ b/tests/ref/fate/sub-pjs
@@ -0,0 +1 @@
+d044f6ffdee48e48efff072b33baee0a
diff --git a/tests/ref/fate/sub-subripenc b/tests/ref/fate/sub-subripenc
index 7daa4f5..9666e9b 100644
--- a/tests/ref/fate/sub-subripenc
+++ b/tests/ref/fate/sub-subripenc
@@ -1 +1 @@
-bd520f85238abf9df292374aed54681a
+b7cb0eeb34af0da364e29b238f0634ae
diff --git a/tests/ref/fate/sub-subviewer b/tests/ref/fate/sub-subviewer
index 3b5327f..abae1f7 100644
--- a/tests/ref/fate/sub-subviewer
+++ b/tests/ref/fate/sub-subviewer
@@ -1 +1 @@
-303c25863d2283928c19db58a53c93e2
+aef995d49af4517b40589b72cfa918f7
diff --git a/tests/ref/fate/sub-subviewer1 b/tests/ref/fate/sub-subviewer1
new file mode 100644
index 0000000..116fce7
--- /dev/null
+++ b/tests/ref/fate/sub-subviewer1
@@ -0,0 +1 @@
+0c2096fedf7c971742b2e879bb303ce9
diff --git a/tests/ref/fate/sub-vplayer b/tests/ref/fate/sub-vplayer
new file mode 100644
index 0000000..b8fc40e
--- /dev/null
+++ b/tests/ref/fate/sub-vplayer
@@ -0,0 +1 @@
+c8201c542f43a9ea42a787ac74d28049
diff --git a/tests/ref/fate/sub-webvtt b/tests/ref/fate/sub-webvtt
index 2e32e55..45cccde 100644
--- a/tests/ref/fate/sub-webvtt
+++ b/tests/ref/fate/sub-webvtt
@@ -1 +1 @@
-5384a70c89ddca4b007fb7ffba95cffb
+2cf38e2c99f8717f78a91a3f31197fb4
diff --git a/tests/ref/fate/sub2video b/tests/ref/fate/sub2video
new file mode 100644
index 0000000..f866c21
--- /dev/null
+++ b/tests/ref/fate/sub2video
@@ -0,0 +1,94 @@
+#tb 0: 1/5
+#tb 1: 1/1000
+0,          0,          0,        1,   518400, 0x46c47f38
+0,          1,          1,        1,   518400, 0xa814ca60
+0,          2,          2,        1,   518400, 0xa771e1af
+1,        499,        499,     4960,     1015, 0x19e092d2, F=0x0
+0,          3,          3,        1,   518400, 0x267abb76
+0,          4,          4,        1,   518400, 0x184ca91f
+0,          5,          5,        1,   518400, 0xc348bfee
+0,          6,          6,        1,   518400, 0x80451196
+0,          7,          7,        1,   518400, 0xfeb1781b
+0,          8,          8,        1,   518400, 0xa7e1b76c
+0,          9,          9,        1,   518400, 0x1fa10b77
+0,         10,         10,        1,   518400, 0xbbeaa20e
+0,         11,         11,        1,   518400, 0x5b5ba97f
+0,         12,         12,        1,   518400, 0xe189fbdd
+0,         13,         13,        1,   518400, 0xe143a932
+0,         14,         14,        1,   518400, 0x13f18190
+0,         15,         15,        1,   518400, 0x7eed3662
+0,         16,         16,        1,   518400, 0x2c79137b
+0,         17,         17,        1,   518400, 0xe08c0c5b
+0,         18,         18,        1,   518400, 0x87b62f9d
+0,         19,         19,        1,   518400, 0xe93d71ae
+0,         20,         20,        1,   518400, 0x3038eca5
+0,         21,         21,        1,   518400, 0xd77054bb
+0,         22,         22,        1,   518400, 0x077ca600
+0,         23,         23,        1,   518400, 0xf0ceba79
+0,         24,         24,        1,   518400, 0x4acb661d
+0,         25,         25,        1,   518400, 0xc28ae50a
+0,         26,         26,        1,   518400, 0xa5381dd1
+0,         27,         27,        1,   518400, 0x259f15e5
+0,         28,         28,        1,   518400, 0xe1487038
+0,         29,         29,        1,   518400, 0x7b5e5ec3
+0,         30,         30,        1,   518400, 0x6b638cee
+0,         31,         31,        1,   518400, 0x791da218
+0,         32,         32,        1,   518400, 0xd1e4980c
+0,         33,         33,        1,   518400, 0xce9aa6f8
+0,         34,         34,        1,   518400, 0x9abe6cac
+0,         35,         35,        1,   518400, 0xb472272a
+0,         36,         36,        1,   518400, 0x730bfc44
+0,         37,         37,        1,   518400, 0xf3e0b969
+0,         38,         38,        1,   518400, 0x96a77064
+0,         39,         39,        1,   518400, 0x16e94bf0
+0,         40,         40,        1,   518400, 0x0ba93871
+0,         41,         41,        1,   518400, 0x5e004779
+0,         42,         42,        1,   518400, 0xc87864d5
+0,         43,         43,        1,   518400, 0xa4b7c331
+0,         44,         44,        1,   518400, 0xb8ec424a
+0,         45,         45,        1,   518400, 0x4fa12b83
+0,         46,         46,        1,   518400, 0x55acfb38
+0,         47,         47,        1,   518400, 0xa4d66b64
+0,         48,         48,        1,   518400, 0xd4008e86
+0,         49,         49,        1,   518400, 0x88729869
+1,      15355,      15355,     4733,     2094, 0x3c171425, F=0x0
+1,      48797,      48797,     2560,     2480, 0x7c0edf21, F=0x0
+1,      51433,      51433,     2366,     3059, 0xc95b8a05, F=0x0
+1,      53919,      53919,     2696,     2095, 0x61bb15ed, F=0x0
+1,      56663,      56663,     1262,     1013, 0xc9ae89b7, F=0x0
+1,      58014,      58014,     1661,      969, 0xe01878f0, F=0x0
+1,      67724,      67724,     1365,      844, 0xe7db4fc1, F=0x0
+1,      69175,      69175,     1558,      802, 0xf48531ba, F=0x0
+1,      70819,      70819,     1865,     1709, 0xb4d5a1bd, F=0x0
+1,      72762,      72762,     1968,     2438, 0x99d7bc82, F=0x0
+1,      74806,      74806,     1831,     2116, 0x96514097, F=0x0
+1,      76716,      76716,     1262,     1822, 0xefccc72e, F=0x0
+1,      78051,      78051,     1524,      987, 0x7b927a27, F=0x0
+1,      79644,      79644,     2662,     2956, 0x190778f7, F=0x0
+1,      82380,      82380,     2764,     3094, 0xc021b7d3, F=0x0
+1,      85225,      85225,     2366,     2585, 0x74d0048f, F=0x0
+1,      87652,      87652,     1831,      634, 0x8832fda1, F=0x0
+1,      91531,      91531,     2332,     2080, 0x97a1146f, F=0x0
+1,      95510,      95510,     3299,     2964, 0x8b8f6684, F=0x0
+1,      98872,      98872,     2161,     1875, 0x9002ef71, F=0x0
+1,     101124,     101124,     4096,     3872, 0x20c6ed9c, F=0x0
+1,     105303,     105303,     2730,     3094, 0xf203a663, F=0x0
+1,     108106,     108106,     2059,     2404, 0x41a7b429, F=0x0
+1,     141556,     141556,     1661,     1088, 0xde20aa20, F=0x0
+1,     163445,     163445,     1331,      339, 0x8bd186ef, F=0x0
+1,     168049,     168049,     1900,     1312, 0x0bf20e8d, F=0x0
+1,     172203,     172203,     1695,     1826, 0x9a1ac769, F=0x0
+1,     173947,     173947,     1934,     1474, 0xa9b03cdc, F=0x0
+1,     175957,     175957,     1763,     1019, 0x20409355, F=0x0
+1,     189295,     189295,     1968,     1596, 0x408c726e, F=0x0
+1,     191356,     191356,     1228,     1517, 0xae8c5c2b, F=0x0
+1,     192640,     192640,     1763,     2506, 0xa458d6d4, F=0x0
+1,     195193,     195193,     1092,     1074, 0x397ba9a8, F=0x0
+1,     196369,     196369,     1524,     1715, 0x695ca41e, F=0x0
+1,     197946,     197946,     1160,      789, 0xc63a189e, F=0x0
+1,     199230,     199230,     1627,     1846, 0xeea8c599, F=0x0
+1,     200924,     200924,     1763,      922, 0xd4a87222, F=0x0
+1,     210600,     210600,     1831,      665, 0x55580135, F=0x0
+1,     214771,     214771,     1558,     1216, 0x50d1f6c5, F=0x0
+1,     225640,     225640,     2127,     2133, 0x670c11a5, F=0x0
+1,     227834,     227834,     1262,     1264, 0xc1d9fc57, F=0x0
diff --git a/tests/ref/fate/vp3-coeff-level64 b/tests/ref/fate/theora-coeff-level64
similarity index 100%
rename from tests/ref/fate/vp3-coeff-level64
rename to tests/ref/fate/theora-coeff-level64
diff --git a/tests/ref/fate/siff b/tests/ref/fate/vb
similarity index 91%
rename from tests/ref/fate/siff
rename to tests/ref/fate/vb
index 8cc6d7f..336d426 100644
--- a/tests/ref/fate/siff
+++ b/tests/ref/fate/vb
@@ -1,7 +1,5 @@
 #tb 0: 1/12
-#tb 1: 1/22050
 0,          0,          0,        1,   230400, 0x3bd1d731
-1,          0,          0,    22050,    44100, 0xd0a49e09
 0,          1,          1,        1,   230400, 0x9d0774c3
 0,          2,          2,        1,   230400, 0xa0faafe2
 0,          3,          3,        1,   230400, 0x38325309
@@ -14,7 +12,6 @@
 0,         10,         10,        1,   230400, 0xf52b8db4
 0,         11,         11,        1,   230400, 0x2b70c1dc
 0,         12,         12,        1,   230400, 0x8157a6e9
-1,      22050,      22050,    22050,    44100, 0xf151af4d
 0,         13,         13,        1,   230400, 0xd4a3c357
 0,         14,         14,        1,   230400, 0x703861bb
 0,         15,         15,        1,   230400, 0xa13cf75e
@@ -27,7 +24,6 @@
 0,         22,         22,        1,   230400, 0x0f5c8a0d
 0,         23,         23,        1,   230400, 0x3475df44
 0,         24,         24,        1,   230400, 0x65354e06
-1,      44100,      44100,    22050,    44100, 0xecd3cd08
 0,         25,         25,        1,   230400, 0xb9a01978
 0,         26,         26,        1,   230400, 0x15207ee1
 0,         27,         27,        1,   230400, 0x3b214f0b
diff --git a/tests/ref/fate/vc1_sa10143 b/tests/ref/fate/vc1_sa10143
index 0d2e697..6a5137f 100644
--- a/tests/ref/fate/vc1_sa10143
+++ b/tests/ref/fate/vc1_sa10143
@@ -1,31 +1,31 @@
 #tb 0: 1/25
 0,          0,          0,        1,   518400, 0x89407f55
-0,          2,          2,        1,   518400, 0x1480849d
+0,          2,          2,        1,   518400, 0x8611849c
 0,          3,          3,        1,   518400, 0x0e69ff59
-0,          4,          4,        1,   518400, 0x00d6db06
+0,          4,          4,        1,   518400, 0xf31adb03
 0,          5,          5,        1,   518400, 0x1a5b6a69
-0,          6,          6,        1,   518400, 0xc1a1232e
+0,          6,          6,        1,   518400, 0x6ae6232e
 0,          7,          7,        1,   518400, 0x9a4e3c54
-0,          8,          8,        1,   518400, 0x04122b44
+0,          8,          8,        1,   518400, 0xe5852b45
 0,          9,          9,        1,   518400, 0x0fcfeebc
-0,         10,         10,        1,   518400, 0xc7882dc1
+0,         10,         10,        1,   518400, 0x06e22dc3
 0,         11,         11,        1,   518400, 0x9d79df09
-0,         12,         12,        1,   518400, 0xff6b716f
+0,         12,         12,        1,   518400, 0xcb2c716f
 0,         13,         13,        1,   518400, 0x638a8746
-0,         14,         14,        1,   518400, 0x07572efb
+0,         14,         14,        1,   518400, 0xf7032efd
 0,         15,         15,        1,   518400, 0x306f6cef
-0,         16,         16,        1,   518400, 0xd7602518
+0,         16,         16,        1,   518400, 0xe83d2518
 0,         17,         17,        1,   518400, 0x49ab5bf5
-0,         18,         18,        1,   518400, 0x3c736b6c
+0,         18,         18,        1,   518400, 0x6b336b6f
 0,         19,         19,        1,   518400, 0x95ae00c9
-0,         20,         20,        1,   518400, 0x7b9ab64e
+0,         20,         20,        1,   518400, 0x68ddb64f
 0,         21,         21,        1,   518400, 0x5205ea68
-0,         22,         22,        1,   518400, 0xb486e618
+0,         22,         22,        1,   518400, 0xb088e617
 0,         23,         23,        1,   518400, 0xa3217616
-0,         24,         24,        1,   518400, 0xc66bbc56
+0,         24,         24,        1,   518400, 0x1723bc53
 0,         25,         25,        1,   518400, 0xf024872a
-0,         26,         26,        1,   518400, 0x97d2a8ba
+0,         26,         26,        1,   518400, 0x2e81a8bb
 0,         27,         27,        1,   518400, 0xa3a2418e
-0,         28,         28,        1,   518400, 0x08460005
+0,         28,         28,        1,   518400, 0xb7beffed
 0,         29,         29,        1,   518400, 0x50fb6c94
 0,         30,         30,        1,   518400, 0x5584bb40
diff --git a/tests/ref/fate/vp8-alpha b/tests/ref/fate/vp8-alpha
new file mode 100644
index 0000000..f857a87
--- /dev/null
+++ b/tests/ref/fate/vp8-alpha
@@ -0,0 +1,121 @@
+#tb 0: 1/1000
+0,          1,          1,        0,     2108, 0x59b92a34, S=1,     1900, 0x8fb3adc5
+0,         33,         33,        0,      142, 0x2f2a3fed, F=0x0, S=1,      160, 0xa13346af
+0,         66,         66,        0,      157, 0x17804767, F=0x0, S=1,      209, 0x64115f15
+0,        100,        100,        0,      206, 0x537262ca, F=0x0, S=1,      317, 0x44a09dd0
+0,        133,        133,        0,      259, 0x73ff74b6, F=0x0, S=1,      384, 0x2ee2c588
+0,        166,        166,        0,      320, 0x0fcf8ce4, F=0x0, S=1,      415, 0xff68c953
+0,        200,        200,        0,      377, 0x8fffb5f5, F=0x0, S=1,      475, 0x4166f3eb
+0,        233,        233,        0,      407, 0xe476c19e, F=0x0, S=1,      193, 0x3ff75489
+0,        266,        266,        0,      539, 0x90202334, F=0x0, S=1,      681, 0x776656b0
+0,        300,        300,        0,      560, 0xc6e2168d, F=0x0, S=1,      585, 0xddc81b8a
+0,        333,        333,        0,      597, 0x201a32a7, F=0x0, S=1,      574, 0x8baa1d65
+0,        366,        366,        0,      770, 0xab2b8891, F=0x0, S=1,      666, 0xcd8e51eb
+0,        400,        400,        0,      708, 0xc2386711, F=0x0, S=1,      706, 0x046b6444
+0,        433,        433,        0,      905, 0x7211c52d, F=0x0, S=1,      814, 0x5e288def
+0,        466,        466,        0,      770, 0xda4f8574, F=0x0, S=1,      829, 0xa0e8a949
+0,        500,        500,        0,      955, 0xf9a1d77a, F=0x0, S=1,      857, 0x9b63b955
+0,        533,        533,        0,      970, 0xff4de39a, F=0x0, S=1,      153, 0x3b00416c
+0,        566,        566,        0,      978, 0x12bcf81f, F=0x0, S=1,     1181, 0xce175555
+0,        600,        600,        0,     1233, 0x2903744a, F=0x0, S=1,      860, 0x737eb566
+0,        633,        633,        0,     1118, 0x7f274f50, F=0x0, S=1,      933, 0xb669c6b6
+0,        666,        666,        0,      941, 0x6bffd4b1, F=0x0, S=1,     1058, 0x07581cee
+0,        700,        700,        0,     1598, 0xc007219f, F=0x0, S=1,      939, 0x2c0bdc45
+0,        733,        733,        0,     1218, 0x25d962b6, F=0x0, S=1,     1090, 0x96482341
+0,        766,        766,        0,     1200, 0x86b85be3, F=0x0, S=1,      189, 0x3f085309
+0,        800,        800,        0,     1329, 0x298a848a, F=0x0, S=1,     1426, 0x6ea3df12
+0,        833,        833,        0,     1500, 0xe437edec, F=0x0, S=1,     1244, 0x32836b8d
+0,        866,        866,        0,     1288, 0xc4447dd5, F=0x0, S=1,     1289, 0x06a57b0f
+0,        900,        900,        0,     1281, 0xb5bf7e9f, F=0x0, S=1,     1227, 0xd96d5697
+0,        933,        933,        0,     1372, 0x09be9014, F=0x0, S=1,     1556, 0x2630fbff
+0,        966,        966,        0,     1238, 0x42ce6316, F=0x0, S=1,     1287, 0x1d3084f6
+0,       1000,       1000,        0,     1655, 0xb94b45c2, F=0x0, S=1,     1494, 0x34dbd1a4
+0,       1033,       1033,        0,     1164, 0xf6b93ad0, F=0x0, S=1,     1337, 0xba6d9673
+0,       1066,       1066,        0,     1084, 0x58c50fb5, F=0x0, S=1,     1384, 0x3fabb82b
+0,       1100,       1100,        0,     1151, 0x0b3f3359, F=0x0, S=1,     1353, 0x08e2a1d7
+0,       1133,       1133,        0,     1277, 0xa3ae77e1, F=0x0, S=1,     1409, 0xf65cb9f7
+0,       1166,       1166,        0,      782, 0xdcf671ff, F=0x0, S=1,     1408, 0x01e2ac53
+0,       1200,       1200,        0,      926, 0xe913c286, F=0x0, S=1,     1320, 0x32e38e42
+0,       1233,       1233,        0,      970, 0x3d86e5ae, F=0x0, S=1,     1608, 0x40b52618
+0,       1266,       1266,        0,     1353, 0xe4f197b2, F=0x0, S=1,     1272, 0xf1d272a5
+0,       1300,       1300,        0,      685, 0x629b4ce4, F=0x0, S=1,     1257, 0x14845de9
+0,       1333,       1333,        0,      743, 0x6f1172a3, F=0x0, S=1,     1260, 0xa6c66fda
+0,       1366,       1366,        0,      789, 0x94fc84cd, F=0x0, S=1,     1009, 0x7daaf2b0
+0,       1400,       1400,        0,     1460, 0x668adb82, F=0x0, S=1,      944, 0x44b6ccf5
+0,       1433,       1433,        0,      766, 0x49c884ef, F=0x0, S=1,      996, 0x8646e6dd
+0,       1466,       1466,        0,     1037, 0x24831498, F=0x0, S=1,      983, 0x14a9e7a6
+0,       1500,       1500,        0,      943, 0x1f53d180, F=0x0, S=1,     1107, 0x02f72acb
+0,       1533,       1533,        0,     1152, 0xbf6a35ae, F=0x0, S=1,     1026, 0xd57afda0
+0,       1566,       1566,        0,      730, 0x42806abf, F=0x0, S=1,     1029, 0xfb0402d5
+0,       1600,       1600,        0,      975, 0xa5ffec57, F=0x0, S=1,     1081, 0xe2890cea
+0,       1633,       1633,        0,      970, 0xbe8ee224, F=0x0, S=1,     1151, 0x7b0d3b20
+0,       1666,       1666,        0,     1012, 0x20c6f0d8, F=0x0, S=1,      979, 0xc25cd69c
+0,       1700,       1700,        0,      874, 0x1a2fb4da, F=0x0, S=1,      943, 0xdb2dc9f8
+0,       1733,       1733,        0,      869, 0xab0caf3d, F=0x0, S=1,      934, 0x48b9bfcc
+0,       1766,       1766,        0,      863, 0xd8caa2e5, F=0x0, S=1,      874, 0x0b34b026
+0,       1800,       1800,        0,     1246, 0x47866cdc, F=0x0, S=1,      818, 0x0c908eeb
+0,       1833,       1833,        0,      742, 0xa6296ac1, F=0x0, S=1,      921, 0x97b6b053
+0,       1866,       1866,        0,      828, 0x0b568d7a, F=0x0, S=1,      969, 0x3314dbfa
+0,       1900,       1900,        0,      825, 0x6d329394, F=0x0, S=1,      982, 0x5f66e68c
+0,       1933,       1933,        0,      836, 0x8ace8dfb, F=0x0, S=1,      929, 0x9ffdc2fd
+0,       1966,       1966,        0,     1774, 0xd4686726, F=0x0, S=1,      909, 0x11a9c07a
+0,       2000,       2000,        0,     1803, 0x08c879ce, F=0x0, S=1,     1525, 0x1e11f02f
+0,       2033,       2033,        0,      518, 0x7c32fc72, F=0x0, S=1,      785, 0xfc1f792a
+0,       2066,       2066,        0,      790, 0x3dac8aa0, F=0x0, S=1,      876, 0x0918c88d
+0,       2100,       2100,        0,      927, 0x4feccb24, F=0x0, S=1,     1059, 0xbcaa05c7
+0,       2133,       2133,        0,      835, 0x29d39266, F=0x0, S=1,      980, 0x4913e409
+0,       2166,       2166,        0,      951, 0xc1dddd12, F=0x0, S=1,     1041, 0x0541047e
+0,       2200,       2200,        0,      876, 0x2f6eb89d, F=0x0, S=1,      949, 0x2d56c53b
+0,       2233,       2233,        0,      959, 0xf0dedabd, F=0x0, S=1,     1022, 0x8d33f5fa
+0,       2266,       2266,        0,      860, 0x9274ab39, F=0x0, S=1,     1061, 0x289c0132
+0,       2300,       2300,        0,      863, 0x7058ba30, F=0x0, S=1,      940, 0x1f32d4a3
+0,       2333,       2333,        0,     1021, 0xcabdf84f, F=0x0, S=1,      887, 0xda8ab95e
+0,       2366,       2366,        0,      897, 0x9867c8e8, F=0x0, S=1,      840, 0xd93eaaf5
+0,       2400,       2400,        0,      897, 0x6a16b5db, F=0x0, S=1,      977, 0x7b77dc9b
+0,       2433,       2433,        0,      953, 0xe9b4cf1f, F=0x0, S=1,      921, 0x75a8ca45
+0,       2466,       2466,        0,      847, 0x0335ad37, F=0x0, S=1,     1000, 0x2691f3bd
+0,       2500,       2500,        0,      902, 0x3360b315, F=0x0, S=1,     1008, 0xd5e1deb6
+0,       2533,       2533,        0,      881, 0xf5309d59, F=0x0, S=1,     1113, 0xdbef3065
+0,       2566,       2566,        0,      974, 0x7c2de3ce, F=0x0, S=1,     1086, 0x365626bb
+0,       2600,       2600,        0,      974, 0xf42bd9f5, F=0x0, S=1,     1039, 0xa7e9060d
+0,       2633,       2633,        0,     1029, 0x7c33f4d0, F=0x0, S=1,     1041, 0xf4affa59
+0,       2666,       2666,        0,      881, 0x9021a565, F=0x0, S=1,     1039, 0xc1e00521
+0,       2700,       2700,        0,     1157, 0xe1c136f7, F=0x0, S=1,      917, 0x357ac7d3
+0,       2733,       2733,        0,      649, 0xdffb3cb7, F=0x0, S=1,      976, 0xa386e05e
+0,       2766,       2766,        0,      758, 0xb67875f3, F=0x0, S=1,     1041, 0xae4e0a63
+0,       2800,       2800,        0,     1105, 0x8ffb1a26, F=0x0, S=1,      962, 0x211ddc5e
+0,       2833,       2833,        0,      866, 0xa60eb2d9, F=0x0, S=1,      929, 0xe9e4c84b
+0,       2866,       2866,        0,      912, 0xcd34bf9b, F=0x0, S=1,      946, 0xfce9d359
+0,       2900,       2900,        0,      868, 0x5651a343, F=0x0, S=1,      809, 0x624a8ef9
+0,       2933,       2933,        0,      997, 0xfa66eaeb, F=0x0, S=1,      992, 0xc913e5e2
+0,       2966,       2966,        0,     1111, 0x3f272497, F=0x0, S=1,     1007, 0xf78ee6a7
+0,       3000,       3000,        0,      842, 0xe442999f, F=0x0, S=1,      972, 0x25a0d25c
+0,       3033,       3033,        0,     1030, 0x6f97ffad, F=0x0, S=1,      993, 0x4059fd6b
+0,       3066,       3066,        0,     1176, 0x66e64926, F=0x0, S=1,      951, 0x2762cdf1
+0,       3100,       3100,        0,      803, 0xfd1699cb, F=0x0, S=1,      959, 0x5cf9d56c
+0,       3133,       3133,        0,      972, 0x1cdff00e, F=0x0, S=1,     1023, 0xeaf20900
+0,       3166,       3166,        0,      907, 0x17f8acca, F=0x0, S=1,     1054, 0xeb010c4d
+0,       3200,       3200,        0,      915, 0x3569b545, F=0x0, S=1,      987, 0x73b2e159
+0,       3233,       3233,        0,     1021, 0x14c5076a, F=0x0, S=1,     1007, 0x6c4bf7f0
+0,       3266,       3266,        0,      837, 0xbf86b0ef, F=0x0, S=1,      963, 0xf472d31a
+0,       3300,       3300,        0,      885, 0x1caac123, F=0x0, S=1,     1052, 0x2b7bfd20
+0,       3333,       3333,        0,     1355, 0x299e8d3c, F=0x0, S=1,      858, 0x2bbca3f0
+0,       3366,       3366,        0,      784, 0xb0bd7e9d, F=0x0, S=1,      969, 0xc865dc00
+0,       3400,       3400,        0,      991, 0xbc7ddda9, F=0x0, S=1,     1028, 0x801b00a6
+0,       3433,       3433,        0,      986, 0xb356f6b1, F=0x0, S=1,     1056, 0x8b840add
+0,       3466,       3466,        0,      978, 0x94a3e87e, F=0x0, S=1,     1018, 0xe766fa52
+0,       3500,       3500,        0,      976, 0x55ddd14a, F=0x0, S=1,      992, 0x58a9ddfe
+0,       3533,       3533,        0,     1241, 0x1ec867f7, F=0x0, S=1,      966, 0xa329e84f
+0,       3566,       3566,        0,      975, 0xecf5dbb3, F=0x0, S=1,      899, 0xa7539f4d
+0,       3600,       3600,        0,     1129, 0xb7243037, F=0x0, S=1,     1057, 0xbd0d10bd
+0,       3633,       3633,        0,      913, 0xe5f1d03d, F=0x0, S=1,     1092, 0xeb9621f8
+0,       3666,       3666,        0,      943, 0x87d0ed78, F=0x0, S=1,     1057, 0x079c1054
+0,       3700,       3700,        0,      917, 0x536cc3fd, F=0x0, S=1,      946, 0xd2b9d0e2
+0,       3733,       3733,        0,      892, 0x4dffb1e2, F=0x0, S=1,      930, 0x70c9cc40
+0,       3766,       3766,        0,      957, 0x1a98e71c, F=0x0, S=1,      719, 0x6fec614a
+0,       3800,       3800,        0,      893, 0xf405b2c3, F=0x0, S=1,      821, 0x63529cab
+0,       3833,       3833,        0,      978, 0xa0a8d5f6, F=0x0, S=1,      745, 0x3c616219
+0,       3866,       3866,        0,      887, 0xfa7cb65d, F=0x0, S=1,      768, 0xb8f07885
+0,       3900,       3900,        0,      867, 0xd808ade7, F=0x0, S=1,      783, 0xf82b6b9a
+0,       3933,       3933,        0,     1068, 0x6f8b135a, F=0x0, S=1,      807, 0x52028d50
+0,       3966,       3966,        0,     2010, 0x536fe0b6, F=0x0, S=1,     1512, 0x690aeb55
diff --git a/tests/ref/fate/xxan-wc4 b/tests/ref/fate/xxan-wc4
index 34857bf..88dcc98 100644
--- a/tests/ref/fate/xxan-wc4
+++ b/tests/ref/fate/xxan-wc4
@@ -1,22 +1,22 @@
 #tb 0: 1/15
-0,          0,          0,        1,    79360, 0x3b0a7d1b
-0,          1,          1,        1,    79360, 0x740842c3
-0,          2,          2,        1,    79360, 0x85160167
-0,          3,          3,        1,    79360, 0xaf510e92
-0,          4,          4,        1,    79360, 0x8e290bec
-0,          5,          5,        1,    79360, 0x51e981b0
-0,          6,          6,        1,    79360, 0x16e52c60
-0,          7,          7,        1,    79360, 0x66e1e60a
-0,          8,          8,        1,    79360, 0x40fa58f6
-0,          9,          9,        1,    79360, 0x00388edd
-0,         10,         10,        1,    79360, 0xc74f95bf
-0,         11,         11,        1,    79360, 0xf446a3fd
-0,         12,         12,        1,    79360, 0x27b5eb60
-0,         13,         13,        1,    79360, 0xea9266a2
-0,         14,         14,        1,    79360, 0x7b6a7907
-0,         15,         15,        1,    79360, 0x2be7d946
-0,         16,         16,        1,    79360, 0x61881ee4
-0,         17,         17,        1,    79360, 0x9214bd4f
-0,         18,         18,        1,    79360, 0xeb294afe
-0,         19,         19,        1,    79360, 0xc861ad55
-0,         20,         20,        1,    79360, 0x3d3b6220
+0,          0,          0,        1,    79360, 0x8537821b
+0,          1,          1,        1,    79360, 0x110c4343
+0,          2,          2,        1,    79360, 0xa85105bb
+0,          3,          3,        1,    79360, 0x87431836
+0,          4,          4,        1,    79360, 0x5c701720
+0,          5,          5,        1,    79360, 0x20308ce4
+0,          6,          6,        1,    79360, 0xe51d3794
+0,          7,          7,        1,    79360, 0x80e6f1e0
+0,          8,          8,        1,    79360, 0x5aff64cc
+0,          9,          9,        1,    79360, 0x1a3d9ab3
+0,         10,         10,        1,    79360, 0xe154a195
+0,         11,         11,        1,    79360, 0x608dafdc
+0,         12,         12,        1,    79360, 0x93edf73f
+0,         13,         13,        1,    79360, 0x56d97281
+0,         14,         14,        1,    79360, 0xe7a284e6
+0,         15,         15,        1,    79360, 0xd4e5e513
+0,         16,         16,        1,    79360, 0x0a952ab1
+0,         17,         17,        1,    79360, 0x3b21c91c
+0,         18,         18,        1,    79360, 0x943656cb
+0,         19,         19,        1,    79360, 0xffbdb94b
+0,         20,         20,        1,    79360, 0x74976e16
diff --git a/tests/ref/fate/yop b/tests/ref/fate/yop
index 537447a..1920281 100644
--- a/tests/ref/fate/yop
+++ b/tests/ref/fate/yop
@@ -1,8 +1,7 @@
 #tb 0: 1/12
 0,          0,          0,        1,   302760, 0xf24dfa37
 0,          1,          1,        1,   302760, 0xcedcbb6c
-0,          2,          2,        1,   302760, 0x8c2d19a2
-0,          3,          3,        1,   302760, 0xe0fc92da
-0,          4,          4,        1,   302760, 0xd7699bb4
+0,          2,          2,        1,   302760, 0xc87716a2
+0,          3,          3,        1,   302760, 0x7e378e5a
+0,          4,          4,        1,   302760, 0xd4a19734
 0,          5,          5,        1,   302760, 0x26e93266
-0,          6,          6,        1,   302760, 0x4cddb216
diff --git a/tests/ref/fate/zerocodec b/tests/ref/fate/zerocodec
index 4d358ca..2d368c3 100644
--- a/tests/ref/fate/zerocodec
+++ b/tests/ref/fate/zerocodec
@@ -1,39 +1,39 @@
 #tb 0: 417083/10000000
-0,          0,          0,        1,  1843200, 0x09f24bd5
-0,          1,          1,        1,  1843200, 0x8c932d04
-0,          2,          2,        1,  1843200, 0xe04904a0
-0,          3,          3,        1,  1843200, 0x1969f383
-0,          4,          4,        1,  1843200, 0x70781331
-0,          5,          5,        1,  1843200, 0xf494496b
-0,          6,          6,        1,  1843200, 0xf6226da2
-0,          7,          7,        1,  1843200, 0x5d657925
-0,          8,          8,        1,  1843200, 0xde15820d
-0,          9,          9,        1,  1843200, 0xb6768df1
-0,         10,         10,        1,  1843200, 0xc4318e08
-0,         11,         11,        1,  1843200, 0x8530a7d5
-0,         12,         12,        1,  1843200, 0x0ee29f10
-0,         13,         13,        1,  1843200, 0xcbb6b185
-0,         14,         14,        1,  1843200, 0x085aac47
-0,         15,         15,        1,  1843200, 0xb42e7b1b
-0,         16,         16,        1,  1843200, 0xea3a2cd6
-0,         17,         17,        1,  1843200, 0x7600ee09
-0,         18,         18,        1,  1843200, 0xe39fc9d4
-0,         19,         19,        1,  1843200, 0xc122cd4c
-0,         20,         20,        1,  1843200, 0x5fb4c1cb
-0,         21,         21,        1,  1843200, 0x1552cb6c
-0,         22,         22,        1,  1843200, 0x5b66ce2f
-0,         23,         23,        1,  1843200, 0x70a8c318
-0,         24,         24,        1,  1843200, 0x8b86af2d
-0,         25,         25,        1,  1843200, 0x94886a49
-0,         26,         26,        1,  1843200, 0xda05684f
-0,         27,         27,        1,  1843200, 0xe57c8f33
-0,         28,         28,        1,  1843200, 0x39ef9c7e
-0,         29,         29,        1,  1843200, 0xe7a0cab8
-0,         30,         30,        1,  1843200, 0x43f0d766
-0,         31,         31,        1,  1843200, 0x733d3c7b
-0,         32,         32,        1,  1843200, 0x42713cea
-0,         33,         33,        1,  1843200, 0xdd844e53
-0,         34,         34,        1,  1843200, 0xa0875ba8
-0,         35,         35,        1,  1843200, 0x318b6114
-0,         36,         36,        1,  1843200, 0xcc986275
-0,         37,         37,        1,  1843200, 0x14eb6704
+0,          0,          0,        1,  1843200, 0x04154bd5
+0,          1,          1,        1,  1843200, 0x3a872d04
+0,          2,          2,        1,  1843200, 0x3b1304a0
+0,          3,          3,        1,  1843200, 0x7474f383
+0,          4,          4,        1,  1843200, 0xce7d1331
+0,          5,          5,        1,  1843200, 0x3cdf496b
+0,          6,          6,        1,  1843200, 0xe9096da2
+0,          7,          7,        1,  1843200, 0x30be7925
+0,          8,          8,        1,  1843200, 0x600b820d
+0,          9,          9,        1,  1843200, 0xe7bb8df1
+0,         10,         10,        1,  1843200, 0x62848e08
+0,         11,         11,        1,  1843200, 0x9a71a7d5
+0,         12,         12,        1,  1843200, 0x743a9f10
+0,         13,         13,        1,  1843200, 0x62b0b185
+0,         14,         14,        1,  1843200, 0xd94eac47
+0,         15,         15,        1,  1843200, 0xa1007b1b
+0,         16,         16,        1,  1843200, 0x11d72cd6
+0,         17,         17,        1,  1843200, 0x141aee09
+0,         18,         18,        1,  1843200, 0x9a90c9d4
+0,         19,         19,        1,  1843200, 0x6bd5cd4c
+0,         20,         20,        1,  1843200, 0xdf2ec1cb
+0,         21,         21,        1,  1843200, 0xeecbcb6c
+0,         22,         22,        1,  1843200, 0x9ecace2f
+0,         23,         23,        1,  1843200, 0x7b59c318
+0,         24,         24,        1,  1843200, 0x050baf2d
+0,         25,         25,        1,  1843200, 0xada36a49
+0,         26,         26,        1,  1843200, 0x4f4d684f
+0,         27,         27,        1,  1843200, 0x9ddc8f33
+0,         28,         28,        1,  1843200, 0x914d9c7e
+0,         29,         29,        1,  1843200, 0x0dc3cab8
+0,         30,         30,        1,  1843200, 0x98f8d766
+0,         31,         31,        1,  1843200, 0x872e3c7b
+0,         32,         32,        1,  1843200, 0xdf7b3cea
+0,         33,         33,        1,  1843200, 0xf7864e53
+0,         34,         34,        1,  1843200, 0x13315ba8
+0,         35,         35,        1,  1843200, 0xc4586114
+0,         36,         36,        1,  1843200, 0x57a96275
+0,         37,         37,        1,  1843200, 0x6e756704
diff --git a/tests/ref/lavf/aiff b/tests/ref/lavf/aiff
index e5d6fc3..2a5cd81 100644
--- a/tests/ref/lavf/aiff
+++ b/tests/ref/lavf/aiff
@@ -1,3 +1,3 @@
-379908755146d4ead062abe9c3b5c582 *./tests/data/lavf/lavf.aif
-90166 ./tests/data/lavf/lavf.aif
+b0d42747a6fc99a5cd1ab0e861671f3a *./tests/data/lavf/lavf.aif
+90182 ./tests/data/lavf/lavf.aif
 ./tests/data/lavf/lavf.aif CRC=0xf1ae5536
diff --git a/tests/ref/lavf/ast b/tests/ref/lavf/ast
new file mode 100644
index 0000000..72a9824
--- /dev/null
+++ b/tests/ref/lavf/ast
@@ -0,0 +1,3 @@
+7fa8cd2dd7453428e71930a7c65f7b62 *./tests/data/lavf/lavf.ast
+181696 ./tests/data/lavf/lavf.ast
+./tests/data/lavf/lavf.ast CRC=0x7bd585ff
diff --git a/tests/ref/lavf/dpx b/tests/ref/lavf/dpx
index 1196934..5961e00 100644
--- a/tests/ref/lavf/dpx
+++ b/tests/ref/lavf/dpx
@@ -5,5 +5,5 @@
 ./tests/data/images/dpx/%02d.dpx CRC=0xe5b9c023
 609920 ./tests/data/images/dpx/02.dpx
 13dc41b1e1e36399a5e1f8b7e3344a81 *./tests/data/images/dpx/02.dpx
-./tests/data/images/dpx/%02d.dpx CRC=0xf0a1c097
+./tests/data/images/dpx/%02d.dpx CRC=0xb6310a70
 407168 ./tests/data/images/dpx/02.dpx
diff --git a/tests/ref/lavf/dv_fmt b/tests/ref/lavf/dv_fmt
index e8720af..ed8c5cc 100644
--- a/tests/ref/lavf/dv_fmt
+++ b/tests/ref/lavf/dv_fmt
@@ -1,9 +1,9 @@
-6f9cfff48f536fa727696f2f9fb3ac08 *./tests/data/lavf/lavf.dv
+11be3e5caa2892236b3475c3f7807b76 *./tests/data/lavf/lavf.dv
 3600000 ./tests/data/lavf/lavf.dv
-./tests/data/lavf/lavf.dv CRC=0x5ce4e5e4
-2e8989478f05f6d4eaf1921fdfac4799 *./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=0x747caf33
+./tests/data/lavf/lavf.dv CRC=0x1cec8738
 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/gif b/tests/ref/lavf/gif
index 41d5018..509ea24 100644
--- a/tests/ref/lavf/gif
+++ b/tests/ref/lavf/gif
@@ -1,6 +1,6 @@
 e6089fd4ef3b9df44090ab3650bdd810 *./tests/data/lavf/lavf.gif
 2906401 ./tests/data/lavf/lavf.gif
-./tests/data/lavf/lavf.gif CRC=0xbf89a246
+./tests/data/lavf/lavf.gif CRC=0x9825d7c0
 022dc66b5068404e88c618ce79d9eb5f *./tests/data/images/gif/02.gif
 ./tests/data/images/gif/%02d.gif CRC=0x032e0034
 81538 ./tests/data/images/gif/02.gif
diff --git a/tests/ref/lavf/gxf b/tests/ref/lavf/gxf
index b242875..9e7871d 100644
--- a/tests/ref/lavf/gxf
+++ b/tests/ref/lavf/gxf
@@ -1,9 +1,9 @@
-72e150dc3430a6a78656790658eb9a09 *./tests/data/lavf/lavf.gxf
+c8b3a8e3ba0185ce39122ac150c12bc3 *./tests/data/lavf/lavf.gxf
 795876 ./tests/data/lavf/lavf.gxf
-./tests/data/lavf/lavf.gxf CRC=0xaee412d1
-cb6b1f522a9a8df145f55905c63a65b6 *./tests/data/lavf/lavf.gxf
-816752 ./tests/data/lavf/lavf.gxf
-./tests/data/lavf/lavf.gxf CRC=0xb73759d8
+./tests/data/lavf/lavf.gxf CRC=0x147ff044
+b26bd3cb439dff8b33cd74a27a3fc2d6 *./tests/data/lavf/lavf.gxf
+794656 ./tests/data/lavf/lavf.gxf
+./tests/data/lavf/lavf.gxf CRC=0xe0199511
 e4721383461d7a9feae41435567c9257 *./tests/data/lavf/lavf.gxf
 795876 ./tests/data/lavf/lavf.gxf
 ./tests/data/lavf/lavf.gxf CRC=0xd9d58865
diff --git a/tests/ref/lavf/ircam b/tests/ref/lavf/ircam
new file mode 100644
index 0000000..e29a7ad
--- /dev/null
+++ b/tests/ref/lavf/ircam
@@ -0,0 +1,3 @@
+2cfae025de1b13098ef84a5e7f9947aa *./tests/data/lavf/lavf.ircam
+91136 ./tests/data/lavf/lavf.ircam
+./tests/data/lavf/lavf.ircam CRC=0xf1ae5536
diff --git a/tests/ref/lavf/ismv b/tests/ref/lavf/ismv
index c6651b5..6f9f57b 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
 ./tests/data/lavf/lavf.ismv CRC=0x9d9a638a
-33d07ab6c5485d639e7052ccc73aeb70 *./tests/data/lavf/lavf.ismv
-331253 ./tests/data/lavf/lavf.ismv
-./tests/data/lavf/lavf.ismv CRC=0x2a63dc62
+1b98502911dd19a9792777de67922db2 *./tests/data/lavf/lavf.ismv
+321189 ./tests/data/lavf/lavf.ismv
+./tests/data/lavf/lavf.ismv CRC=0xe8130120
 a24a0426b5f8dc896daaf18502e38790 *./tests/data/lavf/lavf.ismv
 312263 ./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 d92aaa8..64979b2 100644
--- a/tests/ref/lavf/mkv
+++ b/tests/ref/lavf/mkv
@@ -1,3 +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
diff --git a/tests/ref/lavf/mmf b/tests/ref/lavf/mmf
index 8909784..fea8015 100644
--- a/tests/ref/lavf/mmf
+++ b/tests/ref/lavf/mmf
@@ -1,3 +1,3 @@
-1982e25aaa5307068c5e0f0fd54b193a *./tests/data/lavf/lavf.mmf
-22609 ./tests/data/lavf/lavf.mmf
+b165af6f2e5c6c1de733e9d3848bcebb *./tests/data/lavf/lavf.mmf
+22611 ./tests/data/lavf/lavf.mmf
 ./tests/data/lavf/lavf.mmf CRC=0x03633476
diff --git a/tests/ref/lavf/mov b/tests/ref/lavf/mov
index 4554ea6..2ed8ad0 100644
--- a/tests/ref/lavf/mov
+++ b/tests/ref/lavf/mov
@@ -4,9 +4,9 @@
 72eac0051107a16e41d5263dab640f26 *./tests/data/lavf/lavf.mov
 358455 ./tests/data/lavf/lavf.mov
 ./tests/data/lavf/lavf.mov CRC=0xb2f59ab4
-cbc587335946df1f08d838f48ef396f0 *./tests/data/lavf/lavf.mov
-377613 ./tests/data/lavf/lavf.mov
-./tests/data/lavf/lavf.mov CRC=0xc882139b
+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
diff --git a/tests/ref/lavf/mpg b/tests/ref/lavf/mpg
index c880fe6..798ee03 100644
--- a/tests/ref/lavf/mpg
+++ b/tests/ref/lavf/mpg
@@ -1,9 +1,9 @@
-bba1d30df5e8309c8eac70722014ad92 *./tests/data/lavf/lavf.mpg
+ddc5cd5469eb8a0500f8a725baead5e5 *./tests/data/lavf/lavf.mpg
 372736 ./tests/data/lavf/lavf.mpg
 ./tests/data/lavf/lavf.mpg CRC=0x5b136bb1
-f716380af800eb85112ba87c99845ac0 *./tests/data/lavf/lavf.mpg
-399360 ./tests/data/lavf/lavf.mpg
-./tests/data/lavf/lavf.mpg CRC=0xd21e5631
-e396acf92df0c0b8753f54a15b5770ae *./tests/data/lavf/lavf.mpg
+7962eab004026dd7a8c0417470cdf574 *./tests/data/lavf/lavf.mpg
+389120 ./tests/data/lavf/lavf.mpg
+./tests/data/lavf/lavf.mpg CRC=0xbbbf92bc
+bb22933de60193bce9032f67ce6fcc23 *./tests/data/lavf/lavf.mpg
 372736 ./tests/data/lavf/lavf.mpg
 ./tests/data/lavf/lavf.mpg CRC=0x5b136bb1
diff --git a/tests/ref/lavf/mxf b/tests/ref/lavf/mxf
index b489162..b1e46e9 100644
--- a/tests/ref/lavf/mxf
+++ b/tests/ref/lavf/mxf
@@ -1,9 +1,9 @@
-c53c9f7ee2091405fbe50374f9055679 *./tests/data/lavf/lavf.mxf
+967f6ee9223c865328f4891465191108 *./tests/data/lavf/lavf.mxf
 525369 ./tests/data/lavf/lavf.mxf
-./tests/data/lavf/lavf.mxf CRC=0x17ce1069
-14d0ac1513840b670a785daf4331aca8 *./tests/data/lavf/lavf.mxf
-554553 ./tests/data/lavf/lavf.mxf
-./tests/data/lavf/lavf.mxf CRC=0x468cdbc4
-5636cee18b0f34a5acb33a8efb9f80c6 *./tests/data/lavf/lavf.mxf
+./tests/data/lavf/lavf.mxf CRC=0xdbfff6f1
+7788939d349d09a7f9b546e59376a496 *./tests/data/lavf/lavf.mxf
+560697 ./tests/data/lavf/lavf.mxf
+./tests/data/lavf/lavf.mxf CRC=0xb69f428b
+ce535b606423d117675213b16275206a *./tests/data/lavf/lavf.mxf
 525369 ./tests/data/lavf/lavf.mxf
-./tests/data/lavf/lavf.mxf CRC=0x17ce1069
+./tests/data/lavf/lavf.mxf CRC=0xdbfff6f1
diff --git a/tests/ref/lavf/rm b/tests/ref/lavf/rm
index 2c05806..d396e00 100644
--- a/tests/ref/lavf/rm
+++ b/tests/ref/lavf/rm
@@ -1,2 +1,2 @@
-85ef42a1fdeffaf083d14b633bbd697f *./tests/data/lavf/lavf.rm
+a3a875be9c528a2a4534a5a31230fdae *./tests/data/lavf/lavf.rm
 346424 ./tests/data/lavf/lavf.rm
diff --git a/tests/ref/lavf/w64 b/tests/ref/lavf/w64
new file mode 100644
index 0000000..9acda83
--- /dev/null
+++ b/tests/ref/lavf/w64
@@ -0,0 +1,3 @@
+420bf38762386ae2ba8bf2e85b6cc7f2 *./tests/data/lavf/lavf.w64
+90224 ./tests/data/lavf/lavf.w64
+./tests/data/lavf/lavf.w64 CRC=0xf1ae5536
diff --git a/tests/ref/lavfi/field b/tests/ref/lavfi/field
index ec50dc1..68a4643 100644
--- a/tests/ref/lavfi/field
+++ b/tests/ref/lavfi/field
@@ -15,6 +15,15 @@
 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
 gray16be            a447af6482b922c9997ac02e5d3535f1
 gray16le            c1dd0db327295898ff282d07f48c105d
@@ -75,21 +84,21 @@
 yuv444p9le          e29799ecb6fac9f5b6d85bc34d248d4b
 yuva420p            82ab09bb7a3a24bf95aeb3fa9d939847
 yuva420p10be        f4559039e99ecf74a58e7063b1e7c5d3
-yuva420p10le        b1eb7df29134936450c2c312ae23a1a4
+yuva420p10le        32b3858b01be5bfe2579dadd1be3ab12
 yuva420p16be        c580495d34c6ac6e3e3b81772a0f3070
 yuva420p16le        1c49deeafb8f81e9186f3906c9b1a670
 yuva420p9be         a788d7cc6ad67ad52619a08da126569a
 yuva420p9le         c1579a5c015908f26b76480d82f6a648
 yuva422p            c162b37ce05360c47b2a2224ea0748ad
-yuva422p10be        6df70d1018e8c0c9fa377f72f49bf81b
-yuva422p10le        2eb54f20d3e5f180c539d92a75fe66e9
+yuva422p10be        b7c0adc12a8602ab8b40b611785cc18c
+yuva422p10le        97f91d820f8ba642a3f9ae0901d03826
 yuva422p16be        1c61492076be33404894c1d3ec578d87
 yuva422p16le        1c085c9479a57eea35e74c264c947d73
 yuva422p9be         271c6cc091052731373ef5313bc76435
 yuva422p9le         b8c2e963ac35371e8aa6a05d5c252b37
 yuva444p            4a85f1f17e95829cd53c9a28928fd8eb
-yuva444p10be        d312f0d30a88fdd18e992362ea3b5f81
-yuva444p10le        d12aed62a367bc7735e59503a3cf8cc6
+yuva444p10be        04c1026f4328ebf24bd7906291b33464
+yuva444p10le        3e8ea3b211bd7ac99cb96ebf71d0e75a
 yuva444p16be        ac5c17adeb0ef6730a0de1dbd1d14a1a
 yuva444p16le        41f1a82eb686d7191bdb00206f723247
 yuva444p9be         413d01385a8b008031b2ab3ef0b9eff4
diff --git a/tests/ref/lavfi/histeq b/tests/ref/lavfi/histeq
new file mode 100644
index 0000000..a250902
--- /dev/null
+++ b/tests/ref/lavfi/histeq
@@ -0,0 +1,6 @@
+abgr                a538e1221c94a12fb4e60b47b5358f67
+argb                d0ef008d603d67a6a7d698d2a8f53d6a
+bgr24               9ef3c69a658490c4fbc807272372e73a
+bgra                716e70fdf7413d9a3b83e0365c2b0a99
+rgb24               8423322bbc66bc5050f6b93fdab23433
+rgba                a960c9423bbb3925c3511362348b38e2
diff --git a/tests/ref/lavfi/il b/tests/ref/lavfi/il
new file mode 100644
index 0000000..d4a8142
--- /dev/null
+++ b/tests/ref/lavfi/il
@@ -0,0 +1,109 @@
+0bgr                b85afb77d7c3198ad7ff9ca5cceb970b
+0rgb                7ca2257e526092027c67311e273767bf
+abgr                4df961441de91db58f5a8a80603de585
+argb                db1e1e487a489674fbf260f56ac2705d
+bgr0                4335fb9738bb6ca5d6d39d738b934bbd
+bgr24               7446301030e6a26853aca2036309fa8a
+bgr444be            f80a44936b1295d14b0bac1db624d02e
+bgr444le            cfc1511a390f7ca18516540c31c097c3
+bgr48be             0b1084ac65d328552bd62b4e819ab91d
+bgr48le             04e4f510b6d586dc9082af43a59c0ede
+bgr4_byte           2dfd29e0705fbb2b590458028cb2939d
+bgr555be            5622aa808b389095658a203970bd6028
+bgr555le            6a5ad1e35cbacc45aeb9fd593c6f61ba
+bgr565be            5ff7a76d9f58800e38f21a84d88c7129
+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
+gray16be            cd9c1367dabd2f1858ae4f31693e622f
+gray16le            4ef774c282280d7ed4780690df6e5cb4
+monob               07cffe7f5f25f39c3aa38866303791c6
+monow               f2d1bdb939813a49abd6348ecfbb2703
+nv12                6847b3f7141ca1e3c40d3a494f0e13cb
+nv21                e7a8e94001151e2bdd68a0ee7e4ac544
+rgb0                0d1dfb1edc9b4a7ad28dde9a1b0bee23
+rgb24               15781da8615974ed12b18f7439a25d6f
+rgb444be            19bc79cdbafee996eb48feea597d761e
+rgb444le            de61209ae25f005d357b68e0836c4739
+rgb48be             fa24415175a0759ac49949a948820f27
+rgb48le             82d5d55b03dfd9a74f0cc087793cdfc6
+rgb4_byte           7ec4d55df1bfb02ffa9956d85ade89f7
+rgb555be            34ef691ed2b6d22136c086d37bb0fefd
+rgb555le            04b20c057eed7dcaee1858d45500ba54
+rgb565be            077604cc5dc91008b018264db73c8f0c
+rgb565le            a97549f25e63dd0dd404db41bbe05c07
+rgb8                a35d3c3b9b87261c7417076a8b18fdb8
+rgba                8ca9c8db589615ebbaa964be4ce62d08
+uyvy422             8be40aded4b407ff66305911ba5ce2ce
+yuv410p             92112d85ba4f74cbd3044945c0f33402
+yuv411p             b6b22000e5275c92baf5afc417c32a70
+yuv420p             fca7fbbff753612a718ee13e1dfe2af2
+yuv420p10be         15c655b60ff5d212657e0620ed69fadf
+yuv420p10le         c9c71c78e00034af1b0fdcfe68615c6f
+yuv420p12be         a5377d262bd05698b2bbcfc8dd2b15ea
+yuv420p12le         7d076ea30985ecf2eb590041a45f2cc6
+yuv420p14be         7a33da52fed0ffdc7f90ebcb677dc155
+yuv420p14le         f431bf16d8204fb919ba0abf4ea54288
+yuv420p16be         254b78ba00a928d22cba98380546fe9d
+yuv420p16le         e6c182b47c3b57814d28248dbbaaea35
+yuv420p9be          b1eafb2e864fa86c08684d8dd4628535
+yuv420p9le          f07b2282c50f8eb6f138029d748eadfe
+yuv422p             ffc2693b9e1d39b59aabb9a7e1dffe05
+yuv422p10be         e83db7f2f485bea0ea808f22ffcdb7bc
+yuv422p10le         bfd8fbeb5d89ba3904514d835aa6947d
+yuv422p12be         5f31197795eda7998a0ec813496e57f1
+yuv422p12le         903939621d457a034c0181032164b3c1
+yuv422p14be         8d08189d27d3a97fbecec7edd690c691
+yuv422p14le         01b717875b85707185acd48ac75dd6f9
+yuv422p16be         0feb24228cc5ec3963dc0bde913d14be
+yuv422p16le         0d6fe6924f14e77b2fef02e7ad1c47c8
+yuv422p9be          003b2032a30281845dfb6f9a7ebccc71
+yuv422p9le          427c505eb27af0059aeafffd1a858189
+yuv440p             23b55dcf6c876f0c53cf46960b13e6a3
+yuv444p             7730197c0570d46493d50bc163244754
+yuv444p10be         74b13f67114ac0f92af7bb427d6335ae
+yuv444p10le         9ab09ae4acc46a2fa04fdbde1373a9f9
+yuv444p12be         76320bae89f10947e692b6ce1fa22b93
+yuv444p12le         a79e40c464df640ba97c13456616b25c
+yuv444p14be         de7f737796d1de38a8227511b91d3378
+yuv444p14le         7c27d1b7846beb3565ce086c7df1131f
+yuv444p16be         1d51af32b9e077bf1ad750c6a1787b2c
+yuv444p16le         94a936f571861f25f2539ba099cafd56
+yuv444p9be          384dd0aa411d00b2deb2363a9f345db9
+yuv444p9le          77758bad5ca383b3a698fdcb38a85f20
+yuva420p            24337fc952d7f9c633756549a7b94146
+yuva420p10be        f586830e7605b5bbc307f6f5c532958c
+yuva420p10le        7bc9e81d18021dbb7c96ceeef4a18090
+yuva420p16be        54362c9d57d26ead878b9eb05a523785
+yuva420p16le        af55baa12d11c0ac6c9065df730d81ef
+yuva420p9be         a290f1b1e1fe18ac22fed3535562ff98
+yuva420p9le         89d0fa6679548757044c0e1971c1cbfd
+yuva422p            e3fe9f137a37e1b3817fe8579d2d2acc
+yuva422p10be        4aa77b690225054f9b5c7ce7c66950e8
+yuva422p10le        e7c6538112fc1d9539f4635dedf52eae
+yuva422p16be        0e5a1b0b52d42f4f07d7e63dbe4ab83b
+yuva422p16le        5b3a1219d7224650929e6272693f1cd3
+yuva422p9be         9d6f936fa9666e2bcbada5188e2a4942
+yuva422p9le         0f97c4d357e103e7263705b918a37824
+yuva444p            fe4dbba35f355d68b6c254c06db1cbad
+yuva444p10be        3926a29639556a11acc95888e29517d6
+yuva444p10le        1b68842a69b3b9d5a23854217b410c69
+yuva444p16be        45ec67a0828aedf18f1ed54fcfb0ff83
+yuva444p16le        7b8e5963f19e6fe7fd409b34af014489
+yuva444p9be         6d2905a9e61ce4ff5b3d7b972a7333eb
+yuva444p9le         e2ffdb1d867a1b78f3bd38d600b17193
+yuvj420p            d1a8d9cf6b4035ac5d6439ab2754b09d
+yuvj422p            d20df6138cdf62d7f3b93eb1277827d6
+yuvj440p            17a24a86f279febaebb66d65509088e8
+yuvj444p            326bb83d1aec23d941894a1324984c56
+yuyv422             f9121733169ca5437e95e7600a7c5aea
diff --git a/tests/ref/lavfi/kerndeint b/tests/ref/lavfi/kerndeint
new file mode 100644
index 0000000..2769319
--- /dev/null
+++ b/tests/ref/lavfi/kerndeint
@@ -0,0 +1,10 @@
+0bgr                58fb0bda60562ce17e75f1c3459d0504
+0rgb                d29f6a7b63ade359ec81f5856633ec06
+abgr                71071045b8ec66a6d0a38bb3fed1ca51
+argb                93ba0daa1e945ad1a6f8c0c1cd2e1858
+bgr0                364b8bcd1c7a384902077bc7190c5ea3
+bgra                81ac8315a4c66e363bc6fa3e99d9cd2b
+rgb0                ae0c2afbc266345c1372276755595105
+rgba                42a6cc9b815ca0ee69c29db3616ce25e
+yuv420p             40ca042814882b0b791cbec38e289702
+yuyv422             f549c98059ba9ce50e28204256d13b5d
diff --git a/tests/ref/lavfi/pixfmts_copy b/tests/ref/lavfi/pixfmts_copy
index 1171546..68ec828 100644
--- a/tests/ref/lavfi/pixfmts_copy
+++ b/tests/ref/lavfi/pixfmts_copy
@@ -15,6 +15,15 @@
 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
@@ -75,21 +84,21 @@
 yuv444p9le          4d12d20a68dc28618594c96c2ade4ff4
 yuva420p            3a8c5c142e051367c196f95696e0e2c3
 yuva420p10be        1b7c5ec6691498e24676ce6ed97f62f8
-yuva420p10le        ad2d0424033e7acbafa6d58f59b4487e
+yuva420p10le        4c13322bca914df2727da91cca85ca1a
 yuva420p16be        6afcf758f4b66c0b4173c942d42212d7
 yuva420p16le        13e195aa96329eb49921b6f9f07b875c
 yuva420p9be         05a78390de312dfd21ac666a9da05fbd
 yuva420p9le         78f5593bf51a31841ef83df41d0316eb
 yuva422p            45ae66d6f69fd5b77e6831e98d228bf4
-yuva422p10be        90ce250a517843b3e8a1ac0f4fdad733
-yuva422p10le        c74cfda8934e3bf86940b7a08c809b35
+yuva422p10be        18284c58b926fe2389605c692a703145
+yuva422p10le        b934d28b615729a24bebf0381c465e37
 yuva422p16be        c3f7354b6013b43439e02aa02be5fe69
 yuva422p16le        a7ccc43820683ab15061d14cf8efce6c
 yuva422p9be         14c55a16d19499b54b4341f135d3e558
 yuva422p9le         a8bf168e5d2709222192d0aff46b1373
 yuva444p            86b05da54db8c7e8cf5b6638e19c6fc5
-yuva444p10be        bea827ff82f229145a016954120b731f
-yuva444p10le        c51b0554cfba0fabacf979683dceee95
+yuva444p10be        8c417158165c00fbd42def60cbc27d69
+yuva444p10le        5f303ef3fb56faed69b4cc1c760ac6ae
 yuva444p16be        52a9591ec0d5059e49b1b2803f8582aa
 yuva444p16le        a9272ac197e4a4195662ce90f533976c
 yuva444p9be         f72f646ef07cdab613420585aba041ac
diff --git a/tests/ref/lavfi/pixfmts_hflip b/tests/ref/lavfi/pixfmts_hflip
index e696997..ee5c2d3 100644
--- a/tests/ref/lavfi/pixfmts_hflip
+++ b/tests/ref/lavfi/pixfmts_hflip
@@ -1,5 +1,8 @@
+0bgr                03d8a8920dbb408218376baee8665649
+0rgb                6ee5f3b85ec38953df0762ddd0bdf561
 abgr                8ab842e280c8b31f66450e8951dfedfa
 argb                cdb6aa47939d49c0ff72537bfc8c82e0
+bgr0                1b0b59382ddbbf045be6b160b7df5881
 bgr24               5b64fd60e2050946b50da1f4945127fb
 bgr444be            b52c1b9d9dc02cb46c04e80d97139e60
 bgr444le            48172797fa65a25c0ad30ddc7e8f5bcb
@@ -12,10 +15,22 @@
 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
 gray16be            d206a080739d89cb7dc0009ad4082ed4
 gray16le            7ebcfd9401ba85e584230de8fc02986d
+nv12                719adbc47fa74e92f83150921917483f
+nv21                9c833b3ce53539d270e1f21e4319797b
 pal8                19c8735b23feeed18ec2d37913a5f3f8
+rgb0                ce26538ebe1ec09dec3dde5e4d8a1405
 rgb24               c2752464ac2b549268e9638745dba857
 rgb444be            85586541cc7eb12e05ff7162b12304c2
 rgb444le            670da20b82403e00609bf2c1f5611223
@@ -31,16 +46,60 @@
 yuv410p             a1280c2b9b562dba3c2d35a1e5fc4b23
 yuv411p             6bf10756ac5c7841db63a97106ff911b
 yuv420p             45f4a06481f2cd8e28fb29c7c151e110
+yuv420p10be         ddfef981d53de0f808173bb267203ca6
+yuv420p10le         966b8c55de4d8a12bdc8db3d9ad3ae6d
+yuv420p12be         735da68f3ac8380a993f46a460c02432
+yuv420p12le         3a71ae4e6a7b106b3e1532c6d148fa61
+yuv420p14be         d921d7b364d0a7bde183ba717a77f1d4
+yuv420p14le         ab410b636acd41234cc396967f66c859
 yuv420p16be         cde798cad650bcb087943442a399c8ea
 yuv420p16le         b7124c56605eeb12f3d13287ddc77f3a
+yuv420p9be          b0f6044fb40cf0ef41cc536311566cc6
+yuv420p9le          086f9320167a755faed18c0a3a36c0e6
 yuv422p             c3982fbb57e796881efedae11b8346de
+yuv422p10be         a3db158525c7794fd06b4d20e558e64d
+yuv422p10le         31cf611e502584fcf846d3ba2583028a
+yuv422p12be         8cafc31b579b168a71f7093a161b8023
+yuv422p12le         be83ffe86cb99ecfef76affb2b73d5b2
+yuv422p14be         96870c66856e2669095ccdea034558ab
+yuv422p14le         46dcb0160aa8ada4025b365873a78d6c
 yuv422p16be         4b96fb571e686185d96b4a97e3413d5f
 yuv422p16le         503bc49bace58dae1767173746a16056
+yuv422p9be          0ffc1bfde0b679e6e7b7e0c8c84e686a
+yuv422p9le          3c061cdb9f302c8f8806b409bd2b0aca
 yuv440p             44f78792c5766ab896fbe0d718976946
 yuv444p             a36b8ce12de27971b52e93267fe6583f
+yuv444p10be         90e94770d3eb4693b09925f549d7311e
+yuv444p10le         8a26fba7c2223d72cd5ad00c1941948f
+yuv444p12be         24bdad5d7ddca614da7d105e931c49e8
+yuv444p12le         a996cb8a1c062d2238b58a5db9b990dd
+yuv444p14be         a9f7dd66b6f54bbdbf176894b01d7422
+yuv444p14le         6204f763af4a0d26f41ddca1d1ae9741
 yuv444p16be         9370058632b2582ab7a21725ec4f4e1d
 yuv444p16le         0674c63a0e8debbfc010a2730da66a13
+yuv444p9be          b1327e7ca47a950ee99bd2a7e05f56d0
+yuv444p9le          2f89171f0470eefa9f89fdc43874dc1d
 yuva420p            a62cf0a72905b54a7ef10fcaeff723bc
+yuva420p10be        602b6a8c0b16ce2b55ddcae443e75dac
+yuva420p10le        1c086d4ee0619ac65cb5a69481b981ca
+yuva420p16be        51c45f4227ba86159f46c65783d64cef
+yuva420p16le        e87030429a965f2ddc8f07ca49014573
+yuva420p9be         a48309403dc66dc5242cac19cc7598e5
+yuva420p9le         ae2dcb326eb3a2ff170f498077ae5624
+yuva422p            6e7c30ea252a41b70d26250f624ab284
+yuva422p10be        e0ee8576f9328ca4ec174a8c084f2235
+yuva422p10le        b489c203b9b0ebc42adb794bb10a3c4f
+yuva422p16be        550b1d2ecbc3d5f50041816090d62a02
+yuva422p16le        73a426eb63685247ea037389595cb43a
+yuva422p9be         c65251c422cd3c81ff5d97d207312292
+yuva422p9le         3405924773c6bdc42325a8a1ff658595
+yuva444p            e32ba5dcb01ba848e7dead04112b1aa5
+yuva444p10be        97549388c7f9fbc1425b1663b46c43d1
+yuva444p10le        0b88bed194caea2fa06f458034b1b90e
+yuva444p16be        2dd545e4ddb0f134322eee1c1de4c2ff
+yuva444p16le        1e144cc9ea16429c1655c67e2f12f5c9
+yuva444p9be         e37fa0743bf720fbe31605714d7f7ad6
+yuva444p9le         9bd4083c1384a55e91f02630161dc4c3
 yuvj420p            86370b945c5d19d809ee92386d476a53
 yuvj422p            d3bda08bd4b92a256a8ec8432c4767d1
 yuvj440p            dbae7083c82f20a38fc55e6f8bc374bc
diff --git a/tests/ref/lavfi/pixfmts_null b/tests/ref/lavfi/pixfmts_null
index 1171546..68ec828 100644
--- a/tests/ref/lavfi/pixfmts_null
+++ b/tests/ref/lavfi/pixfmts_null
@@ -15,6 +15,15 @@
 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
@@ -75,21 +84,21 @@
 yuv444p9le          4d12d20a68dc28618594c96c2ade4ff4
 yuva420p            3a8c5c142e051367c196f95696e0e2c3
 yuva420p10be        1b7c5ec6691498e24676ce6ed97f62f8
-yuva420p10le        ad2d0424033e7acbafa6d58f59b4487e
+yuva420p10le        4c13322bca914df2727da91cca85ca1a
 yuva420p16be        6afcf758f4b66c0b4173c942d42212d7
 yuva420p16le        13e195aa96329eb49921b6f9f07b875c
 yuva420p9be         05a78390de312dfd21ac666a9da05fbd
 yuva420p9le         78f5593bf51a31841ef83df41d0316eb
 yuva422p            45ae66d6f69fd5b77e6831e98d228bf4
-yuva422p10be        90ce250a517843b3e8a1ac0f4fdad733
-yuva422p10le        c74cfda8934e3bf86940b7a08c809b35
+yuva422p10be        18284c58b926fe2389605c692a703145
+yuva422p10le        b934d28b615729a24bebf0381c465e37
 yuva422p16be        c3f7354b6013b43439e02aa02be5fe69
 yuva422p16le        a7ccc43820683ab15061d14cf8efce6c
 yuva422p9be         14c55a16d19499b54b4341f135d3e558
 yuva422p9le         a8bf168e5d2709222192d0aff46b1373
 yuva444p            86b05da54db8c7e8cf5b6638e19c6fc5
-yuva444p10be        bea827ff82f229145a016954120b731f
-yuva444p10le        c51b0554cfba0fabacf979683dceee95
+yuva444p10be        8c417158165c00fbd42def60cbc27d69
+yuva444p10le        5f303ef3fb56faed69b4cc1c760ac6ae
 yuva444p16be        52a9591ec0d5059e49b1b2803f8582aa
 yuva444p16le        a9272ac197e4a4195662ce90f533976c
 yuva444p9be         f72f646ef07cdab613420585aba041ac
diff --git a/tests/ref/lavfi/pixfmts_pad b/tests/ref/lavfi/pixfmts_pad
index 9c31974..192ff6a 100644
--- a/tests/ref/lavfi/pixfmts_pad
+++ b/tests/ref/lavfi/pixfmts_pad
@@ -5,6 +5,7 @@
 bgr0                c55368036cccbb0af471d6bd82abe02a
 bgr24               67f9fd70dc6d9896b7122976b33932b4
 bgra                c8dd017b5a3b55e8b9d0ac1cdcf327bd
+gbrp                74f83deee9866bbdce3f91fa2aeddaaa
 gray                b1abadae3718522aa57a7972da8cbe17
 rgb0                b1977b45634c4db58a183a07feb2acff
 rgb24               e73de9dc0fdd78f4853c168603cc7aba
diff --git a/tests/ref/lavfi/pixfmts_pixdesctest b/tests/ref/lavfi/pixfmts_pixdesctest
index 1057c41..05d5e0f 100644
--- a/tests/ref/lavfi/pixfmts_pixdesctest
+++ b/tests/ref/lavfi/pixfmts_pixdesctest
@@ -15,6 +15,15 @@
 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
@@ -75,21 +84,21 @@
 yuv444p9le          4d12d20a68dc28618594c96c2ade4ff4
 yuva420p            3a8c5c142e051367c196f95696e0e2c3
 yuva420p10be        1b7c5ec6691498e24676ce6ed97f62f8
-yuva420p10le        ad2d0424033e7acbafa6d58f59b4487e
+yuva420p10le        4c13322bca914df2727da91cca85ca1a
 yuva420p16be        6afcf758f4b66c0b4173c942d42212d7
 yuva420p16le        13e195aa96329eb49921b6f9f07b875c
 yuva420p9be         05a78390de312dfd21ac666a9da05fbd
 yuva420p9le         78f5593bf51a31841ef83df41d0316eb
 yuva422p            45ae66d6f69fd5b77e6831e98d228bf4
-yuva422p10be        90ce250a517843b3e8a1ac0f4fdad733
-yuva422p10le        c74cfda8934e3bf86940b7a08c809b35
+yuva422p10be        18284c58b926fe2389605c692a703145
+yuva422p10le        b934d28b615729a24bebf0381c465e37
 yuva422p16be        c3f7354b6013b43439e02aa02be5fe69
 yuva422p16le        a7ccc43820683ab15061d14cf8efce6c
 yuva422p9be         14c55a16d19499b54b4341f135d3e558
 yuva422p9le         a8bf168e5d2709222192d0aff46b1373
 yuva444p            86b05da54db8c7e8cf5b6638e19c6fc5
-yuva444p10be        bea827ff82f229145a016954120b731f
-yuva444p10le        c51b0554cfba0fabacf979683dceee95
+yuva444p10be        8c417158165c00fbd42def60cbc27d69
+yuva444p10le        5f303ef3fb56faed69b4cc1c760ac6ae
 yuva444p16be        52a9591ec0d5059e49b1b2803f8582aa
 yuva444p16le        a9272ac197e4a4195662ce90f533976c
 yuva444p9be         f72f646ef07cdab613420585aba041ac
diff --git a/tests/ref/lavfi/pixfmts_scale b/tests/ref/lavfi/pixfmts_scale
index 825dc3a..9bc3ced 100644
--- a/tests/ref/lavfi/pixfmts_scale
+++ b/tests/ref/lavfi/pixfmts_scale
@@ -15,6 +15,15 @@
 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
 gray16be            70064f9acdc5e3935ccda67e765bf2fb
 gray16le            578241fb43029e5ae841a3c94d940dce
@@ -75,21 +84,21 @@
 yuv444p9le          693b8d30958ef1a37296b1690b4b36d2
 yuva420p            df46b738bdaf30d3a7f880b5ae45b092
 yuva420p10be        8e5f3b069fdf2f0c14f49ad827991092
-yuva420p10le        e6915376ad7d0f2be9d50099e5ee33ef
+yuva420p10le        ce4ac1961e0466c40448353cf76b3282
 yuva420p16be        aa8ca29a93936c62ef038ca8a57f47d7
 yuva420p16le        ee0cbb31f9cdb897c1982df0caa8ffa0
 yuva420p9be         b8ca5603123aeb953b9d4fc8ec8e35e1
 yuva420p9le         220212a81cda0f2d112f7ae96d532ff9
 yuva422p            650755270debb03d2c03b2e93b64c576
-yuva422p10be        fe0d8c2509d2d23f856093f9aea83cba
-yuva422p10le        c641064c6306c6eaf95b387e5ae08d67
+yuva422p10be        8d077362542a73c72aadb885510ea0c7
+yuva422p10le        80f729d9f8f438d2ab87909797c27873
 yuva422p16be        0b8f9385498d2449b18fb15237b0a448
 yuva422p16le        ce22b20deb93b4846a5043aa104f22d1
 yuva422p9be         822df465d12916d8852340d6b56247c8
 yuva422p9le         f69c09e872838fe392dfe1825263d3f1
 yuva444p            72083e0941cc45af9f97b89d3cd16112
-yuva444p10be        d8b6fe8cfb60c6e516563c0a4f5c75a8
-yuva444p10le        4a85b717f21975216144efc11e2f2cda
+yuva444p10be        42e159c62771239fa14d06a2db3b357d
+yuva444p10le        ee9786aee055c39da2dfbdb91ab834b5
 yuva444p16be        36a8797545163c24fc0d73f669c3108c
 yuva444p16le        c017c229aacb832a12c2297fb080a7a0
 yuva444p9be         8bfb5decfc8b71478b090a5b48c316c3
diff --git a/tests/ref/lavfi/pixfmts_vflip b/tests/ref/lavfi/pixfmts_vflip
index 1d5d1bd..7990c3e 100644
--- a/tests/ref/lavfi/pixfmts_vflip
+++ b/tests/ref/lavfi/pixfmts_vflip
@@ -15,6 +15,15 @@
 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
 gray16be            9b23f3e79c54a6ccb62e0135a32e3045
 gray16le            93cfa8fbb2a86ead275ce1817444e6d5
@@ -75,21 +84,21 @@
 yuv444p9le          e43ba2026848ec803fabf74d77c10125
 yuva420p            dc8fd115eaf203a3eac351b92a7d8f18
 yuva420p10be        b3aaa8a5c9b9c3c9d66053159af3ec99
-yuva420p10le        f43a991e8b5fe7e192cf4e0dfee2b6cb
+yuva420p10le        f7a8ae85fcac45db1f1689a1ab7cc63e
 yuva420p16be        b5c54895e87521f65a298d33bab5eb08
 yuva420p16le        95e208bc6644e23a2126ac5fca085f06
 yuva420p9be         1ba55d16f060bf54698dd7200523b44f
 yuva420p9le         4b57b8bd1534743f6740502c74bef385
 yuva422p            6091f9c62a121c09eadb02e9173b2da2
-yuva422p10be        93b6afb2b1d1538b1c87caa040c43f4e
-yuva422p10le        1c9359025ab8d257f0f5296e6b5a5787
+yuva422p10be        a6e8352978f263ea89e63ad06a9339b1
+yuva422p10le        ee39cfa1d29c294dc096f739bf454478
 yuva422p16be        3fa019b3d5e6dcb7c8e338837b9cffe1
 yuva422p16le        871f244989e14f5d3eda45abb6b3dfd1
 yuva422p9be         923c816778f782ff8a56bcd1b14ef08d
 yuva422p9le         bd882d40af0369d9ef7891c8e7891024
 yuva444p            9a55e83047abcc7a709f20805070135e
-yuva444p10be        7ae88f488969b527c1348383c0d06ade
-yuva444p10le        79a8dab388eb4d6cd12949b456ef5975
+yuva444p10be        6258901ef2ddfdb526a1038d92e8b63c
+yuva444p10le        24b8ef0f63e60f0f0a4d47a5870ad773
 yuva444p16be        4699a802e8ea3e74e968122980c0b0b0
 yuva444p16le        6f54a8cff38c54a235b92a0f1314e0aa
 yuva444p9be         7472bb4b0c774d5d741035086d5e4330
diff --git a/tests/ref/lavfi/pp b/tests/ref/lavfi/pp
index bfa86ef..1f7efef 100644
--- a/tests/ref/lavfi/pp
+++ b/tests/ref/lavfi/pp
@@ -1 +1 @@
-pp                  8e68fb247880aa083e91bcbddf9d76c7
+pp                  62a6acf1969155f29249fd0757540f9f
diff --git a/tests/ref/lavfi/pp2 b/tests/ref/lavfi/pp2
index 819d4e4..b32bd1a 100644
--- a/tests/ref/lavfi/pp2
+++ b/tests/ref/lavfi/pp2
@@ -1 +1 @@
-pp2                 28e91376aeb49c79dae9221b1a4997ae
+pp2                 efcfe545df8f869e3a93ae25a3e08967
diff --git a/tests/ref/lavfi/pp3 b/tests/ref/lavfi/pp3
index 2956375..ccf2eeb 100644
--- a/tests/ref/lavfi/pp3
+++ b/tests/ref/lavfi/pp3
@@ -1 +1 @@
-pp3                 d8d19c1f5e3f4032e9ed7bbb2026f030
+pp3                 39af1a30d0ea0e906df264773adfcaa6
diff --git a/tests/ref/seek/lavf-aiff b/tests/ref/seek/lavf-aiff
index 784b144..eb9ada0 100644
--- a/tests/ref/seek/lavf-aiff
+++ b/tests/ref/seek/lavf-aiff
@@ -1,53 +1,53 @@
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     54 size:  4096
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     70 size:  4096
 ret: 0         st:-1 flags:0  ts:-1.000000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     54 size:  4096
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     70 size:  4096
 ret: 0         st:-1 flags:1  ts: 1.894167
 ret:-EOF
 ret: 0         st: 0 flags:0  ts: 0.788345
-ret: 0         st: 0 flags:1 dts: 0.788345 pts: 0.788345 pos:  69586 size:  4096
+ret: 0         st: 0 flags:1 dts: 0.788345 pts: 0.788345 pos:  69602 size:  4096
 ret: 0         st: 0 flags:1  ts:-0.317506
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     54 size:  4096
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     70 size:  4096
 ret: 0         st:-1 flags:0  ts: 2.576668
 ret:-EOF
 ret: 0         st:-1 flags:1  ts: 1.470835
 ret:-EOF
 ret: 0         st: 0 flags:0  ts: 0.365011
-ret: 0         st: 0 flags:1 dts: 0.365011 pts: 0.365011 pos:  32248 size:  4096
+ret: 0         st: 0 flags:1 dts: 0.365011 pts: 0.365011 pos:  32264 size:  4096
 ret: 0         st: 0 flags:1  ts:-0.740839
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     54 size:  4096
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     70 size:  4096
 ret: 0         st:-1 flags:0  ts: 2.153336
 ret:-EOF
 ret: 0         st:-1 flags:1  ts: 1.047503
 ret:-EOF
 ret: 0         st: 0 flags:0  ts:-0.058322
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     54 size:  4096
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     70 size:  4096
 ret: 0         st: 0 flags:1  ts: 2.835828
 ret:-EOF
 ret: 0         st:-1 flags:0  ts: 1.730004
 ret:-EOF
 ret: 0         st:-1 flags:1  ts: 0.624171
-ret: 0         st: 0 flags:1 dts: 0.624172 pts: 0.624172 pos:  55106 size:  4096
+ret: 0         st: 0 flags:1 dts: 0.624172 pts: 0.624172 pos:  55122 size:  4096
 ret: 0         st: 0 flags:0  ts:-0.481655
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     54 size:  4096
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     70 size:  4096
 ret: 0         st: 0 flags:1  ts: 2.412494
 ret:-EOF
 ret: 0         st:-1 flags:0  ts: 1.306672
 ret:-EOF
 ret: 0         st:-1 flags:1  ts: 0.200839
-ret: 0         st: 0 flags:1 dts: 0.200839 pts: 0.200839 pos:  17768 size:  4096
+ret: 0         st: 0 flags:1 dts: 0.200839 pts: 0.200839 pos:  17784 size:  4096
 ret: 0         st: 0 flags:0  ts:-0.904989
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     54 size:  4096
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     70 size:  4096
 ret: 0         st: 0 flags:1  ts: 1.989184
 ret:-EOF
 ret: 0         st:-1 flags:0  ts: 0.883340
-ret: 0         st: 0 flags:1 dts: 0.883333 pts: 0.883333 pos:  77964 size:  4096
+ret: 0         st: 0 flags:1 dts: 0.883333 pts: 0.883333 pos:  77980 size:  4096
 ret: 0         st:-1 flags:1  ts:-0.222493
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     54 size:  4096
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     70 size:  4096
 ret: 0         st: 0 flags:0  ts: 2.671678
 ret:-EOF
 ret: 0         st: 0 flags:1  ts: 1.565850
 ret:-EOF
 ret: 0         st:-1 flags:0  ts: 0.460008
-ret: 0         st: 0 flags:1 dts: 0.460000 pts: 0.460000 pos:  40626 size:  4096
+ret: 0         st: 0 flags:1 dts: 0.460000 pts: 0.460000 pos:  40642 size:  4096
 ret: 0         st:-1 flags:1  ts:-0.645825
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     54 size:  4096
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     70 size:  4096
diff --git a/tests/ref/seek/lavf-bmp b/tests/ref/seek/lavf-bmp
index d60729b..0f0b152 100644
--- a/tests/ref/seek/lavf-bmp
+++ b/tests/ref/seek/lavf-bmp
@@ -5,7 +5,8 @@
 ret:-EINVAL    st: 0 flags:1  ts:-0.320000
 ret:-EINVAL    st:-1 flags:0  ts: 2.576668
 ret:-EINVAL    st:-1 flags:1  ts: 1.470835
-ret:-EINVAL    st: 0 flags:0  ts: 0.360000
+ret: 0         st: 0 flags:0  ts: 0.360000
+ret: 0         st: 0 flags:1 dts: 0.360000 pts: 0.360000 pos:     -1 size:304182
 ret:-EINVAL    st: 0 flags:1  ts:-0.760000
 ret:-EINVAL    st:-1 flags:0  ts: 2.153336
 ret:-EINVAL    st:-1 flags:1  ts: 1.047503
@@ -16,12 +17,14 @@
 ret:-EINVAL    st: 0 flags:0  ts:-0.480000
 ret:-EINVAL    st: 0 flags:1  ts: 2.400000
 ret:-EINVAL    st:-1 flags:0  ts: 1.306672
-ret:-EINVAL    st:-1 flags:1  ts: 0.200839
+ret: 0         st:-1 flags:1  ts: 0.200839
+ret: 0         st: 0 flags:1 dts: 0.200000 pts: 0.200000 pos:     -1 size:304182
 ret:-EINVAL    st: 0 flags:0  ts:-0.920000
 ret:-EINVAL    st: 0 flags:1  ts: 2.000000
 ret:-EINVAL    st:-1 flags:0  ts: 0.883340
 ret:-EINVAL    st:-1 flags:1  ts:-0.222493
 ret:-EINVAL    st: 0 flags:0  ts: 2.680000
 ret:-EINVAL    st: 0 flags:1  ts: 1.560000
-ret:-EINVAL    st:-1 flags:0  ts: 0.460008
+ret: 0         st:-1 flags:0  ts: 0.460008
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:     -1 size:304182
 ret:-EINVAL    st:-1 flags:1  ts:-0.645825
diff --git a/tests/ref/seek/lavf-jpg b/tests/ref/seek/lavf-jpg
index 88964ca..4f3a14c 100644
--- a/tests/ref/seek/lavf-jpg
+++ b/tests/ref/seek/lavf-jpg
@@ -5,7 +5,8 @@
 ret:-EINVAL    st: 0 flags:1  ts:-0.320000
 ret:-EINVAL    st:-1 flags:0  ts: 2.576668
 ret:-EINVAL    st:-1 flags:1  ts: 1.470835
-ret:-EINVAL    st: 0 flags:0  ts: 0.360000
+ret: 0         st: 0 flags:0  ts: 0.360000
+ret: 0         st: 0 flags:1 dts: 0.360000 pts: 0.360000 pos:     -1 size: 27771
 ret:-EINVAL    st: 0 flags:1  ts:-0.760000
 ret:-EINVAL    st:-1 flags:0  ts: 2.153336
 ret:-EINVAL    st:-1 flags:1  ts: 1.047503
@@ -16,12 +17,14 @@
 ret:-EINVAL    st: 0 flags:0  ts:-0.480000
 ret:-EINVAL    st: 0 flags:1  ts: 2.400000
 ret:-EINVAL    st:-1 flags:0  ts: 1.306672
-ret:-EINVAL    st:-1 flags:1  ts: 0.200839
+ret: 0         st:-1 flags:1  ts: 0.200839
+ret: 0         st: 0 flags:1 dts: 0.200000 pts: 0.200000 pos:     -1 size: 28197
 ret:-EINVAL    st: 0 flags:0  ts:-0.920000
 ret:-EINVAL    st: 0 flags:1  ts: 2.000000
 ret:-EINVAL    st:-1 flags:0  ts: 0.883340
 ret:-EINVAL    st:-1 flags:1  ts:-0.222493
 ret:-EINVAL    st: 0 flags:0  ts: 2.680000
 ret:-EINVAL    st: 0 flags:1  ts: 1.560000
-ret:-EINVAL    st:-1 flags:0  ts: 0.460008
+ret: 0         st:-1 flags:0  ts: 0.460008
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:     -1 size: 27950
 ret:-EINVAL    st:-1 flags:1  ts:-0.645825
diff --git a/tests/ref/seek/lavf-mmf b/tests/ref/seek/lavf-mmf
index b7fd5f5..0bc98fa 100644
--- a/tests/ref/seek/lavf-mmf
+++ b/tests/ref/seek/lavf-mmf
@@ -1,27 +1,44 @@
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     81 size:  4096
-ret:-1         st:-1 flags:0  ts:-1.000000
-ret:-1         st:-1 flags:1  ts: 1.894167
-ret:-1         st: 0 flags:0  ts: 0.788345
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     83 size:  4096
+ret: 0         st:-1 flags:0  ts:-1.000000
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     83 size:  4096
+ret: 0         st:-1 flags:1  ts: 1.894167
+ret: 0         st: 0 flags:1 dts: 0.928798 pts: 0.928798 pos:  20563 size:  2048
+ret: 0         st: 0 flags:0  ts: 0.788345
+ret: 0         st: 0 flags:1 dts: 0.928798 pts: 0.928798 pos:  20563 size:  2048
 ret:-1         st: 0 flags:1  ts:-0.317506
 ret:-1         st:-1 flags:0  ts: 2.576668
-ret:-1         st:-1 flags:1  ts: 1.470835
-ret:-1         st: 0 flags:0  ts: 0.365011
+ret: 0         st:-1 flags:1  ts: 1.470835
+ret: 0         st: 0 flags:1 dts: 0.928798 pts: 0.928798 pos:  20563 size:  2048
+ret: 0         st: 0 flags:0  ts: 0.365011
+ret: 0         st: 0 flags:1 dts: 0.371519 pts: 0.371519 pos:   8275 size:  4096
 ret:-1         st: 0 flags:1  ts:-0.740839
 ret:-1         st:-1 flags:0  ts: 2.153336
-ret:-1         st:-1 flags:1  ts: 1.047503
-ret:-1         st: 0 flags:0  ts:-0.058322
-ret:-1         st: 0 flags:1  ts: 2.835828
+ret: 0         st:-1 flags:1  ts: 1.047503
+ret: 0         st: 0 flags:1 dts: 0.928798 pts: 0.928798 pos:  20563 size:  2048
+ret: 0         st: 0 flags:0  ts:-0.058322
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     83 size:  4096
+ret: 0         st: 0 flags:1  ts: 2.835828
+ret: 0         st: 0 flags:1 dts: 0.928798 pts: 0.928798 pos:  20563 size:  2048
 ret:-1         st:-1 flags:0  ts: 1.730004
-ret:-1         st:-1 flags:1  ts: 0.624171
-ret:-1         st: 0 flags:0  ts:-0.481655
-ret:-1         st: 0 flags:1  ts: 2.412494
+ret: 0         st:-1 flags:1  ts: 0.624171
+ret: 0         st: 0 flags:1 dts: 0.557279 pts: 0.557279 pos:  12371 size:  4096
+ret: 0         st: 0 flags:0  ts:-0.481655
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     83 size:  4096
+ret: 0         st: 0 flags:1  ts: 2.412494
+ret: 0         st: 0 flags:1 dts: 0.928798 pts: 0.928798 pos:  20563 size:  2048
 ret:-1         st:-1 flags:0  ts: 1.306672
-ret:-1         st:-1 flags:1  ts: 0.200839
-ret:-1         st: 0 flags:0  ts:-0.904989
-ret:-1         st: 0 flags:1  ts: 1.989184
-ret:-1         st:-1 flags:0  ts: 0.883340
+ret: 0         st:-1 flags:1  ts: 0.200839
+ret: 0         st: 0 flags:1 dts: 0.185760 pts: 0.185760 pos:   4179 size:  4096
+ret: 0         st: 0 flags:0  ts:-0.904989
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     83 size:  4096
+ret: 0         st: 0 flags:1  ts: 1.989184
+ret: 0         st: 0 flags:1 dts: 0.928798 pts: 0.928798 pos:  20563 size:  2048
+ret: 0         st:-1 flags:0  ts: 0.883340
+ret: 0         st: 0 flags:1 dts: 0.928798 pts: 0.928798 pos:  20563 size:  2048
 ret:-1         st:-1 flags:1  ts:-0.222493
 ret:-1         st: 0 flags:0  ts: 2.671678
-ret:-1         st: 0 flags:1  ts: 1.565850
-ret:-1         st:-1 flags:0  ts: 0.460008
+ret: 0         st: 0 flags:1  ts: 1.565850
+ret: 0         st: 0 flags:1 dts: 0.928798 pts: 0.928798 pos:  20563 size:  2048
+ret: 0         st:-1 flags:0  ts: 0.460008
+ret: 0         st: 0 flags:1 dts: 0.557279 pts: 0.557279 pos:  12371 size:  4096
 ret:-1         st:-1 flags:1  ts:-0.645825
diff --git a/tests/ref/seek/lavf-mpg b/tests/ref/seek/lavf-mpg
index 935eae1..e804b84 100644
--- a/tests/ref/seek/lavf-mpg
+++ b/tests/ref/seek/lavf-mpg
@@ -1,53 +1,53 @@
-ret: 0         st: 1 flags:1 dts: 0.989089 pts: 0.989089 pos:   2048 size:   208
+ret: 0         st: 1 flags:1 dts: 0.529089 pts: 0.529089 pos:   2048 size:   208
 ret: 0         st:-1 flags:0  ts:-1.000000
-ret: 0         st: 1 flags:1 dts: 0.989089 pts: 0.989089 pos:   2048 size:   208
+ret: 0         st: 1 flags:1 dts: 0.529089 pts: 0.529089 pos:   2048 size:   208
 ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 0 flags:0 dts: 1.880000 pts: 1.920000 pos: 327680 size: 12629
+ret: 0         st: 1 flags:1 dts: 1.051544 pts: 1.051544 pos: 342028 size:   314
 ret: 0         st: 0 flags:0  ts: 0.788333
-ret: 0         st: 1 flags:1 dts: 0.989089 pts: 0.989089 pos:   2048 size:   208
+ret: 0         st: 0 flags:0 dts: 0.820000 pts: 0.860000 pos: 118784 size: 14717
 ret: 0         st: 0 flags:1  ts:-0.317500
-ret: 0         st: 1 flags:1 dts: 0.989089 pts: 0.989089 pos:   2048 size:   208
+ret: 0         st: 1 flags:1 dts: 0.529089 pts: 0.529089 pos:   2048 size:   208
 ret: 0         st: 1 flags:0  ts: 2.576667
-ret: 0         st: 1 flags:1 dts: 1.772767 pts: 1.772767 pos: 368652 size:   379
+ret: 0         st: 1 flags:1 dts: 1.312767 pts: 1.312767 pos: 368652 size:   379
 ret: 0         st: 1 flags:1  ts: 1.470833
-ret: 0         st: 1 flags:1 dts: 1.250322 pts: 1.250322 pos: 145408 size:   261
+ret: 0         st: 1 flags:1 dts: 1.312767 pts: 1.312767 pos: 368652 size:   379
 ret: 0         st:-1 flags:0  ts: 0.365002
-ret: 0         st: 1 flags:1 dts: 0.989089 pts: 0.989089 pos:   2048 size:   208
+ret: 0         st: 1 flags:1 dts: 0.529089 pts: 0.529089 pos:   2048 size:   208
 ret: 0         st:-1 flags:1  ts:-0.740831
-ret: 0         st: 1 flags:1 dts: 0.989089 pts: 0.989089 pos:   2048 size:   208
+ret: 0         st: 1 flags:1 dts: 0.529089 pts: 0.529089 pos:   2048 size:   208
 ret: 0         st: 0 flags:0  ts: 2.153333
-ret: 0         st: 1 flags:1 dts: 1.511544 pts: 1.511544 pos: 342028 size:   314
+ret: 0         st: 1 flags:1 dts: 1.051544 pts: 1.051544 pos: 342028 size:   314
 ret: 0         st: 0 flags:1  ts: 1.047500
-ret: 0         st: 0 flags:0 dts: 1.040000 pts: 1.080000 pos:  40960 size: 16073
+ret: 0         st: 0 flags:0 dts: 1.020000 pts: 1.060000 pos: 196608 size: 17639
 ret: 0         st: 1 flags:0  ts:-0.058333
-ret: 0         st: 1 flags:1 dts: 0.989089 pts: 0.989089 pos:   2048 size:   208
+ret: 0         st: 1 flags:1 dts: 0.529089 pts: 0.529089 pos:   2048 size:   208
 ret: 0         st: 1 flags:1  ts: 2.835833
-ret: 0         st: 1 flags:1 dts: 1.772767 pts: 1.772767 pos: 368652 size:   379
+ret: 0         st: 1 flags:1 dts: 1.312767 pts: 1.312767 pos: 368652 size:   379
 ret: 0         st:-1 flags:0  ts: 1.730004
-ret: 0         st: 0 flags:0 dts: 1.760000 pts: 1.800000 pos: 292864 size: 12894
+ret: 0         st: 1 flags:1 dts: 1.051544 pts: 1.051544 pos: 342028 size:   314
 ret: 0         st:-1 flags:1  ts: 0.624171
-ret: 0         st: 1 flags:1 dts: 0.989089 pts: 0.989089 pos:   2048 size:   208
+ret: 0         st: 0 flags:0 dts: 0.620000 pts: 0.660000 pos:  55296 size: 14239
 ret: 0         st: 0 flags:0  ts:-0.481667
-ret: 0         st: 1 flags:1 dts: 0.989089 pts: 0.989089 pos:   2048 size:   208
+ret: 0         st: 1 flags:1 dts: 0.529089 pts: 0.529089 pos:   2048 size:   208
 ret: 0         st: 0 flags:1  ts: 2.412500
-ret: 0         st: 1 flags:1 dts: 1.511544 pts: 1.511544 pos: 342028 size:   314
+ret: 0         st: 1 flags:1 dts: 1.051544 pts: 1.051544 pos: 342028 size:   314
 ret: 0         st: 1 flags:0  ts: 1.306667
-ret: 0         st: 1 flags:1 dts: 1.511544 pts: 1.511544 pos: 342028 size:   314
+ret: 0         st: 1 flags:1 dts: 1.312767 pts: 1.312767 pos: 368652 size:   379
 ret: 0         st: 1 flags:1  ts: 0.200844
-ret: 0         st: 1 flags:1 dts: 0.989089 pts: 0.989089 pos:   2048 size:   208
+ret: 0         st: 1 flags:1 dts: 0.529089 pts: 0.529089 pos:   2048 size:   208
 ret: 0         st:-1 flags:0  ts:-0.904994
-ret: 0         st: 1 flags:1 dts: 0.989089 pts: 0.989089 pos:   2048 size:   208
+ret: 0         st: 1 flags:1 dts: 0.529089 pts: 0.529089 pos:   2048 size:   208
 ret: 0         st:-1 flags:1  ts: 1.989173
-ret: 0         st: 1 flags:1 dts: 1.511544 pts: 1.511544 pos: 342028 size:   314
+ret: 0         st: 1 flags:1 dts: 1.051544 pts: 1.051544 pos: 342028 size:   314
 ret: 0         st: 0 flags:0  ts: 0.883344
-ret: 0         st: 1 flags:1 dts: 0.989089 pts: 0.989089 pos:   2048 size:   208
+ret: 0         st: 0 flags:0 dts: 0.900000 pts: 0.940000 pos: 147456 size: 12755
 ret: 0         st: 0 flags:1  ts:-0.222489
-ret: 0         st: 1 flags:1 dts: 0.989089 pts: 0.989089 pos:   2048 size:   208
+ret: 0         st: 1 flags:1 dts: 0.529089 pts: 0.529089 pos:   2048 size:   208
 ret: 0         st: 1 flags:0  ts: 2.671678
-ret: 0         st: 1 flags:1 dts: 1.772767 pts: 1.772767 pos: 368652 size:   379
+ret: 0         st: 1 flags:1 dts: 1.312767 pts: 1.312767 pos: 368652 size:   379
 ret: 0         st: 1 flags:1  ts: 1.565844
-ret: 0         st: 1 flags:1 dts: 1.511544 pts: 1.511544 pos: 342028 size:   314
+ret: 0         st: 1 flags:1 dts: 1.312767 pts: 1.312767 pos: 368652 size:   379
 ret: 0         st:-1 flags:0  ts: 0.460008
-ret: 0         st: 1 flags:1 dts: 0.989089 pts: 0.989089 pos:   2048 size:   208
+ret: 0         st: 1 flags:1 dts: 0.529089 pts: 0.529089 pos:   2048 size:   208
 ret: 0         st:-1 flags:1  ts:-0.645825
-ret: 0         st: 1 flags:1 dts: 0.989089 pts: 0.989089 pos:   2048 size:   208
+ret: 0         st: 1 flags:1 dts: 0.529089 pts: 0.529089 pos:   2048 size:   208
diff --git a/tests/ref/seek/lavf-mxf b/tests/ref/seek/lavf-mxf
index 34dddc3..9b23466 100644
--- a/tests/ref/seek/lavf-mxf
+++ b/tests/ref/seek/lavf-mxf
@@ -30,7 +30,7 @@
 ret: 0         st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460288 size: 24711
 ret:-1         st: 1 flags:0  ts: 1.306667
 ret: 0         st: 1 flags:1  ts: 0.200833
-ret: 0         st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460288 size: 24711
+ret: 0         st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos:   6144 size: 24801
 ret: 0         st:-1 flags:0  ts:-0.904994
 ret: 0         st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos:   6144 size: 24801
 ret: 0         st:-1 flags:1  ts: 1.989173
diff --git a/tests/ref/seek/lavf-mxf_d10 b/tests/ref/seek/lavf-mxf_d10
index e091c77..17cca29 100644
--- a/tests/ref/seek/lavf-mxf_d10
+++ b/tests/ref/seek/lavf-mxf_d10
@@ -34,7 +34,7 @@
 ret: 0         st: 1 flags:0  ts: 1.306667
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:5117952 size:150000
 ret: 0         st: 1 flags:1  ts: 0.200833
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:5117952 size:150000
+ret: 0         st: 0 flags:1 dts: 0.200000 pts: 0.200000 pos:1071104 size:150000
 ret: 0         st:-1 flags:0  ts:-0.904994
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   6144 size:150000
 ret: 0         st:-1 flags:1  ts: 1.989173
diff --git a/tests/ref/seek/lavf-ogg b/tests/ref/seek/lavf-ogg
index 2898d10..583526e 100644
--- a/tests/ref/seek/lavf-ogg
+++ b/tests/ref/seek/lavf-ogg
@@ -1,35 +1,53 @@
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    143 size:  1364
 ret: 0         st:-1 flags:0  ts:-1.000000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    143 size:  1364
-ret:-1         st:-1 flags:1  ts: 1.894167
-ret:-1         st: 0 flags:0  ts: 0.788345
+ret: 0         st:-1 flags:1  ts: 1.894167
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    143 size:  1364
+ret: 0         st: 0 flags:0  ts: 0.788345
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    143 size:  1364
 ret: 0         st: 0 flags:1  ts:-0.317506
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    143 size:  1364
-ret:-1         st:-1 flags:0  ts: 2.576668
-ret:-1         st:-1 flags:1  ts: 1.470835
-ret:-1         st: 0 flags:0  ts: 0.365011
+ret: 0         st:-1 flags:0  ts: 2.576668
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    143 size:  1364
+ret: 0         st:-1 flags:1  ts: 1.470835
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    143 size:  1364
+ret: 0         st: 0 flags:0  ts: 0.365011
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    143 size:  1364
 ret: 0         st: 0 flags:1  ts:-0.740839
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    143 size:  1364
-ret:-1         st:-1 flags:0  ts: 2.153336
-ret:-1         st:-1 flags:1  ts: 1.047503
+ret: 0         st:-1 flags:0  ts: 2.153336
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    143 size:  1364
+ret: 0         st:-1 flags:1  ts: 1.047503
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    143 size:  1364
 ret: 0         st: 0 flags:0  ts:-0.058322
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    143 size:  1364
-ret:-1         st: 0 flags:1  ts: 2.835828
-ret:-1         st:-1 flags:0  ts: 1.730004
-ret:-1         st:-1 flags:1  ts: 0.624171
+ret: 0         st: 0 flags:1  ts: 2.835828
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    143 size:  1364
+ret: 0         st:-1 flags:0  ts: 1.730004
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    143 size:  1364
+ret: 0         st:-1 flags:1  ts: 0.624171
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    143 size:  1364
 ret: 0         st: 0 flags:0  ts:-0.481655
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    143 size:  1364
-ret:-1         st: 0 flags:1  ts: 2.412494
-ret:-1         st:-1 flags:0  ts: 1.306672
-ret:-1         st:-1 flags:1  ts: 0.200839
+ret: 0         st: 0 flags:1  ts: 2.412494
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    143 size:  1364
+ret: 0         st:-1 flags:0  ts: 1.306672
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    143 size:  1364
+ret: 0         st:-1 flags:1  ts: 0.200839
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    143 size:  1364
 ret: 0         st: 0 flags:0  ts:-0.904989
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    143 size:  1364
-ret:-1         st: 0 flags:1  ts: 1.989184
-ret:-1         st:-1 flags:0  ts: 0.883340
+ret: 0         st: 0 flags:1  ts: 1.989184
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    143 size:  1364
+ret: 0         st:-1 flags:0  ts: 0.883340
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    143 size:  1364
 ret: 0         st:-1 flags:1  ts:-0.222493
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    143 size:  1364
-ret:-1         st: 0 flags:0  ts: 2.671678
-ret:-1         st: 0 flags:1  ts: 1.565850
-ret:-1         st:-1 flags:0  ts: 0.460008
+ret: 0         st: 0 flags:0  ts: 2.671678
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    143 size:  1364
+ret: 0         st: 0 flags:1  ts: 1.565850
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    143 size:  1364
+ret: 0         st:-1 flags:0  ts: 0.460008
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    143 size:  1364
 ret: 0         st:-1 flags:1  ts:-0.645825
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    143 size:  1364
diff --git a/tests/ref/seek/lavf-pcx b/tests/ref/seek/lavf-pcx
index 418674f..ba21627 100644
--- a/tests/ref/seek/lavf-pcx
+++ b/tests/ref/seek/lavf-pcx
@@ -5,7 +5,8 @@
 ret:-EINVAL    st: 0 flags:1  ts:-0.320000
 ret:-EINVAL    st:-1 flags:0  ts: 2.576668
 ret:-EINVAL    st:-1 flags:1  ts: 1.470835
-ret:-EINVAL    st: 0 flags:0  ts: 0.360000
+ret: 0         st: 0 flags:0  ts: 0.360000
+ret: 0         st: 0 flags:1 dts: 0.360000 pts: 0.360000 pos:     -1 size:363107
 ret:-EINVAL    st: 0 flags:1  ts:-0.760000
 ret:-EINVAL    st:-1 flags:0  ts: 2.153336
 ret:-EINVAL    st:-1 flags:1  ts: 1.047503
@@ -16,12 +17,14 @@
 ret:-EINVAL    st: 0 flags:0  ts:-0.480000
 ret:-EINVAL    st: 0 flags:1  ts: 2.400000
 ret:-EINVAL    st:-1 flags:0  ts: 1.306672
-ret:-EINVAL    st:-1 flags:1  ts: 0.200839
+ret: 0         st:-1 flags:1  ts: 0.200839
+ret: 0         st: 0 flags:1 dts: 0.200000 pts: 0.200000 pos:     -1 size:364760
 ret:-EINVAL    st: 0 flags:0  ts:-0.920000
 ret:-EINVAL    st: 0 flags:1  ts: 2.000000
 ret:-EINVAL    st:-1 flags:0  ts: 0.883340
 ret:-EINVAL    st:-1 flags:1  ts:-0.222493
 ret:-EINVAL    st: 0 flags:0  ts: 2.680000
 ret:-EINVAL    st: 0 flags:1  ts: 1.560000
-ret:-EINVAL    st:-1 flags:0  ts: 0.460008
+ret: 0         st:-1 flags:0  ts: 0.460008
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:     -1 size:362983
 ret:-EINVAL    st:-1 flags:1  ts:-0.645825
diff --git a/tests/ref/seek/lavf-pgm b/tests/ref/seek/lavf-pgm
index 2836367..ceac008 100644
--- a/tests/ref/seek/lavf-pgm
+++ b/tests/ref/seek/lavf-pgm
@@ -5,7 +5,8 @@
 ret:-EINVAL    st: 0 flags:1  ts:-0.320000
 ret:-EINVAL    st:-1 flags:0  ts: 2.576668
 ret:-EINVAL    st:-1 flags:1  ts: 1.470835
-ret:-EINVAL    st: 0 flags:0  ts: 0.360000
+ret: 0         st: 0 flags:0  ts: 0.360000
+ret: 0         st: 0 flags:1 dts: 0.360000 pts: 0.360000 pos:     -1 size:101391
 ret:-EINVAL    st: 0 flags:1  ts:-0.760000
 ret:-EINVAL    st:-1 flags:0  ts: 2.153336
 ret:-EINVAL    st:-1 flags:1  ts: 1.047503
@@ -16,12 +17,14 @@
 ret:-EINVAL    st: 0 flags:0  ts:-0.480000
 ret:-EINVAL    st: 0 flags:1  ts: 2.400000
 ret:-EINVAL    st:-1 flags:0  ts: 1.306672
-ret:-EINVAL    st:-1 flags:1  ts: 0.200839
+ret: 0         st:-1 flags:1  ts: 0.200839
+ret: 0         st: 0 flags:1 dts: 0.200000 pts: 0.200000 pos:     -1 size:101391
 ret:-EINVAL    st: 0 flags:0  ts:-0.920000
 ret:-EINVAL    st: 0 flags:1  ts: 2.000000
 ret:-EINVAL    st:-1 flags:0  ts: 0.883340
 ret:-EINVAL    st:-1 flags:1  ts:-0.222493
 ret:-EINVAL    st: 0 flags:0  ts: 2.680000
 ret:-EINVAL    st: 0 flags:1  ts: 1.560000
-ret:-EINVAL    st:-1 flags:0  ts: 0.460008
+ret: 0         st:-1 flags:0  ts: 0.460008
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:     -1 size:101391
 ret:-EINVAL    st:-1 flags:1  ts:-0.645825
diff --git a/tests/ref/seek/lavf-ppm b/tests/ref/seek/lavf-ppm
index 6376b5e..6d53ce0 100644
--- a/tests/ref/seek/lavf-ppm
+++ b/tests/ref/seek/lavf-ppm
@@ -5,7 +5,8 @@
 ret:-EINVAL    st: 0 flags:1  ts:-0.320000
 ret:-EINVAL    st:-1 flags:0  ts: 2.576668
 ret:-EINVAL    st:-1 flags:1  ts: 1.470835
-ret:-EINVAL    st: 0 flags:0  ts: 0.360000
+ret: 0         st: 0 flags:0  ts: 0.360000
+ret: 0         st: 0 flags:1 dts: 0.360000 pts: 0.360000 pos:     -1 size:304143
 ret:-EINVAL    st: 0 flags:1  ts:-0.760000
 ret:-EINVAL    st:-1 flags:0  ts: 2.153336
 ret:-EINVAL    st:-1 flags:1  ts: 1.047503
@@ -16,12 +17,14 @@
 ret:-EINVAL    st: 0 flags:0  ts:-0.480000
 ret:-EINVAL    st: 0 flags:1  ts: 2.400000
 ret:-EINVAL    st:-1 flags:0  ts: 1.306672
-ret:-EINVAL    st:-1 flags:1  ts: 0.200839
+ret: 0         st:-1 flags:1  ts: 0.200839
+ret: 0         st: 0 flags:1 dts: 0.200000 pts: 0.200000 pos:     -1 size:304143
 ret:-EINVAL    st: 0 flags:0  ts:-0.920000
 ret:-EINVAL    st: 0 flags:1  ts: 2.000000
 ret:-EINVAL    st:-1 flags:0  ts: 0.883340
 ret:-EINVAL    st:-1 flags:1  ts:-0.222493
 ret:-EINVAL    st: 0 flags:0  ts: 2.680000
 ret:-EINVAL    st: 0 flags:1  ts: 1.560000
-ret:-EINVAL    st:-1 flags:0  ts: 0.460008
+ret: 0         st:-1 flags:0  ts: 0.460008
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:     -1 size:304143
 ret:-EINVAL    st:-1 flags:1  ts:-0.645825
diff --git a/tests/ref/seek/lavf-sgi b/tests/ref/seek/lavf-sgi
index b2f605a..b07132a 100644
--- a/tests/ref/seek/lavf-sgi
+++ b/tests/ref/seek/lavf-sgi
@@ -5,7 +5,8 @@
 ret:-EINVAL    st: 0 flags:1  ts:-0.320000
 ret:-EINVAL    st:-1 flags:0  ts: 2.576668
 ret:-EINVAL    st:-1 flags:1  ts: 1.470835
-ret:-EINVAL    st: 0 flags:0  ts: 0.360000
+ret: 0         st: 0 flags:0  ts: 0.360000
+ret: 0         st: 0 flags:1 dts: 0.360000 pts: 0.360000 pos:     -1 size:308572
 ret:-EINVAL    st: 0 flags:1  ts:-0.760000
 ret:-EINVAL    st:-1 flags:0  ts: 2.153336
 ret:-EINVAL    st:-1 flags:1  ts: 1.047503
@@ -16,12 +17,14 @@
 ret:-EINVAL    st: 0 flags:0  ts:-0.480000
 ret:-EINVAL    st: 0 flags:1  ts: 2.400000
 ret:-EINVAL    st:-1 flags:0  ts: 1.306672
-ret:-EINVAL    st:-1 flags:1  ts: 0.200839
+ret: 0         st:-1 flags:1  ts: 0.200839
+ret: 0         st: 0 flags:1 dts: 0.200000 pts: 0.200000 pos:     -1 size:308294
 ret:-EINVAL    st: 0 flags:0  ts:-0.920000
 ret:-EINVAL    st: 0 flags:1  ts: 2.000000
 ret:-EINVAL    st:-1 flags:0  ts: 0.883340
 ret:-EINVAL    st:-1 flags:1  ts:-0.222493
 ret:-EINVAL    st: 0 flags:0  ts: 2.680000
 ret:-EINVAL    st: 0 flags:1  ts: 1.560000
-ret:-EINVAL    st:-1 flags:0  ts: 0.460008
+ret: 0         st:-1 flags:0  ts: 0.460008
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:     -1 size:307773
 ret:-EINVAL    st:-1 flags:1  ts:-0.645825
diff --git a/tests/ref/seek/lavf-tga b/tests/ref/seek/lavf-tga
index 8f90753..ee7552a 100644
--- a/tests/ref/seek/lavf-tga
+++ b/tests/ref/seek/lavf-tga
@@ -5,7 +5,8 @@
 ret:-EINVAL    st: 0 flags:1  ts:-0.320000
 ret:-EINVAL    st:-1 flags:0  ts: 2.576668
 ret:-EINVAL    st:-1 flags:1  ts: 1.470835
-ret:-EINVAL    st: 0 flags:0  ts: 0.360000
+ret: 0         st: 0 flags:0  ts: 0.360000
+ret: 0         st: 0 flags:1 dts: 0.360000 pts: 0.360000 pos:     -1 size:304172
 ret:-EINVAL    st: 0 flags:1  ts:-0.760000
 ret:-EINVAL    st:-1 flags:0  ts: 2.153336
 ret:-EINVAL    st:-1 flags:1  ts: 1.047503
@@ -16,12 +17,14 @@
 ret:-EINVAL    st: 0 flags:0  ts:-0.480000
 ret:-EINVAL    st: 0 flags:1  ts: 2.400000
 ret:-EINVAL    st:-1 flags:0  ts: 1.306672
-ret:-EINVAL    st:-1 flags:1  ts: 0.200839
+ret: 0         st:-1 flags:1  ts: 0.200839
+ret: 0         st: 0 flags:1 dts: 0.200000 pts: 0.200000 pos:     -1 size:304172
 ret:-EINVAL    st: 0 flags:0  ts:-0.920000
 ret:-EINVAL    st: 0 flags:1  ts: 2.000000
 ret:-EINVAL    st:-1 flags:0  ts: 0.883340
 ret:-EINVAL    st:-1 flags:1  ts:-0.222493
 ret:-EINVAL    st: 0 flags:0  ts: 2.680000
 ret:-EINVAL    st: 0 flags:1  ts: 1.560000
-ret:-EINVAL    st:-1 flags:0  ts: 0.460008
+ret: 0         st:-1 flags:0  ts: 0.460008
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:     -1 size:304172
 ret:-EINVAL    st:-1 flags:1  ts:-0.645825
diff --git a/tests/ref/seek/lavf-tiff b/tests/ref/seek/lavf-tiff
index 1b49f2f..0d9fb04 100644
--- a/tests/ref/seek/lavf-tiff
+++ b/tests/ref/seek/lavf-tiff
@@ -5,7 +5,8 @@
 ret:-EINVAL    st: 0 flags:1  ts:-0.320000
 ret:-EINVAL    st:-1 flags:0  ts: 2.576668
 ret:-EINVAL    st:-1 flags:1  ts: 1.470835
-ret:-EINVAL    st: 0 flags:0  ts: 0.360000
+ret: 0         st: 0 flags:0  ts: 0.360000
+ret: 0         st: 0 flags:1 dts: 0.360000 pts: 0.360000 pos:     -1 size:307150
 ret:-EINVAL    st: 0 flags:1  ts:-0.760000
 ret:-EINVAL    st:-1 flags:0  ts: 2.153336
 ret:-EINVAL    st:-1 flags:1  ts: 1.047503
@@ -16,12 +17,14 @@
 ret:-EINVAL    st: 0 flags:0  ts:-0.480000
 ret:-EINVAL    st: 0 flags:1  ts: 2.400000
 ret:-EINVAL    st:-1 flags:0  ts: 1.306672
-ret:-EINVAL    st:-1 flags:1  ts: 0.200839
+ret: 0         st:-1 flags:1  ts: 0.200839
+ret: 0         st: 0 flags:1 dts: 0.200000 pts: 0.200000 pos:     -1 size:307140
 ret:-EINVAL    st: 0 flags:0  ts:-0.920000
 ret:-EINVAL    st: 0 flags:1  ts: 2.000000
 ret:-EINVAL    st:-1 flags:0  ts: 0.883340
 ret:-EINVAL    st:-1 flags:1  ts:-0.222493
 ret:-EINVAL    st: 0 flags:0  ts: 2.680000
 ret:-EINVAL    st: 0 flags:1  ts: 1.560000
-ret:-EINVAL    st:-1 flags:0  ts: 0.460008
+ret: 0         st:-1 flags:0  ts: 0.460008
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:     -1 size:307140
 ret:-EINVAL    st:-1 flags:1  ts:-0.645825
diff --git a/tests/ref/seek/vsynth2-wmv2 b/tests/ref/seek/vsynth2-wmv2
index 8b9d3f3..a29f0d4 100644
--- a/tests/ref/seek/vsynth2-wmv2
+++ b/tests/ref/seek/vsynth2-wmv2
@@ -2,45 +2,45 @@
 ret: 0         st:-1 flags:0  ts:-1.000000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5652 size:  8917
 ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:  83790 size: 11169
+ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:  83764 size: 11169
 ret: 0         st: 0 flags:0  ts: 0.800000
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:  54572 size:  9989
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:  54534 size:  9989
 ret:-1         st: 0 flags:1  ts:-0.320000
 ret:-1         st:-1 flags:0  ts: 2.576668
 ret: 0         st:-1 flags:1  ts: 1.470835
-ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:  83790 size: 11169
+ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:  83764 size: 11169
 ret: 0         st: 0 flags:0  ts: 0.360000
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  29632 size:  8839
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  29588 size:  8839
 ret:-1         st: 0 flags:1  ts:-0.760000
 ret:-1         st:-1 flags:0  ts: 2.153336
 ret: 0         st:-1 flags:1  ts: 1.047503
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:  54572 size:  9989
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:  54534 size:  9989
 ret: 0         st: 0 flags:0  ts:-0.040000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5652 size:  8917
 ret: 0         st: 0 flags:1  ts: 2.840000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 116044 size: 11554
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 116066 size: 11554
 ret: 0         st:-1 flags:0  ts: 1.730004
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 116044 size: 11554
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 116066 size: 11554
 ret: 0         st:-1 flags:1  ts: 0.624171
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  29632 size:  8839
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  29588 size:  8839
 ret: 0         st: 0 flags:0  ts:-0.480000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5652 size:  8917
 ret: 0         st: 0 flags:1  ts: 2.400000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 116044 size: 11554
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 116066 size: 11554
 ret: 0         st:-1 flags:0  ts: 1.306672
-ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:  83790 size: 11169
+ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:  83764 size: 11169
 ret: 0         st:-1 flags:1  ts: 0.200839
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5652 size:  8917
 ret: 0         st: 0 flags:0  ts:-0.920000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5652 size:  8917
 ret: 0         st: 0 flags:1  ts: 2.000000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 116044 size: 11554
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 116066 size: 11554
 ret: 0         st:-1 flags:0  ts: 0.883340
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:  54572 size:  9989
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:  54534 size:  9989
 ret:-1         st:-1 flags:1  ts:-0.222493
 ret:-1         st: 0 flags:0  ts: 2.680000
 ret: 0         st: 0 flags:1  ts: 1.560000
-ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:  83790 size: 11169
+ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:  83764 size: 11169
 ret: 0         st:-1 flags:0  ts: 0.460008
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  29632 size:  8839
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  29588 size:  8839
 ret:-1         st:-1 flags:1  ts:-0.645825
diff --git a/tests/ref/vsynth/vsynth1-avui b/tests/ref/vsynth/vsynth1-avui
index 03f2b31..e4434e8 100644
--- a/tests/ref/vsynth/vsynth1-avui
+++ b/tests/ref/vsynth/vsynth1-avui
@@ -1,4 +1,4 @@
-853dad3a1248614c6d61c2f9dc2a999c *tests/data/fate/vsynth1-avui.mov
-42624907 tests/data/fate/vsynth1-avui.mov
+0e71be51f4e0701d91ff7fa4d9ea0533 *tests/data/fate/vsynth1-avui.mov
+42624917 tests/data/fate/vsynth1-avui.mov
 c5ccac874dbf808e9088bc3107860042 *tests/data/fate/vsynth1-avui.out.rawvideo
 stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  7603200/  7603200
diff --git a/tests/ref/vsynth/vsynth1-dnxhd-1080i b/tests/ref/vsynth/vsynth1-dnxhd-1080i
index 899ef9e..dbe2c37 100644
--- a/tests/ref/vsynth/vsynth1-dnxhd-1080i
+++ b/tests/ref/vsynth/vsynth1-dnxhd-1080i
@@ -1,4 +1,4 @@
-9a4781b0a052d9efaafbaf8893db9632 *tests/data/fate/vsynth1-dnxhd-1080i.mov
+124c991ee3ac0caef39a58a45287a762 *tests/data/fate/vsynth1-dnxhd-1080i.mov
 3031911 tests/data/fate/vsynth1-dnxhd-1080i.mov
-e55bf857297ba4d911a9d17a984b125d *tests/data/fate/vsynth1-dnxhd-1080i.out.rawvideo
+a09132c6db44f415e831dcaa630a351b *tests/data/fate/vsynth1-dnxhd-1080i.out.rawvideo
 stddev:    6.29 PSNR: 32.15 MAXDIFF:   64 bytes:  7603200/   760320
diff --git a/tests/ref/vsynth/vsynth1-mjpeg-444 b/tests/ref/vsynth/vsynth1-mjpeg-444
index 3ad0c51..ba24914 100644
--- a/tests/ref/vsynth/vsynth1-mjpeg-444
+++ b/tests/ref/vsynth/vsynth1-mjpeg-444
@@ -1,4 +1,4 @@
-bf3e8f03857c8b3c7b1cdc7bb1aa5bae *tests/data/fate/vsynth1-mjpeg-444.avi
-1987582 tests/data/fate/vsynth1-mjpeg-444.avi
+94ca37e075ee24047b5dcd8f27b51a9f *tests/data/fate/vsynth1-mjpeg-444.avi
+1989780 tests/data/fate/vsynth1-mjpeg-444.avi
 313a4a76af13d5879ea4910107b7ea74 *tests/data/fate/vsynth1-mjpeg-444.out.rawvideo
 stddev:    7.37 PSNR: 30.77 MAXDIFF:   63 bytes:  7603200/  7603200
diff --git a/tests/ref/vsynth/vsynth1-wmv2 b/tests/ref/vsynth/vsynth1-wmv2
index 79a1302..872ffc9 100644
--- a/tests/ref/vsynth/vsynth1-wmv2
+++ b/tests/ref/vsynth/vsynth1-wmv2
@@ -1,4 +1,4 @@
-532f99495482015c12a2773ec1065a4d *tests/data/fate/vsynth1-wmv2.avi
-659832 tests/data/fate/vsynth1-wmv2.avi
-3354066ebdd8cd8098394be2384744e7 *tests/data/fate/vsynth1-wmv2.out.rawvideo
-stddev:    7.97 PSNR: 30.09 MAXDIFF:  110 bytes:  7603200/  7603200
+4ab9357e6369c81fecb1ebcbc7551f0c *tests/data/fate/vsynth1-wmv2.avi
+659138 tests/data/fate/vsynth1-wmv2.avi
+8a6061ef825e79d887705db656d51247 *tests/data/fate/vsynth1-wmv2.out.rawvideo
+stddev:    7.97 PSNR: 30.09 MAXDIFF:  105 bytes:  7603200/  7603200
diff --git a/tests/ref/vsynth/vsynth2-avui b/tests/ref/vsynth/vsynth2-avui
index 59bac8d..743c6ff 100644
--- a/tests/ref/vsynth/vsynth2-avui
+++ b/tests/ref/vsynth/vsynth2-avui
@@ -1,4 +1,4 @@
-d6ed112daf14e73ea50f1c32ecc6d4ce *tests/data/fate/vsynth2-avui.mov
-42624907 tests/data/fate/vsynth2-avui.mov
+ec8b12fd9f1f7737f7e23419457fe431 *tests/data/fate/vsynth2-avui.mov
+42624917 tests/data/fate/vsynth2-avui.mov
 dde5895817ad9d219f79a52d0bdfb001 *tests/data/fate/vsynth2-avui.out.rawvideo
 stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  7603200/  7603200
diff --git a/tests/ref/vsynth/vsynth2-dnxhd-1080i b/tests/ref/vsynth/vsynth2-dnxhd-1080i
index 874e60b..f657eb4 100644
--- a/tests/ref/vsynth/vsynth2-dnxhd-1080i
+++ b/tests/ref/vsynth/vsynth2-dnxhd-1080i
@@ -1,4 +1,4 @@
-93b878dcf8f2ecc9798d0e0885c9eec9 *tests/data/fate/vsynth2-dnxhd-1080i.mov
+5d7ab75ce6e547ed63a7a0eacf18f078 *tests/data/fate/vsynth2-dnxhd-1080i.mov
 3031911 tests/data/fate/vsynth2-dnxhd-1080i.mov
-27edc8dfe2ca19097c7f9119705b3a60 *tests/data/fate/vsynth2-dnxhd-1080i.out.rawvideo
+744ba46da5d4c19a28562ea31061d170 *tests/data/fate/vsynth2-dnxhd-1080i.out.rawvideo
 stddev:    1.31 PSNR: 45.77 MAXDIFF:   23 bytes:  7603200/   760320
diff --git a/tests/ref/vsynth/vsynth2-mjpeg-444 b/tests/ref/vsynth/vsynth2-mjpeg-444
index e04c31c..b09f889 100644
--- a/tests/ref/vsynth/vsynth2-mjpeg-444
+++ b/tests/ref/vsynth/vsynth2-mjpeg-444
@@ -1,4 +1,4 @@
-0af500d33a7e4d04e9778fb9ed6180b3 *tests/data/fate/vsynth2-mjpeg-444.avi
-856628 tests/data/fate/vsynth2-mjpeg-444.avi
+10abd087833f9bdf3b77c1aa37dc11e5 *tests/data/fate/vsynth2-mjpeg-444.avi
+851442 tests/data/fate/vsynth2-mjpeg-444.avi
 34edcb9c87ff7aac456a4fb07f43504b *tests/data/fate/vsynth2-mjpeg-444.out.rawvideo
 stddev:    4.05 PSNR: 35.96 MAXDIFF:   49 bytes:  7603200/  7603200
diff --git a/tests/ref/vsynth/vsynth2-wmv2 b/tests/ref/vsynth/vsynth2-wmv2
index 41beb4e..5de4898 100644
--- a/tests/ref/vsynth/vsynth2-wmv2
+++ b/tests/ref/vsynth/vsynth2-wmv2
@@ -1,4 +1,4 @@
-f2a29f4e98a526e104067ca381716e47 *tests/data/fate/vsynth2-wmv2.avi
-129834 tests/data/fate/vsynth2-wmv2.avi
-dec44e3c04db4fef49a7728f164d9159 *tests/data/fate/vsynth2-wmv2.out.rawvideo
-stddev:    5.33 PSNR: 33.60 MAXDIFF:   77 bytes:  7603200/  7603200
+1b0e968e180346914c11875f4eec57eb *tests/data/fate/vsynth2-wmv2.avi
+129852 tests/data/fate/vsynth2-wmv2.avi
+b4de16a0d302c52702f7a4362da989bc *tests/data/fate/vsynth2-wmv2.out.rawvideo
+stddev:    5.33 PSNR: 33.59 MAXDIFF:   77 bytes:  7603200/  7603200
diff --git a/tools/bookmarklets.html b/tools/bookmarklets.html
new file mode 100644
index 0000000..9800ab5
--- /dev/null
+++ b/tools/bookmarklets.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<html>
+<head>
+<!--
+    This file is part of FFmpeg.
+
+    All scripts contained in this file can be considered public domain.
+  -->
+<title>FFmpeg bookmarklets</title>
+<meta charset="UTF-8">
+<script type="text/javascript">
+function convert(js) {
+  js = js.replace(/\/\*.*?\*\//g, ""); /* comments */
+  js = js.replace(/\s+/g, " ");
+  js = js.replace(/\s+\z/, "");
+  js = "(function(){" + js + "})();void 0";
+  return "javascript:" + escape(js);
+}
+function init() {
+  var pre = document.getElementsByTagName("pre");
+  for (var i = 0; pre.length > i; i++) {
+    document.getElementById(pre[i].id + "-link").href = convert(pre[i].textContent);
+  }
+}
+</script>
+<style type="text/css">
+pre { border: solid black 1px; padding: 0.2ex; font-size: 80% }
+</style>
+</head>
+<body onload="init()">
+
+<h1>Introduction</h1>
+
+The scripts in this page are
+<a href="http://en.wikipedia.org/wiki/Bookmarklet">bookmarklets</a>: store
+their link version in a bookmark, and later activate the bookmark on a page
+to run the script.
+
+<h1>TED Talks captions</h1>
+
+<p><a id="ted_talks_captions-link" href="#">Get links to the captions</a></p>
+
+<pre id="ted_talks_captions">
+d = window.open("", "sub", "width=256,height=512,resizable=yes,scrollbars=yes").document;
+l = document.getElementById("languageCode").getElementsByTagName("option");
+for (i = 1; i &lt; l.length ; i++) {
+  d.body.appendChild(p = d.createElement("p"));
+  p.appendChild(a = d.createElement("a"));
+  a.appendChild(d.createTextNode(l[i].textContent));
+  a.href="http://www.ted.com/talks/subtitles/id/" + talkID+"/lang/" + l[i].value;
+}
+</pre>
+
+</body>
+</html>
diff --git a/tools/ismindex.c b/tools/ismindex.c
index 9efdebe..803c5b7 100644
--- a/tools/ismindex.c
+++ b/tools/ismindex.c
@@ -40,6 +40,8 @@
 #define mkdir(a, b) _mkdir(a)
 #endif
 
+#include "cmdutils.h"
+
 #include "libavformat/avformat.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/mathematics.h"
diff --git a/tools/patcheck b/tools/patcheck
index f82787b..83db4c0 100755
--- a/tools/patcheck
+++ b/tools/patcheck
@@ -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)\b' 'common typos' $*
+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 'av_log\( *NULL' 'Missing context in av_log' $*
 hiegrep '[^sn]printf' 'Please use av_log' $*
@@ -158,7 +158,7 @@
 cat $TMP | tr '@' '\n'
 
 
-# doesnt work
+# does not work
 #cat $* | tr '\n' '@' | $EGREP -o '[^a-zA-Z_0-9]([a-zA-Z][a-zA-Z_0-9]*) *=[^=].*\1' | $EGREP -o '[^a-zA-Z_0-9]([a-zA-Z][a-zA-Z_0-9]*) *=[^=].*\1 *=[^=]'  >$TMP && printf "\nPossibly written 2x before read\n"
 #cat $TMP | tr '@' '\n'
 
@@ -173,7 +173,7 @@
 /* and * align
 arrays fitting in smaller types
 variables written to twice with no interspaced read
-memset(block, 0, 6*64*sizeof(DCTELEM)); -> clear_blocks
+memset(block, 0, 6*64*sizeof(int16_t)); -> clear_blocks
 check existence of long_name in AVCodec
 check that the patch does not touch codec & (de)muxer layer at the same time ->split
 
diff --git a/tools/plotframes b/tools/plotframes
new file mode 100755
index 0000000..f379723
--- /dev/null
+++ b/tools/plotframes
@@ -0,0 +1,164 @@
+#!/usr/bin/env perl
+
+# Copyright (c) 2007-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
+
+=head1 NAME
+
+plotframes - Plot video frame sizes using ffprobe and gnuplot
+
+=head1 SYNOPSIS
+
+plotframes [I<options>] [I<input>]
+
+=head1 DESCRIPTION
+
+plotframes reads a multimedia files with ffprobe, and plots the
+collected video sizes with gnuplot.
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<--input|-i> I<infile>
+
+Specify multimedia file to read. This is the file passed to the
+ffprobe command. If not specified it is the first argument passed to
+the script.
+
+=item B<--help|--usage|-h|-?>
+
+Print a brief help message and exit.
+
+=item B<--manpage|-m>
+
+Print the man page.
+
+=item B<--output|-o> I<outfile>
+
+Set the name of the output used by gnuplot. If not specified no output
+is created. Must be used in conjunction with the B<terminal> option.
+
+=item B<--stream|--s> I<stream_specifier>
+
+Specify stream. The value must be a string containing a stream
+specifier. Default value is "v".
+
+=item B<--terminal|-t> I<terminal>
+
+Set the name of the terminal used by gnuplot. By default it is
+"x11". Must be used in conjunction with the B<output> option. Check
+the gnuplot manual for the valid values.
+
+=back
+
+=cut
+
+=head1 SEE ALSO
+
+ffprobe(1), gnuplot(1)
+
+=cut
+
+use warnings;
+use strict;
+
+use File::Temp;
+use JSON -support_by_pp;
+use Getopt::Long;
+use Pod::Usage;
+
+my $input = $ARGV[0];
+my $stream_specifier = "v";
+my $gnuplot_terminal = "x11";
+my $gnuplot_output;
+
+GetOptions (
+    'input|i=s'      => \$input,
+    'help|usage|?|h' => sub { pod2usage ( { -verbose => 1, -exitval => 0 }) },
+    'manpage|m'      => sub { pod2usage ( { -verbose => 2, -exitval => 0 }) },
+    'stream|s=s'     => \$stream_specifier,
+    'terminal|t=s'   => \$gnuplot_terminal,
+    'output|o=s'     => \$gnuplot_output,
+    ) or pod2usage( { -message=> "Parsing error", -verbose => 1, -exitval => 1 });
+
+die "You must specify an input file\n" unless $input;
+
+# fetch data
+my @cmd = (qw{ffprobe -show_entries frame -select_streams}, $stream_specifier, "-of", "json", $input);
+print STDERR "Executing command: @cmd\n";
+my $json_struct;
+{
+    open(FH, "-|", @cmd) or die "ffprobe command failed: $!\n";
+    local $/;
+    my $json_text = <FH>;
+    close FH;
+    die "ffprobe command failed" if $?;
+    eval { $json_struct = decode_json($json_text); };
+    die "JSON parsing error: $@\n" if $@;
+}
+
+# collect and print frame statistics per pict_type
+my %stats;
+my $frames = $json_struct->{frames};
+my $frame_count = 0;
+foreach my $frame (@{$frames}) {
+    my $type = $frame->{pict_type};
+    $frame->{count} = $frame_count++;
+    if (not $stats{$type}) {
+        $stats{$type}->{tmpfile} = File::Temp->new(SUFFIX => '.dat');
+        my $fn = $stats{$type}->{tmpfile}->filename;
+        open($stats{$type}->{fh}, ">", $fn) or die "Can't open $fn";
+    }
+
+    print { $stats{$type}->{fh} }
+        "$frame->{count} ", $frame->{pkt_size} * 8 / 1000, "\n";
+}
+foreach (keys %stats) { close $stats{$_}->{fh}; }
+
+# write gnuplot script
+my %type_color_map = (
+    "I" => "red",
+    "P" => "green",
+    "B" => "blue"
+    );
+
+my $gnuplot_script_tmpfile = File::Temp->new(SUFFIX => '.gnuplot');
+my $fn = $gnuplot_script_tmpfile->filename;
+open(FH, ">", $fn) or die "Couldn't open $fn: $!";
+print FH << "EOF";
+set title "video frame sizes"
+set xlabel "frame time"
+set ylabel "frame size (Kbits)"
+set grid
+set terminal "$gnuplot_terminal"
+EOF
+
+print FH "set output \"$gnuplot_output\"\n" if $gnuplot_output;
+print FH "plot";
+my $sep = "";
+foreach my $type (keys %stats) {
+    my $fn = $stats{$type}->{tmpfile}->filename;
+    print FH "$sep\"$fn\" title \"$type frames\" with impulses";
+    print FH " linecolor rgb \"$type_color_map{$type}\"" if $type_color_map{$type};
+    $sep = ", ";
+}
+close FH;
+
+# launch gnuplot with the generated script
+system ("gnuplot", "--persist", $gnuplot_script_tmpfile->filename);
diff --git a/tools/qt-faststart.c b/tools/qt-faststart.c
index ecf163a..c9aa6e8 100644
--- a/tools/qt-faststart.c
+++ b/tools/qt-faststart.c
@@ -235,6 +235,10 @@
                 goto error_out;
             }
             offset_count = BE_32(&moov_atom[i + 8]);
+            if (i + 12LL + offset_count * 4LL > moov_atom_size) {
+                printf(" bad atom size\n");
+                goto error_out;
+            }
             for (j = 0; j < offset_count; j++) {
                 current_offset  = BE_32(&moov_atom[i + 12 + j * 4]);
                 current_offset += moov_atom_size;
@@ -252,6 +256,10 @@
                 goto error_out;
             }
             offset_count = BE_32(&moov_atom[i + 8]);
+            if (i + 12LL + offset_count * 8LL > moov_atom_size) {
+                printf(" bad atom size\n");
+                goto error_out;
+            }
             for (j = 0; j < offset_count; j++) {
                 current_offset  = BE_64(&moov_atom[i + 12 + j * 8]);
                 current_offset += moov_atom_size;
diff --git a/tools/seek_print.c b/tools/seek_print.c
new file mode 100644
index 0000000..a99a0ad
--- /dev/null
+++ b/tools/seek_print.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2013 Nicolas George
+ *
+ * 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 <unistd.h>
+
+#include "config.h"
+#if HAVE_UNISTD_H
+#include <unistd.h>             /* getopt */
+#endif
+
+#include "libavformat/avformat.h"
+#include "libavutil/timestamp.h"
+
+#if !HAVE_GETOPT
+#include "compat/getopt.c"
+#endif
+
+static void usage(int ret)
+{
+    fprintf(ret ? stderr : stdout,
+            "Usage: seek_print file [command ...]\n"
+            "Commands:\n"
+            "    read\n"
+            "    seek:stream:min_ts:ts:max_ts:flags\n"
+            );
+    exit(ret);
+}
+
+int main(int argc, char **argv)
+{
+    int opt, ret, stream, flags;
+    const char *filename;
+    AVFormatContext *avf = NULL;
+    int64_t min_ts, max_ts, ts;
+    AVPacket packet;
+
+    while ((opt = getopt(argc, argv, "h")) != -1) {
+        switch (opt) {
+        case 'h':
+            usage(0);
+        default:
+            usage(1);
+        }
+    }
+    argc -= optind;
+    argv += optind;
+    if (!argc)
+        usage(1);
+    filename = *argv;
+    argv++;
+    argc--;
+
+    av_register_all();
+    if ((ret = avformat_open_input(&avf, filename, NULL, NULL)) < 0) {
+        fprintf(stderr, "%s: %s\n", filename, av_err2str(ret));
+        return 1;
+    }
+    if ((ret = avformat_find_stream_info(avf, NULL)) < 0) {
+        fprintf(stderr, "%s: could not find codec parameters: %s\n", filename,
+                av_err2str(ret));
+        return 1;
+    }
+
+    for (; argc; argc--, argv++) {
+        if (!strcmp(*argv, "read")) {
+            ret = av_read_frame(avf, &packet);
+            if (ret < 0) {
+                printf("read: %d (%s)\n", ret, av_err2str(ret));
+            } else {
+                AVRational *tb = &avf->streams[packet.stream_index]->time_base;
+                printf("read: %d size=%d stream=%d dts=%s (%s) pts=%s (%s)\n",
+                       ret, packet.size, packet.stream_index,
+                       av_ts2str(packet.dts), av_ts2timestr(packet.dts, tb),
+                       av_ts2str(packet.pts), av_ts2timestr(packet.pts, tb));
+                av_free_packet(&packet);
+            }
+        } else if (sscanf(*argv, "seek:%i:%"PRIi64":%"PRIi64":%"PRIi64":%i",
+                   &stream, &min_ts, &ts, &max_ts, &flags) == 5) {
+            ret = avformat_seek_file(avf, stream, min_ts, ts, max_ts, flags);
+            printf("seek: %d (%s)\n", ret, av_err2str(ret));
+        } else {
+            fprintf(stderr, "'%s': unknown command\n", *argv);
+            return 1;
+        }
+    }
+
+    avformat_close_input(&avf);
+
+    return 0;
+}